forked from cores/microwatt
				
			Add a rotate/mask/shift unit and use it in execute1
This adds a new entity 'rotator' which contains combinatorial logic for rotating and masking 64-bit values. It implements the operations of the rlwinm, rlwnm, rlwimi, rldicl, rldicr, rldic, rldimi, rldcl, rldcr, sld, slw, srd, srw, srad, sradi, sraw and srawi instructions. It consists of a 3-stage 64-bit rotator using 4:1 multiplexors at each stage, two mask generators, output logic and control logic. The insn_type_t values used for these instructions have been reduced to just 5: OP_RLC, OP_RLCL and OP_RLCR for the rotate and mask instructions (clear both left and right, clear left, clear right variants), OP_SHL for left shifts, and OP_SHR for right shifts. The control signals for the rotator are derived from the opcode and from the is_32bit and is_signed fields of the decode_rom_t. The rotator is instantiated as an entity in execute1 so that we can be sure we only have one of it. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>jtag-port
							parent
							
								
									90b6e27380
								
							
						
					
					
						commit
						f7c393ba7e
					
				@ -0,0 +1,183 @@
 | 
				
			|||||||
 | 
					library ieee;
 | 
				
			||||||
 | 
					use ieee.std_logic_1164.all;
 | 
				
			||||||
 | 
					use ieee.numeric_std.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					library work;
 | 
				
			||||||
 | 
					use work.common.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					entity rotator is
 | 
				
			||||||
 | 
					    port (rs: in std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
						  ra: in std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
						  shift: in std_ulogic_vector(6 downto 0);
 | 
				
			||||||
 | 
						  insn: in std_ulogic_vector(31 downto 0);
 | 
				
			||||||
 | 
						  is_32bit: in std_ulogic;
 | 
				
			||||||
 | 
						  right_shift: in std_ulogic;
 | 
				
			||||||
 | 
						  arith: in std_ulogic;
 | 
				
			||||||
 | 
						  clear_left: in std_ulogic;
 | 
				
			||||||
 | 
						  clear_right: in std_ulogic;
 | 
				
			||||||
 | 
						  result: out std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
						  carry_out: out std_ulogic
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					end entity rotator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					architecture behaviour of rotator is
 | 
				
			||||||
 | 
					    signal repl32: std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
					    signal rot_count: std_ulogic_vector(5 downto 0);
 | 
				
			||||||
 | 
					    signal rot1, rot2, rot: std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
					    signal sh, mb, me: std_ulogic_vector(6 downto 0);
 | 
				
			||||||
 | 
					    signal mr, ml: std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
					    signal output_mode: std_ulogic_vector(1 downto 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    -- note BE bit numbering
 | 
				
			||||||
 | 
					    function right_mask(mask_begin: std_ulogic_vector(6 downto 0)) return std_ulogic_vector is
 | 
				
			||||||
 | 
						variable ret: std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
					    begin
 | 
				
			||||||
 | 
						ret := (others => '0');
 | 
				
			||||||
 | 
						for i in 0 to 63 loop
 | 
				
			||||||
 | 
						    if i >= to_integer(unsigned(mask_begin)) then
 | 
				
			||||||
 | 
							ret(63 - i) := '1';
 | 
				
			||||||
 | 
						    end if;
 | 
				
			||||||
 | 
						end loop;
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					    end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function left_mask(mask_end: std_ulogic_vector(6 downto 0)) return std_ulogic_vector is
 | 
				
			||||||
 | 
						variable ret: std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
					    begin
 | 
				
			||||||
 | 
						ret := (others => '0');
 | 
				
			||||||
 | 
						if mask_end(6) = '0' then
 | 
				
			||||||
 | 
						    for i in 0 to 63 loop
 | 
				
			||||||
 | 
							if i <= to_integer(unsigned(mask_end)) then
 | 
				
			||||||
 | 
							    ret(63 - i) := '1';
 | 
				
			||||||
 | 
							end if;
 | 
				
			||||||
 | 
						    end loop;
 | 
				
			||||||
 | 
						end if;
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					    end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					    rotator_0: process(all)
 | 
				
			||||||
 | 
					    begin
 | 
				
			||||||
 | 
						-- First replicate bottom 32 bits to both halves if 32-bit
 | 
				
			||||||
 | 
						if is_32bit = '1' then
 | 
				
			||||||
 | 
						    repl32 <= rs(31 downto 0) & rs(31 downto 0);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    repl32 <= rs;
 | 
				
			||||||
 | 
						end if;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Negate shift count for right shifts
 | 
				
			||||||
 | 
						if right_shift = '1' then
 | 
				
			||||||
 | 
						    rot_count <= std_ulogic_vector(- signed(shift(5 downto 0)));
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    rot_count <= shift(5 downto 0);
 | 
				
			||||||
 | 
						end if;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Rotator works in 3 stages using 2 bits of the rotate count each
 | 
				
			||||||
 | 
						-- time.  This gives 4:1 multiplexors which is ideal for the 6-input
 | 
				
			||||||
 | 
						-- LUTs in the Xilinx Artix 7.
 | 
				
			||||||
 | 
						-- We look at the low bits of the rotate count first because they will
 | 
				
			||||||
 | 
						-- have less delay through the negation above.
 | 
				
			||||||
 | 
						-- First rotate by 0, 1, 2, or 3
 | 
				
			||||||
 | 
						case rot_count(1 downto 0) is
 | 
				
			||||||
 | 
						    when "00" =>
 | 
				
			||||||
 | 
							rot1 <= repl32;
 | 
				
			||||||
 | 
						    when "01" =>
 | 
				
			||||||
 | 
							rot1 <= repl32(62 downto 0) & repl32(63);
 | 
				
			||||||
 | 
						    when "10" =>
 | 
				
			||||||
 | 
							rot1 <= repl32(61 downto 0) & repl32(63 downto 62);
 | 
				
			||||||
 | 
						    when others =>
 | 
				
			||||||
 | 
							rot1 <= repl32(60 downto 0) & repl32(63 downto 61);
 | 
				
			||||||
 | 
						end case;
 | 
				
			||||||
 | 
						-- Next rotate by 0, 4, 8 or 12
 | 
				
			||||||
 | 
						case rot_count(3 downto 2) is
 | 
				
			||||||
 | 
						    when "00" =>
 | 
				
			||||||
 | 
							rot2 <= rot1;
 | 
				
			||||||
 | 
						    when "01" =>
 | 
				
			||||||
 | 
							rot2 <= rot1(59 downto 0) & rot1(63 downto 60);
 | 
				
			||||||
 | 
						    when "10" =>
 | 
				
			||||||
 | 
							rot2 <= rot1(55 downto 0) & rot1(63 downto 56);
 | 
				
			||||||
 | 
						    when others =>
 | 
				
			||||||
 | 
							rot2 <= rot1(51 downto 0) & rot1(63 downto 52);
 | 
				
			||||||
 | 
						end case;
 | 
				
			||||||
 | 
						-- Lastly rotate by 0, 16, 32 or 48
 | 
				
			||||||
 | 
						case rot_count(5 downto 4) is
 | 
				
			||||||
 | 
						    when "00" =>
 | 
				
			||||||
 | 
							rot <= rot2;
 | 
				
			||||||
 | 
						    when "01" =>
 | 
				
			||||||
 | 
							rot <= rot2(47 downto 0) & rot2(63 downto 48);
 | 
				
			||||||
 | 
						    when "10" =>
 | 
				
			||||||
 | 
							rot <= rot2(31 downto 0) & rot2(63 downto 32);
 | 
				
			||||||
 | 
						    when others =>
 | 
				
			||||||
 | 
							rot <= rot2(15 downto 0) & rot2(63 downto 16);
 | 
				
			||||||
 | 
						end case;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Trim shift count to 6 bits for 32-bit shifts
 | 
				
			||||||
 | 
						sh <= (shift(6) and not is_32bit) & shift(5 downto 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Work out mask begin/end indexes (caution, big-endian bit numbering)
 | 
				
			||||||
 | 
						if clear_left = '1' then
 | 
				
			||||||
 | 
						    if is_32bit = '1' then
 | 
				
			||||||
 | 
							mb <= "01" & insn(10 downto 6);
 | 
				
			||||||
 | 
						    else
 | 
				
			||||||
 | 
							mb <= "0" & insn(5) & insn(10 downto 6);
 | 
				
			||||||
 | 
						    end if;
 | 
				
			||||||
 | 
						elsif right_shift = '1' then
 | 
				
			||||||
 | 
						    -- this is basically mb <= sh + (is_32bit? 32: 0);
 | 
				
			||||||
 | 
						    if is_32bit = '1' then
 | 
				
			||||||
 | 
							mb <= sh(5) & not sh(5) & sh(4 downto 0);
 | 
				
			||||||
 | 
						    else
 | 
				
			||||||
 | 
							mb <= sh;
 | 
				
			||||||
 | 
						    end if;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    mb <= ('0' & is_32bit & "00000");
 | 
				
			||||||
 | 
						end if;
 | 
				
			||||||
 | 
						if clear_right = '1' and is_32bit = '1' then
 | 
				
			||||||
 | 
						    me <= "01" & insn(5 downto 1);
 | 
				
			||||||
 | 
						elsif clear_right = '1' and clear_left = '0' then
 | 
				
			||||||
 | 
						    me <= "0" & insn(5) & insn(10 downto 6);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    -- effectively, 63 - sh
 | 
				
			||||||
 | 
						    me <= sh(6) & not sh(5 downto 0);
 | 
				
			||||||
 | 
						end if;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Calculate left and right masks
 | 
				
			||||||
 | 
						mr <= right_mask(mb);
 | 
				
			||||||
 | 
						ml <= left_mask(me);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Work out output mode
 | 
				
			||||||
 | 
						-- 00 for sl[wd]
 | 
				
			||||||
 | 
						-- 0w for rlw*, rldic, rldicr, rldimi, where w = 1 iff mb > me
 | 
				
			||||||
 | 
						-- 10 for rldicl, sr[wd]
 | 
				
			||||||
 | 
						-- 1z for sra[wd][i], z = 1 if rs is negative
 | 
				
			||||||
 | 
						if (clear_left = '1' and clear_right = '0') or right_shift = '1' then
 | 
				
			||||||
 | 
						    output_mode(1) <= '1';
 | 
				
			||||||
 | 
						    output_mode(0) <= arith and repl32(63);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    output_mode(1) <= '0';
 | 
				
			||||||
 | 
						    if clear_right = '1' and unsigned(mb(5 downto 0)) > unsigned(me(5 downto 0)) then
 | 
				
			||||||
 | 
							output_mode(0) <= '1';
 | 
				
			||||||
 | 
						    else
 | 
				
			||||||
 | 
							output_mode(0) <= '0';
 | 
				
			||||||
 | 
						    end if;
 | 
				
			||||||
 | 
						end if;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Generate output from rotated input and masks
 | 
				
			||||||
 | 
						case output_mode is
 | 
				
			||||||
 | 
						    when "00" =>
 | 
				
			||||||
 | 
							result <= (rot and (mr and ml)) or (ra and not (mr and ml));
 | 
				
			||||||
 | 
						    when "01" =>
 | 
				
			||||||
 | 
							result <= (rot and (mr or ml)) or (ra and not (mr or ml));
 | 
				
			||||||
 | 
						    when "10" =>
 | 
				
			||||||
 | 
							result <= rot and mr;
 | 
				
			||||||
 | 
						    when others =>
 | 
				
			||||||
 | 
							result <= rot or not mr;
 | 
				
			||||||
 | 
						end case;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Generate carry output for arithmetic shift right of negative value
 | 
				
			||||||
 | 
						if output_mode = "11" then
 | 
				
			||||||
 | 
						    carry_out <= or (rs and not ml);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    carry_out <= '0';
 | 
				
			||||||
 | 
						end if;
 | 
				
			||||||
 | 
					    end process;
 | 
				
			||||||
 | 
					end behaviour;
 | 
				
			||||||
@ -0,0 +1,269 @@
 | 
				
			|||||||
 | 
					library ieee;
 | 
				
			||||||
 | 
					use ieee.std_logic_1164.all;
 | 
				
			||||||
 | 
					use ieee.numeric_std.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					library work;
 | 
				
			||||||
 | 
					use work.common.all;
 | 
				
			||||||
 | 
					use work.glibc_random.all;
 | 
				
			||||||
 | 
					use work.ppc_fx_insns.all;
 | 
				
			||||||
 | 
					use work.insn_helpers.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					entity rotator_tb is
 | 
				
			||||||
 | 
					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 result: std_ulogic_vector(63 downto 0);
 | 
				
			||||||
 | 
					    signal carry_out: 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,
 | 
				
			||||||
 | 
						    result => result,
 | 
				
			||||||
 | 
						    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);
 | 
				
			||||||
 | 
					    begin
 | 
				
			||||||
 | 
						-- rlwinm, rlwnm
 | 
				
			||||||
 | 
					        report "test rlw[i]nm";
 | 
				
			||||||
 | 
						ra <= (others => '0');
 | 
				
			||||||
 | 
						is_32bit <= '1';
 | 
				
			||||||
 | 
						right_shift <= '0';
 | 
				
			||||||
 | 
						arith <= '0';
 | 
				
			||||||
 | 
						clear_left <= '1';
 | 
				
			||||||
 | 
						clear_right <= '1';
 | 
				
			||||||
 | 
					        rlwnm_loop : for i in 0 to 1000 loop
 | 
				
			||||||
 | 
						    rs <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= pseudorand(7);
 | 
				
			||||||
 | 
						    insn <= x"00000" & '0' & pseudorand(10) & '0';
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_rlwinm(rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad rlwnm expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- rlwimi
 | 
				
			||||||
 | 
					        report "test rlwimi";
 | 
				
			||||||
 | 
						is_32bit <= '1';
 | 
				
			||||||
 | 
						right_shift <= '0';
 | 
				
			||||||
 | 
						arith <= '0';
 | 
				
			||||||
 | 
						clear_left <= '1';
 | 
				
			||||||
 | 
						clear_right <= '1';
 | 
				
			||||||
 | 
					        rlwimi_loop : for i in 0 to 1000 loop
 | 
				
			||||||
 | 
						    rs <= pseudorand(64);
 | 
				
			||||||
 | 
						    ra <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= "00" & pseudorand(5);
 | 
				
			||||||
 | 
						    insn <= x"00000" & '0' & pseudorand(10) & '0';
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_rlwimi(ra, rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad rlwimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- rldicl, rldcl
 | 
				
			||||||
 | 
					        report "test rld[i]cl";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= pseudorand(7);
 | 
				
			||||||
 | 
						    insn <= x"00000" & '0' & pseudorand(10) & '0';
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_rldicl(rs, shift(5 downto 0), insn_mb(insn));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad rldicl expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- rldicr, rldcr
 | 
				
			||||||
 | 
					        report "test rld[i]cr";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= pseudorand(7);
 | 
				
			||||||
 | 
						    insn <= x"00000" & '0' & pseudorand(10) & '0';
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_rldicr(rs, shift(5 downto 0), insn_me(insn));
 | 
				
			||||||
 | 
						    --report "rs = " & to_hstring(rs);
 | 
				
			||||||
 | 
						    --report "ra = " & to_hstring(ra);
 | 
				
			||||||
 | 
						    --report "shift = " & to_hstring(shift);
 | 
				
			||||||
 | 
						    --report "insn me = " & to_hstring(insn_me(insn));
 | 
				
			||||||
 | 
						    --report "result = " & to_hstring(result);
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad rldicr expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- rldic
 | 
				
			||||||
 | 
					        report "test rldic";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= '0' & pseudorand(6);
 | 
				
			||||||
 | 
						    insn <= x"00000" & '0' & pseudorand(10) & '0';
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_rldic(rs, shift(5 downto 0), insn_mb(insn));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad rldic expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- rldimi
 | 
				
			||||||
 | 
					        report "test rldimi";
 | 
				
			||||||
 | 
						is_32bit <= '0';
 | 
				
			||||||
 | 
						right_shift <= '0';
 | 
				
			||||||
 | 
						arith <= '0';
 | 
				
			||||||
 | 
						clear_left <= '1';
 | 
				
			||||||
 | 
						clear_right <= '1';
 | 
				
			||||||
 | 
					        rldimi_loop : for i in 0 to 1000 loop
 | 
				
			||||||
 | 
						    rs <= pseudorand(64);
 | 
				
			||||||
 | 
						    ra <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= '0' & pseudorand(6);
 | 
				
			||||||
 | 
						    insn <= x"00000" & '0' & pseudorand(10) & '0';
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_rldimi(ra, rs, shift(5 downto 0), insn_mb(insn));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad rldimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- slw
 | 
				
			||||||
 | 
					        report "test slw";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= pseudorand(7);
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_slw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad slw expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- sld
 | 
				
			||||||
 | 
					        report "test sld";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= pseudorand(7);
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_sld(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad sld expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- srw
 | 
				
			||||||
 | 
					        report "test srw";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= pseudorand(7);
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_srw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad srw expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- srd
 | 
				
			||||||
 | 
					        report "test srd";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= pseudorand(7);
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ra := ppc_srd(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | 
				
			||||||
 | 
						    assert behave_ra = result
 | 
				
			||||||
 | 
							report "bad srd expected " & to_hstring(behave_ra) & " got " & to_hstring(result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- sraw[i]
 | 
				
			||||||
 | 
					        report "test sraw[i]";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= '0' & pseudorand(6);
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ca_ra := ppc_sraw(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | 
				
			||||||
 | 
						    --report "rs = " & to_hstring(rs);
 | 
				
			||||||
 | 
						    --report "ra = " & to_hstring(ra);
 | 
				
			||||||
 | 
						    --report "shift = " & to_hstring(shift);
 | 
				
			||||||
 | 
						    --report "result = " & to_hstring(carry_out & result);
 | 
				
			||||||
 | 
						    assert behave_ca_ra(63 downto 0) = result and behave_ca_ra(64) = carry_out
 | 
				
			||||||
 | 
							report "bad sraw expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- srad[i]
 | 
				
			||||||
 | 
					        report "test srad[i]";
 | 
				
			||||||
 | 
						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 <= pseudorand(64);
 | 
				
			||||||
 | 
						    shift <= pseudorand(7);
 | 
				
			||||||
 | 
						    wait for clk_period;
 | 
				
			||||||
 | 
						    behave_ca_ra := ppc_srad(rs, std_ulogic_vector(resize(unsigned(shift), 64)));
 | 
				
			||||||
 | 
						    --report "rs = " & to_hstring(rs);
 | 
				
			||||||
 | 
						    --report "ra = " & to_hstring(ra);
 | 
				
			||||||
 | 
						    --report "shift = " & to_hstring(shift);
 | 
				
			||||||
 | 
						    --report "result = " & to_hstring(carry_out & result);
 | 
				
			||||||
 | 
						    assert behave_ca_ra(63 downto 0) = result and behave_ca_ra(64) = carry_out
 | 
				
			||||||
 | 
							report "bad srad expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result);
 | 
				
			||||||
 | 
					        end loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert false report "end of test" severity failure;
 | 
				
			||||||
 | 
					        wait;
 | 
				
			||||||
 | 
					    end process;
 | 
				
			||||||
 | 
					end behave;
 | 
				
			||||||
					Loading…
					
					
				
		Reference in New Issue