Skip to content
Snippets Groups Projects
Commit 1477216a authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Cleanup the tb.

parent ac6b53ce
No related branches found
No related tags found
1 merge request!147L2SDP-494
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
-- p_verify verifies that the instances of common_complex_mult all yield the -- p_verify verifies that the instances of common_complex_mult all yield the
-- expected results and ASSERTs an ERROR in case they differ. -- expected results and ASSERTs an ERROR in case they differ.
-- Usage: -- Usage:
-- > as 10 -- > as 12
-- > run -all -- signal tb_end will stop the simulation by stopping the clk -- > run -all -- signal tb_end will stop the simulation by stopping the clk
LIBRARY IEEE, common_lib, technology_lib, tech_mult_lib, ip_stratixiv_mult_lib; LIBRARY IEEE, common_lib, technology_lib, tech_mult_lib, ip_stratixiv_mult_lib;
...@@ -32,14 +32,15 @@ USE IEEE.numeric_std.ALL; ...@@ -32,14 +32,15 @@ USE IEEE.numeric_std.ALL;
USE technology_lib.technology_select_pkg.ALL; USE technology_lib.technology_select_pkg.ALL;
USE common_lib.common_pkg.ALL; USE common_lib.common_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL; USE common_lib.common_lfsr_sequences_pkg.ALL;
USE common_lib.common_str_pkg.ALL;
USE common_lib.tb_common_pkg.ALL; USE common_lib.tb_common_pkg.ALL;
ENTITY tb_common_complex_mult IS ENTITY tb_common_complex_mult IS
GENERIC ( GENERIC (
g_in_dat_w : NATURAL := 4; g_variant : STRING := "IP"; -- "RTL" or "IP"
g_out_dat_w : NATURAL := 8; -- g_in_dat_w*2 for multiply and +1 for adder g_in_dat_w : NATURAL := 18;
g_conjugate_b : BOOLEAN := FALSE; -- When FALSE p = a * b, else p = a * conj(b) g_conjugate_b : BOOLEAN := TRUE; -- When FALSE p = a * b, else p = a * conj(b)
g_pipeline_input : NATURAL := 1; g_pipeline_input : NATURAL := 1;
g_pipeline_product : NATURAL := 0; g_pipeline_product : NATURAL := 0;
g_pipeline_adder : NATURAL := 1; g_pipeline_adder : NATURAL := 1;
...@@ -53,9 +54,14 @@ ARCHITECTURE tb OF tb_common_complex_mult IS ...@@ -53,9 +54,14 @@ ARCHITECTURE tb OF tb_common_complex_mult IS
CONSTANT clk_period : TIME := 10 ns; CONSTANT clk_period : TIME := 10 ns;
CONSTANT c_pipeline : NATURAL := g_pipeline_input + g_pipeline_product + g_pipeline_adder + g_pipeline_output; CONSTANT c_pipeline : NATURAL := g_pipeline_input + g_pipeline_product + g_pipeline_adder + g_pipeline_output;
-- g_in_dat_w*2 for multiply and +1 for adder to fit largest im product value
CONSTANT c_out_dat_w : NATURAL := g_in_dat_w * 2 + 1;
CONSTANT c_max : INTEGER := 2**(g_in_dat_w-1)-1; CONSTANT c_max : INTEGER := 2**(g_in_dat_w-1)-1;
CONSTANT c_min : INTEGER := -2**(g_in_dat_w-1); CONSTANT c_min : INTEGER := -2**(g_in_dat_w-1);
CONSTANT c_small : INTEGER := smallest(5, c_max);
CONSTANT c_technology : NATURAL := c_tech_select_default; CONSTANT c_technology : NATURAL := c_tech_select_default;
SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL tb_end : STD_LOGIC := '0';
...@@ -64,25 +70,32 @@ ARCHITECTURE tb OF tb_common_complex_mult IS ...@@ -64,25 +70,32 @@ ARCHITECTURE tb OF tb_common_complex_mult IS
SIGNAL random : STD_LOGIC_VECTOR(14 DOWNTO 0) := (OTHERS=>'0'); -- use different lengths to have different random sequences SIGNAL random : STD_LOGIC_VECTOR(14 DOWNTO 0) := (OTHERS=>'0'); -- use different lengths to have different random sequences
-- Input
SIGNAL in_ar : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0); SIGNAL in_ar : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL in_ai : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0); SIGNAL in_ai : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL in_br : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0); SIGNAL in_br : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL in_bi : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0); SIGNAL in_bi : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL in_val : STD_LOGIC; -- in_val is only passed on to out_val SIGNAL in_val : STD_LOGIC; -- in_val is only passed on to out_val, not used by multiplier itself
SIGNAL result_val_expected : STD_LOGIC;
SIGNAL result_val_rtl : STD_LOGIC;
SIGNAL result_val_ip : STD_LOGIC;
SIGNAL out_result_re : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); -- combinatorial result
SIGNAL out_result_im : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
SIGNAL result_re_expected : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); -- pipelined results
SIGNAL result_re_rtl : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
SIGNAL result_re_ip : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
SIGNAL result_im_expected : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
SIGNAL result_im_rtl : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
SIGNAL result_im_ip : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
-- Results
-- . expected valid and DUT valid, only depends on in_val and c_pipeline
SIGNAL result_val_expected : STD_LOGIC;
SIGNAL result_val_dut : STD_LOGIC;
-- . product result
SIGNAL ref_result_re : STD_LOGIC_VECTOR(c_out_dat_w-1 DOWNTO 0); -- combinatorial result
SIGNAL ref_result_im : STD_LOGIC_VECTOR(c_out_dat_w-1 DOWNTO 0);
SIGNAL result_re_expected : STD_LOGIC_VECTOR(c_out_dat_w-1 DOWNTO 0); -- pipelined results
SIGNAL result_re_dut : STD_LOGIC_VECTOR(c_out_dat_w-1 DOWNTO 0);
SIGNAL result_im_expected : STD_LOGIC_VECTOR(c_out_dat_w-1 DOWNTO 0);
SIGNAL result_im_dut : STD_LOGIC_VECTOR(c_out_dat_w-1 DOWNTO 0);
-- Debug signals to view constant values in wave window
SIGNAL dbg_variant : STRING(g_variant'RANGE) := g_variant;
SIGNAL dbg_in_dat_w : NATURAL := g_in_dat_w;
SIGNAL dbg_conjugate_b : BOOLEAN := g_conjugate_b;
SIGNAL dbg_pipeline : NATURAL := c_pipeline;
BEGIN BEGIN
...@@ -101,34 +114,36 @@ BEGIN ...@@ -101,34 +114,36 @@ BEGIN
in_ai <= TO_SVEC(0, g_in_dat_w); in_ai <= TO_SVEC(0, g_in_dat_w);
in_bi <= TO_SVEC(0, g_in_dat_w); in_bi <= TO_SVEC(0, g_in_dat_w);
WAIT UNTIL rising_edge(clk); WAIT UNTIL rising_edge(clk);
FOR I IN 0 TO 9 LOOP proc_common_wait_some_cycles(clk, 10);
WAIT UNTIL rising_edge(clk);
END LOOP;
rst <= '0'; rst <= '0';
FOR I IN 0 TO 9 LOOP proc_common_wait_some_cycles(clk, 10);
WAIT UNTIL rising_edge(clk);
END LOOP;
-- Some special combinations -- Some more special combinations with max and min
in_ar <= TO_SVEC(2, g_in_dat_w);
in_ai <= TO_SVEC(4, g_in_dat_w);
in_br <= TO_SVEC(3, g_in_dat_w);
in_bi <= TO_SVEC(5, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC( c_max, g_in_dat_w); -- p*p - p*p + j ( p*p + p*p) = 0 + j 2pp or p*p + p*p + j (-p*p + p*p) = 2pp + j 0 in_ar <= TO_SVEC( c_max, g_in_dat_w); -- p*p - p*p + j ( p*p + p*p) = 0 + j 2pp or p*p + p*p + j (-p*p + p*p) = 2pp + j 0
in_ai <= TO_SVEC( c_max, g_in_dat_w); in_ai <= TO_SVEC( c_max, g_in_dat_w);
in_br <= TO_SVEC( c_max, g_in_dat_w); in_br <= TO_SVEC( c_max, g_in_dat_w);
in_bi <= TO_SVEC( c_max, g_in_dat_w); in_bi <= TO_SVEC( c_max, g_in_dat_w);
WAIT UNTIL rising_edge(clk); WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC( c_min, g_in_dat_w);
in_ai <= TO_SVEC( c_min, g_in_dat_w); -- Skip (c_min + j*c_min) * (c_min + j*c_min), because that just does not fit in 2*g_in_dat_w bits of complex multiplier
in_br <= TO_SVEC( c_min, g_in_dat_w); --in_ar <= TO_SVEC( c_min, g_in_dat_w);
in_bi <= TO_SVEC( c_min, g_in_dat_w); --in_ai <= TO_SVEC( c_min, g_in_dat_w);
WAIT UNTIL rising_edge(clk); --in_br <= TO_SVEC( c_min, g_in_dat_w);
in_ar <= TO_SVEC( c_max, g_in_dat_w); --in_bi <= TO_SVEC( c_min, g_in_dat_w);
in_ai <= TO_SVEC( c_max, g_in_dat_w); --WAIT UNTIL rising_edge(clk);
in_br <= TO_SVEC( c_min, g_in_dat_w);
in_bi <= TO_SVEC( c_min, g_in_dat_w); IF dbg_conjugate_b = FALSE THEN
in_ar <= TO_SVEC( c_max, g_in_dat_w);
in_ai <= TO_SVEC( c_max, g_in_dat_w);
in_br <= TO_SVEC( c_min, g_in_dat_w);
in_bi <= TO_SVEC( c_min, g_in_dat_w);
ELSE
in_ar <= TO_SVEC( c_min, g_in_dat_w);
in_ai <= TO_SVEC( c_min, g_in_dat_w);
in_br <= TO_SVEC( c_max, g_in_dat_w);
in_bi <= TO_SVEC( c_max, g_in_dat_w);
END IF;
WAIT UNTIL rising_edge(clk); WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC( c_max, g_in_dat_w); in_ar <= TO_SVEC( c_max, g_in_dat_w);
in_ai <= TO_SVEC( c_max, g_in_dat_w); in_ai <= TO_SVEC( c_max, g_in_dat_w);
...@@ -140,51 +155,85 @@ BEGIN ...@@ -140,51 +155,85 @@ BEGIN
in_br <= TO_SVEC(-c_max, g_in_dat_w); in_br <= TO_SVEC(-c_max, g_in_dat_w);
in_bi <= TO_SVEC(-c_max, g_in_dat_w); in_bi <= TO_SVEC(-c_max, g_in_dat_w);
WAIT UNTIL rising_edge(clk); WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC(0, g_in_dat_w);
in_br <= TO_SVEC(0, g_in_dat_w);
in_ai <= TO_SVEC(0, g_in_dat_w);
in_bi <= TO_SVEC(0, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
proc_common_wait_some_cycles(clk, 10);
FOR I IN 0 TO 49 LOOP -- Some special combinations close to max, min
WAIT UNTIL rising_edge(clk); in_ar <= TO_SVEC( c_max, g_in_dat_w);
END LOOP; in_ai <= TO_SVEC( c_max-1, g_in_dat_w);
in_br <= TO_SVEC( c_max-2, g_in_dat_w);
in_bi <= TO_SVEC( c_max-3, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC( c_min, g_in_dat_w);
in_ai <= TO_SVEC( c_min+1, g_in_dat_w);
in_br <= TO_SVEC( c_min+2, g_in_dat_w);
in_bi <= TO_SVEC( c_min+3, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC( c_max, g_in_dat_w);
in_ai <= TO_SVEC( c_max-1, g_in_dat_w);
in_br <= TO_SVEC( c_min+2, g_in_dat_w);
in_bi <= TO_SVEC( c_min+3, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC( c_max, g_in_dat_w);
in_ai <= TO_SVEC( c_max-1, g_in_dat_w);
in_br <= TO_SVEC(-c_max+2, g_in_dat_w);
in_bi <= TO_SVEC(-c_max+3, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC( c_min, g_in_dat_w);
in_ai <= TO_SVEC( c_min+1, g_in_dat_w);
in_br <= TO_SVEC(-c_max+2, g_in_dat_w);
in_bi <= TO_SVEC(-c_max+3, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
in_ar <= TO_SVEC(0, g_in_dat_w);
in_br <= TO_SVEC(0, g_in_dat_w);
in_ai <= TO_SVEC(0, g_in_dat_w);
in_bi <= TO_SVEC(0, g_in_dat_w);
WAIT UNTIL rising_edge(clk);
proc_common_wait_some_cycles(clk, 100);
-- All combinations -- Try all small combinations
FOR I IN -c_max TO c_max LOOP FOR I IN -c_small TO c_small LOOP
FOR J IN -c_max TO c_max LOOP FOR J IN -c_small TO c_small LOOP
FOR K IN -c_max TO c_max LOOP FOR K IN -c_small TO c_small LOOP
FOR L IN -c_max TO c_max LOOP FOR L IN -c_small TO c_small LOOP
in_ar <= TO_SVEC(I, g_in_dat_w); in_ar <= TO_SVEC(I, g_in_dat_w);
in_ai <= TO_SVEC(K, g_in_dat_w); in_ai <= TO_SVEC(K, g_in_dat_w);
in_br <= TO_SVEC(J, g_in_dat_w); in_br <= TO_SVEC(J, g_in_dat_w);
in_bi <= TO_SVEC(L, g_in_dat_w); in_bi <= TO_SVEC(L, g_in_dat_w);
WAIT UNTIL rising_edge(clk); WAIT UNTIL rising_edge(clk);
END LOOP; END LOOP;
proc_common_wait_some_cycles(clk, 10);
END LOOP; END LOOP;
proc_common_wait_some_cycles(clk, 100);
END LOOP; END LOOP;
END LOOP; proc_common_wait_some_cycles(clk, 1000);
FOR I IN 0 TO 49 LOOP
WAIT UNTIL rising_edge(clk);
END LOOP; END LOOP;
tb_end <= '1'; tb_end <= '1';
WAIT; WAIT;
END PROCESS; END PROCESS;
-- Expected combinatorial complex multiply out_result -- Expected combinatorial complex multiply ref_result
out_result_re <= func_complex_multiply(in_ar, in_ai, in_br, in_bi, g_conjugate_b, "RE", g_out_dat_w); ref_result_re <= func_complex_multiply(in_ar, in_ai, in_br, in_bi, g_conjugate_b, "RE", c_out_dat_w);
out_result_im <= func_complex_multiply(in_ar, in_ai, in_br, in_bi, g_conjugate_b, "IM", g_out_dat_w); ref_result_im <= func_complex_multiply(in_ar, in_ai, in_br, in_bi, g_conjugate_b, "IM", c_out_dat_w);
u_result_re : ENTITY common_lib.common_pipeline u_result_re : ENTITY common_lib.common_pipeline
GENERIC MAP ( GENERIC MAP (
g_representation => "SIGNED", g_representation => "SIGNED",
g_pipeline => c_pipeline, g_pipeline => c_pipeline,
g_reset_value => 0, g_reset_value => 0,
g_in_dat_w => g_out_dat_w, g_in_dat_w => c_out_dat_w,
g_out_dat_w => g_out_dat_w g_out_dat_w => c_out_dat_w
) )
PORT MAP ( PORT MAP (
rst => rst, rst => rst,
clk => clk, clk => clk,
clken => '1', clken => '1',
in_dat => out_result_re, in_dat => ref_result_re,
out_dat => result_re_expected out_dat => result_re_expected
); );
...@@ -193,14 +242,14 @@ BEGIN ...@@ -193,14 +242,14 @@ BEGIN
g_representation => "SIGNED", g_representation => "SIGNED",
g_pipeline => c_pipeline, g_pipeline => c_pipeline,
g_reset_value => 0, g_reset_value => 0,
g_in_dat_w => g_out_dat_w, g_in_dat_w => c_out_dat_w,
g_out_dat_w => g_out_dat_w g_out_dat_w => c_out_dat_w
) )
PORT MAP ( PORT MAP (
rst => rst, rst => rst,
clk => clk, clk => clk,
clken => '1', clken => '1',
in_dat => out_result_im, in_dat => ref_result_im,
out_dat => result_im_expected out_dat => result_im_expected
); );
...@@ -217,40 +266,13 @@ BEGIN ...@@ -217,40 +266,13 @@ BEGIN
out_dat => result_val_expected out_dat => result_val_expected
); );
u_dut_rtl : ENTITY work.common_complex_mult u_dut : ENTITY work.common_complex_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_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 => '1',
in_ar => in_ar,
in_ai => in_ai,
in_br => in_br,
in_bi => in_bi,
in_val => in_val,
out_pr => result_re_rtl,
out_pi => result_im_rtl,
out_val => result_val_rtl
);
u_dut_ip : ENTITY work.common_complex_mult
GENERIC MAP ( GENERIC MAP (
g_technology => c_technology, g_technology => c_technology,
g_variant => "IP", g_variant => g_variant,
g_in_a_w => g_in_dat_w, g_in_a_w => g_in_dat_w,
g_in_b_w => g_in_dat_w, g_in_b_w => g_in_dat_w,
g_out_p_w => g_out_dat_w, g_out_p_w => c_out_dat_w,
g_conjugate_b => g_conjugate_b, g_conjugate_b => g_conjugate_b,
g_pipeline_input => g_pipeline_input, g_pipeline_input => g_pipeline_input,
g_pipeline_product => g_pipeline_product, g_pipeline_product => g_pipeline_product,
...@@ -266,23 +288,18 @@ BEGIN ...@@ -266,23 +288,18 @@ BEGIN
in_br => in_br, in_br => in_br,
in_bi => in_bi, in_bi => in_bi,
in_val => in_val, in_val => in_val,
out_pr => result_re_ip, out_pr => result_re_dut,
out_pi => result_im_ip, out_pi => result_im_dut,
out_val => result_val_ip out_val => result_val_dut
); );
p_verify : PROCESS(rst, clk) p_verify : PROCESS(rst, clk)
BEGIN BEGIN
IF rst='0' THEN IF rst='0' THEN
IF rising_edge(clk) THEN IF rising_edge(clk) THEN
ASSERT result_re_rtl = result_re_expected REPORT "Error: RE wrong RTL result" SEVERITY ERROR; ASSERT result_re_dut = result_re_expected REPORT "Error: RE wrong result, " & slv_to_str(result_re_dut) & " /= " & slv_to_str(result_re_expected) SEVERITY ERROR;
ASSERT result_im_rtl = result_im_expected REPORT "Error: IM wrong RTL result" SEVERITY ERROR; ASSERT result_im_dut = result_im_expected REPORT "Error: IM wrong result, " & slv_to_str(result_im_dut) & " /= " & slv_to_str(result_im_expected) SEVERITY ERROR;
ASSERT result_val_rtl = result_val_expected REPORT "Error: VAL wrong RTL result" SEVERITY ERROR; ASSERT result_val_dut = result_val_expected REPORT "Error: VAL wrong result" SEVERITY ERROR;
ASSERT result_re_ip = result_re_expected REPORT "Error: RE wrong IP result" SEVERITY ERROR;
ASSERT result_im_ip = result_im_expected REPORT "Error: IM wrong IP result" SEVERITY ERROR;
ASSERT result_val_ip = result_val_expected REPORT "Error: VAL wrong IP result" SEVERITY ERROR;
END IF; END IF;
END IF; END IF;
END PROCESS; END PROCESS;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment