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

Subversion Repositories astron_adder

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /astron_adder/trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/common_add_sub.vhd
0,0 → 1,100
-------------------------------------------------------------------------------
--
-- 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, common_components_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
 
ENTITY common_add_sub IS
GENERIC (
g_direction : STRING := "ADD"; -- or "SUB", or "BOTH" and use sel_add
g_representation : STRING := "SIGNED"; -- or "UNSIGNED", important if g_out_dat_w > g_in_dat_w, not relevant if g_out_dat_w = g_in_dat_w
g_pipeline_input : NATURAL := 0; -- 0 or 1
g_pipeline_output : NATURAL := 1; -- >= 0
g_in_dat_w : NATURAL := 8;
g_out_dat_w : NATURAL := 9 -- only support g_out_dat_w=g_in_dat_w and g_out_dat_w=g_in_dat_w+1
);
PORT (
clk : IN STD_LOGIC;
clken : IN STD_LOGIC := '1';
sel_add : IN STD_LOGIC := '1'; -- only used for g_direction "BOTH"
in_a : IN STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
in_b : IN STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
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 common_components_lib.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;
common_add_sub.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: hdllib.cfg =================================================================== --- hdllib.cfg (nonexistent) +++ hdllib.cfg (revision 2) @@ -0,0 +1,21 @@ +hdl_lib_name = common_add_sub +hdl_library_clause_name = common_add_sub_lib +hdl_lib_uses_synth = common_pkg common_components +hdl_lib_uses_sim = +hdl_lib_technology = + +synth_files = + common_add_sub.vhd + +test_bench_files = + tb_common_add_sub.vhd + tb_tb_common_add_sub.vhd + +regression_test_vhdl = + tb_tb_common_add_sub.vhd + +[modelsim_project_file] +modelsim_copy_files = + +[quartus_project_file] +
hdllib.cfg Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tb_common_add_sub.vhd =================================================================== --- tb_common_add_sub.vhd (nonexistent) +++ tb_common_add_sub.vhd (revision 2) @@ -0,0 +1,177 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009 +-- ASTRON (Netherlands Institute for Radio Astronomy) +-- 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 . +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_pkg_lib, common_components_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_pkg_lib.common_pkg.ALL; + + +ENTITY tb_common_add_sub IS + GENERIC ( + g_direction : STRING := "SUB"; -- "SUB", "ADD" or "BOTH" + g_sel_add : STD_LOGIC :='1'; -- '0' = sub, '1' = add, only valid for g_direction = "BOTH" + g_pipeline_in : NATURAL := 0; -- input pipelining 0 or 1 + g_pipeline_out : NATURAL := 2; -- output pipelining >= 0 + g_in_dat_w : NATURAL := 5; + g_out_dat_w : NATURAL := 5 -- g_in_dat_w or g_in_dat_w+1 + ); +END tb_common_add_sub; + + +ARCHITECTURE tb OF tb_common_add_sub IS + + CONSTANT clk_period : TIME := 10 ns; + CONSTANT c_pipeline : NATURAL := g_pipeline_in + g_pipeline_out; + + FUNCTION func_result(in_a, in_b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS + VARIABLE v_a, v_b, v_result : INTEGER; + BEGIN + -- Calculate expected result + v_a := TO_SINT(in_a); + v_b := TO_SINT(in_b); + IF g_direction="ADD" THEN v_result := v_a + v_b; END IF; + IF g_direction="SUB" THEN v_result := v_a - v_b; END IF; + IF g_direction="BOTH" AND g_sel_add='1' THEN v_result := v_a + v_b; END IF; + IF g_direction="BOTH" AND g_sel_add='0' THEN v_result := v_a - v_b; END IF; + -- Wrap to avoid warning: NUMERIC_STD.TO_SIGNED: vector truncated + IF v_result > 2**(g_out_dat_w-1)-1 THEN v_result := v_result - 2**g_out_dat_w; END IF; + IF v_result < -2**(g_out_dat_w-1) THEN v_result := v_result + 2**g_out_dat_w; END IF; + RETURN TO_SVEC(v_result, g_out_dat_w); + END; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL rst : STD_LOGIC; + SIGNAL clk : STD_LOGIC := '0'; + 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 out_result : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); -- combinatorial result + SIGNAL result_expected : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); -- pipelined results + SIGNAL result_rtl : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); + +BEGIN + + clk <= NOT clk OR tb_end AFTER clk_period/2; + + -- run 1 us or -all + 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); + WAIT UNTIL rising_edge(clk); + FOR I IN 0 TO 9 LOOP + WAIT UNTIL rising_edge(clk); + END LOOP; + rst <= '0'; + FOR I IN 0 TO 9 LOOP + WAIT UNTIL rising_edge(clk); + END LOOP; + + -- Some special combinations + in_a <= TO_SVEC(2, g_in_dat_w); + in_b <= TO_SVEC(5, g_in_dat_w); + WAIT UNTIL rising_edge(clk); + in_a <= TO_SVEC(2, g_in_dat_w); + in_b <= TO_SVEC(-5, g_in_dat_w); + WAIT UNTIL rising_edge(clk); + in_a <= TO_SVEC(-3, g_in_dat_w); + in_b <= TO_SVEC(-9, g_in_dat_w); + WAIT UNTIL rising_edge(clk); + in_a <= TO_SVEC(-3, g_in_dat_w); + in_b <= TO_SVEC(9, g_in_dat_w); + WAIT UNTIL rising_edge(clk); + in_a <= TO_SVEC(11, g_in_dat_w); + in_b <= TO_SVEC(15, g_in_dat_w); + WAIT UNTIL rising_edge(clk); + in_a <= TO_SVEC(11, g_in_dat_w); + in_b <= TO_SVEC(-15, g_in_dat_w); + WAIT UNTIL rising_edge(clk); + in_a <= TO_SVEC(-11, g_in_dat_w); + in_b <= TO_SVEC(15, g_in_dat_w); + WAIT UNTIL rising_edge(clk); + in_a <= TO_SVEC(-11, g_in_dat_w); + in_b <= TO_SVEC(-15, g_in_dat_w); + WAIT UNTIL rising_edge(clk); + + FOR I IN 0 TO 49 LOOP + WAIT UNTIL rising_edge(clk); + END LOOP; + + -- 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; + WAIT UNTIL rising_edge(clk); + tb_end <= '1'; + WAIT; + END PROCESS; + + out_result <= func_result(in_a, in_b); + + u_result : 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_result, + out_dat => result_expected + ); + + u_dut_rtl : ENTITY work.common_add_sub + GENERIC MAP ( + g_direction => g_direction, + g_representation => "SIGNED", + g_pipeline_input => g_pipeline_in, + g_pipeline_output => g_pipeline_out, + g_in_dat_w => g_in_dat_w, + g_out_dat_w => g_out_dat_w + ) + PORT MAP ( + clk => clk, + clken => '1', + sel_add => g_sel_add, + in_a => in_a, + in_b => in_b, + result => result_rtl + ); + + p_verify : PROCESS(rst, clk) + BEGIN + IF rst='0' THEN + IF rising_edge(clk) THEN + ASSERT result_rtl = result_expected REPORT "Error: wrong RTL result" SEVERITY ERROR; + END IF; + END IF; + END PROCESS; + +END tb;
tb_common_add_sub.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tb_tb_common_add_sub.vhd =================================================================== --- tb_tb_common_add_sub.vhd (nonexistent) +++ tb_tb_common_add_sub.vhd (revision 2) @@ -0,0 +1,47 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009 +-- ASTRON (Netherlands Institute for Radio Astronomy) +-- 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 . +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + +ENTITY tb_tb_common_add_sub IS +END tb_tb_common_add_sub; + +ARCHITECTURE tb OF tb_tb_common_add_sub IS + SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' +BEGIN + -- g_direction : STRING := "SUB"; -- "SUB" or "ADD" + -- g_sel_add : STD_LOGIC :='1'; -- '0' = sub, '1' = add, only valid for g_direction = "BOTH" + -- g_pipeline_in : NATURAL := 0; -- input pipelining 0 or 1 + -- g_pipeline_out : NATURAL := 1; -- output pipelining >= 0 + -- g_in_dat_w : NATURAL := 5; + -- g_out_dat_w : NATURAL := 5; -- g_in_dat_w or g_in_dat_w+1 + + u_add_5_5 : ENTITY work.tb_common_add_sub GENERIC MAP ("ADD", '1', 0, 2, 5, 5); + u_add_5_6 : ENTITY work.tb_common_add_sub GENERIC MAP ("ADD", '1', 0, 2, 5, 6); + u_sub_5_5 : ENTITY work.tb_common_add_sub GENERIC MAP ("SUB", '0', 0, 2, 5, 5); + u_sub_5_6 : ENTITY work.tb_common_add_sub GENERIC MAP ("SUB", '0', 0, 2, 5, 6); + u_both_add_5_5 : ENTITY work.tb_common_add_sub GENERIC MAP ("BOTH", '1', 0, 2, 5, 5); + u_both_add_5_6 : ENTITY work.tb_common_add_sub GENERIC MAP ("BOTH", '1', 0, 2, 5, 6); + u_both_sub_5_5 : ENTITY work.tb_common_add_sub GENERIC MAP ("BOTH", '0', 0, 2, 5, 5); + u_both_sub_5_6 : ENTITY work.tb_common_add_sub GENERIC MAP ("BOTH", '0', 0, 2, 5, 6); + +END tb;
tb_tb_common_add_sub.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property

powered by: WebSVN 2.1.0

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