mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-13 15:18:09 +00:00
The decode2 stage was spaghetti code and needed cleaning up. Create a series of functions to pull fields from a ppc instruction and also a series of helpers to extract values for the execution units. As suggested by Paul, we should pass all signals to the execution units and only set the valid signal conditionally, which should use less resources. Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
197 lines
7.2 KiB
VHDL
197 lines
7.2 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
|
|
library work;
|
|
use work.decode_types.all;
|
|
|
|
package common is
|
|
type ctrl_t is record
|
|
lr: std_ulogic_vector(63 downto 0);
|
|
ctr: std_ulogic_vector(63 downto 0);
|
|
tb: std_ulogic_vector(63 downto 0);
|
|
carry: std_ulogic;
|
|
end record;
|
|
|
|
type Fetch1ToFetch2Type is record
|
|
valid: std_ulogic;
|
|
nia: std_ulogic_vector(63 downto 0);
|
|
end record;
|
|
|
|
type Fetch2ToDecode1Type is record
|
|
valid: std_ulogic;
|
|
nia: std_ulogic_vector(63 downto 0);
|
|
insn: std_ulogic_vector(31 downto 0);
|
|
end record;
|
|
constant Fetch2ToDecode1Init : Fetch2ToDecode1Type := (valid => '0', others => (others => '0'));
|
|
|
|
type Decode1ToDecode2Type is record
|
|
valid: std_ulogic;
|
|
nia: std_ulogic_vector(63 downto 0);
|
|
insn: std_ulogic_vector(31 downto 0);
|
|
decode: decode_rom_t;
|
|
end record;
|
|
constant Decode1ToDecode2Init : Decode1ToDecode2Type := (valid => '0', decode => decode_rom_init, others => (others => '0'));
|
|
|
|
type Decode2ToExecute1Type is record
|
|
valid: std_ulogic;
|
|
insn_type: insn_type_t;
|
|
nia: std_ulogic_vector(63 downto 0);
|
|
write_reg: std_ulogic_vector(4 downto 0);
|
|
read_reg1: std_ulogic_vector(4 downto 0);
|
|
read_reg2: std_ulogic_vector(4 downto 0);
|
|
read_data1: std_ulogic_vector(63 downto 0);
|
|
read_data2: std_ulogic_vector(63 downto 0);
|
|
const1: std_ulogic_vector(7 downto 0);
|
|
const2: std_ulogic_vector(5 downto 0);
|
|
const3: std_ulogic_vector(4 downto 0);
|
|
cr: std_ulogic_vector(31 downto 0);
|
|
lr: std_ulogic;
|
|
rc: std_ulogic;
|
|
input_carry: std_ulogic;
|
|
output_carry: std_ulogic;
|
|
input_cr: std_ulogic;
|
|
output_cr: std_ulogic;
|
|
input_cr_data: std_ulogic_vector(31 downto 0);
|
|
end record;
|
|
constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0'));
|
|
|
|
type Decode2ToMultiplyType is record
|
|
valid: std_ulogic;
|
|
insn_type: insn_type_t;
|
|
nia: std_ulogic_vector(63 downto 0);
|
|
write_reg: std_ulogic_vector(4 downto 0);
|
|
data1: std_ulogic_vector(64 downto 0);
|
|
data2: std_ulogic_vector(64 downto 0);
|
|
rc: std_ulogic;
|
|
end record;
|
|
constant Decode2ToMultiplyInit : Decode2ToMultiplyType := (valid => '0', insn_type => OP_ILLEGAL, rc => '0', others => (others => '0'));
|
|
|
|
type Decode2ToRegisterFileType is record
|
|
read1_reg : std_ulogic_vector(4 downto 0);
|
|
read2_reg : std_ulogic_vector(4 downto 0);
|
|
read3_reg : std_ulogic_vector(4 downto 0);
|
|
end record;
|
|
|
|
type RegisterFileToDecode2Type is record
|
|
read1_data : std_ulogic_vector(63 downto 0);
|
|
read2_data : std_ulogic_vector(63 downto 0);
|
|
read3_data : std_ulogic_vector(63 downto 0);
|
|
end record;
|
|
|
|
type Decode2ToCrFileType is record
|
|
read_cr_nr_1 : integer;
|
|
read_cr_nr_2 : integer;
|
|
end record;
|
|
|
|
type CrFileToDecode2Type is record
|
|
read_cr_data : std_ulogic_vector(31 downto 0);
|
|
read_cr_data_1 : std_ulogic_vector(3 downto 0);
|
|
read_cr_data_2 : std_ulogic_vector(3 downto 0);
|
|
end record;
|
|
|
|
type Execute1ToFetch1Type is record
|
|
redirect: std_ulogic;
|
|
redirect_nia: std_ulogic_vector(63 downto 0);
|
|
end record;
|
|
constant Execute1ToFetch1TypeInit : Execute1ToFetch1Type := (redirect => '0', others => (others => '0'));
|
|
|
|
type Decode2ToLoadstore1Type is record
|
|
valid : std_ulogic;
|
|
nia: std_ulogic_vector(63 downto 0);
|
|
load : std_ulogic; -- is this a load or store
|
|
addr1 : std_ulogic_vector(63 downto 0);
|
|
addr2 : std_ulogic_vector(63 downto 0);
|
|
data : std_ulogic_vector(63 downto 0); -- data to write, unused for read
|
|
write_reg : std_ulogic_vector(4 downto 0); -- read data goes to this register
|
|
length : std_ulogic_vector(3 downto 0);
|
|
byte_reverse : std_ulogic;
|
|
sign_extend : std_ulogic; -- do we need to sign extend?
|
|
update : std_ulogic; -- is this an update instruction?
|
|
update_reg : std_ulogic_vector(4 downto 0); -- if so, the register to update
|
|
end record;
|
|
constant Decode2ToLoadstore1Init : Decode2ToLoadstore1Type := (valid => '0', load => '0', byte_reverse => '0', sign_extend => '0', update => '0', others => (others => '0'));
|
|
|
|
type Loadstore1ToLoadstore2Type is record
|
|
valid : std_ulogic;
|
|
load : std_ulogic;
|
|
addr : std_ulogic_vector(63 downto 0);
|
|
data : std_ulogic_vector(63 downto 0);
|
|
write_reg : std_ulogic_vector(4 downto 0);
|
|
length : std_ulogic_vector(3 downto 0);
|
|
byte_reverse : std_ulogic;
|
|
sign_extend : std_ulogic;
|
|
update : std_ulogic;
|
|
update_reg : std_ulogic_vector(4 downto 0);
|
|
end record;
|
|
|
|
type Loadstore2ToWritebackType is record
|
|
valid : std_ulogic;
|
|
write_enable: std_ulogic;
|
|
write_reg : std_ulogic_vector(4 downto 0);
|
|
write_data : std_ulogic_vector(63 downto 0);
|
|
write_enable2: std_ulogic;
|
|
write_reg2 : std_ulogic_vector(4 downto 0);
|
|
write_data2 : std_ulogic_vector(63 downto 0);
|
|
end record;
|
|
constant Loadstore2ToWritebackInit : Loadstore2ToWritebackType := (valid => '0', write_enable => '0', write_enable2 => '0', others => (others => '0'));
|
|
|
|
type Execute1ToExecute2Type is record
|
|
valid: std_ulogic;
|
|
write_enable : std_ulogic;
|
|
write_reg: std_ulogic_vector(4 downto 0);
|
|
write_data: std_ulogic_vector(63 downto 0);
|
|
write_cr_enable : std_ulogic;
|
|
write_cr_mask : std_ulogic_vector(7 downto 0);
|
|
write_cr_data : std_ulogic_vector(31 downto 0);
|
|
rc : std_ulogic;
|
|
end record;
|
|
constant Execute1ToExecute2Init : Execute1ToExecute2Type := (valid => '0', write_enable => '0', write_cr_enable => '0', rc => '0', others => (others => '0'));
|
|
|
|
type Execute2ToWritebackType is record
|
|
valid: std_ulogic;
|
|
write_enable : std_ulogic;
|
|
write_reg: std_ulogic_vector(4 downto 0);
|
|
write_data: std_ulogic_vector(63 downto 0);
|
|
write_cr_enable : std_ulogic;
|
|
write_cr_mask : std_ulogic_vector(7 downto 0);
|
|
write_cr_data : std_ulogic_vector(31 downto 0);
|
|
end record;
|
|
constant Execute2ToWritebackInit : Execute2ToWritebackType := (valid => '0', write_enable => '0', write_cr_enable => '0', others => (others => '0'));
|
|
|
|
type MultiplyToWritebackType is record
|
|
valid: std_ulogic;
|
|
|
|
write_reg_enable : std_ulogic;
|
|
write_reg_nr: std_ulogic_vector(4 downto 0);
|
|
write_reg_data: std_ulogic_vector(63 downto 0);
|
|
write_cr_enable: std_ulogic;
|
|
write_cr_mask: std_ulogic_vector(7 downto 0);
|
|
write_cr_data: std_ulogic_vector(31 downto 0);
|
|
end record;
|
|
constant MultiplyToWritebackInit : MultiplyToWritebackType := (valid => '0', write_reg_enable => '0', write_cr_enable => '0', others => (others => '0'));
|
|
|
|
type WritebackToRegisterFileType is record
|
|
write_reg : std_ulogic_vector(4 downto 0);
|
|
write_data : std_ulogic_vector(63 downto 0);
|
|
write_enable : std_ulogic;
|
|
write_reg2 : std_ulogic_vector(4 downto 0);
|
|
write_data2 : std_ulogic_vector(63 downto 0);
|
|
write_enable2 : std_ulogic;
|
|
end record;
|
|
constant WritebackToRegisterFileInit : WritebackToRegisterFileType := (write_enable => '0', write_enable2 => '0', others => (others => '0'));
|
|
|
|
type WritebackToCrFileType is record
|
|
write_cr_enable : std_ulogic;
|
|
write_cr_mask : std_ulogic_vector(7 downto 0);
|
|
write_cr_data : std_ulogic_vector(31 downto 0);
|
|
end record;
|
|
constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', others => (others => '0'));
|
|
|
|
-- Would prefer not to expose this outside the register file, but ghdl
|
|
-- doesn't support external names
|
|
type regfile is array(0 to 32) of std_ulogic_vector(63 downto 0);
|
|
end common;
|
|
|
|
package body common is
|
|
end common;
|