mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
This implements the EVIRT bit in the LPCR register. When set to 1, EVIRT causes mfspr and mtspr to an undefined SPR number in privileged mode (i.e. hypervisor mode) to cause a hypervisor emulation assistance interrupt. When set to 0, such instructions are executed as no-ops. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
995 lines
39 KiB
VHDL
995 lines
39 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
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_HV : integer := (63 - 3); -- Hypervisor mode (always 1)
|
|
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
|
|
|
|
-- SPR numbers
|
|
subtype spr_num_t is integer range 0 to 1023;
|
|
|
|
function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t;
|
|
|
|
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_TBLW : spr_num_t := 284;
|
|
constant SPR_TBUW : spr_num_t := 285;
|
|
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_SPRG1 : spr_num_t := 273;
|
|
constant SPR_SPRG2 : spr_num_t := 274;
|
|
constant SPR_SPRG3 : spr_num_t := 275;
|
|
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_LPCR : spr_num_t := 318;
|
|
constant SPR_PVR : spr_num_t := 287;
|
|
constant SPR_FSCR : spr_num_t := 153;
|
|
constant SPR_HFSCR : spr_num_t := 190;
|
|
constant SPR_HEIR : spr_num_t := 339;
|
|
constant SPR_CTRL : spr_num_t := 136;
|
|
constant SPR_CTRLW : spr_num_t := 152;
|
|
constant SPR_UDSCR : spr_num_t := 3;
|
|
constant SPR_DSCR : spr_num_t := 17;
|
|
constant SPR_VRSAVE : spr_num_t := 256;
|
|
constant SPR_PIR : spr_num_t := 1023;
|
|
constant SPR_CIABR : spr_num_t := 187;
|
|
constant SPR_DAWR0 : spr_num_t := 180;
|
|
constant SPR_DAWR1 : spr_num_t := 181;
|
|
constant SPR_DAWRX0 : spr_num_t := 188;
|
|
constant SPR_DAWRX1 : spr_num_t := 189;
|
|
constant SPR_HASHKEYR : spr_num_t := 468;
|
|
constant SPR_HASHPKEYR : spr_num_t := 469;
|
|
constant SPR_DEXCR : spr_num_t := 828;
|
|
constant SPR_DEXCRU : spr_num_t := 812;
|
|
constant SPR_HDEXCR : spr_num_t := 471;
|
|
constant SPR_HDEXCU : spr_num_t := 455;
|
|
constant SPR_NOOP0 : spr_num_t := 808;
|
|
constant SPR_NOOP1 : spr_num_t := 809;
|
|
constant SPR_NOOP2 : spr_num_t := 810;
|
|
constant SPR_NOOP3 : spr_num_t := 811;
|
|
constant SPR_HMER : spr_num_t := 336;
|
|
constant SPR_HMEER : spr_num_t := 337;
|
|
constant SPR_HRMOR : spr_num_t := 313;
|
|
|
|
-- 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_USIER2 : spr_num_t := 736;
|
|
constant SPR_USIER3 : spr_num_t := 737;
|
|
constant SPR_UMMCR3 : spr_num_t := 738;
|
|
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;
|
|
constant SPR_SIER2 : spr_num_t := 752;
|
|
constant SPR_SIER3 : spr_num_t := 753;
|
|
constant SPR_MMCR3 : spr_num_t := 754;
|
|
|
|
-- GPR indices in the register file (GPR only)
|
|
subtype gpr_index_t is std_ulogic_vector(4 downto 0);
|
|
|
|
-- Extended GPR index (can hold a GPR or a FPR)
|
|
subtype gspr_index_t is std_ulogic_vector(5 downto 0);
|
|
|
|
-- FPR indices
|
|
subtype fpr_index_t is std_ulogic_vector(4 downto 0);
|
|
|
|
-- FPRs are stored in the register file, using GSPR
|
|
-- numbers from 32 to 63.
|
|
--
|
|
|
|
-- Indices conversion functions
|
|
function gspr_to_gpr(i: gspr_index_t) return gpr_index_t;
|
|
function gpr_to_gspr(i: gpr_index_t) return gspr_index_t;
|
|
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
|
|
-- control). The rest is stored in ctrl_t (effectively in execute1).
|
|
type xer_common_t is record
|
|
ca : std_ulogic;
|
|
ca32 : std_ulogic;
|
|
ov : std_ulogic;
|
|
ov32 : std_ulogic;
|
|
so : std_ulogic;
|
|
end record;
|
|
constant xerc_init : xer_common_t := (others => '0');
|
|
|
|
-- Some SPRs are stored in a pair of small RAMs in execute1
|
|
-- Even half:
|
|
subtype ramspr_index_range is natural range 0 to 7;
|
|
subtype ramspr_index is unsigned(2 downto 0);
|
|
constant RAMSPR_SRR0 : ramspr_index := to_unsigned(0,3);
|
|
constant RAMSPR_HSRR0 : ramspr_index := to_unsigned(1,3);
|
|
constant RAMSPR_SPRG0 : ramspr_index := to_unsigned(2,3);
|
|
constant RAMSPR_SPRG2 : ramspr_index := to_unsigned(3,3);
|
|
constant RAMSPR_HSPRG0 : ramspr_index := to_unsigned(4,3);
|
|
constant RAMSPR_LR : ramspr_index := to_unsigned(5,3); -- must equal RAMSPR_CTR
|
|
constant RAMSPR_TAR : ramspr_index := to_unsigned(6,3);
|
|
constant RAMSPR_VRSAVE : ramspr_index := to_unsigned(7,3);
|
|
-- Odd half:
|
|
constant RAMSPR_SRR1 : ramspr_index := to_unsigned(0,3);
|
|
constant RAMSPR_HSRR1 : ramspr_index := to_unsigned(1,3);
|
|
constant RAMSPR_SPRG1 : ramspr_index := to_unsigned(2,3);
|
|
constant RAMSPR_SPRG3 : ramspr_index := to_unsigned(3,3);
|
|
constant RAMSPR_HSPRG1 : ramspr_index := to_unsigned(4,3);
|
|
constant RAMSPR_CTR : ramspr_index := to_unsigned(5,3); -- must equal RAMSPR_LR
|
|
constant RAMSPR_HASHKY : ramspr_index := to_unsigned(6,3);
|
|
constant RAMSPR_HASHPK : ramspr_index := to_unsigned(7,3);
|
|
|
|
type ram_spr_info is record
|
|
index : ramspr_index;
|
|
isodd : std_ulogic;
|
|
is32b : std_ulogic;
|
|
valid : std_ulogic;
|
|
end record;
|
|
constant ram_spr_info_init: ram_spr_info := (index => to_unsigned(0,3), others => '0');
|
|
|
|
subtype spr_selector is std_ulogic_vector(3 downto 0);
|
|
type spr_id is record
|
|
sel : spr_selector;
|
|
valid : std_ulogic;
|
|
ispmu : std_ulogic;
|
|
ronly : std_ulogic;
|
|
wonly : std_ulogic;
|
|
noop : std_ulogic;
|
|
end record;
|
|
constant spr_id_init : spr_id := (sel => "0000", others => '0');
|
|
|
|
constant SPRSEL_ZERO : spr_selector := 4x"0";
|
|
constant SPRSEL_TB : spr_selector := 4x"1";
|
|
constant SPRSEL_TBU : spr_selector := 4x"2";
|
|
constant SPRSEL_DEC : spr_selector := 4x"3";
|
|
constant SPRSEL_PVR : spr_selector := 4x"4";
|
|
constant SPRSEL_LOGR : spr_selector := 4x"5";
|
|
constant SPRSEL_CFAR : spr_selector := 4x"6";
|
|
constant SPRSEL_FSCR : spr_selector := 4x"7";
|
|
constant SPRSEL_LPCR : spr_selector := 4x"8";
|
|
constant SPRSEL_HEIR : spr_selector := 4x"9";
|
|
constant SPRSEL_CTRL : spr_selector := 4x"a";
|
|
constant SPRSEL_DSCR : spr_selector := 4x"b";
|
|
constant SPRSEL_PIR : spr_selector := 4x"c";
|
|
constant SPRSEL_CIABR : spr_selector := 4x"d";
|
|
constant SPRSEL_DEXCR : spr_selector := 4x"e";
|
|
constant SPRSEL_XER : spr_selector := 4x"f";
|
|
|
|
-- FSCR bit numbers
|
|
constant FSCR_PREFIX : integer := 63 - 50;
|
|
constant FSCR_SCV : integer := 63 - 51;
|
|
constant FSCR_TAR : integer := 63 - 55;
|
|
constant FSCR_DSCR : integer := 63 - 61;
|
|
|
|
-- 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;
|
|
|
|
-- LPCR bit numbers
|
|
constant LPCR_HAIL : integer := 63 - 37;
|
|
constant LPCR_UPRT : integer := 63 - 41;
|
|
constant LPCR_EVIRT : integer := 63 - 42;
|
|
constant LPCR_HR : integer := 63 - 43;
|
|
constant LPCR_LD : integer := 63 - 46;
|
|
constant LPCR_HEIC : integer := 63 - 59;
|
|
constant LPCR_LPES : integer := 63 - 60;
|
|
constant LPCR_HVICE : integer := 63 - 62;
|
|
|
|
-- 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;
|
|
|
|
-- Minimum page size
|
|
constant MIN_LG_PGSZ : positive := 12;
|
|
constant MIN_PAGESZ : positive := 2 ** MIN_LG_PGSZ;
|
|
|
|
-- 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.
|
|
-- We don't know NCPUS or SRC_NUM here, so make this
|
|
-- large enough for 4 cpus and 16 interrupt sources for now.
|
|
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(15 downto 0); -- 4 bits each for 4 cpus
|
|
pri : std_ulogic_vector(31 downto 0); -- 8 bits each for 4 cpus
|
|
end record;
|
|
|
|
-- Bits in each half of DEXCR and HDEXCR
|
|
subtype aspect_bits_t is std_ulogic_vector(4 downto 0);
|
|
constant aspect_bits_init : aspect_bits_t := (others => '1');
|
|
-- Bit numbers in aspect_bits_t
|
|
constant DEXCR_SBHE : integer := 4; -- speculative branch hint enable
|
|
constant DEXCR_IBRTPD : integer := 3; -- indirect branch recurrent target prediction disable
|
|
constant DEXCR_SRAPD : integer := 2; -- subroutine return address prediction disable
|
|
constant DEXCR_NPHIE : integer := 1; -- non-privileged hash instruction enable
|
|
constant DEXCR_PHIE : integer := 0; -- privileged hash instruction enable
|
|
|
|
-- This needs to die...
|
|
type ctrl_t is record
|
|
wait_state: std_ulogic;
|
|
run: std_ulogic;
|
|
dec: std_ulogic_vector(63 downto 0);
|
|
msr: std_ulogic_vector(63 downto 0);
|
|
cfar: std_ulogic_vector(63 downto 0);
|
|
xer_low: std_ulogic_vector(17 downto 0);
|
|
fscr_ic: std_ulogic_vector(3 downto 0);
|
|
fscr_pref: std_ulogic;
|
|
fscr_scv: std_ulogic;
|
|
fscr_tar: std_ulogic;
|
|
fscr_dscr: std_ulogic;
|
|
heir: std_ulogic_vector(63 downto 0);
|
|
dscr: std_ulogic_vector(24 downto 0);
|
|
ciabr: std_ulogic_vector(63 downto 0);
|
|
dexcr_pnh: aspect_bits_t;
|
|
dexcr_pro: aspect_bits_t;
|
|
hdexcr_hyp: aspect_bits_t;
|
|
hdexcr_enf: aspect_bits_t;
|
|
lpcr_hail: std_ulogic;
|
|
lpcr_evirt: std_ulogic;
|
|
lpcr_ld: std_ulogic;
|
|
lpcr_heic: std_ulogic;
|
|
lpcr_lpes: std_ulogic;
|
|
lpcr_hvice: std_ulogic;
|
|
end record;
|
|
constant ctrl_t_init : ctrl_t :=
|
|
(wait_state => '0', run => '1', xer_low => 18x"0",
|
|
fscr_ic => x"0", fscr_pref => '1', fscr_scv => '1', fscr_tar => '1', fscr_dscr => '1',
|
|
dscr => (others => '0'),
|
|
dexcr_pnh => aspect_bits_init, dexcr_pro => aspect_bits_init,
|
|
hdexcr_hyp => aspect_bits_init, hdexcr_enf => aspect_bits_init,
|
|
lpcr_hail => '0', lpcr_evirt => '0', lpcr_ld => '1', lpcr_heic => '0',
|
|
lpcr_lpes => '0', lpcr_hvice => '0',
|
|
others => (others => '0'));
|
|
|
|
type timebase_ctrl is record
|
|
reset : std_ulogic;
|
|
rd_prot : std_ulogic; -- read-protect => userspace can't read TB
|
|
freeze : std_ulogic;
|
|
end record;
|
|
|
|
type Fetch1ToIcacheType is record
|
|
req: std_ulogic;
|
|
fetch_fail : std_ulogic;
|
|
virt_mode : std_ulogic;
|
|
priv_mode : std_ulogic;
|
|
big_endian : std_ulogic;
|
|
stop_mark: std_ulogic;
|
|
predicted : std_ulogic;
|
|
pred_ntaken : std_ulogic;
|
|
nia: std_ulogic_vector(63 downto 0);
|
|
next_nia: std_ulogic_vector(63 downto 0);
|
|
rpn: std_ulogic_vector(REAL_ADDR_BITS - MIN_LG_PGSZ - 1 downto 0);
|
|
next_rpn: std_ulogic_vector(REAL_ADDR_BITS - MIN_LG_PGSZ - 1 downto 0);
|
|
end 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);
|
|
icode: insn_code;
|
|
big_endian: std_ulogic;
|
|
next_predicted: std_ulogic;
|
|
next_pred_ntaken: std_ulogic;
|
|
end record;
|
|
constant IcacheToDecode1Init : IcacheToDecode1Type :=
|
|
(nia => (others => '0'), insn => (others => '0'), icode => INSN_illegal, others => '0');
|
|
|
|
type IcacheEventType is record
|
|
icache_miss : std_ulogic;
|
|
itlb_miss_resolved : std_ulogic;
|
|
end record;
|
|
|
|
type Decode1ToDecode2Type is record
|
|
valid: std_ulogic;
|
|
stop_mark : std_ulogic;
|
|
second : std_ulogic;
|
|
nia: std_ulogic_vector(63 downto 0);
|
|
prefixed: std_ulogic;
|
|
prefix: std_ulogic_vector(25 downto 0);
|
|
illegal_suffix: std_ulogic;
|
|
misaligned_prefix: std_ulogic;
|
|
insn: std_ulogic_vector(31 downto 0);
|
|
decode: decode_rom_t;
|
|
br_pred: std_ulogic; -- Branch was predicted to be taken
|
|
big_endian: std_ulogic;
|
|
spr_info : spr_id;
|
|
ram_spr : ram_spr_info;
|
|
reg_a : gspr_index_t;
|
|
reg_b : gspr_index_t;
|
|
reg_c : gspr_index_t;
|
|
end record;
|
|
constant Decode1ToDecode2Init : Decode1ToDecode2Type :=
|
|
(valid => '0', stop_mark => '0', second => '0', nia => (others => '0'),
|
|
prefixed => '0', prefix => (others => '0'), insn => (others => '0'),
|
|
illegal_suffix => '0', misaligned_prefix => '0',
|
|
decode => decode_rom_init, br_pred => '0', big_endian => '0',
|
|
spr_info => spr_id_init, ram_spr => ram_spr_info_init,
|
|
reg_a => (others => '0'), reg_b => (others => '0'), reg_c => (others => '0'));
|
|
|
|
type Decode1ToFetch1Type is record
|
|
redirect : std_ulogic;
|
|
redirect_nia : std_ulogic_vector(63 downto 0);
|
|
end record;
|
|
|
|
type Decode1ToRegisterFileType is record
|
|
reg_1_addr : gspr_index_t;
|
|
reg_2_addr : gspr_index_t;
|
|
reg_3_addr : gspr_index_t;
|
|
read_1_enable : std_ulogic;
|
|
read_2_enable : std_ulogic;
|
|
read_3_enable : std_ulogic;
|
|
end record;
|
|
|
|
type bypass_data_t is record
|
|
tag : instr_tag_t;
|
|
reg : gspr_index_t;
|
|
data : std_ulogic_vector(63 downto 0);
|
|
end record;
|
|
constant bypass_data_init : bypass_data_t :=
|
|
(tag => instr_tag_init, reg => (others => '0'), 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_reg3: 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);
|
|
reg_valid1: std_ulogic;
|
|
reg_valid2: std_ulogic;
|
|
reg_valid3: 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;
|
|
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);
|
|
data_len: 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?
|
|
reserve : std_ulogic; -- set for larx/stcx
|
|
br_pred : std_ulogic;
|
|
result_sel : result_sel_t; -- select source of result
|
|
sub_select : subresult_sel_t; -- sub-result selection
|
|
repeat : std_ulogic; -- set if instruction is cracked into two ops
|
|
second : std_ulogic; -- set if this is the second op
|
|
spr_select : spr_id;
|
|
spr_is_ram : std_ulogic;
|
|
ramspr_even_rdaddr : ramspr_index;
|
|
ramspr_odd_rdaddr : ramspr_index;
|
|
ramspr_rd_odd : std_ulogic;
|
|
ramspr_wraddr : ramspr_index;
|
|
ramspr_write_even : std_ulogic;
|
|
ramspr_write_odd : std_ulogic;
|
|
ramspr_32bit : std_ulogic;
|
|
dbg_spr_access : std_ulogic;
|
|
dec_ctr : std_ulogic;
|
|
privileged : std_ulogic;
|
|
prefixed : std_ulogic;
|
|
prefix : std_ulogic_vector(25 downto 0);
|
|
illegal_suffix : std_ulogic;
|
|
misaligned_prefix : std_ulogic;
|
|
illegal_form : std_ulogic;
|
|
uses_tar : std_ulogic;
|
|
uses_dscr : std_ulogic;
|
|
right_shift : std_ulogic;
|
|
rot_clear_left : std_ulogic;
|
|
rot_clear_right : std_ulogic;
|
|
rot_sign_ext : std_ulogic;
|
|
do_popcnt : std_ulogic;
|
|
end record;
|
|
constant Decode2ToExecute1Init : Decode2ToExecute1Type :=
|
|
(valid => '0', unit => ALU, 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',
|
|
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'),
|
|
reg_valid1 => '0', reg_valid2 => '0', reg_valid3 => '0',
|
|
cr => (others => '0'), insn => (others => '0'), data_len => (others => '0'),
|
|
result_sel => ADD, sub_select => "000",
|
|
repeat => '0', second => '0', spr_select => spr_id_init,
|
|
spr_is_ram => '0',
|
|
ramspr_even_rdaddr => (others => '0'), ramspr_odd_rdaddr => (others => '0'), ramspr_rd_odd => '0',
|
|
ramspr_wraddr => (others => '0'), ramspr_write_even => '0', ramspr_write_odd => '0',
|
|
ramspr_32bit => '0',
|
|
dbg_spr_access => '0',
|
|
dec_ctr => '0',
|
|
privileged => '0', prefixed => '0', prefix => (others => '0'), illegal_suffix => '0',
|
|
misaligned_prefix => '0', illegal_form => '0', uses_tar => '0', uses_dscr => '0',
|
|
right_shift => '0', rot_clear_left => '0', rot_clear_right => '0', rot_sign_ext => '0',
|
|
do_popcnt => '0',
|
|
others => (others => '0'));
|
|
|
|
type MultiplyInputType is record
|
|
valid: std_ulogic;
|
|
data1: std_ulogic_vector(63 downto 0);
|
|
data2: std_ulogic_vector(63 downto 0);
|
|
addend: std_ulogic_vector(127 downto 0);
|
|
is_signed: std_ulogic;
|
|
subtract: std_ulogic; -- 0 => addend + data1 * data2, 1 => addend - data1 * data2
|
|
end record;
|
|
constant MultiplyInputInit : MultiplyInputType := (data1 => 64x"0", data2 => 64x"0",
|
|
addend => 128x"0", 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;
|
|
flush: std_ulogic;
|
|
dividend: std_ulogic_vector(63 downto 0);
|
|
divisor: std_ulogic_vector(63 downto 0);
|
|
is_signed: std_ulogic;
|
|
is_32bit: std_ulogic;
|
|
is_extended: std_ulogic;
|
|
is_modulus: std_ulogic;
|
|
neg_result: std_ulogic;
|
|
end record;
|
|
constant Execute1ToDividerInit: Execute1ToDividerType := (
|
|
dividend => 64x"0", divisor => 64x"0", 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;
|
|
trace : 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;
|
|
read2_enable : std_ulogic;
|
|
read3_enable : std_ulogic;
|
|
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 : std_ulogic;
|
|
end record;
|
|
|
|
type CrFileToDecode2Type is record
|
|
read_cr_data : std_ulogic_vector(31 downto 0);
|
|
read_xerc_data : xer_common_t;
|
|
end record;
|
|
|
|
type Execute1ToLoadstore1Type is record
|
|
valid : std_ulogic;
|
|
op : insn_type_t; -- what ld/st or m[tf]spr or TLB op to do
|
|
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 : 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?
|
|
hash : std_ulogic;
|
|
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)
|
|
mode_32bit : std_ulogic; -- trim addresses to 32 bits
|
|
is_32bit : std_ulogic;
|
|
prefixed : std_ulogic;
|
|
repeat : std_ulogic;
|
|
second : std_ulogic;
|
|
e2stall : std_ulogic;
|
|
msr : std_ulogic_vector(63 downto 0);
|
|
hashkey : std_ulogic_vector(63 downto 0);
|
|
hash_enable : std_ulogic;
|
|
end record;
|
|
constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type :=
|
|
(valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0',
|
|
sign_extend => '0', update => '0', hash => '0', xerc => xerc_init,
|
|
reserve => '0', rc => '0', virt_mode => '0', priv_mode => '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', prefixed => '0',
|
|
repeat => '0', second => '0', e2stall => '0',
|
|
msr => (others => '0'), hashkey => (others => '0'), hash_enable => '0');
|
|
|
|
type Loadstore1ToExecute1Type is record
|
|
busy : std_ulogic;
|
|
l2stall : std_ulogic;
|
|
ea_for_pmu : std_ulogic_vector(63 downto 0);
|
|
ea_valid : std_ulogic;
|
|
end record;
|
|
|
|
type Loadstore1ToDcacheType is record
|
|
valid : std_ulogic;
|
|
hold : std_ulogic;
|
|
load : std_ulogic; -- is this a load
|
|
dcbz : std_ulogic;
|
|
flush : std_ulogic;
|
|
touch : std_ulogic;
|
|
sync : std_ulogic;
|
|
nc : std_ulogic;
|
|
reserve : std_ulogic;
|
|
atomic_qw : std_ulogic; -- part of a quadword atomic op
|
|
atomic_first : std_ulogic;
|
|
atomic_last : std_ulogic;
|
|
virt_mode : std_ulogic;
|
|
priv_mode : std_ulogic;
|
|
tlb_probe : std_ulogic;
|
|
addr : 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);
|
|
dawr_match : std_ulogic; -- valid the cycle after .valid = 1
|
|
end record;
|
|
constant Loadstore1ToDcacheInit : Loadstore1ToDcacheType :=
|
|
(addr => (others => '0'), data => (others => '0'), byte_sel => x"00",
|
|
others => '0');
|
|
|
|
type DcacheToLoadstore1Type is record
|
|
valid : std_ulogic;
|
|
data : std_ulogic_vector(63 downto 0);
|
|
store_done : std_ulogic;
|
|
error : std_ulogic;
|
|
cache_paradox : std_ulogic;
|
|
reserve_nc : 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;
|
|
ric : std_ulogic_vector(1 downto 0);
|
|
sprnf : std_ulogic;
|
|
sprnt : std_ulogic;
|
|
addr : std_ulogic_vector(63 downto 0);
|
|
rs : std_ulogic_vector(63 downto 0);
|
|
end record;
|
|
|
|
type MmuToLoadstore1Type is record
|
|
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 MmuToITLBType 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 : 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;
|
|
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,
|
|
srr1 => (others => '0'));
|
|
|
|
type Loadstore1EventType is record
|
|
load_complete : std_ulogic;
|
|
store_complete : std_ulogic;
|
|
itlb_miss : std_ulogic;
|
|
end record;
|
|
|
|
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_enable : std_ulogic;
|
|
write_cr_mask : std_ulogic_vector(7 downto 0);
|
|
write_cr_data : std_ulogic_vector(31 downto 0);
|
|
write_xerc_enable : std_ulogic;
|
|
xerc : xer_common_t;
|
|
interrupt : std_ulogic;
|
|
alt_intr : std_ulogic;
|
|
hv_intr : std_ulogic;
|
|
is_scv : 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_last: std_ulogic;
|
|
br_taken: std_ulogic;
|
|
abs_br: std_ulogic;
|
|
srr1: std_ulogic_vector(15 downto 0);
|
|
end record;
|
|
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', alt_intr => '0', hv_intr => '0', is_scv => '0', intr_vec => 0,
|
|
redirect => '0', redir_mode => "0000",
|
|
last_nia => (others => '0'),
|
|
br_last => '0', br_taken => '0', abs_br => '0',
|
|
srr1 => (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;
|
|
is_signed : 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);
|
|
valid_a : std_ulogic;
|
|
valid_b : std_ulogic;
|
|
valid_c : std_ulogic;
|
|
frt : gspr_index_t;
|
|
rc : std_ulogic;
|
|
m32b : std_ulogic;
|
|
out_cr : std_ulogic;
|
|
oe : std_ulogic;
|
|
xerc : xer_common_t;
|
|
stall : std_ulogic;
|
|
end record;
|
|
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'),
|
|
valid_a => '0', valid_b => '0', valid_c => '0',
|
|
single => '0', is_signed => '0', out_cr => '0',
|
|
m32b => '0', oe => '0', xerc => xerc_init,
|
|
stall => '0');
|
|
|
|
type FPUToExecute1Type is record
|
|
busy : std_ulogic;
|
|
f2stall : 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);
|
|
write_xerc : std_ulogic;
|
|
xerc : xer_common_t;
|
|
intr_vec : intr_vector_t;
|
|
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'),
|
|
write_xerc => '0', xerc => xerc_init,
|
|
intr_vec => 0, srr1 => (others => '0'),
|
|
others => (others => '0'));
|
|
|
|
type DividerToExecute1Type is record
|
|
valid: std_ulogic;
|
|
write_reg_data: std_ulogic_vector(63 downto 0);
|
|
overflow : std_ulogic;
|
|
end record;
|
|
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;
|
|
interrupt : std_ulogic;
|
|
alt_intr : std_ulogic;
|
|
intr_vec : std_ulogic_vector(63 downto 0);
|
|
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'),
|
|
interrupt => '0', alt_intr => '0', intr_vec => 64x"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', write_data => (others => '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);
|
|
write_xerc_enable : std_ulogic;
|
|
write_xerc_data : xer_common_t;
|
|
end record;
|
|
constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', write_xerc_enable => '0',
|
|
write_xerc_data => xerc_init,
|
|
write_cr_mask => (others => '0'),
|
|
write_cr_data => (others => '0'));
|
|
|
|
type WritebackToExecute1Type is record
|
|
intr : std_ulogic;
|
|
hv_intr : std_ulogic;
|
|
scv_int : std_ulogic;
|
|
alt_int : std_ulogic;
|
|
srr1 : std_ulogic_vector(15 downto 0);
|
|
end record;
|
|
|
|
type WritebackEventType is record
|
|
instr_complete : std_ulogic;
|
|
fp_complete : std_ulogic;
|
|
end record;
|
|
|
|
end common;
|
|
|
|
package body common is
|
|
function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t is
|
|
begin
|
|
return to_integer(unsigned(insn(15 downto 11) & insn(20 downto 16)));
|
|
end;
|
|
|
|
function gspr_to_gpr(i: gspr_index_t) return gpr_index_t is
|
|
begin
|
|
return i(4 downto 0);
|
|
end;
|
|
|
|
function gpr_to_gspr(i: gpr_index_t) return gspr_index_t is
|
|
begin
|
|
return "0" & i;
|
|
end;
|
|
|
|
function fpr_to_gspr(f: fpr_index_t) return gspr_index_t is
|
|
begin
|
|
return "1" & 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;
|