Распределенная конвейерная вставка для блоков MATLAB function

Обзор

Distributed pipeline insertion является специальной оптимизацией для HDL-кода, сгенерированного из графиков Stateflow® или блоков MATLAB function. Распределенная конвейерная вставка позволяет вам достигнуть более высоких тактовых частот в своих приложениях HDL, за счет некоторой суммы задержки, вызванной введением конвейерных регистров.

Для получения общей информации о распределенной конвейерной вставке, включая ограничения, смотрите DistributedPipelining.

Распределенная конвейеризация в цепочке множителя

Этот пример показывает распределенную конвейерную вставку в простой модели, которая реализует цепочку 5 умножения.

Чтобы открыть модель, введите следующее:

mpipe_multchain

Корневая модель уровня содержит подсистему multi_chain. Подсистема multi_chain функционирует как устройство под тестом (DUT), от которого можно сгенерировать HDL-код. Подсистема управляет блоком MATLAB function, mult8. Следующие данные показывают подсистему.

Следующее показывает цепочку умножения, как закодировано в блоке MATLAB function mult8:

function y = fcn(x1,x2,x3,x4,x5,x6,x7,x8)
% A chained multiplication:
% y = (x1*x2)*(x3*x4)*(x5*x6)*(x7*x8)

y1 = x1 * x2;
y2 = x3 * x4;
y3 = x5 * x6;
y4 = x7 * x8;

y5 = y1 * y2;
y6 = y3 * y4;

y = y5 * y6;

Чтобы применить распределенную конвейерную вставку к этому блоку, используйте диалоговое окно HDL Properties для блока mult8. Задайте генерацию двух настроек канала связи для блока MATLAB function и включите распределенную конвейерную оптимизацию:

В диалоговом окне Configuration Parameters опции HDL Code Generation верхнего уровня указывают что:

  • Код VHDL® сгенерирован от подсистемы mpipe_multchain/mult_chain.

  • HDL Coder™ сгенерирует код и отобразит сгенерированную модель.

Вставка двух настроек канала связи в сгенерированный HDL-код приводит к задержке двух тактов. В сгенерированной модели задержка двух тактов вставляется перед выводом подсистемы mpipe_multchain/mult_chain/mult8 так, чтобы симуляции образцового отражения поведение сгенерированного HDL-кода. Следующие данные показывают вставленный блок Delay.

Следующий листинг показывает полный раздел архитектуры сгенерированного кода. Комментарии, сгенерированные HDL Coder, указывают на конвейерные определения регистра.

ARCHITECTURE fsm_SFHDL OF mult8 IS

    SIGNAL pipe_var_0_1 : signed(7 DOWNTO 0);   -- Pipeline reg from stage 0 to stage 1
    SIGNAL b_pipe_var_0_1 : signed(7 DOWNTO 0);   -- Pipeline reg from stage 0 to stage 1
    SIGNAL c_pipe_var_0_1 : signed(7 DOWNTO 0);   -- Pipeline reg from stage 0 to stage 1
    SIGNAL d_pipe_var_0_1 : signed(7 DOWNTO 0);   -- Pipeline reg from stage 0 to stage 1
    SIGNAL pipe_var_1_2 : signed(7 DOWNTO 0);   -- Pipeline reg from stage 1 to stage 2
    SIGNAL b_pipe_var_1_2 : signed(7 DOWNTO 0);   -- Pipeline reg from stage 1 to stage 2
    SIGNAL pipe_var_0_1_next : signed(7 DOWNTO 0);
    SIGNAL b_pipe_var_0_1_next : signed(7 DOWNTO 0);
    SIGNAL c_pipe_var_0_1_next : signed(7 DOWNTO 0);
    SIGNAL d_pipe_var_0_1_next : signed(7 DOWNTO 0);
    SIGNAL pipe_var_1_2_next : signed(7 DOWNTO 0);
    SIGNAL b_pipe_var_1_2_next : signed(7 DOWNTO 0);
    SIGNAL y1 : signed(7 DOWNTO 0);
    SIGNAL y2 : signed(7 DOWNTO 0);
    SIGNAL y3 : signed(7 DOWNTO 0);
    SIGNAL y4 : signed(7 DOWNTO 0);
    SIGNAL y5 : signed(7 DOWNTO 0);
    SIGNAL y6 : signed(7 DOWNTO 0);
    SIGNAL mul_temp : signed(15 DOWNTO 0);
    SIGNAL mul_temp_0 : signed(15 DOWNTO 0);
    SIGNAL mul_temp_1 : signed(15 DOWNTO 0);
    SIGNAL mul_temp_2 : signed(15 DOWNTO 0);
    SIGNAL mul_temp_3 : signed(15 DOWNTO 0);
    SIGNAL mul_temp_4 : signed(15 DOWNTO 0);
    SIGNAL mul_temp_5 : signed(15 DOWNTO 0);

BEGIN
    initialize_mult8 : PROCESS (clk, reset)
    BEGIN
        IF reset = '1' THEN
            pipe_var_0_1 <= to_signed(0, 8);
            b_pipe_var_0_1 <= to_signed(0, 8);
            c_pipe_var_0_1 <= to_signed(0, 8);
            d_pipe_var_0_1 <= to_signed(0, 8);
            pipe_var_1_2 <= to_signed(0, 8);
            b_pipe_var_1_2 <= to_signed(0, 8);
        ELSIF clk'EVENT AND clk= '1' THEN
            IF clk_enable= '1' THEN
                pipe_var_0_1 <= pipe_var_0_1_next;
                b_pipe_var_0_1 <= b_pipe_var_0_1_next;
                c_pipe_var_0_1 <= c_pipe_var_0_1_next;
                d_pipe_var_0_1 <= d_pipe_var_0_1_next;
                pipe_var_1_2 <= pipe_var_1_2_next;
                b_pipe_var_1_2 <= b_pipe_var_1_2_next;
            END IF;
        END IF;
    END PROCESS initialize_mult8;

    -- This block supports an embeddable subset of the MATLAB language.
    -- See the help menu for details. 
    --y = (x1+x2)+(x3+x4)+(x5+x6)+(x7+x8);
    mul_temp <= signed(x1) * signed(x2);
    
    y1 <= "01111111" WHEN (mul_temp(15) = '0') AND (mul_temp(14 DOWNTO 7) /= "00000000")
        ELSE "10000000" WHEN (mul_temp(15) = '1') AND (mul_temp(14 DOWNTO 7) /= "11111111")
        ELSE mul_temp(7 DOWNTO 0);

    mul_temp_0 <= signed(x3) * signed(x4);
    
    y2 <= "01111111" WHEN (mul_temp_0(15) ='0') AND (mul_temp_0(14 DOWNTO 7) /= "00000000")
    ELSE "10000000" WHEN (mul_temp_0(15) = '1') AND (mul_temp_0(14 DOWNTO 7) /= "11111111")
    ELSE mul_temp_0(7 DOWNTO 0);

    mul_temp_1 <= signed(x5) * signed(x6);
    
   y3 <= "01111111" WHEN (mul_temp_1(15) = '0') AND (mul_temp_1(14 DOWNTO 7) /= "00000000")
   ELSE "10000000" WHEN (mul_temp_1(15) = '1') AND (mul_temp_1(14 DOWNTO 7) /= "11111111")
   ELSE mul_temp_1(7 DOWNTO 0);

    mul_temp_2 <= signed(x7) * signed(x8);
    
    y4 <= "01111111" WHEN (mul_temp_2(15)= '0')AND (mul_temp_2(14 DOWNTO 7) /= "00000000")
    ELSE "10000000" WHEN (mul_temp_2(15) = '1') AND (mul_temp_2(14 DOWNTO 7) /= "11111111")
    ELSE mul_temp_2(7 DOWNTO 0);

    mul_temp_3 <= pipe_var_0_1 * b_pipe_var_0_1;
    
    y5 <= "01111111" WHEN (mul_temp_3(15) = '0') AND (mul_temp_3(14 DOWNTO 7)/= "00000000")
    ELSE "10000000" WHEN (mul_temp_3(15) = '1') AND (mul_temp_3(14 DOWNTO 7) /= "11111111")
    ELSE mul_temp_3(7 DOWNTO 0);

    mul_temp_4 <= c_pipe_var_0_1 * d_pipe_var_0_1;
    
    y6 <= "01111111" WHEN (mul_temp_4(15)='0') AND (mul_temp_4(14 DOWNTO 7) /= "00000000")
    ELSE "10000000" WHEN (mul_temp_4(15) = '1') AND (mul_temp_4(14 DOWNTO 7) /= "11111111")
    ELSE mul_temp_4(7 DOWNTO 0);

    mul_temp_5 <= pipe_var_1_2 * b_pipe_var_1_2;
    
    y <= "01111111" WHEN (mul_temp_5(15) = '0') AND (mul_temp_5(14 DOWNTO 7) /= "00000000")
    ELSE "10000000" WHEN (mul_temp_5(15) = '1') AND (mul_temp_5(14 DOWNTO 7) /= "11111111")
    ELSE std_logic_vector(mul_temp_5(7 DOWNTO 0));

    b_pipe_var_1_2_next <= y6;
    pipe_var_1_2_next <= y5;
    d_pipe_var_0_1_next <= y4;
    c_pipe_var_0_1_next <= y3;
    b_pipe_var_0_1_next <= y2;
    pipe_var_0_1_next <= y1;
END fsm_SFHDL;