MATLAB Function шаблоны проекта блоков для HDL

Библиотека eml_hdl_design_patterns

The eml_hdl_design_patterns библиотека представляет собой обширный набор примеров, демонстрирующих полезные приложения блока MATLAB Function при генерации HDL-кода.

Чтобы открыть библиотеку, введите следующую команду в MATLAB® приглашение:

eml_hdl_design_patterns

Можно использовать много блоков в библиотеке как примеры cookbook различных аппаратных элементов, следующим образом:

  • Скопируйте блок из библиотеки в вашу модель и используйте его как вычислительный модуль.

  • Скопируйте код из блока и используйте его как локальную функцию в существующем блоке MATLAB Function.

Когда вы создаете пользовательские блоки, можно управлять, входить ли в строку или создавать экземпляры HDL-кода, сгенерированного из MATLAB Function блоков. Установите флажок Inline MATLAB Function block code в разделе HDL Code Generation > Global Settings > Coding style диалогового окна Параметры конфигурации. Для получения дополнительной информации см. Inline MATLAB Function block code.

Примечание

Не используйте настройку 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, имеет битовое значение true к семантике MATLAB. Сгенерированный код использует бит операторов манипуляции и битового доступа (для примера, Среза, Extend, Reduce, 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 как описано в Design Guidelines для Блок 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-кодирования, таких как high level 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 библиотека включает несколько альтернативных алгоритмов для нахождения минимального значения вектора. The Comparators/eml_linear_min блок последовательно находит минимум вектора в линейном режиме. The Comparators/eml_tree_min блок сравнивает элементы в древовидной структуре. Реализация дерева может достичь более высокой тактовой частоты путем добавления регистров конвейера между log2(N) этапы. (См. eml_hdl_design_patterns/Filters для примера.)

Теперь рассмотрите замену простой операции сравнения в Comparators блоки с арифметической операцией (для примера, сложения, вычитания или умножения), где промежуточные результаты должны быть квантованы. Использование fimath настройки округления, можно точно настроить расчеты промежуточных значений перед подачей промежуточных значений на следующий этап. Можно использовать этот метод для настройки сгенерированного оборудования или настройки алгоритма.

Неотключаемые аргументы параметра

Можно объявить нетронутый параметр для блока MATLAB Function, установив его Scope на Parameter в графическом интерфейсе пользователя Ports and Data Manager и очистке опции Tunable.

Неотключаемый параметр не отображается как сигнальный порт на блоке. Аргументы параметра для блоков MATLAB Function берут их значения из параметров, определенных в родительском Simulink® маскированная подсистема или от переменных, определенных в базовом рабочем пространстве MATLAB, а не от сигналов в модели Simulink.

Логика управления моделированием и простая конечная Машина состояний

MATLAB Function блока управляющие конструкции, такие как switch/case и if-elseif-else, в сочетании с арифметическими операциями с фиксированной точкой, позволяют вам быстро моделировать логику управления.

The FSMs/mealy_fsm_blk и FSMs/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) моделирует переменные состояния. Это выход зависит только от переменных состояния, таким образом моделируя машину Мура.

The FSMs/mealy_fsm_blk блок в eml_hdl_design_patterns библиотека реализует конечный автомат Мили. Конечный автомат Мили отличается от конечного автомата Мура тем, что выходы зависят от входов, а также от переменных состояния.

Блок MATLAB Function может быстро смоделировать простые машины состояний и другие основанные на управлении алгоритмы оборудования (такие как шаблоны matcher или контроллеры, связанные с синхронизацией), используя операторы управления и постоянные переменные.

Для моделирования более сложных и иерархических машин состояний с сложной временной логикой используйте Stateflow® график для моделирования конечного автомата.

Счетчики моделирования

Для реализации арифметических и управляющих логических алгоритмов в блоках MATLAB Function, предназначенных для генерации HDL-кода, существуют некоторые простые требования к HDL-кодированию:

  • Блок MATLAB Function верхнего уровня должен вызываться один раз в временной шаг.

  • Должна быть возможность полного разблокирования циклов программы.

  • Стойкие переменные с значениями сброса и логикой обновления должны использоваться, чтобы удерживать значения на всех временных шагах симуляции.

  • Квантованные переменные данных должны использоваться внутри циклов.

Следующий скрипт показывает, как смоделировать синхронный счетчик вверх/вниз с предустановленными значениями и входами управления. Пример предоставляет и главное управление сбросом переменных стойкого состояния, и локальное управление сбросом с помощью блока входов (например presetClear). The isempty условие входит в процесс инициализации под управлением синхронного сброса. The 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;

The Shift Registers/shift_reg_1by64 блок показывает 64-битный переключатель. В этом случае сдвигатель использует два слова с фиксированной точкой, чтобы представлять операнд, преодолевая 32-битное ограничение размера слова для целых чисел с фиксированной точкой.

Просмотр eml_hdl_design_patterns модель для других полезных аппаратных элементов, которые можно легко реализовать с помощью блока MATLAB Function.

Десятичное преобразование в двоичное

Можно выполнить преобразования из целого типа, чтобы сгенерировать выход вектора битов и наоборот. Для примера модели, которая показывает, как выполнить это преобразование, откройте модель hdlcoder_int2bits_bits2int.

open_system('hdlcoder_int2bits_bits2int')
Модель использует блоки MATLAB Function, которые реализованы в eml_hdl_design_patterns библиотека под Word Twiddlers библиотека.

См. также

Похожие темы