First pass at U-mode CSR support. Bizarrely causes CXXRTL tb to not write to stdout when invoked by subprocess.run from Python.
This commit is contained in:
parent
4ba3f7ceb9
commit
d62861159f
|
@ -77,12 +77,15 @@ parameter CSR_M_TRAP = 1,
|
|||
// CSR_COUNTER: Include performance counters and relevant M-mode CSRs
|
||||
parameter CSR_COUNTER = 1,
|
||||
|
||||
// U_MODE: support for the U (user, unprivileged) execution mode. If U_MODE is
|
||||
// 1, PMP support is recommended.
|
||||
// U_MODE: Support the U (user) execution mode. In U mode, the core performs
|
||||
// unprivileged bus accesses, and software's access to CSRs is restricted.
|
||||
// Additionally, if the PMP is included, the core may restrict U-mode
|
||||
// software's access to memory.
|
||||
// Requires: CSR_M_TRAP.
|
||||
parameter U_MODE = 0,
|
||||
|
||||
// PMP_REGIONS: Number of physical memory protection regions, or 0 for no PMP.
|
||||
// PMP is more useful if U mode is supported, but has use on M-only systems.
|
||||
// PMP is more useful if U mode is supported, but this is not a requirement.
|
||||
parameter PMP_REGIONS = 0,
|
||||
|
||||
// DEBUG_SUPPORT: Support for run/halt and instruction injection from an
|
||||
|
|
|
@ -118,7 +118,6 @@ begin
|
|||
end
|
||||
endfunction
|
||||
|
||||
|
||||
wire enter_debug_mode;
|
||||
wire exit_debug_mode;
|
||||
|
||||
|
@ -130,30 +129,57 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Trap-handling CSRs
|
||||
|
||||
wire debug_suppresses_trap_update = DEBUG_SUPPORT && (debug_mode || enter_debug_mode);
|
||||
|
||||
|
||||
// Two-level interrupt enable stack, shuffled on entry/exit:
|
||||
reg m_mode;
|
||||
reg mstatus_mpie;
|
||||
reg mstatus_mie;
|
||||
reg mstatus_mpp; // only MSB is implemented
|
||||
reg mstatus_mprv;
|
||||
|
||||
wire wen_m_mode = wen && (m_mode || debug_mode);
|
||||
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
m_mode <= 1'b1;
|
||||
mstatus_mpie <= 1'b0;
|
||||
mstatus_mie <= 1'b0;
|
||||
mstatus_mpp <= 1'b1;
|
||||
mstatus_mprv <= 1'b0;
|
||||
end else if (CSR_M_TRAP) begin
|
||||
if (trap_enter_vld && trap_enter_rdy && !debug_suppresses_trap_update) begin
|
||||
if (except == EXCEPT_MRET) begin
|
||||
mstatus_mpie <= 1'b1;
|
||||
mstatus_mie <= mstatus_mpie;
|
||||
if (U_MODE) begin
|
||||
m_mode <= mstatus_mpp;
|
||||
end
|
||||
end else begin
|
||||
mstatus_mpie <= mstatus_mie;
|
||||
mstatus_mie <= 1'b0;
|
||||
if (U_MODE) begin
|
||||
m_mode <= 1'b1;
|
||||
mstatus_mpp <= m_mode;
|
||||
end
|
||||
end else if (wen && addr == MSTATUS) begin
|
||||
{mstatus_mpie, mstatus_mie} <= {wdata_update[7], wdata_update[3]};
|
||||
end
|
||||
end else if (wen_m_mode && addr == MSTATUS) begin
|
||||
mstatus_mpie <= wdata_update[7];
|
||||
mstatus_mie <= wdata_update[3];
|
||||
mstatus_mprv <= wdata_update[17];
|
||||
// Note only the MSB of MPP is implemented. It reads back as 11 or 00.
|
||||
mstatus_mpp <= wdata_update[12];
|
||||
end else if (wen && debug_mode && addr == DCSR && U_MODE && DEBUG_SUPPORT) begin
|
||||
// Debugger can change/observe core state directly through
|
||||
// dcsr.prv (this doesn't affect debugger operation, as all
|
||||
// operations have an effective level of M-mode whilst the core
|
||||
// is halted for debug.)
|
||||
m_mode <= wdata_update[1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -164,7 +190,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
if (!rst_n) begin
|
||||
mscratch <= X0;
|
||||
end else if (CSR_M_TRAP) begin
|
||||
if (wen && addr == MSCRATCH)
|
||||
if (wen_m_mode && addr == MSCRATCH)
|
||||
mscratch <= wdata_update;
|
||||
end
|
||||
end
|
||||
|
@ -178,7 +204,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
if (!rst_n) begin
|
||||
mtvec_reg <= MTVEC_INIT;
|
||||
end else if (CSR_M_TRAP) begin
|
||||
if (wen && addr == MTVEC)
|
||||
if (wen_m_mode && addr == MTVEC)
|
||||
mtvec_reg <= update_nonconst(mtvec_reg, MTVEC_WMASK);
|
||||
end
|
||||
end
|
||||
|
@ -194,7 +220,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
end else if (CSR_M_TRAP) begin
|
||||
if (trap_enter_vld && trap_enter_rdy && except != EXCEPT_MRET && !debug_suppresses_trap_update) begin
|
||||
mepc <= mepc_in & MEPC_MASK;
|
||||
end else if (wen && addr == MEPC) begin
|
||||
end else if (wen_m_mode && addr == MEPC) begin
|
||||
mepc <= wdata_update & MEPC_MASK;
|
||||
end
|
||||
end
|
||||
|
@ -208,7 +234,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
if (!rst_n) begin
|
||||
mie <= X0;
|
||||
end else if (CSR_M_TRAP) begin
|
||||
if (wen && addr == MIE)
|
||||
if (wen_m_mode && addr == MIE)
|
||||
mie <= update_nonconst(mie, MIE_WMASK);
|
||||
end
|
||||
end
|
||||
|
@ -236,7 +262,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
if (trap_enter_vld && trap_enter_rdy && except != EXCEPT_MRET && !debug_suppresses_trap_update) begin
|
||||
mcause_irq <= mcause_irq_next;
|
||||
mcause_code <= mcause_code_next;
|
||||
end else if (wen && addr == MCAUSE) begin
|
||||
end else if (wen_m_mode && addr == MCAUSE) begin
|
||||
{mcause_irq, mcause_code} <= {wdata_update[31], wdata_update[5:0]};
|
||||
end
|
||||
end
|
||||
|
@ -266,13 +292,13 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
meie1 <= X0;
|
||||
meie2 <= X0;
|
||||
meie3 <= X0;
|
||||
end else if (wen && addr == MEIE0) begin
|
||||
end else if (wen_m_mode && addr == MEIE0) begin
|
||||
meie0 <= update_nonconst(meie0, MEIE0_WMASK);
|
||||
end else if (wen && addr == MEIE1) begin
|
||||
end else if (wen_m_mode && addr == MEIE1) begin
|
||||
meie1 <= update_nonconst(meie1, MEIE1_WMASK);
|
||||
end else if (wen && addr == MEIE2) begin
|
||||
end else if (wen_m_mode && addr == MEIE2) begin
|
||||
meie2 <= update_nonconst(meie2, MEIE2_WMASK);
|
||||
end else if (wen && addr == MEIE3) begin
|
||||
end else if (wen_m_mode && addr == MEIE3) begin
|
||||
meie3 <= update_nonconst(meie3, MEIE3_WMASK);
|
||||
end
|
||||
end
|
||||
|
@ -313,7 +339,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
if (!(mcountinhibit_ir || debug_mode) && instr_ret)
|
||||
{minstreth, minstret} <= (({minstreth, minstret} + 1'b1) & ~({2*XLEN{1'b1}} << W_COUNTER))
|
||||
| ({minstreth, minstret} & ({2*XLEN{1'b1}} << W_COUNTER));
|
||||
if (wen) begin
|
||||
if (wen_m_mode) begin
|
||||
if (addr == MCYCLEH)
|
||||
mcycleh <= wdata_update;
|
||||
if (addr == MCYCLE)
|
||||
|
@ -329,6 +355,27 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
end
|
||||
end
|
||||
|
||||
// Note we still implement tm, even though the time/timeh CSRs are
|
||||
// unimplemented. The tm bit provides a standard way to configure whether
|
||||
// M-mode software permits the trapped access to reach the timer registers.
|
||||
// (This is in fact required by the RVM-CSI platform spec.)
|
||||
reg mcounteren_cy;
|
||||
reg mcounteren_tm;
|
||||
reg mcounteren_ir;
|
||||
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
mcounteren_cy <= 1'b0;
|
||||
mcounteren_tm <= 1'b0;
|
||||
mcounteren_ir <= 1'b0;
|
||||
end else if (CSR_COUNTER && U_MODE && wen_m_mode && addr == MCOUNTEREN) begin
|
||||
// Note this register only exists when U mode is implemented.
|
||||
mcounteren_cy <= wdata_update[0];
|
||||
mcounteren_tm <= wdata_update[1];
|
||||
mcounteren_ir <= wdata_update[2];
|
||||
end
|
||||
end
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Debug-mode CSRs
|
||||
|
||||
|
@ -387,6 +434,14 @@ assign dbg_data0_wen = debug_mode && wen && addr == DMDATA0;
|
|||
|
||||
reg decode_match;
|
||||
|
||||
// Address match conditions -- certain CSRs are inaccessible if their
|
||||
// conditions are not met:
|
||||
wire match_drw = DEBUG_SUPPORT && debug_mode;
|
||||
wire match_mrw = m_mode || debug_mode;
|
||||
wire match_mro = (m_mode || debug_mode) && !wen_soon;
|
||||
wire match_urw = U_MODE && 1'b1;
|
||||
wire match_uro = U_MODE && !wen_soon;
|
||||
|
||||
always @ (*) begin
|
||||
decode_match = 1'b0;
|
||||
rdata = {XLEN{1'b0}};
|
||||
|
@ -397,7 +452,7 @@ always @ (*) begin
|
|||
|
||||
MISA: if (CSR_M_MANDATORY) begin
|
||||
// WARL, so it is legal to be tied constant
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = {
|
||||
2'h1, // MXL: 32-bit
|
||||
{XLEN-28{1'b0}}, // WLRL
|
||||
|
@ -415,30 +470,30 @@ always @ (*) begin
|
|||
};
|
||||
end
|
||||
MVENDORID: if (CSR_M_MANDATORY) begin
|
||||
decode_match = !wen_soon; // MRO
|
||||
decode_match = match_mro;
|
||||
rdata = MVENDORID_VAL;
|
||||
end
|
||||
MARCHID: if (CSR_M_MANDATORY) begin
|
||||
decode_match = !wen_soon; // MRO
|
||||
decode_match = match_mro;
|
||||
// Hazard3's open source architecture ID
|
||||
rdata = 32'd27;
|
||||
end
|
||||
MIMPID: if (CSR_M_MANDATORY) begin
|
||||
decode_match = !wen_soon; // MRO
|
||||
decode_match = match_mro;
|
||||
rdata = MIMPID_VAL;
|
||||
end
|
||||
MHARTID: if (CSR_M_MANDATORY) begin
|
||||
decode_match = !wen_soon; // MRO
|
||||
decode_match = match_mro;
|
||||
rdata = MHARTID_VAL;
|
||||
end
|
||||
|
||||
MCONFIGPTR: if (CSR_M_MANDATORY) begin
|
||||
decode_match = !wen_soon; // MRO
|
||||
decode_match = match_mro;
|
||||
rdata = MCONFIGPTR_VAL;
|
||||
end
|
||||
|
||||
MSTATUS: if (CSR_M_MANDATORY || CSR_M_TRAP) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = {
|
||||
1'b0, // Never any dirty state besides GPRs
|
||||
8'd0, // (WPRI)
|
||||
|
@ -447,14 +502,14 @@ always @ (*) begin
|
|||
1'b0, // TVM (trap virtual memory), tied 0 if no S mode.
|
||||
1'b0, // MXR (Make eXecutable Readable), tied 0 if not S mode.
|
||||
1'b0, // SUM, tied 0, we have no S or U mode
|
||||
1'b0, // MPRV (modify privilege), tied 0 if no U mode
|
||||
mstatus_mprv, // MPRV (modify privilege)
|
||||
4'd0, // XS, FS always "off" (no extension state to clear!)
|
||||
2'b11, // MPP (M-mode previous privilege), we are always M-mode
|
||||
{2{m_mode}}, // MPP (M-mode previous privilege), only M and U supported
|
||||
2'd0, // (WPRI)
|
||||
1'b0, // SPP, tied 0 if S mode not supported
|
||||
mstatus_mpie,
|
||||
mstatus_mpie, // Previous interrupt enable
|
||||
3'd0, // No S, U
|
||||
mstatus_mie,
|
||||
mstatus_mie, // Interrupt enable
|
||||
3'd0 // No S, U
|
||||
};
|
||||
end
|
||||
|
@ -464,7 +519,7 @@ always @ (*) begin
|
|||
// unimplemented in this case, but now it must be decoded even if
|
||||
// hardwired to 0.
|
||||
MSTATUSH: if (CSR_M_MANDATORY || CSR_M_TRAP) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
end
|
||||
|
||||
// MEDELEG, MIDELEG should not exist for M-only implementations. Will raise
|
||||
|
@ -476,17 +531,17 @@ always @ (*) begin
|
|||
// This is a 32 bit synthesised register with set/clear/write/read, don't
|
||||
// turn it on unless we really have to
|
||||
MSCRATCH: if (CSR_M_TRAP && CSR_M_MANDATORY) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = mscratch;
|
||||
end
|
||||
|
||||
MEPC: if (CSR_M_TRAP) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = mepc;
|
||||
end
|
||||
|
||||
MCAUSE: if (CSR_M_TRAP) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = {
|
||||
mcause_irq, // Sign bit is 1 for IRQ, 0 for exception
|
||||
{26{1'b0}}, // Padding
|
||||
|
@ -495,23 +550,23 @@ always @ (*) begin
|
|||
end
|
||||
|
||||
MTVAL: if (CSR_M_TRAP) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
// Hardwired to 0
|
||||
end
|
||||
|
||||
MIE: if (CSR_M_TRAP) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = mie;
|
||||
end
|
||||
|
||||
MIP: if (CSR_M_TRAP) begin
|
||||
// Writes are permitted, but ignored.
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = mip;
|
||||
end
|
||||
|
||||
MTVEC: if (CSR_M_TRAP) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = {
|
||||
mtvec[XLEN-1:2], // BASE
|
||||
1'b0, // Reserved mode bit gets WARL'd to 0
|
||||
|
@ -523,98 +578,98 @@ always @ (*) begin
|
|||
// Counter CSRs
|
||||
|
||||
// Get the tied WARLs out the way first
|
||||
MHPMCOUNTER3: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER4: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER5: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER6: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER7: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER8: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER9: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER10: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER11: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER12: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER13: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER14: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER15: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER16: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER17: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER18: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER19: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER20: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER21: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER22: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER23: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER24: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER25: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER26: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER27: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER28: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER29: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER30: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER31: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER3: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER4: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER5: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER6: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER7: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER8: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER9: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER10: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER11: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER12: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER13: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER14: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER15: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER16: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER17: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER18: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER19: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER20: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER21: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER22: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER23: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER24: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER25: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER26: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER27: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER28: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER29: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER30: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER31: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
|
||||
MHPMCOUNTER3H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER4H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER5H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER6H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER7H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER8H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER9H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER10H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER11H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER12H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER13H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER14H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER15H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER16H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER17H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER18H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER19H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER20H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER21H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER22H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER23H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER24H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER25H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER26H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER27H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER28H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER29H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER30H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER31H: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMCOUNTER3H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER4H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER5H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER6H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER7H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER8H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER9H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER10H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER11H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER12H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER13H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER14H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER15H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER16H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER17H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER18H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER19H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER20H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER21H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER22H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER23H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER24H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER25H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER26H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER27H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER28H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER29H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER30H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMCOUNTER31H: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
|
||||
MHPMEVENT3: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT4: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT5: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT6: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT7: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT8: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT9: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT10: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT11: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT12: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT13: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT14: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT15: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT16: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT17: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT18: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT19: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT20: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT21: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT22: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT23: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT24: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT25: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT26: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT27: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT28: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT29: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT30: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT31: if (CSR_COUNTER) begin decode_match = 1'b1; end
|
||||
MHPMEVENT3: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT4: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT5: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT6: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT7: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT8: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT9: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT10: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT11: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT12: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT13: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT14: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT15: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT16: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT17: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT18: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT19: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT20: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT21: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT22: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT23: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT24: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT25: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT26: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT27: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT28: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT29: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT30: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
MHPMEVENT31: if (CSR_COUNTER) begin decode_match = match_mrw; end
|
||||
|
||||
MCOUNTINHIBIT: if (CSR_COUNTER) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = {
|
||||
29'd0,
|
||||
mcountinhibit_ir,
|
||||
|
@ -624,20 +679,53 @@ always @ (*) begin
|
|||
end
|
||||
|
||||
MCYCLE: if (CSR_COUNTER) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = mcycle;
|
||||
end
|
||||
MINSTRET: if (CSR_COUNTER) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = minstret;
|
||||
end
|
||||
|
||||
MCYCLEH: if (CSR_COUNTER) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = mcycleh;
|
||||
end
|
||||
MINSTRETH: if (CSR_COUNTER) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = minstreth;
|
||||
end
|
||||
|
||||
MCOUNTEREN: if (CSR_COUNTER && U_MODE) begin
|
||||
decode_match = match_mrw;
|
||||
rdata = {
|
||||
29'd0,
|
||||
mcounteren_ir,
|
||||
mcounteren_tm,
|
||||
mcounteren_cy
|
||||
};
|
||||
end
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// U-mode CSRs
|
||||
|
||||
// The read-only counters are always visible to M mode, and are visible to
|
||||
// U mode if the corresponding mcounteren bit is set.
|
||||
CYCLE: if (CSR_COUNTER) begin
|
||||
decode_match = mcounteren_cy ? match_uro : match_mro;
|
||||
rdata = mcycle;
|
||||
end
|
||||
CYCLEH: if (CSR_COUNTER && U_MODE) begin
|
||||
decode_match = mcounteren_cy ? match_uro : match_mro;
|
||||
rdata = mcycleh;
|
||||
end
|
||||
|
||||
INSTRET: if (CSR_COUNTER) begin
|
||||
decode_match = mcounteren_ir ? match_uro : match_mro;
|
||||
rdata = minstret;
|
||||
end
|
||||
INSTRETH: if (CSR_COUNTER) begin
|
||||
decode_match = mcounteren_ir ? match_uro : match_mro;
|
||||
rdata = minstreth;
|
||||
end
|
||||
|
||||
|
@ -649,14 +737,14 @@ always @ (*) begin
|
|||
// - tselect must raise an exception when written to
|
||||
// Otherwise it returns an error instead of 0 count when enumerating triggers
|
||||
TSELECT: if (DEBUG_SUPPORT) begin
|
||||
decode_match = !wen_soon;
|
||||
decode_match = match_mro;
|
||||
end
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Debug CSRs
|
||||
|
||||
DCSR: if (DEBUG_SUPPORT && debug_mode) begin
|
||||
decode_match = 1'b1;
|
||||
DCSR: if (DEBUG_SUPPORT) begin
|
||||
decode_match = match_drw;
|
||||
rdata = {
|
||||
4'h4, // xdebugver = 4, for 0.13.2 debug spec
|
||||
12'd0, // reserved
|
||||
|
@ -667,20 +755,20 @@ always @ (*) begin
|
|||
1'b1, // stoptime = 0, no core-local timer increment in debug mode
|
||||
dcsr_cause,
|
||||
1'b0, // reserved
|
||||
1'b0, // mprven = 0, we don't have MPRV support
|
||||
1'b0, // mprven = 0, debugger always acts as M-mode
|
||||
1'b0, // nmip = 0, we have no NMI
|
||||
dcsr_step,
|
||||
2'h3 // prv = 3, we only have M mode
|
||||
{2{m_mode}} // priv = M or U, report the core state directly
|
||||
};
|
||||
end
|
||||
|
||||
DPC: if (DEBUG_SUPPORT && debug_mode) begin
|
||||
decode_match = 1'b1;
|
||||
DPC: if (DEBUG_SUPPORT) begin
|
||||
decode_match = match_drw;
|
||||
rdata = dpc;
|
||||
end
|
||||
|
||||
DMDATA0: if (DEBUG_SUPPORT && debug_mode) begin
|
||||
decode_match = 1'b1;
|
||||
DMDATA0: if (DEBUG_SUPPORT) begin
|
||||
decode_match = match_drw;
|
||||
rdata = dbg_data0_rdata;
|
||||
end
|
||||
|
||||
|
@ -688,47 +776,47 @@ always @ (*) begin
|
|||
// Custom CSRs
|
||||
|
||||
MEIE0: if (CSR_M_TRAP && N_IRQ_REG0 > 0) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = meie0;
|
||||
end
|
||||
|
||||
MEIE1: if (CSR_M_TRAP && N_IRQ_REG1 > 0) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = meie1;
|
||||
end
|
||||
|
||||
MEIE2: if (CSR_M_TRAP && N_IRQ_REG2 > 0) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = meie2;
|
||||
end
|
||||
|
||||
MEIE3: if (CSR_M_TRAP && N_IRQ_REG3 > 0) begin
|
||||
decode_match = 1'b1;
|
||||
decode_match = match_mrw;
|
||||
rdata = meie3;
|
||||
end
|
||||
|
||||
MEIP0: if (CSR_M_TRAP && N_IRQ_REG0 > 0) begin
|
||||
decode_match = !wen_soon;
|
||||
decode_match = match_mro;
|
||||
rdata = meip0;
|
||||
end
|
||||
|
||||
MEIP1: if (CSR_M_TRAP && N_IRQ_REG1 > 0) begin
|
||||
decode_match = !wen_soon;
|
||||
decode_match = match_mro;
|
||||
rdata = meip1;
|
||||
end
|
||||
|
||||
MEIP2: if (CSR_M_TRAP && N_IRQ_REG2 > 0) begin
|
||||
decode_match = !wen_soon;
|
||||
decode_match = match_mro;
|
||||
rdata = meip2;
|
||||
end
|
||||
|
||||
MEIP3: if (CSR_M_TRAP && N_IRQ_REG3 > 0) begin
|
||||
decode_match = !wen_soon;
|
||||
decode_match = match_mro;
|
||||
rdata = meip3;
|
||||
end
|
||||
|
||||
MLEI: if (CSR_M_TRAP) begin
|
||||
decode_match = !wen_soon;
|
||||
decode_match = match_mro;
|
||||
rdata = {{XLEN-9{1'b0}}, mlei, 2'b00};
|
||||
end
|
||||
|
||||
|
|
|
@ -161,6 +161,17 @@ localparam MEIP2 = 12'hfe2; // External interrupt pending register 2
|
|||
localparam MEIP3 = 12'hfe3; // External interrupt pending register 3
|
||||
localparam MLEI = 12'hfe4; // Lowest external interrupt number
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// U-mode CSRs
|
||||
|
||||
// Read-only aliases of M-mode counter CSRs:
|
||||
localparam CYCLE = 12'hc00;
|
||||
localparam TIME = 12'hc01;
|
||||
localparam INSTRET = 12'hc02;
|
||||
localparam CYCLEH = 12'hc80;
|
||||
localparam TIMEH = 12'hc81;
|
||||
localparam INSTRETH = 12'hc82;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Trigger Module
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ always @ (*) begin: check_i_match
|
|||
i_partial_match = 1'b0;
|
||||
i_l = 1'b0;
|
||||
i_x = 1'b0;
|
||||
for (i = PMP_REGIONS - 1; i >= 0; i = i - 1) begin
|
||||
for (i = PMP_REGIONS - 1; i >= 0; i = i -q 1) begin
|
||||
match_hw0 = |pmpcfg_a[i] && (i_addr & match_mask[i]) == match_addr[i];
|
||||
match_hw1 = |pmpcfg_a[i] && (i_addr_hw1 & match_mask[i]) == match_addr[i];
|
||||
if (match_hw0 || match_hw1) begin
|
||||
|
|
Loading…
Reference in New Issue