exponenta event banner

Шаблоны проектирования функциональных блоков MATLAB для HDL

Библиотека eml_hdl_design_patterns

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

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

eml_hdl_design_patterns

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

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

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

При создании пользовательских блоков можно управлять встроением или созданием экземпляра кода HDL, созданного из функциональных блоков MATLAB. Установите флажок «Inline MATLAB Function block code» в разделе «Создание кода HDL» > «Global Settings» > «Coding style» диалогового окна «Configuration Parameters». Дополнительные сведения см. в разделе Встроенный код функционального блока MATLAB.

Примечание

Не используйте настройку Inline MATLAB Function block code с помощью MATLAB Datapath архитектура функционального блока MATLAB. Вместо этого используйте FlattenHierarchy. Дополнительные сведения см. в разделе Оптимизация HDL по границе функционального блока MATLAB с использованием архитектуры Datapath MATLAB.

Эффективные алгоритмы с фиксированной точкой

Блок MATLAB Function поддерживает арифметику с плавающей запятой, а также арифметику с фиксированной точкой с помощью Designer™ Fixed-Point fi функция. Эта функция поддерживает режимы округления и насыщения, которые полезны для алгоритмов кодирования, которые манипулируют произвольными длинами слов и дробей. HDL Coder™ поддерживает все fi режимы округления и переполнения. Код HDL, сгенерированный из функционального блока MATLAB, имеет значение bit-true для семантики MATLAB. Созданный код использует операторы управления битами и доступа к битам (например, Slice, Extend, Reduce, Concat и т.д.), которые являются собственными для VHDL ® и Verilog ®.

В следующем описании показано, как код HDL, генерируемый из блока MATLAB Function, следует семантике перед строкой, в которой операнды сложения и вычитания приводятся к типу результата перед выполнением сложения или вычитания.

Откройте окно eml_hdl_design_patterns и выберите Combinatorics/eml_expr блок. eml_expr реализует простое выражение, содержащее операторы сложения, вычитания и умножения с различными типами данных с фиксированной точкой. Созданный код HDL показывает преобразование этого выражения с операндами с фиксированной точкой. Функциональный блок MATLAB использует следующий код:

% 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, это выражение далее разбивается внутри следующим образом:

  • На основе указанного 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 представляет поведение истинных битов арифметических выражений с фиксированной точкой с использованием высокоуровневых операторов HDL. Код HDL генерируется с использованием правил кодирования HDL, таких как высокий уровень bitselect и partselect операторы репликации и операторы явного расширения и изменения размеров.

Состояние модели с использованием постоянных переменных

В модели программирования блока функций MATLAB элементы удержания состояния представлены в виде постоянных переменных. Объявленная переменная persistent сохраняет свое значение в вызовах функций в программном обеспечении и во временных шагах выборки во время моделирования.

Обратите внимание, что код MATLAB должен считывать постоянную переменную перед ее написанием, если требуется, чтобы кодер HDL выводил регистр в код 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 генерирует следующий код 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 в модели.

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

Функциональный блок MATLAB помогает создавать интеллектуальную собственность и альтернативные реализации части алгоритма. Таким образом, используя функциональные блоки MATLAB, можно управлять детальной работой генератора кодов 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 в графическом интерфейсе пользователя «Ports and Data Manager» и снимите флажок «Tunable».

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

Моделирование логики управления и простых конечных автоматов

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

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

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

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

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

Моделирование счетчиков

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

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

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

  • Постоянные переменные со значениями сброса и логикой обновления должны использоваться для хранения значений на всех этапах моделирования.

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

В следующем сценарии показано, как моделировать синхронный счетчик с заданными значениями и управляющими входами. Пример обеспечивает как главное управление сбросом переменных постоянного состояния, так и локальное управление сбросом с использованием входов блоков (например, presetClear). isempty условие входит в процесс инициализации под управлением синхронного сброса. presetClear секция реализуется в выходной секции в сгенерированном коде ЛПВП.

Операторы «вверх» и «вниз», реализующие цикл подсчета, требуют, чтобы значения счетчика квантовались после сложения или вычитания. По умолчанию блок 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 с помощью 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')
Модель использует функциональные блоки MATLAB, реализованные в eml_hdl_design_patterns в библиотеке под Word Twiddlers библиотека.

См. также

Связанные темы