В этом примере показано, как можно использовать В Каждой Подсистеме, чтобы реализовать алгоритм квадратного корня потоковой передачи путем расположения каскадом идентичных итераций 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/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/MATLAB Function2 as hdlsrc/hdlcoder_foreach_cordic/MATLAB_Function2.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/BR2020ad_1302590_239645/publish_examples2/tp967cfa6e/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)
сформировать входные параметры Для Каждой Подсистемы. Это требует, чтобы каскадные блоки использовали те же типы входных и выходных данных.