В этом примере показано, как можно использовать Для Каждой Подсистемы, чтобы реализовать алгоритм квадратного корня потоковой передачи путем расположения каскадом идентичных итераций CORDIC. Можно затем сгенерировать код для алгоритма при помощи HDL Coder™.
CORDIC является итеративным алгоритмом, который может использоваться, чтобы аппроксимировать математику фиксированной точки, такую как тригонометрические функции, квадратный корень, и разделиться. Итеративное ядро состоит из простого сдвига, и добавьте операции, позволив алгоритму быть реализованными эффективно на оборудовании ASIC или FPGA. Для низких приложений скорости передачи данных одноядерное может быть снова использовано, чтобы выполнить все итерации и достигнуть места очень небольшой площади. Для приложений, требующих, чтобы новая выборка данных была обработана в каждом такте, отдельное ядро может использоваться, чтобы вычислить каждую итерацию в каскадной цепи, как показано в следующей схеме.
В то время как это прямо, чтобы вручную расположить каскадом ядра в Simulink®, способность автоматически настроить количество ядер на основе значения параметров была бы очень желательна. Можно сделать точно что с помощью Для Каждой Подсистемы.
В этой модели итеративное ядро помещается в Для Каждой Подсистемы, которая будет повторена времена N, где N является количеством итераций, заданных в маске блока верхнего уровня. То
базовые выходные параметры формируют вектор в For Each Subsystem выход, где они являются конвейерными, и затем возвращены в Для Каждой Подсистемы входные параметры. Выходные параметры от базового (1:N-1)
соединяются с входными параметрами базового (2:N)
, точно то же самое как во вручную каскадной модели.
Допустимый путь прохождения сигнала включен, чтобы обработать неустойчивые входные данные и протестирован путем вставки случайных разрывов между допустимыми выборками данных.
open_system('hdlcoder_foreach_cordic') open_system('hdlcoder_foreach_cordic/For Each Cordic Sqrt','force')
Используя 14-битный вход со знаком в области значений [0.5,2)
, выход модели Simulink совпадает с cordicsqrt
ссылочная функция точно. Входной диапазон за пределами [0.5,2)
как ожидают, не будет работать, потому что пример испытывает недостаток в этапе нормализатора.
Кроме того, итоговая корректировка усиления в модели использует 18-битный параметр усиления для оптимального отображения DSP FPGA; в то время как cordicsqrt
функционируйте совпадает с размером слова параметра усиления к тому из входа усиления. Это приводит к незначительным различиям между моделью Simulink выход и cordicsqrt
функционируйте, когда другие типы входных данных будут использоваться.
slout = sim('hdlcoder_foreach_cordic'); data_out = slout.logsout.getElement('data out').Values.Data; valid_out = slout.logsout.getElement('valid out').Values.Data; data_out = data_out(valid_out); ref_cordic = double(cordicsqrt(v_fix, niter)); data_in = double(v_fix); data_out = double(data_out'); figure; subplot(211); plot(data_in, data_out, 'r.', data_in, ref_cordic, 'b-'); legend('ForEach', 'MATLAB CORDICSQRT', 'Location', 'SouthEast'); title('ForEach Model and MATLAB CORDICSQRT Reference Results'); subplot(212); absErr = abs(ref_cordic - data_out); plot(data_in, absErr); title('Absolute Differences (vs. MATLAB CORDICSQRT Reference)');
makehdl('hdlcoder_foreach_cordic/For Each Cordic Sqrt');
### Generating HDL for 'hdlcoder_foreach_cordic/For Each Cordic Sqrt'. ### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_foreach_cordic', { 'HDL Code Generation' } )">hdlcoder_foreach_cordic</a> for HDL code generation parameters. ### Starting HDL check. ### Begin VHDL Code Generation for 'hdlcoder_foreach_cordic'. ### Working on hdlcoder_foreach_cordic/For Each Cordic Sqrt/MATLAB Function2 as hdlsrc/hdlcoder_foreach_cordic/MATLAB_Function2.vhd. ### Working on hdlcoder_foreach_cordic/For Each Cordic Sqrt/For Each Subsystem/MATLAB Function1 as hdlsrc/hdlcoder_foreach_cordic/MATLAB_Function1.vhd. ### Working on hdlcoder_foreach_cordic/For Each Cordic Sqrt/For Each Subsystem as hdlsrc/hdlcoder_foreach_cordic/For_Each_Subsystem.vhd. ### Working on hdlcoder_foreach_cordic/For Each Cordic Sqrt as hdlsrc/hdlcoder_foreach_cordic/For_Each_Cordic_Sqrt.vhd. ### Generating package file hdlsrc/hdlcoder_foreach_cordic/For_Each_Cordic_Sqrt_pkg.vhd. ### Creating HDL Code Generation Check Report file:///tmp/BR2020bd_1444674_32127/publish_examples2/tp51ebd25b/hdlsrc/hdlcoder_foreach_cordic/For_Each_Cordic_Sqrt_report.html ### HDL check for 'hdlcoder_foreach_cordic' complete with 0 errors, 0 warnings, and 0 messages. ### HDL code generation complete.
Наблюдайте следующие инструкции при расположении каскадом блоков в использовании алгоритма Для Каждой Подсистемы:
С тех пор Для Каждой Подсистемы является атомарным, связь между выходом блока X и входом блока X+1 создает искусственный алгебраический цикл. Чтобы повредить этот цикл, поместите конвейерные регистры между расположением каскадом блоков за пределами Для Каждой Подсистемы, как продемонстрировано в этом примере.
Блок мультиплексора используется, чтобы конкатенировать внешний вход и выходные параметры блока (1:N-1)
сформировать входные параметры Для Каждой Подсистемы. Это требует, чтобы каскадные блоки использовали те же типы входных и выходных данных.