mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 21:07:34 -04:00
[rtl] Alter some CSR WARL behaviour to match spike
The following changes are made: - For unimplemented counters corresponding bits in MCOUNTINHIBIT read as 0 not 1 - For MHPMEVENTx we start at x = 3 with the first bit set (0-2 MHPMEVENTx CSRs do not exist) - When writing an invalid privilege mode to MSTATUS.MPP/DCSR.PRV default to U rather than M mode. These new behaviours remain spec compliant and match spike.
This commit is contained in:
parent
19d12ee3a7
commit
e53a02ab31
2 changed files with 13 additions and 10 deletions
|
@ -33,11 +33,11 @@ RegisterModel::RegisterModel(SimCtrl *sc, CSRParams *params) : simctrl_(sc) {
|
|||
}
|
||||
}
|
||||
// mcountinhibit
|
||||
// - MSBs are always 1: unused counters cannot be enabled
|
||||
// - MSBs are always 0: unused counters cannot be inhibited
|
||||
// - Bit 1 is always 0: time cannot be disabled
|
||||
uint32_t mcountinhibit_mask =
|
||||
(~((0x1 << params->MHPMCounterNum) - 1) << 3) | 0x2;
|
||||
uint32_t mcountinhibit_resval = ~((0x1 << params->MHPMCounterNum) - 1) << 3;
|
||||
uint32_t mcountinhibit_resval = 0;
|
||||
register_map_.push_back(std::make_unique<WARLRegister>(
|
||||
0x320, ®ister_map_, mcountinhibit_mask, mcountinhibit_resval));
|
||||
// Performance counter setup
|
||||
|
@ -45,7 +45,7 @@ RegisterModel::RegisterModel(SimCtrl *sc, CSRParams *params) : simctrl_(sc) {
|
|||
uint32_t reg_addr = 0x320 + i;
|
||||
if (i < (params->MHPMCounterNum + 3)) {
|
||||
register_map_.push_back(std::make_unique<WARLRegister>(
|
||||
reg_addr, ®ister_map_, 0xFFFFFFFF, 0x1 << i));
|
||||
reg_addr, ®ister_map_, 0xFFFFFFFF, 0x1 << (i - 3)));
|
||||
} else {
|
||||
register_map_.push_back(
|
||||
std::make_unique<NonImpRegister>(reg_addr, ®ister_map_));
|
||||
|
|
|
@ -566,9 +566,9 @@ module ibex_cs_registers #(
|
|||
mprv: csr_wdata_int[CSR_MSTATUS_MPRV_BIT],
|
||||
tw: csr_wdata_int[CSR_MSTATUS_TW_BIT]
|
||||
};
|
||||
// Convert illegal values to M-mode
|
||||
// Convert illegal values to U-mode
|
||||
if ((mstatus_d.mpp != PRIV_LVL_M) && (mstatus_d.mpp != PRIV_LVL_U)) begin
|
||||
mstatus_d.mpp = PRIV_LVL_M;
|
||||
mstatus_d.mpp = PRIV_LVL_U;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -592,9 +592,9 @@ module ibex_cs_registers #(
|
|||
CSR_DCSR: begin
|
||||
dcsr_d = csr_wdata_int;
|
||||
dcsr_d.xdebugver = XDEBUGVER_STD;
|
||||
// Change to PRIV_LVL_M if software writes an unsupported value
|
||||
// Change to PRIV_LVL_U if software writes an unsupported value
|
||||
if ((dcsr_d.prv != PRIV_LVL_M) && (dcsr_d.prv != PRIV_LVL_U)) begin
|
||||
dcsr_d.prv = PRIV_LVL_M;
|
||||
dcsr_d.prv = PRIV_LVL_U;
|
||||
end
|
||||
|
||||
// Read-only for SW
|
||||
|
@ -1254,8 +1254,11 @@ module ibex_cs_registers #(
|
|||
|
||||
// activate all
|
||||
for (int i = 0; i < 32; i++) begin : gen_mhpmevent_active
|
||||
mhpmevent[i] = '0;
|
||||
mhpmevent[i][i] = 1'b1;
|
||||
mhpmevent[i] = '0;
|
||||
|
||||
if (i >= 3) begin
|
||||
mhpmevent[i][i - 3] = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// deactivate
|
||||
|
@ -1358,7 +1361,7 @@ module ibex_cs_registers #(
|
|||
logic [29-MHPMCounterNum-1:0] unused_mhphcounterh_we;
|
||||
logic [29-MHPMCounterNum-1:0] unused_mhphcounter_incr;
|
||||
|
||||
assign mcountinhibit = {{29 - MHPMCounterNum{1'b1}}, mcountinhibit_q};
|
||||
assign mcountinhibit = {{29 - MHPMCounterNum{1'b0}}, mcountinhibit_q};
|
||||
// Lint tieoffs for unused bits
|
||||
assign unused_mhphcounter_we = mhpmcounter_we[31:MHPMCounterNum+3];
|
||||
assign unused_mhphcounterh_we = mhpmcounterh_we[31:MHPMCounterNum+3];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue