1 |
11 |
dinesha |
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
|
2 |
|
|
/// @file
|
3 |
|
|
/// @brief Control Status Registers (CSR)
|
4 |
|
|
///
|
5 |
|
|
|
6 |
|
|
//------------------------------------------------------------------------------
|
7 |
|
|
//
|
8 |
|
|
// Functionality:
|
9 |
|
|
// - Provides access to RISC-V CSR Machine registers
|
10 |
|
|
// - Handles events (EXC, IRQ and MRET):
|
11 |
|
|
// - Setups handling configuration
|
12 |
|
|
// - Displays events statuses and information
|
13 |
|
|
// - Generates new PC
|
14 |
|
|
// - Provides information about the number of executed instructions and elapsed
|
15 |
|
|
// cycles
|
16 |
|
|
// - Provides interfaces for IPIC, HDU and TDU registers access
|
17 |
|
|
//
|
18 |
|
|
// Structure:
|
19 |
|
|
// - Events (EXC, IRQ, MRET) logic
|
20 |
|
|
// - CSR read/write interface
|
21 |
|
|
// - CSR registers:
|
22 |
|
|
// - Machine Trap Setup registers
|
23 |
|
|
// - Machine Trap Handling registers
|
24 |
|
|
// - Machine Counters/Timers registers
|
25 |
|
|
// - Non-standard CSRs (MCOUNTEN)
|
26 |
|
|
// - CSR <-> EXU i/f
|
27 |
|
|
// - CSR <-> IPIC i/f
|
28 |
|
|
// - CSR <-> HDU i/f
|
29 |
|
|
// - CSR <-> TDU i/f
|
30 |
|
|
//
|
31 |
|
|
//------------------------------------------------------------------------------
|
32 |
|
|
|
33 |
|
|
`include "scr1_arch_description.svh"
|
34 |
|
|
`include "scr1_csr.svh"
|
35 |
|
|
`include "scr1_arch_types.svh"
|
36 |
|
|
`include "scr1_riscv_isa_decoding.svh"
|
37 |
|
|
`ifdef SCR1_IPIC_EN
|
38 |
|
|
`include "scr1_ipic.svh"
|
39 |
|
|
`endif // SCR1_IPIC_EN
|
40 |
|
|
`ifdef SCR1_DBG_EN
|
41 |
|
|
`include "scr1_hdu.svh"
|
42 |
|
|
`endif // SCR1_DBG_EN
|
43 |
|
|
`ifdef SCR1_TDU_EN
|
44 |
|
|
`include "scr1_tdu.svh"
|
45 |
|
|
`endif // SCR1_TDU_EN
|
46 |
|
|
|
47 |
|
|
module scr1_pipe_csr (
|
48 |
|
|
// Common
|
49 |
|
|
input logic rst_n, // CSR reset
|
50 |
|
|
input logic clk, // Gated CSR clock
|
51 |
|
|
`ifdef SCR1_CLKCTRL_EN
|
52 |
|
|
input logic clk_alw_on, // Not-gated CSR clock
|
53 |
|
|
`endif // SCR1_CLKCTRL_EN
|
54 |
|
|
|
55 |
|
|
// SOC signals
|
56 |
|
|
// IRQ
|
57 |
|
|
input logic soc2csr_irq_ext_i, // External interrupt request
|
58 |
|
|
input logic soc2csr_irq_soft_i, // Software interrupt request
|
59 |
|
|
input logic soc2csr_irq_mtimer_i, // External timer interrupt request
|
60 |
|
|
|
61 |
|
|
// Memory-mapped external timer
|
62 |
|
|
input logic [63:0] soc2csr_mtimer_val_i, // External timer value
|
63 |
|
|
|
64 |
|
|
// MHARTID fuse
|
65 |
|
|
input logic [`SCR1_XLEN-1:0] soc2csr_fuse_mhartid_i, // MHARTID fuse
|
66 |
|
|
|
67 |
|
|
// CSR <-> EXU read/write interface
|
68 |
|
|
input logic exu2csr_r_req_i, // CSR read/write address
|
69 |
|
|
input logic [SCR1_CSR_ADDR_WIDTH-1:0] exu2csr_rw_addr_i, // CSR read request
|
70 |
|
|
output logic [`SCR1_XLEN-1:0] csr2exu_r_data_o, // CSR read data
|
71 |
|
|
input logic exu2csr_w_req_i, // CSR write request
|
72 |
|
|
input type_scr1_csr_cmd_sel_e exu2csr_w_cmd_i, // CSR write command
|
73 |
|
|
input logic [`SCR1_XLEN-1:0] exu2csr_w_data_i, // CSR write data
|
74 |
|
|
output logic csr2exu_rw_exc_o, // CSR read/write access exception
|
75 |
|
|
|
76 |
|
|
// CSR <-> EXU event interface
|
77 |
|
|
input logic exu2csr_take_irq_i, // Take IRQ trap
|
78 |
|
|
input logic exu2csr_take_exc_i, // Take exception trap
|
79 |
|
|
input logic exu2csr_mret_update_i, // MRET update CSR
|
80 |
|
|
input logic exu2csr_mret_instr_i, // MRET instruction
|
81 |
|
|
input logic [SCR1_EXC_CODE_WIDTH_E-1:0] exu2csr_exc_code_i, // Exception code (see scr1_arch_types.svh) - cp.7
|
82 |
|
|
input logic [`SCR1_XLEN-1:0] exu2csr_trap_val_i, // Trap value
|
83 |
|
|
output logic csr2exu_irq_o, // IRQ request
|
84 |
|
|
output logic csr2exu_ip_ie_o, // Some IRQ pending and locally enabled
|
85 |
|
|
output logic csr2exu_mstatus_mie_up_o, // MSTATUS or MIE update in the current cycle
|
86 |
|
|
|
87 |
|
|
`ifdef SCR1_IPIC_EN
|
88 |
|
|
// CSR <-> IPIC interface
|
89 |
|
|
output logic csr2ipic_r_req_o, // IPIC read request
|
90 |
|
|
output logic csr2ipic_w_req_o, // IPIC write request
|
91 |
|
|
output logic [2:0] csr2ipic_addr_o, // IPIC address
|
92 |
|
|
output logic [`SCR1_XLEN-1:0] csr2ipic_wdata_o, // IPIC write data
|
93 |
|
|
input logic [`SCR1_XLEN-1:0] ipic2csr_rdata_i, // IPIC read data
|
94 |
|
|
`endif // SCR1_IPIC_EN
|
95 |
|
|
|
96 |
|
|
`ifdef SCR1_DBG_EN
|
97 |
|
|
// CSR <-> HDU interface
|
98 |
|
|
output logic csr2hdu_req_o, // Request to HDU
|
99 |
|
|
output type_scr1_csr_cmd_sel_e csr2hdu_cmd_o, // HDU command
|
100 |
|
|
output logic [SCR1_HDU_DEBUGCSR_ADDR_WIDTH-1:0] csr2hdu_addr_o, // HDU address
|
101 |
|
|
output logic [`SCR1_XLEN-1:0] csr2hdu_wdata_o, // HDU write data
|
102 |
|
|
input logic [`SCR1_XLEN-1:0] hdu2csr_rdata_i, // HDU read data
|
103 |
|
|
input type_scr1_csr_resp_e hdu2csr_resp_i, // HDU response
|
104 |
|
|
input logic hdu2csr_no_commit_i, // Forbid instruction commitment
|
105 |
|
|
`endif // SCR1_DBG_EN
|
106 |
|
|
|
107 |
|
|
`ifdef SCR1_TDU_EN
|
108 |
|
|
// CSR <-> TDU interface
|
109 |
|
|
output logic csr2tdu_req_o, // Request to TDU
|
110 |
|
|
output type_scr1_csr_cmd_sel_e csr2tdu_cmd_o, // TDU command
|
111 |
|
|
output logic [SCR1_CSR_ADDR_TDU_OFFS_W-1:0] csr2tdu_addr_o, // TDU address
|
112 |
|
|
output logic [`SCR1_XLEN-1:0] csr2tdu_wdata_o, // TDU write data
|
113 |
|
|
input logic [`SCR1_XLEN-1:0] tdu2csr_rdata_i, // TDU read data
|
114 |
|
|
input type_scr1_csr_resp_e tdu2csr_resp_i, // TDU response
|
115 |
|
|
`endif // SCR1_TDU_EN
|
116 |
|
|
|
117 |
|
|
// CSR <-> EXU PC interface
|
118 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
119 |
|
|
input logic exu2csr_instret_no_exc_i, // Instruction retired (without exception)
|
120 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
121 |
|
|
input logic [`SCR1_XLEN-1:0] exu2csr_pc_curr_i, // Current PC
|
122 |
|
|
input logic [`SCR1_XLEN-1:0] exu2csr_pc_next_i, // Next PC
|
123 |
|
|
output logic [`SCR1_XLEN-1:0] csr2exu_new_pc_o // Exception/IRQ/MRET new PC
|
124 |
|
|
);
|
125 |
|
|
|
126 |
|
|
//------------------------------------------------------------------------------
|
127 |
|
|
// Local parameters
|
128 |
|
|
//------------------------------------------------------------------------------
|
129 |
|
|
|
130 |
|
|
`ifdef SCR1_RVC_EXT
|
131 |
|
|
localparam PC_LSB = 1;
|
132 |
|
|
`else
|
133 |
|
|
localparam PC_LSB = 2;
|
134 |
|
|
`endif
|
135 |
|
|
|
136 |
|
|
//------------------------------------------------------------------------------
|
137 |
|
|
// Local signals declaration
|
138 |
|
|
//------------------------------------------------------------------------------
|
139 |
|
|
|
140 |
|
|
// Machine Trap Setup registers
|
141 |
|
|
//------------------------------------------------------------------------------
|
142 |
|
|
|
143 |
|
|
// MSTATUS register
|
144 |
|
|
logic csr_mstatus_upd; // MSTATUS update enable
|
145 |
|
|
logic [`SCR1_XLEN-1:0] csr_mstatus; // Aggregated MSTATUS
|
146 |
|
|
logic csr_mstatus_mie_ff; // MSTATUS: Global interrupt enable
|
147 |
|
|
logic csr_mstatus_mie_next; // MSTATUS: Global interrupt enable next value
|
148 |
|
|
logic csr_mstatus_mpie_ff; // MSTATUS: Global interrupt enable prior to the trap
|
149 |
|
|
logic csr_mstatus_mpie_next; // MSTATUS: Global interrupt enable prior to the trap next value
|
150 |
|
|
|
151 |
|
|
// MIE register
|
152 |
|
|
logic csr_mie_upd; // MIE update enable
|
153 |
|
|
logic [`SCR1_XLEN-1:0] csr_mie; // Aggregated MIE
|
154 |
|
|
logic csr_mie_mtie_ff; // MIE: Machine timer interrupt enable
|
155 |
|
|
logic csr_mie_meie_ff; // MIE: Machine external interrupt enable
|
156 |
|
|
logic csr_mie_msie_ff; // MIE: Machine software interrupt enable
|
157 |
|
|
|
158 |
|
|
// MTVEC register
|
159 |
|
|
logic csr_mtvec_upd; // MTVEC update enable
|
160 |
|
|
logic [`SCR1_XLEN-1:SCR1_CSR_MTVEC_BASE_ZERO_BITS] csr_mtvec_base; // MTVEC: Base (upper 26 bits)
|
161 |
|
|
logic csr_mtvec_mode; // MTVEC: Mode (0-direct, 1-vectored) (wired)
|
162 |
|
|
`ifdef SCR1_MTVEC_MODE_EN
|
163 |
|
|
logic csr_mtvec_mode_ff; // MTVEC: Mode (0-direct, 1-vectored) (registered)
|
164 |
|
|
logic csr_mtvec_mode_vect;
|
165 |
|
|
`endif
|
166 |
|
|
|
167 |
|
|
// Machine Trap Handling registers
|
168 |
|
|
//------------------------------------------------------------------------------
|
169 |
|
|
|
170 |
|
|
// MSCRATCH register
|
171 |
|
|
logic csr_mscratch_upd; // MSCRATCH update enable
|
172 |
|
|
logic [`SCR1_XLEN-1:0] csr_mscratch_ff; // MSCRATCH
|
173 |
|
|
|
174 |
|
|
// MEPC register
|
175 |
|
|
logic csr_mepc_upd; // MEPC update enable
|
176 |
|
|
logic [`SCR1_XLEN-1:PC_LSB] csr_mepc_ff; // MEPC registered value
|
177 |
|
|
logic [`SCR1_XLEN-1:PC_LSB] csr_mepc_next; // MEPC next value
|
178 |
|
|
logic [`SCR1_XLEN-1:0] csr_mepc; // MEPC registered value extended to XLEN
|
179 |
|
|
|
180 |
|
|
// MCAUSE register
|
181 |
|
|
logic csr_mcause_upd; // MCAUSE update enable
|
182 |
|
|
logic csr_mcause_i_ff; // MCAUSE: Interrupt
|
183 |
|
|
logic csr_mcause_i_next; // MCAUSE: Interrupt next value
|
184 |
|
|
logic [SCR1_EXC_CODE_WIDTH_E-1:0] csr_mcause_ec_ff; // MCAUSE: Exception code - cp.7
|
185 |
|
|
logic [SCR1_EXC_CODE_WIDTH_E-1:0] csr_mcause_ec_next; // MCAUSE: Exception code next value - cp.7
|
186 |
|
|
logic [SCR1_EXC_CODE_WIDTH_E-1:0] csr_mcause_ec_new; // MCAUSE: Exception code new value (IRQs) - cp.7
|
187 |
|
|
|
188 |
|
|
// MTVAL register
|
189 |
|
|
logic csr_mtval_upd; // MTVAL update enable
|
190 |
|
|
logic [`SCR1_XLEN-1:0] csr_mtval_ff; // MTVAL registered value
|
191 |
|
|
logic [`SCR1_XLEN-1:0] csr_mtval_next; // MTVAL next value
|
192 |
|
|
|
193 |
|
|
// MIP register
|
194 |
|
|
logic [`SCR1_XLEN-1:0] csr_mip; // Aggregated MIP
|
195 |
|
|
logic csr_mip_mtip; // MIP: Machine timer interrupt pending
|
196 |
|
|
logic csr_mip_meip; // MIP: Machine external interrupt pending
|
197 |
|
|
logic csr_mip_msip; // MIP: Machine software interrupt pending
|
198 |
|
|
|
199 |
|
|
// Machine Counters/Timers registers
|
200 |
|
|
//------------------------------------------------------------------------------
|
201 |
|
|
|
202 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
203 |
|
|
// MINSTRET register
|
204 |
|
|
logic [1:0] csr_minstret_upd;
|
205 |
|
|
logic [SCR1_CSR_COUNTERS_WIDTH-1:0] csr_minstret;
|
206 |
|
|
logic csr_minstret_lo_inc;
|
207 |
|
|
logic csr_minstret_lo_upd;
|
208 |
|
|
logic [7:0] csr_minstret_lo_ff;
|
209 |
|
|
logic [7:0] csr_minstret_lo_next;
|
210 |
|
|
logic csr_minstret_hi_inc;
|
211 |
|
|
logic csr_minstret_hi_upd;
|
212 |
|
|
logic [SCR1_CSR_COUNTERS_WIDTH-1:8] csr_minstret_hi_ff;
|
213 |
|
|
logic [SCR1_CSR_COUNTERS_WIDTH-1:8] csr_minstret_hi_next;
|
214 |
|
|
logic [SCR1_CSR_COUNTERS_WIDTH-1:8] csr_minstret_hi_new;
|
215 |
|
|
|
216 |
|
|
// MCYCLE register
|
217 |
|
|
logic [1:0] csr_mcycle_upd;
|
218 |
|
|
logic [SCR1_CSR_COUNTERS_WIDTH-1:0] csr_mcycle;
|
219 |
|
|
logic csr_mcycle_lo_inc;
|
220 |
|
|
logic csr_mcycle_lo_upd;
|
221 |
|
|
logic [7:0] csr_mcycle_lo_ff;
|
222 |
|
|
logic [7:0] csr_mcycle_lo_next;
|
223 |
|
|
logic csr_mcycle_hi_inc;
|
224 |
|
|
logic csr_mcycle_hi_upd;
|
225 |
|
|
logic [SCR1_CSR_COUNTERS_WIDTH-1:8] csr_mcycle_hi_ff;
|
226 |
|
|
logic [SCR1_CSR_COUNTERS_WIDTH-1:8] csr_mcycle_hi_next;
|
227 |
|
|
logic [SCR1_CSR_COUNTERS_WIDTH-1:8] csr_mcycle_hi_new;
|
228 |
|
|
`endif // ~SCR1_CSR_REDUCED_CNT
|
229 |
|
|
|
230 |
|
|
// Non-standard CSRs
|
231 |
|
|
//------------------------------------------------------------------------------
|
232 |
|
|
|
233 |
|
|
// MCOUNTEN register
|
234 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
235 |
|
|
logic csr_mcounten_upd; // MCOUNTEN update enable
|
236 |
|
|
logic [`SCR1_XLEN-1:0] csr_mcounten; // Aggregated MCOUNTEN
|
237 |
|
|
logic csr_mcounten_cy_ff; // Cycle count enable
|
238 |
|
|
logic csr_mcounten_ir_ff; // Instret count enable
|
239 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
240 |
|
|
|
241 |
|
|
// CSR read/write i/f
|
242 |
|
|
//------------------------------------------------------------------------------
|
243 |
|
|
|
244 |
|
|
logic [`SCR1_XLEN-1:0] csr_r_data;
|
245 |
|
|
logic [`SCR1_XLEN-1:0] csr_w_data;
|
246 |
|
|
|
247 |
|
|
// Events (exceptions, interrupts, mret) signals
|
248 |
|
|
//------------------------------------------------------------------------------
|
249 |
|
|
|
250 |
|
|
// Event flags
|
251 |
|
|
logic e_exc; // Successful exception trap
|
252 |
|
|
logic e_irq; // Successful IRQ trap
|
253 |
|
|
logic e_mret; // MRET instruction
|
254 |
|
|
logic e_irq_nmret; // IRQ trap without MRET instruction
|
255 |
|
|
|
256 |
|
|
// Interrupt pending & enable signals
|
257 |
|
|
logic csr_eirq_pnd_en; // External IRQ pending and locally enabled
|
258 |
|
|
logic csr_sirq_pnd_en; // Software IRQ pending and locally enabled
|
259 |
|
|
logic csr_tirq_pnd_en; // Timer IRQ pending and locally enabled
|
260 |
|
|
|
261 |
|
|
// Exception flags
|
262 |
|
|
logic csr_w_exc;
|
263 |
|
|
logic csr_r_exc;
|
264 |
|
|
logic exu_req_no_exc;
|
265 |
|
|
|
266 |
|
|
// Requests to other modules
|
267 |
|
|
logic csr_ipic_req;
|
268 |
|
|
`ifdef SCR1_DBG_EN
|
269 |
|
|
logic csr_hdu_req;
|
270 |
|
|
`endif // SCR1_DBG_EN
|
271 |
|
|
`ifdef SCR1_TDU_EN
|
272 |
|
|
logic csr_brkm_req;
|
273 |
|
|
`endif // SCR1_TDU_EN
|
274 |
|
|
|
275 |
|
|
//------------------------------------------------------------------------------
|
276 |
|
|
// Events (IRQ, EXC, MRET)
|
277 |
|
|
//------------------------------------------------------------------------------
|
278 |
|
|
|
279 |
|
|
// Events priority
|
280 |
|
|
assign e_exc = exu2csr_take_exc_i
|
281 |
|
|
`ifdef SCR1_DBG_EN
|
282 |
|
|
& ~hdu2csr_no_commit_i
|
283 |
|
|
`endif // SCR1_DBG_EN
|
284 |
|
|
;
|
285 |
|
|
assign e_irq = exu2csr_take_irq_i & ~exu2csr_take_exc_i
|
286 |
|
|
`ifdef SCR1_DBG_EN
|
287 |
|
|
& ~hdu2csr_no_commit_i
|
288 |
|
|
`endif // SCR1_DBG_EN
|
289 |
|
|
;
|
290 |
|
|
assign e_mret = exu2csr_mret_update_i
|
291 |
|
|
`ifdef SCR1_DBG_EN
|
292 |
|
|
& ~hdu2csr_no_commit_i
|
293 |
|
|
`endif // SCR1_DBG_EN
|
294 |
|
|
;
|
295 |
|
|
assign e_irq_nmret = e_irq & ~exu2csr_mret_instr_i;
|
296 |
|
|
|
297 |
|
|
// IRQ pending & enable signals
|
298 |
|
|
assign csr_eirq_pnd_en = csr_mip_meip & csr_mie_meie_ff;
|
299 |
|
|
assign csr_sirq_pnd_en = csr_mip_msip & csr_mie_msie_ff;
|
300 |
|
|
assign csr_tirq_pnd_en = csr_mip_mtip & csr_mie_mtie_ff;
|
301 |
|
|
|
302 |
|
|
// IRQ exception codes priority
|
303 |
|
|
always_comb begin
|
304 |
|
|
case (1'b1)
|
305 |
|
|
csr_eirq_pnd_en: csr_mcause_ec_new = SCR1_EXC_CODE_IRQ_M_EXTERNAL; // cp.7
|
306 |
|
|
csr_sirq_pnd_en: csr_mcause_ec_new = SCR1_EXC_CODE_IRQ_M_SOFTWARE; // cp.7
|
307 |
|
|
csr_tirq_pnd_en: csr_mcause_ec_new = SCR1_EXC_CODE_IRQ_M_TIMER; // cp.7
|
308 |
|
|
default : csr_mcause_ec_new = SCR1_EXC_CODE_IRQ_M_EXTERNAL; // cp.7
|
309 |
|
|
endcase
|
310 |
|
|
end
|
311 |
|
|
|
312 |
|
|
assign exu_req_no_exc = ((exu2csr_r_req_i & ~csr_r_exc)
|
313 |
|
|
| (exu2csr_w_req_i & ~csr_w_exc));
|
314 |
|
|
|
315 |
|
|
//------------------------------------------------------------------------------
|
316 |
|
|
// CSR read/write interface
|
317 |
|
|
//------------------------------------------------------------------------------
|
318 |
|
|
|
319 |
|
|
// CSR read logic
|
320 |
|
|
//------------------------------------------------------------------------------
|
321 |
|
|
|
322 |
|
|
always_comb begin
|
323 |
|
|
csr_r_data = '0;
|
324 |
|
|
csr_r_exc = 1'b0;
|
325 |
|
|
`ifdef SCR1_DBG_EN
|
326 |
|
|
csr_hdu_req = 1'b0;
|
327 |
|
|
`endif // SCR1_DBG_EN
|
328 |
|
|
`ifdef SCR1_TDU_EN
|
329 |
|
|
csr_brkm_req = 1'b0;
|
330 |
|
|
`endif // SCR1_TDU_EN
|
331 |
|
|
`ifdef SCR1_IPIC_EN
|
332 |
|
|
csr2ipic_r_req_o = 1'b0;
|
333 |
|
|
`endif // SCR1_IPIC_EN
|
334 |
|
|
|
335 |
|
|
casez (exu2csr_rw_addr_i)
|
336 |
|
|
// Machine Information Registers (read-only)
|
337 |
|
|
SCR1_CSR_ADDR_MVENDORID : csr_r_data = SCR1_CSR_MVENDORID;
|
338 |
|
|
SCR1_CSR_ADDR_MARCHID : csr_r_data = SCR1_CSR_MARCHID;
|
339 |
|
|
SCR1_CSR_ADDR_MIMPID : csr_r_data = SCR1_CSR_MIMPID;
|
340 |
|
|
SCR1_CSR_ADDR_MHARTID : csr_r_data = soc2csr_fuse_mhartid_i;
|
341 |
|
|
|
342 |
|
|
// Machine Trap Setup (read-write)
|
343 |
|
|
SCR1_CSR_ADDR_MSTATUS : csr_r_data = csr_mstatus;
|
344 |
|
|
SCR1_CSR_ADDR_MISA : csr_r_data = SCR1_CSR_MISA;
|
345 |
|
|
SCR1_CSR_ADDR_MIE : csr_r_data = csr_mie;
|
346 |
|
|
SCR1_CSR_ADDR_MTVEC : csr_r_data = {csr_mtvec_base, 4'd0, 2'(csr_mtvec_mode)};
|
347 |
|
|
|
348 |
|
|
// Machine Trap Handling (read-write)
|
349 |
|
|
SCR1_CSR_ADDR_MSCRATCH : csr_r_data = csr_mscratch_ff;
|
350 |
|
|
SCR1_CSR_ADDR_MEPC : csr_r_data = csr_mepc;
|
351 |
|
|
SCR1_CSR_ADDR_MCAUSE : csr_r_data = {csr_mcause_i_ff, (`SCR1_XLEN-1)'(csr_mcause_ec_ff)};
|
352 |
|
|
SCR1_CSR_ADDR_MTVAL : csr_r_data = csr_mtval_ff;
|
353 |
|
|
SCR1_CSR_ADDR_MIP : csr_r_data = csr_mip;
|
354 |
|
|
|
355 |
|
|
// User Counters/Timers (read-only)
|
356 |
|
|
{SCR1_CSR_ADDR_HPMCOUNTER_MASK, 5'b?????} : begin
|
357 |
|
|
case (exu2csr_rw_addr_i[4:0])
|
358 |
|
|
5'd1 : csr_r_data = soc2csr_mtimer_val_i[31:0];
|
359 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
360 |
|
|
5'd0 : csr_r_data = csr_mcycle[31:0];
|
361 |
|
|
5'd2 : csr_r_data = csr_minstret[31:0];
|
362 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
363 |
|
|
default : begin
|
364 |
|
|
// return 0
|
365 |
|
|
end
|
366 |
|
|
endcase
|
367 |
|
|
end
|
368 |
|
|
|
369 |
|
|
{SCR1_CSR_ADDR_HPMCOUNTERH_MASK, 5'b?????} : begin
|
370 |
|
|
case (exu2csr_rw_addr_i[4:0])
|
371 |
|
|
5'd1 : csr_r_data = soc2csr_mtimer_val_i[63:32];
|
372 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
373 |
|
|
5'd0 : csr_r_data = csr_mcycle[63:32];
|
374 |
|
|
5'd2 : csr_r_data = csr_minstret[63:32];
|
375 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
376 |
|
|
default : begin
|
377 |
|
|
// return 0
|
378 |
|
|
end
|
379 |
|
|
endcase
|
380 |
|
|
end
|
381 |
|
|
|
382 |
|
|
// Machine Counters/Timers (read-write)
|
383 |
|
|
{SCR1_CSR_ADDR_MHPMCOUNTER_MASK, 5'b?????} : begin
|
384 |
|
|
case (exu2csr_rw_addr_i[4:0])
|
385 |
|
|
5'd1 : csr_r_exc = exu2csr_r_req_i;
|
386 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
387 |
|
|
5'd0 : csr_r_data = csr_mcycle[31:0];
|
388 |
|
|
5'd2 : csr_r_data = csr_minstret[31:0];
|
389 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
390 |
|
|
default : begin
|
391 |
|
|
// return 0
|
392 |
|
|
end
|
393 |
|
|
endcase
|
394 |
|
|
end
|
395 |
|
|
|
396 |
|
|
{SCR1_CSR_ADDR_MHPMCOUNTERH_MASK, 5'b?????} : begin
|
397 |
|
|
case (exu2csr_rw_addr_i[4:0])
|
398 |
|
|
5'd1 : csr_r_exc = exu2csr_r_req_i;
|
399 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
400 |
|
|
5'd0 : csr_r_data = csr_mcycle[63:32];
|
401 |
|
|
5'd2 : csr_r_data = csr_minstret[63:32];
|
402 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
403 |
|
|
default : begin
|
404 |
|
|
// return 0
|
405 |
|
|
end
|
406 |
|
|
endcase
|
407 |
|
|
end
|
408 |
|
|
|
409 |
|
|
{SCR1_CSR_ADDR_MHPMEVENT_MASK, 5'b?????} : begin
|
410 |
|
|
case (exu2csr_rw_addr_i[4:0])
|
411 |
|
|
5'd0,
|
412 |
|
|
5'd1,
|
413 |
|
|
5'd2 : csr_r_exc = exu2csr_r_req_i;
|
414 |
|
|
default : begin
|
415 |
|
|
// return 0
|
416 |
|
|
end
|
417 |
|
|
endcase
|
418 |
|
|
end
|
419 |
|
|
|
420 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
421 |
|
|
SCR1_CSR_ADDR_MCOUNTEN : csr_r_data = csr_mcounten;
|
422 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
423 |
|
|
|
424 |
|
|
`ifdef SCR1_IPIC_EN
|
425 |
|
|
// IPIC registers
|
426 |
|
|
SCR1_CSR_ADDR_IPIC_CISV,
|
427 |
|
|
SCR1_CSR_ADDR_IPIC_CICSR,
|
428 |
|
|
SCR1_CSR_ADDR_IPIC_IPR,
|
429 |
|
|
SCR1_CSR_ADDR_IPIC_ISVR,
|
430 |
|
|
SCR1_CSR_ADDR_IPIC_EOI,
|
431 |
|
|
SCR1_CSR_ADDR_IPIC_SOI,
|
432 |
|
|
SCR1_CSR_ADDR_IPIC_IDX,
|
433 |
|
|
SCR1_CSR_ADDR_IPIC_ICSR : begin
|
434 |
|
|
csr_r_data = ipic2csr_rdata_i;
|
435 |
|
|
csr2ipic_r_req_o = exu2csr_r_req_i;
|
436 |
|
|
end
|
437 |
|
|
`endif // SCR1_IPIC_EN
|
438 |
|
|
|
439 |
|
|
`ifdef SCR1_DBG_EN
|
440 |
|
|
// HDU registers
|
441 |
|
|
SCR1_HDU_DBGCSR_ADDR_DCSR,
|
442 |
|
|
SCR1_HDU_DBGCSR_ADDR_DPC,
|
443 |
|
|
SCR1_HDU_DBGCSR_ADDR_DSCRATCH0,
|
444 |
|
|
SCR1_HDU_DBGCSR_ADDR_DSCRATCH1 : begin
|
445 |
|
|
csr_hdu_req = 1'b1;
|
446 |
|
|
csr_r_data = hdu2csr_rdata_i;
|
447 |
|
|
end
|
448 |
|
|
`endif // SCR1_DBG_EN
|
449 |
|
|
|
450 |
|
|
`ifdef SCR1_TDU_EN
|
451 |
|
|
// TDU registers
|
452 |
|
|
SCR1_CSR_ADDR_TDU_TSELECT,
|
453 |
|
|
SCR1_CSR_ADDR_TDU_TDATA1,
|
454 |
|
|
SCR1_CSR_ADDR_TDU_TDATA2,
|
455 |
|
|
SCR1_CSR_ADDR_TDU_TINFO: begin
|
456 |
|
|
csr_brkm_req = 1'b1;
|
457 |
|
|
csr_r_data = tdu2csr_rdata_i;
|
458 |
|
|
end
|
459 |
|
|
`endif // SCR1_TDU_EN
|
460 |
|
|
|
461 |
|
|
default : begin
|
462 |
|
|
csr_r_exc = exu2csr_r_req_i;
|
463 |
|
|
end
|
464 |
|
|
endcase // exu2csr_rw_addr_i
|
465 |
|
|
end
|
466 |
|
|
|
467 |
|
|
assign csr2exu_r_data_o = csr_r_data;
|
468 |
|
|
|
469 |
|
|
// CSR write logic
|
470 |
|
|
//------------------------------------------------------------------------------
|
471 |
|
|
|
472 |
|
|
always_comb begin
|
473 |
|
|
case (exu2csr_w_cmd_i)
|
474 |
|
|
SCR1_CSR_CMD_WRITE : csr_w_data = exu2csr_w_data_i;
|
475 |
|
|
SCR1_CSR_CMD_SET : csr_w_data = exu2csr_w_data_i | csr_r_data;
|
476 |
|
|
SCR1_CSR_CMD_CLEAR : csr_w_data = ~exu2csr_w_data_i & csr_r_data;
|
477 |
|
|
default : csr_w_data = '0;
|
478 |
|
|
endcase
|
479 |
|
|
end
|
480 |
|
|
|
481 |
|
|
always_comb begin
|
482 |
|
|
csr_mstatus_upd = 1'b0;
|
483 |
|
|
csr_mie_upd = 1'b0;
|
484 |
|
|
csr_mscratch_upd = 1'b0;
|
485 |
|
|
csr_mepc_upd = 1'b0;
|
486 |
|
|
csr_mcause_upd = 1'b0;
|
487 |
|
|
csr_mtval_upd = 1'b0;
|
488 |
|
|
csr_mtvec_upd = 1'b0;
|
489 |
|
|
|
490 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
491 |
|
|
csr_mcycle_upd = 2'b00;
|
492 |
|
|
csr_minstret_upd = 2'b00;
|
493 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
494 |
|
|
|
495 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
496 |
|
|
csr_mcounten_upd = 1'b0;
|
497 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
498 |
|
|
csr_w_exc = 1'b0;
|
499 |
|
|
`ifdef SCR1_IPIC_EN
|
500 |
|
|
csr2ipic_w_req_o = 1'b0;
|
501 |
|
|
`endif // SCR1_IPIC_EN
|
502 |
|
|
|
503 |
|
|
if (exu2csr_w_req_i) begin
|
504 |
|
|
casez (exu2csr_rw_addr_i)
|
505 |
|
|
// Machine Trap Setup (read-write)
|
506 |
|
|
SCR1_CSR_ADDR_MSTATUS : csr_mstatus_upd = 1'b1;
|
507 |
|
|
SCR1_CSR_ADDR_MISA : begin end
|
508 |
|
|
SCR1_CSR_ADDR_MIE : csr_mie_upd = 1'b1;
|
509 |
|
|
SCR1_CSR_ADDR_MTVEC : csr_mtvec_upd = 1'b1;
|
510 |
|
|
|
511 |
|
|
// Machine Trap Handling (read-write)
|
512 |
|
|
SCR1_CSR_ADDR_MSCRATCH : csr_mscratch_upd = 1'b1;
|
513 |
|
|
SCR1_CSR_ADDR_MEPC : csr_mepc_upd = 1'b1;
|
514 |
|
|
SCR1_CSR_ADDR_MCAUSE : csr_mcause_upd = 1'b1;
|
515 |
|
|
SCR1_CSR_ADDR_MTVAL : csr_mtval_upd = 1'b1;
|
516 |
|
|
SCR1_CSR_ADDR_MIP : begin end
|
517 |
|
|
|
518 |
|
|
// Machine Counters/Timers (read-write)
|
519 |
|
|
{SCR1_CSR_ADDR_MHPMCOUNTER_MASK, 5'b?????} : begin
|
520 |
|
|
case (exu2csr_rw_addr_i[4:0])
|
521 |
|
|
5'd1 : csr_w_exc = 1'b1;
|
522 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
523 |
|
|
5'd0 : csr_mcycle_upd[0] = 1'b1;
|
524 |
|
|
5'd2 : csr_minstret_upd[0] = 1'b1;
|
525 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
526 |
|
|
default : begin
|
527 |
|
|
// no exception
|
528 |
|
|
end
|
529 |
|
|
endcase
|
530 |
|
|
end
|
531 |
|
|
|
532 |
|
|
{SCR1_CSR_ADDR_MHPMCOUNTERH_MASK, 5'b?????} : begin
|
533 |
|
|
case (exu2csr_rw_addr_i[4:0])
|
534 |
|
|
5'd1 : csr_w_exc = 1'b1;
|
535 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
536 |
|
|
5'd0 : csr_mcycle_upd[1] = 1'b1;
|
537 |
|
|
5'd2 : csr_minstret_upd[1] = 1'b1;
|
538 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
539 |
|
|
default : begin
|
540 |
|
|
// no exception
|
541 |
|
|
end
|
542 |
|
|
endcase
|
543 |
|
|
end
|
544 |
|
|
|
545 |
|
|
{SCR1_CSR_ADDR_MHPMEVENT_MASK, 5'b?????} : begin
|
546 |
|
|
case (exu2csr_rw_addr_i[4:0])
|
547 |
|
|
5'd0,
|
548 |
|
|
5'd1,
|
549 |
|
|
5'd2 : csr_w_exc = 1'b1;
|
550 |
|
|
default : begin
|
551 |
|
|
// no exception
|
552 |
|
|
end
|
553 |
|
|
endcase
|
554 |
|
|
end
|
555 |
|
|
|
556 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
557 |
|
|
SCR1_CSR_ADDR_MCOUNTEN : csr_mcounten_upd = 1'b1;
|
558 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
559 |
|
|
|
560 |
|
|
`ifdef SCR1_IPIC_EN
|
561 |
|
|
// IPIC registers
|
562 |
|
|
SCR1_CSR_ADDR_IPIC_CICSR,
|
563 |
|
|
SCR1_CSR_ADDR_IPIC_IPR,
|
564 |
|
|
SCR1_CSR_ADDR_IPIC_EOI,
|
565 |
|
|
SCR1_CSR_ADDR_IPIC_SOI,
|
566 |
|
|
SCR1_CSR_ADDR_IPIC_IDX,
|
567 |
|
|
SCR1_CSR_ADDR_IPIC_ICSR : begin
|
568 |
|
|
csr2ipic_w_req_o = 1'b1;
|
569 |
|
|
end
|
570 |
|
|
SCR1_CSR_ADDR_IPIC_CISV,
|
571 |
|
|
SCR1_CSR_ADDR_IPIC_ISVR : begin
|
572 |
|
|
// no exception on write
|
573 |
|
|
end
|
574 |
|
|
`endif // SCR1_IPIC_EN
|
575 |
|
|
|
576 |
|
|
`ifdef SCR1_DBG_EN
|
577 |
|
|
SCR1_HDU_DBGCSR_ADDR_DCSR,
|
578 |
|
|
SCR1_HDU_DBGCSR_ADDR_DPC,
|
579 |
|
|
SCR1_HDU_DBGCSR_ADDR_DSCRATCH0,
|
580 |
|
|
SCR1_HDU_DBGCSR_ADDR_DSCRATCH1 : begin
|
581 |
|
|
end
|
582 |
|
|
`endif // SCR1_DBG_EN
|
583 |
|
|
|
584 |
|
|
`ifdef SCR1_TDU_EN
|
585 |
|
|
// TDU registers
|
586 |
|
|
SCR1_CSR_ADDR_TDU_TSELECT,
|
587 |
|
|
SCR1_CSR_ADDR_TDU_TDATA1,
|
588 |
|
|
SCR1_CSR_ADDR_TDU_TDATA2,
|
589 |
|
|
SCR1_CSR_ADDR_TDU_TINFO: begin
|
590 |
|
|
end
|
591 |
|
|
`endif // SCR1_TDU_EN
|
592 |
|
|
|
593 |
|
|
default : begin
|
594 |
|
|
csr_w_exc = 1'b1;
|
595 |
|
|
end
|
596 |
|
|
endcase
|
597 |
|
|
end
|
598 |
|
|
end
|
599 |
|
|
|
600 |
|
|
//------------------------------------------------------------------------------
|
601 |
|
|
// Machine Trap Setup registers
|
602 |
|
|
//------------------------------------------------------------------------------
|
603 |
|
|
//
|
604 |
|
|
// Registers:
|
605 |
|
|
// - MSTATUS
|
606 |
|
|
// - MIE
|
607 |
|
|
// - MTVEC
|
608 |
|
|
//
|
609 |
|
|
|
610 |
|
|
// MSTATUS register
|
611 |
|
|
//------------------------------------------------------------------------------
|
612 |
|
|
// Consists of 2 bits - current and previous (before trap) global interrupt
|
613 |
|
|
// enable bits (MIE & MPIE)
|
614 |
|
|
|
615 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
616 |
|
|
if (~rst_n) begin
|
617 |
|
|
csr_mstatus_mie_ff <= SCR1_CSR_MSTATUS_MIE_RST_VAL;
|
618 |
|
|
csr_mstatus_mpie_ff <= SCR1_CSR_MSTATUS_MPIE_RST_VAL;
|
619 |
|
|
end else begin
|
620 |
|
|
csr_mstatus_mie_ff <= csr_mstatus_mie_next;
|
621 |
|
|
csr_mstatus_mpie_ff <= csr_mstatus_mpie_next;
|
622 |
|
|
end
|
623 |
|
|
end
|
624 |
|
|
|
625 |
|
|
always_comb begin
|
626 |
|
|
case (1'b1)
|
627 |
|
|
e_exc, e_irq : begin
|
628 |
|
|
csr_mstatus_mie_next = 1'b0;
|
629 |
|
|
csr_mstatus_mpie_next = csr_mstatus_mie_ff;
|
630 |
|
|
end
|
631 |
|
|
e_mret : begin
|
632 |
|
|
csr_mstatus_mie_next = csr_mstatus_mpie_ff;
|
633 |
|
|
csr_mstatus_mpie_next = 1'b1;
|
634 |
|
|
end
|
635 |
|
|
csr_mstatus_upd: begin
|
636 |
|
|
csr_mstatus_mie_next = csr_w_data[SCR1_CSR_MSTATUS_MIE_OFFSET];
|
637 |
|
|
csr_mstatus_mpie_next = csr_w_data[SCR1_CSR_MSTATUS_MPIE_OFFSET];
|
638 |
|
|
end
|
639 |
|
|
default : begin
|
640 |
|
|
csr_mstatus_mie_next = csr_mstatus_mie_ff;
|
641 |
|
|
csr_mstatus_mpie_next = csr_mstatus_mpie_ff;
|
642 |
|
|
end
|
643 |
|
|
endcase
|
644 |
|
|
end
|
645 |
|
|
|
646 |
|
|
always_comb begin
|
647 |
|
|
csr_mstatus = '0;
|
648 |
|
|
csr_mstatus[SCR1_CSR_MSTATUS_MIE_OFFSET] = csr_mstatus_mie_ff;
|
649 |
|
|
csr_mstatus[SCR1_CSR_MSTATUS_MPIE_OFFSET] = csr_mstatus_mpie_ff;
|
650 |
|
|
csr_mstatus[SCR1_CSR_MSTATUS_MPP_OFFSET+1:SCR1_CSR_MSTATUS_MPP_OFFSET] = SCR1_CSR_MSTATUS_MPP;
|
651 |
|
|
end
|
652 |
|
|
|
653 |
|
|
// MIE register
|
654 |
|
|
//------------------------------------------------------------------------------
|
655 |
|
|
// Contains interrupt enable bits (external, software, timer IRQs)
|
656 |
|
|
|
657 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
658 |
|
|
if (~rst_n) begin
|
659 |
|
|
csr_mie_mtie_ff <= SCR1_CSR_MIE_MTIE_RST_VAL;
|
660 |
|
|
csr_mie_meie_ff <= SCR1_CSR_MIE_MEIE_RST_VAL;
|
661 |
|
|
csr_mie_msie_ff <= SCR1_CSR_MIE_MSIE_RST_VAL;
|
662 |
|
|
end else if (csr_mie_upd) begin
|
663 |
|
|
csr_mie_mtie_ff <= csr_w_data[SCR1_CSR_MIE_MTIE_OFFSET];
|
664 |
|
|
csr_mie_meie_ff <= csr_w_data[SCR1_CSR_MIE_MEIE_OFFSET];
|
665 |
|
|
csr_mie_msie_ff <= csr_w_data[SCR1_CSR_MIE_MSIE_OFFSET];
|
666 |
|
|
end
|
667 |
|
|
end
|
668 |
|
|
|
669 |
|
|
always_comb begin
|
670 |
|
|
csr_mie = '0;
|
671 |
|
|
csr_mie[SCR1_CSR_MIE_MSIE_OFFSET] = csr_mie_msie_ff;
|
672 |
|
|
csr_mie[SCR1_CSR_MIE_MTIE_OFFSET] = csr_mie_mtie_ff;
|
673 |
|
|
csr_mie[SCR1_CSR_MIE_MEIE_OFFSET] = csr_mie_meie_ff;
|
674 |
|
|
end
|
675 |
|
|
|
676 |
|
|
// MTVEC register
|
677 |
|
|
//------------------------------------------------------------------------------
|
678 |
|
|
// Holds trap vector configuation. Consists of base and mode parts
|
679 |
|
|
|
680 |
|
|
// MTVEC BASE part
|
681 |
|
|
//------------------------------------------------------------------------------
|
682 |
|
|
// Holds trap vector base address
|
683 |
|
|
generate
|
684 |
|
|
// All bits of MTVEC base are Read-Only and hardwired to 0's
|
685 |
|
|
if (SCR1_MTVEC_BASE_WR_BITS == 0) begin : mtvec_base_ro
|
686 |
|
|
|
687 |
|
|
assign csr_mtvec_base = SCR1_CSR_MTVEC_BASE_RST_VAL;
|
688 |
|
|
|
689 |
|
|
// All bits of MTVEC base are RW
|
690 |
|
|
end else if (SCR1_MTVEC_BASE_WR_BITS == SCR1_CSR_MTVEC_BASE_VAL_BITS) begin : mtvec_base_rw
|
691 |
|
|
|
692 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
693 |
|
|
if (~rst_n) begin
|
694 |
|
|
csr_mtvec_base <= SCR1_CSR_MTVEC_BASE_RST_VAL;
|
695 |
|
|
end else if (csr_mtvec_upd) begin
|
696 |
|
|
csr_mtvec_base <= csr_w_data[`SCR1_XLEN-1:SCR1_CSR_MTVEC_BASE_ZERO_BITS];
|
697 |
|
|
end
|
698 |
|
|
end
|
699 |
|
|
|
700 |
|
|
// Lower bits of MTVEC base are RO, higher - RW
|
701 |
|
|
end else begin : mtvec_base_ro_rw
|
702 |
|
|
|
703 |
|
|
logic [(`SCR1_XLEN-1):(`SCR1_XLEN-SCR1_MTVEC_BASE_WR_BITS)] csr_mtvec_base_reg;
|
704 |
|
|
|
705 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
706 |
|
|
if (~rst_n) begin
|
707 |
|
|
csr_mtvec_base_reg <= SCR1_CSR_MTVEC_BASE_RST_VAL[(`SCR1_XLEN-1)-:SCR1_MTVEC_BASE_WR_BITS] ;
|
708 |
|
|
end else if (csr_mtvec_upd) begin
|
709 |
|
|
csr_mtvec_base_reg <= csr_w_data[(`SCR1_XLEN-1)-:SCR1_MTVEC_BASE_WR_BITS];
|
710 |
|
|
end
|
711 |
|
|
end
|
712 |
|
|
|
713 |
|
|
assign csr_mtvec_base = {csr_mtvec_base_reg, SCR1_CSR_MTVEC_BASE_RST_VAL[SCR1_CSR_MTVEC_BASE_ZERO_BITS+:SCR1_CSR_MTVEC_BASE_RO_BITS]};
|
714 |
|
|
end
|
715 |
|
|
endgenerate
|
716 |
|
|
|
717 |
|
|
// MTVEC MODE part
|
718 |
|
|
//------------------------------------------------------------------------------
|
719 |
|
|
// Chooses between direct (all exceptions set PC to BASE) or vectored
|
720 |
|
|
// (asynchronous interrupts set PC to BASE+4xcause) interrupt modes
|
721 |
|
|
|
722 |
|
|
`ifdef SCR1_MTVEC_MODE_EN
|
723 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
724 |
|
|
if (~rst_n) begin
|
725 |
|
|
csr_mtvec_mode_ff <= SCR1_CSR_MTVEC_MODE_DIRECT;
|
726 |
|
|
end else if (csr_mtvec_upd) begin
|
727 |
|
|
csr_mtvec_mode_ff <= csr_w_data[0];
|
728 |
|
|
end
|
729 |
|
|
end
|
730 |
|
|
|
731 |
|
|
assign csr_mtvec_mode = csr_mtvec_mode_ff;
|
732 |
|
|
assign csr_mtvec_mode_vect = (csr_mtvec_mode_ff == SCR1_CSR_MTVEC_MODE_VECTORED);
|
733 |
|
|
`else // SCR1_MTVEC_MODE_EN
|
734 |
|
|
assign csr_mtvec_mode = SCR1_CSR_MTVEC_MODE_DIRECT;
|
735 |
|
|
`endif // SCR1_MTVEC_MODE_EN
|
736 |
|
|
|
737 |
|
|
//------------------------------------------------------------------------------
|
738 |
|
|
// Machine Trap Handling registers
|
739 |
|
|
//------------------------------------------------------------------------------
|
740 |
|
|
//
|
741 |
|
|
// Registers:
|
742 |
|
|
// - MSCRATCH
|
743 |
|
|
// - MEPC
|
744 |
|
|
// - MCAUSE
|
745 |
|
|
// - MTVAL
|
746 |
|
|
// - MIP
|
747 |
|
|
//
|
748 |
|
|
|
749 |
|
|
// MSCRATCH register
|
750 |
|
|
//------------------------------------------------------------------------------
|
751 |
|
|
// Holds a pointer to a machine-mode hart-local context space
|
752 |
|
|
|
753 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
754 |
|
|
if (~rst_n) begin
|
755 |
|
|
csr_mscratch_ff <= '0;
|
756 |
|
|
end else if (csr_mscratch_upd) begin
|
757 |
|
|
csr_mscratch_ff <= csr_w_data;
|
758 |
|
|
end
|
759 |
|
|
end
|
760 |
|
|
|
761 |
|
|
// MEPC register
|
762 |
|
|
//------------------------------------------------------------------------------
|
763 |
|
|
// When a trap is taken into M-mode saves the virtual address of instruction that
|
764 |
|
|
// was interrupted or that encountered the exception
|
765 |
|
|
|
766 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
767 |
|
|
if (~rst_n) begin
|
768 |
|
|
csr_mepc_ff <= '0;
|
769 |
|
|
end else begin
|
770 |
|
|
csr_mepc_ff <= csr_mepc_next;
|
771 |
|
|
end
|
772 |
|
|
end
|
773 |
|
|
|
774 |
|
|
always_comb begin
|
775 |
|
|
case (1'b1)
|
776 |
|
|
e_exc : csr_mepc_next = exu2csr_pc_curr_i[`SCR1_XLEN-1:PC_LSB];
|
777 |
|
|
e_irq_nmret : csr_mepc_next = exu2csr_pc_next_i[`SCR1_XLEN-1:PC_LSB];
|
778 |
|
|
csr_mepc_upd: csr_mepc_next = csr_w_data[`SCR1_XLEN-1:PC_LSB];
|
779 |
|
|
default : csr_mepc_next = csr_mepc_ff;
|
780 |
|
|
endcase
|
781 |
|
|
end
|
782 |
|
|
|
783 |
|
|
`ifdef SCR1_RVC_EXT
|
784 |
|
|
assign csr_mepc = {csr_mepc_ff, 1'b0};
|
785 |
|
|
`else
|
786 |
|
|
assign csr_mepc = {csr_mepc_ff, 2'b00};
|
787 |
|
|
`endif
|
788 |
|
|
|
789 |
|
|
// MCAUSE register
|
790 |
|
|
//------------------------------------------------------------------------------
|
791 |
|
|
// When a trap is taken into M-mode saves a code indicating the event that caused
|
792 |
|
|
// the trap
|
793 |
|
|
|
794 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
795 |
|
|
if (~rst_n) begin
|
796 |
|
|
csr_mcause_i_ff <= 1'b0;
|
797 |
|
|
csr_mcause_ec_ff <= SCR1_EXC_CODE_RESET; // cp.7
|
798 |
|
|
end else begin
|
799 |
|
|
csr_mcause_i_ff <= csr_mcause_i_next;
|
800 |
|
|
csr_mcause_ec_ff <= csr_mcause_ec_next;
|
801 |
|
|
end
|
802 |
|
|
end
|
803 |
|
|
|
804 |
|
|
always_comb begin
|
805 |
|
|
case (1'b1)
|
806 |
|
|
e_exc : begin
|
807 |
|
|
csr_mcause_i_next = 1'b0;
|
808 |
|
|
csr_mcause_ec_next = exu2csr_exc_code_i;
|
809 |
|
|
end
|
810 |
|
|
e_irq : begin
|
811 |
|
|
csr_mcause_i_next = 1'b1;
|
812 |
|
|
csr_mcause_ec_next = csr_mcause_ec_new;
|
813 |
|
|
end
|
814 |
|
|
csr_mcause_upd: begin
|
815 |
|
|
csr_mcause_i_next = csr_w_data[`SCR1_XLEN-1];
|
816 |
|
|
csr_mcause_ec_next = csr_w_data[SCR1_EXC_CODE_WIDTH_E-1:0]; // cp.7
|
817 |
|
|
end
|
818 |
|
|
default : begin
|
819 |
|
|
csr_mcause_i_next = csr_mcause_i_ff;
|
820 |
|
|
csr_mcause_ec_next = csr_mcause_ec_ff;
|
821 |
|
|
end
|
822 |
|
|
endcase
|
823 |
|
|
end
|
824 |
|
|
|
825 |
|
|
// MTVAL register
|
826 |
|
|
//------------------------------------------------------------------------------
|
827 |
|
|
// When a trap is taken into M-mode is either set to zero or written with exception-
|
828 |
|
|
// specific information
|
829 |
|
|
|
830 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
831 |
|
|
if (~rst_n) begin
|
832 |
|
|
csr_mtval_ff <= '0;
|
833 |
|
|
end else begin
|
834 |
|
|
csr_mtval_ff <= csr_mtval_next;
|
835 |
|
|
end
|
836 |
|
|
end
|
837 |
|
|
|
838 |
|
|
always_comb begin
|
839 |
|
|
case (1'b1)
|
840 |
|
|
e_exc : csr_mtval_next = exu2csr_trap_val_i;
|
841 |
|
|
e_irq : csr_mtval_next = '0;
|
842 |
|
|
csr_mtval_upd: csr_mtval_next = csr_w_data;
|
843 |
|
|
default : csr_mtval_next = csr_mtval_ff;
|
844 |
|
|
endcase
|
845 |
|
|
end
|
846 |
|
|
|
847 |
|
|
// MIP register
|
848 |
|
|
//------------------------------------------------------------------------------
|
849 |
|
|
// Contains information on pending interrupts (external, software, timer IRQs)
|
850 |
|
|
|
851 |
|
|
assign csr_mip_mtip = soc2csr_irq_mtimer_i;
|
852 |
|
|
assign csr_mip_meip = soc2csr_irq_ext_i;
|
853 |
|
|
assign csr_mip_msip = soc2csr_irq_soft_i;
|
854 |
|
|
|
855 |
|
|
always_comb begin
|
856 |
|
|
csr_mip = '0;
|
857 |
|
|
csr_mip[SCR1_CSR_MIE_MSIE_OFFSET] = csr_mip_msip;
|
858 |
|
|
csr_mip[SCR1_CSR_MIE_MTIE_OFFSET] = csr_mip_mtip;
|
859 |
|
|
csr_mip[SCR1_CSR_MIE_MEIE_OFFSET] = csr_mip_meip;
|
860 |
|
|
end
|
861 |
|
|
|
862 |
|
|
//------------------------------------------------------------------------------
|
863 |
|
|
// Machine Counters/Timers registers
|
864 |
|
|
//------------------------------------------------------------------------------
|
865 |
|
|
//
|
866 |
|
|
// Registers:
|
867 |
|
|
// - MCYCLE
|
868 |
|
|
// - MINSTRET
|
869 |
|
|
//
|
870 |
|
|
|
871 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
872 |
|
|
// MCYCLE register
|
873 |
|
|
//------------------------------------------------------------------------------
|
874 |
|
|
// Holds the number of clock cycles since some arbitrary point of time in the
|
875 |
|
|
// past at which MCYCLE was zero
|
876 |
|
|
|
877 |
|
|
assign csr_mcycle_lo_inc = 1'b1
|
878 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
879 |
|
|
& csr_mcounten_cy_ff
|
880 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
881 |
|
|
;
|
882 |
|
|
assign csr_mcycle_hi_inc = csr_mcycle_lo_inc & (&csr_mcycle_lo_ff);
|
883 |
|
|
|
884 |
|
|
assign csr_mcycle_lo_upd = csr_mcycle_lo_inc | csr_mcycle_upd[0];
|
885 |
|
|
assign csr_mcycle_hi_upd = csr_mcycle_hi_inc | (|csr_mcycle_upd);
|
886 |
|
|
|
887 |
|
|
`ifndef SCR1_CLKCTRL_EN
|
888 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
889 |
|
|
`else // SCR1_CLKCTRL_EN
|
890 |
|
|
always_ff @(negedge rst_n, posedge clk_alw_on) begin
|
891 |
|
|
`endif // SCR1_CLKCTRL_EN
|
892 |
|
|
if (~rst_n) begin
|
893 |
|
|
csr_mcycle_lo_ff <= '0;
|
894 |
|
|
csr_mcycle_hi_ff <= '0;
|
895 |
|
|
end else begin
|
896 |
|
|
if (csr_mcycle_lo_upd) csr_mcycle_lo_ff <= csr_mcycle_lo_next;
|
897 |
|
|
if (csr_mcycle_hi_upd) csr_mcycle_hi_ff <= csr_mcycle_hi_next;
|
898 |
|
|
end
|
899 |
|
|
end
|
900 |
|
|
|
901 |
|
|
assign csr_mcycle_hi_new = csr_mcycle_hi_ff + 1'b1;
|
902 |
|
|
|
903 |
|
|
assign csr_mcycle_lo_next = csr_mcycle_upd[0] ? csr_w_data[7:0]
|
904 |
|
|
: csr_mcycle_lo_inc ? csr_mcycle_lo_ff + 1'b1
|
905 |
|
|
: csr_mcycle_lo_ff;
|
906 |
|
|
assign csr_mcycle_hi_next = csr_mcycle_upd[0] ? {csr_mcycle_hi_new[63:32], csr_w_data[31:8]}
|
907 |
|
|
: csr_mcycle_upd[1] ? {csr_w_data, csr_mcycle_hi_new[31:8]}
|
908 |
|
|
: csr_mcycle_hi_inc ? csr_mcycle_hi_new
|
909 |
|
|
: csr_mcycle_hi_ff;
|
910 |
|
|
|
911 |
|
|
assign csr_mcycle = {csr_mcycle_hi_ff, csr_mcycle_lo_ff};
|
912 |
|
|
|
913 |
|
|
// MINSTRET register
|
914 |
|
|
//------------------------------------------------------------------------------
|
915 |
|
|
// Holds the number of instructions executed by the core from some arbitrary time
|
916 |
|
|
// in the past at which MINSTRET was equal to zero
|
917 |
|
|
|
918 |
|
|
assign csr_minstret_lo_inc = exu2csr_instret_no_exc_i
|
919 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
920 |
|
|
& csr_mcounten_ir_ff
|
921 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
922 |
|
|
;
|
923 |
|
|
assign csr_minstret_hi_inc = csr_minstret_lo_inc & (&csr_minstret_lo_ff);
|
924 |
|
|
|
925 |
|
|
assign csr_minstret_lo_upd = csr_minstret_lo_inc | csr_minstret_upd[0];
|
926 |
|
|
assign csr_minstret_hi_upd = csr_minstret_hi_inc | (|csr_minstret_upd);
|
927 |
|
|
|
928 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
929 |
|
|
if (~rst_n) begin
|
930 |
|
|
csr_minstret_lo_ff <= '0;
|
931 |
|
|
csr_minstret_hi_ff <= '0;
|
932 |
|
|
end else begin
|
933 |
|
|
if (csr_minstret_lo_upd) csr_minstret_lo_ff <= csr_minstret_lo_next;
|
934 |
|
|
if (csr_minstret_hi_upd) csr_minstret_hi_ff <= csr_minstret_hi_next;
|
935 |
|
|
end
|
936 |
|
|
end
|
937 |
|
|
|
938 |
|
|
assign csr_minstret_hi_new = csr_minstret_hi_ff + 1'b1;
|
939 |
|
|
|
940 |
|
|
assign csr_minstret_lo_next = csr_minstret_upd[0] ? csr_w_data[7:0]
|
941 |
|
|
: csr_minstret_lo_inc ? csr_minstret_lo_ff + 1'b1
|
942 |
|
|
: csr_minstret_lo_ff;
|
943 |
|
|
assign csr_minstret_hi_next = csr_minstret_upd[0] ? {csr_minstret_hi_new[63:32], csr_w_data[31:8]}
|
944 |
|
|
: csr_minstret_upd[1] ? {csr_w_data, csr_minstret_hi_new[31:8]}
|
945 |
|
|
: csr_minstret_hi_inc ? csr_minstret_hi_new
|
946 |
|
|
: csr_minstret_hi_ff;
|
947 |
|
|
|
948 |
|
|
assign csr_minstret = {csr_minstret_hi_ff, csr_minstret_lo_ff};
|
949 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
950 |
|
|
|
951 |
|
|
//------------------------------------------------------------------------------
|
952 |
|
|
// Non-standard CSR
|
953 |
|
|
//------------------------------------------------------------------------------
|
954 |
|
|
|
955 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
956 |
|
|
// MCOUNTEN register
|
957 |
|
|
//------------------------------------------------------------------------------
|
958 |
|
|
// Holds Counters enable bits (CY - MCYCLE counter; IR - MINSTRET counter)
|
959 |
|
|
|
960 |
|
|
always_ff @(negedge rst_n, posedge clk) begin
|
961 |
|
|
if (~rst_n) begin
|
962 |
|
|
csr_mcounten_cy_ff <= 1'b1;
|
963 |
|
|
csr_mcounten_ir_ff <= 1'b1;
|
964 |
|
|
end else if (csr_mcounten_upd) begin
|
965 |
|
|
csr_mcounten_cy_ff <= csr_w_data[SCR1_CSR_MCOUNTEN_CY_OFFSET];
|
966 |
|
|
csr_mcounten_ir_ff <= csr_w_data[SCR1_CSR_MCOUNTEN_IR_OFFSET];
|
967 |
|
|
end
|
968 |
|
|
end
|
969 |
|
|
|
970 |
|
|
always_comb begin
|
971 |
|
|
csr_mcounten = '0;
|
972 |
|
|
csr_mcounten[SCR1_CSR_MCOUNTEN_CY_OFFSET] = csr_mcounten_cy_ff;
|
973 |
|
|
csr_mcounten[SCR1_CSR_MCOUNTEN_IR_OFFSET] = csr_mcounten_ir_ff;
|
974 |
|
|
end
|
975 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
976 |
|
|
|
977 |
|
|
//------------------------------------------------------------------------------
|
978 |
|
|
// CSR <-> EXU interface
|
979 |
|
|
//------------------------------------------------------------------------------
|
980 |
|
|
|
981 |
|
|
// CSR exception
|
982 |
|
|
assign csr2exu_rw_exc_o = csr_r_exc | csr_w_exc
|
983 |
|
|
`ifdef SCR1_DBG_EN
|
984 |
|
|
| (csr2hdu_req_o & (hdu2csr_resp_i != SCR1_CSR_RESP_OK))
|
985 |
|
|
`endif // SCR1_DBG_EN
|
986 |
|
|
`ifdef SCR1_TDU_EN
|
987 |
|
|
| (csr2tdu_req_o & (tdu2csr_resp_i != SCR1_CSR_RESP_OK))
|
988 |
|
|
`endif // SCR1_TDU_EN
|
989 |
|
|
;
|
990 |
|
|
assign csr2exu_ip_ie_o = csr_eirq_pnd_en | csr_sirq_pnd_en | csr_tirq_pnd_en;
|
991 |
|
|
assign csr2exu_irq_o = csr2exu_ip_ie_o & csr_mstatus_mie_ff;
|
992 |
|
|
|
993 |
|
|
assign csr2exu_mstatus_mie_up_o = csr_mstatus_upd | csr_mie_upd | e_mret;
|
994 |
|
|
|
995 |
|
|
// New PC multiplexer
|
996 |
|
|
`ifndef SCR1_MTVEC_MODE_EN
|
997 |
|
|
assign csr2exu_new_pc_o = (exu2csr_mret_instr_i & ~exu2csr_take_irq_i)
|
998 |
|
|
? csr_mepc
|
999 |
|
|
: {csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)};
|
1000 |
|
|
`else // SCR1_MTVEC_MODE_EN
|
1001 |
|
|
always_comb begin
|
1002 |
|
|
if (exu2csr_mret_instr_i & ~exu2csr_take_irq_i) begin
|
1003 |
|
|
csr2exu_new_pc_o = csr_mepc;
|
1004 |
|
|
end else begin
|
1005 |
|
|
if (csr_mtvec_mode_vect) begin
|
1006 |
|
|
case (1'b1)
|
1007 |
|
|
exu2csr_take_exc_i: csr2exu_new_pc_o = {csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)};
|
1008 |
|
|
csr_eirq_pnd_en : csr2exu_new_pc_o = {csr_mtvec_base, SCR1_EXC_CODE_IRQ_M_EXTERNAL, 2'd0};
|
1009 |
|
|
csr_sirq_pnd_en : csr2exu_new_pc_o = {csr_mtvec_base, SCR1_EXC_CODE_IRQ_M_SOFTWARE, 2'd0};
|
1010 |
|
|
csr_tirq_pnd_en : csr2exu_new_pc_o = {csr_mtvec_base, SCR1_EXC_CODE_IRQ_M_TIMER, 2'd0};
|
1011 |
|
|
default : csr2exu_new_pc_o = {csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)};
|
1012 |
|
|
endcase
|
1013 |
|
|
end else begin // direct mode
|
1014 |
|
|
csr2exu_new_pc_o = {csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)};
|
1015 |
|
|
end
|
1016 |
|
|
end
|
1017 |
|
|
end
|
1018 |
|
|
`endif // SCR1_MTVEC_MODE_EN
|
1019 |
|
|
|
1020 |
|
|
`ifdef SCR1_IPIC_EN
|
1021 |
|
|
//------------------------------------------------------------------------------
|
1022 |
|
|
// CSR <-> IPIC interface
|
1023 |
|
|
//------------------------------------------------------------------------------
|
1024 |
|
|
|
1025 |
|
|
assign csr_ipic_req = csr2ipic_r_req_o | csr2ipic_w_req_o;
|
1026 |
|
|
assign csr2ipic_addr_o = csr_ipic_req ? exu2csr_rw_addr_i[2:0] : '0;
|
1027 |
|
|
assign csr2ipic_wdata_o = csr2ipic_w_req_o ? exu2csr_w_data_i : '0;
|
1028 |
|
|
`endif // SCR1_IPIC_EN
|
1029 |
|
|
|
1030 |
|
|
`ifdef SCR1_DBG_EN
|
1031 |
|
|
//------------------------------------------------------------------------------
|
1032 |
|
|
// CSR <-> HDU interface
|
1033 |
|
|
//------------------------------------------------------------------------------
|
1034 |
|
|
|
1035 |
|
|
assign csr2hdu_req_o = csr_hdu_req & exu_req_no_exc;
|
1036 |
|
|
assign csr2hdu_cmd_o = exu2csr_w_cmd_i;
|
1037 |
|
|
assign csr2hdu_addr_o = exu2csr_rw_addr_i[SCR1_HDU_DEBUGCSR_ADDR_WIDTH-1:0];
|
1038 |
|
|
assign csr2hdu_wdata_o = exu2csr_w_data_i;
|
1039 |
|
|
`endif // SCR1_DBG_EN
|
1040 |
|
|
|
1041 |
|
|
`ifdef SCR1_TDU_EN
|
1042 |
|
|
//------------------------------------------------------------------------------
|
1043 |
|
|
// CSR <-> TDU interface
|
1044 |
|
|
//------------------------------------------------------------------------------
|
1045 |
|
|
|
1046 |
|
|
assign csr2tdu_req_o = csr_brkm_req & exu_req_no_exc;
|
1047 |
|
|
assign csr2tdu_cmd_o = exu2csr_w_cmd_i;
|
1048 |
|
|
assign csr2tdu_addr_o = exu2csr_rw_addr_i[SCR1_CSR_ADDR_TDU_OFFS_W-1:0];
|
1049 |
|
|
assign csr2tdu_wdata_o = exu2csr_w_data_i;
|
1050 |
|
|
`endif // SCR1_TDU_EN
|
1051 |
|
|
|
1052 |
|
|
`ifdef SCR1_TRGT_SIMULATION
|
1053 |
|
|
//------------------------------------------------------------------------------
|
1054 |
|
|
// Assertions
|
1055 |
|
|
//------------------------------------------------------------------------------
|
1056 |
|
|
|
1057 |
|
|
// X checks
|
1058 |
|
|
|
1059 |
|
|
SCR1_SVA_CSR_XCHECK_CTRL : assert property (
|
1060 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1061 |
|
|
!$isunknown({exu2csr_r_req_i, exu2csr_w_req_i, exu2csr_take_irq_i, exu2csr_take_exc_i, exu2csr_mret_update_i
|
1062 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
1063 |
|
|
, exu2csr_instret_no_exc_i
|
1064 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
1065 |
|
|
})
|
1066 |
|
|
) else $error("CSR Error: unknown control values");
|
1067 |
|
|
|
1068 |
|
|
SCR1_SVA_CSR_XCHECK_READ : assert property (
|
1069 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1070 |
|
|
exu2csr_r_req_i |-> !$isunknown({exu2csr_rw_addr_i, csr2exu_r_data_o, csr2exu_rw_exc_o})
|
1071 |
|
|
) else $error("CSR Error: unknown control values");
|
1072 |
|
|
|
1073 |
|
|
SCR1_SVA_CSR_XCHECK_WRITE : assert property (
|
1074 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1075 |
|
|
exu2csr_w_req_i |-> !$isunknown({exu2csr_rw_addr_i, exu2csr_w_cmd_i, exu2csr_w_data_i, csr2exu_rw_exc_o})
|
1076 |
|
|
) else $error("CSR Error: unknown control values");
|
1077 |
|
|
|
1078 |
|
|
`ifdef SCR1_IPIC_EN
|
1079 |
|
|
SCR1_SVA_CSR_XCHECK_READ_IPIC : assert property (
|
1080 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1081 |
|
|
csr2ipic_r_req_o |-> !$isunknown({csr2ipic_addr_o, ipic2csr_rdata_i})
|
1082 |
|
|
) else $error("CSR Error: unknown control values");
|
1083 |
|
|
|
1084 |
|
|
SCR1_SVA_CSR_XCHECK_WRITE_IPIC : assert property (
|
1085 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1086 |
|
|
csr2ipic_w_req_o |-> !$isunknown({csr2ipic_addr_o, csr2ipic_wdata_o})
|
1087 |
|
|
) else $error("CSR Error: unknown control values");
|
1088 |
|
|
`endif // SCR1_IPIC_EN
|
1089 |
|
|
|
1090 |
|
|
// Behavior checks
|
1091 |
|
|
|
1092 |
|
|
`ifndef VERILATOR
|
1093 |
|
|
SCR1_SVA_CSR_MRET : assert property (
|
1094 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1095 |
|
|
e_mret |=> ($stable(csr_mepc_ff) & $stable(csr_mtval_ff))
|
1096 |
|
|
) else $error("CSR Error: MRET wrong behavior");
|
1097 |
|
|
|
1098 |
|
|
SCR1_SVA_CSR_MRET_IRQ : assert property (
|
1099 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1100 |
|
|
(exu2csr_mret_instr_i & e_irq)
|
1101 |
|
|
|=> ($stable(csr_mepc_ff) & (exu2csr_pc_curr_i != csr_mepc))
|
1102 |
|
|
) else $error("CSR Error: MRET+IRQ wrong behavior");
|
1103 |
|
|
|
1104 |
|
|
SCR1_SVA_CSR_EXC_IRQ : assert property (
|
1105 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1106 |
|
|
(exu2csr_take_exc_i & exu2csr_take_irq_i
|
1107 |
|
|
`ifdef SCR1_DBG_EN
|
1108 |
|
|
& ~hdu2csr_no_commit_i
|
1109 |
|
|
`endif
|
1110 |
|
|
) |=>
|
1111 |
|
|
(~csr_mstatus_mie_ff & (~csr_mcause_i_ff)
|
1112 |
|
|
& (exu2csr_pc_curr_i=={csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)}))
|
1113 |
|
|
) else $error("CSR Error: wrong EXC+IRQ");
|
1114 |
|
|
`endif // VERILATOR
|
1115 |
|
|
SCR1_SVA_CSR_EVENTS : assert property (
|
1116 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1117 |
|
|
$onehot0({e_irq, e_exc, e_mret})
|
1118 |
|
|
) else $error("CSR Error: more than one event at a time");
|
1119 |
|
|
|
1120 |
|
|
SCR1_SVA_CSR_RW_EXC : assert property (
|
1121 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1122 |
|
|
csr2exu_rw_exc_o |-> (exu2csr_w_req_i | exu2csr_r_req_i)
|
1123 |
|
|
) else $error("CSR Error: impossible exception");
|
1124 |
|
|
|
1125 |
|
|
`ifndef VERILATOR
|
1126 |
|
|
SCR1_SVA_CSR_MSTATUS_MIE_UP : assert property (
|
1127 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1128 |
|
|
csr2exu_mstatus_mie_up_o |=> ~csr2exu_mstatus_mie_up_o
|
1129 |
|
|
) else $error("CSR Error: csr2exu_mstatus_mie_up_o can only be high for one mcycle");
|
1130 |
|
|
`endif // VERILATOR
|
1131 |
|
|
|
1132 |
|
|
`ifndef SCR1_CSR_REDUCED_CNT
|
1133 |
|
|
|
1134 |
|
|
`ifndef VERILATOR
|
1135 |
|
|
SCR1_SVA_CSR_CYCLE_INC : assert property (
|
1136 |
|
|
@(
|
1137 |
|
|
`ifndef SCR1_CLKCTRL_EN
|
1138 |
|
|
negedge clk
|
1139 |
|
|
`else // SCR1_CLKCTRL_EN
|
1140 |
|
|
negedge clk_alw_on
|
1141 |
|
|
`endif // SCR1_CLKCTRL_EN
|
1142 |
|
|
) disable iff (~rst_n)
|
1143 |
|
|
(~|csr_mcycle_upd) |=>
|
1144 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
1145 |
|
|
($past(csr_mcounten_cy_ff) ? (csr_mcycle == $past(csr_mcycle + 1'b1)) : $stable(csr_mcycle))
|
1146 |
|
|
`else //SCR1_MCOUNTEN_EN
|
1147 |
|
|
(csr_mcycle == $past(csr_mcycle + 1'b1))
|
1148 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
1149 |
|
|
) else $error("CSR Error: CYCLE increment wrong behavior");
|
1150 |
|
|
|
1151 |
|
|
SCR1_SVA_CSR_INSTRET_INC : assert property (
|
1152 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1153 |
|
|
(exu2csr_instret_no_exc_i & ~|csr_minstret_upd) |=>
|
1154 |
|
|
`ifdef SCR1_MCOUNTEN_EN
|
1155 |
|
|
($past(csr_mcounten_ir_ff) ? (csr_minstret == $past(csr_minstret + 1'b1)) : $stable(csr_minstret))
|
1156 |
|
|
`else //SCR1_MCOUNTEN_EN
|
1157 |
|
|
(csr_minstret == $past(csr_minstret + 1'b1))
|
1158 |
|
|
`endif // SCR1_MCOUNTEN_EN
|
1159 |
|
|
) else $error("CSR Error: INSTRET increment wrong behavior");
|
1160 |
|
|
`endif
|
1161 |
|
|
SCR1_SVA_CSR_CYCLE_INSTRET_UP : assert property (
|
1162 |
|
|
@(negedge clk) disable iff (~rst_n)
|
1163 |
|
|
~(&csr_minstret_upd | &csr_mcycle_upd)
|
1164 |
|
|
) else $error("CSR Error: INSTRET/CYCLE up illegal value");
|
1165 |
|
|
|
1166 |
|
|
`endif // SCR1_CSR_REDUCED_CNT
|
1167 |
|
|
|
1168 |
|
|
`endif // SCR1_TRGT_SIMULATION
|
1169 |
|
|
|
1170 |
|
|
endmodule : scr1_pipe_csr
|