Distributed Pipeline Insertion for MATLAB Function Blocks

Overview

Distributed pipeline insertion is a special optimization for HDL code generated from MATLAB Function blocks or Stateflow® charts. Distributed pipeline insertion lets you achieve higher clock rates in your HDL applications, at the cost of some amount of latency caused by the introduction of pipeline registers.

For general information on distributed pipeline insertion, including limitations, see DistributedPipelining.

Distributed Pipelining in a Multiplier Chain

This example shows distributed pipeline insertion in a simple model that implements a chain of 5 multiplications.

To open the model, enter the following:

mpipe_multichain

The root level model contains a subsystem multi_chain. The multi_chain subsystem functions as the device under test (DUT) from which to generate HDL code. The subsystem drives a MATLAB Function block, mult8. The following figure shows the subsystem.

The following shows a chain of multiplications as coded in the mult8 MATLAB Function block:

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;

To apply distributed pipeline insertion to this block, use the HDL Properties dialog box for the mult8 block. Specify generation of two pipeline stages for the MATLAB Function block, and enable the distributed pipeline optimization:

In the Configuration Parameters dialog box, the top-level HDL Code Generation options specify that:

  • VHDL® code is generated from the subsystem mpipe_multchain/mult_chain.

  • HDL Coder™ will generate code and display the generated model.

The insertion of two pipeline stages into the generated HDL code results in a latency of two clock cycles. In the generated model, a delay of two clock cycles is inserted before the output of the mpipe_multchain/mult_chain/mult8 subsystem so that simulations of the model reflect the behavior of the generated HDL code. The following figure shows the inserted Delay block.

The following listing shows the complete architecture section of the generated code. Comments generated by HDL Coder indicate the pipeline register definitions.

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;
Was this topic helpful?