diff --git a/decode1.vhdl b/decode1.vhdl index 214285e..ae3e970 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -398,6 +398,17 @@ begin -- major opcode 31, lots of things v.decode := decode_op_31_array(to_integer(unsigned(f_in.insn(10 downto 1)))); + -- Work out ispr1/ispr2 independent of v.decode since they seem to be critical path + sprn := decode_spr_num(f_in.insn); + v.ispr1 := fast_spr_num(sprn); + + elsif majorop = "010000" then + -- CTR may be needed as input to bc + v.decode := major_decode_rom_array(to_integer(majorop)); + if f_in.insn(23) = '0' then + v.ispr1 := fast_spr_num(SPR_CTR); + end if; + elsif majorop = "010011" then if decode_op_19_valid(to_integer(unsigned(f_in.insn(10 downto 1)))) = '0' then report "op 19 illegal subcode"; @@ -408,6 +419,27 @@ begin report "op 19 sub " & to_hstring(op_19_bits); end if; + -- Work out ispr1/ispr2 independent of v.decode since they seem to be critical path + if f_in.insn(2) = '0' then + -- Could be OP_BCREG: bclr, bcctr, bctar + -- Branch uses CTR as condition when BO(2) is 0. This is + -- also used to indicate that CTR is modified (they go + -- together). + if f_in.insn(23) = '0' then + v.ispr1 := fast_spr_num(SPR_CTR); + end if; + -- TODO: Add TAR + if f_in.insn(10) = '0' then + v.ispr2 := fast_spr_num(SPR_LR); + else + v.ispr2 := fast_spr_num(SPR_CTR); + end if; + else + -- Could be OP_RFID + v.ispr1 := fast_spr_num(SPR_SRR0); + v.ispr2 := fast_spr_num(SPR_SRR1); + end if; + elsif majorop = "011110" then v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 1)))); @@ -423,30 +455,11 @@ begin else v.decode := major_decode_rom_array(to_integer(majorop)); - end if; - -- Set ISPR1/ISPR2 when needed - if v.decode.insn_type = OP_BC or v.decode.insn_type = OP_BCREG then - -- Branch uses CTR as condition when BO(2) is 0. This is - -- also used to indicate that CTR is modified (they go - -- together). - -- - if f_in.insn(23) = '0' then - v.ispr1 := fast_spr_num(SPR_CTR); - end if; + end if; - -- Branch source register is an SPR - if v.decode.insn_type = OP_BCREG then - -- TODO: Add TAR - if f_in.insn(10) = '0' then - v.ispr2 := fast_spr_num(SPR_LR); - else - v.ispr2 := fast_spr_num(SPR_CTR); - end if; - end if; - elsif v.decode.insn_type = OP_MFSPR or v.decode.insn_type = OP_MTSPR then + if v.decode.insn_type = OP_MFSPR or v.decode.insn_type = OP_MTSPR then sprn := decode_spr_num(f_in.insn); - v.ispr1 := fast_spr_num(sprn); -- Make slow SPRs single issue if is_fast_spr(v.ispr1) = '0' then v.decode.sgl_pipe := '1'; @@ -457,10 +470,6 @@ begin when others => end case; end if; - elsif v.decode.insn_type = OP_RFID then - report "PPC RFID"; - v.ispr1 := fast_spr_num(SPR_SRR0); - v.ispr2 := fast_spr_num(SPR_SRR1); end if; if flush_in = '1' then diff --git a/decode2.vhdl b/decode2.vhdl index 5b8cbc1..6acbca7 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -67,8 +67,6 @@ architecture behaviour of decode2 is return decode_input_reg_t is begin if t = RA or (t = RA_OR_ZERO and insn_ra(insn_in) /= "00000") then - assert is_fast_spr(ispr) = '0' report "Decode A says GPR but ISPR says SPR:" & - to_hstring(ispr) severity failure; return ('1', gpr_to_gspr(insn_ra(insn_in)), reg_data); elsif t = SPR then -- ISPR must be either a valid fast SPR number or all 0 for a slow SPR. @@ -93,8 +91,6 @@ architecture behaviour of decode2 is begin case t is when RB => - assert is_fast_spr(ispr) = '0' report "Decode B says GPR but ISPR says SPR:" & - to_hstring(ispr) severity failure; ret := ('1', gpr_to_gspr(insn_rb(insn_in)), reg_data); when CONST_UI => ret := ('0', (others => '0'), std_ulogic_vector(resize(unsigned(insn_ui(insn_in)), 64))); @@ -277,8 +273,10 @@ begin end if; end process; - r_out.read1_reg <= gpr_or_spr_to_gspr(insn_ra(d_in.insn), d_in.ispr1); - r_out.read2_reg <= gpr_or_spr_to_gspr(insn_rb(d_in.insn), d_in.ispr2); + r_out.read1_reg <= d_in.ispr1 when d_in.decode.input_reg_a = SPR + else gpr_to_gspr(insn_ra(d_in.insn)); + r_out.read2_reg <= d_in.ispr2 when d_in.decode.input_reg_b = SPR + else gpr_to_gspr(insn_rb(d_in.insn)); r_out.read3_reg <= insn_rs(d_in.insn); c_out.read <= d_in.decode.input_cr;