hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv Cov: 100%

   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: /**
   7:  * Main controller of the processor
   8:  */
   9: module ibex_controller (
  10:     input  logic                  clk_i,
  11:     input  logic                  rst_ni,
  12: 
  13:     input  logic                  fetch_enable_i,        // start decoding
  14:     output logic                  ctrl_busy_o,           // core is busy processing instrs
  15: 
  16:     // decoder related signals
  17:     input  logic                  illegal_insn_i,        // decoder has an invalid instr
  18:     input  logic                  ecall_insn_i,          // decoder has ECALL instr
  19:     input  logic                  mret_insn_i,           // decoder has MRET instr
  20:     input  logic                  dret_insn_i,           // decoder has DRET instr
  21:     input  logic                  wfi_insn_i,            // decoder has WFI instr
  22:     input  logic                  ebrk_insn_i,           // decoder has EBREAK instr
  23:     input  logic                  csr_pipe_flush_i,      // do CSR-related pipeline flush
  24: 
  25:     // from IF-ID pipeline stage
  26:     input  logic                  instr_valid_i,         // instr from IF-ID reg is valid
  27:     input  logic [31:0]           instr_i,               // instr from IF-ID reg, for mtval
  28:     input  logic [15:0]           instr_compressed_i,    // instr from IF-ID reg, for mtval
  29:     input  logic                  instr_is_compressed_i, // instr from IF-ID reg is compressed
  30:     input  logic                  instr_fetch_err_i,     // instr from IF-ID reg has error
  31:     input  logic [31:0]           pc_id_i,               // instr from IF-ID reg address
  32: 
  33:     // to IF-ID pipeline stage
  34:     output logic                  instr_valid_clear_o,   // kill instr in IF-ID reg
  35:     output logic                  id_in_ready_o,         // ID stage is ready for new instr
  36: 
  37:     // to prefetcher
  38:     output logic                  instr_req_o,           // start fetching instructions
  39:     output logic                  pc_set_o,              // jump to address set by pc_mux
  40:     output ibex_pkg::pc_sel_e     pc_mux_o,              // IF stage fetch address selector
  41:                                                          // (boot, normal, exception...)
  42:     output ibex_pkg::exc_pc_sel_e exc_pc_mux_o,          // IF stage selector for exception PC
  43:     output ibex_pkg::exc_cause_e  exc_cause_o,           // for IF stage, CSRs
  44: 
  45:     // LSU
  46:     input  logic [31:0]           lsu_addr_last_i,       // for mtval
  47:     input  logic                  load_err_i,
  48:     input  logic                  store_err_i,
  49: 
  50:     // jump/branch signals
  51:     input  logic                  branch_set_i,          // branch taken set signal
  52:     input  logic                  jump_set_i,            // jump taken set signal
  53: 
  54:     // interrupt signals
  55:     input  logic                  csr_mstatus_mie_i,     // M-mode interrupt enable bit
  56:     input  logic                  csr_msip_i,            // software interrupt pending
  57:     input  logic                  csr_mtip_i,            // timer interrupt pending
  58:     input  logic                  csr_meip_i,            // external interrupt pending
  59:     input  logic [14:0]           csr_mfip_i,            // fast interrupt pending
  60:     input  logic                  irq_pending_i,         // interrupt request pending
  61:     input  logic                  irq_nm_i,              // non-maskeable interrupt
  62:     output logic                  nmi_mode_o,            // core executing NMI handler
  63: 
  64:     // debug signals
  65:     input  logic                  debug_req_i,
  66:     output ibex_pkg::dbg_cause_e  debug_cause_o,
  67:     output logic                  debug_csr_save_o,
  68:     output logic                  debug_mode_o,
  69:     input  logic                  debug_single_step_i,
  70:     input  logic                  debug_ebreakm_i,
  71:     input  logic                  debug_ebreaku_i,
  72:     input  logic                  trigger_match_i,
  73: 
  74:     output logic                  csr_save_if_o,
  75:     output logic                  csr_save_id_o,
  76:     output logic                  csr_restore_mret_id_o,
  77:     output logic                  csr_restore_dret_id_o,
  78:     output logic                  csr_save_cause_o,
  79:     output logic [31:0]           csr_mtval_o,
  80:     input  ibex_pkg::priv_lvl_e   priv_mode_i,
  81:     input  logic                  csr_mstatus_tw_i,
  82: 
  83:     // stall signals
  84:     input  logic                  stall_lsu_i,
  85:     input  logic                  stall_multdiv_i,
  86:     input  logic                  stall_jump_i,
  87:     input  logic                  stall_branch_i,
  88: 
  89:     // performance monitors
  90:     output logic                  perf_jump_o,           // we are executing a jump
  91:                                                          // instruction (j, jr, jal, jalr)
  92:     output logic                  perf_tbranch_o         // we are executing a taken branch
  93:                                                          // instruction
  94: );
  95:   import ibex_pkg::*;
  96: 
  97:   // FSM state encoding
  98:   typedef enum logic [3:0] {
  99:     RESET, BOOT_SET, WAIT_SLEEP, SLEEP, FIRST_FETCH, DECODE, FLUSH,
 100:     IRQ_TAKEN, DBG_TAKEN_IF, DBG_TAKEN_ID
 101:   } ctrl_fsm_e;
 102: 
 103:   ctrl_fsm_e ctrl_fsm_cs, ctrl_fsm_ns;
 104: 
 105:   logic nmi_mode_q, nmi_mode_d;
 106:   logic debug_mode_q, debug_mode_d;
 107:   logic load_err_q, load_err_d;
 108:   logic store_err_q, store_err_d;
 109:   logic exc_req_q, exc_req_d;
 110:   logic illegal_insn_q, illegal_insn_d;
 111: 
 112:   logic stall;
 113:   logic halt_if;
 114:   logic flush_id;
 115:   logic illegal_dret;
 116:   logic illegal_umode;
 117:   logic exc_req_lsu;
 118:   logic special_req;
 119:   logic enter_debug_mode;
 120:   logic ebreak_into_debug;
 121:   logic handle_irq;
 122: 
 123:   logic [3:0] mfip_id;
 124:   logic       unused_csr_mtip;
 125: 
 126:   logic ecall_insn;
 127:   logic mret_insn;
 128:   logic dret_insn;
 129:   logic wfi_insn;
 130:   logic ebrk_insn;
 131:   logic csr_pipe_flush;
 132:   logic instr_fetch_err;
 133: 
 134: `ifndef SYNTHESIS
 135:   // synopsys translate_off
 136:   // make sure we are called later so that we do not generate messages for
 137:   // glitches
 138:   always_ff @(negedge clk_i) begin
 139:     // print warning in case of decoding errors
 140:     if ((ctrl_fsm_cs == DECODE) && instr_valid_i && !instr_fetch_err_i && illegal_insn_d) begin
 141:       $display("%t: Illegal instruction (hart %0x) at PC 0x%h: 0x%h", $time, ibex_core.hart_id_i,
 142:                ibex_id_stage.pc_id_i, ibex_id_stage.instr_rdata_i);
 143:     end
 144:   end
 145:   // synopsys translate_on
 146: `endif
 147: 
 148:   ////////////////
 149:   // Exceptions //
 150:   ////////////////
 151: 
 152:   assign load_err_d  = load_err_i;
 153:   assign store_err_d = store_err_i;
 154: 
 155:   // Decoder doesn't take instr_valid into account, factor it in here.
 156:   assign ecall_insn      = ecall_insn_i      & instr_valid_i;
 157:   assign mret_insn       = mret_insn_i       & instr_valid_i;
 158:   assign dret_insn       = dret_insn_i       & instr_valid_i;
 159:   assign wfi_insn        = wfi_insn_i        & instr_valid_i;
 160:   assign ebrk_insn       = ebrk_insn_i       & instr_valid_i;
 161:   assign csr_pipe_flush  = csr_pipe_flush_i  & instr_valid_i;
 162:   assign instr_fetch_err = instr_fetch_err_i & instr_valid_i;
 163: 
 164:   // "Executing DRET outside of Debug Mode causes an illegal instruction exception."
 165:   // [Debug Spec v0.13.2, p.41]
 166:   assign illegal_dret = dret_insn & ~debug_mode_q;
 167: 
 168:   // Some instructions can only be executed in M-Mode
 169:   assign illegal_umode = (priv_mode_i != PRIV_LVL_M) &
 170:                          // MRET must be in M-Mode. TW means trap WFI to M-Mode.
 171:                          (mret_insn | (csr_mstatus_tw_i & wfi_insn));
 172: 
 173:   // This is recorded in the illegal_insn_q flop to help timing.  Specifically
 174:   // it is needed to break the path from ibex_cs_registers/illegal_csr_insn_o
 175:   // to pc_set_o.  Clear when controller is in FLUSH so it won't remain set
 176:   // once illegal instruction is handled.
 177:   assign illegal_insn_d = (illegal_insn_i | illegal_dret | illegal_umode) & (ctrl_fsm_cs != FLUSH);
 178: 
 179:   // exception requests
 180:   // requests are flopped in exc_req_q.  This is cleared when controller is in
 181:   // the FLUSH state so the cycle following exc_req_q won't remain set for an
 182:   // exception request that has just been handled.
 183:   assign exc_req_d = (ecall_insn | ebrk_insn | illegal_insn_d | instr_fetch_err) &
 184:                      (ctrl_fsm_cs != FLUSH);
 185: 
 186:   // LSU exception requests
 187:   assign exc_req_lsu = store_err_i | load_err_i;
 188: 
 189:   // special requests: special instructions, pipeline flushes, exceptions...
 190:   assign special_req = mret_insn | dret_insn | wfi_insn | csr_pipe_flush |
 191:       exc_req_d | exc_req_lsu;
 192: 
 193:   ////////////////
 194:   // Interrupts //
 195:   ////////////////
 196: 
 197:   // Enter debug mode due to an external debug_req_i or because the core is in
 198:   // single step mode (dcsr.step == 1). Single step must be qualified with
 199:   // instruction valid otherwise the core will immediately enter debug mode
 200:   // due to a recently flushed IF (or a delay in an instruction returning from
 201:   // memory) before it has had anything to single step.
 202:   // Also enter debug mode on a trigger match (hardware breakpoint)
 203:   assign enter_debug_mode = (debug_req_i | (debug_single_step_i & instr_valid_i) |
 204:                              trigger_match_i) & ~debug_mode_q;
 205: 
 206:   // Set when an ebreak should enter debug mode rather than jump to exception
 207:   // handler
 208:   assign ebreak_into_debug = priv_mode_i == PRIV_LVL_M ? debug_ebreakm_i :
 209:                              priv_mode_i == PRIV_LVL_U ? debug_ebreaku_i :
 210:                                                          1'b0;
 211: 
 212:   // interrupts including NMI are ignored while in debug mode [Debug Spec v0.13.2, p.39]
 213:   assign handle_irq       = ~debug_mode_q &
 214:       ((irq_nm_i & ~nmi_mode_q) | (irq_pending_i & csr_mstatus_mie_i));
 215: 
 216:   // generate ID of fast interrupts, highest priority to highest ID
 217:   always_comb begin : gen_mfip_id
 218:     if      (csr_mfip_i[14]) mfip_id = 4'd14;
 219:     else if (csr_mfip_i[13]) mfip_id = 4'd13;
 220:     else if (csr_mfip_i[12]) mfip_id = 4'd12;
 221:     else if (csr_mfip_i[11]) mfip_id = 4'd11;
 222:     else if (csr_mfip_i[10]) mfip_id = 4'd10;
 223:     else if (csr_mfip_i[ 9]) mfip_id = 4'd9;
 224:     else if (csr_mfip_i[ 8]) mfip_id = 4'd8;
 225:     else if (csr_mfip_i[ 7]) mfip_id = 4'd7;
 226:     else if (csr_mfip_i[ 6]) mfip_id = 4'd6;
 227:     else if (csr_mfip_i[ 5]) mfip_id = 4'd5;
 228:     else if (csr_mfip_i[ 5]) mfip_id = 4'd5;
 229:     else if (csr_mfip_i[ 4]) mfip_id = 4'd4;
 230:     else if (csr_mfip_i[ 3]) mfip_id = 4'd3;
 231:     else if (csr_mfip_i[ 2]) mfip_id = 4'd2;
 232:     else if (csr_mfip_i[ 1]) mfip_id = 4'd1;
 233:     else                     mfip_id = 4'd0;
 234:   end
 235: 
 236:   assign unused_csr_mtip = csr_mtip_i;
 237: 
 238:   /////////////////////
 239:   // Core controller //
 240:   /////////////////////
 241: 
 242:   always_comb begin
 243:     // Default values
 244:     instr_req_o           = 1'b1;
 245: 
 246:     csr_save_if_o         = 1'b0;
 247:     csr_save_id_o         = 1'b0;
 248:     csr_restore_mret_id_o = 1'b0;
 249:     csr_restore_dret_id_o = 1'b0;
 250:     csr_save_cause_o      = 1'b0;
 251:     csr_mtval_o           = '0;
 252: 
 253:     pc_mux_o              = PC_BOOT;
 254:     pc_set_o              = 1'b0;
 255: 
 256:     exc_pc_mux_o          = EXC_PC_IRQ;
 257:     exc_cause_o           = EXC_CAUSE_INSN_ADDR_MISA; // = 6'h00
 258: 
 259:     ctrl_fsm_ns           = ctrl_fsm_cs;
 260: 
 261:     ctrl_busy_o           = 1'b1;
 262: 
 263:     halt_if               = 1'b0;
 264:     flush_id              = 1'b0;
 265: 
 266:     debug_csr_save_o      = 1'b0;
 267:     debug_cause_o         = DBG_CAUSE_EBREAK;
 268:     debug_mode_d          = debug_mode_q;
 269:     nmi_mode_d            = nmi_mode_q;
 270: 
 271:     perf_tbranch_o        = 1'b0;
 272:     perf_jump_o           = 1'b0;
 273: 
 274:     unique case (ctrl_fsm_cs)
 275:       RESET: begin
 276:         // just wait for fetch_enable
 277:         instr_req_o   = 1'b0;
 278:         pc_mux_o      = PC_BOOT;
 279:         pc_set_o      = 1'b1;
 280:         if (fetch_enable_i) begin
 281:           ctrl_fsm_ns = BOOT_SET;
 282:         end
 283:       end
 284: 
 285:       BOOT_SET: begin
 286:         // copy boot address to instr fetch address
 287:         instr_req_o   = 1'b1;
 288:         pc_mux_o      = PC_BOOT;
 289:         pc_set_o      = 1'b1;
 290: 
 291:         ctrl_fsm_ns = FIRST_FETCH;
 292:       end
 293: 
 294:       WAIT_SLEEP: begin
 295:         ctrl_busy_o   = 1'b0;
 296:         instr_req_o   = 1'b0;
 297:         halt_if       = 1'b1;
 298:         flush_id      = 1'b1;
 299:         ctrl_fsm_ns   = SLEEP;
 300:       end
 301: 
 302:       SLEEP: begin
 303:         // instruction in IF stage is already valid
 304:         // we begin execution when an interrupt has arrived
 305:         instr_req_o   = 1'b0;
 306:         halt_if       = 1'b1;
 307:         flush_id      = 1'b1;
 308: 
 309:         // normal execution flow
 310:         // in debug mode or single step mode we leave immediately (wfi=nop)
 311:         if (irq_nm_i || irq_pending_i || debug_req_i || debug_mode_q || debug_single_step_i) begin
 312:           ctrl_fsm_ns = FIRST_FETCH;
 313:         end else begin
 314:           // Make sure clock remains disabled.
 315:           ctrl_busy_o = 1'b0;
 316:         end
 317:       end
 318: 
 319:       FIRST_FETCH: begin
 320:         // Stall because of IF miss
 321:         if (id_in_ready_o) begin
 322:           ctrl_fsm_ns = DECODE;
 323:         end
 324: 
 325:         // handle interrupts
 326:         if (handle_irq) begin
 327:           // This assumes that the pipeline is always flushed before
 328:           // going to sleep.
 329:           ctrl_fsm_ns = IRQ_TAKEN;
 330:           halt_if     = 1'b1;
 331:           flush_id    = 1'b1;
 332:         end
 333: 
 334:         // enter debug mode
 335:         if (enter_debug_mode) begin
 336:           ctrl_fsm_ns = DBG_TAKEN_IF;
 337:           // Halt IF only for now, ID will be flushed in DBG_TAKEN_IF as the
 338:           // ID state is needed for correct debug mode entry
 339:           halt_if     = 1'b1;
 340:         end
 341:       end
 342: 
 343:       DECODE: begin
 344:         // normal operating mode of the ID stage, in case of debug and interrupt requests,
 345:         // priorities are as follows (lower number == higher priority)
 346:         // 1. currently running (multicycle) instructions and exceptions caused by these
 347:         // 2. debug requests
 348:         // 3. interrupt requests
 349: 
 350:         if (instr_valid_i) begin
 351: 
 352:           // get ready for special instructions, exceptions, pipeline flushes
 353:           if (special_req) begin
 354:             // Halt IF but don't flush ID. This leaves a valid instruction in
 355:             // ID so controller can determine appropriate action in the
 356:             // FLUSH state.
 357:             ctrl_fsm_ns = FLUSH;
 358:             halt_if     = 1'b1;
 359:           // set PC in IF stage to branch or jump target
 360:           end else if (branch_set_i || jump_set_i) begin
 361:             pc_mux_o       = PC_JUMP;
 362:             pc_set_o       = 1'b1;
 363: 
 364:             perf_tbranch_o = branch_set_i;
 365:             perf_jump_o    = jump_set_i;
 366:           end
 367: 
 368:           // If entering debug mode or handling an IRQ the core needs to wait
 369:           // until the current instruction has finished executing. Stall IF
 370:           // during that time.
 371:           if ((enter_debug_mode || handle_irq) && stall) begin
 372:             halt_if = 1'b1;
 373:           end
 374:         end // instr_valid_i
 375: 
 376:         if (!stall && !special_req) begin
 377:           if (enter_debug_mode) begin
 378:             // enter debug mode
 379:             ctrl_fsm_ns = DBG_TAKEN_IF;
 380:             // Halt IF only for now, ID will be flushed in DBG_TAKEN_IF as the
 381:             // ID state is needed for correct debug mode entry
 382:             halt_if     = 1'b1;
 383:           end else if (handle_irq) begin
 384:             // handle interrupt (not in debug mode)
 385:             ctrl_fsm_ns = IRQ_TAKEN;
 386:             halt_if     = 1'b1;
 387:             flush_id    = 1'b1;
 388:           end
 389:         end
 390: 
 391:       end // DECODE
 392: 
 393:       IRQ_TAKEN: begin
 394:         if (handle_irq) begin
 395:           pc_mux_o         = PC_EXC;
 396:           pc_set_o         = 1'b1;
 397:           exc_pc_mux_o     = EXC_PC_IRQ;
 398: 
 399:           csr_save_if_o    = 1'b1;
 400:           csr_save_cause_o = 1'b1;
 401: 
 402:           // interrupt priorities according to Privileged Spec v1.11 p.31
 403:           if (irq_nm_i && !nmi_mode_q) begin
 404:             exc_cause_o = EXC_CAUSE_IRQ_NM;
 405:             nmi_mode_d  = 1'b1; // enter NMI mode
 406:           end else if (csr_mfip_i != 15'b0) begin
 407:             // generate exception cause ID from fast interrupt ID:
 408:             // - first bit distinguishes interrupts from exceptions,
 409:             // - second bit adds 16 to fast interrupt ID
 410:             // for example EXC_CAUSE_IRQ_FAST_0 = {1'b1, 5'd16}
 411:             exc_cause_o = exc_cause_e'({2'b11, mfip_id});
 412:           end else if (csr_meip_i) begin
 413:             exc_cause_o = EXC_CAUSE_IRQ_EXTERNAL_M;
 414:           end else if (csr_msip_i) begin
 415:             exc_cause_o = EXC_CAUSE_IRQ_SOFTWARE_M;
 416:           end else begin // csr_mtip_i
 417:             exc_cause_o = EXC_CAUSE_IRQ_TIMER_M;
 418:           end
 419:         end
 420: 
 421:         ctrl_fsm_ns = DECODE;
 422:       end
 423: 
 424:       DBG_TAKEN_IF: begin
 425:         // enter debug mode and save PC in IF to dpc
 426:         // jump to debug exception handler in debug memory
 427:         if (debug_single_step_i || debug_req_i || trigger_match_i) begin
 428:           flush_id         = 1'b1;
 429:           pc_mux_o         = PC_EXC;
 430:           pc_set_o         = 1'b1;
 431:           exc_pc_mux_o     = EXC_PC_DBD;
 432: 
 433:           csr_save_if_o    = 1'b1;
 434:           debug_csr_save_o = 1'b1;
 435: 
 436:           csr_save_cause_o = 1'b1;
 437:           if (trigger_match_i) begin
 438:             debug_cause_o = DBG_CAUSE_TRIGGER;
 439:           end else if (debug_single_step_i) begin
 440:             debug_cause_o = DBG_CAUSE_STEP;
 441:           end else begin
 442:             debug_cause_o = DBG_CAUSE_HALTREQ;
 443:           end
 444: 
 445:           // enter debug mode
 446:           debug_mode_d = 1'b1;
 447:         end
 448: 
 449:         ctrl_fsm_ns  = DECODE;
 450:       end
 451: 
 452:       DBG_TAKEN_ID: begin
 453:         // enter debug mode and save PC in ID to dpc, used when encountering
 454:         // 1. EBREAK during debug mode
 455:         // 2. EBREAK with forced entry into debug mode (ebreakm or ebreaku set).
 456:         // regular ebreak's go through FLUSH.
 457:         //
 458:         // for 1. do not update dcsr and dpc, for 2. do so [Debug Spec v0.13.2, p.39]
 459:         // jump to debug exception handler in debug memory
 460:         flush_id     = 1'b1;
 461:         pc_mux_o     = PC_EXC;
 462:         pc_set_o     = 1'b1;
 463:         exc_pc_mux_o = EXC_PC_DBD;
 464: 
 465:         // update dcsr and dpc
 466:         if (ebreak_into_debug && !debug_mode_q) begin // ebreak with forced entry
 467: 
 468:           // dpc (set to the address of the EBREAK, i.e. set to PC in ID stage)
 469:           csr_save_cause_o = 1'b1;
 470:           csr_save_id_o    = 1'b1;
 471: 
 472:           // dcsr
 473:           debug_csr_save_o = 1'b1;
 474:           debug_cause_o    = DBG_CAUSE_EBREAK;
 475:         end
 476: 
 477:         // enter debug mode
 478:         debug_mode_d = 1'b1;
 479: 
 480:         ctrl_fsm_ns  = DECODE;
 481:       end
 482: 
 483:       FLUSH: begin
 484:         // flush the pipeline
 485:         halt_if     = 1'b1;
 486:         flush_id    = 1'b1;
 487:         ctrl_fsm_ns = DECODE;
 488: 
 489:         // exceptions: set exception PC, save PC and exception cause
 490:         // exc_req_lsu is high for one clock cycle only (in DECODE)
 491:         if (exc_req_q || store_err_q || load_err_q) begin
 492:           pc_set_o         = 1'b1;
 493:           pc_mux_o         = PC_EXC;
 494:           exc_pc_mux_o     = debug_mode_q ? EXC_PC_DBG_EXC : EXC_PC_EXC;
 495:           csr_save_id_o    = 1'b1;
 496:           csr_save_cause_o = 1'b1;
 497: 
 498:           // set exception registers, priorities according to Table 3.7 of Privileged Spec v1.11
 499:           if (instr_fetch_err) begin
 500:             exc_cause_o = EXC_CAUSE_INSTR_ACCESS_FAULT;
 501:             csr_mtval_o = pc_id_i;
 502: 
 503:           end else if (illegal_insn_q) begin
 504:             exc_cause_o = EXC_CAUSE_ILLEGAL_INSN;
 505:             csr_mtval_o = instr_is_compressed_i ? {16'b0, instr_compressed_i} : instr_i;
 506: 
 507:           end else if (ecall_insn) begin
 508:             exc_cause_o = (priv_mode_i == PRIV_LVL_M) ? EXC_CAUSE_ECALL_MMODE :
 509:                                                         EXC_CAUSE_ECALL_UMODE;
 510: 
 511:           end else if (ebrk_insn) begin
 512:             if (debug_mode_q | ebreak_into_debug) begin
 513:               /*
 514:                * EBREAK in debug mode re-enters debug mode
 515:                *
 516:                * "The only exception is EBREAK. When that is executed in Debug
 517:                * Mode, it halts the hart again but without updating dpc or
 518:                * dcsr." [Debug Spec v0.13.2, p.39]
 519:                */
 520: 
 521:               /*
 522:                * dcsr.ebreakm == 1:
 523:                * "EBREAK instructions in M-mode enter Debug Mode."
 524:                * [Debug Spec v0.13.2, p.42]
 525:                */
 526:               pc_set_o         = 1'b0;
 527:               csr_save_id_o    = 1'b0;
 528:               csr_save_cause_o = 1'b0;
 529:               ctrl_fsm_ns      = DBG_TAKEN_ID;
 530:               flush_id         = 1'b0;
 531:             end else begin
 532:               /*
 533:                * "The EBREAK instruction is used by debuggers to cause control
 534:                * to be transferred back to a debugging environment. It
 535:                * generates a breakpoint exception and performs no other
 536:                * operation. [...] ECALL and EBREAK cause the receiving
 537:                * privilege mode's epc register to be set to the address of the
 538:                * ECALL or EBREAK instruction itself, not the address of the
 539:                * following instruction." [Privileged Spec v1.11, p.40]
 540:                */
 541:               exc_cause_o      = EXC_CAUSE_BREAKPOINT;
 542:             end
 543: 
 544:           end else if (store_err_q) begin
 545:             exc_cause_o = EXC_CAUSE_STORE_ACCESS_FAULT;
 546:             csr_mtval_o = lsu_addr_last_i;
 547: 
 548:           end else begin // load_err_q
 549:             exc_cause_o = EXC_CAUSE_LOAD_ACCESS_FAULT;
 550:             csr_mtval_o = lsu_addr_last_i;
 551:           end
 552: 
 553:         end else begin
 554:           // special instructions and pipeline flushes
 555:           if (mret_insn) begin
 556:             pc_mux_o              = PC_ERET;
 557:             pc_set_o              = 1'b1;
 558:             csr_restore_mret_id_o = 1'b1;
 559:             if (nmi_mode_q) begin
 560:               nmi_mode_d          = 1'b0; // exit NMI mode
 561:             end
 562:           end else if (dret_insn) begin
 563:             pc_mux_o              = PC_DRET;
 564:             pc_set_o              = 1'b1;
 565:             debug_mode_d          = 1'b0;
 566:             csr_restore_dret_id_o = 1'b1;
 567:           end else if (wfi_insn) begin
 568:             ctrl_fsm_ns           = WAIT_SLEEP;
 569:           end else if (csr_pipe_flush && handle_irq) begin
 570:             // start handling IRQs when doing CSR-related pipeline flushes
 571:             ctrl_fsm_ns           = IRQ_TAKEN;
 572:           end
 573:         end // exc_req_q
 574: 
 575:         // Entering debug mode due to either single step or debug_req. Ensure
 576:         // registers are set for exception but then enter debug handler rather
 577:         // than exception handler [Debug Spec v0.13.2, p.44]
 578:         // Leave all other signals as is to ensure CSRs and PC get set as if
 579:         // core was entering exception handler, entry to debug mode will then
 580:         // see the appropriate state and setup dpc correctly.
 581:         if (enter_debug_mode) begin
 582:           ctrl_fsm_ns = DBG_TAKEN_IF;
 583:         end
 584:       end // FLUSH
 585: 
 586:       default: begin
 587:         instr_req_o = 1'b0;
 588:         ctrl_fsm_ns = RESET;
 589:       end
 590:     endcase
 591:   end
 592: 
 593:   // signal to CSR when in debug mode
 594:   assign debug_mode_o = debug_mode_q;
 595: 
 596:   // signal to CSR when in an NMI handler (for nested exception handling)
 597:   assign nmi_mode_o = nmi_mode_q;
 598: 
 599:   ///////////////////
 600:   // Stall control //
 601:   ///////////////////
 602: 
 603:   // if high, current instr needs at least one more cycle to finish after the current cycle
 604:   // if low, current instr finishes in current cycle
 605:   // multicycle instructions have this set except during the last cycle
 606:   assign stall = stall_lsu_i | stall_multdiv_i | stall_jump_i | stall_branch_i;
 607: 
 608:   // signal to IF stage that ID stage is ready for next instr
 609:   assign id_in_ready_o       = ~stall & ~halt_if;
 610: 
 611:   // kill instr in IF-ID pipeline reg that are done, or if a
 612:   // multicycle instr causes an exception for example
 613:   // halt_if is another kind of stall, where the instr_valid bit must remain
 614:   // set (unless flush_id is set also). It cannot be factored directly into
 615:   // stall as this causes a combinational loop.
 616:   assign instr_valid_clear_o = ~(stall | halt_if) | flush_id;
 617: 
 618:   // update registers
 619:   always_ff @(posedge clk_i or negedge rst_ni) begin : update_regs
 620:     if (!rst_ni) begin
 621:       ctrl_fsm_cs    <= RESET;
 622:       nmi_mode_q     <= 1'b0;
 623:       debug_mode_q   <= 1'b0;
 624:       load_err_q     <= 1'b0;
 625:       store_err_q    <= 1'b0;
 626:       exc_req_q      <= 1'b0;
 627:       illegal_insn_q <= 1'b0;
 628:     end else begin
 629:       ctrl_fsm_cs    <= ctrl_fsm_ns;
 630:       nmi_mode_q     <= nmi_mode_d;
 631:       debug_mode_q   <= debug_mode_d;
 632:       load_err_q     <= load_err_d;
 633:       store_err_q    <= store_err_d;
 634:       exc_req_q      <= exc_req_d;
 635:       illegal_insn_q <= illegal_insn_d;
 636:     end
 637:   end
 638: 
 639:   ////////////////
 640:   // Assertions //
 641:   ////////////////
 642: 
 643:   // Selectors must be known/valid.
 644:   `ASSERT(IbexCtrlStateValid, ctrl_fsm_cs inside {
 645:       RESET, BOOT_SET, WAIT_SLEEP, SLEEP, FIRST_FETCH, DECODE, FLUSH,
 646:       IRQ_TAKEN, DBG_TAKEN_IF, DBG_TAKEN_ID
 647:       }, clk_i, !rst_ni)
 648: 
 649: endmodule
 650: