From 78ab02613536626242a1f1b0e81bb49e9421a868 Mon Sep 17 00:00:00 2001 From: Zanting <zanting> Date: Wed, 18 Nov 2015 11:18:06 +0000 Subject: [PATCH] Added Arria 10 multiplier components --- libraries/technology/mult/hdllib.cfg | 3 + .../technology/mult/tech_complex_mult.vhd | 57 ++++++++++ libraries/technology/mult/tech_mult.vhd | 44 ++++++++ .../mult/tech_mult_component_pkg.vhd | 101 +++++++++++++++++- 4 files changed, 200 insertions(+), 5 deletions(-) diff --git a/libraries/technology/mult/hdllib.cfg b/libraries/technology/mult/hdllib.cfg index 5fb5ca03e3..f68c58c85c 100644 --- a/libraries/technology/mult/hdllib.cfg +++ b/libraries/technology/mult/hdllib.cfg @@ -3,6 +3,9 @@ hdl_library_clause_name = tech_mult_lib hdl_lib_uses_synth = common technology ip_stratixiv_mult + ip_arria10_mult + ip_arria10_complex_mult + ip_arria10_complex_mult_rtl hdl_lib_uses_sim = hdl_lib_technology = diff --git a/libraries/technology/mult/tech_complex_mult.vhd b/libraries/technology/mult/tech_complex_mult.vhd index a22307f35b..6c7908a007 100644 --- a/libraries/technology/mult/tech_complex_mult.vhd +++ b/libraries/technology/mult/tech_complex_mult.vhd @@ -28,6 +28,10 @@ USE work.tech_mult_component_pkg.ALL; -- Declare IP libraries to ensure default binding in simulation. The IP library clause is ignored by synthesis. LIBRARY ip_stratixiv_mult_lib; +--LIBRARY ip_arria10_mult_lib; +--LIBRARY ip_arria10_mult_rtl_lib; +LIBRARY ip_arria10_complex_mult_altmult_complex_150; +LIBRARY ip_arria10_complex_mult_rtl_lib; ENTITY tech_complex_mult IS @@ -128,5 +132,58 @@ begin ); END GENERATE; + gen_ip_arria10_ip : IF (g_technology=c_tech_arria10 AND g_variant="IP") GENERATE + + -- Adapt DSP input widths + ar <= RESIZE_SVEC(in_ar, c_dsp_dat_w); + ai <= RESIZE_SVEC(in_ai, c_dsp_dat_w); + br <= RESIZE_SVEC(in_br, c_dsp_dat_w); + bi <= RESIZE_SVEC(in_bi, c_dsp_dat_w) WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), c_dsp_dat_w); + + u0 : ip_arria10_complex_mult + PORT MAP ( + aclr => rst, + clock => clk, + dataa_imag => ai, + dataa_real => ar, + datab_imag => bi, + datab_real => br, + ena => clken, + result_imag => mult_im, + result_real => mult_re + ); + + -- Back to true input widths and then resize for output width + result_re <= RESIZE_SVEC(mult_re, g_out_p_w); + result_im <= RESIZE_SVEC(mult_im, g_out_p_w); + + END GENERATE; + + gen_ip_arria10_rtl : IF (g_technology=c_tech_arria10 AND g_variant="RTL") GENERATE + u0 : ip_arria10_complex_mult_rtl + GENERIC MAP( + g_in_a_w => g_in_a_w, + g_in_b_w => g_in_b_w, + g_out_p_w => g_out_p_w, + g_conjugate_b => g_conjugate_b, + g_pipeline_input => g_pipeline_input, + g_pipeline_product => g_pipeline_product, + g_pipeline_adder => g_pipeline_adder, + g_pipeline_output => g_pipeline_output + ) + PORT MAP( + rst => rst, + clk => clk, + clken => clken, + in_ar => in_ar, + in_ai => in_ai, + in_br => in_br, + in_bi => in_bi, + result_re => result_re, + result_im => result_im + ); + END GENERATE; + + end str; diff --git a/libraries/technology/mult/tech_mult.vhd b/libraries/technology/mult/tech_mult.vhd index 505ba49caa..f1e57fa0cc 100644 --- a/libraries/technology/mult/tech_mult.vhd +++ b/libraries/technology/mult/tech_mult.vhd @@ -28,6 +28,7 @@ USE work.tech_mult_component_pkg.ALL; -- Declare IP libraries to ensure default binding in simulation. The IP library clause is ignored by synthesis. LIBRARY ip_stratixiv_mult_lib; +LIBRARY ip_arria10_mult_lib; ENTITY tech_mult IS @@ -106,6 +107,49 @@ begin ); END GENERATE; + gen_ip_arria10_ip : IF (g_technology=c_tech_arria10 AND g_variant="IP") GENERATE + u0 : ip_arria10_mult + GENERIC MAP( + g_in_a_w => g_in_a_w, + g_in_b_w => g_in_b_w, + g_out_p_w => g_out_p_w, + g_nof_mult => g_nof_mult, + g_pipeline_input => g_pipeline_input, + g_pipeline_product => g_pipeline_product, + g_pipeline_output => g_pipeline_output, + g_representation => g_representation + ) + PORT MAP( + clk => clk, + clken => clken, + in_a => in_a, + in_b => in_b, + out_p => prod + ); + END GENERATE; + + gen_ip_arria10_rtl : IF (g_technology=c_tech_arria10 AND g_variant="RTL") GENERATE + u0 : ip_arria10_mult_rtl + GENERIC MAP( + g_in_a_w => g_in_a_w, + g_in_b_w => g_in_b_w, + g_out_p_w => g_out_p_w, + g_nof_mult => g_nof_mult, + g_pipeline_input => g_pipeline_input, + g_pipeline_product => g_pipeline_product, + g_pipeline_output => g_pipeline_output, + g_representation => g_representation + ) + PORT MAP( + rst => rst, + clk => clk, + clken => clken, + in_a => in_a, + in_b => in_b, + out_p => prod + ); + END GENERATE; + gen_trunk : FOR I IN 0 TO g_nof_mult-1 GENERATE -- Truncate MSbits, also for signed (common_pkg.vhd for explanation of RESIZE_SVEC) out_p((I+1)*g_out_p_w-1 DOWNTO I*g_out_p_w) <= RESIZE_SVEC(prod((I+1)*c_prod_w-1 DOWNTO I*c_prod_w), g_out_p_w) WHEN g_representation="SIGNED" ELSE diff --git a/libraries/technology/mult/tech_mult_component_pkg.vhd b/libraries/technology/mult/tech_mult_component_pkg.vhd index efb07cd0a9..f3e4e4b2d9 100644 --- a/libraries/technology/mult/tech_mult_component_pkg.vhd +++ b/libraries/technology/mult/tech_mult_component_pkg.vhd @@ -72,6 +72,55 @@ PACKAGE tech_mult_component_pkg IS ); END COMPONENT; + ----------------------------------------------------------------------------- + -- mult arria 10 ip component + ----------------------------------------------------------------------------- + + COMPONENT ip_arria10_mult IS + GENERIC ( + g_in_a_w : POSITIVE := 18; -- Width of the data A port + g_in_b_w : POSITIVE := 18; -- Width of the data B port + g_out_p_w : POSITIVE := 36; -- Width of the result port + g_nof_mult : POSITIVE := 1; -- using 2 for 18x18, 4 for 9x9 may yield better results when inferring * is used + g_pipeline_input : NATURAL := 1; -- 0 or 1 + g_pipeline_product : NATURAL := 1; -- 0 or 1 + g_pipeline_output : NATURAL := 1; -- >= 0 + g_representation : STRING := "SIGNED" -- or "UNSIGNED" + ); + PORT ( + clk : IN STD_LOGIC; + clken : IN STD_LOGIC := '1'; + in_a : IN STD_LOGIC_VECTOR(g_nof_mult*g_in_a_w-1 DOWNTO 0); + in_b : IN STD_LOGIC_VECTOR(g_nof_mult*g_in_b_w-1 DOWNTO 0); + out_p : OUT STD_LOGIC_VECTOR(g_nof_mult*(g_in_a_w+g_in_b_w)-1 DOWNTO 0) + ); + END COMPONENT; + + ----------------------------------------------------------------------------- + -- mult arria 10 rtl component + ----------------------------------------------------------------------------- + + COMPONENT ip_arria10_mult_rtl IS + GENERIC ( + g_in_a_w : POSITIVE := 18; + g_in_b_w : POSITIVE := 18; + g_out_p_w : POSITIVE := 36; -- c_prod_w = g_in_a_w+g_in_b_w, use smaller g_out_p_w to truncate MSbits, or larger g_out_p_w to extend MSbits + g_nof_mult : POSITIVE := 1; -- using 2 for 18x18, 4 for 9x9 may yield better results when inferring * is used + g_pipeline_input : NATURAL := 1; -- 0 or 1 + g_pipeline_product : NATURAL := 1; -- 0 or 1 + g_pipeline_output : NATURAL := 1; -- >= 0 + g_representation : STRING := "SIGNED" -- or "UNSIGNED" + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + clken : IN STD_LOGIC := '1'; + in_a : IN STD_LOGIC_VECTOR(g_nof_mult*g_in_a_w-1 DOWNTO 0); + in_b : IN STD_LOGIC_VECTOR(g_nof_mult*g_in_b_w-1 DOWNTO 0); + out_p : OUT STD_LOGIC_VECTOR(g_nof_mult*(g_in_a_w+g_in_b_w)-1 DOWNTO 0) + ); + END COMPONENT; + ----------------------------------------------------------------------------- -- mult stratixiv ip component ----------------------------------------------------------------------------- @@ -94,9 +143,13 @@ PACKAGE tech_mult_component_pkg IS in_b : IN STD_LOGIC_VECTOR(g_nof_mult*g_in_b_w-1 DOWNTO 0); out_p : OUT STD_LOGIC_VECTOR(g_nof_mult*(g_in_a_w+g_in_b_w)-1 DOWNTO 0) ); - END COMPONENT; + END COMPONENT; + + ----------------------------------------------------------------------------- + -- mult stratixiv rtl component + ----------------------------------------------------------------------------- - COMPONENT ip_stratixiv_mult_rtl IS + COMPONENT ip_stratixiv_mult_rtl IS GENERIC ( g_in_a_w : POSITIVE := 18; g_in_b_w : POSITIVE := 18; @@ -115,14 +168,52 @@ PACKAGE tech_mult_component_pkg IS in_b : IN STD_LOGIC_VECTOR(g_nof_mult*g_in_b_w-1 DOWNTO 0); out_p : OUT STD_LOGIC_VECTOR(g_nof_mult*(g_in_a_w+g_in_b_w)-1 DOWNTO 0) ); - END COMPONENT; + END COMPONENT; ----------------------------------------------------------------------------- -- arria10 ip component ----------------------------------------------------------------------------- - + + COMPONENT ip_arria10_complex_mult is + PORT ( + dataa_real : in std_logic_vector(17 downto 0) := (others => '0'); -- complex_input.dataa_real + dataa_imag : in std_logic_vector(17 downto 0) := (others => '0'); -- .dataa_imag + datab_real : in std_logic_vector(17 downto 0) := (others => '0'); -- .datab_real + datab_imag : in std_logic_vector(17 downto 0) := (others => '0'); -- .datab_imag + clock : in std_logic := '0'; -- .clk + aclr : in std_logic := '0'; -- .aclr + ena : in std_logic := '0'; -- .ena + result_real : out std_logic_vector(35 downto 0); -- complex_output.result_real + result_imag : out std_logic_vector(35 downto 0) -- .result_imag + ); + END COMPONENT; + ----------------------------------------------------------------------------- -- arria10 rtl component ----------------------------------------------------------------------------- - + + COMPONENT ip_arria10_complex_mult_rtl IS + GENERIC ( + g_in_a_w : POSITIVE := 18; + g_in_b_w : POSITIVE := 18; + g_out_p_w : POSITIVE := 36; + g_conjugate_b : BOOLEAN := FALSE; + g_pipeline_input : NATURAL := 1; -- 0 or 1 + g_pipeline_product : NATURAL := 0; -- 0 or 1 + g_pipeline_adder : NATURAL := 1; -- 0 or 1 + g_pipeline_output : NATURAL := 1 -- >= 0 + ); + PORT ( + rst : IN STD_LOGIC := '0'; + clk : IN STD_LOGIC; + clken : IN STD_LOGIC := '1'; + in_ar : IN STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0); + in_ai : IN STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0); + in_br : IN STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0); + in_bi : IN STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0); + result_re : OUT STD_LOGIC_VECTOR(g_out_p_w-1 DOWNTO 0); + result_im : OUT STD_LOGIC_VECTOR(g_out_p_w-1 DOWNTO 0) + ); + END COMPONENT; + END tech_mult_component_pkg; -- GitLab