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 <paulus@ozlabs.org>
pull/78/head
Paul Mackerras 4 years ago
parent 96b402a4bf
commit 7fe84220a5

@ -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;

@ -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
);


@ -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;

@ -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);

@ -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 =>

Loading…
Cancel
Save