type major_rom_array_t is array(0 to 63) of decode_rom_t;
type minor_valid_array_t is array(0 to 1023) of std_ulogic;
type op_19_subop_array_t is array(0 to 7) of decode_rom_t;
- type op_30_subop_array_t is array(0 to 7) of decode_rom_t;
+ type op_30_subop_array_t is array(0 to 15) of decode_rom_t;
type op_31_subop_array_t is array(0 to 1023) of decode_rom_t;
type minor_rom_array_2_t is array(0 to 3) of decode_rom_t;
7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli
24 => (ALU, OP_OR, NONE, CONST_UI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori
25 => (ALU, OP_OR, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris
- 20 => (ALU, OP_RLWIMI, RA, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi
- 21 => (ALU, OP_RLWINM, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm
- 23 => (ALU, OP_RLWNM, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm
+ 20 => (ALU, OP_RLC, RA, CONST_SH32, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- rlwimi
+ 21 => (ALU, OP_RLC, NONE, CONST_SH32, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- rlwinm
+ 23 => (ALU, OP_RLC, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- rlwnm
38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb
39 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu
44 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth
constant decode_op_30_array : op_30_subop_array_t := (
-- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl
-- op in out A in out len ext pipe
- 2#010# => (ALU, OP_RLDIC, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),
- 2#000# => (ALU, OP_RLDICL, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),
- 2#001# => (ALU, OP_RLDICR, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),
- 2#011# => (ALU, OP_RLDIMI, RA, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),
- -- rldcl, rldcr
- 2#100# => (ALU, OP_RLDCX, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),
+ 2#0100# => (ALU, OP_RLC, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldic
+ 2#0101# => (ALU, OP_RLC, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldic
+ 2#0000# => (ALU, OP_RLCL, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldicl
+ 2#0001# => (ALU, OP_RLCL, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldicl
+ 2#0010# => (ALU, OP_RLCR, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldicr
+ 2#0011# => (ALU, OP_RLCR, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldicr
+ 2#0110# => (ALU, OP_RLC, RA, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldimi
+ 2#0111# => (ALU, OP_RLC, RA, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldimi
+ 2#1000# => (ALU, OP_RLCL, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldcl
+ 2#1001# => (ALU, OP_RLCR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldcr
others => illegal_inst
);
2#0010111010# => (ALU, OP_PRTYD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd
2#0010011010# => (ALU, OP_PRTYW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw
-- 2#0010000000# setb
- 2#0000011011# => (ALU, OP_SLD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld
- 2#0000011000# => (ALU, OP_SLW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw
- 2#1100011010# => (ALU, OP_SRAD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad
- 2#1100111010# => (ALU, OP_SRADI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi
- 2#1100111011# => (ALU, OP_SRADI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi
- 2#1100011000# => (ALU, OP_SRAW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw
- 2#1100111000# => (ALU, OP_SRAWI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi
- 2#1000011011# => (ALU, OP_SRD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd
- 2#1000011000# => (ALU, OP_SRW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw
+ 2#0000011011# => (ALU, OP_SHL, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld
+ 2#0000011000# => (ALU, OP_SHL, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- slw
+ 2#1100011010# => (ALU, OP_SHR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- srad
+ 2#1100111010# => (ALU, OP_SHR, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- sradi
+ 2#1100111011# => (ALU, OP_SHR, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- sradi
+ 2#1100011000# => (ALU, OP_SHR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- sraw
+ 2#1100111000# => (ALU, OP_SHR, NONE, CONST_SH32, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- srawi
+ 2#1000011011# => (ALU, OP_SHR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd
+ 2#1000011000# => (ALU, OP_SHR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- srw
2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx
2#0011110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux
2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx
variable v : Decode1ToDecode2Type;
variable majorop : major_opcode_t;
variable op_19_bits: std_ulogic_vector(2 downto 0);
- variable op_30_bits: std_ulogic_vector(2 downto 0);
begin
v := r;
end if;
elsif majorop = "011110" then
- v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 2))));
+ v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 1))));
elsif majorop = "111010" then
v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0))));
--- /dev/null
+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;