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

Несмотря на простоту каскадирования ядер в Simulink ® вручную, возможность автоматической регулировки количества ядер на основе значения параметра была бы весьма желательной. Это можно сделать точно с помощью параметра «Для каждой подсистемы».
В этой модели итеративное ядро помещается в «Для каждой подсистемы», повторяющейся N раз, где N - количество итераций, определенных в маске блока верхнего уровня. N основные выходы образуют вектор на выходе «For Each Subsystem» (Для каждой подсистемы), где они конвейерируются, а затем подаются обратно на входы «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.
### Running HDL checks on the model 'hdlcoder_foreach_cordic'.
### Begin compilation of the model 'hdlcoder_foreach_cordic'...
### Applying HDL optimizations on the model 'hdlcoder_foreach_cordic'...
### Begin model generation.
### Model generation complete.
### 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.
### Code Generation for 'hdlcoder_foreach_cordic' completed.
### Creating HDL Code Generation Check Report file:///tmp/BR2021ad_1584584_202060/publish_examples1/tp8fdc0684/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) для формирования входных данных каждой подсистемы. Это требует, чтобы каскадные блоки использовали один и тот же тип входных и выходных данных.