Используя подсистемы ForEach в HDL Coder

В этом примере показано, как можно использовать В Каждой Подсистеме, чтобы реализовать алгоритм квадратного корня потоковой передачи путем расположения каскадом идентичных итераций CORDIC. Можно затем сгенерировать код для алгоритма при помощи HDL Coder™.

Используя алгоритм CORDIC для аппаратных функций

CORDIC является итеративным алгоритмом, который может использоваться, чтобы аппроксимировать математику фиксированной точки, такую как тригонометрические функции, квадратный корень, и разделиться. Итеративное ядро состоит из простого сдвига, и добавьте операции, позволив алгоритму быть реализованными эффективно на оборудовании ASIC или FPGA. Для низких приложений скорости передачи данных одноядерное может быть снова использовано, чтобы выполнить все итерации и достигнуть места очень небольшой площади. Для приложений, требующих, чтобы новая выборка данных была обработана в каждом такте, отдельное ядро может использоваться, чтобы вычислить каждую итерацию в каскадной цепи, как показано в следующей схеме.

В то время как это прямо, чтобы вручную расположить каскадом ядра в Simulink®, способность автоматически настроить количество ядер на основе значения параметров была бы очень желательна. Можно сделать точно что с помощью Для Каждой Подсистемы.

Расположите каскадом итерации CORDIC Используя для каждой подсистемы

В этой модели итеративное ядро помещается в Для Каждой Подсистемы, которая будет повторена времена 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')

Сравните Выход со ссылкой квадратного корня CORDIC

Используя 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)');

Сгенерируйте HDL-код

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) сформировать входные параметры Для Каждой Подсистемы. Это требует, чтобы каскадные блоки использовали те же типы входных и выходных данных.

Похожие темы