Шаблоны разработки блока MATLAB function для HDL

eml_hdl_design_patterns Библиотека

Библиотека 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);

сломан внутренне в следующие подшаги:

  1. tmul = a * b;

  2. tadd = a + b;

  3. tsub = tmul - tadd;

  4. 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 помогает вам интеллектуальная собственность автора, и создайте альтернативные реализации части алгоритма. При помощи блоков 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.