-------------------------------------------------------------------------------- -- Instantiate several modular multipliers (ch7) -- Generates random vectors and comparte resutls -- -- -------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE IEEE.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.numeric_std.ALL; USE ieee.std_logic_textio.ALL; use ieee.math_real.all; -- for UNIFORM, TRUNC USE std.textio.ALL; use work.classic_multiplier_parameters.all; ENTITY test_mult_comparac IS END test_mult_comparac; ARCHITECTURE behavior OF test_mult_comparac IS -- Component Declaration for the Unit Under Test (UUT1) COMPONENT interleaved_mult is PORT ( A, B: in std_logic_vector (M-1 downto 0); clk, reset, start: in std_logic; Z: out std_logic_vector (M-1 downto 0); done: out std_logic ); END COMPONENT; -- Component Declaration for the Unit Under Test (UUT2) COMPONENT classic_multiplication PORT( a : IN std_logic_vector(M-1 downto 0); b : IN std_logic_vector(M-1 downto 0); c : OUT std_logic_vector(M-1 downto 0) ); END COMPONENT; COMPONENT mastrovito_multiplication PORT( a : IN std_logic_vector(M-1 downto 0); b : IN std_logic_vector(M-1 downto 0); c : OUT std_logic_vector(M-1 downto 0) ); END COMPONENT; COMPONENT mastrovito_V2_multiplication PORT( a : IN std_logic_vector(M-1 downto 0); b : IN std_logic_vector(M-1 downto 0); c : OUT std_logic_vector(M-1 downto 0) ); END COMPONENT; COMPONENT montgomery_mult PORT ( A, B: in std_logic_vector (M-1 downto 0); clk, reset, start: in std_logic; Z: out std_logic_vector (M-1 downto 0); done: out std_logic ); END COMPONENT; COMPONENT montgomery_comb_mult PORT( a : IN std_logic_vector(M-1 downto 0); b : IN std_logic_vector(M-1 downto 0); c : OUT std_logic_vector(M-1 downto 0) ); END COMPONENT; -- Internal signals SIGNAL x, y, z, c, cM, cMv2, zMontg, r, zMontgAdj : std_logic_vector(M-1 downto 0) := (others=>'0'); SIGNAL montg_comb, f_x_f_montg, f_x_f_montg2,montg_comb_adj : std_logic_vector(M-1 downto 0) := (others=>'0'); SIGNAL clk, reset, start, done, done_Montg: std_logic; constant DELAY : time := 100 ns; constant PERIOD : time := 200 ns; constant DUTY_CYCLE : real := 0.5; constant OFFSET : time := 0 ns; constant NUMBER_TESTS: natural := 1000; BEGIN -- Instantiate the Unit Under Test (UUT) uut1: interleaved_mult PORT MAP(A => x, B => y, clk => clk, reset => reset, start => start, z => z, done => done); uut2: classic_multiplication PORT MAP( a => x, b => y, c => c ); uut3: mastrovito_multiplication PORT MAP( a => x, b => y, c => cM ); uut4: mastrovito_V2_multiplication PORT MAP( a => x, b => y, c => cMv2 ); uut5: montgomery_mult PORT MAP(A => x, B => y, clk => clk, reset => reset, start => start, z => zMontg, done => done_montg); r <= F; --2**K mod F = F adjM: classic_multiplication PORT MAP( a => zMontg, b => r, c => zMontgAdj ); uut6: montgomery_comb_mult PORT MAP( a => x, b => y, c => montg_comb ); adjMC1: classic_multiplication PORT MAP( a => r , b => r, c => f_x_f_montg ); uutMC2: montgomery_comb_mult PORT MAP( a => montg_comb, b => f_x_f_montg, c => montg_comb_adj ); PROCESS -- clock process for clk BEGIN WAIT for OFFSET; CLOCK_LOOP : LOOP clk <= '0'; WAIT FOR (PERIOD *(1.0 - DUTY_CYCLE)); clk <= '1'; WAIT FOR (PERIOD * DUTY_CYCLE); END LOOP CLOCK_LOOP; END PROCESS; tb_proc : PROCESS --generate values PROCEDURE gen_random(X : out std_logic_vector (M-1 DownTo 0); w: natural; s1, s2: inout Natural) IS VARIABLE i_x, aux: integer; VARIABLE rand: real; BEGIN aux := W/16; for i in 1 to aux loop UNIFORM(s1, s2, rand); i_x := INTEGER(TRUNC(rand * real(2**16))); x(i*16-1 downto (i-1)*16) := CONV_STD_LOGIC_VECTOR (i_x, 16); end loop; UNIFORM(s1, s2, rand); i_x := INTEGER(TRUNC(rand * real(2**(w-aux*16)))); x(w-1 downto aux*16) := CONV_STD_LOGIC_VECTOR (i_x, (w-aux*16)); END PROCEDURE; VARIABLE TX_LOC : LINE; VARIABLE TX_STR : String(1 to 4096); VARIABLE seed1, seed2: positive; VARIABLE i_x, i_y, i_p, i_z, i_yz_modp: integer; VARIABLE cycles, max_cycles, min_cycles, total_cycles: integer := 0; VARIABLE avg_cycles: real; VARIABLE initial_time, final_time: time; VARIABLE xx: std_logic_vector (M-1 DownTo 0) ; BEGIN min_cycles:= 2**20; start <= '0'; reset <= '1'; WAIT FOR PERIOD; reset <= '0'; WAIT FOR PERIOD; for I in 1 to NUMBER_TESTS loop gen_random(xx, M, seed1, seed2); x <= xx; gen_random(xx, M, seed1, seed2); y <= xx; start <= '1'; initial_time := now; WAIT FOR PERIOD; start <= '0'; wait until done_montg = '1'; final_time := now; cycles := (final_time - initial_time)/PERIOD; total_cycles := total_cycles+cycles; --ASSERT (FALSE) REPORT "Number of Cycles: " & integer'image(cycles) & " TotalCycles: " & integer'image(total_cycles) SEVERITY WARNING; if cycles > max_cycles then max_cycles:= cycles; end if; if cycles < min_cycles then min_cycles:= cycles; end if; WAIT FOR 2*PERIOD; IF ( c /= z or cM/=z or cMv2/=z or zMontgAdj/=z or montg_comb_adj/=z) THEN write(TX_LOC,string'("ERROR!!! C=")); write(TX_LOC, c); write(TX_LOC,string'("/= Z=")); write(TX_LOC, z); write(TX_LOC,string'("/= cM=")); write(TX_LOC, cm); write(TX_LOC,string'("/= cMv2=")); write(TX_LOC, cMv2); write(TX_LOC,string'("/= MontgAdj=")); write(TX_LOC, zMontgAdj); write(TX_LOC,string'(" (Montg=")); write(TX_LOC, zMontg); write(TX_LOC,string'(") /= MontgCombAdj=")); write(TX_LOC, montg_comb_adj); write(TX_LOC,string'(" (Montg comb=")); write(TX_LOC, montg_comb); write(TX_LOC,string'(") using: ( A =")); write(TX_LOC, x); write(TX_LOC, string'(", B =")); write(TX_LOC, y); write(TX_LOC, string'(", F = 1")); write(TX_LOC, F); write(TX_LOC, string'(" )")); TX_STR(TX_LOC.all'range) := TX_LOC.all; Deallocate(TX_LOC); ASSERT (FALSE) REPORT TX_STR SEVERITY ERROR; END IF; end loop; WAIT FOR DELAY; avg_cycles := real(total_cycles)/real(NUMBER_TESTS); ASSERT (FALSE) REPORT "Simulation successful!. MinCycles: " & integer'image(min_cycles) & " MaxCycles: " & integer'image(max_cycles) & " TotalCycles: " & integer'image(total_cycles) & " AvgCycles: " & real'image(avg_cycles) SEVERITY FAILURE; END PROCESS; END;