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: