From: Paul Mackerras Date: Fri, 5 Jun 2020 01:29:31 +0000 (+1000) Subject: core: Do addpcis using the main adder (#189) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4a4a98d4b9a0c2e287ff054e1acc2fbae028869f;p=microwatt.git core: Do addpcis using the main adder (#189) By adding logic to decode2 to be able to send the instruction address down the A input, and making CONST_DX_HI (renamed to CONST_DXHI4) add 4 to the immediate value (easy since the bottom 16 bits were zero), we can do addpcis using the main adder. This reduces the width of the result mux and frees up one value in insn_type_t, since we can now use OP_ADD for addpcis. Signed-off-by: Paul Mackerras --- diff --git a/decode1.vhdl b/decode1.vhdl index 5eedbab..4aae707 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -107,7 +107,7 @@ architecture behaviour of decode1 is -- mcrf; and cr logical ops 2#000# => (ALU, OP_CROP, NONE, NONE, NONE, NONE, '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- addpcis - 2#001# => (ALU, OP_ADDPCIS, NONE, CONST_DX_HI, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), + 2#001# => (ALU, OP_ADD, CIA, CONST_DXHI4, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- bclr, bcctr, bctar 2#100# => (ALU, OP_BCREG, SPR, SPR, NONE, SPR, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), -- isync diff --git a/decode2.vhdl b/decode2.vhdl index da0bdff..772c1df 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -56,7 +56,9 @@ architecture behaviour of decode2 is function decode_input_reg_a (t : input_reg_a_t; insn_in : std_ulogic_vector(31 downto 0); reg_data : std_ulogic_vector(63 downto 0); - ispr : gspr_index_t) return decode_input_reg_t is + ispr : gspr_index_t; + instr_addr : std_ulogic_vector(63 downto 0)) + 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:" & @@ -71,6 +73,8 @@ architecture behaviour of decode2 is report "Decode A says SPR but ISPR is invalid:" & to_hstring(ispr) severity failure; return (is_fast_spr(ispr), ispr, reg_data); + elsif t = CIA then + return ('0', (others => '0'), instr_addr); else return ('0', (others => '0'), (others => '0')); end if; @@ -100,8 +104,8 @@ architecture behaviour of decode2 is ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_bd(insn_in)) & "00", 64))); when CONST_DS => ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_ds(insn_in)) & "00", 64))); - when CONST_DX_HI => - ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_dx(insn_in)) & x"0000", 64))); + when CONST_DXHI4 => + ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_dx(insn_in)) & x"0004", 64))); when CONST_M1 => ret := ('0', (others => '0'), x"FFFFFFFFFFFFFFFF"); when CONST_SH => @@ -282,7 +286,8 @@ begin --v.e.input_cr := d_in.decode.input_cr; --v.e.output_cr := d_in.decode.output_cr; - decoded_reg_a := decode_input_reg_a (d_in.decode.input_reg_a, d_in.insn, r_in.read1_data, d_in.ispr1); + decoded_reg_a := decode_input_reg_a (d_in.decode.input_reg_a, d_in.insn, r_in.read1_data, d_in.ispr1, + d_in.nia); decoded_reg_b := decode_input_reg_b (d_in.decode.input_reg_b, d_in.insn, r_in.read2_data, d_in.ispr2); decoded_reg_c := decode_input_reg_c (d_in.decode.input_reg_c, d_in.insn, r_in.read3_data); decoded_reg_o := decode_output_reg (d_in.decode.output_reg_a, d_in.insn, d_in.ispr1); diff --git a/decode_types.vhdl b/decode_types.vhdl index bd16507..9cd6d69 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -3,7 +3,7 @@ use ieee.std_logic_1164.all; package decode_types is type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD, - OP_ADDPCIS, OP_AND, OP_ATTN, OP_B, OP_BC, OP_BCREG, + OP_AND, OP_ATTN, OP_B, OP_BC, OP_BCREG, OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPRB, OP_CNTZ, OP_CROP, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST, @@ -20,8 +20,9 @@ package decode_types is OP_XOR, OP_FETCH_FAILED ); - type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR); - type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DX_HI, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR); + type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR, CIA); + type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, + CONST_DXHI4, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR); type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA, SPR); type rc_t is (NONE, ONE, RC); diff --git a/execute1.vhdl b/execute1.vhdl index 3207958..cac8e8a 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -528,9 +528,6 @@ begin end if; when OP_NOP => -- Do nothing - when OP_ADDPCIS => - result := ppc_adde(next_nia, b_in, '0')(63 downto 0); - result_en := '1'; when OP_ADD | OP_CMP | OP_TRAP => if e_in.invert_a = '0' then a_inv := a_in;