cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Explorer
Explorer
237 Views
Registered: ‎11-22-2016

Coding style for Inferring DSP pattern detection?

Jump to solution

Is there a (VHDL) coding pattern in Vivado 2019.2 which will allow DSP pattern detection implementation to be inferred?  The alternative of explicitly instantiating the DSP48E1 is tiresome and somewhat error prone.

I've tried the attached, but without luck:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity test_dsp is
    Port (
        clk_i : in std_ulogic;
        a_i : in signed(17 downto 0);
        b_i : in signed(24 downto 0);
        c_o : out signed(42 downto 0);
        ones_o : out std_ulogic
    );
end test_dsp;

architecture arch of test_dsp is
    signal a_in : signed(17 downto 0);
    signal b_in : signed(24 downto 0);
    signal ab : signed(42 downto 0);
    signal ab_result : signed(42 downto 0);

    constant MASK : std_ulogic_vector(42 downto 0) := (
        42 downto 16 => '0',
        15 downto 0 => '1');
        
    function pdetect(
        mask : std_ulogic_vector; pattern : std_ulogic_vector)
        return std_ulogic
    is
        variable result : std_ulogic := '1';
    begin
        for i in mask'RANGE loop
            result := result and (mask(i) or pattern(i));
        end loop;
        return result;
    end;    

begin
    process (clk_i) begin
        if rising_edge(clk_i) then
            a_in <= a_i;
            b_in <= b_i;
            ab <= a_in * b_in;
            c_o <= ab;
            ones_o <= pdetect(MASK, std_ulogic_vector(ab));
        end if;
    end process;
end arch;
1 Solution

Accepted Solutions
Highlighted
Explorer
Explorer
157 Views
Registered: ‎11-22-2016

Re: Coding style for Inferring DSP pattern detection?

Jump to solution

Thank you, that example code gave me the direction I needed.  It seems that a very direct style of coding is needed, and it seems it's enough to write

all_ones <= ab(RANGE) = ONES_MASK;
all_zeros <= ab(RANGE) = 0;

where ab about to be assigned to the P register, to get the required inference to synthesise DSP pattern detection.

I've checked both with and without accumulator, the example code below now synthesises to exactly one DSP and one LUT (for the final ovf_o computation).  Perfect!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity test_dsp is
    port (
        clk_i : in std_ulogic;
        a_i : in signed(17 downto 0);
        b_i : in signed(24 downto 0);
        c_i : in signed(47 downto 0);
        p_o : out signed(47 downto 0);
        ovf_o : out std_ulogic
    );
end test_dsp;

architecture arch of test_dsp is
    signal a_in : signed(17 downto 0);
    signal b_in : signed(24 downto 0);
    signal c_in : signed(47 downto 0);
    signal ab : signed(42 downto 0);
    signal abc : signed(47 downto 0);

    subtype OVF_RANGE is natural range 47 downto 16;
    constant ONES_MASK : signed(OVF_RANGE) := (others => '1');
    signal all_ones : boolean;
    signal all_zeros : boolean;

begin
    process (clk_i) begin
        if rising_edge(clk_i) then
            a_in <= a_i;
            b_in <= b_i;
            c_in <= c_i;
            ab <= a_in * b_in;
            p_o <= abc;
            all_ones <= abc(OVF_RANGE) = ONES_MASK;
            all_zeros <= abc(OVF_RANGE) = 0;
        end if;
    end process;
    
    abc <= resize(ab, 48) + c_in;
    ovf_o <= '0' when all_ones or all_zeros else '1';
end arch;

 

View solution in original post

2 Replies
Highlighted
Teacher
Teacher
213 Views
Registered: ‎07-09-2009

Re: Coding style for Inferring DSP pattern detection?

Jump to solution
A good question

this doc, page 98
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_4/ug901-vivado-synthesis.pdf

uses the pattern detect to do a rounding,
dont know if its of any use, I'm interested in your results,
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Explorer
Explorer
158 Views
Registered: ‎11-22-2016

Re: Coding style for Inferring DSP pattern detection?

Jump to solution

Thank you, that example code gave me the direction I needed.  It seems that a very direct style of coding is needed, and it seems it's enough to write

all_ones <= ab(RANGE) = ONES_MASK;
all_zeros <= ab(RANGE) = 0;

where ab about to be assigned to the P register, to get the required inference to synthesise DSP pattern detection.

I've checked both with and without accumulator, the example code below now synthesises to exactly one DSP and one LUT (for the final ovf_o computation).  Perfect!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity test_dsp is
    port (
        clk_i : in std_ulogic;
        a_i : in signed(17 downto 0);
        b_i : in signed(24 downto 0);
        c_i : in signed(47 downto 0);
        p_o : out signed(47 downto 0);
        ovf_o : out std_ulogic
    );
end test_dsp;

architecture arch of test_dsp is
    signal a_in : signed(17 downto 0);
    signal b_in : signed(24 downto 0);
    signal c_in : signed(47 downto 0);
    signal ab : signed(42 downto 0);
    signal abc : signed(47 downto 0);

    subtype OVF_RANGE is natural range 47 downto 16;
    constant ONES_MASK : signed(OVF_RANGE) := (others => '1');
    signal all_ones : boolean;
    signal all_zeros : boolean;

begin
    process (clk_i) begin
        if rising_edge(clk_i) then
            a_in <= a_i;
            b_in <= b_i;
            c_in <= c_i;
            ab <= a_in * b_in;
            p_o <= abc;
            all_ones <= abc(OVF_RANGE) = ONES_MASK;
            all_zeros <= abc(OVF_RANGE) = 0;
        end if;
    end process;
    
    abc <= resize(ab, 48) + c_in;
    ovf_o <= '0' when all_ones or all_zeros else '1';
end arch;

 

View solution in original post