OpenCores
URL https://opencores.org/ocsvn/astron_multiplier/astron_multiplier/trunk

Subversion Repositories astron_multiplier

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /astron_multiplier
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/trunk/common_mult.vhd
0,0 → 1,132
-------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
 
LIBRARY ieee, common_pkg_lib, common_components_lib;
USE ieee.std_logic_1164.ALL;
--USE technology_lib.technology_select_pkg.ALL;
USE common_pkg_lib.common_pkg.ALL;
 
-- Function: Default one or more independent products dependent on g_nof_mult
--
-- If g_nof_mult = 2 then the input vectors are
-- a = a(1) & a(0) and b = b(1) & b(0)
-- and the independent products in the product vector will be:
-- p = a(1)*b(1) & a(0)*b(0)
--
-- Remarks:
-- . When g_out_p_w < g_in_a_w+g_in_b_w then the common_mult truncates the
-- MSbit of the product.
-- . For c_prod_w = g_in_a_w+g_in_b_w the full product range is preserved. Use
-- g_out_p_w = c_prod_w-1 to skip the double sign bit that is only needed
-- when the maximum positive product -2**(g_in_a_w-1) * -2**(g_in_b_w-1) has
-- to be represented, which is typically not needed in DSP.
 
ENTITY common_mult IS
GENERIC (
g_technology : NATURAL := 0;
g_variant : STRING := "IP";
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 := '0';
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);
in_val : IN STD_LOGIC := '1'; -- only propagate valid, not used internally
out_p : OUT STD_LOGIC_VECTOR(g_nof_mult*g_out_p_w-1 DOWNTO 0);
out_val : OUT STD_LOGIC
);
END common_mult;
 
ARCHITECTURE str OF common_mult IS
 
CONSTANT c_pipeline : NATURAL := g_pipeline_input + g_pipeline_product + g_pipeline_output;
-- Extra output pipelining using common_pipeline is only needed when g_pipeline_output > 1
CONSTANT c_pipeline_output : NATURAL := sel_a_b(g_pipeline_output>0, g_pipeline_output-1, 0);
 
SIGNAL result : STD_LOGIC_VECTOR(out_p'RANGE); -- stage dependent on g_pipeline_output being 0 or 1
 
BEGIN
 
u_mult : ENTITY work.tech_mult
GENERIC MAP(
g_technology => g_technology,
g_variant => g_variant,
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 => result
);
-- Propagate in_val with c_pipeline latency
u_out_val : ENTITY common_components_lib.common_pipeline_sl
GENERIC MAP (
g_pipeline => c_pipeline
)
PORT MAP (
rst => rst,
clk => clk,
clken => clken,
in_dat => in_val,
out_dat => out_val
);
 
------------------------------------------------------------------------------
-- Extra output pipelining
------------------------------------------------------------------------------
 
u_output_pipe : ENTITY common_components_lib.common_pipeline -- pipeline output
GENERIC MAP (
g_representation => g_representation,
g_pipeline => c_pipeline_output,
g_in_dat_w => result'LENGTH,
g_out_dat_w => result'LENGTH
)
PORT MAP (
rst => rst,
clk => clk,
clken => clken,
in_dat => STD_LOGIC_VECTOR(result),
out_dat => out_p
);
 
END str;
/trunk/hdllib.cfg
18,13 → 18,18
 
common_complex_mult.vhd
 
tech_mult.vhd
common_mult.vhd
 
test_bench_files =
tb_common_complex_mult.vhd
tb_common_mult.vhd
tb_tb_common_mult.vhd
 
regression_test_vhdl =
tb_common_complex_mult.vhd
tb_tb_common_mult.vhd
 
 
[modelsim_project_file]
 
 
/trunk/tb_common_mult.vhd
0,0 → 1,350
-------------------------------------------------------------------------------
--
-- Copyright (C) 2009
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
 
-- Purpose: Tb for common_mult architectures
-- Description:
-- The tb is self verifying.
-- Usage:
-- > as 10
-- > run -all
 
LIBRARY IEEE, common_pkg_lib, common_components_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
--USE technology_lib.technology_select_pkg.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE common_pkg_lib.tb_common_pkg.ALL;
 
 
ENTITY tb_common_mult IS
GENERIC (
g_in_dat_w : NATURAL := 7;
g_out_dat_w : NATURAL := 11; -- = 2*g_in_dat_w, or smaller to truncate MSbits, or larger to extend MSbits
g_nof_mult : NATURAL := 2;
g_pipeline_input : NATURAL := 1;
g_pipeline_product : NATURAL := 1;
g_pipeline_output : NATURAL := 1
);
END tb_common_mult;
 
ARCHITECTURE tb OF tb_common_mult IS
 
CONSTANT clk_period : TIME := 10 ns;
CONSTANT c_pipeline : NATURAL := g_pipeline_input + g_pipeline_product + g_pipeline_output;
CONSTANT c_nof_mult : NATURAL := 2; -- fixed
 
CONSTANT c_max_p : INTEGER := 2**(g_in_dat_w-1)-1;
CONSTANT c_min : INTEGER := -c_max_p;
CONSTANT c_max_n : INTEGER := -2**(g_in_dat_w-1);
 
CONSTANT c_technology : NATURAL := 0;
 
FUNCTION func_sresult(in_a, in_b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
CONSTANT c_res_w : NATURAL := 2*g_in_dat_w; -- use sufficiently large result width
VARIABLE v_a : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
VARIABLE v_b : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
VARIABLE v_result : SIGNED(c_res_w-1 DOWNTO 0);
BEGIN
-- Calculate expected result
v_a := RESIZE_SVEC(in_a, g_in_dat_w);
v_b := RESIZE_SVEC(in_b, g_in_dat_w);
v_result := RESIZE_NUM(SIGNED(v_a)*SIGNED(v_b), c_res_w);
RETURN RESIZE_SVEC(STD_LOGIC_VECTOR(v_result), g_out_dat_w); -- Truncate MSbits or sign extend MSBits
END;
 
FUNCTION func_uresult(in_a, in_b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
CONSTANT c_res_w : NATURAL := 2*g_in_dat_w; -- use sufficiently large result width
VARIABLE v_a : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
VARIABLE v_b : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
VARIABLE v_result : UNSIGNED(c_res_w-1 DOWNTO 0);
BEGIN
-- Calculate expected result
v_a := RESIZE_UVEC(in_a, g_in_dat_w);
v_b := RESIZE_UVEC(in_b, g_in_dat_w);
v_result := RESIZE_NUM(UNSIGNED(v_a)*UNSIGNED(v_b), c_res_w);
RETURN RESIZE_UVEC(STD_LOGIC_VECTOR(v_result), g_out_dat_w); -- Truncate MSbits or zero extend MSBits
END;
 
SIGNAL rst : STD_LOGIC;
SIGNAL clk : STD_LOGIC := '0';
SIGNAL tb_end : STD_LOGIC := '0';
 
-- Input signals
SIGNAL in_a : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL in_b : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL in_a_p : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL in_b_p : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
 
-- Product signals
SIGNAL sresult_expected : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); -- pipelined expected result
SIGNAL sresult_rtl : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
SIGNAL sresult_ip : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
SIGNAL uresult_expected : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); -- pipelined expected result
SIGNAL uresult_rtl : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
SIGNAL uresult_ip : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
 
-- auxiliary signals
SIGNAL in_a_arr : STD_LOGIC_VECTOR(g_nof_mult*g_in_dat_w-1 DOWNTO 0);
SIGNAL in_b_arr : STD_LOGIC_VECTOR(g_nof_mult*g_in_dat_w-1 DOWNTO 0);
SIGNAL out_sresult : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); -- combinatorial expected result
SIGNAL out_uresult : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); -- combinatorial expected result
SIGNAL sresult_arr_expected : STD_LOGIC_VECTOR(g_nof_mult*g_out_dat_w-1 DOWNTO 0);
SIGNAL uresult_arr_expected : STD_LOGIC_VECTOR(g_nof_mult*g_out_dat_w-1 DOWNTO 0);
SIGNAL sresult_arr_rtl : STD_LOGIC_VECTOR(g_nof_mult*g_out_dat_w-1 DOWNTO 0);
SIGNAL uresult_arr_rtl : STD_LOGIC_VECTOR(g_nof_mult*g_out_dat_w-1 DOWNTO 0);
SIGNAL sresult_arr_ip : STD_LOGIC_VECTOR(g_nof_mult*g_out_dat_w-1 DOWNTO 0);
SIGNAL uresult_arr_ip : STD_LOGIC_VECTOR(g_nof_mult*g_out_dat_w-1 DOWNTO 0);
 
BEGIN
 
clk <= NOT clk OR tb_end AFTER clk_period/2;
 
-- run 1 us
p_in_stimuli : PROCESS
BEGIN
rst <= '1';
in_a <= TO_SVEC(0, g_in_dat_w);
in_b <= TO_SVEC(0, g_in_dat_w);
proc_common_wait_some_cycles(clk, 10);
rst <= '0';
proc_common_wait_some_cycles(clk, 10);
 
-- Some special combinations
in_a <= TO_SVEC(2, g_in_dat_w);
in_b <= TO_SVEC(3, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_a <= TO_SVEC(c_max_p, g_in_dat_w); -- p*p = pp
in_b <= TO_SVEC(c_max_p, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_a <= TO_SVEC(c_max_n, g_in_dat_w); -- -p*-p = pp
in_b <= TO_SVEC(c_max_n, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_a <= TO_SVEC(c_max_p, g_in_dat_w); -- p*-p = = -pp
in_b <= TO_SVEC(c_max_n, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_a <= TO_SVEC(c_max_p, g_in_dat_w); -- p*(-p-1) = -pp - p
in_b <= TO_SVEC(c_min, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_a <= TO_SVEC(c_max_n, g_in_dat_w); -- -p*(-p-1) = pp + p
in_b <= TO_SVEC(c_min, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
 
proc_common_wait_some_cycles(clk, 50);
 
-- All combinations
FOR I IN -2**(g_in_dat_w-1) TO 2**(g_in_dat_w-1)-1 LOOP
FOR J IN -2**(g_in_dat_w-1) TO 2**(g_in_dat_w-1)-1 LOOP
in_a <= TO_SVEC(I, g_in_dat_w);
in_b <= TO_SVEC(J, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
END LOOP;
END LOOP;
 
proc_common_wait_some_cycles(clk, 50);
tb_end <= '1';
WAIT;
END PROCESS;
 
-- pipeline inputs to ease comparison in the Wave window
u_in_a_pipeline : ENTITY common_components_lib.common_pipeline
GENERIC MAP (
g_representation => "SIGNED",
g_pipeline => c_pipeline,
g_reset_value => 0,
g_in_dat_w => g_in_dat_w,
g_out_dat_w => g_in_dat_w
)
PORT MAP (
rst => rst,
clk => clk,
clken => '1',
in_dat => in_a,
out_dat => in_a_p
);
 
u_in_b_pipeline : ENTITY common_components_lib.common_pipeline
GENERIC MAP (
g_representation => "SIGNED",
g_pipeline => c_pipeline,
g_reset_value => 0,
g_in_dat_w => g_in_dat_w,
g_out_dat_w => g_in_dat_w
)
PORT MAP (
rst => rst,
clk => clk,
clken => '1',
in_dat => in_b,
out_dat => in_b_p
);
 
gen_wires : FOR I IN 0 TO g_nof_mult-1 GENERATE
-- use same input for all multipliers
in_a_arr((I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= in_a;
in_b_arr((I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= in_b;
-- calculate expected output only for one multiplier
out_sresult <= func_sresult(in_a, in_b);
out_uresult <= func_uresult(in_a, in_b);
-- copy the expected result for all multipliers
sresult_arr_expected((I+1)*g_out_dat_w-1 DOWNTO I*g_out_dat_w) <= sresult_expected;
uresult_arr_expected((I+1)*g_out_dat_w-1 DOWNTO I*g_out_dat_w) <= uresult_expected;
END GENERATE;
 
-- use mult(0) to observe result in Wave window
sresult_rtl <= sresult_arr_rtl(g_out_dat_w-1 DOWNTO 0);
uresult_rtl <= uresult_arr_rtl(g_out_dat_w-1 DOWNTO 0);
sresult_ip <= sresult_arr_ip(g_out_dat_w-1 DOWNTO 0);
uresult_ip <= uresult_arr_ip(g_out_dat_w-1 DOWNTO 0);
 
u_sresult : ENTITY common_components_lib.common_pipeline
GENERIC MAP (
g_representation => "SIGNED",
g_pipeline => c_pipeline,
g_reset_value => 0,
g_in_dat_w => g_out_dat_w,
g_out_dat_w => g_out_dat_w
)
PORT MAP (
rst => rst,
clk => clk,
clken => '1',
in_dat => out_sresult,
out_dat => sresult_expected
);
 
u_uresult : ENTITY common_components_lib.common_pipeline
GENERIC MAP (
g_representation => "UNSIGNED",
g_pipeline => c_pipeline,
g_reset_value => 0,
g_in_dat_w => g_out_dat_w,
g_out_dat_w => g_out_dat_w
)
PORT MAP (
rst => rst,
clk => clk,
clken => '1',
in_dat => out_uresult,
out_dat => uresult_expected
);
 
u_sdut_rtl : ENTITY work.common_mult
GENERIC MAP (
g_technology => c_technology,
g_variant => "RTL",
g_in_a_w => g_in_dat_w,
g_in_b_w => g_in_dat_w,
g_out_p_w => g_out_dat_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 => "SIGNED"
)
PORT MAP (
rst => '0',
clk => clk,
clken => '1',
in_a => in_a_arr,
in_b => in_b_arr,
out_p => sresult_arr_rtl
);
 
u_udut_rtl : ENTITY work.common_mult
GENERIC MAP (
g_technology => c_technology,
g_variant => "RTL",
g_in_a_w => g_in_dat_w,
g_in_b_w => g_in_dat_w,
g_out_p_w => g_out_dat_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 => "UNSIGNED"
)
PORT MAP (
rst => '0',
clk => clk,
clken => '1',
in_a => in_a_arr,
in_b => in_b_arr,
out_p => uresult_arr_rtl
);
 
u_sdut_ip : ENTITY work.common_mult
GENERIC MAP (
g_technology => c_technology,
g_variant => "IP",
g_in_a_w => g_in_dat_w,
g_in_b_w => g_in_dat_w,
g_out_p_w => g_out_dat_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 => "SIGNED"
)
PORT MAP (
rst => '0',
clk => clk,
clken => '1',
in_a => in_a_arr,
in_b => in_b_arr,
out_p => sresult_arr_ip
);
 
u_udut_ip : ENTITY work.common_mult
GENERIC MAP (
g_technology => c_technology,
g_variant => "IP",
g_in_a_w => g_in_dat_w,
g_in_b_w => g_in_dat_w,
g_out_p_w => g_out_dat_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 => "UNSIGNED"
)
PORT MAP (
rst => '0',
clk => clk,
clken => '1',
in_a => in_a_arr,
in_b => in_b_arr,
out_p => uresult_arr_ip
);
 
p_verify : PROCESS(rst, clk)
BEGIN
IF rst='0' THEN
IF rising_edge(clk) THEN
-- verify all multipliers in parallel
ASSERT sresult_arr_rtl = sresult_arr_expected REPORT "Error: wrong Signed RTL result" SEVERITY ERROR;
ASSERT uresult_arr_rtl = uresult_arr_expected REPORT "Error: wrong Unsigned RTL result" SEVERITY ERROR;
ASSERT sresult_arr_ip = sresult_arr_expected REPORT "Error: wrong Signed IP result" SEVERITY ERROR;
ASSERT uresult_arr_ip = uresult_arr_expected REPORT "Error: wrong Unsigned IP result" SEVERITY ERROR;
END IF;
END IF;
END PROCESS;
 
END tb;
/trunk/tb_tb_common_mult.vhd
0,0 → 1,59
-------------------------------------------------------------------------------
--
-- Copyright (C) 2009
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
 
-- Usage:
-- > as 3
-- > run -all
 
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
 
ENTITY tb_tb_common_mult IS
END tb_tb_common_mult;
 
ARCHITECTURE tb OF tb_tb_common_mult IS
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
-- g_in_dat_w : NATURAL := 7;
-- g_out_dat_w : NATURAL := 11; -- = 2*g_in_dat_w, or smaller to truncate MSbits, or larger to extend MSbits
-- g_nof_mult : NATURAL := 2;
-- g_pipeline_input : NATURAL := 1;
-- g_pipeline_product : NATURAL := 1;
-- g_pipeline_output : NATURAL := 1
-- Vary g_out_dat_w
u_mult_7_12_nof_2_pipe_1_1_1 : ENTITY work.tb_common_mult GENERIC MAP (7, 12, 2, 1, 1, 1); -- truncate extra bit
u_mult_7_13_nof_2_pipe_1_1_1 : ENTITY work.tb_common_mult GENERIC MAP (7, 13, 2, 1, 1, 1); -- truncate double sign bit
u_mult_7_14_nof_2_pipe_1_1_1 : ENTITY work.tb_common_mult GENERIC MAP (7, 14, 2, 1, 1, 1); -- preserve full product range
u_mult_7_15_nof_2_pipe_1_1_1 : ENTITY work.tb_common_mult GENERIC MAP (7, 15, 2, 1, 1, 1); -- extend product
-- Vary g_nof_mult
u_mult_7_11_nof_1_pipe_1_1_1 : ENTITY work.tb_common_mult GENERIC MAP (7, 11, 1, 1, 1, 1);
u_mult_7_11_nof_3_pipe_1_1_1 : ENTITY work.tb_common_mult GENERIC MAP (7, 11, 3, 1, 1, 1);
-- Vary g_pipeline_*
u_mult_7_11_nof_1_pipe_0_0_0 : ENTITY work.tb_common_mult GENERIC MAP (7, 11, 2, 0, 0, 0);
u_mult_7_11_nof_1_pipe_1_0_0 : ENTITY work.tb_common_mult GENERIC MAP (7, 11, 2, 1, 0, 0);
u_mult_7_11_nof_1_pipe_0_1_0 : ENTITY work.tb_common_mult GENERIC MAP (7, 11, 2, 0, 1, 0);
u_mult_7_11_nof_1_pipe_0_0_1 : ENTITY work.tb_common_mult GENERIC MAP (7, 11, 2, 0, 0, 1);
END tb;
/trunk/tech_mult.vhd
0,0 → 1,160
-------------------------------------------------------------------------------
--
-- Copyright (C) 2009
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
 
LIBRARY IEEE, common_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
--USE technology_lib.technology_pkg.ALL;
--USE technology_lib.technology_select_pkg.ALL;
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
GENERIC (
g_technology : NATURAL := 0;
g_variant : STRING := "IP";
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_out_p_w-1 DOWNTO 0)
);
END tech_mult;
 
ARCHITECTURE str of tech_mult is
 
-- When g_out_p_w < g_in_a_w+g_in_b_w then the LPM_MULT truncates the LSbits of the product. Therefore
-- define c_prod_w to be able to let common_mult truncate the LSBits of the product.
CONSTANT c_prod_w : NATURAL := g_in_a_w + g_in_b_w;
 
SIGNAL prod : STD_LOGIC_VECTOR(g_nof_mult*c_prod_w-1 DOWNTO 0);
 
begin
 
gen_ip_stratixiv_ip : IF (g_technology=0 AND g_variant="IP") GENERATE
u0 : ip_stratixiv_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_stratixiv_rtl : IF (g_technology=0 AND g_variant="RTL") GENERATE
u0 : ip_stratixiv_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_ip_arria10_ip : IF ((g_technology=c_tech_arria10 OR g_technology=c_tech_arria10_e3sge3 OR g_technology=c_tech_arria10_e1sg ) 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 OR g_technology=c_tech_arria10_e3sge3 OR g_technology=c_tech_arria10_e1sg ) 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
RESIZE_UVEC(prod((I+1)*c_prod_w-1 DOWNTO I*c_prod_w), g_out_p_w);
END GENERATE;
 
end str;
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.