OpenCores
URL https://opencores.org/ocsvn/yifive/yifive/trunk

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [syntacore/] [scr1/] [src/] [core/] [pipeline/] [scr1_pipe_csr.sv] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.