From: Paul Mackerras Date: Fri, 4 Oct 2019 09:26:37 +0000 (+1000) Subject: decode: Avoid multiplexing from instruction reg fields to regfile address ports X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7fe84220a51f08d79af71966c46ae52bc8369b00;p=microwatt.git decode: Avoid multiplexing from instruction reg fields to regfile address ports This aims to simplify the logic between the instruction image and the register file read address ports and reduce the size of the decode tables. With this patch, the input_reg_a column of the decode tables can only select RA or zeroes, the input_reg_b column can only select RB or a constant (0, -1, or an immediate value from the instruction), and the input_reg_c columns can only select RS or zeroes. That means that the rotate/shift/logical ops now have their first input coming in via the input_reg_c column. That means we need to add a read_data3 field to the Decode2ToExecuteType record, but that will go away again when we split out the rotate/mask/logical ops to their own unit. As a related but not tightly connected change, this patch also sets the read1_enable signal to the register file be 0 when RA=0 and the input_reg_a for the instruction is RA_OR_ZERO (previously it was 1). Signed-off-by: Paul Mackerras --- diff --git a/common.vhdl b/common.vhdl index bd24329..67872c8 100644 --- a/common.vhdl +++ b/common.vhdl @@ -52,6 +52,7 @@ package common is read_reg2: std_ulogic_vector(4 downto 0); read_data1: std_ulogic_vector(63 downto 0); read_data2: std_ulogic_vector(63 downto 0); + read_data3: std_ulogic_vector(63 downto 0); cr: std_ulogic_vector(31 downto 0); lr: std_ulogic; rc: std_ulogic; diff --git a/decode1.vhdl b/decode1.vhdl index 9125758..0173084 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -40,8 +40,8 @@ architecture behaviour of decode1 is 13 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- addic. 14 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addi 15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addis - 28 => (ALU, OP_AND, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. - 29 => (ALU, OP_AND, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andis. + 28 => (ALU, OP_AND, NONE, CONST_UI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. + 29 => (ALU, OP_AND, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andis. 18 => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- b 16 => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- bc 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpi @@ -55,11 +55,11 @@ architecture behaviour of decode1 is 32 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwz 33 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzu 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, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori - 25 => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris - 20 => (ALU, OP_RLWIMI, RA, RS, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi - 21 => (ALU, OP_RLWINM, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm - 23 => (ALU, OP_RLWNM, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm + 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 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 @@ -69,8 +69,8 @@ architecture behaviour of decode1 is 8 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '1', ONE, '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- subfic 2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi --PPC_TWI 3 - 26 => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori - 27 => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris + 26 => (ALU, OP_XOR, NONE, CONST_UI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori + 27 => (ALU, OP_XOR, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris others => illegal_inst ); @@ -115,12 +115,12 @@ architecture behaviour of decode1 is 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 mul mul rc lk sgl -- op in out A in out len ext 32 sgn pipe - 2#010# => (ALU, OP_RLDIC, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#000# => (ALU, OP_RLDICL, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#001# => (ALU, OP_RLDICR, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#011# => (ALU, OP_RLDIMI, RA, RS, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 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, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#100# => (ALU, OP_RLDCX, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), others => illegal_inst ); @@ -133,18 +133,18 @@ architecture behaviour of decode1 is 2#0010001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- adde 2#0011101010# => (ALU, OP_ADD, RA, CONST_M1, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addme 2#0011001010# => (ALU, OP_ADD, RA, NONE, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addze - 2#0000011100# => (ALU, OP_AND, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and - 2#0000111100# => (ALU, OP_ANDC, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc + 2#0000011100# => (ALU, OP_AND, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and + 2#0000111100# => (ALU, OP_ANDC, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc -- 2#0011111100# bperm 2#0000000000# => (ALU, OP_CMP, RA, RB, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmp - 2#0111111100# => (ALU, OP_CMPB, RS, RB, NONE, RA, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb + 2#0111111100# => (ALU, OP_CMPB, NONE, RB, RS, RA, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb -- 2#0011100000# cmpeqb 2#0000100000# => (ALU, OP_CMPL, RA, RB, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpl -- 2#0011000000# cmprb - 2#0000111010# => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd - 2#0000011010# => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw - 2#1000111010# => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd - 2#1000011010# => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw + 2#0000111010# => (ALU, OP_CNTLZD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd + 2#0000011010# => (ALU, OP_CNTLZW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw + 2#1000111010# => (ALU, OP_CNTTZD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd + 2#1000011010# => (ALU, OP_CNTTZW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw -- 2#1011110011# darn 2#0001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbf 2#0000110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbst @@ -159,10 +159,10 @@ architecture behaviour of decode1 is 2#0111001011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwu 2#0111101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divd 2#0111101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divw - 2#0100011100# => (ALU, OP_EQV, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv - 2#1110111010# => (ALU, OP_EXTSB, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb - 2#1110011010# => (ALU, OP_EXTSH, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh - 2#1111011010# => (ALU, OP_EXTSW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw + 2#0100011100# => (ALU, OP_EQV, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv + 2#1110111010# => (ALU, OP_EXTSB, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb + 2#1110011010# => (ALU, OP_EXTSH, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh + 2#1111011010# => (ALU, OP_EXTSW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw -- 2#110111101-# extswsli -- 2#1111010110# icbi 2#0000010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt @@ -225,8 +225,8 @@ architecture behaviour of decode1 is 2#0100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- moduw 2#1100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsd 2#1100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsw - 2#0010010000# => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf - 2#0111010011# => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr + 2#0010010000# => (ALU, OP_MTCRF, NONE, NONE, RS, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf + 2#0111010011# => (ALU, OP_MTSPR, NONE, NONE, RS, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr 2#0001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd 2#0000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu 2#0001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw @@ -238,26 +238,26 @@ architecture behaviour of decode1 is 2#1000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu 2#0011101001# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulld 2#0011101011# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mullw - 2#0111011100# => (ALU, OP_NAND, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand + 2#0111011100# => (ALU, OP_NAND, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand 2#0001101000# => (ALU, OP_NEG, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- neg - 2#0001111100# => (ALU, OP_NOR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor - 2#0110111100# => (ALU, OP_OR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or - 2#0110011100# => (ALU, OP_ORC, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc - 2#0001111010# => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb - 2#0111111010# => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd - 2#0101111010# => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw - 2#0010111010# => (ALU, OP_PRTYD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd - 2#0010011010# => (ALU, OP_PRTYW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw + 2#0001111100# => (ALU, OP_NOR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor + 2#0110111100# => (ALU, OP_OR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or + 2#0110011100# => (ALU, OP_ORC, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc + 2#0001111010# => (ALU, OP_POPCNTB, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb + 2#0111111010# => (ALU, OP_POPCNTD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd + 2#0101111010# => (ALU, OP_POPCNTW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw + 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, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld - 2#0000011000# => (ALU, OP_SLW, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw - 2#1100011010# => (ALU, OP_SRAD, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad - 2#1100111010# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100111011# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100011000# => (ALU, OP_SRAW, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw - 2#1100111000# => (ALU, OP_SRAWI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi - 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd - 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw + 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#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 @@ -281,7 +281,7 @@ architecture behaviour of decode1 is 2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync -- 2#0001000100# td 2#0000000100# => (ALU, OP_TW, RA, RB, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tw - 2#0100111100# => (ALU, OP_XOR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor + 2#0100111100# => (ALU, OP_XOR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor others => illegal_inst ); diff --git a/decode2.vhdl b/decode2.vhdl index 1594b0f..e22b065 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -62,16 +62,11 @@ 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)) return decode_input_reg_t is begin - case t is - when RA => + if t = RA or (t = RA_OR_ZERO and insn_ra(insn_in) /= "00000") then return ('1', insn_ra(insn_in), reg_data); - when RA_OR_ZERO => - return ('1', insn_ra(insn_in), ra_or_zero(reg_data, insn_ra(insn_in))); - when RS => - return ('1', insn_rs(insn_in), reg_data); - when NONE => + else return ('0', (others => '0'), (others => '0')); - end case; + end if; end; function decode_input_reg_b (t : input_reg_b_t; insn_in : std_ulogic_vector(31 downto 0); @@ -80,8 +75,6 @@ architecture behaviour of decode2 is case t is when RB => return ('1', insn_rb(insn_in), reg_data); - when RS => - return ('1', insn_rs(insn_in), reg_data); when CONST_UI => return ('0', (others => '0'), std_ulogic_vector(resize(unsigned(insn_ui(insn_in)), 64))); when CONST_SI => @@ -152,17 +145,9 @@ begin end if; end process; - r_out.read1_reg <= insn_ra(d_in.insn) when (d_in.decode.input_reg_a = RA) else - insn_ra(d_in.insn) when d_in.decode.input_reg_a = RA_OR_ZERO else - insn_rs(d_in.insn) when d_in.decode.input_reg_a = RS else - (others => '0'); - - r_out.read2_reg <= insn_rb(d_in.insn) when d_in.decode.input_reg_b = RB else - insn_rs(d_in.insn) when d_in.decode.input_reg_b = RS else - (others => '0'); - - r_out.read3_reg <= insn_rs(d_in.insn) when d_in.decode.input_reg_c = RS else - (others => '0'); + r_out.read1_reg <= insn_ra(d_in.insn); + r_out.read2_reg <= insn_rb(d_in.insn); + r_out.read3_reg <= insn_rs(d_in.insn); c_out.read <= d_in.decode.input_cr; @@ -207,6 +192,7 @@ begin v.e.read_data1 := decoded_reg_a.data; v.e.read_reg2 := decoded_reg_b.reg; v.e.read_data2 := decoded_reg_b.data; + v.e.read_data3 := decoded_reg_c.data; v.e.write_reg := decode_output_reg(d_in.decode.output_reg_a, d_in.insn); v.e.rc := decode_rc(d_in.decode.rc, d_in.insn); v.e.cr := c_in.read_cr_data; diff --git a/decode_types.vhdl b/decode_types.vhdl index ccc6a8d..cbdf449 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -21,8 +21,8 @@ package decode_types is OP_SYNC, OP_TD, OP_TDI, OP_TW, OP_TWI, OP_XOR, OP_SIM_CONFIG); - type input_reg_a_t is (NONE, RA, RA_OR_ZERO, RS); - type input_reg_b_t is (NONE, RB, RS, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1); + type input_reg_a_t is (NONE, RA, RA_OR_ZERO); + type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1); type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA); type rc_t is (NONE, ONE, RC); diff --git a/execute1.vhdl b/execute1.vhdl index 6d77361..cdd79f1 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -118,10 +118,10 @@ begin end if; result_en := 1; when OP_AND => - result := ppc_and(e_in.read_data1, e_in.read_data2); + result := ppc_and(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_ANDC => - result := ppc_andc(e_in.read_data1, e_in.read_data2); + result := ppc_andc(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_B => f_out.redirect <= '1'; @@ -160,7 +160,7 @@ begin end if; end if; when OP_CMPB => - result := ppc_cmpb(e_in.read_data1, e_in.read_data2); + result := ppc_cmpb(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_CMP => bf := insn_bf(e_in.insn); @@ -185,28 +185,28 @@ begin v.e.write_cr_data(hi downto lo) := ppc_cmpl(l, e_in.read_data1, e_in.read_data2); end loop; when OP_CNTLZW => - result := ppc_cntlzw(e_in.read_data1); + result := ppc_cntlzw(e_in.read_data3); result_en := 1; when OP_CNTTZW => - result := ppc_cnttzw(e_in.read_data1); + result := ppc_cnttzw(e_in.read_data3); result_en := 1; when OP_CNTLZD => - result := ppc_cntlzd(e_in.read_data1); + result := ppc_cntlzd(e_in.read_data3); result_en := 1; when OP_CNTTZD => - result := ppc_cnttzd(e_in.read_data1); + result := ppc_cnttzd(e_in.read_data3); result_en := 1; when OP_EXTSB => - result := ppc_extsb(e_in.read_data1); + result := ppc_extsb(e_in.read_data3); result_en := 1; when OP_EXTSH => - result := ppc_extsh(e_in.read_data1); + result := ppc_extsh(e_in.read_data3); result_en := 1; when OP_EXTSW => - result := ppc_extsw(e_in.read_data1); + result := ppc_extsw(e_in.read_data3); result_en := 1; when OP_EQV => - result := ppc_eqv(e_in.read_data1, e_in.read_data2); + result := ppc_eqv(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_ISEL => crnum := to_integer(unsigned(insn_bc(e_in.insn))); @@ -273,125 +273,125 @@ begin crnum := fxm_to_num(insn_fxm(e_in.insn)); v.e.write_cr_mask := num_to_fxm(crnum); end if; - v.e.write_cr_data := e_in.read_data1(31 downto 0); + v.e.write_cr_data := e_in.read_data3(31 downto 0); when OP_MTSPR => if std_match(e_in.insn(20 downto 11), "0100100000") then - ctrl_tmp.ctr <= e_in.read_data1; + ctrl_tmp.ctr <= e_in.read_data3; elsif std_match(e_in.insn(20 downto 11), "0100000000") then - ctrl_tmp.lr <= e_in.read_data1; + ctrl_tmp.lr <= e_in.read_data3; end if; when OP_NAND => - result := ppc_nand(e_in.read_data1, e_in.read_data2); + result := ppc_nand(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_NEG => result := ppc_neg(e_in.read_data1); result_en := 1; when OP_NOR => - result := ppc_nor(e_in.read_data1, e_in.read_data2); + result := ppc_nor(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_OR => - result := ppc_or(e_in.read_data1, e_in.read_data2); + result := ppc_or(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_ORC => - result := ppc_orc(e_in.read_data1, e_in.read_data2); + result := ppc_orc(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_POPCNTB => - result := ppc_popcntb(e_in.read_data1); + result := ppc_popcntb(e_in.read_data3); result_en := 1; when OP_POPCNTW => - result := ppc_popcntw(e_in.read_data1); + result := ppc_popcntw(e_in.read_data3); result_en := 1; when OP_POPCNTD => - result := ppc_popcntd(e_in.read_data1); + result := ppc_popcntd(e_in.read_data3); result_en := 1; when OP_PRTYD => - result := ppc_prtyd(e_in.read_data1); + result := ppc_prtyd(e_in.read_data3); result_en := 1; when OP_PRTYW => - result := ppc_prtyw(e_in.read_data1); + result := ppc_prtyw(e_in.read_data3); result_en := 1; when OP_RLDCX => -- note rldcl mb field and rldcr me field are in the same place mb := insn_mb(e_in.insn); if e_in.insn(1) = '0' then - result := ppc_rldcl(e_in.read_data1, e_in.read_data2, mb); + result := ppc_rldcl(e_in.read_data3, e_in.read_data2, mb); else - result := ppc_rldcr(e_in.read_data1, e_in.read_data2, mb); + result := ppc_rldcr(e_in.read_data3, e_in.read_data2, mb); end if; result_en := 1; when OP_RLDICL => sh := insn_sh(e_in.insn); mb := insn_mb(e_in.insn); - result := ppc_rldicl(e_in.read_data1, sh, mb); + result := ppc_rldicl(e_in.read_data3, sh, mb); result_en := 1; when OP_RLDICR => sh := insn_sh(e_in.insn); me := insn_me(e_in.insn); - result := ppc_rldicr(e_in.read_data1, sh, me); + result := ppc_rldicr(e_in.read_data3, sh, me); result_en := 1; when OP_RLWNM => mb32 := insn_mb32(e_in.insn); me32 := insn_me32(e_in.insn); - result := ppc_rlwnm(e_in.read_data1, e_in.read_data2, mb32, me32); + result := ppc_rlwnm(e_in.read_data3, e_in.read_data2, mb32, me32); result_en := 1; when OP_RLWINM => sh32 := insn_sh32(e_in.insn); mb32 := insn_mb32(e_in.insn); me32 := insn_me32(e_in.insn); - result := ppc_rlwinm(e_in.read_data1, sh32, mb32, me32); + result := ppc_rlwinm(e_in.read_data3, sh32, mb32, me32); result_en := 1; when OP_RLDIC => sh := insn_sh(e_in.insn); mb := insn_mb(e_in.insn); - result := ppc_rldic(e_in.read_data1, sh, mb); + result := ppc_rldic(e_in.read_data3, sh, mb); result_en := 1; when OP_RLDIMI => sh := insn_sh(e_in.insn); mb := insn_mb(e_in.insn); - result := ppc_rldimi(e_in.read_data1, e_in.read_data2, sh, mb); + result := ppc_rldimi(e_in.read_data1, e_in.read_data3, sh, mb); result_en := 1; when OP_RLWIMI => sh32 := insn_sh32(e_in.insn); mb32 := insn_mb32(e_in.insn); me32 := insn_me32(e_in.insn); - result := ppc_rlwimi(e_in.read_data1, e_in.read_data2, sh32, mb32, me32); + result := ppc_rlwimi(e_in.read_data1, e_in.read_data3, sh32, mb32, me32); result_en := 1; when OP_SLD => - result := ppc_sld(e_in.read_data1, e_in.read_data2); + result := ppc_sld(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_SLW => - result := ppc_slw(e_in.read_data1, e_in.read_data2); + result := ppc_slw(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_SRAW => - result_with_carry := ppc_sraw(e_in.read_data1, e_in.read_data2); + result_with_carry := ppc_sraw(e_in.read_data3, e_in.read_data2); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRAWI => sh := '0' & insn_sh32(e_in.insn); - result_with_carry := ppc_srawi(e_in.read_data1, sh); + result_with_carry := ppc_srawi(e_in.read_data3, sh); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRAD => - result_with_carry := ppc_srad(e_in.read_data1, e_in.read_data2); + result_with_carry := ppc_srad(e_in.read_data3, e_in.read_data2); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRADI => sh := insn_sh(e_in.insn); - result_with_carry := ppc_sradi(e_in.read_data1, sh); + result_with_carry := ppc_sradi(e_in.read_data3, sh); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRD => - result := ppc_srd(e_in.read_data1, e_in.read_data2); + result := ppc_srd(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_SRW => - result := ppc_srw(e_in.read_data1, e_in.read_data2); + result := ppc_srw(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_XOR => - result := ppc_xor(e_in.read_data1, e_in.read_data2); + result := ppc_xor(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_SIM_CONFIG =>