Библиотека eml_hdl_design_patterns
является обширным набором примеров, демонстрирующих полезные приложения блока MATLAB function в генерации HDL-кода.
Чтобы открыть библиотеку, введите следующую команду в подсказке MATLAB®:
eml_hdl_design_patterns
Можно использовать много блоков в библиотеке как примеры поваренной книги различных аппаратных компонентов, можно следующим образом:
Скопируйте блок от библиотеки до вашей модели и используйте его в качестве вычислительного модуля.
Скопируйте код с блока и используйте его в качестве локальной функции в существующем блоке MATLAB function.
Когда вы создаете авторские блоки, можно управлять, встроить ли или инстанцировать HDL-кода, сгенерированного от блоков MATLAB function. Используйте флажок Inline MATLAB Function block code в разделе HDL Code Generation> Global Settings> Coding style диалогового окна Configuration Parameters. Для получения дополнительной информации см. Встроенный код блока MATLAB function.
Блок MATLAB function поддерживает вычисления с фиксированной точкой с помощью функции fi
Fixed-Point Designer™. Эти поддержки функции, округляющиеся и режимы насыщения, которые полезны для алгоритмов кодирования, которые управляют произвольным словом и дробными длинами. HDL Coder™ поддерживает все округление fi
и режимы переполнения.
HDL-код, сгенерированный от блока MATLAB function, битно-верен для семантики MATLAB. Сгенерированный код использует побитовую обработку и битные операторы доступа (например, Срез, Расширьте, Уменьшайте, Concat, и т.д.), которые являются нативными к VHDL® и Verilog®.
Следующее обсуждение показывает, как HDL-код, сгенерированный от блока MATLAB function, следует за семантикой броска перед суммой, в которой сложение и операнды вычитания брошены к типу результата перед сложением, или вычитание выполняется.
Откройте библиотеку eml_hdl_design_patterns
и выберите блок Combinatorics/eml_expr
. eml_expr
реализует простое выражение, содержащее сложение, вычитание и операторы умножения с отличающимися типами данных фиксированной точки. Сгенерированный HDL-код показывает преобразование этого выражения с операндами фиксированной точки. Блок MATLAB function использует следующий код:
% fixpt arithmetic expression expr = (a*b) - (a+b); % cast the result to (sfix7_En4) output type y = fi(expr, 1, 7, 4);
Спецификация fimath
по умолчанию для блока определяет поведение арифметических выражений с помощью операндов фиксированной точки в блоке MATLAB function:
fimath(... 'RoundMode', 'ceil',... 'OverflowMode', 'saturate',... 'ProductMode', 'FullPrecision', 'ProductWordLength', 32,... 'SumMode', 'FullPrecision', 'SumWordLength', 32,... 'CastBeforeSum', true)
Типы данных операндов и вывода следующие:
a:
(sfix5_En2)
b:
(sfix5_En3)
y:
(sfix7_En4)
Перед генерацией HDL-кода, операцией
expr = (a*b) - (a+b);
сломан внутренне в следующие подшаги:
tmul = a * b;
tadd = a + b;
tsub = tmul - tadd;
y = tsub;
На основе настроек fimath
(см. Руководство по проектированию для блока MATLAB function) это выражение далее сломано внутренне можно следующим образом:
На основе заданного ProductMode
, 'FullPrecision'
, выходной тип tmul
вычисляется как (sfix10_En5)
.
Поскольку свойство CastBeforeSum
установлено в 'true'
, подшаг 2 сломан можно следующим образом:
t1 = (sfix7_En3) a; t2 = (sfix7_En3) b; tadd = t1 + t2;
sfix7_En3
является типом суммы результата после выравнивания двоичных точек и составления дополнительного бита, чтобы составлять возможное переполнение.
На основе промежуточных типов tmul (sfix10_En5)
и tadd (sfix7_En3)
тип результата вычитания на подшаге 3 вычисляется как sfix11_En5
. Соответственно, подшаг 3 сломан можно следующим образом:
t3 = (sfix11_En5) tmul; t4 = (sfix11_En5) tadd; tsub = t3 - t4;
Наконец, результат брошен к меньшему типу (sfix7_En4
) продвижение к следующим итоговым операторам выражения:
tmul = a * b; t1 = (sfix7_En3) a; t2 = (sfix7_En3) b; tadd = t1 + t2; t3 = (sfix11_En5) tmul; t4 = (sfix11_En5) tadd; tsub = t3 - t4; y = (sfix7_En4) tsub;
Следующие списки показывают сгенерированный код VHDL и Verilog от блока eml_expr
.
Выборка VHDL кода:
BEGIN --MATLAB Function 'Subsystem/eml_expr': '<S2>:1' -- fixpt arithmetic expression --'<S2>:1:4' mul_temp <= signed(a) * signed(b); sub_cast <= resize(mul_temp, 11); add_cast <= resize(signed(a & '0'), 7); add_cast_0 <= resize(signed(b), 7); add_temp <= add_cast + add_cast_0; sub_cast_0 <= resize(add_temp & '0' & '0', 11); expr <= sub_cast - sub_cast_0; -- cast the result to correct output type --'<S2>:1:7' y <= "0111111" WHEN ((expr(10) = '0') AND (expr(9 DOWNTO 7) /= "000")) OR ((expr(10) = '0') AND (expr(7 DOWNTO 1) = "0111111")) ELSE "1000000" WHEN (expr(10) = '1') AND (expr(9 DOWNTO 7) /= "111") ELSE std_logic_vector(expr(7 DOWNTO 1) + ("0" & expr(0))); END fsm_SFHDL;
Выборка Verilog кода:
//MATLAB Function 'Subsystem/eml_expr': '<S2>:1' // fixpt arithmetic expression //'<S2>:1:4' assign mul_temp = a * b; assign sub_cast = mul_temp; assign add_cast = {a[4], {a, 1'b0}}; assign add_cast_0 = b; assign add_temp = add_cast + add_cast_0; assign sub_cast_0 = {{2{add_temp[6]}}, {add_temp, 2'b00}}; assign expr = sub_cast - sub_cast_0; // cast the result to correct output type //'<S2>:1:7' assign y = (((expr[10] == 0) && (expr[9:7] != 0)) || ((expr[10] == 0) && (expr[7:1] == 63)) ? 7'sb0111111 : ((expr[10] == 1) && (expr[9:7] != 7) ? 7'sb1000000 : expr[7:1] + $signed({1'b0, expr[0]})));
Эти выборки кода показывают, что сгенерированный HDL-код от блока MATLAB function представляет битно-истинное поведение выражений вычислений с фиксированной точкой с помощью операторов HDL высокого уровня. HDL-код сгенерирован, использовав правила кодирования HDL как bitselect
высокого уровня и операторы репликации partselect
и явное расширение знака, и измените размер операторов.
В модели программирования блока MATLAB function содержащие состояние элементы представлены как персистентные переменные. Переменная, которая объявляется persistent
, сохраняет свое значение через вызовы функции в программном обеспечении, и через шаги шага расчета во время симуляции.
Обратите внимание на то, что ваш код MATLAB должен считать персистентную переменную, прежде чем это будет записано, если вы хотите, чтобы HDL Coder вывел регистр в HDL-коде. Кодер отображает предупреждающее сообщение, если ваш код не следует этому правилу.
Следующий пример показывает блок unit delay
, который задерживает входную выборку, u
, одним шагом времени симуляции. u
является операндом фиксированной точки типа sfix6
. u_d
является персистентной переменной, которая содержит входную выборку.
function y = fcn(u) persistent u_d; if isempty(u_d) u_d = fi(-1, numerictype(u), fimath(u)); end % return delayed input from last sample time hit y = u_d; % store the current input to be used later u_d = u;
Поскольку этот код намеревается для u_d
вывести регистр во время генерации HDL-кода, u_d
читается в операторе присваивания, y = u_d
, прежде чем это будет написано в u_d = u
.
HDL Coder генерирует следующий HDL-код для блока unit delay
.
ENTITY Unit_Delay IS PORT ( clk : IN std_logic; clk_enable : IN std_logic; reset : IN std_logic; u : IN std_logic_vector(15 DOWNTO 0); y : OUT std_logic_vector(15 DOWNTO 0)); END Unit_Delay; ARCHITECTURE fsm_SFHDL OF Unit_Delay IS BEGIN initialize_Unit_Delay : PROCESS (clk, reset) BEGIN IF reset = '1' THEN y <= std_logic_vector(to_signed(0, 16)); ELSIF clk'EVENT AND clk = '1' THEN IF clk_enable = '1' THEN y <= u; END IF; END IF; END PROCESS initialize_Unit_Delay;
Инициализация персистентных переменных перемещена в основную область сброса в процессе инициализации.
Обратитесь к подсистеме Delays
в библиотеке eml_hdl_design_patterns
, чтобы видеть, как векторы персистентных переменных могут использоваться к образцовой целочисленной задержке, коснитесь задержки и блоков вектора задержки касания. Эти шаблоны разработки полезны в реализации алгоритмов последовательности, которые несут состояние между выполнением блока MATLAB function в модели.
Блок MATLAB function помогает вам интеллектуальная собственность автора, и создайте альтернативные реализации части алгоритма. При помощи блоков MATLAB function таким образом, можно вести подробную работу генератора HDL-кода даже при написании высокоуровневых алгоритмов.
Например, подсистема Comparators
в библиотеке eml_hdl_design_patterns
включает несколько альтернативных алгоритмов для нахождения минимального значения вектора. Блок Comparators/eml_linear_min
находит минимум вектора в линейном режиме последовательно. Блок Comparators/eml_tree_min
сравнивает элементы в древовидной структуре. Древовидная реализация может достигнуть более высокой частоты часов путем добавления конвейерных регистров между этапами log2(N)
. (См. eml_hdl_design_patterns/Filters
для примера.)
Теперь рассмотрите заменяющий простую операцию сравнения в блоках Comparators
с арифметической операцией (например, сложение, вычитание или умножение), где промежуточные результаты должны быть квантованы. Используя настройки округления fimath
, можно точно настроить вычисления промежуточного значения перед каналом промежуточных значений в следующий этап. Можно использовать этот метод для настройки сгенерированного оборудования или настройки алгоритма.
Можно объявить ненастраиваемый параметр для блока MATLAB function путем установки его Scope на Parameter
в Портах и графический интерфейсе пользователя Менеджера данных, и очистки опции Tunable.
Ненастраиваемый параметр не появляется как порт сигнала на блоке. Аргументы параметра для блоков MATLAB function принимают, их значения от параметров, заданных в родительском Simulink®, замаскировали подсистему или от переменных, заданных в базовом рабочем пространстве MATLAB, не от сигналов в модели Simulink.
Построения управления блоком MATLAB function, такие как switch/case
и if-elseif-else
, вместе с операциями вычислений с фиксированной точкой позволяют вам управляющая логика модели быстро.
FSMs/mealy_fsm_blk
andFSMs/moore_fsm_blk
блоки в библиотеке eml_hdl_design_patterns
обеспечивает реализации в качестве примера Мучнистых и конечных автоматов Мура в блоке MATLAB function.
Следующий листинг реализует конечный автомат Мура.
function Z = moore_fsm(A) persistent moore_state_reg; if isempty(moore_state_reg) moore_state_reg = fi(0, 0, 2, 0); end S1 = 0; S2 = 1; S3 = 2; S4 = 3; switch uint8(moore_state_reg) case S1, Z = true; if (~A) moore_state_reg(1) = S1; else moore_state_reg(1) = S2; end case S2, Z = false; if (~A) moore_state_reg(1) = S1; else moore_state_reg(1) = S2; end case S3, Z = false; if (~A) moore_state_reg(1) = S2; else moore_state_reg(1) = S3; end case S4, Z = true; if (~A) moore_state_reg(1) = S1; else moore_state_reg(1) = S3; end otherwise, Z = false; end
В этом примере, персистентный переменный (moore_state_reg
) переменные состояния моделей. Вывод зависит только от переменных состояния, таким образом моделируя машину Мура.
Блок FSMs/mealy_fsm_blk
в библиотеке eml_hdl_design_patterns
реализует Мучнистый конечный автомат. Мучнистый конечный автомат отличается от конечного автомата Мура в этом, выходные параметры зависят от входных параметров, а также переменных состояния.
Блок MATLAB function может быстро смоделировать простую машину состояний и другие основанные на управлении аппаратные алгоритмы (такие как сопоставители или связанные с синхронизацией контроллеры), использование проверяет утверждения и персистентные переменные.
Для моделирования более комплексной и иерархической машины состояний со сложной временной логикой используйте график Stateflow®, чтобы смоделировать конечный автомат.
Чтобы реализовать алгоритмы арифметической и управляющей логики в блоках MATLAB function, предназначенных для генерации HDL-кода, существуют некоторые простые связанные с HDL требования кодирования:
Блок MATLAB function верхнего уровня должен быть назван однажды на временной шаг.
Должно быть возможно полностью развернуть программные циклы.
Персистентные переменные со значениями сброса и логикой обновления должны использоваться, чтобы содержать значения через шаги времени симуляции.
Квантованные переменные данных должны использоваться в циклах.
Следующий скрипт показывает, как смоделировать синхронное/обратный счетчик с предварительно установленными значениями и входными параметрами управления. Пример обеспечивает и основное управление сбросом переменных постоянного состояния и локальные входные параметры блока использования управления сбросом (например, presetClear
). Условие isempty
вводит процесс инициализации под управлением синхронного сброса. Раздел presetClear
реализован в выходном разделе в сгенерированном HDL-коде.
Оба вверх и вниз по операторам выбора, реализующим цикл количества, требуют, чтобы значения счетчика были квантованы после сложения или вычитания. По умолчанию блок MATLAB function автоматически распространяет настройки фиксированной точки, заданные для блока. В этом скрипте, однако, явным образом заданы настройки фиксированной точки для промежуточных количеств и констант.
function [Q, QN] = up_down_ctr(upDown, presetClear, loadData, presetData) % up down result % 'result' syntheses into sequential element result_nt = numerictype(0,4,0); result_fm = fimath('OverflowMode', 'saturate', 'RoundMode', 'floor'); initVal = fi(0, result_nt, result_fm); persistent count; if isempty(count) count = initVal; end if presetClear count = initVal; elseif loadData count = presetData; elseif upDown inc = count + fi(1, result_nt, result_fm); -- quantization of output count = fi(inc, result_nt, result_fm); else dec = count - fi(1, result_nt, result_fm); -- quantization of output count = fi(dec, result_nt, result_fm); end Q = count; QN = bitcmp(count);
Следующий пример кода показывает, как смоделировать сдвиговые регистры в коде блока MATLAB function при помощи функций bitconcat
и bitsliceget
. Эта функция реализует последовательный ввод и вывод переключатели с 32-битным входом операнда фиксированной точки. Смотрите блок Shift Registers/shift_reg_1by32
в библиотеке eml_hdl_design_patterns
для получения дополнительной информации.
function sr_out = fcn(shift, sr_in) %shift register 1 by 32 persistent sr; if isempty(sr) sr = fi(0, 0, 32, 0, 'fimath', fimath(sr_in)); end % return sr[31] sr_out = getmsb(sr); if (shift) % sr_new[32:1] = sr[31:1] & sr_in sr = bitconcat(bitsliceget(sr, 31, 1), sr_in); end
Следующий пример кода показывает код процесса VHDL, сгенерированный для блока shift_reg_1by32
.
shift_reg_1by32 : PROCESS (shift, sr_in, sr) BEGIN sr_next <= sr; -- MATLAB Function Function 'Subsystem/shift_reg_1by32': '<S2>:1' --shift register 1 by 32 --'<S2>:1:1 -- return sr[31] --'<S2>:1:10' sr_out <= sr(31); IF shift /= '0' THEN --'<S2>:1:12' -- sr_new[32:1] = sr[31:1] & sr_in --'<S2>:1:14' sr_next <= sr(30 DOWNTO 0) & sr_in; END IF; END PROCESS shift_reg_1by32;
Блок Shift Registers/shift_reg_1by64
показывает переключатель на 64 бита. В этом случае переключатель использует два слова фиксированной точки, чтобы представлять операнд, преодолевая 32-битное ограничение размера слова для целых чисел фиксированной точки.
Просмотрите модель eml_hdl_design_patterns
другие полезные аппаратные компоненты, которые могут быть легко реализованы с помощью блока MATLAB function.