../src/lowrisc_ibex_ibex_core_0.1/rtl/ibex_core.sv Cov: 89.9%
1: // Copyright lowRISC contributors.
2: // Copyright 2018 ETH Zurich and University of Bologna, see also CREDITS.md.
3: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
4: // SPDX-License-Identifier: Apache-2.0
5:
6: `ifdef RISCV_FORMAL
7: `define RVFI
8: `endif
9:
10: `include "prim_assert.sv"
11:
12: /**
13: * Top level module of the ibex RISC-V core
14: */
15: module ibex_core #(
16: parameter bit PMPEnable = 1'b0,
17: parameter int unsigned PMPGranularity = 0,
18: parameter int unsigned PMPNumRegions = 4,
19: parameter int unsigned MHPMCounterNum = 0,
20: parameter int unsigned MHPMCounterWidth = 40,
21: parameter bit RV32E = 1'b0,
22: parameter bit RV32M = 1'b1,
23: parameter bit RV32B = 1'b0,
24: parameter bit BranchTargetALU = 1'b0,
25: parameter bit WritebackStage = 1'b0,
26: parameter MultiplierImplementation = "fast",
27: parameter bit ICache = 1'b0,
28: parameter bit ICacheECC = 1'b0,
29: parameter bit DbgTriggerEn = 1'b0,
30: parameter bit SecureIbex = 1'b0,
31: parameter int unsigned DmHaltAddr = 32'h1A110800,
32: parameter int unsigned DmExceptionAddr = 32'h1A110808
33: ) (
34: // Clock and Reset
35: input logic clk_i,
36: input logic rst_ni,
37:
38: input logic test_en_i, // enable all clock gates for testing
39:
40: input logic [31:0] hart_id_i,
41: input logic [31:0] boot_addr_i,
42:
43: // Instruction memory interface
44: output logic instr_req_o,
45: input logic instr_gnt_i,
46: input logic instr_rvalid_i,
47: output logic [31:0] instr_addr_o,
48: input logic [31:0] instr_rdata_i,
49: input logic instr_err_i,
50:
51: // Data memory interface
52: output logic data_req_o,
53: input logic data_gnt_i,
54: input logic data_rvalid_i,
55: output logic data_we_o,
56: output logic [3:0] data_be_o,
57: output logic [31:0] data_addr_o,
58: output logic [31:0] data_wdata_o,
59: input logic [31:0] data_rdata_i,
60: input logic data_err_i,
61:
62: // Interrupt inputs
63: input logic irq_software_i,
64: input logic irq_timer_i,
65: input logic irq_external_i,
66: input logic [14:0] irq_fast_i,
67: input logic irq_nm_i, // non-maskeable interrupt
68:
69: // Debug Interface
70: input logic debug_req_i,
71:
72: // RISC-V Formal Interface
73: // Does not comply with the coding standards of _i/_o suffixes, but follows
74: // the convention of RISC-V Formal Interface Specification.
75: `ifdef RVFI
76: output logic rvfi_valid,
77: output logic [63:0] rvfi_order,
78: output logic [31:0] rvfi_insn,
79: output logic rvfi_trap,
80: output logic rvfi_halt,
81: output logic rvfi_intr,
82: output logic [ 1:0] rvfi_mode,
83: output logic [ 1:0] rvfi_ixl,
84: output logic [ 4:0] rvfi_rs1_addr,
85: output logic [ 4:0] rvfi_rs2_addr,
86: output logic [ 4:0] rvfi_rs3_addr,
87: output logic [31:0] rvfi_rs1_rdata,
88: output logic [31:0] rvfi_rs2_rdata,
89: output logic [31:0] rvfi_rs3_rdata,
90: output logic [ 4:0] rvfi_rd_addr,
91: output logic [31:0] rvfi_rd_wdata,
92: output logic [31:0] rvfi_pc_rdata,
93: output logic [31:0] rvfi_pc_wdata,
94: output logic [31:0] rvfi_mem_addr,
95: output logic [ 3:0] rvfi_mem_rmask,
96: output logic [ 3:0] rvfi_mem_wmask,
97: output logic [31:0] rvfi_mem_rdata,
98: output logic [31:0] rvfi_mem_wdata,
99: `endif
100:
101: // CPU Control Signals
102: input logic fetch_enable_i,
103: output logic core_sleep_o
104: );
105:
106: import ibex_pkg::*;
107:
108: localparam int unsigned PMP_NUM_CHAN = 2;
109: localparam bit DataIndTiming = SecureIbex;
110: localparam bit DummyInstructions = SecureIbex;
111: // Speculative branch option, trades-off performance against timing.
112: // Setting this to 1 eases branch target critical paths significantly but reduces performance
113: // by ~3% (based on Coremark/MHz score).
114: // Set by default in the max PMP config which has the tightest budget for branch target timing.
115: localparam bit SpecBranch = PMPEnable & (PMPNumRegions == 16);
116:
117: // IF/ID signals
118: logic dummy_instr_id;
119: logic instr_valid_id;
120: logic instr_new_id;
121: logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
122: logic [31:0] instr_rdata_alu_id; // Instruction sampled inside IF stage (replicated to ease
123: // fan-out)
124: logic [15:0] instr_rdata_c_id; // Compressed instruction sampled inside IF stage
125: logic instr_is_compressed_id;
126: logic instr_fetch_err; // Bus error on instr fetch
127: logic instr_fetch_err_plus2; // Instruction error is misaligned
128: logic illegal_c_insn_id; // Illegal compressed instruction sent to ID stage
129: logic [31:0] pc_if; // Program counter in IF stage
130: logic [31:0] pc_id; // Program counter in ID stage
131: logic [31:0] pc_wb; // Program counter in WB stage
132: logic [33:0] imd_val_d_ex; // Intermediate register for multicycle Ops
133: logic [33:0] imd_val_q_ex; // Intermediate register for multicycle Ops
134: logic imd_val_we_ex;
135:
136: logic data_ind_timing;
137: logic dummy_instr_en;
138: logic [2:0] dummy_instr_mask;
139: logic dummy_instr_seed_en;
140: logic [31:0] dummy_instr_seed;
141: logic icache_enable;
142: logic icache_inval;
143:
144: logic instr_first_cycle_id;
145: logic instr_valid_clear;
146: logic pc_set;
147: logic pc_set_spec;
148: pc_sel_e pc_mux_id; // Mux selector for next PC
149: exc_pc_sel_e exc_pc_mux_id; // Mux selector for exception PC
150: exc_cause_e exc_cause; // Exception cause
151:
152: logic lsu_load_err;
153: logic lsu_store_err;
154:
155: // LSU signals
156: logic lsu_addr_incr_req;
157: logic [31:0] lsu_addr_last;
158:
159: // Jump and branch target and decision (EX->IF)
160: logic [31:0] branch_target_ex;
161: logic branch_decision;
162:
163: // Core busy signals
164: logic ctrl_busy;
165: logic if_busy;
166: logic lsu_busy;
167: logic core_busy_d, core_busy_q;
168:
169: // Register File
170: logic [4:0] rf_raddr_a;
171: logic [31:0] rf_rdata_a;
172: logic [4:0] rf_raddr_b;
173: logic [31:0] rf_rdata_b;
174: logic [4:0] rf_waddr_wb;
175: logic [31:0] rf_wdata_wb;
176: // Writeback register write data that can be used on the forwarding path (doesn't factor in memory
177: // read data as this is too late for the forwarding path)
178: logic [31:0] rf_wdata_fwd_wb;
179: logic [31:0] rf_wdata_lsu;
180: logic rf_we_wb;
181: logic rf_we_lsu;
182:
183: logic [4:0] rf_waddr_id;
184: logic [31:0] rf_wdata_id;
185: logic rf_we_id;
186:
187: // ALU Control
188: alu_op_e alu_operator_ex;
189: logic [31:0] alu_operand_a_ex;
190: logic [31:0] alu_operand_b_ex;
191:
192: logic [31:0] bt_a_operand;
193: logic [31:0] bt_b_operand;
194:
195: logic [31:0] alu_adder_result_ex; // Used to forward computed address to LSU
196: logic [31:0] result_ex;
197:
198: // Multiplier Control
199: logic mult_en_ex;
200: logic div_en_ex;
201: logic mult_sel_ex;
202: logic div_sel_ex;
203: md_op_e multdiv_operator_ex;
204: logic [1:0] multdiv_signed_mode_ex;
205: logic [31:0] multdiv_operand_a_ex;
206: logic [31:0] multdiv_operand_b_ex;
207: logic multdiv_ready_id;
208:
209: // CSR control
210: logic csr_access;
211: csr_op_e csr_op;
212: logic csr_op_en;
213: csr_num_e csr_addr;
214: logic [31:0] csr_rdata;
215: logic [31:0] csr_wdata;
216: logic illegal_csr_insn_id; // CSR access to non-existent register,
217: // with wrong priviledge level,
218: // or missing write permissions
219:
220: // Data Memory Control
221: logic lsu_we;
222: logic [1:0] lsu_type;
223: logic lsu_sign_ext;
224: logic lsu_req;
225: logic [31:0] lsu_wdata;
226: logic lsu_req_done;
227:
228: // stall control
229: logic id_in_ready;
230: logic ex_valid;
231:
232: logic lsu_resp_valid;
233:
234: // Signals between instruction core interface and pipe (if and id stages)
235: logic instr_req_int; // Id stage asserts a req to instruction core interface
236:
237: // Writeback stage
238: logic en_wb;
239: wb_instr_type_e instr_type_wb;
240: logic ready_wb;
241: logic rf_write_wb;
242: logic outstanding_load_wb;
243: logic outstanding_store_wb;
244:
245: // Interrupts
246: logic irq_pending;
247: logic nmi_mode;
248: irqs_t irqs;
249: logic csr_mstatus_mie;
250: logic [31:0] csr_mepc, csr_depc;
251:
252: // PMP signals
253: logic [33:0] csr_pmp_addr [PMPNumRegions];
254: pmp_cfg_t csr_pmp_cfg [PMPNumRegions];
255: logic pmp_req_err [PMP_NUM_CHAN];
256: logic instr_req_out;
257: logic data_req_out;
258:
259: logic csr_save_if;
260: logic csr_save_id;
261: logic csr_save_wb;
262: logic csr_restore_mret_id;
263: logic csr_restore_dret_id;
264: logic csr_save_cause;
265: logic csr_mtvec_init;
266: logic [31:0] csr_mtvec;
267: logic [31:0] csr_mtval;
268: logic csr_mstatus_tw;
269: priv_lvl_e priv_mode_id;
270: priv_lvl_e priv_mode_if;
271: priv_lvl_e priv_mode_lsu;
272:
273: // debug mode and dcsr configuration
274: logic debug_mode;
275: dbg_cause_e debug_cause;
276: logic debug_csr_save;
277: logic debug_single_step;
278: logic debug_ebreakm;
279: logic debug_ebreaku;
280: logic trigger_match;
281:
282: // signals relating to instruction movements between pipeline stages
283: // used by performance counters and RVFI
284: logic instr_id_done;
285: logic instr_id_done_compressed;
286: logic instr_done_wb;
287:
288: logic perf_iside_wait;
289: logic perf_dside_wait;
290: logic perf_mul_wait;
291: logic perf_div_wait;
292: logic perf_jump;
293: logic perf_branch;
294: logic perf_tbranch;
295: logic perf_load;
296: logic perf_store;
297:
298: // for RVFI
299: logic illegal_insn_id, unused_illegal_insn_id; // ID stage sees an illegal instruction
300:
301: // RISC-V Formal Interface signals
302: `ifdef RVFI
303: logic rvfi_instr_new_wb;
304: logic rvfi_intr_d;
305: logic rvfi_intr_q;
306: logic rvfi_set_trap_pc_d;
307: logic rvfi_set_trap_pc_q;
308: logic [31:0] rvfi_insn_id;
309: logic [4:0] rvfi_rs1_addr_d;
310: logic [4:0] rvfi_rs1_addr_q;
311: logic [4:0] rvfi_rs2_addr_d;
312: logic [4:0] rvfi_rs2_addr_q;
313: logic [4:0] rvfi_rs3_addr_d;
314: logic [31:0] rvfi_rs1_data_d;
315: logic [31:0] rvfi_rs1_data_q;
316: logic [31:0] rvfi_rs2_data_d;
317: logic [31:0] rvfi_rs2_data_q;
318: logic [31:0] rvfi_rs3_data_d;
319: logic [4:0] rvfi_rd_addr_wb;
320: logic [4:0] rvfi_rd_addr_q;
321: logic [4:0] rvfi_rd_addr_d;
322: logic [31:0] rvfi_rd_wdata_wb;
323: logic [31:0] rvfi_rd_wdata_d;
324: logic [31:0] rvfi_rd_wdata_q;
325: logic rvfi_rd_we_wb;
326: logic [3:0] rvfi_mem_mask_int;
327: logic [31:0] rvfi_mem_rdata_d;
328: logic [31:0] rvfi_mem_rdata_q;
329: logic [31:0] rvfi_mem_wdata_d;
330: logic [31:0] rvfi_mem_wdata_q;
331: logic [31:0] rvfi_mem_addr_d;
332: logic [31:0] rvfi_mem_addr_q;
333: logic rf_ren_a;
334: logic rf_ren_b;
335: `endif
336:
337: //////////////////////
338: // Clock management //
339: //////////////////////
340:
341: logic clk;
342:
343: logic clock_en;
344:
345: // Before going to sleep, wait for I- and D-side
346: // interfaces to finish ongoing operations.
347: assign core_busy_d = ctrl_busy | if_busy | lsu_busy;
348:
349: always_ff @(posedge clk_i or negedge rst_ni) begin
350: if (!rst_ni) begin
351: core_busy_q <= 1'b0;
352: end else begin
353: core_busy_q <= core_busy_d;
354: end
355: end
356:
357: assign clock_en = core_busy_q | debug_req_i | irq_pending | irq_nm_i;
358: assign core_sleep_o = ~clock_en;
359:
360: // main clock gate of the core
361: // generates all clocks except the one for the debug unit which is
362: // independent
363: prim_clock_gating core_clock_gate_i (
364: .clk_i ( clk_i ),
365: .en_i ( clock_en ),
366: .test_en_i ( test_en_i ),
367: .clk_o ( clk )
368: );
369:
370: //////////////
371: // IF stage //
372: //////////////
373:
374: ibex_if_stage #(
375: .DmHaltAddr ( DmHaltAddr ),
376: .DmExceptionAddr ( DmExceptionAddr ),
377: .DummyInstructions ( DummyInstructions ),
378: .ICache ( ICache ),
379: .ICacheECC ( ICacheECC )
380: ) if_stage_i (
381: .clk_i ( clk ),
382: .rst_ni ( rst_ni ),
383:
384: .boot_addr_i ( boot_addr_i ),
385: .req_i ( instr_req_int ), // instruction request control
386:
387: // instruction cache interface
388: .instr_req_o ( instr_req_out ),
389: .instr_addr_o ( instr_addr_o ),
390: .instr_gnt_i ( instr_gnt_i ),
391: .instr_rvalid_i ( instr_rvalid_i ),
392: .instr_rdata_i ( instr_rdata_i ),
393: .instr_err_i ( instr_err_i ),
394: .instr_pmp_err_i ( pmp_req_err[PMP_I] ),
395:
396: // outputs to ID stage
397: .instr_valid_id_o ( instr_valid_id ),
398: .instr_new_id_o ( instr_new_id ),
399: .instr_rdata_id_o ( instr_rdata_id ),
400: .instr_rdata_alu_id_o ( instr_rdata_alu_id ),
401: .instr_rdata_c_id_o ( instr_rdata_c_id ),
402: .instr_is_compressed_id_o ( instr_is_compressed_id ),
403: .instr_fetch_err_o ( instr_fetch_err ),
404: .instr_fetch_err_plus2_o ( instr_fetch_err_plus2 ),
405: .illegal_c_insn_id_o ( illegal_c_insn_id ),
406: .dummy_instr_id_o ( dummy_instr_id ),
407: .pc_if_o ( pc_if ),
408: .pc_id_o ( pc_id ),
409:
410: // control signals
411: .instr_valid_clear_i ( instr_valid_clear ),
412: .pc_set_i ( pc_set ),
413: .pc_set_spec_i ( pc_set_spec ),
414: .pc_mux_i ( pc_mux_id ),
415: .exc_pc_mux_i ( exc_pc_mux_id ),
416: .exc_cause ( exc_cause ),
417: .dummy_instr_en_i ( dummy_instr_en ),
418: .dummy_instr_mask_i ( dummy_instr_mask ),
419: .dummy_instr_seed_en_i ( dummy_instr_seed_en ),
420: .dummy_instr_seed_i ( dummy_instr_seed ),
421: .icache_enable_i ( icache_enable ),
422: .icache_inval_i ( icache_inval ),
423:
424: // branch targets
425: .branch_target_ex_i ( branch_target_ex ),
426:
427: // CSRs
428: .csr_mepc_i ( csr_mepc ), // exception return address
429: .csr_depc_i ( csr_depc ), // debug return address
430: .csr_mtvec_i ( csr_mtvec ), // trap-vector base address
431: .csr_mtvec_init_o ( csr_mtvec_init ),
432:
433: // pipeline stalls
434: .id_in_ready_i ( id_in_ready ),
435:
436: .if_busy_o ( if_busy )
437: );
438:
439: // Core is waiting for the ISide when ID/EX stage is ready for a new instruction but none are
440: // available
441: assign perf_iside_wait = id_in_ready & ~instr_valid_id;
442:
443: // Qualify the instruction request with PMP error
444: assign instr_req_o = instr_req_out & ~pmp_req_err[PMP_I];
445:
446: //////////////
447: // ID stage //
448: //////////////
449:
450: ibex_id_stage #(
451: .RV32E ( RV32E ),
452: .RV32M ( RV32M ),
453: .RV32B ( RV32B ),
454: .BranchTargetALU ( BranchTargetALU ),
455: .DataIndTiming ( DataIndTiming ),
456: .SpecBranch ( SpecBranch ),
457: .WritebackStage ( WritebackStage )
458: ) id_stage_i (
459: .clk_i ( clk ),
460: .rst_ni ( rst_ni ),
461:
462: // Processor Enable
463: .fetch_enable_i ( fetch_enable_i ),
464: .ctrl_busy_o ( ctrl_busy ),
465: .illegal_insn_o ( illegal_insn_id ),
466:
467: // from/to IF-ID pipeline register
468: .instr_valid_i ( instr_valid_id ),
469: .instr_rdata_i ( instr_rdata_id ),
470: .instr_rdata_alu_i ( instr_rdata_alu_id ),
471: .instr_rdata_c_i ( instr_rdata_c_id ),
472: .instr_is_compressed_i ( instr_is_compressed_id ),
473:
474: // Jumps and branches
475: .branch_decision_i ( branch_decision ),
476:
477: // IF and ID control signals
478: .instr_first_cycle_id_o ( instr_first_cycle_id ),
479: .instr_valid_clear_o ( instr_valid_clear ),
480: .id_in_ready_o ( id_in_ready ),
481: .instr_req_o ( instr_req_int ),
482: .pc_set_o ( pc_set ),
483: .pc_set_spec_o ( pc_set_spec ),
484: .pc_mux_o ( pc_mux_id ),
485: .exc_pc_mux_o ( exc_pc_mux_id ),
486: .exc_cause_o ( exc_cause ),
487: .icache_inval_o ( icache_inval ),
488:
489: .instr_fetch_err_i ( instr_fetch_err ),
490: .instr_fetch_err_plus2_i ( instr_fetch_err_plus2 ),
491: .illegal_c_insn_i ( illegal_c_insn_id ),
492:
493: .pc_id_i ( pc_id ),
494:
495: // Stalls
496: .ex_valid_i ( ex_valid ),
497: .lsu_resp_valid_i ( lsu_resp_valid ),
498:
499: .alu_operator_ex_o ( alu_operator_ex ),
500: .alu_operand_a_ex_o ( alu_operand_a_ex ),
501: .alu_operand_b_ex_o ( alu_operand_b_ex ),
502:
503: .imd_val_q_ex_o ( imd_val_q_ex ),
504: .imd_val_d_ex_i ( imd_val_d_ex ),
505: .imd_val_we_ex_i ( imd_val_we_ex ),
506:
507: .bt_a_operand_o ( bt_a_operand ),
508: .bt_b_operand_o ( bt_b_operand ),
509:
510: .mult_en_ex_o ( mult_en_ex ),
511: .div_en_ex_o ( div_en_ex ),
512: .mult_sel_ex_o ( mult_sel_ex ),
513: .div_sel_ex_o ( div_sel_ex ),
514: .multdiv_operator_ex_o ( multdiv_operator_ex ),
515: .multdiv_signed_mode_ex_o ( multdiv_signed_mode_ex ),
516: .multdiv_operand_a_ex_o ( multdiv_operand_a_ex ),
517: .multdiv_operand_b_ex_o ( multdiv_operand_b_ex ),
518: .multdiv_ready_id_o ( multdiv_ready_id ),
519:
520: // CSR ID/EX
521: .csr_access_o ( csr_access ),
522: .csr_op_o ( csr_op ),
523: .csr_op_en_o ( csr_op_en ),
524: .csr_save_if_o ( csr_save_if ), // control signal to save PC
525: .csr_save_id_o ( csr_save_id ), // control signal to save PC
526: .csr_save_wb_o ( csr_save_wb ), // control signal to save PC
527: .csr_restore_mret_id_o ( csr_restore_mret_id ), // restore mstatus upon MRET
528: .csr_restore_dret_id_o ( csr_restore_dret_id ), // restore mstatus upon MRET
529: .csr_save_cause_o ( csr_save_cause ),
530: .csr_mtval_o ( csr_mtval ),
531: .priv_mode_i ( priv_mode_id ),
532: .csr_mstatus_tw_i ( csr_mstatus_tw ),
533: .illegal_csr_insn_i ( illegal_csr_insn_id ),
534: .data_ind_timing_i ( data_ind_timing ),
535:
536: // LSU
537: .lsu_req_o ( lsu_req ), // to load store unit
538: .lsu_we_o ( lsu_we ), // to load store unit
539: .lsu_type_o ( lsu_type ), // to load store unit
540: .lsu_sign_ext_o ( lsu_sign_ext ), // to load store unit
541: .lsu_wdata_o ( lsu_wdata ), // to load store unit
542: .lsu_req_done_i ( lsu_req_done ), // from load store unit
543:
544: .lsu_addr_incr_req_i ( lsu_addr_incr_req ),
545: .lsu_addr_last_i ( lsu_addr_last ),
546:
547: .lsu_load_err_i ( lsu_load_err ),
548: .lsu_store_err_i ( lsu_store_err ),
549:
550: // Interrupt Signals
551: .csr_mstatus_mie_i ( csr_mstatus_mie ),
552: .irq_pending_i ( irq_pending ),
553: .irqs_i ( irqs ),
554: .irq_nm_i ( irq_nm_i ),
555: .nmi_mode_o ( nmi_mode ),
556:
557: // Debug Signal
558: .debug_mode_o ( debug_mode ),
559: .debug_cause_o ( debug_cause ),
560: .debug_csr_save_o ( debug_csr_save ),
561: .debug_req_i ( debug_req_i ),
562: .debug_single_step_i ( debug_single_step ),
563: .debug_ebreakm_i ( debug_ebreakm ),
564: .debug_ebreaku_i ( debug_ebreaku ),
565: .trigger_match_i ( trigger_match ),
566:
567: // write data to commit in the register file
568: .result_ex_i ( result_ex ),
569: .csr_rdata_i ( csr_rdata ),
570:
571: .rf_raddr_a_o ( rf_raddr_a ),
572: .rf_rdata_a_i ( rf_rdata_a ),
573: .rf_raddr_b_o ( rf_raddr_b ),
574: .rf_rdata_b_i ( rf_rdata_b ),
575: `ifdef RVFI
576: .rf_ren_a_o ( rf_ren_a ),
577: .rf_ren_b_o ( rf_ren_b ),
578: `endif
579: .rf_waddr_id_o ( rf_waddr_id ),
580: .rf_wdata_id_o ( rf_wdata_id ),
581: .rf_we_id_o ( rf_we_id ),
582:
583: .rf_waddr_wb_i ( rf_waddr_wb ),
584: .rf_wdata_fwd_wb_i ( rf_wdata_fwd_wb ),
585: .rf_write_wb_i ( rf_write_wb ),
586:
587: .en_wb_o ( en_wb ),
588: .instr_type_wb_o ( instr_type_wb ),
589: .ready_wb_i ( ready_wb ),
590: .outstanding_load_wb_i ( outstanding_load_wb ),
591: .outstanding_store_wb_i ( outstanding_store_wb ),
592:
593: // Performance Counters
594: .perf_jump_o ( perf_jump ),
595: .perf_branch_o ( perf_branch ),
596: .perf_tbranch_o ( perf_tbranch ),
597: .perf_dside_wait_o ( perf_dside_wait ),
598: .perf_mul_wait_o ( perf_mul_wait ),
599: .perf_div_wait_o ( perf_div_wait ),
600: .instr_id_done_o ( instr_id_done ),
601: .instr_id_done_compressed_o ( instr_id_done_compressed )
602: );
603:
604: // for RVFI only
605: assign unused_illegal_insn_id = illegal_insn_id;
606:
607: ibex_ex_block #(
608: .RV32M ( RV32M ),
609: .RV32B ( RV32B ),
610: .BranchTargetALU ( BranchTargetALU ),
611: .MultiplierImplementation ( MultiplierImplementation )
612: ) ex_block_i (
613: .clk_i ( clk ),
614: .rst_ni ( rst_ni ),
615:
616: // ALU signal from ID stage
617: .alu_operator_i ( alu_operator_ex ),
618: .alu_operand_a_i ( alu_operand_a_ex ),
619: .alu_operand_b_i ( alu_operand_b_ex ),
620: .alu_instr_first_cycle_i ( instr_first_cycle_id ),
621:
622: // Branch target ALU signal from ID stage
623: .bt_a_operand_i ( bt_a_operand ),
624: .bt_b_operand_i ( bt_b_operand ),
625:
626: // Multipler/Divider signal from ID stage
627: .multdiv_operator_i ( multdiv_operator_ex ),
628: .mult_en_i ( mult_en_ex ),
629: .div_en_i ( div_en_ex ),
630: .mult_sel_i ( mult_sel_ex ),
631: .div_sel_i ( div_sel_ex ),
632: .multdiv_signed_mode_i ( multdiv_signed_mode_ex ),
633: .multdiv_operand_a_i ( multdiv_operand_a_ex ),
634: .multdiv_operand_b_i ( multdiv_operand_b_ex ),
635: .multdiv_ready_id_i ( multdiv_ready_id ),
636: .data_ind_timing_i ( data_ind_timing ),
637:
638: // Intermediate value register
639: .imd_val_we_o ( imd_val_we_ex ),
640: .imd_val_d_o ( imd_val_d_ex ),
641: .imd_val_q_i ( imd_val_q_ex ),
642:
643: // Outputs
644: .alu_adder_result_ex_o ( alu_adder_result_ex ), // to LSU
645: .result_ex_o ( result_ex ), // to ID
646:
647: .branch_target_o ( branch_target_ex ), // to IF
648: .branch_decision_o ( branch_decision ), // to ID
649:
650: .ex_valid_o ( ex_valid )
651: );
652:
653: /////////////////////
654: // Load/store unit //
655: /////////////////////
656:
657: assign data_req_o = data_req_out & ~pmp_req_err[PMP_D];
658:
659: ibex_load_store_unit load_store_unit_i (
660: .clk_i ( clk ),
661: .rst_ni ( rst_ni ),
662:
663: // data interface
664: .data_req_o ( data_req_out ),
665: .data_gnt_i ( data_gnt_i ),
666: .data_rvalid_i ( data_rvalid_i ),
667: .data_err_i ( data_err_i ),
668: .data_pmp_err_i ( pmp_req_err[PMP_D] ),
669:
670: .data_addr_o ( data_addr_o ),
671: .data_we_o ( data_we_o ),
672: .data_be_o ( data_be_o ),
673: .data_wdata_o ( data_wdata_o ),
674: .data_rdata_i ( data_rdata_i ),
675:
676: // signals to/from ID/EX stage
677: .lsu_we_i ( lsu_we ),
678: .lsu_type_i ( lsu_type ),
679: .lsu_wdata_i ( lsu_wdata ),
680: .lsu_sign_ext_i ( lsu_sign_ext ),
681:
682: .lsu_rdata_o ( rf_wdata_lsu ),
683: .lsu_rdata_valid_o ( rf_we_lsu ),
684: .lsu_req_i ( lsu_req ),
685: .lsu_req_done_o ( lsu_req_done ),
686:
687: .adder_result_ex_i ( alu_adder_result_ex ),
688:
689: .addr_incr_req_o ( lsu_addr_incr_req ),
690: .addr_last_o ( lsu_addr_last ),
691:
692:
693: .lsu_resp_valid_o ( lsu_resp_valid ),
694:
695: // exception signals
696: .load_err_o ( lsu_load_err ),
697: .store_err_o ( lsu_store_err ),
698:
699: .busy_o ( lsu_busy ),
700:
701: .perf_load_o ( perf_load ),
702: .perf_store_o ( perf_store )
703: );
704:
705: ibex_wb_stage #(
706: .WritebackStage ( WritebackStage )
707: ) wb_stage_i (
708: .clk_i ( clk_i ),
709: .rst_ni ( rst_ni ),
710: .en_wb_i ( en_wb ),
711: .instr_type_wb_i ( instr_type_wb ),
712: .pc_id_i ( pc_id ),
713:
714: .ready_wb_o ( ready_wb ),
715: .rf_write_wb_o ( rf_write_wb ),
716: .outstanding_load_wb_o ( outstanding_load_wb ),
717: .outstanding_store_wb_o ( outstanding_store_wb ),
718: .pc_wb_o ( pc_wb ),
719:
720: .rf_waddr_id_i ( rf_waddr_id ),
721: .rf_wdata_id_i ( rf_wdata_id ),
722: .rf_we_id_i ( rf_we_id ),
723:
724: .rf_wdata_lsu_i ( rf_wdata_lsu ),
725: .rf_we_lsu_i ( rf_we_lsu ),
726:
727: .rf_wdata_fwd_wb_o ( rf_wdata_fwd_wb ),
728:
729: .rf_waddr_wb_o ( rf_waddr_wb ),
730: .rf_wdata_wb_o ( rf_wdata_wb ),
731: .rf_we_wb_o ( rf_we_wb ),
732:
733: .lsu_resp_valid_i ( lsu_resp_valid ),
734:
735: .instr_done_wb_o ( instr_done_wb )
736: );
737:
738: ibex_register_file #(
739: .RV32E (RV32E),
740: .DataWidth (32),
741: .DummyInstructions (DummyInstructions)
742: ) register_file_i (
743: .clk_i ( clk_i ),
744: .rst_ni ( rst_ni ),
745:
746: .test_en_i ( test_en_i ),
747: .dummy_instr_id_i ( dummy_instr_id ),
748:
749: // Read port a
750: .raddr_a_i ( rf_raddr_a ),
751: .rdata_a_o ( rf_rdata_a ),
752: // Read port b
753: .raddr_b_i ( rf_raddr_b ),
754: .rdata_b_o ( rf_rdata_b ),
755: // write port
756: .waddr_a_i ( rf_waddr_wb ),
757: .wdata_a_i ( rf_wdata_wb ),
758: .we_a_i ( rf_we_wb )
759: );
760:
761: // Explict INC_ASSERT block to avoid unused signal lint warnings were asserts are not included
762: `ifdef INC_ASSERT
763: // Signals used for assertions only
764: logic outstanding_load_resp;
765: logic outstanding_store_resp;
766:
767: logic outstanding_load_id;
768: logic outstanding_store_id;
769:
770: assign outstanding_load_id = id_stage_i.instr_executing & id_stage_i.lsu_req_dec & ~id_stage_i.lsu_we;
771: assign outstanding_store_id = id_stage_i.instr_executing & id_stage_i.lsu_req_dec & id_stage_i.lsu_we;
772:
773: if (WritebackStage) begin
774: // When the writeback stage is present a load/store could be in ID or WB. A Load/store in ID can
775: // see a response before it moves to WB when it is unaligned otherwise we should only see
776: // a response when load/store is in WB.
777: assign outstanding_load_resp = outstanding_load_wb |
778: (outstanding_load_id & load_store_unit_i.split_misaligned_access);
779:
780: assign outstanding_store_resp = outstanding_store_wb |
781: (outstanding_store_id & load_store_unit_i.split_misaligned_access);
782:
783: // When writing back the result of a load, the load must have made it to writeback
784: `ASSERT(NoMemRFWriteWithoutPendingLoad, rf_we_lsu |-> outstanding_load_wb, clk_i, !rst_ni)
785: end else begin
786: // Without writeback stage only look into whether load or store is in ID to determine if
787: // a response is expected.
788: assign outstanding_load_resp = outstanding_load_id;
789: assign outstanding_store_resp = outstanding_store_id;
790:
791: `ASSERT(NoMemRFWriteWithoutPendingLoad, rf_we_lsu |-> outstanding_load_id, clk_i, !rst_ni)
792: end
793:
794: `ASSERT(NoMemResponseWithoutPendingAccess,
795: data_rvalid_i |-> outstanding_load_resp | outstanding_store_resp, clk_i, !rst_ni)
796: `endif
797:
798: ////////////////////////
799: // RF (Register File) //
800: ////////////////////////
801: `ifdef RVFI
802: assign rvfi_rd_addr_wb = rf_waddr_wb;
803: assign rvfi_rd_wdata_wb = rf_we_wb ? rf_wdata_wb : rf_wdata_lsu;
804: assign rvfi_rd_we_wb = rf_we_wb | rf_we_lsu;
805: `endif
806:
807:
808: /////////////////////////////////////////
809: // CSRs (Control and Status Registers) //
810: /////////////////////////////////////////
811:
812: assign csr_wdata = alu_operand_a_ex;
813: assign csr_addr = csr_num_e'(csr_access ? alu_operand_b_ex[11:0] : 12'b0);
814:
815: ibex_cs_registers #(
816: .DbgTriggerEn ( DbgTriggerEn ),
817: .DataIndTiming ( DataIndTiming ),
818: .DummyInstructions ( DummyInstructions ),
819: .ICache ( ICache ),
820: .MHPMCounterNum ( MHPMCounterNum ),
821: .MHPMCounterWidth ( MHPMCounterWidth ),
822: .PMPEnable ( PMPEnable ),
823: .PMPGranularity ( PMPGranularity ),
824: .PMPNumRegions ( PMPNumRegions ),
825: .RV32E ( RV32E ),
826: .RV32M ( RV32M )
827: ) cs_registers_i (
828: .clk_i ( clk ),
829: .rst_ni ( rst_ni ),
830:
831: // Hart ID from outside
832: .hart_id_i ( hart_id_i ),
833: .priv_mode_id_o ( priv_mode_id ),
834: .priv_mode_if_o ( priv_mode_if ),
835: .priv_mode_lsu_o ( priv_mode_lsu ),
836:
837: // mtvec
838: .csr_mtvec_o ( csr_mtvec ),
839: .csr_mtvec_init_i ( csr_mtvec_init ),
840: .boot_addr_i ( boot_addr_i ),
841:
842: // Interface to CSRs ( SRAM like )
843: .csr_access_i ( csr_access ),
844: .csr_addr_i ( csr_addr ),
845: .csr_wdata_i ( csr_wdata ),
846: .csr_op_i ( csr_op ),
847: .csr_op_en_i ( csr_op_en ),
848: .csr_rdata_o ( csr_rdata ),
849:
850: // Interrupt related control signals
851: .irq_software_i ( irq_software_i ),
852: .irq_timer_i ( irq_timer_i ),
853: .irq_external_i ( irq_external_i ),
854: .irq_fast_i ( irq_fast_i ),
855: .nmi_mode_i ( nmi_mode ),
856: .irq_pending_o ( irq_pending ),
857: .irqs_o ( irqs ),
858: .csr_mstatus_mie_o ( csr_mstatus_mie ),
859: .csr_mstatus_tw_o ( csr_mstatus_tw ),
860: .csr_mepc_o ( csr_mepc ),
861:
862: // PMP
863: .csr_pmp_cfg_o ( csr_pmp_cfg ),
864: .csr_pmp_addr_o ( csr_pmp_addr ),
865:
866: // debug
867: .csr_depc_o ( csr_depc ),
868: .debug_mode_i ( debug_mode ),
869: .debug_cause_i ( debug_cause ),
870: .debug_csr_save_i ( debug_csr_save ),
871: .debug_single_step_o ( debug_single_step ),
872: .debug_ebreakm_o ( debug_ebreakm ),
873: .debug_ebreaku_o ( debug_ebreaku ),
874: .trigger_match_o ( trigger_match ),
875:
876: .pc_if_i ( pc_if ),
877: .pc_id_i ( pc_id ),
878: .pc_wb_i ( pc_wb ),
879:
880: .data_ind_timing_o ( data_ind_timing ),
881: .dummy_instr_en_o ( dummy_instr_en ),
882: .dummy_instr_mask_o ( dummy_instr_mask ),
883: .dummy_instr_seed_en_o ( dummy_instr_seed_en ),
884: .dummy_instr_seed_o ( dummy_instr_seed ),
885: .icache_enable_o ( icache_enable ),
886:
887: .csr_save_if_i ( csr_save_if ),
888: .csr_save_id_i ( csr_save_id ),
889: .csr_save_wb_i ( csr_save_wb ),
890: .csr_restore_mret_i ( csr_restore_mret_id ),
891: .csr_restore_dret_i ( csr_restore_dret_id ),
892: .csr_save_cause_i ( csr_save_cause ),
893: .csr_mcause_i ( exc_cause ),
894: .csr_mtval_i ( csr_mtval ),
895: .illegal_csr_insn_o ( illegal_csr_insn_id ),
896:
897: // performance counter related signals
898: .instr_ret_i ( instr_id_done ),
899: .instr_ret_compressed_i ( instr_id_done_compressed ),
900: .iside_wait_i ( perf_iside_wait ),
901: .jump_i ( perf_jump ),
902: .branch_i ( perf_branch ),
903: .branch_taken_i ( perf_tbranch ),
904: .mem_load_i ( perf_load ),
905: .mem_store_i ( perf_store ),
906: .dside_wait_i ( perf_dside_wait ),
907: .mul_wait_i ( perf_mul_wait ),
908: .div_wait_i ( perf_div_wait )
909: );
910:
911: // These assertions are in top-level as instr_valid_id required as the enable term
912: `ASSERT(IbexCsrOpValid, instr_valid_id |-> csr_op inside {
913: CSR_OP_READ,
914: CSR_OP_WRITE,
915: CSR_OP_SET,
916: CSR_OP_CLEAR
917: })
918: `ASSERT_KNOWN_IF(IbexCsrWdataIntKnown, cs_registers_i.csr_wdata_int, csr_op_en)
919:
920: if (PMPEnable) begin : g_pmp
921: logic [33:0] pmp_req_addr [PMP_NUM_CHAN];
922: pmp_req_e pmp_req_type [PMP_NUM_CHAN];
923: priv_lvl_e pmp_priv_lvl [PMP_NUM_CHAN];
924:
925: assign pmp_req_addr[PMP_I] = {2'b00,instr_addr_o[31:0]};
926: assign pmp_req_type[PMP_I] = PMP_ACC_EXEC;
927: assign pmp_priv_lvl[PMP_I] = priv_mode_if;
928: assign pmp_req_addr[PMP_D] = {2'b00,data_addr_o[31:0]};
929: assign pmp_req_type[PMP_D] = data_we_o ? PMP_ACC_WRITE : PMP_ACC_READ;
930: assign pmp_priv_lvl[PMP_D] = priv_mode_lsu;
931:
932: ibex_pmp #(
933: .PMPGranularity ( PMPGranularity ),
934: .PMPNumChan ( PMP_NUM_CHAN ),
935: .PMPNumRegions ( PMPNumRegions )
936: ) pmp_i (
937: .clk_i ( clk ),
938: .rst_ni ( rst_ni ),
939: // Interface to CSRs
940: .csr_pmp_cfg_i ( csr_pmp_cfg ),
941: .csr_pmp_addr_i ( csr_pmp_addr ),
942: .priv_mode_i ( pmp_priv_lvl ),
943: // Access checking channels
944: .pmp_req_addr_i ( pmp_req_addr ),
945: .pmp_req_type_i ( pmp_req_type ),
946: .pmp_req_err_o ( pmp_req_err )
947: );
948: end else begin : g_no_pmp
949: // Unused signal tieoff
950: priv_lvl_e unused_priv_lvl_if, unused_priv_lvl_ls;
951: logic [33:0] unused_csr_pmp_addr [PMPNumRegions];
952: pmp_cfg_t unused_csr_pmp_cfg [PMPNumRegions];
953: assign unused_priv_lvl_if = priv_mode_if;
954: assign unused_priv_lvl_ls = priv_mode_lsu;
955: assign unused_csr_pmp_addr = csr_pmp_addr;
956: assign unused_csr_pmp_cfg = csr_pmp_cfg;
957:
958: // Output tieoff
959: assign pmp_req_err[PMP_I] = 1'b0;
960: assign pmp_req_err[PMP_D] = 1'b0;
961: end
962:
963: `ifdef RVFI
964: // When writeback stage is present RVFI information is emitted when instruction is finished in
965: // third stage but some information must be captured whilst the instruction is in the second
966: // stage. Without writeback stage RVFI information is all emitted when instruction retires in
967: // second stage. RVFI outputs are all straight from flops. So 2 stage pipeline requires a single
968: // set of flops (instr_info => RVFI_out), 3 stage pipeline requires two sets (instr_info => wb
969: // => RVFI_out)
970: localparam RVFI_STAGES = WritebackStage ? 2 : 1;
971:
972: logic rvfi_stage_valid [RVFI_STAGES-1:0];
973: logic [63:0] rvfi_stage_order [RVFI_STAGES-1:0];
974: logic [31:0] rvfi_stage_insn [RVFI_STAGES-1:0];
975: logic rvfi_stage_trap [RVFI_STAGES-1:0];
976: logic rvfi_stage_halt [RVFI_STAGES-1:0];
977: logic rvfi_stage_intr [RVFI_STAGES-1:0];
978: logic [ 1:0] rvfi_stage_mode [RVFI_STAGES-1:0];
979: logic [ 1:0] rvfi_stage_ixl [RVFI_STAGES-1:0];
980: logic [ 4:0] rvfi_stage_rs1_addr [RVFI_STAGES-1:0];
981: logic [ 4:0] rvfi_stage_rs2_addr [RVFI_STAGES-1:0];
982: logic [ 4:0] rvfi_stage_rs3_addr [RVFI_STAGES-1:0];
983: logic [31:0] rvfi_stage_rs1_rdata [RVFI_STAGES-1:0];
984: logic [31:0] rvfi_stage_rs2_rdata [RVFI_STAGES-1:0];
985: logic [31:0] rvfi_stage_rs3_rdata [RVFI_STAGES-1:0];
986: logic [ 4:0] rvfi_stage_rd_addr [RVFI_STAGES-1:0];
987: logic [31:0] rvfi_stage_rd_wdata [RVFI_STAGES-1:0];
988: logic [31:0] rvfi_stage_pc_rdata [RVFI_STAGES-1:0];
989: logic [31:0] rvfi_stage_pc_wdata [RVFI_STAGES-1:0];
990: logic [31:0] rvfi_stage_mem_addr [RVFI_STAGES-1:0];
991: logic [ 3:0] rvfi_stage_mem_rmask [RVFI_STAGES-1:0];
992: logic [ 3:0] rvfi_stage_mem_wmask [RVFI_STAGES-1:0];
993: logic [31:0] rvfi_stage_mem_rdata [RVFI_STAGES-1:0];
994: logic [31:0] rvfi_stage_mem_wdata [RVFI_STAGES-1:0];
995:
996: logic rvfi_stage_valid_d [RVFI_STAGES-1:0];
997:
998: assign rvfi_valid = rvfi_stage_valid [RVFI_STAGES-1];
999: assign rvfi_order = rvfi_stage_order [RVFI_STAGES-1];
1000: assign rvfi_insn = rvfi_stage_insn [RVFI_STAGES-1];
1001: assign rvfi_trap = rvfi_stage_trap [RVFI_STAGES-1];
1002: assign rvfi_halt = rvfi_stage_halt [RVFI_STAGES-1];
1003: assign rvfi_intr = rvfi_stage_intr [RVFI_STAGES-1];
1004: assign rvfi_mode = rvfi_stage_mode [RVFI_STAGES-1];
1005: assign rvfi_ixl = rvfi_stage_ixl [RVFI_STAGES-1];
1006: assign rvfi_rs1_addr = rvfi_stage_rs1_addr [RVFI_STAGES-1];
1007: assign rvfi_rs2_addr = rvfi_stage_rs2_addr [RVFI_STAGES-1];
1008: assign rvfi_rs3_addr = rvfi_stage_rs3_addr [RVFI_STAGES-1];
1009: assign rvfi_rs1_rdata = rvfi_stage_rs1_rdata[RVFI_STAGES-1];
1010: assign rvfi_rs2_rdata = rvfi_stage_rs2_rdata[RVFI_STAGES-1];
1011: assign rvfi_rs3_rdata = rvfi_stage_rs3_rdata[RVFI_STAGES-1];
1012: assign rvfi_rd_addr = rvfi_stage_rd_addr [RVFI_STAGES-1];
1013: assign rvfi_rd_wdata = rvfi_stage_rd_wdata [RVFI_STAGES-1];
1014: assign rvfi_pc_rdata = rvfi_stage_pc_rdata [RVFI_STAGES-1];
1015: assign rvfi_pc_wdata = rvfi_stage_pc_wdata [RVFI_STAGES-1];
1016: assign rvfi_mem_addr = rvfi_stage_mem_addr [RVFI_STAGES-1];
1017: assign rvfi_mem_rmask = rvfi_stage_mem_rmask[RVFI_STAGES-1];
1018: assign rvfi_mem_wmask = rvfi_stage_mem_wmask[RVFI_STAGES-1];
1019: assign rvfi_mem_rdata = rvfi_stage_mem_rdata[RVFI_STAGES-1];
1020: assign rvfi_mem_wdata = rvfi_stage_mem_wdata[RVFI_STAGES-1];
1021:
1022: if (WritebackStage) begin
1023: logic unused_instr_new_id;
1024:
1025: assign unused_instr_new_id = instr_new_id;
1026:
1027: // With writeback stage first RVFI stage buffers instruction information captured in ID/EX
1028: // awaiting instruction retirement and RF Write data/Mem read data whilst instruction is in WB
1029: // So first stage becomes valid when instruction leaves ID/EX stage and remains valid until
1030: // instruction leaves WB
1031: assign rvfi_stage_valid_d[0] = (instr_id_done & ~dummy_instr_id) |
1032: (rvfi_stage_valid[0] & ~instr_done_wb);
1033: // Second stage is output stage so simple valid cycle after instruction leaves WB (and so has
1034: // retired)
1035: assign rvfi_stage_valid_d[1] = instr_done_wb;
1036:
1037: // Signal new instruction in WB cycle after instruction leaves ID/EX (to enter WB)
1038: logic rvfi_instr_new_wb_q;
1039:
1040: assign rvfi_instr_new_wb = rvfi_instr_new_wb_q;
1041:
1042: always_ff @(posedge clk or negedge rst_ni) begin
1043: if (~rst_ni) begin
1044: rvfi_instr_new_wb_q <= 0;
1045: end else begin
1046: rvfi_instr_new_wb_q <= instr_id_done;
1047: end
1048: end
1049: end else begin
1050: // Without writeback stage first RVFI stage is output stage so simply valid the cycle after
1051: // instruction leaves ID/EX (and so has retired)
1052: assign rvfi_stage_valid_d[0] = instr_id_done & ~dummy_instr_id;
1053: // Without writeback stage signal new instr_new_wb when instruction enters ID/EX to correctly
1054: // setup register write signals
1055: assign rvfi_instr_new_wb = instr_new_id;
1056: end
1057:
1058: for (genvar i = 0;i < RVFI_STAGES; i = i + 1) begin : g_rvfi_stages
1059: always_ff @(posedge clk or negedge rst_ni) begin
1060: if (!rst_ni) begin
1061: rvfi_stage_halt[i] <= '0;
1062: rvfi_stage_trap[i] <= '0;
1063: rvfi_stage_intr[i] <= '0;
1064: rvfi_stage_order[i] <= '0;
1065: rvfi_stage_insn[i] <= '0;
1066: rvfi_stage_mode[i] <= {PRIV_LVL_M};
1067: rvfi_stage_ixl[i] <= CSR_MISA_MXL;
1068: rvfi_stage_rs1_addr[i] <= '0;
1069: rvfi_stage_rs2_addr[i] <= '0;
1070: rvfi_stage_rs3_addr[i] <= '0;
1071: rvfi_stage_pc_rdata[i] <= '0;
1072: rvfi_stage_pc_wdata[i] <= '0;
1073: rvfi_stage_mem_rmask[i] <= '0;
1074: rvfi_stage_mem_wmask[i] <= '0;
1075: rvfi_stage_valid[i] <= '0;
1076: rvfi_stage_rs1_rdata[i] <= '0;
1077: rvfi_stage_rs2_rdata[i] <= '0;
1078: rvfi_stage_rs3_rdata[i] <= '0;
1079: rvfi_stage_rd_wdata[i] <= '0;
1080: rvfi_stage_rd_addr[i] <= '0;
1081: rvfi_stage_mem_rdata[i] <= '0;
1082: rvfi_stage_mem_wdata[i] <= '0;
1083: rvfi_stage_mem_addr[i] <= '0;
1084: end else begin
1085: rvfi_stage_valid[i] <= rvfi_stage_valid_d[i];
1086:
1087: if (i == 0) begin
1088: if(instr_id_done) begin
1089: rvfi_stage_halt[i] <= '0;
1090: rvfi_stage_trap[i] <= illegal_insn_id;
1091: rvfi_stage_intr[i] <= rvfi_intr_d;
1092: rvfi_stage_order[i] <= rvfi_stage_order[i] + 64'(rvfi_stage_valid_d[i]);
1093: rvfi_stage_insn[i] <= rvfi_insn_id;
1094: rvfi_stage_mode[i] <= {priv_mode_id};
1095: rvfi_stage_ixl[i] <= CSR_MISA_MXL;
1096: rvfi_stage_rs1_addr[i] <= rvfi_rs1_addr_d;
1097: rvfi_stage_rs2_addr[i] <= rvfi_rs2_addr_d;
1098: rvfi_stage_rs3_addr[i] <= rvfi_rs3_addr_d;
1099: rvfi_stage_pc_rdata[i] <= pc_id;
1100: rvfi_stage_pc_wdata[i] <= pc_set ? branch_target_ex : pc_if;
1101: rvfi_stage_mem_rmask[i] <= rvfi_mem_mask_int;
1102: rvfi_stage_mem_wmask[i] <= data_we_o ? rvfi_mem_mask_int : 4'b0000;
1103: rvfi_stage_rs1_rdata[i] <= rvfi_rs1_data_d;
1104: rvfi_stage_rs2_rdata[i] <= rvfi_rs2_data_d;
1105: rvfi_stage_rs3_rdata[i] <= rvfi_rs3_data_d;
1106: rvfi_stage_rd_addr[i] <= rvfi_rd_addr_d;
1107: rvfi_stage_rd_wdata[i] <= rvfi_rd_wdata_d;
1108: rvfi_stage_mem_rdata[i] <= rvfi_mem_rdata_d;
1109: rvfi_stage_mem_wdata[i] <= rvfi_mem_wdata_d;
1110: rvfi_stage_mem_addr[i] <= rvfi_mem_addr_d;
1111: end
1112: end else begin
1113: if(instr_done_wb) begin
1114: rvfi_stage_halt[i] <= rvfi_stage_halt[i-1];
1115: rvfi_stage_trap[i] <= rvfi_stage_trap[i-1];
1116: rvfi_stage_intr[i] <= rvfi_stage_intr[i-1];
1117: rvfi_stage_order[i] <= rvfi_stage_order[i-1];
1118: rvfi_stage_insn[i] <= rvfi_stage_insn[i-1];
1119: rvfi_stage_mode[i] <= rvfi_stage_mode[i-1];
1120: rvfi_stage_ixl[i] <= rvfi_stage_ixl[i-1];
1121: rvfi_stage_rs1_addr[i] <= rvfi_stage_rs1_addr[i-1];
1122: rvfi_stage_rs2_addr[i] <= rvfi_stage_rs2_addr[i-1];
1123: rvfi_stage_rs3_addr[i] <= rvfi_stage_rs3_addr[i-1];
1124: rvfi_stage_pc_rdata[i] <= rvfi_stage_pc_rdata[i-1];
1125: rvfi_stage_pc_wdata[i] <= rvfi_stage_pc_wdata[i-1];
1126: rvfi_stage_mem_rmask[i] <= rvfi_stage_mem_rmask[i-1];
1127: rvfi_stage_mem_wmask[i] <= rvfi_stage_mem_wmask[i-1];
1128: rvfi_stage_rs1_rdata[i] <= rvfi_stage_rs1_rdata[i-1];
1129: rvfi_stage_rs2_rdata[i] <= rvfi_stage_rs2_rdata[i-1];
1130: rvfi_stage_rs3_rdata[i] <= rvfi_stage_rs3_rdata[i-1];
1131: rvfi_stage_mem_wdata[i] <= rvfi_stage_mem_wdata[i-1];
1132: rvfi_stage_mem_addr[i] <= rvfi_stage_mem_addr[i-1];
1133:
1134: // For 2 RVFI_STAGES/Writeback Stage ignore first stage flops for rd_addr, rd_wdata and
1135: // mem_rdata. For RF write addr/data actual write happens in writeback so capture
1136: // address/data there. For mem_rdata that is only available from the writeback stage.
1137: // Previous stage flops still exist in RTL as they are used by the non writeback config
1138: rvfi_stage_rd_addr[i] <= rvfi_rd_addr_d;
1139: rvfi_stage_rd_wdata[i] <= rvfi_rd_wdata_d;
1140: rvfi_stage_mem_rdata[i] <= rvfi_mem_rdata_d;
1141: end
1142: end
1143: end
1144: end
1145: end
1146:
1147:
1148: // Memory adddress/write data available first cycle of ld/st instruction from register read
1149: always_comb begin
1150: if (instr_first_cycle_id) begin
1151: rvfi_mem_addr_d = alu_adder_result_ex;
1152: rvfi_mem_wdata_d = lsu_wdata;
1153: end else begin
1154: rvfi_mem_addr_d = rvfi_mem_addr_q;
1155: rvfi_mem_wdata_d = rvfi_mem_wdata_q;
1156: end
1157: end
1158:
1159: // Capture read data from LSU when it becomes valid
1160: always_comb begin
1161: if (lsu_resp_valid) begin
1162: rvfi_mem_rdata_d = rf_wdata_lsu;
1163: end else begin
1164: rvfi_mem_rdata_d = rvfi_mem_rdata_q;
1165: end
1166: end
1167:
1168: always_ff @(posedge clk or negedge rst_ni) begin
1169: if (!rst_ni) begin
1170: rvfi_mem_addr_q <= '0;
1171: rvfi_mem_rdata_q <= '0;
1172: rvfi_mem_wdata_q <= '0;
1173: end else begin
1174: rvfi_mem_addr_q <= rvfi_mem_addr_d;
1175: rvfi_mem_rdata_q <= rvfi_mem_rdata_d;
1176: rvfi_mem_wdata_q <= rvfi_mem_wdata_d;
1177: end
1178: end
1179: // Byte enable based on data type
1180: always_comb begin
1181: unique case (lsu_type)
1182: 2'b00: rvfi_mem_mask_int = 4'b1111;
1183: 2'b01: rvfi_mem_mask_int = 4'b0011;
1184: 2'b10: rvfi_mem_mask_int = 4'b0001;
1185: default: rvfi_mem_mask_int = 4'b0000;
1186: endcase
1187: end
1188:
1189: always_comb begin
1190: if (instr_is_compressed_id) begin
1191: rvfi_insn_id = {16'b0, instr_rdata_c_id};
1192: end else begin
1193: rvfi_insn_id = instr_rdata_id;
1194: end
1195: end
1196:
1197: // Source registers 1 and 2 are read in the first instruction cycle
1198: // Source register 3 is read in the second instruction cycle.
1199: always_comb begin
1200: if (instr_first_cycle_id) begin
1201: rvfi_rs1_data_d = rf_ren_a ? multdiv_operand_a_ex : '0;
1202: rvfi_rs1_addr_d = rf_ren_a ? rf_raddr_a : '0;
1203: rvfi_rs2_data_d = rf_ren_b ? multdiv_operand_b_ex : '0;
1204: rvfi_rs2_addr_d = rf_ren_b ? rf_raddr_b : '0;
1205: rvfi_rs3_data_d = '0;
1206: rvfi_rs3_addr_d = '0;
1207: end else begin
1208: rvfi_rs1_data_d = rvfi_rs1_data_q;
1209: rvfi_rs1_addr_d = rvfi_rs1_addr_q;
1210: rvfi_rs2_data_d = rvfi_rs2_data_q;
1211: rvfi_rs2_addr_d = rvfi_rs2_addr_q;
1212: rvfi_rs3_data_d = multdiv_operand_a_ex;
1213: rvfi_rs3_addr_d = rf_raddr_a;
1214: end
1215: end
1216: always_ff @(posedge clk or negedge rst_ni) begin
1217: if (!rst_ni) begin
1218: rvfi_rs1_data_q <= '0;
1219: rvfi_rs1_addr_q <= '0;
1220: rvfi_rs2_data_q <= '0;
1221: rvfi_rs2_addr_q <= '0;
1222:
1223: end else begin
1224: rvfi_rs1_data_q <= rvfi_rs1_data_d;
1225: rvfi_rs1_addr_q <= rvfi_rs1_addr_d;
1226: rvfi_rs2_data_q <= rvfi_rs2_data_d;
1227: rvfi_rs2_addr_q <= rvfi_rs2_addr_d;
1228: end
1229: end
1230:
1231: always_comb begin
1232: if(rvfi_rd_we_wb) begin
1233: // Capture address/data of write to register file
1234: rvfi_rd_addr_d = rvfi_rd_addr_wb;
1235: // If writing to x0 zero write data as required by RVFI specification
1236: if(rvfi_rd_addr_wb == 5'b0) begin
1237: rvfi_rd_wdata_d = '0;
1238: end else begin
1239: rvfi_rd_wdata_d = rvfi_rd_wdata_wb;
1240: end
1241: end else if(rvfi_instr_new_wb) begin
1242: // If no RF write but new instruction in Writeback (when present) or ID/EX (when no writeback
1243: // stage present) then zero RF write address/data as required by RVFI specification
1244: rvfi_rd_addr_d = '0;
1245: rvfi_rd_wdata_d = '0;
1246: end else begin
1247: // Otherwise maintain previous value
1248: rvfi_rd_addr_d = rvfi_rd_addr_q;
1249: rvfi_rd_wdata_d = rvfi_rd_wdata_q;
1250: end
1251: end
1252:
1253: // RD write register is refreshed only once per cycle and
1254: // then it is kept stable for the cycle.
1255: always_ff @(posedge clk or negedge rst_ni) begin
1256: if (!rst_ni) begin
1257: rvfi_rd_addr_q <= '0;
1258: rvfi_rd_wdata_q <= '0;
1259: end else begin
1260: rvfi_rd_addr_q <= rvfi_rd_addr_d;
1261: rvfi_rd_wdata_q <= rvfi_rd_wdata_d;
1262: end
1263: end
1264:
1265: // rvfi_intr must be set for first instruction that is part of a trap handler.
1266: // On the first cycle of a new instruction see if a trap PC was set by the previous instruction,
1267: // otherwise maintain value.
1268: assign rvfi_intr_d = instr_first_cycle_id ? rvfi_set_trap_pc_q : rvfi_intr_q;
1269:
1270: always_comb begin
1271: rvfi_set_trap_pc_d = rvfi_set_trap_pc_q;
1272:
1273: if (pc_set && pc_mux_id == PC_EXC &&
1274: (exc_pc_mux_id == EXC_PC_EXC || exc_pc_mux_id == EXC_PC_IRQ)) begin
1275: // PC is set to enter a trap handler
1276: rvfi_set_trap_pc_d = 1'b1;
1277: end else if (rvfi_set_trap_pc_q && instr_id_done) begin
1278: // first instruction has been executed after PC is set to trap handler
1279: rvfi_set_trap_pc_d = 1'b0;
1280: end
1281: end
1282:
1283: always_ff @(posedge clk or negedge rst_ni) begin
1284: if (!rst_ni) begin
1285: rvfi_set_trap_pc_q <= 1'b0;
1286: rvfi_intr_q <= 1'b0;
1287: end else begin
1288: rvfi_set_trap_pc_q <= rvfi_set_trap_pc_d;
1289: rvfi_intr_q <= rvfi_intr_d;
1290: end
1291: end
1292:
1293: `endif
1294:
1295: endmodule
1296: