diff --git a/libraries/base/common/src/vhdl/common_add_sub.vhd b/libraries/base/common/src/vhdl/common_add_sub.vhd index 4f57613fc8281dfa8e90c1b975b2763eed568472..5d96cf43ffc6d3191450294b0c6e1a6e56d9b5c2 100644 --- a/libraries/base/common/src/vhdl/common_add_sub.vhd +++ b/libraries/base/common/src/vhdl/common_add_sub.vhd @@ -21,6 +21,7 @@ LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; +USE work.common_pkg.ALL; ENTITY common_add_sub IS GENERIC ( @@ -40,3 +41,60 @@ ENTITY common_add_sub IS result : OUT STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0) ); END common_add_sub; + +ARCHITECTURE str OF common_add_sub IS + + CONSTANT c_res_w : NATURAL := g_in_dat_w+1; + + SIGNAL in_a_p : STD_LOGIC_VECTOR(in_a'RANGE); + SIGNAL in_b_p : STD_LOGIC_VECTOR(in_b'RANGE); + + SIGNAL in_add : STD_LOGIC; + SIGNAL sel_add_p : STD_LOGIC; + + SIGNAL result_p : STD_LOGIC_VECTOR(c_res_w-1 DOWNTO 0); + +BEGIN + + in_add <= '1' WHEN g_direction="ADD" OR (g_direction="BOTH" AND sel_add='1') ELSE '0'; + + no_input_reg : IF g_pipeline_input=0 GENERATE -- wired input + in_a_p <= in_a; + in_b_p <= in_b; + sel_add_p <= in_add; + END GENERATE; + gen_input_reg : IF g_pipeline_input>0 GENERATE -- register input + p_reg : PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + IF clken='1' THEN + in_a_p <= in_a; + in_b_p <= in_b; + sel_add_p <= in_add; + END IF; + END IF; + END PROCESS; + END GENERATE; + + gen_signed : IF g_representation = "SIGNED" GENERATE + result_p <= ADD_SVEC(in_a_p, in_b_p, c_res_w) WHEN sel_add_p='1' ELSE SUB_SVEC(in_a_p, in_b_p, c_res_w); + END GENERATE; + gen_unsigned : IF g_representation = "UNSIGNED" GENERATE + result_p <= ADD_UVEC(in_a_p, in_b_p, c_res_w) WHEN sel_add_p='1' ELSE SUB_UVEC(in_a_p, in_b_p, c_res_w); + END GENERATE; + + u_output_pipe : ENTITY work.common_pipeline -- pipeline output + GENERIC MAP ( + g_representation => g_representation, + g_pipeline => g_pipeline_output, -- 0 for wires, >0 for register stages + g_in_dat_w => result'LENGTH, + g_out_dat_w => result'LENGTH + ) + PORT MAP ( + clk => clk, + clken => clken, + in_dat => result_p(result'RANGE), + out_dat => result + ); + +END str; \ No newline at end of file diff --git a/libraries/base/common/src/vhdl/common_adder_tree_a_str.vhd b/libraries/base/common/src/vhdl/common_adder_tree_a_str.vhd index 86d037d9f826c66bc3d20c0cca29d75d00892abf..0147ec1399d90228add04aecdfae607307058f7a 100644 --- a/libraries/base/common/src/vhdl/common_adder_tree_a_str.vhd +++ b/libraries/base/common/src/vhdl/common_adder_tree_a_str.vhd @@ -93,7 +93,7 @@ BEGIN -- Adder tree gen_stage : FOR j IN 0 TO c_nof_stages-1 GENERATE gen_add : FOR i IN 0 TO (c_N+(2**j)-1)/(2**(j+1)) - 1 GENERATE - u_addj : ENTITY work.common_add_sub(rtl) + u_addj : ENTITY work.common_add_sub GENERIC MAP ( g_direction => "ADD", g_representation => g_representation, diff --git a/libraries/base/common/src/vhdl/common_pkg.vhd b/libraries/base/common/src/vhdl/common_pkg.vhd index d86a8f196ca7ad2df25f5a9c59763eed79b1d68d..bdca0ff0e16a58ab65ed328435b3ed9eb8c5ebf7 100644 --- a/libraries/base/common/src/vhdl/common_pkg.vhd +++ b/libraries/base/common/src/vhdl/common_pkg.vhd @@ -333,7 +333,7 @@ PACKAGE common_pkg IS FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : UNSIGNED) RETURN STD_LOGIC_VECTOR; FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR; FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : SIGNED) RETURN STD_LOGIC_VECTOR; - -- Used in common_add_sub_a_rtl.vhd + -- Used in common_add_sub.vhd FUNCTION ADD_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR; -- l_vec + r_vec, treat slv operands as signed, slv output width is res_w FUNCTION SUB_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR; -- l_vec - r_vec, treat slv operands as signed, slv output width is res_w FUNCTION ADD_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR; -- l_vec + r_vec, treat slv operands as unsigned, slv output width is res_w