use ieee.numeric_std.all;
library work;
+use work.utils.all;
use work.decode_types.all;
package common is
+ -- Processor Version Number
+ constant PVR_MICROWATT : std_ulogic_vector(31 downto 0) := x"00630000";
-- MSR bit numbers
constant MSR_SF : integer := (63 - 0); -- Sixty-Four bit mode
constant MSR_EE : integer := (63 - 48); -- External interrupt Enable
constant MSR_PR : integer := (63 - 49); -- PRoblem state
+ constant MSR_FP : integer := (63 - 50); -- Floating Point available
+ constant MSR_FE0 : integer := (63 - 52); -- Floating Exception mode
+ constant MSR_SE : integer := (63 - 53); -- Single-step bit of TE field
+ constant MSR_BE : integer := (63 - 54); -- Branch trace bit of TE field
+ constant MSR_FE1 : integer := (63 - 55); -- Floating Exception mode
constant MSR_IR : integer := (63 - 58); -- Instruction Relocation
constant MSR_DR : integer := (63 - 59); -- Data Relocation
+ constant MSR_PMM : integer := (63 - 61); -- Performance Monitor Mark
constant MSR_RI : integer := (63 - 62); -- Recoverable Interrupt
constant MSR_LE : integer := (63 - 63); -- Little Endian
constant SPR_XER : spr_num_t := 1;
constant SPR_LR : spr_num_t := 8;
constant SPR_CTR : spr_num_t := 9;
+ constant SPR_TAR : spr_num_t := 815;
constant SPR_DSISR : spr_num_t := 18;
constant SPR_DAR : spr_num_t := 19;
constant SPR_TB : spr_num_t := 268;
+ constant SPR_TBU : spr_num_t := 269;
constant SPR_DEC : spr_num_t := 22;
constant SPR_SRR0 : spr_num_t := 26;
constant SPR_SRR1 : spr_num_t := 27;
+ constant SPR_CFAR : spr_num_t := 28;
constant SPR_HSRR0 : spr_num_t := 314;
constant SPR_HSRR1 : spr_num_t := 315;
constant SPR_SPRG0 : spr_num_t := 272;
constant SPR_SPRG3U : spr_num_t := 259;
constant SPR_HSPRG0 : spr_num_t := 304;
constant SPR_HSPRG1 : spr_num_t := 305;
+ constant SPR_PID : spr_num_t := 48;
+ constant SPR_PTCR : spr_num_t := 464;
+ constant SPR_PVR : spr_num_t := 287;
+
+ -- PMU registers
+ constant SPR_UPMC1 : spr_num_t := 771;
+ constant SPR_UPMC2 : spr_num_t := 772;
+ constant SPR_UPMC3 : spr_num_t := 773;
+ constant SPR_UPMC4 : spr_num_t := 774;
+ constant SPR_UPMC5 : spr_num_t := 775;
+ constant SPR_UPMC6 : spr_num_t := 776;
+ constant SPR_UMMCR0 : spr_num_t := 779;
+ constant SPR_UMMCR1 : spr_num_t := 782;
+ constant SPR_UMMCR2 : spr_num_t := 769;
+ constant SPR_UMMCRA : spr_num_t := 770;
+ constant SPR_USIER : spr_num_t := 768;
+ constant SPR_USIAR : spr_num_t := 780;
+ constant SPR_USDAR : spr_num_t := 781;
+ constant SPR_PMC1 : spr_num_t := 787;
+ constant SPR_PMC2 : spr_num_t := 788;
+ constant SPR_PMC3 : spr_num_t := 789;
+ constant SPR_PMC4 : spr_num_t := 790;
+ constant SPR_PMC5 : spr_num_t := 791;
+ constant SPR_PMC6 : spr_num_t := 792;
+ constant SPR_MMCR0 : spr_num_t := 795;
+ constant SPR_MMCR1 : spr_num_t := 798;
+ constant SPR_MMCR2 : spr_num_t := 785;
+ constant SPR_MMCRA : spr_num_t := 786;
+ constant SPR_SIER : spr_num_t := 784;
+ constant SPR_SIAR : spr_num_t := 796;
+ constant SPR_SDAR : spr_num_t := 797;
-- GPR indices in the register file (GPR only)
subtype gpr_index_t is std_ulogic_vector(4 downto 0);
- -- Extended GPR indice (can hold an SPR)
- subtype gspr_index_t is std_ulogic_vector(5 downto 0);
+ -- Extended GPR index (can hold an SPR or a FPR)
+ subtype gspr_index_t is std_ulogic_vector(6 downto 0);
+
+ -- FPR indices
+ subtype fpr_index_t is std_ulogic_vector(4 downto 0);
-- Some SPRs are stored in the register file, they use the magic
-- GPR numbers above 31.
-- indicates if this is indeed a fast SPR. If clear, then
-- the SPR is not stored in the GPR file.
--
+ -- FPRs are also stored in the register file, using GSPR
+ -- numbers from 64 to 95.
+ --
function fast_spr_num(spr: spr_num_t) return gspr_index_t;
-- Indices conversion functions
function gpr_to_gspr(i: gpr_index_t) return gspr_index_t;
function gpr_or_spr_to_gspr(g: gpr_index_t; s: gspr_index_t) return gspr_index_t;
function is_fast_spr(s: gspr_index_t) return std_ulogic;
+ function fpr_to_gspr(f: fpr_index_t) return gspr_index_t;
-- The XER is split: the common bits (CA, OV, SO, OV32 and CA32) are
-- in the CR file as a kind of CR extension (with a separate write
end record;
constant xerc_init : xer_common_t := (others => '0');
- type irq_state_t is (WRITE_SRR0, WRITE_SRR1);
+ -- FPSCR bit numbers
+ constant FPSCR_FX : integer := 63 - 32;
+ constant FPSCR_FEX : integer := 63 - 33;
+ constant FPSCR_VX : integer := 63 - 34;
+ constant FPSCR_OX : integer := 63 - 35;
+ constant FPSCR_UX : integer := 63 - 36;
+ constant FPSCR_ZX : integer := 63 - 37;
+ constant FPSCR_XX : integer := 63 - 38;
+ constant FPSCR_VXSNAN : integer := 63 - 39;
+ constant FPSCR_VXISI : integer := 63 - 40;
+ constant FPSCR_VXIDI : integer := 63 - 41;
+ constant FPSCR_VXZDZ : integer := 63 - 42;
+ constant FPSCR_VXIMZ : integer := 63 - 43;
+ constant FPSCR_VXVC : integer := 63 - 44;
+ constant FPSCR_FR : integer := 63 - 45;
+ constant FPSCR_FI : integer := 63 - 46;
+ constant FPSCR_C : integer := 63 - 47;
+ constant FPSCR_FL : integer := 63 - 48;
+ constant FPSCR_FG : integer := 63 - 49;
+ constant FPSCR_FE : integer := 63 - 50;
+ constant FPSCR_FU : integer := 63 - 51;
+ constant FPSCR_VXSOFT : integer := 63 - 53;
+ constant FPSCR_VXSQRT : integer := 63 - 54;
+ constant FPSCR_VXCVI : integer := 63 - 55;
+ constant FPSCR_VE : integer := 63 - 56;
+ constant FPSCR_OE : integer := 63 - 57;
+ constant FPSCR_UE : integer := 63 - 58;
+ constant FPSCR_ZE : integer := 63 - 59;
+ constant FPSCR_XE : integer := 63 - 60;
+ constant FPSCR_NI : integer := 63 - 61;
+ constant FPSCR_RN : integer := 63 - 63;
+
+ -- Real addresses
+ -- REAL_ADDR_BITS is the number of real address bits that we store
+ constant REAL_ADDR_BITS : positive := 56;
+ subtype real_addr_t is std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0);
+ function addr_to_real(addr: std_ulogic_vector(63 downto 0)) return real_addr_t;
+
+ -- Used for tracking instruction completion and pending register writes
+ constant TAG_COUNT : positive := 4;
+ constant TAG_NUMBER_BITS : natural := log2(TAG_COUNT);
+ subtype tag_number_t is integer range 0 to TAG_COUNT - 1;
+ subtype tag_index_t is unsigned(TAG_NUMBER_BITS - 1 downto 0);
+ type instr_tag_t is record
+ tag : tag_number_t;
+ valid : std_ulogic;
+ end record;
+ constant instr_tag_init : instr_tag_t := (tag => 0, valid => '0');
+ function tag_match(tag1 : instr_tag_t; tag2 : instr_tag_t) return boolean;
+
+ subtype intr_vector_t is integer range 0 to 16#fff#;
+
+ -- For now, fixed 16 sources, make this either a parametric
+ -- package of some sort or an unconstrainted array.
+ type ics_to_icp_t is record
+ -- Level interrupts only, ICS just keeps prsenting the
+ -- highest priority interrupt. Once handling edge, something
+ -- smarter involving handshake & reject support will be needed
+ src : std_ulogic_vector(3 downto 0);
+ pri : std_ulogic_vector(7 downto 0);
+ end record;
-- This needs to die...
type ctrl_t is record
tb: std_ulogic_vector(63 downto 0);
dec: std_ulogic_vector(63 downto 0);
msr: std_ulogic_vector(63 downto 0);
- irq_state : irq_state_t;
- irq_nia: std_ulogic_vector(63 downto 0);
- srr1: std_ulogic_vector(63 downto 0);
+ cfar: std_ulogic_vector(63 downto 0);
end record;
type Fetch1ToIcacheType is record
req: std_ulogic;
+ virt_mode : std_ulogic;
+ priv_mode : std_ulogic;
+ big_endian : std_ulogic;
stop_mark: std_ulogic;
+ sequential: std_ulogic;
+ predicted : std_ulogic;
+ pred_ntaken : std_ulogic;
nia: std_ulogic_vector(63 downto 0);
end record;
- type IcacheToFetch2Type is record
+ type IcacheToDecode1Type is record
valid: std_ulogic;
stop_mark: std_ulogic;
+ fetch_failed: std_ulogic;
nia: std_ulogic_vector(63 downto 0);
insn: std_ulogic_vector(31 downto 0);
+ big_endian: std_ulogic;
+ next_predicted: std_ulogic;
+ next_pred_ntaken: std_ulogic;
end record;
- type Fetch2ToDecode1Type is record
- valid: std_ulogic;
- stop_mark : std_ulogic;
- nia: std_ulogic_vector(63 downto 0);
- insn: std_ulogic_vector(31 downto 0);
+ type IcacheEventType is record
+ icache_miss : std_ulogic;
+ itlb_miss_resolved : std_ulogic;
end record;
- constant Fetch2ToDecode1Init : Fetch2ToDecode1Type := (valid => '0', stop_mark => '0', others => (others => '0'));
type Decode1ToDecode2Type is record
valid: std_ulogic;
insn: std_ulogic_vector(31 downto 0);
ispr1: gspr_index_t; -- (G)SPR used for branch condition (CTR) or mfspr
ispr2: gspr_index_t; -- (G)SPR used for branch target (CTR, LR, TAR)
+ ispro: gspr_index_t; -- (G)SPR written with LR or CTR
decode: decode_rom_t;
+ br_pred: std_ulogic; -- Branch was predicted to be taken
+ big_endian: std_ulogic;
+ end record;
+ constant Decode1ToDecode2Init : Decode1ToDecode2Type :=
+ (valid => '0', stop_mark => '0', nia => (others => '0'), insn => (others => '0'),
+ ispr1 => (others => '0'), ispr2 => (others => '0'), ispro => (others => '0'),
+ decode => decode_rom_init, br_pred => '0', big_endian => '0');
+
+ type Decode1ToFetch1Type is record
+ redirect : std_ulogic;
+ redirect_nia : std_ulogic_vector(63 downto 0);
+ end record;
+
+ type bypass_data_t is record
+ tag : instr_tag_t;
+ data : std_ulogic_vector(63 downto 0);
end record;
- constant Decode1ToDecode2Init : Decode1ToDecode2Type := (valid => '0', stop_mark => '0', decode => decode_rom_init, others => (others => '0'));
+ constant bypass_data_init : bypass_data_t := (tag => instr_tag_init, data => (others => '0'));
+
+ type cr_bypass_data_t is record
+ tag : instr_tag_t;
+ data : std_ulogic_vector(31 downto 0);
+ end record;
+ constant cr_bypass_data_init : cr_bypass_data_t := (tag => instr_tag_init, data => (others => '0'));
type Decode2ToExecute1Type is record
valid: std_ulogic;
unit : unit_t;
+ fac : facility_t;
insn_type: insn_type_t;
nia: std_ulogic_vector(63 downto 0);
+ instr_tag : instr_tag_t;
write_reg: gspr_index_t;
+ write_reg_enable: std_ulogic;
read_reg1: gspr_index_t;
read_reg2: gspr_index_t;
read_data1: std_ulogic_vector(63 downto 0);
read_data2: std_ulogic_vector(63 downto 0);
read_data3: std_ulogic_vector(63 downto 0);
- bypass_data1: std_ulogic;
- bypass_data2: std_ulogic;
- bypass_data3: std_ulogic;
cr: std_ulogic_vector(31 downto 0);
xerc: xer_common_t;
lr: std_ulogic;
+ br_abs: std_ulogic;
rc: std_ulogic;
oe: std_ulogic;
invert_a: std_ulogic;
+ addm1 : std_ulogic;
invert_out: std_ulogic;
input_carry: carry_in_t;
output_carry: std_ulogic;
input_cr: std_ulogic;
output_cr: std_ulogic;
+ output_xer: std_ulogic;
is_32bit: std_ulogic;
is_signed: std_ulogic;
insn: std_ulogic_vector(31 downto 0);
sign_extend : std_ulogic; -- do we need to sign extend?
update : std_ulogic; -- is this an update instruction?
reserve : std_ulogic; -- set for larx/stcx
+ br_pred : std_ulogic;
+ result_sel : std_ulogic_vector(2 downto 0); -- select source of result
+ sub_select : std_ulogic_vector(2 downto 0); -- sub-result selection
+ repeat : std_ulogic; -- set if instruction is cracked into two ops
+ second : std_ulogic; -- set if this is the second op
end record;
constant Decode2ToExecute1Init : Decode2ToExecute1Type :=
- (valid => '0', unit => NONE, insn_type => OP_ILLEGAL, bypass_data1 => '0', bypass_data2 => '0', bypass_data3 => '0',
- lr => '0', rc => '0', oe => '0', invert_a => '0',
- invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0', output_cr => '0',
- is_32bit => '0', is_signed => '0', xerc => xerc_init, reserve => '0',
- byte_reverse => '0', sign_extend => '0', update => '0', others => (others => '0'));
-
- type Execute1ToMultiplyType is record
+ (valid => '0', unit => NONE, fac => NONE, insn_type => OP_ILLEGAL, instr_tag => instr_tag_init,
+ write_reg_enable => '0',
+ lr => '0', br_abs => '0', rc => '0', oe => '0', invert_a => '0', addm1 => '0',
+ invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0',
+ output_cr => '0', output_xer => '0',
+ is_32bit => '0', is_signed => '0', xerc => xerc_init, reserve => '0', br_pred => '0',
+ byte_reverse => '0', sign_extend => '0', update => '0', nia => (others => '0'),
+ read_data1 => (others => '0'), read_data2 => (others => '0'), read_data3 => (others => '0'),
+ cr => (others => '0'), insn => (others => '0'), data_len => (others => '0'),
+ result_sel => "000", sub_select => "000",
+ repeat => '0', second => '0', others => (others => '0'));
+
+ type MultiplyInputType is record
valid: std_ulogic;
- insn_type: insn_type_t;
- data1: std_ulogic_vector(64 downto 0);
- data2: std_ulogic_vector(64 downto 0);
+ data1: std_ulogic_vector(63 downto 0);
+ data2: std_ulogic_vector(63 downto 0);
+ addend: std_ulogic_vector(127 downto 0);
is_32bit: std_ulogic;
+ not_result: std_ulogic;
end record;
- constant Execute1ToMultiplyInit : Execute1ToMultiplyType := (valid => '0', insn_type => OP_ILLEGAL,
- is_32bit => '0',
- others => (others => '0'));
+ constant MultiplyInputInit : MultiplyInputType := (valid => '0',
+ is_32bit => '0', not_result => '0',
+ others => (others => '0'));
+
+ type MultiplyOutputType is record
+ valid: std_ulogic;
+ result: std_ulogic_vector(127 downto 0);
+ overflow : std_ulogic;
+ end record;
+ constant MultiplyOutputInit : MultiplyOutputType := (valid => '0', overflow => '0',
+ others => (others => '0'));
type Execute1ToDividerType is record
valid: std_ulogic;
is_extended => '0', is_modulus => '0',
neg_result => '0', others => (others => '0'));
+ type PMUEventType is record
+ no_instr_avail : std_ulogic;
+ dispatch : std_ulogic;
+ ext_interrupt : std_ulogic;
+ instr_complete : std_ulogic;
+ fp_complete : std_ulogic;
+ ld_complete : std_ulogic;
+ st_complete : std_ulogic;
+ br_taken_complete : std_ulogic;
+ br_mispredict : std_ulogic;
+ ipref_discard : std_ulogic;
+ itlb_miss : std_ulogic;
+ itlb_miss_resolved : std_ulogic;
+ icache_miss : std_ulogic;
+ dc_miss_resolved : std_ulogic;
+ dc_load_miss : std_ulogic;
+ dc_ld_miss_resolved : std_ulogic;
+ dc_store_miss : std_ulogic;
+ dtlb_miss : std_ulogic;
+ dtlb_miss_resolved : std_ulogic;
+ ld_miss_nocache : std_ulogic;
+ ld_fill_nocache : std_ulogic;
+ end record;
+ constant PMUEventInit : PMUEventType := (others => '0');
+
+ type Execute1ToPMUType is record
+ mfspr : std_ulogic;
+ mtspr : std_ulogic;
+ spr_num : std_ulogic_vector(4 downto 0);
+ spr_val : std_ulogic_vector(63 downto 0);
+ tbbits : std_ulogic_vector(3 downto 0); -- event bits from timebase
+ pmm_msr : std_ulogic; -- PMM bit from MSR
+ pr_msr : std_ulogic; -- PR bit from MSR
+ run : std_ulogic;
+ nia : std_ulogic_vector(63 downto 0);
+ addr : std_ulogic_vector(63 downto 0);
+ addr_v : std_ulogic;
+ occur : PMUEventType;
+ end record;
+
+ type PMUToExecute1Type is record
+ spr_val : std_ulogic_vector(63 downto 0);
+ intr : std_ulogic;
+ end record;
+
type Decode2ToRegisterFileType is record
read1_enable : std_ulogic;
read1_reg : gspr_index_t;
read2_enable : std_ulogic;
read2_reg : gspr_index_t;
read3_enable : std_ulogic;
- read3_reg : gpr_index_t;
+ read3_reg : gspr_index_t;
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);
+ 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_xerc_data : xer_common_t;
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 Execute1ToLoadstore1Type is record
valid : std_ulogic;
op : insn_type_t; -- what ld/st or m[tf]spr or TLB op to do
+ nia : std_ulogic_vector(63 downto 0);
+ insn : std_ulogic_vector(31 downto 0);
+ instr_tag : instr_tag_t;
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 : gpr_index_t;
+ write_reg : gspr_index_t;
length : std_ulogic_vector(3 downto 0);
ci : std_ulogic; -- cache-inhibited load/store
byte_reverse : std_ulogic;
sign_extend : std_ulogic; -- do we need to sign extend?
update : std_ulogic; -- is this an update instruction?
- update_reg : gpr_index_t; -- if so, the register to update
xerc : xer_common_t;
reserve : std_ulogic; -- set for larx/stcx.
rc : std_ulogic; -- set for stcx.
virt_mode : std_ulogic; -- do translation through TLB
priv_mode : std_ulogic; -- privileged mode (MSR[PR] = 0)
- spr_num : spr_num_t; -- SPR number for mfspr/mtspr
+ mode_32bit : std_ulogic; -- trim addresses to 32 bits
+ is_32bit : std_ulogic;
+ repeat : std_ulogic;
+ second : std_ulogic;
+ msr : std_ulogic_vector(63 downto 0);
end record;
- constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type := (valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0',
- sign_extend => '0', update => '0', xerc => xerc_init,
- reserve => '0', rc => '0', virt_mode => '0', priv_mode => '0',
- spr_num => 0, others => (others => '0'));
+ constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type :=
+ (valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0',
+ sign_extend => '0', update => '0', xerc => xerc_init,
+ reserve => '0', rc => '0', virt_mode => '0', priv_mode => '0',
+ nia => (others => '0'), insn => (others => '0'),
+ instr_tag => instr_tag_init,
+ addr1 => (others => '0'), addr2 => (others => '0'), data => (others => '0'),
+ write_reg => (others => '0'),
+ length => (others => '0'),
+ mode_32bit => '0', is_32bit => '0',
+ repeat => '0', second => '0',
+ msr => (others => '0'));
type Loadstore1ToExecute1Type is record
- exception : std_ulogic;
+ busy : std_ulogic;
+ in_progress : std_ulogic;
+ interrupt : std_ulogic;
end record;
type Loadstore1ToDcacheType is record
valid : std_ulogic;
+ hold : std_ulogic;
load : std_ulogic; -- is this a load
dcbz : std_ulogic;
nc : std_ulogic;
reserve : std_ulogic;
+ atomic : std_ulogic; -- part of a multi-transfer atomic op
+ atomic_last : std_ulogic;
virt_mode : std_ulogic;
priv_mode : std_ulogic;
addr : std_ulogic_vector(63 downto 0);
- data : std_ulogic_vector(63 downto 0);
+ data : std_ulogic_vector(63 downto 0); -- valid the cycle after .valid = 1
byte_sel : std_ulogic_vector(7 downto 0);
end record;
data : std_ulogic_vector(63 downto 0);
store_done : std_ulogic;
error : std_ulogic;
- tlb_miss : std_ulogic;
- perm_error : std_ulogic;
- rc_error : std_ulogic;
+ cache_paradox : std_ulogic;
+ end record;
+
+ type DcacheEventType is record
+ load_miss : std_ulogic;
+ store_miss : std_ulogic;
+ dcache_refill : std_ulogic;
+ dtlb_miss : std_ulogic;
+ dtlb_miss_resolved : std_ulogic;
end record;
type Loadstore1ToMmuType is record
valid : std_ulogic;
tlbie : std_ulogic;
+ slbia : std_ulogic;
+ mtspr : std_ulogic;
+ iside : std_ulogic;
+ load : std_ulogic;
+ priv : std_ulogic;
+ sprn : std_ulogic_vector(9 downto 0);
addr : std_ulogic_vector(63 downto 0);
rs : std_ulogic_vector(63 downto 0);
end record;
type MmuToLoadstore1Type is record
- done : std_ulogic;
- error : std_ulogic;
+ done : std_ulogic;
+ err : std_ulogic;
+ invalid : std_ulogic;
+ badtree : std_ulogic;
+ segerr : std_ulogic;
+ perm_error : std_ulogic;
+ rc_error : std_ulogic;
+ sprval : std_ulogic_vector(63 downto 0);
end record;
type MmuToDcacheType is record
valid : std_ulogic;
tlbie : std_ulogic;
+ doall : std_ulogic;
+ tlbld : std_ulogic;
addr : std_ulogic_vector(63 downto 0);
pte : std_ulogic_vector(63 downto 0);
end record;
type DcacheToMmuType is record
stall : std_ulogic;
done : std_ulogic;
+ err : std_ulogic;
+ data : std_ulogic_vector(63 downto 0);
+ end record;
+
+ type MmuToIcacheType is record
+ tlbld : std_ulogic;
+ tlbie : std_ulogic;
+ doall : std_ulogic;
+ addr : std_ulogic_vector(63 downto 0);
+ pte : std_ulogic_vector(63 downto 0);
end record;
type Loadstore1ToWritebackType is record
valid : std_ulogic;
+ instr_tag : instr_tag_t;
write_enable: std_ulogic;
- write_reg : gpr_index_t;
+ write_reg : gspr_index_t;
write_data : std_ulogic_vector(63 downto 0);
xerc : xer_common_t;
rc : std_ulogic;
store_done : std_ulogic;
+ interrupt : std_ulogic;
+ intr_vec : intr_vector_t;
+ srr0: std_ulogic_vector(63 downto 0);
+ srr1: std_ulogic_vector(15 downto 0);
+ end record;
+ constant Loadstore1ToWritebackInit : Loadstore1ToWritebackType :=
+ (valid => '0', instr_tag => instr_tag_init, write_enable => '0',
+ write_reg => (others => '0'), write_data => (others => '0'),
+ xerc => xerc_init, rc => '0', store_done => '0',
+ interrupt => '0', intr_vec => 0,
+ srr0 => (others => '0'), srr1 => (others => '0'));
+
+ type Loadstore1EventType is record
+ load_complete : std_ulogic;
+ store_complete : std_ulogic;
+ itlb_miss : std_ulogic;
end record;
- constant Loadstore1ToWritebackInit : Loadstore1ToWritebackType := (valid => '0', write_enable => '0', xerc => xerc_init,
- rc => '0', store_done => '0', others => (others => '0'));
type Execute1ToWritebackType is record
valid: std_ulogic;
+ instr_tag : instr_tag_t;
rc : std_ulogic;
+ mode_32bit : std_ulogic;
write_enable : std_ulogic;
write_reg: gspr_index_t;
write_data: std_ulogic_vector(63 downto 0);
write_cr_data : std_ulogic_vector(31 downto 0);
write_xerc_enable : std_ulogic;
xerc : xer_common_t;
- exc_write_enable : std_ulogic;
- exc_write_reg : gspr_index_t;
- exc_write_data : std_ulogic_vector(63 downto 0);
+ interrupt : std_ulogic;
+ intr_vec : intr_vector_t;
+ redirect: std_ulogic;
+ redir_mode: std_ulogic_vector(3 downto 0);
+ last_nia: std_ulogic_vector(63 downto 0);
+ br_offset: std_ulogic_vector(63 downto 0);
+ br_last: std_ulogic;
+ br_taken: std_ulogic;
+ abs_br: std_ulogic;
+ srr1: std_ulogic_vector(15 downto 0);
+ msr: std_ulogic_vector(63 downto 0);
end record;
- constant Execute1ToWritebackInit : Execute1ToWritebackType := (valid => '0', rc => '0', write_enable => '0',
- write_cr_enable => '0', exc_write_enable => '0',
- write_xerc_enable => '0', xerc => xerc_init,
- others => (others => '0'));
-
- type MultiplyToExecute1Type is record
- valid: std_ulogic;
- write_reg_data: std_ulogic_vector(63 downto 0);
- overflow : std_ulogic;
+ constant Execute1ToWritebackInit : Execute1ToWritebackType :=
+ (valid => '0', instr_tag => instr_tag_init, rc => '0', mode_32bit => '0',
+ write_enable => '0', write_cr_enable => '0',
+ write_xerc_enable => '0', xerc => xerc_init,
+ write_data => (others => '0'), write_cr_mask => (others => '0'),
+ write_cr_data => (others => '0'), write_reg => (others => '0'),
+ interrupt => '0', intr_vec => 0, redirect => '0', redir_mode => "0000",
+ last_nia => (others => '0'), br_offset => (others => '0'),
+ br_last => '0', br_taken => '0', abs_br => '0',
+ srr1 => (others => '0'), msr => (others => '0'));
+
+ type Execute1ToFPUType is record
+ valid : std_ulogic;
+ op : insn_type_t;
+ nia : std_ulogic_vector(63 downto 0);
+ itag : instr_tag_t;
+ insn : std_ulogic_vector(31 downto 0);
+ single : std_ulogic;
+ fe_mode : std_ulogic_vector(1 downto 0);
+ fra : std_ulogic_vector(63 downto 0);
+ frb : std_ulogic_vector(63 downto 0);
+ frc : std_ulogic_vector(63 downto 0);
+ frt : gspr_index_t;
+ rc : std_ulogic;
+ out_cr : std_ulogic;
end record;
- constant MultiplyToExecute1Init : MultiplyToExecute1Type := (valid => '0', overflow => '0',
- others => (others => '0'));
+ constant Execute1ToFPUInit : Execute1ToFPUType := (valid => '0', op => OP_ILLEGAL, nia => (others => '0'),
+ itag => instr_tag_init,
+ insn => (others => '0'), fe_mode => "00", rc => '0',
+ fra => (others => '0'), frb => (others => '0'),
+ frc => (others => '0'), frt => (others => '0'),
+ single => '0', out_cr => '0');
+
+ type FPUToExecute1Type is record
+ busy : std_ulogic;
+ exception : std_ulogic;
+ end record;
+ constant FPUToExecute1Init : FPUToExecute1Type := (others => '0');
+
+ type FPUToWritebackType is record
+ valid : std_ulogic;
+ interrupt : std_ulogic;
+ instr_tag : instr_tag_t;
+ write_enable : std_ulogic;
+ write_reg : gspr_index_t;
+ 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);
+ intr_vec : intr_vector_t;
+ srr0 : std_ulogic_vector(63 downto 0);
+ srr1 : std_ulogic_vector(15 downto 0);
+ end record;
+ constant FPUToWritebackInit : FPUToWritebackType :=
+ (valid => '0', interrupt => '0', instr_tag => instr_tag_init,
+ write_enable => '0', write_reg => (others => '0'),
+ write_cr_enable => '0', write_cr_mask => (others => '0'),
+ write_cr_data => (others => '0'),
+ intr_vec => 0, srr1 => (others => '0'),
+ others => (others => '0'));
type DividerToExecute1Type is record
valid: std_ulogic;
constant DividerToExecute1Init : DividerToExecute1Type := (valid => '0', overflow => '0',
others => (others => '0'));
+ type WritebackToFetch1Type is record
+ redirect: std_ulogic;
+ virt_mode: std_ulogic;
+ priv_mode: std_ulogic;
+ big_endian: std_ulogic;
+ mode_32bit: std_ulogic;
+ redirect_nia: std_ulogic_vector(63 downto 0);
+ br_nia : std_ulogic_vector(63 downto 0);
+ br_last : std_ulogic;
+ br_taken : std_ulogic;
+ end record;
+ constant WritebackToFetch1Init : WritebackToFetch1Type :=
+ (redirect => '0', virt_mode => '0', priv_mode => '0', big_endian => '0',
+ mode_32bit => '0', redirect_nia => (others => '0'),
+ br_last => '0', br_taken => '0', br_nia => (others => '0'));
+
type WritebackToRegisterFileType is record
write_reg : gspr_index_t;
write_data : std_ulogic_vector(63 downto 0);
write_enable : std_ulogic;
end record;
- constant WritebackToRegisterFileInit : WritebackToRegisterFileType := (write_enable => '0', others => (others => '0'));
+ constant WritebackToRegisterFileInit : WritebackToRegisterFileType :=
+ (write_enable => '0', write_data => (others => '0'), others => (others => '0'));
type WritebackToCrFileType is record
write_cr_enable : std_ulogic;
end record;
constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', write_xerc_enable => '0',
write_xerc_data => xerc_init,
- others => (others => '0'));
+ write_cr_mask => (others => '0'),
+ write_cr_data => (others => '0'));
- type XicsToExecute1Type is record
- irq : std_ulogic;
+ type WritebackEventType is record
+ instr_complete : std_ulogic;
+ fp_complete : std_ulogic;
end record;
end common;
end;
function fast_spr_num(spr: spr_num_t) return gspr_index_t is
variable n : integer range 0 to 31;
+ -- tmp variable introduced as workaround for VCS compilation
+ -- simulation was failing with subtype constraint mismatch error
+ -- see GitHub PR #173
+ variable tmp : std_ulogic_vector(4 downto 0);
begin
case spr is
when SPR_LR =>
- n := 0;
+ n := 0; -- N.B. decode2 relies on this specific value
when SPR_CTR =>
- n:= 1;
+ n := 1; -- N.B. decode2 relies on this specific value
when SPR_SRR0 =>
n := 2;
when SPR_SRR1 =>
n := 11;
when SPR_XER =>
n := 12;
+ when SPR_TAR =>
+ n := 13;
when others =>
n := 0;
- return "000000";
+ return "0000000";
end case;
- return "1" & std_ulogic_vector(to_unsigned(n, 5));
+ tmp := std_ulogic_vector(to_unsigned(n, 5));
+ return "01" & tmp;
end;
function gspr_to_gpr(i: gspr_index_t) return gpr_index_t is
function gpr_to_gspr(i: gpr_index_t) return gspr_index_t is
begin
- return "0" & i;
+ return "00" & i;
end;
function gpr_or_spr_to_gspr(g: gpr_index_t; s: gspr_index_t) return gspr_index_t is
begin
return s(5);
end;
+
+ function fpr_to_gspr(f: fpr_index_t) return gspr_index_t is
+ begin
+ return "10" & f;
+ end;
+
+ function tag_match(tag1 : instr_tag_t; tag2 : instr_tag_t) return boolean is
+ begin
+ return tag1.valid = '1' and tag2.valid = '1' and tag1.tag = tag2.tag;
+ end;
+
+ function addr_to_real(addr: std_ulogic_vector(63 downto 0)) return real_addr_t is
+ begin
+ return addr(real_addr_t'range);
+ end;
end common;