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.
Примечание
Не используйте установку Inline MATLAB Function block code с MATLAB Datapath
архитектура блока MATLAB Function. Используйте FlattenHierarchy вместо этого. Для получения дополнительной информации смотрите Оптимизацию HDL Через Контур блока MATLAB function Используя Архитектуру MATLAB Datapath.
Блок MATLAB Function поддерживает арифметику с плавающей точкой и также вычисления с фиксированной точкой при помощи Fixed-Point Designer™ fi
функция. Эти поддержки функции, округляющиеся и режимы насыщения, которые полезны для алгоритмов кодирования, которые управляют произвольным словом и дробными длинами. 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 при помощи bitsliceget
и bitconcat
функции. Эта функция реализует последовательный ввод и вывод переключатели с 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.
Можно выполнить преобразования из целочисленного типа, чтобы сгенерировать немного векторного выхода и наоборот. Для модели в качестве примера, которая показывает, как выполнить это преобразование, открыть модель hdlcoder_int2bits_bits2int
.
open_system('hdlcoder_int2bits_bits2int')
eml_hdl_design_patterns
библиотека под Word Twiddlers
библиотека.Проверяйте на настройки блока MATLAB function