You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			290 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			VHDL
		
	
			
		
		
	
	
			290 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			VHDL
		
	
| library vunit_lib;
 | |
| context vunit_lib.vunit_context;
 | |
| 
 | |
| library ieee;
 | |
| use ieee.std_logic_1164.all;
 | |
| use ieee.numeric_std.all;
 | |
| 
 | |
| library work;
 | |
| use work.common.all;
 | |
| use work.ppc_fx_insns.all;
 | |
| use work.insn_helpers.all;
 | |
| 
 | |
| library osvvm;
 | |
| use osvvm.RandomPkg.all;
 | |
| 
 | |
| entity rotator_tb is
 | |
|     generic (runner_cfg : string := runner_cfg_default);
 | |
| end rotator_tb;
 | |
| 
 | |
| architecture behave of rotator_tb is
 | |
|     constant clk_period: time := 10 ns;
 | |
|     signal ra, rs: std_ulogic_vector(63 downto 0);
 | |
|     signal shift: std_ulogic_vector(6 downto 0) := (others => '0');
 | |
|     signal insn: std_ulogic_vector(31 downto 0) := (others => '0');
 | |
|     signal is_32bit, right_shift, arith, clear_left, clear_right: std_ulogic := '0';
 | |
|     signal res: std_ulogic_vector(63 downto 0);
 | |
|     signal carry_out: std_ulogic;
 | |
|     signal extsw: std_ulogic;
 | |
| 
 | |
| begin
 | |
|     rotator_0: entity work.rotator
 | |
|         port map (
 | |
|             rs => rs,
 | |
|             ra => ra,
 | |
|             shift => shift,
 | |
|             insn => insn,
 | |
|             is_32bit => is_32bit,
 | |
|             right_shift => right_shift,
 | |
|             arith => arith,
 | |
|             clear_left => clear_left,
 | |
|             clear_right => clear_right,
 | |
|             sign_ext_rs => extsw,
 | |
|             result => res,
 | |
|             carry_out => carry_out
 | |
|         );
 | |
| 
 | |
|     stim_process: process
 | |
|         variable behave_ra: std_ulogic_vector(63 downto 0);
 | |
|         variable behave_ca_ra: std_ulogic_vector(64 downto 0);
 | |
|         variable rnd : RandomPType;
 | |
|     begin
 | |
|         rnd.InitSeed(stim_process'path_name);
 | |
|         
 | |
|         -- TODO: Consider making debug messages visible with a command line option
 | |
|         -- rather than uncommenting this line:
 | |
|         -- show(display_handler, debug);
 | |
|         
 | |
|         test_runner_setup(runner, runner_cfg);
 | |
| 
 | |
|         while test_suite loop
 | |
|             if run("Test rlw[i]nm") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '1';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '1';
 | |
|                 clear_right <= '1';
 | |
|                 extsw <= '0';
 | |
|                 rlwnm_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= rnd.RandSlv(7);
 | |
|                     insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_rlwinm(rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn));
 | |
|                     check_equal(res, behave_ra, result("for rlwnm"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test rlwimi") then
 | |
|                 is_32bit <= '1';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '1';
 | |
|                 clear_right <= '1';
 | |
|                 rlwimi_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     ra <= rnd.RandSlv(64);
 | |
|                     shift <= "00" & rnd.RandSlv(5);
 | |
|                     insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_rlwimi(ra, rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn));
 | |
|                     check_equal(res, behave_ra, result("for rlwnimi"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test rld[i]cl") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '0';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '1';
 | |
|                 clear_right <= '0';
 | |
|                 rldicl_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= rnd.RandSlv(7);
 | |
|                     insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_rldicl(rs, shift(5 downto 0), insn_mb(insn));
 | |
|                     check_equal(res, behave_ra, result("for rldicl"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test rld[i]cr") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '0';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '0';
 | |
|                 clear_right <= '1';
 | |
|                 rldicr_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= rnd.RandSlv(7);
 | |
|                     insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_rldicr(rs, shift(5 downto 0), insn_me(insn));
 | |
|                     debug("rs = " & to_hstring(rs));
 | |
|                     debug("ra = " & to_hstring(ra));
 | |
|                     debug("shift = " & to_hstring(shift));
 | |
|                     debug("insn me = " & to_hstring(insn_me(insn)));
 | |
|                     debug("result = " & to_hstring(res));
 | |
|                     check_equal(res, behave_ra, result("for rldicr"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test rldic") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '0';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '1';
 | |
|                 clear_right <= '1';
 | |
|                 rldic_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= '0' & rnd.RandSlv(6);
 | |
|                     insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_rldic(rs, shift(5 downto 0), insn_mb(insn));
 | |
|                     check_equal(res, behave_ra, result("for rldic"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test rldimi") then
 | |
|                 is_32bit <= '0';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '1';
 | |
|                 clear_right <= '1';
 | |
|                 rldimi_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     ra <= rnd.RandSlv(64);
 | |
|                     shift <= '0' & rnd.RandSlv(6);
 | |
|                     insn <= x"00000" & '0' & rnd.RandSlv(10) & '0';
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_rldimi(ra, rs, shift(5 downto 0), insn_mb(insn));
 | |
|                     check_equal(res, behave_ra, result("for rldimi"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test slw") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '1';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '0';
 | |
|                 clear_right <= '0';
 | |
|                 slw_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= rnd.RandSlv(7);
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_slw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | |
|                     check_equal(res, behave_ra, result("for slv"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test sld") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '0';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '0';
 | |
|                 clear_right <= '0';
 | |
|                 sld_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= rnd.RandSlv(7);
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_sld(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | |
|                     check_equal(res, behave_ra, result("for sld"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test srw") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '1';
 | |
|                 right_shift <= '1';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '0';
 | |
|                 clear_right <= '0';
 | |
|                 srw_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= rnd.RandSlv(7);
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_srw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | |
|                     check_equal(res, behave_ra, result("for srw"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test srd") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '0';
 | |
|                 right_shift <= '1';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '0';
 | |
|                 clear_right <= '0';
 | |
|                 srd_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= rnd.RandSlv(7);
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := ppc_srd(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | |
|                     check_equal(res, behave_ra, result("for srd"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test sraw[i]") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '1';
 | |
|                 right_shift <= '1';
 | |
|                 arith <= '1';
 | |
|                 clear_left <= '0';
 | |
|                 clear_right <= '0';
 | |
|                 sraw_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= '0' & rnd.RandSlv(6);
 | |
|                     wait for clk_period;
 | |
|                     behave_ca_ra := ppc_sraw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | |
|                     debug("rs = " & to_hstring(rs));
 | |
|                     debug("ra = " & to_hstring(ra));
 | |
|                     debug("shift = " & to_hstring(shift));
 | |
|                     debug("result = " & to_hstring(carry_out & res));
 | |
|                     check_equal(res, behave_ca_ra(63 downto 0), result("for sraw"));
 | |
|                     check_equal(carry_out, behave_ca_ra(64), result("for sraw carry_out"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test srad[i]") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '0';
 | |
|                 right_shift <= '1';
 | |
|                 arith <= '1';
 | |
|                 clear_left <= '0';
 | |
|                 clear_right <= '0';
 | |
|                 srad_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= rnd.RandSlv(7);
 | |
|                     wait for clk_period;
 | |
|                     behave_ca_ra := ppc_srad(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | |
|                     debug("rs = " & to_hstring(rs));
 | |
|                     debug("ra = " & to_hstring(ra));
 | |
|                     debug("shift = " & to_hstring(shift));
 | |
|                     debug("result = " & to_hstring(carry_out & res));
 | |
|                     check_equal(res, behave_ca_ra(63 downto 0), result("for srad"));
 | |
|                     check_equal(carry_out, behave_ca_ra(64), result("for srad carry_out"));
 | |
|                 end loop;
 | |
| 
 | |
|             elsif run("Test extswsli") then
 | |
|                 ra <= (others => '0');
 | |
|                 is_32bit <= '0';
 | |
|                 right_shift <= '0';
 | |
|                 arith <= '0';
 | |
|                 clear_left <= '0';
 | |
|                 clear_right <= '0';
 | |
|                 extsw <= '1';
 | |
|                 extswsli_loop : for i in 0 to 1000 loop
 | |
|                     rs <= rnd.RandSlv(64);
 | |
|                     shift <= '0' & rnd.RandSlv(6);
 | |
|                     wait for clk_period;
 | |
|                     behave_ra := rs;
 | |
|                     behave_ra(63 downto 32) := (others => rs(31));
 | |
|                     behave_ra := std_ulogic_vector(shift_left(unsigned(behave_ra),
 | |
|                                                               to_integer(unsigned(shift))));
 | |
|                     debug("rs = " & to_hstring(rs));
 | |
|                     debug("ra = " & to_hstring(ra));
 | |
|                     debug("shift = " & to_hstring(shift));
 | |
|                     debug("result = " & to_hstring(carry_out & res));
 | |
|                     check_equal(res, behave_ra, result("for extswsli"));
 | |
|                 end loop;
 | |
|             end if;
 | |
|         end loop;
 | |
|         test_runner_cleanup(runner);
 | |
|     end process;
 | |
| end behave;
 |