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_exu.sv] - Blame information for rev 21

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      Execution Unit (EXU)
4
///
5
 
6
//------------------------------------------------------------------------------
7
 //
8
 // Functionality:
9
 // - Performs instructions execution:
10
 //   - Prevents instructions from execution if the HART is in WFI or Debug Halted
11
 //     state
12
 //   - Fetches operands for IALU
13
 //   - Calculates operation results via IALU
14
 //   - Stores IALU results in MPRF
15
 //   - Performs LOAD/STORE operations via LSU
16
 // - Handles exceptions:
17
 //   - Generates exception request
18
 //   - Encodes exception code
19
 //   - Calculates exception trap value
20
 // - Controls WFI instruction execution
21
 // - Calculates PC value:
22
 //   - Initializes PC on reset
23
 //   - Stores the current PC value
24
 //   - Calculates a New PC value and generates a New PC request to IFU
25
 //
26
 // Structure:
27
 // - Instruction queue
28
 // - Integer Arithmetic Logic Unit (IALU)
29
 // - Exceptions logic
30
 // - WFI logic
31
 // - Program Counter logic
32
 // - Load-Store Unit (LSU)
33
 // - EXU status logic
34
 // - EXU <-> MPRF i/f
35
 // - EXU <-> CSR i/f
36
 // - EXU <-> TDU i/f
37
 //
38
//------------------------------------------------------------------------------
39
 
40
`include "scr1_arch_description.svh"
41
`include "scr1_arch_types.svh"
42
`include "scr1_memif.svh"
43
`include "scr1_riscv_isa_decoding.svh"
44
`include "scr1_csr.svh"
45
 
46
`ifdef SCR1_DBG_EN
47
 `include "scr1_hdu.svh"
48
`endif // SCR1_DBG_EN
49
 
50
`ifdef SCR1_TDU_EN
51
 `include "scr1_tdu.svh"
52
`endif // SCR1_TDU_EN
53
 
54
module scr1_pipe_exu (
55
    // Common
56
    input   logic                               rst_n,                      // EXU reset
57
    input   logic                               clk,                        // Gated EXU clock
58
`ifdef SCR1_CLKCTRL_EN
59
    input   logic                               clk_alw_on,                 // Not-gated EXU clock
60
    input   logic                               clk_pipe_en,                // EXU clock enabled flag
61
`endif // SCR1_CLKCTRL_EN
62
 
63
    // EXU <-> IDU interface
64
    input   logic                               idu2exu_req_i,              // Request form IDU to EXU
65
    output  logic                               exu2idu_rdy_o,              // EXU ready for new data from IDU
66
    input   type_scr1_exu_cmd_s                 idu2exu_cmd_i,              // EXU command
67
    input   logic                               idu2exu_use_rs1_i,          // Clock gating on rs1_addr field
68
    input   logic                               idu2exu_use_rs2_i,          // Clock gating on rs2_addr field
69
`ifndef SCR1_NO_EXE_STAGE
70
    input   logic                               idu2exu_use_rd_i,           // Clock gating on rd_addr field
71
    input   logic                               idu2exu_use_imm_i,          // Clock gating on imm field
72
`endif // SCR1_NO_EXE_STAGE
73
 
74
    // EXU <-> MPRF interface
75
    output  logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rs1_addr_o,        // MPRF rs1 read address
76
    input   logic [`SCR1_XLEN-1:0]              mprf2exu_rs1_data_i,        // MPRF rs1 read data
77
    output  logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rs2_addr_o,        // MPRF rs2 read address
78
    input   logic [`SCR1_XLEN-1:0]              mprf2exu_rs2_data_i,        // MPRF rs2 read data
79
    output  logic                               exu2mprf_w_req_o,           // MPRF write request
80
    output  logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rd_addr_o,         // MPRF rd write address
81
    output  logic [`SCR1_XLEN-1:0]              exu2mprf_rd_data_o,         // MPRF rd write data
82
 
83
    // EXU <-> CSR read/write interface
84
    output  logic [SCR1_CSR_ADDR_WIDTH-1:0]     exu2csr_rw_addr_o,          // CSR read/write address
85
    output  logic                               exu2csr_r_req_o,            // CSR read request
86
    input   logic [`SCR1_XLEN-1:0]              csr2exu_r_data_i,           // CSR read data
87
    output  logic                               exu2csr_w_req_o,            // CSR write request
88
    output  type_scr1_csr_cmd_sel_e             exu2csr_w_cmd_o,            // CSR write command
89
    output  logic [`SCR1_XLEN-1:0]              exu2csr_w_data_o,           // CSR write data
90
    input   logic                               csr2exu_rw_exc_i,           // CSR read/write access exception
91
 
92
    // EXU <-> CSR events interface
93
    output  logic                               exu2csr_take_irq_o,         // Take IRQ trap
94
    output  logic                               exu2csr_take_exc_o,         // Take exception trap
95
    output  logic                               exu2csr_mret_update_o,      // MRET update CSR
96
    output  logic                               exu2csr_mret_instr_o,       // MRET instruction
97
    output  logic [SCR1_EXC_CODE_WIDTH_E-1:0]   exu2csr_exc_code_o,         // Exception code (see scr1_arch_types.svh) - cp.7
98
    output  logic [`SCR1_XLEN-1:0]              exu2csr_trap_val_o,         // Trap value
99
    input   logic [`SCR1_XLEN-1:0]              csr2exu_new_pc_i,           // Exception/IRQ/MRET new PC
100
    input   logic                               csr2exu_irq_i,              // IRQ request
101
    input   logic                               csr2exu_ip_ie_i,            // Some IRQ pending and locally enabled
102
    input   logic                               csr2exu_mstatus_mie_up_i,   // MSTATUS or MIE update in the current cycle
103
 
104
    // EXU <-> DMEM interface
105
    output  logic                               exu2dmem_req_o,             // Data memory request
106
    output  logic                               exu2dmem_cmd_o,             // Data memory command - cp.7
107 21 dinesha
    output  logic [1:0]                         exu2dmem_width_o,           // Data memory width
108 11 dinesha
    output  logic [`SCR1_DMEM_AWIDTH-1:0]       exu2dmem_addr_o,            // Data memory address
109
    output  logic [`SCR1_DMEM_DWIDTH-1:0]       exu2dmem_wdata_o,           // Data memory write data
110
    input   logic                               dmem2exu_req_ack_i,         // Data memory request acknowledge
111
    input   logic [`SCR1_DMEM_DWIDTH-1:0]       dmem2exu_rdata_i,           // Data memory read data
112
    input   logic [1:0]                         dmem2exu_resp_i,            // Data memory response - cp.7
113
 
114
    // EXU control
115
    output  logic                               exu2pipe_exc_req_o,         // Exception on last instruction
116
    output  logic                               exu2pipe_brkpt_o,           // Software Breakpoint (EBREAK)
117
    output  logic                               exu2pipe_init_pc_o,         // Reset exit
118
    output  logic                               exu2pipe_wfi_run2halt_o,    // Transition to WFI halted state
119
    output  logic                               exu2pipe_instret_o,         // Instruction retired (with or without exception)
120
    output  logic                               exu2csr_instret_no_exc_o,   // Instruction retired (without exception)
121
    output  logic                               exu2pipe_exu_busy_o,        // EXU busy
122
 
123
`ifdef SCR1_DBG_EN
124
    // EXU <-> HDU interface
125
    input   logic                               hdu2exu_no_commit_i,        // Forbid instruction commitment
126
    input   logic                               hdu2exu_irq_dsbl_i,         // Disable IRQ
127
    input   logic                               hdu2exu_pc_advmt_dsbl_i,    // Forbid PC advancement
128
    input   logic                               hdu2exu_dmode_sstep_en_i,   // Enable single-step
129
    input   logic                               hdu2exu_pbuf_fetch_i,       // Take instructions from Program Buffer
130
    input   logic                               hdu2exu_dbg_halted_i,       // Debug halted state
131
    input   logic                               hdu2exu_dbg_run2halt_i,     // Transition to debug halted state
132
    input   logic                               hdu2exu_dbg_halt2run_i,     // Transition to run state
133
    input   logic                               hdu2exu_dbg_run_start_i,    // First cycle of run state
134
    input   logic [`SCR1_XLEN-1:0]              hdu2exu_dbg_new_pc_i,       // New PC as starting point for HART Resume
135
`endif // SCR1_DBG_EN
136
 
137
`ifdef SCR1_TDU_EN
138
    // EXU <-> TDU interface
139
    output type_scr1_brkm_instr_mon_s           exu2tdu_imon_o,             // Instruction monitor
140
    input  logic [SCR1_TDU_ALLTRIG_NUM-1:0]     tdu2exu_ibrkpt_match_i,     // Instruction breakpoint(s) match
141
    input  logic                                tdu2exu_ibrkpt_exc_req_i,   // Instruction breakpoint exception
142
    output type_scr1_brkm_lsu_mon_s             lsu2tdu_dmon_o,             // Data monitor
143
    input  logic                                tdu2lsu_ibrkpt_exc_req_i,   // Instruction breakpoint exception
144
    input  logic [SCR1_TDU_MTRIG_NUM-1:0]       tdu2lsu_dbrkpt_match_i,     // Data breakpoint(s) match
145
    input  logic                                tdu2lsu_dbrkpt_exc_req_i,   // Data breakpoint exception
146
    output logic [SCR1_TDU_ALLTRIG_NUM-1:0]     exu2tdu_ibrkpt_ret_o,       // Instruction with breakpoint flag retire
147
    output logic                                exu2hdu_ibrkpt_hw_o,        // Hardware breakpoint on current instruction
148
`endif // SCR1_TDU_EN
149
 
150
    // PC interface
151
`ifdef SCR1_CLKCTRL_EN
152
    output  logic                               exu2pipe_wfi_halted_o,      // WFI halted state
153
`endif // SCR1_CLKCTRL_EN
154
    output  logic [`SCR1_XLEN-1:0]              exu2pipe_pc_curr_o,         // Current PC
155
    output  logic [`SCR1_XLEN-1:0]              exu2csr_pc_next_o,          // Next PC
156
    output  logic                               exu2ifu_pc_new_req_o,       // New PC request
157
    output  logic [`SCR1_XLEN-1:0]              exu2ifu_pc_new_o            // New PC data
158
);
159
 
160
//------------------------------------------------------------------------------
161
// Local parameters declaration
162
//------------------------------------------------------------------------------
163
 
164
localparam SCR1_JUMP_MASK = `SCR1_XLEN'hFFFF_FFFE;
165
 
166
//------------------------------------------------------------------------------
167
// Local types declaration
168
//------------------------------------------------------------------------------
169
 
170 21 dinesha
//typedef enum logic {
171
parameter     SCR1_CSR_INIT = 1'b0;
172
parameter     SCR1_CSR_RDY  = 1'b1;
173
//} scr1_csr_access_e;
174 11 dinesha
 
175
//------------------------------------------------------------------------------
176
// Local signals declaration
177
//------------------------------------------------------------------------------
178
 
179
// Instruction queue signals
180
//------------------------------------------------------------------------------
181
logic                               exu_queue_vd;
182
type_scr1_exu_cmd_s                 exu_queue;
183
logic                               exu_queue_barrier;
184
 
185
`ifdef SCR1_DBG_EN
186
logic                               dbg_run_start_npbuf;
187
`endif // SCR1_DBG_EN
188
logic                               exu_queue_en;
189
logic [`SCR1_XLEN-1:0]              exu_illegal_instr;
190
 
191
`ifndef SCR1_NO_EXE_STAGE
192
logic                               idu2exu_use_rs1_ff;
193
logic                               idu2exu_use_rs2_ff;
194
 
195
// EXU queue valid flag register signals
196
logic                               exu_queue_vd_upd;
197
logic                               exu_queue_vd_ff;
198
logic                               exu_queue_vd_next;
199
`endif // SCR1_NO_EXE_STAGE
200
 
201
// IALU signals
202
//------------------------------------------------------------------------------
203
`ifdef SCR1_RVM_EXT
204
logic                               ialu_rdy;
205
logic                               ialu_vd;
206
`endif // SCR1_RVM_EXT
207
logic [`SCR1_XLEN-1:0]              ialu_main_op1;
208
logic [`SCR1_XLEN-1:0]              ialu_main_op2;
209
logic [`SCR1_XLEN-1:0]              ialu_main_res;
210
logic [`SCR1_XLEN-1:0]              ialu_addr_op1;
211
logic [`SCR1_XLEN-1:0]              ialu_addr_op2;
212
logic [`SCR1_XLEN-1:0]              ialu_addr_res;
213
logic                               ialu_cmp;
214
 
215
// Exceptions signals
216
//------------------------------------------------------------------------------
217
logic                               exu_exc_req;
218
`ifdef SCR1_DBG_EN
219
logic                               exu_exc_req_ff;
220
logic                               exu_exc_req_next;
221
`endif // SCR1_DBG_EN
222
logic [SCR1_EXC_CODE_WIDTH_E-1:0]   exc_code; // cp.7
223
logic [`SCR1_XLEN-1:0]              exc_trap_val;
224
logic                               instr_fault_rvi_hi;
225
 
226
// WFI signals
227
//------------------------------------------------------------------------------
228
// WFI control signals
229
logic                               wfi_halt_cond;
230
logic                               wfi_run_req;
231
logic                               wfi_halt_req;
232
 
233
// WFI Run Start register
234
logic                               wfi_run_start_ff;
235
logic                               wfi_run_start_next;
236
 
237
// WFI halted register
238
logic                               wfi_halted_upd;
239
logic                               wfi_halted_ff;
240
logic                               wfi_halted_next;
241
 
242
// PC signals
243
//------------------------------------------------------------------------------
244
logic [3:0]                         init_pc_v;
245
logic                               init_pc;
246
logic [`SCR1_XLEN-1:0]              inc_pc;
247
 
248
logic                               branch_taken;
249
logic                               jb_taken;
250
logic [`SCR1_XLEN-1:0]              jb_new_pc;
251
`ifndef SCR1_RVC_EXT
252
logic                               jb_misalign;
253
`endif
254
 
255
// Current PC register
256
logic                               pc_curr_upd;
257
logic [`SCR1_XLEN-1:0]              pc_curr_ff;
258
logic [`SCR1_XLEN-1:0]              pc_curr_next;
259
 
260
// LSU signals
261
//------------------------------------------------------------------------------
262
logic                               lsu_req;
263
logic                               lsu_rdy;
264
logic [`SCR1_XLEN-1:0]              lsu_l_data;
265
logic                               lsu_exc_req;
266
logic [SCR1_EXC_CODE_WIDTH_E-1:0]   lsu_exc_code; // cp.7
267
 
268
// EXU status signals
269
//------------------------------------------------------------------------------
270
logic                               exu_rdy;
271
 
272
// MPRF signals
273
//------------------------------------------------------------------------------
274
logic                               mprf_rs1_req;
275
logic                               mprf_rs2_req;
276
 
277
logic   [`SCR1_MPRF_AWIDTH-1:0]     mprf_rs1_addr;
278
logic   [`SCR1_MPRF_AWIDTH-1:0]     mprf_rs2_addr;
279
 
280
// CSR signals
281
//------------------------------------------------------------------------------
282
// CSR access register
283 21 dinesha
logic                               csr_access_ff;
284
logic                               csr_access_next;
285 11 dinesha
logic                               csr_access_init;
286
 
287
//------------------------------------------------------------------------------
288
// Instruction execution queue
289
//------------------------------------------------------------------------------
290
//
291
 // Instruction execution queue consists of the following functional units:
292
 // - EXU queue control logic
293
 // - EXU queue valid flag register
294
 // - EXU queue register
295
 // - EXU queue status logic
296
//
297
 
298
`ifdef SCR1_DBG_EN
299
assign dbg_run_start_npbuf = hdu2exu_dbg_run_start_i & ~hdu2exu_pbuf_fetch_i;
300
`endif // SCR1_DBG_EN
301
 
302
`ifndef SCR1_NO_EXE_STAGE
303
 
304
// EXU queue control logic
305
//------------------------------------------------------------------------------
306
 
307
assign exu_queue_barrier = wfi_halted_ff | wfi_halt_req | wfi_run_start_ff
308
`ifdef SCR1_DBG_EN
309
                         | hdu2exu_dbg_halted_i  | hdu2exu_dbg_run2halt_i
310
                         | dbg_run_start_npbuf
311
`endif // SCR1_DBG_EN
312
;
313
 
314
assign exu_queue_en = exu2idu_rdy_o & idu2exu_req_i;
315
 
316
// EXU queue valid flag register
317
//------------------------------------------------------------------------------
318
 
319
assign exu_queue_vd_upd = exu_queue_barrier | exu_rdy;
320
 
321
always_ff @(posedge clk, negedge rst_n) begin
322
    if (~rst_n) begin
323
        exu_queue_vd_ff <= 1'b0;
324
    end else if (exu_queue_vd_upd) begin
325
        exu_queue_vd_ff <= exu_queue_vd_next;
326
    end
327
end
328
 
329
assign exu_queue_vd_next = ~exu_queue_barrier & idu2exu_req_i & ~exu2ifu_pc_new_req_o;
330
assign exu_queue_vd      = exu_queue_vd_ff;
331
 
332
// EXU queue register
333
//------------------------------------------------------------------------------
334
 
335
always_ff @(posedge clk) begin
336
    if (exu_queue_en) begin
337
        exu_queue.instr_rvc      <= idu2exu_cmd_i.instr_rvc;
338
        exu_queue.ialu_op        <= idu2exu_cmd_i.ialu_op;
339
        exu_queue.ialu_cmd       <= idu2exu_cmd_i.ialu_cmd;
340
        exu_queue.sum2_op        <= idu2exu_cmd_i.sum2_op;
341
        exu_queue.lsu_cmd        <= idu2exu_cmd_i.lsu_cmd;
342
        exu_queue.csr_op         <= idu2exu_cmd_i.csr_op;
343
        exu_queue.csr_cmd        <= idu2exu_cmd_i.csr_cmd;
344
        exu_queue.rd_wb_sel      <= idu2exu_cmd_i.rd_wb_sel;
345
        exu_queue.jump_req       <= idu2exu_cmd_i.jump_req;
346
        exu_queue.branch_req     <= idu2exu_cmd_i.branch_req;
347
        exu_queue.mret_req       <= idu2exu_cmd_i.mret_req;
348
        exu_queue.fencei_req     <= idu2exu_cmd_i.fencei_req;
349
        exu_queue.wfi_req        <= idu2exu_cmd_i.wfi_req;
350
        exu_queue.exc_req        <= idu2exu_cmd_i.exc_req;
351
        exu_queue.exc_code       <= idu2exu_cmd_i.exc_code;
352
        idu2exu_use_rs1_ff       <= idu2exu_use_rs1_i;
353
        idu2exu_use_rs2_ff       <= idu2exu_use_rs2_i;
354
        if (idu2exu_use_rs1_i) begin
355
            exu_queue.rs1_addr   <= idu2exu_cmd_i.rs1_addr;
356
        end
357
        if (idu2exu_use_rs2_i) begin
358
            exu_queue.rs2_addr   <= idu2exu_cmd_i.rs2_addr;
359
        end
360
        if (idu2exu_use_rd_i)  begin
361
            exu_queue.rd_addr    <= idu2exu_cmd_i.rd_addr;
362
        end
363
        if (idu2exu_use_imm_i) begin
364
            exu_queue.imm        <= idu2exu_cmd_i.imm;
365
        end
366
    end
367
end
368
 
369
`else // ~SCR1_NO_EXE_STAGE
370
 
371
assign exu_queue_barrier = wfi_halted_ff | wfi_run_start_ff
372
`ifdef SCR1_DBG_EN
373
                         | hdu2exu_dbg_halted_i  | dbg_run_start_npbuf
374
`endif // SCR1_DBG_EN
375
;
376
assign exu_queue_vd  = idu2exu_req_i & ~exu_queue_barrier;
377
assign exu_queue     = idu2exu_cmd_i;
378
 
379
`endif // ~SCR1_NO_EXE_STAGE
380
 
381
//------------------------------------------------------------------------------
382
// Integer Arithmetic Logic Unit (IALU)
383
//------------------------------------------------------------------------------
384
 //
385
 // Functionality:
386
 // - Performs addition/subtraction and arithmetic and branch comparisons
387
 // - Performs logical operations (AND(I), OR(I), XOR(I))
388
 // - Performs address calculation for branch, jump, DMEM load and store and AUIPC
389
 //   instructions
390
 // - Performs shift operations
391
 // - Performs MUL/DIV operations
392
 //
393
//------------------------------------------------------------------------------
394
 
395
// IALU main operands fetch
396
//------------------------------------------------------------------------------
397
 
398
`ifdef SCR1_RVM_EXT
399
assign ialu_vd  = exu_queue_vd & (exu_queue.ialu_cmd != SCR1_IALU_CMD_NONE)
400
`ifdef SCR1_TDU_EN
401
                & ~tdu2exu_ibrkpt_exc_req_i
402
`endif // SCR1_TDU_EN
403
                ;
404
`endif // SCR1_RVM_EXT
405
 
406
always_comb begin
407
`ifdef SCR1_RVM_EXT
408
    if (~ialu_vd) begin
409
        ialu_main_op1 = '0;
410
        ialu_main_op2 = '0;
411
    end else begin
412
`endif // SCR1_RVM_EXT
413
        if (exu_queue.ialu_op == SCR1_IALU_OP_REG_REG) begin
414
            ialu_main_op1 = mprf2exu_rs1_data_i;
415
            ialu_main_op2 = mprf2exu_rs2_data_i;
416
        end else begin
417
            ialu_main_op1 = mprf2exu_rs1_data_i;
418
            ialu_main_op2 = exu_queue.imm;
419
        end
420
`ifdef SCR1_RVM_EXT
421
    end
422
`endif // SCR1_RVM_EXT
423
end
424
 
425
// IALU address operands fetch
426
//------------------------------------------------------------------------------
427
 
428
always_comb begin
429
    if (exu_queue.sum2_op == SCR1_SUM2_OP_REG_IMM) begin
430
        ialu_addr_op1 = mprf2exu_rs1_data_i;
431
        ialu_addr_op2 = exu_queue.imm;
432
    end else begin
433
        ialu_addr_op1 = pc_curr_ff;
434
        ialu_addr_op2 = exu_queue.imm;
435
    end
436
end
437
 
438
// IALU module instantiation
439
//------------------------------------------------------------------------------
440
 
441
scr1_pipe_ialu i_ialu(
442
`ifdef SCR1_RVM_EXT
443
    // Common
444
    .clk                        (clk               ),
445
    .rst_n                      (rst_n             ),
446
    .exu2ialu_rvm_cmd_vd_i      (ialu_vd           ),
447
    .ialu2exu_rvm_res_rdy_o     (ialu_rdy          ),
448
`endif // SCR1_RVM_EXT
449
 
450
    // IALU
451
    .exu2ialu_main_op1_i        (ialu_main_op1     ),
452
    .exu2ialu_main_op2_i        (ialu_main_op2     ),
453
    .exu2ialu_cmd_i             (exu_queue.ialu_cmd),
454
    .ialu2exu_main_res_o        (ialu_main_res     ),
455
    .ialu2exu_cmp_res_o         (ialu_cmp          ),
456
 
457
    // Address adder signals
458
    .exu2ialu_addr_op1_i        (ialu_addr_op1     ),
459
    .exu2ialu_addr_op2_i        (ialu_addr_op2     ),
460
    .ialu2exu_addr_res_o        (ialu_addr_res     )
461
);
462
 
463
//------------------------------------------------------------------------------
464
// Exceptions logic
465
//------------------------------------------------------------------------------
466
//
467
 // Exceptions logic consists of the following functional units:
468
 // - Exception request logic
469
 // - Exception code encoder
470
 // - Exception trap value multiplexer
471
 //
472
//
473
 
474
`ifndef SCR1_RVC_EXT
475
assign jb_misalign  = exu_queue_vd  & jb_taken & |jb_new_pc[1:0];
476
`endif // ~SCR1_RVC_EXT
477
 
478
// Exception request
479
assign exu_exc_req  = exu_queue_vd & (exu_queue.exc_req | lsu_exc_req
480
                                                        | csr2exu_rw_exc_i
481
`ifndef SCR1_RVC_EXT
482
                                                        | jb_misalign
483
`endif // ~SCR1_RVC_EXT
484
`ifdef SCR1_TDU_EN
485
                                                        | exu2hdu_ibrkpt_hw_o
486
`endif // SCR1_TDU_EN
487
                                                        );
488
 
489
// EXU exception request register
490
//------------------------------------------------------------------------------
491
 
492
`ifdef SCR1_DBG_EN
493
 
494
always_ff @(posedge clk, negedge rst_n) begin
495
    if (~rst_n) begin
496
        exu_exc_req_ff <= 1'b0;
497
    end else begin
498
        exu_exc_req_ff <= exu_exc_req_next;
499
    end
500
end
501
 
502
assign exu_exc_req_next = hdu2exu_dbg_halt2run_i ? 1'b0 : exu_exc_req;
503
`endif // SCR1_DBG_EN
504
 
505
// Exception code encoder
506
//------------------------------------------------------------------------------
507
 
508
always_comb begin
509
    case (1'b1)
510
`ifdef SCR1_TDU_EN
511
        exu2hdu_ibrkpt_hw_o: exc_code = SCR1_EXC_CODE_BREAKPOINT;
512
`endif // SCR1_TDU_EN
513
        exu_queue.exc_req  : exc_code = exu_queue.exc_code;
514
        lsu_exc_req        : exc_code = lsu_exc_code;
515
        csr2exu_rw_exc_i   : exc_code = SCR1_EXC_CODE_ILLEGAL_INSTR;
516
`ifndef SCR1_RVC_EXT
517
        jb_misalign        : exc_code = SCR1_EXC_CODE_INSTR_MISALIGN;
518
`endif // ~SCR1_RVC_EXT
519
        default            : exc_code = SCR1_EXC_CODE_ECALL_M;
520
    endcase // 1'b1
521
end
522
 
523
// Exception trap value multiplexer
524
//------------------------------------------------------------------------------
525
 
526
assign instr_fault_rvi_hi = exu_queue.instr_rvc;
527
assign exu_illegal_instr = {exu2csr_rw_addr_o,          // CSR address
528
                            5'(exu_queue.rs1_addr),     // rs1 / zimm
529
                            exu_queue.imm[14:12],       // funct3
530
                            5'(exu_queue.rd_addr),      // rd
531
                            SCR1_OPCODE_SYSTEM,
532
                            SCR1_INSTR_RVI
533
                           };
534
 
535
// If Instruction Access Fault occurred on high part of RVI instruction trap
536
// value is set to point on the high part of the instruction (inc_pc=pc+2)
537
always_comb begin
538
    case (exc_code)
539
`ifndef SCR1_RVC_EXT
540
        SCR1_EXC_CODE_INSTR_MISALIGN    : exc_trap_val = jb_new_pc;
541
`endif // SCR1_RVC_EXT
542
        SCR1_EXC_CODE_INSTR_ACCESS_FAULT: exc_trap_val = instr_fault_rvi_hi
543
                                                       ? inc_pc
544
                                                       : pc_curr_ff;
545
`ifdef SCR1_MTVAL_ILLEGAL_INSTR_EN
546
        SCR1_EXC_CODE_ILLEGAL_INSTR     : exc_trap_val = exu_queue.exc_req
547
                                                       ? exu_queue.imm
548
                                                       : exu_illegal_instr;
549
`else // SCR1_MTVAL_ILLEGAL_INSTR_EN
550
        SCR1_EXC_CODE_ILLEGAL_INSTR     : exc_trap_val = '0;
551
`endif // SCR1_MTVAL_ILLEGAL_INSTR_EN
552
`ifdef SCR1_TDU_EN
553
        SCR1_EXC_CODE_BREAKPOINT: begin
554
            case (1'b1)
555
                tdu2exu_ibrkpt_exc_req_i: exc_trap_val = pc_curr_ff;
556
                tdu2lsu_dbrkpt_exc_req_i: exc_trap_val = ialu_addr_res;
557
                default                 : exc_trap_val = '0;
558
            endcase
559
        end
560
`endif // SCR1_TDU_EN
561
        SCR1_EXC_CODE_LD_ADDR_MISALIGN,
562
        SCR1_EXC_CODE_LD_ACCESS_FAULT,
563
        SCR1_EXC_CODE_ST_ADDR_MISALIGN,
564
        SCR1_EXC_CODE_ST_ACCESS_FAULT   : exc_trap_val = ialu_addr_res;
565
        default                         : exc_trap_val = '0;
566
    endcase // exc_code
567
end
568
 
569
//------------------------------------------------------------------------------
570
// WFI logic
571
//------------------------------------------------------------------------------
572
//
573
 // Wait for interrupt (WFI) logic consists of the following functional units:
574
 // - WFI control logic
575
 // - WFI Run Start register
576
 // - WFI Halted flag register
577
 // - WFI status signals
578
//
579
 
580
// WFI control logic
581
//------------------------------------------------------------------------------
582
 
583
assign wfi_halt_cond = ~csr2exu_ip_ie_i
584
                     & ((exu_queue_vd & exu_queue.wfi_req) | wfi_run_start_ff)
585
`ifdef SCR1_DBG_EN
586
                     & ~hdu2exu_no_commit_i & ~hdu2exu_dmode_sstep_en_i & ~hdu2exu_dbg_run2halt_i
587
`endif // SCR1_DBG_EN
588
                     ;
589
assign wfi_halt_req  = ~wfi_halted_ff & wfi_halt_cond;
590
 
591
// HART will exit WFI halted state if the event that causes the HART to resume
592
// execution occurs even if it doesn't cause an interrupt to be taken
593
assign wfi_run_req   = wfi_halted_ff  & (csr2exu_ip_ie_i
594
`ifdef SCR1_DBG_EN
595
                                      | hdu2exu_dbg_halt2run_i
596
`endif // SCR1_DBG_EN
597
                                      );
598
 
599
// WFI Run Start register
600
//------------------------------------------------------------------------------
601
 
602
`ifndef SCR1_CLKCTRL_EN
603
always_ff @(negedge rst_n, posedge clk) begin
604
`else // SCR1_CLKCTRL_EN
605
always_ff @(negedge rst_n, posedge clk_alw_on) begin
606
`endif // SCR1_CLKCTRL_EN
607
    if (~rst_n) begin
608
        wfi_run_start_ff <= 1'b0;
609
    end else begin
610
        wfi_run_start_ff <= wfi_run_start_next;
611
    end
612
end
613
 
614
assign wfi_run_start_next = wfi_halted_ff & csr2exu_ip_ie_i & ~exu2csr_take_irq_o;
615
 
616
// WFI halted flag register
617
//------------------------------------------------------------------------------
618
 
619
assign wfi_halted_upd = wfi_halt_req | wfi_run_req;
620
 
621
`ifndef SCR1_CLKCTRL_EN
622
always_ff @(negedge rst_n, posedge clk) begin
623
`else // SCR1_CLKCTRL_EN
624
always_ff @(negedge rst_n, posedge clk_alw_on) begin
625
`endif // SCR1_CLKCTRL_EN
626
    if (~rst_n) begin
627
        wfi_halted_ff <= 1'b0;
628
    end else if (wfi_halted_upd) begin
629
        wfi_halted_ff <= wfi_halted_next;
630
    end
631
end
632
 
633
assign wfi_halted_next = wfi_halt_req | ~wfi_run_req;
634
 
635
// WFI status signals
636
//------------------------------------------------------------------------------
637
 
638
assign exu2pipe_wfi_run2halt_o = wfi_halt_req;
639
`ifdef SCR1_CLKCTRL_EN
640
assign exu2pipe_wfi_halted_o   = wfi_halted_ff;
641
`endif // SCR1_CLKCTRL_EN
642
 
643
//------------------------------------------------------------------------------
644
// Program Counter logic
645
//------------------------------------------------------------------------------
646
//
647
 // PC logic consists of the following functional units:
648
 // - PC initialization logic
649
 // - Current PC register
650
 // - New PC multiplexer
651
 
652
// PC initialization logic
653
//------------------------------------------------------------------------------
654
// Generates a New PC request to set PC to reset value
655
 
656
always_ff @(posedge clk, negedge rst_n) begin
657
    if (~rst_n) begin
658
        init_pc_v <= '0;
659
    end else begin
660
        if (~&init_pc_v) begin
661
            init_pc_v <= {init_pc_v[2:0], 1'b1};
662
        end
663
    end
664
end
665
 
666
assign init_pc = ~init_pc_v[3] & init_pc_v[2];
667
 
668
// Current PC register
669
//------------------------------------------------------------------------------
670
 
671
assign pc_curr_upd = ((exu2pipe_instret_o | exu2csr_take_irq_o
672
`ifdef SCR1_DBG_EN
673
                   | dbg_run_start_npbuf) & ( ~hdu2exu_pc_advmt_dsbl_i
674
                                            & ~hdu2exu_no_commit_i
675
`endif // SCR1_DBG_EN
676
                   ));
677
 
678
always_ff @(negedge rst_n, posedge clk) begin
679
    if (~rst_n) begin
680
        pc_curr_ff <= SCR1_RST_VECTOR;
681
    end else if (pc_curr_upd) begin
682
        pc_curr_ff <= pc_curr_next;
683
    end
684
end
685
 
686
`ifdef SCR1_RVC_EXT
687
assign inc_pc = pc_curr_ff + (exu_queue.instr_rvc ? `SCR1_XLEN'd2 : `SCR1_XLEN'd4);
688
`else // ~SCR1_RVC_EXT
689
assign inc_pc = pc_curr_ff + `SCR1_XLEN'd4;
690
`endif // ~SCR1_RVC_EXT
691
 
692
assign pc_curr_next = exu2ifu_pc_new_req_o        ? exu2ifu_pc_new_o
693
                    : (inc_pc[6] ^ pc_curr_ff[6]) ? inc_pc
694
                                                  : {pc_curr_ff[`SCR1_XLEN-1:6], inc_pc[5:0]};
695
 
696
// New PC multiplexer
697
//------------------------------------------------------------------------------
698
 
699
always_comb begin
700
    case (1'b1)
701
        init_pc             : exu2ifu_pc_new_o = SCR1_RST_VECTOR;
702
        exu2csr_take_exc_o,
703
        exu2csr_take_irq_o,
704
        exu2csr_mret_instr_o: exu2ifu_pc_new_o = csr2exu_new_pc_i;
705
`ifdef SCR1_DBG_EN
706
        dbg_run_start_npbuf : exu2ifu_pc_new_o = hdu2exu_dbg_new_pc_i;
707
`endif // SCR1_DBG_EN
708
        wfi_run_start_ff    : exu2ifu_pc_new_o = pc_curr_ff;
709
        exu_queue.fencei_req: exu2ifu_pc_new_o = inc_pc;
710
        default             : exu2ifu_pc_new_o = ialu_addr_res & SCR1_JUMP_MASK;
711
    endcase
712
end
713
 
714
assign exu2ifu_pc_new_req_o = init_pc                                        // reset
715
                            | exu2csr_take_irq_o
716
                            | exu2csr_take_exc_o
717
                            | (exu2csr_mret_instr_o & ~csr2exu_mstatus_mie_up_i)
718
                            | (exu_queue_vd & exu_queue.fencei_req)
719
                            | (wfi_run_start_ff
720
`ifdef SCR1_CLKCTRL_EN
721
                            & clk_pipe_en
722
`endif // SCR1_CLKCTRL_EN
723
                            )
724
`ifdef SCR1_DBG_EN
725
                            | dbg_run_start_npbuf
726
`endif // SCR1_DBG_EN
727
                            | (exu_queue_vd & jb_taken);
728
 
729
// Jump/branch signals
730
assign branch_taken = exu_queue.branch_req & ialu_cmp;
731
assign jb_taken     = exu_queue.jump_req | branch_taken;
732
assign jb_new_pc    = ialu_addr_res & SCR1_JUMP_MASK;
733
 
734
// PC to be loaded on MRET from interrupt trap
735
assign exu2csr_pc_next_o  = ~exu_queue_vd ? pc_curr_ff
736
                          : jb_taken      ? jb_new_pc
737
                                          : inc_pc;
738
assign exu2pipe_pc_curr_o = pc_curr_ff;
739
 
740
//------------------------------------------------------------------------------
741
// Load/Store Unit (LSU)
742
//------------------------------------------------------------------------------
743
 //
744
 // Functionality:
745
 // - Performs load and store operations in Data Memory
746
 // - Generates DMEM address misalign and access fault exceptions
747
 // - Passes DMEM operations information to TDU and generates LSU breakpoint exception
748
 //
749
//------------------------------------------------------------------------------
750
 
751
assign lsu_req  = ((exu_queue.lsu_cmd != SCR1_LSU_CMD_NONE) & exu_queue_vd);
752
 
753
scr1_pipe_lsu i_lsu(
754
    .rst_n                      (rst_n                   ),
755
    .clk                        (clk                     ),
756
 
757
    // EXU <-> LSU interface
758
    .exu2lsu_req_i              (lsu_req                 ),       // Request to LSU
759
    .exu2lsu_cmd_i              (exu_queue.lsu_cmd       ),       // LSU command
760
    .exu2lsu_addr_i             (ialu_addr_res           ),       // DMEM address
761
    .exu2lsu_sdata_i            (mprf2exu_rs2_data_i     ),       // Data for store to DMEM
762
    .lsu2exu_rdy_o              (lsu_rdy                 ),       // LSU ready
763
    .lsu2exu_ldata_o            (lsu_l_data              ),       // Loaded data form DMEM
764
    .lsu2exu_exc_o              (lsu_exc_req             ),       // LSU exception
765
    .lsu2exu_exc_code_o         (lsu_exc_code            ),       // LSU exception code
766
 
767
`ifdef SCR1_TDU_EN
768
    // TDU <-> LSU interface
769
    .lsu2tdu_dmon_o             (lsu2tdu_dmon_o          ),
770
    .tdu2lsu_ibrkpt_exc_req_i   (tdu2lsu_ibrkpt_exc_req_i),
771
    .tdu2lsu_dbrkpt_exc_req_i   (tdu2lsu_dbrkpt_exc_req_i),
772
`endif // SCR1_TDU_EN
773
 
774
    // Data memory interface
775
    .lsu2dmem_req_o             (exu2dmem_req_o          ),       // DMEM request
776
    .lsu2dmem_cmd_o             (exu2dmem_cmd_o          ),       // DMEM command
777
    .lsu2dmem_width_o           (exu2dmem_width_o        ),       // DMEM width
778
    .lsu2dmem_addr_o            (exu2dmem_addr_o         ),       // DMEM address
779
    .lsu2dmem_wdata_o           (exu2dmem_wdata_o        ),       // DMEM write data
780
    .dmem2lsu_req_ack_i         (dmem2exu_req_ack_i      ),       // DMEM request acknowledge
781
    .dmem2lsu_rdata_i           (dmem2exu_rdata_i        ),       // DMEM read data
782
    .dmem2lsu_resp_i            (dmem2exu_resp_i         )        // DMEM response
783
);
784
 
785
//------------------------------------------------------------------------------
786
// EXU status logic
787
//------------------------------------------------------------------------------
788
 
789
// EXU ready flag
790
always_comb begin
791
    case (1'b1)
792
        lsu_req                 : exu_rdy = lsu_rdy | lsu_exc_req;
793
`ifdef SCR1_RVM_EXT
794
        ialu_vd                 : exu_rdy = ialu_rdy;
795
`endif // SCR1_RVM_EXT
796
        csr2exu_mstatus_mie_up_i: exu_rdy = 1'b0;
797
        default                 : exu_rdy = 1'b1;
798
    endcase
799
end
800
 
801
assign exu2pipe_init_pc_o       = init_pc;
802
assign exu2idu_rdy_o            = exu_rdy & ~exu_queue_barrier;
803
assign exu2pipe_exu_busy_o      = exu_queue_vd & ~exu_rdy;
804
assign exu2pipe_instret_o       = exu_queue_vd & exu_rdy;
805
assign exu2csr_instret_no_exc_o = exu2pipe_instret_o & ~exu_exc_req;
806
 
807
// Exceptions
808
`ifdef SCR1_DBG_EN
809
assign exu2pipe_exc_req_o  = exu_queue_vd ? exu_exc_req : exu_exc_req_ff;
810
`else // SCR1_DBG_EN
811
assign exu2pipe_exc_req_o  = exu_exc_req;
812
`endif // SCR1_DBG_EN
813
 
814
// Breakpoints
815
assign exu2pipe_brkpt_o    = exu_queue_vd & (exu_queue.exc_code == SCR1_EXC_CODE_BREAKPOINT);
816
`ifdef SCR1_TDU_EN
817
assign exu2hdu_ibrkpt_hw_o = tdu2exu_ibrkpt_exc_req_i | tdu2lsu_dbrkpt_exc_req_i;
818
`endif // SCR1_TDU_EN
819
 
820
//------------------------------------------------------------------------------
821
// EXU <-> MPRF interface
822
//------------------------------------------------------------------------------
823
 
824
// Operands fetching stage
825
//------------------------------------------------------------------------------
826
 
827
`ifdef  SCR1_NO_EXE_STAGE
828
assign mprf_rs1_req = exu_queue_vd & idu2exu_use_rs1_i;
829
assign mprf_rs2_req = exu_queue_vd & idu2exu_use_rs2_i;
830
`else // SCR1_NO_EXE_STAGE
831
 `ifdef  SCR1_MPRF_RAM
832
assign mprf_rs1_req = exu_queue_en
833
                    ? (exu_queue_vd_next & idu2exu_use_rs1_i)
834
                    : (exu_queue_vd      & idu2exu_use_rs1_ff);
835
assign mprf_rs2_req = exu_queue_en
836
                    ? (exu_queue_vd_next & idu2exu_use_rs2_i)
837
                    : (exu_queue_vd      & idu2exu_use_rs2_ff);
838
 `else // SCR1_MPRF_RAM
839
assign mprf_rs1_req = exu_queue_vd & idu2exu_use_rs1_ff;
840
assign mprf_rs2_req = exu_queue_vd & idu2exu_use_rs2_ff;
841
 `endif // SCR1_MPRF_RAM
842
`endif // SCR1_NO_EXE_STAGE
843
 
844
// If exu_queue isn't enabled we need previous addresses and usage flags because
845
// RAM blocks read operation is SYNCHRONOUS
846
`ifdef SCR1_MPRF_RAM
847
assign mprf_rs1_addr = exu_queue_en ? idu2exu_cmd_i.rs1_addr : exu_queue.rs1_addr;
848
assign mprf_rs2_addr = exu_queue_en ? idu2exu_cmd_i.rs2_addr : exu_queue.rs2_addr;
849
`else // SCR1_MPRF_RAM
850
assign mprf_rs1_addr = exu_queue.rs1_addr;
851
assign mprf_rs2_addr = exu_queue.rs2_addr;
852
`endif // SCR1_MPRF_RAM
853
 
854
assign exu2mprf_rs1_addr_o = mprf_rs1_req ? `SCR1_MPRF_AWIDTH'(mprf_rs1_addr) : '0;
855
assign exu2mprf_rs2_addr_o = mprf_rs2_req ? `SCR1_MPRF_AWIDTH'(mprf_rs2_addr) : '0;
856
 
857
// Write back stage
858
//------------------------------------------------------------------------------
859
 
860
assign exu2mprf_w_req_o   = (exu_queue.rd_wb_sel != SCR1_RD_WB_NONE) & exu_queue_vd & ~exu_exc_req
861
`ifdef SCR1_DBG_EN
862
                          & ~hdu2exu_no_commit_i
863
`endif // SCR1_DBG_EN
864
                          & ((exu_queue.rd_wb_sel == SCR1_RD_WB_CSR) ? csr_access_init : exu_rdy);
865
 
866
assign exu2mprf_rd_addr_o = `SCR1_MPRF_AWIDTH'(exu_queue.rd_addr);
867
 
868
// MRPF RD data multiplexer
869
always_comb begin
870
    case (exu_queue.rd_wb_sel)
871
        SCR1_RD_WB_SUM2  : exu2mprf_rd_data_o = ialu_addr_res;
872
        SCR1_RD_WB_IMM   : exu2mprf_rd_data_o = exu_queue.imm;
873
        SCR1_RD_WB_INC_PC: exu2mprf_rd_data_o = inc_pc;
874
        SCR1_RD_WB_LSU   : exu2mprf_rd_data_o = lsu_l_data;
875
        SCR1_RD_WB_CSR   : exu2mprf_rd_data_o = csr2exu_r_data_i;
876
        default          : exu2mprf_rd_data_o = ialu_main_res;
877
    endcase
878
end
879
 
880
//------------------------------------------------------------------------------
881
// EXU <-> CSR interface
882
//------------------------------------------------------------------------------
883
//
884
 // EXU <-> CSR interface consists of the following functional units:
885
 // - CSR write/read interface
886
 // - CSR access FSM
887
 // - CSR events interface:
888
 //   - Exceptions signals
889
 //   - Interrupts signals
890
 //   - MRET signals
891
//
892
 
893
// CSRs write/read interface
894
//------------------------------------------------------------------------------
895
 
896
// CSR write/read request signals calculation
897
always_comb begin
898
    if (~exu_queue_vd
899
`ifdef SCR1_TDU_EN
900
       | tdu2exu_ibrkpt_exc_req_i
901
`endif // SCR1_TDU_EN
902
    ) begin
903
        exu2csr_r_req_o = 1'b0;
904
        exu2csr_w_req_o = 1'b0;
905
    end else begin
906
        case (exu_queue.csr_cmd)
907
            SCR1_CSR_CMD_WRITE  : begin
908
                exu2csr_r_req_o = |exu_queue.rd_addr;
909
                exu2csr_w_req_o = csr_access_init;
910
            end
911
            SCR1_CSR_CMD_SET,
912
            SCR1_CSR_CMD_CLEAR  : begin
913
                exu2csr_r_req_o = 1'b1;
914
                exu2csr_w_req_o = |exu_queue.rs1_addr & csr_access_init;
915
            end
916
            default : begin
917
                exu2csr_r_req_o = 1'b0;
918
                exu2csr_w_req_o = 1'b0;
919
            end
920
        endcase
921
    end
922
end
923
 
924
assign exu2csr_w_cmd_o   = exu_queue.csr_cmd;
925
assign exu2csr_rw_addr_o = exu_queue.imm[SCR1_CSR_ADDR_WIDTH-1:0];
926
assign exu2csr_w_data_o  = (exu_queue.csr_op == SCR1_CSR_OP_REG)
927
                         ? mprf2exu_rs1_data_i
928
                         : {'0, exu_queue.rs1_addr}; // zimm
929
 
930
 
931
// CSR access FSM
932
//------------------------------------------------------------------------------
933
 
934
always_ff @(posedge clk, negedge rst_n) begin
935
    if (~rst_n) begin
936
        csr_access_ff <= SCR1_CSR_INIT;
937
    end else begin
938
        csr_access_ff <= csr_access_next;
939
    end
940
end
941
 
942
assign csr_access_next = (csr_access_init & csr2exu_mstatus_mie_up_i)
943
                       ? SCR1_CSR_RDY
944
                       : SCR1_CSR_INIT;
945
 
946
assign csr_access_init = (csr_access_ff == SCR1_CSR_INIT);
947
 
948
// CSR events interface
949
//------------------------------------------------------------------------------
950
 
951
// Exceptions signals
952
assign exu2csr_take_exc_o = exu_exc_req
953
`ifdef SCR1_DBG_EN
954
                          & ~hdu2exu_dbg_halted_i
955
`endif // SCR1_DBG_EN
956
                          ;
957
assign exu2csr_exc_code_o = exc_code;
958
assign exu2csr_trap_val_o = exc_trap_val;
959
 
960
// Interrupts signals
961
assign exu2csr_take_irq_o = csr2exu_irq_i & ~exu2pipe_exu_busy_o
962
`ifdef SCR1_DBG_EN
963
                          & ~hdu2exu_irq_dsbl_i
964
                          & ~hdu2exu_dbg_halted_i
965
`endif // SCR1_DBG_EN
966
`ifdef SCR1_CLKCTRL_EN
967
                          & clk_pipe_en
968
`endif // SCR1_CLKCTRL_EN
969
                          ;
970
 
971
// MRET signals
972
// MRET instruction flag
973
assign exu2csr_mret_instr_o  = exu_queue_vd & exu_queue.mret_req
974
`ifdef SCR1_TDU_EN
975
                             & ~tdu2exu_ibrkpt_exc_req_i
976
`endif // SCR1_TDU_EN
977
`ifdef SCR1_DBG_EN
978
                             & ~hdu2exu_dbg_halted_i
979
`endif // SCR1_DBG_EN
980
                             ;
981
assign exu2csr_mret_update_o = exu2csr_mret_instr_o & csr_access_init;
982
 
983
`ifdef SCR1_TDU_EN
984
//------------------------------------------------------------------------------
985
// EXU <-> TDU interface
986
//------------------------------------------------------------------------------
987
 
988
// Instruction monitor
989
assign exu2tdu_imon_o.vd    = exu_queue_vd;
990
assign exu2tdu_imon_o.req   = exu2pipe_instret_o;
991
assign exu2tdu_imon_o.addr  = pc_curr_ff;
992
 
993
always_comb begin
994
    exu2tdu_ibrkpt_ret_o = '0;
995
    if (exu_queue_vd) begin
996
        exu2tdu_ibrkpt_ret_o = tdu2exu_ibrkpt_match_i;
997
        if (lsu_req) begin
998
            exu2tdu_ibrkpt_ret_o[SCR1_TDU_MTRIG_NUM-1:0] |= tdu2lsu_dbrkpt_match_i;
999
        end
1000
    end
1001
end
1002
`endif // SCR1_TDU_EN
1003
 
1004
 
1005
`ifdef SCR1_TRGT_SIMULATION
1006
//------------------------------------------------------------------------------
1007
// Tracelog signals
1008
//------------------------------------------------------------------------------
1009
 
1010
logic [`SCR1_XLEN-1:0]      update_pc;
1011
logic                       update_pc_en;
1012
 
1013
assign update_pc_en = (init_pc | exu2pipe_instret_o | exu2csr_take_irq_o)
1014
`ifdef SCR1_DBG_EN
1015
                    & ~hdu2exu_pc_advmt_dsbl_i & ~hdu2exu_no_commit_i
1016
`endif // SCR1_DBG_EN
1017
                    ;
1018
assign update_pc    = exu2ifu_pc_new_req_o ? exu2ifu_pc_new_o : inc_pc;
1019
 
1020
 
1021
//------------------------------------------------------------------------------
1022
// Assertion
1023
//------------------------------------------------------------------------------
1024
 
1025
// X checks
1026
 
1027
SCR1_SVA_EXU_XCHECK_CTRL : assert property (
1028
    @(negedge clk) disable iff (~rst_n)
1029
    !$isunknown({idu2exu_req_i, csr2exu_irq_i, csr2exu_ip_ie_i, lsu_req, lsu_rdy, exu_exc_req})
1030
    ) else $error("EXU Error: unknown control values");
1031
 
1032
SCR1_SVA_EXU_XCHECK_QUEUE : assert property (
1033
    @(negedge clk) disable iff (~rst_n)
1034
    idu2exu_req_i |-> !$isunknown(idu2exu_cmd_i)
1035
    ) else $error("EXU Error: unknown values in queue");
1036
 
1037
SCR1_SVA_EXU_XCHECK_CSR_RDATA : assert property (
1038
    @(negedge clk) disable iff (~rst_n)
1039
    exu2csr_r_req_o |-> !$isunknown({csr2exu_r_data_i, csr2exu_rw_exc_i})
1040
    ) else $error("EXU Error: unknown values from CSR");
1041
 
1042
// Behavior checks
1043
 
1044
SCR1_SVA_EXU_ONEHOT : assert property (
1045
    @(negedge clk) disable iff (~rst_n)
1046
    $onehot0({exu_queue.jump_req, exu_queue.branch_req, lsu_req})
1047
    ) else $error("EXU Error: illegal combination of control signals");
1048
 
1049
SCR1_SVA_EXU_ONEHOT_EXC : assert property (
1050
    @(negedge clk) disable iff (~rst_n)
1051
    exu_queue_vd |->
1052
    $onehot0({exu_queue.exc_req, lsu_exc_req, csr2exu_rw_exc_i
1053
`ifndef SCR1_RVC_EXT
1054
    , jb_misalign
1055
`endif
1056
    })
1057
    ) else $error("EXU Error: exceptions $onehot0 failed");
1058
 
1059
`endif // SCR1_TRGT_SIMULATION
1060
 
1061
endmodule : scr1_pipe_exu

powered by: WebSVN 2.1.0

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