SPR 704 and 705

Two sand BOX SPRs 704 and 705 were added inside the MMU and place holders are set for trace array modelling
pull/465/head
AthiRamRS 2 weeks ago
parent 6081646638
commit 9d9861bf17

@ -12,7 +12,6 @@ package common is


-- MSR bit numbers -- MSR bit numbers
constant MSR_SF : integer := (63 - 0); -- Sixty-Four bit mode 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_EE : integer := (63 - 48); -- External interrupt Enable
constant MSR_PR : integer := (63 - 49); -- PRoblem state constant MSR_PR : integer := (63 - 49); -- PRoblem state
constant MSR_FP : integer := (63 - 50); -- Floating Point available constant MSR_FP : integer := (63 - 50); -- Floating Point available
@ -120,6 +119,11 @@ package common is
constant SPR_SIER3 : spr_num_t := 753; constant SPR_SIER3 : spr_num_t := 753;
constant SPR_MMCR3 : spr_num_t := 754; constant SPR_MMCR3 : spr_num_t := 754;


-- New Sandbox SPR Identifiers
-- Dedicated telemetry/trace-array sandbox SPRs bridging execute1 and the MMU.
constant SPR_704_MMU_INPUT : integer := 704;
constant SPR_705_MMU_OUTPUT : integer := 705;

-- GPR indices in the register file (GPR only) -- GPR indices in the register file (GPR only)
subtype gpr_index_t is std_ulogic_vector(4 downto 0); subtype gpr_index_t is std_ulogic_vector(4 downto 0);


@ -180,39 +184,22 @@ package common is
end record; end record;
constant ram_spr_info_init: ram_spr_info := (index => to_unsigned(0,3), others => '0'); 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); subtype spr_selector is std_ulogic_vector(2 downto 0);
type spr_id is record type spr_id is record
sel : spr_selector; sel : spr_selector;
valid : std_ulogic; valid : std_ulogic;
ispmu : std_ulogic; ispmu : std_ulogic;
ronly : std_ulogic; end record;
wonly : std_ulogic; constant spr_id_init : spr_id := (sel => "000", others => '0');
noop : std_ulogic;
end record; constant SPRSEL_TB : spr_selector := 3x"0";
constant spr_id_init : spr_id := (sel => "0000", others => '0'); constant SPRSEL_TBU : spr_selector := 3x"1";

constant SPRSEL_DEC : spr_selector := 3x"2";
constant SPRSEL_ZERO : spr_selector := 4x"0"; constant SPRSEL_PVR : spr_selector := 3x"3";
constant SPRSEL_TB : spr_selector := 4x"1"; constant SPRSEL_LOGA : spr_selector := 3x"4";
constant SPRSEL_TBU : spr_selector := 4x"2"; constant SPRSEL_LOGD : spr_selector := 3x"5";
constant SPRSEL_DEC : spr_selector := 4x"3"; constant SPRSEL_CFAR : spr_selector := 3x"6";
constant SPRSEL_PVR : spr_selector := 4x"4"; constant SPRSEL_XER : spr_selector := 3x"7";
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 -- FPSCR bit numbers
constant FPSCR_FX : integer := 63 - 32; constant FPSCR_FX : integer := 63 - 32;
@ -246,16 +233,6 @@ package common is
constant FPSCR_NI : integer := 63 - 61; constant FPSCR_NI : integer := 63 - 61;
constant FPSCR_RN : integer := 63 - 63; 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 addresses
-- REAL_ADDR_BITS is the number of real address bits that we store -- REAL_ADDR_BITS is the number of real address bits that we store
constant REAL_ADDR_BITS : positive := 56; constant REAL_ADDR_BITS : positive := 56;
@ -282,68 +259,24 @@ package common is


-- For now, fixed 16 sources, make this either a parametric -- For now, fixed 16 sources, make this either a parametric
-- package of some sort or an unconstrainted array. -- 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 type ics_to_icp_t is record
-- Level interrupts only, ICS just keeps prsenting the -- Level interrupts only, ICS just keeps prsenting the
-- highest priority interrupt. Once handling edge, something -- highest priority interrupt. Once handling edge, something
-- smarter involving handshake & reject support will be needed -- smarter involving handshake & reject support will be needed
src : std_ulogic_vector(15 downto 0); -- 4 bits each for 4 cpus src : std_ulogic_vector(3 downto 0);
pri : std_ulogic_vector(31 downto 0); -- 8 bits each for 4 cpus pri : std_ulogic_vector(7 downto 0);
end record; 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... -- This needs to die...
type ctrl_t is record type ctrl_t is record
wait_state: std_ulogic; tb: std_ulogic_vector(63 downto 0);
run: std_ulogic;
dec: std_ulogic_vector(63 downto 0); dec: std_ulogic_vector(63 downto 0);
msr: std_ulogic_vector(63 downto 0); msr: std_ulogic_vector(63 downto 0);
cfar: std_ulogic_vector(63 downto 0); cfar: std_ulogic_vector(63 downto 0);
xer_low: std_ulogic_vector(17 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; end record;
constant ctrl_t_init : ctrl_t := constant ctrl_t_init : ctrl_t :=
(wait_state => '0', run => '1', xer_low => 18x"0", (xer_low => 18x"0", others => (others => '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 type Fetch1ToIcacheType is record
req: std_ulogic; req: std_ulogic;
@ -382,7 +315,6 @@ package common is
type Decode1ToDecode2Type is record type Decode1ToDecode2Type is record
valid: std_ulogic; valid: std_ulogic;
stop_mark : std_ulogic; stop_mark : std_ulogic;
second : std_ulogic;
nia: std_ulogic_vector(63 downto 0); nia: std_ulogic_vector(63 downto 0);
prefixed: std_ulogic; prefixed: std_ulogic;
prefix: std_ulogic_vector(25 downto 0); prefix: std_ulogic_vector(25 downto 0);
@ -399,7 +331,7 @@ package common is
reg_c : gspr_index_t; reg_c : gspr_index_t;
end record; end record;
constant Decode1ToDecode2Init : Decode1ToDecode2Type := constant Decode1ToDecode2Init : Decode1ToDecode2Type :=
(valid => '0', stop_mark => '0', second => '0', nia => (others => '0'), (valid => '0', stop_mark => '0', nia => (others => '0'),
prefixed => '0', prefix => (others => '0'), insn => (others => '0'), prefixed => '0', prefix => (others => '0'), insn => (others => '0'),
illegal_suffix => '0', misaligned_prefix => '0', illegal_suffix => '0', misaligned_prefix => '0',
decode => decode_rom_init, br_pred => '0', big_endian => '0', decode => decode_rom_init, br_pred => '0', big_endian => '0',
@ -422,11 +354,9 @@ package common is


type bypass_data_t is record type bypass_data_t is record
tag : instr_tag_t; tag : instr_tag_t;
reg : gspr_index_t;
data : std_ulogic_vector(63 downto 0); data : std_ulogic_vector(63 downto 0);
end record; end record;
constant bypass_data_init : bypass_data_t := constant bypass_data_init : bypass_data_t := (tag => instr_tag_init, data => (others => '0'));
(tag => instr_tag_init, reg => (others => '0'), data => (others => '0'));


type cr_bypass_data_t is record type cr_bypass_data_t is record
tag : instr_tag_t; tag : instr_tag_t;
@ -474,8 +404,8 @@ package common is
update : std_ulogic; -- is this an update instruction? update : std_ulogic; -- is this an update instruction?
reserve : std_ulogic; -- set for larx/stcx reserve : std_ulogic; -- set for larx/stcx
br_pred : std_ulogic; br_pred : std_ulogic;
result_sel : result_sel_t; -- select source of result result_sel : std_ulogic_vector(2 downto 0); -- select source of result
sub_select : subresult_sel_t; -- sub-result selection sub_select : std_ulogic_vector(2 downto 0); -- sub-result selection
repeat : std_ulogic; -- set if instruction is cracked into two ops repeat : std_ulogic; -- set if instruction is cracked into two ops
second : std_ulogic; -- set if this is the second op second : std_ulogic; -- set if this is the second op
spr_select : spr_id; spr_select : spr_id;
@ -486,22 +416,11 @@ package common is
ramspr_wraddr : ramspr_index; ramspr_wraddr : ramspr_index;
ramspr_write_even : std_ulogic; ramspr_write_even : std_ulogic;
ramspr_write_odd : std_ulogic; ramspr_write_odd : std_ulogic;
ramspr_32bit : std_ulogic;
dbg_spr_access : std_ulogic; dbg_spr_access : std_ulogic;
dec_ctr : std_ulogic; dec_ctr : std_ulogic;
privileged : std_ulogic;
prefixed : std_ulogic; prefixed : std_ulogic;
prefix : std_ulogic_vector(25 downto 0);
illegal_suffix : std_ulogic; illegal_suffix : std_ulogic;
misaligned_prefix : 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; end record;
constant Decode2ToExecute1Init : Decode2ToExecute1Type := constant Decode2ToExecute1Init : Decode2ToExecute1Type :=
(valid => '0', unit => ALU, fac => NONE, insn_type => OP_ILLEGAL, instr_tag => instr_tag_init, (valid => '0', unit => ALU, fac => NONE, insn_type => OP_ILLEGAL, instr_tag => instr_tag_init,
@ -514,18 +433,14 @@ package common is
read_data1 => (others => '0'), read_data2 => (others => '0'), read_data3 => (others => '0'), read_data1 => (others => '0'), read_data2 => (others => '0'), read_data3 => (others => '0'),
reg_valid1 => '0', reg_valid2 => '0', reg_valid3 => '0', reg_valid1 => '0', reg_valid2 => '0', reg_valid3 => '0',
cr => (others => '0'), insn => (others => '0'), data_len => (others => '0'), cr => (others => '0'), insn => (others => '0'), data_len => (others => '0'),
result_sel => ADD, sub_select => "000", result_sel => "000", sub_select => "000",
repeat => '0', second => '0', spr_select => spr_id_init, repeat => '0', second => '0', spr_select => spr_id_init,
spr_is_ram => '0', spr_is_ram => '0',
ramspr_even_rdaddr => (others => '0'), ramspr_odd_rdaddr => (others => '0'), ramspr_rd_odd => '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_wraddr => (others => '0'), ramspr_write_even => '0', ramspr_write_odd => '0',
ramspr_32bit => '0',
dbg_spr_access => '0', dbg_spr_access => '0',
dec_ctr => '0', dec_ctr => '0',
privileged => '0', prefixed => '0', prefix => (others => '0'), illegal_suffix => '0', prefixed => '0', illegal_suffix => '0', misaligned_prefix => '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')); others => (others => '0'));


type MultiplyInputType is record type MultiplyInputType is record
@ -598,7 +513,6 @@ package common is
nia : std_ulogic_vector(63 downto 0); nia : std_ulogic_vector(63 downto 0);
addr : std_ulogic_vector(63 downto 0); addr : std_ulogic_vector(63 downto 0);
addr_v : std_ulogic; addr_v : std_ulogic;
trace : std_ulogic;
occur : PMUEventType; occur : PMUEventType;
end record; end record;


@ -642,7 +556,6 @@ package common is
byte_reverse : std_ulogic; byte_reverse : std_ulogic;
sign_extend : std_ulogic; -- do we need to sign extend? sign_extend : std_ulogic; -- do we need to sign extend?
update : std_ulogic; -- is this an update instruction? update : std_ulogic; -- is this an update instruction?
hash : std_ulogic;
xerc : xer_common_t; xerc : xer_common_t;
reserve : std_ulogic; -- set for larx/stcx. reserve : std_ulogic; -- set for larx/stcx.
rc : std_ulogic; -- set for stcx. rc : std_ulogic; -- set for stcx.
@ -655,12 +568,10 @@ package common is
second : std_ulogic; second : std_ulogic;
e2stall : std_ulogic; e2stall : std_ulogic;
msr : std_ulogic_vector(63 downto 0); msr : std_ulogic_vector(63 downto 0);
hashkey : std_ulogic_vector(63 downto 0);
hash_enable : std_ulogic;
end record; end record;
constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type := constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type :=
(valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0', (valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0',
sign_extend => '0', update => '0', hash => '0', xerc => xerc_init, sign_extend => '0', update => '0', xerc => xerc_init,
reserve => '0', rc => '0', virt_mode => '0', priv_mode => '0', reserve => '0', rc => '0', virt_mode => '0', priv_mode => '0',
insn => (others => '0'), insn => (others => '0'),
instr_tag => instr_tag_init, instr_tag => instr_tag_init,
@ -669,13 +580,11 @@ package common is
length => (others => '0'), length => (others => '0'),
mode_32bit => '0', is_32bit => '0', prefixed => '0', mode_32bit => '0', is_32bit => '0', prefixed => '0',
repeat => '0', second => '0', e2stall => '0', repeat => '0', second => '0', e2stall => '0',
msr => (others => '0'), hashkey => (others => '0'), hash_enable => '0'); msr => (others => '0'));


type Loadstore1ToExecute1Type is record type Loadstore1ToExecute1Type is record
busy : std_ulogic; busy : std_ulogic;
l2stall : std_ulogic; l2stall : std_ulogic;
ea_for_pmu : std_ulogic_vector(63 downto 0);
ea_valid : std_ulogic;
end record; end record;


type Loadstore1ToDcacheType is record type Loadstore1ToDcacheType is record
@ -683,25 +592,14 @@ package common is
hold : std_ulogic; hold : std_ulogic;
load : std_ulogic; -- is this a load load : std_ulogic; -- is this a load
dcbz : std_ulogic; dcbz : std_ulogic;
flush : std_ulogic;
touch : std_ulogic;
sync : std_ulogic;
nc : std_ulogic; nc : std_ulogic;
reserve : 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; virt_mode : std_ulogic;
priv_mode : std_ulogic; priv_mode : std_ulogic;
tlb_probe : std_ulogic;
addr : std_ulogic_vector(63 downto 0); addr : std_ulogic_vector(63 downto 0);
data : std_ulogic_vector(63 downto 0); -- valid the cycle after .valid = 1 data : std_ulogic_vector(63 downto 0); -- valid the cycle after .valid = 1
byte_sel : std_ulogic_vector(7 downto 0); byte_sel : std_ulogic_vector(7 downto 0);
dawr_match : std_ulogic; -- valid the cycle after .valid = 1
end record; end record;
constant Loadstore1ToDcacheInit : Loadstore1ToDcacheType :=
(addr => (others => '0'), data => (others => '0'), byte_sel => x"00",
others => '0');


type DcacheToLoadstore1Type is record type DcacheToLoadstore1Type is record
valid : std_ulogic; valid : std_ulogic;
@ -709,7 +607,6 @@ package common is
store_done : std_ulogic; store_done : std_ulogic;
error : std_ulogic; error : std_ulogic;
cache_paradox : std_ulogic; cache_paradox : std_ulogic;
reserve_nc : std_ulogic;
end record; end record;


type DcacheEventType is record type DcacheEventType is record
@ -810,9 +707,6 @@ package common is
write_xerc_enable : std_ulogic; write_xerc_enable : std_ulogic;
xerc : xer_common_t; xerc : xer_common_t;
interrupt : std_ulogic; interrupt : std_ulogic;
alt_intr : std_ulogic;
hv_intr : std_ulogic;
is_scv : std_ulogic;
intr_vec : intr_vector_t; intr_vec : intr_vector_t;
redirect: std_ulogic; redirect: std_ulogic;
redir_mode: std_ulogic_vector(3 downto 0); redir_mode: std_ulogic_vector(3 downto 0);
@ -821,6 +715,7 @@ package common is
br_taken: std_ulogic; br_taken: std_ulogic;
abs_br: std_ulogic; abs_br: std_ulogic;
srr1: std_ulogic_vector(15 downto 0); srr1: std_ulogic_vector(15 downto 0);
msr: std_ulogic_vector(63 downto 0);
end record; end record;
constant Execute1ToWritebackInit : Execute1ToWritebackType := constant Execute1ToWritebackInit : Execute1ToWritebackType :=
(valid => '0', instr_tag => instr_tag_init, rc => '0', mode_32bit => '0', (valid => '0', instr_tag => instr_tag_init, rc => '0', mode_32bit => '0',
@ -828,11 +723,30 @@ package common is
write_xerc_enable => '0', xerc => xerc_init, write_xerc_enable => '0', xerc => xerc_init,
write_data => (others => '0'), write_cr_mask => (others => '0'), write_data => (others => '0'), write_cr_mask => (others => '0'),
write_cr_data => (others => '0'), write_reg => (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, interrupt => '0', intr_vec => 0, redirect => '0', redir_mode => "0000",
redirect => '0', redir_mode => "0000",
last_nia => (others => '0'), last_nia => (others => '0'),
br_last => '0', br_taken => '0', abs_br => '0', br_last => '0', br_taken => '0', abs_br => '0',
srr1 => (others => '0')); srr1 => (others => '0'), msr => (others => '0'));

-- MMU sandbox SPR interface (execute1 <-> MMU)
-- Dedicated point-to-point channel used by the telemetry sandbox.
-- Treated as a wire interface (no sprn decoding in the MMU); a write
-- on cycle N becomes visible on e_out.rdata on cycle N+1.
type Execute1ToMmuSprType is record
valid : std_ulogic;
write : std_ulogic;
wdata : std_ulogic_vector(63 downto 0);
end record;

constant Execute1ToMmuSprInit : Execute1ToMmuSprType :=
(valid => '0', write => '0', wdata => (others => '0'));

type MmuToExecute1SprType is record
rdata : std_ulogic_vector(63 downto 0);
end record;

constant MmuToExecute1SprInit : MmuToExecute1SprType :=
(rdata => (others => '0'));


type Execute1ToFPUType is record type Execute1ToFPUType is record
valid : std_ulogic; valid : std_ulogic;
@ -917,14 +831,13 @@ package common is
br_last : std_ulogic; br_last : std_ulogic;
br_taken : std_ulogic; br_taken : std_ulogic;
interrupt : std_ulogic; interrupt : std_ulogic;
alt_intr : std_ulogic; intr_vec : std_ulogic_vector(11 downto 0);
intr_vec : std_ulogic_vector(63 downto 0);
end record; end record;
constant WritebackToFetch1Init : WritebackToFetch1Type := constant WritebackToFetch1Init : WritebackToFetch1Type :=
(redirect => '0', virt_mode => '0', priv_mode => '0', big_endian => '0', (redirect => '0', virt_mode => '0', priv_mode => '0', big_endian => '0',
mode_32bit => '0', redirect_nia => (others => '0'), mode_32bit => '0', redirect_nia => (others => '0'),
br_last => '0', br_taken => '0', br_nia => (others => '0'), br_last => '0', br_taken => '0', br_nia => (others => '0'),
interrupt => '0', alt_intr => '0', intr_vec => 64x"0"); interrupt => '0', intr_vec => x"000");


type WritebackToRegisterFileType is record type WritebackToRegisterFileType is record
write_reg : gspr_index_t; write_reg : gspr_index_t;
@ -948,9 +861,6 @@ package common is


type WritebackToExecute1Type is record type WritebackToExecute1Type is record
intr : std_ulogic; intr : std_ulogic;
hv_intr : std_ulogic;
scv_int : std_ulogic;
alt_int : std_ulogic;
srr1 : std_ulogic_vector(15 downto 0); srr1 : std_ulogic_vector(15 downto 0);
end record; end record;



@ -20,6 +20,11 @@ entity mmu is
d_out : out MmuToDcacheType; d_out : out MmuToDcacheType;
d_in : in DcacheToMmuType; d_in : in DcacheToMmuType;


-- Sandbox telemetry SPR interface to execute1 (dedicated wires,
-- not decoded from sprn). Write on cycle N -> rdata valid on N+1.
e_in : in Execute1ToMmuSprType;
e_out : out MmuToExecute1SprType;

i_out : out MmuToITLBType i_out : out MmuToITLBType
); );
end mmu; end mmu;
@ -70,6 +75,9 @@ architecture behave of mmu is
segerror : std_ulogic; segerror : std_ulogic;
perm_err : std_ulogic; perm_err : std_ulogic;
rc_error : std_ulogic; rc_error : std_ulogic;
-- Sandbox telemetry placeholder. Will eventually be repurposed as
-- a Trace Array capturing bit-packed FSM state for debugging.
temp_trace_array : std_ulogic_vector(63 downto 0);
end record; end record;


signal r, rin : reg_stage_t; signal r, rin : reg_stage_t;
@ -94,6 +102,8 @@ begin
r.pt3_valid <= '0'; r.pt3_valid <= '0';
r.ptcr <= (others => '0'); r.ptcr <= (others => '0');
r.pid <= (others => '0'); r.pid <= (others => '0');
-- Sandbox telemetry register reset
r.temp_trace_array <= (others => '0');
else else
if rin.valid = '1' then if rin.valid = '1' then
report "MMU got tlb miss for " & to_hstring(rin.addr); report "MMU got tlb miss for " & to_hstring(rin.addr);
@ -500,5 +510,56 @@ begin
i_out.addr <= addr; i_out.addr <= addr;
i_out.pte <= tlb_data; i_out.pte <= tlb_data;


-- =====================================================================
-- Sandbox telemetry SPR pipeline
-- ---------------------------------------------------------------------
-- Dedicated point-to-point path between execute1 and the MMU. No sprn
-- decoding happens here: e_in is treated as a pre-selected wire
-- interface. The intent is a deterministic one-cycle round trip so we
-- can validate pipeline integrity and confirm no cross-path leakage
-- before repurposing temp_trace_array as a real Trace Array.
--
-- Write (clocked, via next-state v): cycle N
-- Read (combinational, from r) : cycle N+1
-- =====================================================================

-- Write path: update next-state register when execute1 asserts a
-- valid write on the sandbox channel. This is the only writer of
-- temp_trace_array in the current (non-instrumented) build.
if e_in.valid = '1' and e_in.write = '1' then
v.temp_trace_array := e_in.wdata;
end if;

-- ---------------------------------------------------------------------
-- FUTURE TRACE ARRAY LOGGING BLOCK
-- ---------------------------------------------------------------------
-- When temp_trace_array is promoted from a sandbox placeholder to a
-- real Trace Array, the following pattern will bit-pack selected
-- MMU FSM internals into the register every cycle (or every cycle
-- that a trace-enable qualifier is asserted). The layout below is a
-- proposed example; the final field widths/positions will be fixed
-- once the trace consumer is defined.
--
-- Proposed packing (LSB-first example, 64 bits total):
-- [ 3: 0] r.state encoded as a 4-bit value
-- [ 4] r.badtree
-- [ 5] r.segerror
-- [ 6] r.perm_err
-- [63: 7] reserved / future trace fields
--
-- v.temp_trace_array := (others => '0');
-- v.temp_trace_array(3 downto 0) :=
-- std_ulogic_vector(to_unsigned(state_t'pos(r.state), 4));
-- v.temp_trace_array(4) := r.badtree;
-- v.temp_trace_array(5) := r.segerror;
-- v.temp_trace_array(6) := r.perm_err;
-- ---------------------------------------------------------------------

-- Read path: combinational drive from the current-state register.
-- Because temp_trace_array is only updated through v in mmu_0, any
-- write issued on cycle N is visible here no earlier than cycle N+1,
-- giving the required one-cycle pass-through latency.
e_out.rdata <= r.temp_trace_array;

end process; end process;
end; end;

Loading…
Cancel
Save