../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: