../src/lowrisc_ibex_ibex_core_0.1/rtl/ibex_id_stage.sv Cov: 88.1%
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: /**
11: * Instruction Decode Stage
12: *
13: * Decode stage of the core. It decodes the instructions and hosts the register
14: * file.
15: */
16:
17: `include "prim_assert.sv"
18:
19: module ibex_id_stage #(
20: parameter bit RV32E = 0,
21: parameter bit RV32M = 1,
22: parameter bit RV32B = 0,
23: parameter bit DataIndTiming = 1'b0,
24: parameter bit BranchTargetALU = 0,
25: parameter bit SpecBranch = 0,
26: parameter bit WritebackStage = 0
27: ) (
28: input logic clk_i,
29: input logic rst_ni,
30:
31: input logic fetch_enable_i,
32: output logic ctrl_busy_o,
33: output logic illegal_insn_o,
34:
35: // Interface to IF stage
36: input logic instr_valid_i,
37: input logic [31:0] instr_rdata_i, // from IF-ID pipeline registers
38: input logic [31:0] instr_rdata_alu_i, // from IF-ID pipeline registers
39: input logic [15:0] instr_rdata_c_i, // from IF-ID pipeline registers
40: input logic instr_is_compressed_i,
41: output logic instr_req_o,
42: output logic instr_first_cycle_id_o,
43: output logic instr_valid_clear_o, // kill instr in IF-ID reg
44: output logic id_in_ready_o, // ID stage is ready for next instr
45: output logic icache_inval_o,
46:
47: // Jumps and branches
48: input logic branch_decision_i,
49:
50: // IF and ID stage signals
51: output logic pc_set_o,
52: output logic pc_set_spec_o,
53: output ibex_pkg::pc_sel_e pc_mux_o,
54: output ibex_pkg::exc_pc_sel_e exc_pc_mux_o,
55: output ibex_pkg::exc_cause_e exc_cause_o,
56:
57: input logic illegal_c_insn_i,
58: input logic instr_fetch_err_i,
59: input logic instr_fetch_err_plus2_i,
60:
61: input logic [31:0] pc_id_i,
62:
63: // Stalls
64: input logic ex_valid_i, // EX stage has valid output
65: input logic lsu_resp_valid_i, // LSU has valid output, or is done
66: // ALU
67: output ibex_pkg::alu_op_e alu_operator_ex_o,
68: output logic [31:0] alu_operand_a_ex_o,
69: output logic [31:0] alu_operand_b_ex_o,
70:
71: // Multicycle Operation Stage Register
72: input logic imd_val_we_ex_i,
73: input logic [33:0] imd_val_d_ex_i,
74: output logic [33:0] imd_val_q_ex_o,
75:
76: // Branch target ALU
77: output logic [31:0] bt_a_operand_o,
78: output logic [31:0] bt_b_operand_o,
79:
80: // MUL, DIV
81: output logic mult_en_ex_o,
82: output logic div_en_ex_o,
83: output logic mult_sel_ex_o,
84: output logic div_sel_ex_o,
85: output ibex_pkg::md_op_e multdiv_operator_ex_o,
86: output logic [1:0] multdiv_signed_mode_ex_o,
87: output logic [31:0] multdiv_operand_a_ex_o,
88: output logic [31:0] multdiv_operand_b_ex_o,
89: output logic multdiv_ready_id_o,
90:
91: // CSR
92: output logic csr_access_o,
93: output ibex_pkg::csr_op_e csr_op_o,
94: output logic csr_op_en_o,
95: output logic csr_save_if_o,
96: output logic csr_save_id_o,
97: output logic csr_save_wb_o,
98: output logic csr_restore_mret_id_o,
99: output logic csr_restore_dret_id_o,
100: output logic csr_save_cause_o,
101: output logic [31:0] csr_mtval_o,
102: input ibex_pkg::priv_lvl_e priv_mode_i,
103: input logic csr_mstatus_tw_i,
104: input logic illegal_csr_insn_i,
105: input logic data_ind_timing_i,
106:
107: // Interface to load store unit
108: output logic lsu_req_o,
109: output logic lsu_we_o,
110: output logic [1:0] lsu_type_o,
111: output logic lsu_sign_ext_o,
112: output logic [31:0] lsu_wdata_o,
113:
114: input logic lsu_req_done_i, // Data req to LSU is complete and
115: // instruction can move to writeback
116: // (only relevant where writeback stage is
117: // present)
118:
119: input logic lsu_addr_incr_req_i,
120: input logic [31:0] lsu_addr_last_i,
121:
122: // Interrupt signals
123: input logic csr_mstatus_mie_i,
124: input logic irq_pending_i,
125: input ibex_pkg::irqs_t irqs_i,
126: input logic irq_nm_i,
127: output logic nmi_mode_o,
128:
129: input logic lsu_load_err_i,
130: input logic lsu_store_err_i,
131:
132: // Debug Signal
133: output logic debug_mode_o,
134: output ibex_pkg::dbg_cause_e debug_cause_o,
135: output logic debug_csr_save_o,
136: input logic debug_req_i,
137: input logic debug_single_step_i,
138: input logic debug_ebreakm_i,
139: input logic debug_ebreaku_i,
140: input logic trigger_match_i,
141:
142: // Write back signal
143: input logic [31:0] result_ex_i,
144: input logic [31:0] csr_rdata_i,
145:
146: // Register file read
147: output logic [4:0] rf_raddr_a_o,
148: input logic [31:0] rf_rdata_a_i,
149: output logic [4:0] rf_raddr_b_o,
150: input logic [31:0] rf_rdata_b_i,
151: `ifdef RVFI
152: output logic rf_ren_a_o,
153: output logic rf_ren_b_o,
154: `endif
155:
156: // Register file write (via writeback)
157: output logic [4:0] rf_waddr_id_o,
158: output logic [31:0] rf_wdata_id_o,
159: output logic rf_we_id_o,
160:
161: // Register write information from writeback (for resolving data hazards)
162: input logic [4:0] rf_waddr_wb_i,
163: input logic [31:0] rf_wdata_fwd_wb_i,
164: input logic rf_write_wb_i,
165:
166: output logic en_wb_o,
167: output ibex_pkg::wb_instr_type_e instr_type_wb_o,
168: input logic ready_wb_i,
169: input logic outstanding_load_wb_i,
170: input logic outstanding_store_wb_i,
171:
172: // Performance Counters
173: output logic perf_jump_o, // executing a jump instr
174: output logic perf_branch_o, // executing a branch instr
175: output logic perf_tbranch_o, // executing a taken branch instr
176: output logic perf_dside_wait_o, // instruction in ID/EX is awaiting memory
177: // access to finish before proceeding
178: output logic perf_mul_wait_o,
179: output logic perf_div_wait_o,
180: output logic instr_id_done_o,
181: output logic instr_id_done_compressed_o
182: );
183:
184: import ibex_pkg::*;
185:
186: // Decoder/Controller, ID stage internal signals
187: logic illegal_insn_dec;
188: logic ebrk_insn;
189: logic mret_insn_dec;
190: logic dret_insn_dec;
191: logic ecall_insn_dec;
192: logic wfi_insn_dec;
193:
194: logic wb_exception;
195:
196: logic branch_in_dec;
197: logic branch_spec, branch_set_spec;
198: logic branch_set, branch_set_d;
199: logic branch_taken;
200: logic jump_in_dec;
201: logic jump_set_dec;
202: logic jump_set;
203:
204: logic instr_first_cycle;
205: logic instr_executing;
206: logic instr_done;
207: logic controller_run;
208: logic stall_ld_hz;
209: logic stall_mem;
210: logic lsu_req_in_id;
211: logic stall_multdiv;
212: logic stall_branch;
213: logic stall_jump;
214: logic stall_id;
215: logic stall_wb;
216: logic flush_id;
217: logic multicycle_done;
218:
219: // Immediate decoding and sign extension
220: logic [31:0] imm_i_type;
221: logic [31:0] imm_s_type;
222: logic [31:0] imm_b_type;
223: logic [31:0] imm_u_type;
224: logic [31:0] imm_j_type;
225: logic [31:0] zimm_rs1_type;
226:
227: logic [31:0] imm_a; // contains the immediate for operand b
228: logic [31:0] imm_b; // contains the immediate for operand b
229:
230: // Register file interface
231:
232: rf_wd_sel_e rf_wdata_sel;
233: logic rf_we_dec, rf_we_raw;
234: logic rf_ren_a, rf_ren_b;
235:
236: `ifdef RVFI
237: assign rf_ren_a_o = rf_ren_a;
238: assign rf_ren_b_o = rf_ren_b;
239: `endif
240:
241: logic [31:0] rf_rdata_a_fwd;
242: logic [31:0] rf_rdata_b_fwd;
243:
244: // ALU Control
245: alu_op_e alu_operator;
246: op_a_sel_e alu_op_a_mux_sel, alu_op_a_mux_sel_dec;
247: op_b_sel_e alu_op_b_mux_sel, alu_op_b_mux_sel_dec;
248: logic alu_multicycle_dec;
249: logic stall_alu;
250:
251: logic [33:0] imd_val_q;
252:
253: op_a_sel_e bt_a_mux_sel;
254: imm_b_sel_e bt_b_mux_sel;
255:
256: imm_a_sel_e imm_a_mux_sel;
257: imm_b_sel_e imm_b_mux_sel, imm_b_mux_sel_dec;
258:
259: // Multiplier Control
260: logic mult_en_id, mult_en_dec; // use integer multiplier
261: logic div_en_id, div_en_dec; // use integer division or reminder
262: logic multdiv_en_dec;
263: md_op_e multdiv_operator;
264: logic [1:0] multdiv_signed_mode;
265:
266: // Data Memory Control
267: logic lsu_we;
268: logic [1:0] lsu_type;
269: logic lsu_sign_ext;
270: logic lsu_req, lsu_req_dec;
271: logic data_req_allowed;
272:
273: // CSR control
274: logic csr_pipe_flush;
275:
276: logic [31:0] alu_operand_a;
277: logic [31:0] alu_operand_b;
278:
279: /////////////
280: // LSU Mux //
281: /////////////
282:
283: // Misaligned loads/stores result in two aligned loads/stores, compute second address
284: assign alu_op_a_mux_sel = lsu_addr_incr_req_i ? OP_A_FWD : alu_op_a_mux_sel_dec;
285: assign alu_op_b_mux_sel = lsu_addr_incr_req_i ? OP_B_IMM : alu_op_b_mux_sel_dec;
286: assign imm_b_mux_sel = lsu_addr_incr_req_i ? IMM_B_INCR_ADDR : imm_b_mux_sel_dec;
287:
288: ///////////////////
289: // Operand MUXES //
290: ///////////////////
291:
292: // Main ALU immediate MUX for Operand A
293: assign imm_a = (imm_a_mux_sel == IMM_A_Z) ? zimm_rs1_type : '0;
294:
295: // Main ALU MUX for Operand A
296: always_comb begin : alu_operand_a_mux
297: unique case (alu_op_a_mux_sel)
298: OP_A_REG_A: alu_operand_a = rf_rdata_a_fwd;
299: OP_A_FWD: alu_operand_a = lsu_addr_last_i;
300: OP_A_CURRPC: alu_operand_a = pc_id_i;
301: OP_A_IMM: alu_operand_a = imm_a;
302: default: alu_operand_a = pc_id_i;
303: endcase
304: end
305:
306: if (BranchTargetALU) begin : g_btalu_muxes
307: // Branch target ALU operand A mux
308: always_comb begin : bt_operand_a_mux
309: unique case (bt_a_mux_sel)
310: OP_A_REG_A: bt_a_operand_o = rf_rdata_a_fwd;
311: OP_A_CURRPC: bt_a_operand_o = pc_id_i;
312: default: bt_a_operand_o = pc_id_i;
313: endcase
314: end
315:
316: // Branch target ALU operand B mux
317: always_comb begin : bt_immediate_b_mux
318: unique case (bt_b_mux_sel)
319: IMM_B_I: bt_b_operand_o = imm_i_type;
320: IMM_B_B: bt_b_operand_o = imm_b_type;
321: IMM_B_J: bt_b_operand_o = imm_j_type;
322: IMM_B_INCR_PC: bt_b_operand_o = instr_is_compressed_i ? 32'h2 : 32'h4;
323: default: bt_b_operand_o = instr_is_compressed_i ? 32'h2 : 32'h4;
324: endcase
325: end
326:
327: // Reduced main ALU immediate MUX for Operand B
328: always_comb begin : immediate_b_mux
329: unique case (imm_b_mux_sel)
330: IMM_B_I: imm_b = imm_i_type;
331: IMM_B_S: imm_b = imm_s_type;
332: IMM_B_U: imm_b = imm_u_type;
333: IMM_B_INCR_PC: imm_b = instr_is_compressed_i ? 32'h2 : 32'h4;
334: IMM_B_INCR_ADDR: imm_b = 32'h4;
335: default: imm_b = 32'h4;
336: endcase
337: end
338: `ASSERT(IbexImmBMuxSelValid, instr_valid_i |-> imm_b_mux_sel inside {
339: IMM_B_I,
340: IMM_B_S,
341: IMM_B_U,
342: IMM_B_INCR_PC,
343: IMM_B_INCR_ADDR})
344: end else begin : g_nobtalu
345: op_a_sel_e unused_a_mux_sel;
346: imm_b_sel_e unused_b_mux_sel;
347:
348: assign unused_a_mux_sel = bt_a_mux_sel;
349: assign unused_b_mux_sel = bt_b_mux_sel;
350: assign bt_a_operand_o = '0;
351: assign bt_b_operand_o = '0;
352:
353: // Full main ALU immediate MUX for Operand B
354: always_comb begin : immediate_b_mux
355: unique case (imm_b_mux_sel)
356: IMM_B_I: imm_b = imm_i_type;
357: IMM_B_S: imm_b = imm_s_type;
358: IMM_B_B: imm_b = imm_b_type;
359: IMM_B_U: imm_b = imm_u_type;
360: IMM_B_J: imm_b = imm_j_type;
361: IMM_B_INCR_PC: imm_b = instr_is_compressed_i ? 32'h2 : 32'h4;
362: IMM_B_INCR_ADDR: imm_b = 32'h4;
363: default: imm_b = 32'h4;
364: endcase
365: end
366: `ASSERT(IbexImmBMuxSelValid, instr_valid_i |-> imm_b_mux_sel inside {
367: IMM_B_I,
368: IMM_B_S,
369: IMM_B_B,
370: IMM_B_U,
371: IMM_B_J,
372: IMM_B_INCR_PC,
373: IMM_B_INCR_ADDR})
374: end
375:
376: // ALU MUX for Operand B
377: assign alu_operand_b = (alu_op_b_mux_sel == OP_B_IMM) ? imm_b : rf_rdata_b_fwd;
378:
379: /////////////////////////////////////////
380: // Multicycle Operation Stage Register //
381: /////////////////////////////////////////
382:
383: always_ff @(posedge clk_i or negedge rst_ni) begin : intermediate_val_reg
384: if (!rst_ni) begin
385: imd_val_q <= '0;
386: end else if (imd_val_we_ex_i) begin
387: imd_val_q <= imd_val_d_ex_i;
388: end
389: end
390:
391: assign imd_val_q_ex_o = imd_val_q;
392:
393: ///////////////////////
394: // Register File MUX //
395: ///////////////////////
396:
397: // Suppress register write if there is an illegal CSR access or instruction is not executing
398: assign rf_we_id_o = rf_we_raw & instr_executing & ~illegal_csr_insn_i;
399:
400: // Register file write data mux
401: always_comb begin : rf_wdata_id_mux
402: unique case (rf_wdata_sel)
403: RF_WD_EX: rf_wdata_id_o = result_ex_i;
404: RF_WD_CSR: rf_wdata_id_o = csr_rdata_i;
405: default: rf_wdata_id_o = result_ex_i;
406: endcase;
407: end
408:
409: /////////////
410: // Decoder //
411: /////////////
412:
413: ibex_decoder #(
414: .RV32E ( RV32E ),
415: .RV32M ( RV32M ),
416: .RV32B ( RV32B ),
417: .BranchTargetALU ( BranchTargetALU )
418: ) decoder_i (
419: .clk_i ( clk_i ),
420: .rst_ni ( rst_ni ),
421:
422: // controller
423: .illegal_insn_o ( illegal_insn_dec ),
424: .ebrk_insn_o ( ebrk_insn ),
425: .mret_insn_o ( mret_insn_dec ),
426: .dret_insn_o ( dret_insn_dec ),
427: .ecall_insn_o ( ecall_insn_dec ),
428: .wfi_insn_o ( wfi_insn_dec ),
429: .jump_set_o ( jump_set_dec ),
430: .branch_taken_i ( branch_taken ),
431: .icache_inval_o ( icache_inval_o ),
432:
433: // from IF-ID pipeline register
434: .instr_first_cycle_i ( instr_first_cycle ),
435: .instr_rdata_i ( instr_rdata_i ),
436: .instr_rdata_alu_i ( instr_rdata_alu_i ),
437: .illegal_c_insn_i ( illegal_c_insn_i ),
438:
439: // immediates
440: .imm_a_mux_sel_o ( imm_a_mux_sel ),
441: .imm_b_mux_sel_o ( imm_b_mux_sel_dec ),
442: .bt_a_mux_sel_o ( bt_a_mux_sel ),
443: .bt_b_mux_sel_o ( bt_b_mux_sel ),
444:
445: .imm_i_type_o ( imm_i_type ),
446: .imm_s_type_o ( imm_s_type ),
447: .imm_b_type_o ( imm_b_type ),
448: .imm_u_type_o ( imm_u_type ),
449: .imm_j_type_o ( imm_j_type ),
450: .zimm_rs1_type_o ( zimm_rs1_type ),
451:
452: // register file
453: .rf_wdata_sel_o ( rf_wdata_sel ),
454: .rf_we_o ( rf_we_dec ),
455:
456: .rf_raddr_a_o ( rf_raddr_a_o ),
457: .rf_raddr_b_o ( rf_raddr_b_o ),
458: .rf_waddr_o ( rf_waddr_id_o ),
459: .rf_ren_a_o ( rf_ren_a ),
460: .rf_ren_b_o ( rf_ren_b ),
461:
462: // ALU
463: .alu_operator_o ( alu_operator ),
464: .alu_op_a_mux_sel_o ( alu_op_a_mux_sel_dec ),
465: .alu_op_b_mux_sel_o ( alu_op_b_mux_sel_dec ),
466: .alu_multicycle_o ( alu_multicycle_dec ),
467:
468: // MULT & DIV
469: .mult_en_o ( mult_en_dec ),
470: .div_en_o ( div_en_dec ),
471: .mult_sel_o ( mult_sel_ex_o ),
472: .div_sel_o ( div_sel_ex_o ),
473: .multdiv_operator_o ( multdiv_operator ),
474: .multdiv_signed_mode_o ( multdiv_signed_mode ),
475:
476: // CSRs
477: .csr_access_o ( csr_access_o ),
478: .csr_op_o ( csr_op_o ),
479:
480: // LSU
481: .data_req_o ( lsu_req_dec ),
482: .data_we_o ( lsu_we ),
483: .data_type_o ( lsu_type ),
484: .data_sign_extension_o ( lsu_sign_ext ),
485:
486: // jump/branches
487: .jump_in_dec_o ( jump_in_dec ),
488: .branch_in_dec_o ( branch_in_dec )
489: );
490:
491: /////////////////////////////////
492: // CSR-related pipline flushes //
493: /////////////////////////////////
494: always_comb begin : csr_pipeline_flushes
495: csr_pipe_flush = 1'b0;
496:
497: // A pipeline flush is needed to let the controller react after modifying certain CSRs:
498: // - When enabling interrupts, pending IRQs become visible to the controller only during
499: // the next cycle. If during that cycle the core disables interrupts again, it does not
500: // see any pending IRQs and consequently does not start to handle interrupts.
501: // - When modifying debug CSRs - TODO: Check if this is really needed
502: if (csr_op_en_o == 1'b1 && (csr_op_o == CSR_OP_WRITE || csr_op_o == CSR_OP_SET)) begin
503: if (csr_num_e'(instr_rdata_i[31:20]) == CSR_MSTATUS ||
504: csr_num_e'(instr_rdata_i[31:20]) == CSR_MIE) begin
505: csr_pipe_flush = 1'b1;
506: end
507: end else if (csr_op_en_o == 1'b1 && csr_op_o != CSR_OP_READ) begin
508: if (csr_num_e'(instr_rdata_i[31:20]) == CSR_DCSR ||
509: csr_num_e'(instr_rdata_i[31:20]) == CSR_DPC ||
510: csr_num_e'(instr_rdata_i[31:20]) == CSR_DSCRATCH0 ||
511: csr_num_e'(instr_rdata_i[31:20]) == CSR_DSCRATCH1) begin
512: csr_pipe_flush = 1'b1;
513: end
514: end
515: end
516:
517: ////////////////
518: // Controller //
519: ////////////////
520:
521: assign illegal_insn_o = instr_valid_i & (illegal_insn_dec | illegal_csr_insn_i);
522:
523: ibex_controller #(
524: .WritebackStage ( WritebackStage )
525: ) controller_i (
526: .clk_i ( clk_i ),
527: .rst_ni ( rst_ni ),
528:
529: .fetch_enable_i ( fetch_enable_i ),
530: .ctrl_busy_o ( ctrl_busy_o ),
531:
532: // decoder related signals
533: .illegal_insn_i ( illegal_insn_o ),
534: .ecall_insn_i ( ecall_insn_dec ),
535: .mret_insn_i ( mret_insn_dec ),
536: .dret_insn_i ( dret_insn_dec ),
537: .wfi_insn_i ( wfi_insn_dec ),
538: .ebrk_insn_i ( ebrk_insn ),
539: .csr_pipe_flush_i ( csr_pipe_flush ),
540:
541: // from IF-ID pipeline
542: .instr_valid_i ( instr_valid_i ),
543: .instr_i ( instr_rdata_i ),
544: .instr_compressed_i ( instr_rdata_c_i ),
545: .instr_is_compressed_i ( instr_is_compressed_i ),
546: .instr_fetch_err_i ( instr_fetch_err_i ),
547: .instr_fetch_err_plus2_i ( instr_fetch_err_plus2_i ),
548: .pc_id_i ( pc_id_i ),
549:
550: // to IF-ID pipeline
551: .instr_valid_clear_o ( instr_valid_clear_o ),
552: .id_in_ready_o ( id_in_ready_o ),
553: .controller_run_o ( controller_run ),
554:
555: // to prefetcher
556: .instr_req_o ( instr_req_o ),
557: .pc_set_o ( pc_set_o ),
558: .pc_set_spec_o ( pc_set_spec_o ),
559: .pc_mux_o ( pc_mux_o ),
560: .exc_pc_mux_o ( exc_pc_mux_o ),
561: .exc_cause_o ( exc_cause_o ),
562:
563: // LSU
564: .lsu_addr_last_i ( lsu_addr_last_i ),
565: .load_err_i ( lsu_load_err_i ),
566: .store_err_i ( lsu_store_err_i ),
567: .wb_exception_o ( wb_exception ),
568:
569: // jump/branch control
570: .branch_set_i ( branch_set ),
571: .branch_set_spec_i ( branch_set_spec ),
572: .jump_set_i ( jump_set ),
573:
574: // interrupt signals
575: .csr_mstatus_mie_i ( csr_mstatus_mie_i ),
576: .irq_pending_i ( irq_pending_i ),
577: .irqs_i ( irqs_i ),
578: .irq_nm_i ( irq_nm_i ),
579: .nmi_mode_o ( nmi_mode_o ),
580:
581: // CSR Controller Signals
582: .csr_save_if_o ( csr_save_if_o ),
583: .csr_save_id_o ( csr_save_id_o ),
584: .csr_save_wb_o ( csr_save_wb_o ),
585: .csr_restore_mret_id_o ( csr_restore_mret_id_o ),
586: .csr_restore_dret_id_o ( csr_restore_dret_id_o ),
587: .csr_save_cause_o ( csr_save_cause_o ),
588: .csr_mtval_o ( csr_mtval_o ),
589: .priv_mode_i ( priv_mode_i ),
590: .csr_mstatus_tw_i ( csr_mstatus_tw_i ),
591:
592: // Debug Signal
593: .debug_mode_o ( debug_mode_o ),
594: .debug_cause_o ( debug_cause_o ),
595: .debug_csr_save_o ( debug_csr_save_o ),
596: .debug_req_i ( debug_req_i ),
597: .debug_single_step_i ( debug_single_step_i ),
598: .debug_ebreakm_i ( debug_ebreakm_i ),
599: .debug_ebreaku_i ( debug_ebreaku_i ),
600: .trigger_match_i ( trigger_match_i ),
601:
602: // stall signals
603: .lsu_req_in_id_i ( lsu_req_in_id ),
604: .stall_id_i ( stall_id ),
605: .stall_wb_i ( stall_wb ),
606: .flush_id_o ( flush_id ),
607: .ready_wb_i ( ready_wb_i ),
608:
609: // Performance Counters
610: .perf_jump_o ( perf_jump_o ),
611: .perf_tbranch_o ( perf_tbranch_o )
612: );
613:
614: assign multdiv_en_dec = mult_en_dec | div_en_dec;
615:
616: assign lsu_req = instr_executing ? data_req_allowed & lsu_req_dec : 1'b0;
617: assign mult_en_id = instr_executing ? mult_en_dec : 1'b0;
618: assign div_en_id = instr_executing ? div_en_dec : 1'b0;
619:
620: assign lsu_req_o = lsu_req;
621: assign lsu_we_o = lsu_we;
622: assign lsu_type_o = lsu_type;
623: assign lsu_sign_ext_o = lsu_sign_ext;
624: assign lsu_wdata_o = rf_rdata_b_fwd;
625: // csr_op_en_o is set when CSR access should actually happen.
626: // csv_access_o is set when CSR access instruction is present and is used to compute whether a CSR
627: // access is illegal. A combinational loop would be created if csr_op_en_o was used along (as
628: // asserting it for an illegal csr access would result in a flush that would need to deassert it).
629: assign csr_op_en_o = csr_access_o & instr_executing & instr_id_done_o;
630:
631: assign alu_operator_ex_o = alu_operator;
632: assign alu_operand_a_ex_o = alu_operand_a;
633: assign alu_operand_b_ex_o = alu_operand_b;
634:
635: assign mult_en_ex_o = mult_en_id;
636: assign div_en_ex_o = div_en_id;
637:
638: assign multdiv_operator_ex_o = multdiv_operator;
639: assign multdiv_signed_mode_ex_o = multdiv_signed_mode;
640: assign multdiv_operand_a_ex_o = rf_rdata_a_fwd;
641: assign multdiv_operand_b_ex_o = rf_rdata_b_fwd;
642:
643: ////////////////////////
644: // Branch set control //
645: ////////////////////////
646:
647: if (BranchTargetALU && !DataIndTiming) begin : g_branch_set_direct
648: // Branch set fed straight to controller with branch target ALU
649: // (condition pass/fail used same cycle as generated instruction request)
650: assign branch_set = branch_set_d;
651: assign branch_set_spec = branch_spec;
652: end else begin : g_branch_set_flop
653: // Branch set flopped without branch target ALU, or in fixed time execution mode
654: // (condition pass/fail used next cycle where branch target is calculated)
655: logic branch_set_q;
656:
657: always_ff @(posedge clk_i or negedge rst_ni) begin
658: if (!rst_ni) begin
659: branch_set_q <= 1'b0;
660: end else begin
661: branch_set_q <= branch_set_d;
662: end
663: end
664:
665: // Branches always take two cycles in fixed time execution mode, with or without the branch
666: // target ALU (to avoid a path from the branch decision into the branch target ALU operand
667: // muxing).
668: assign branch_set = (BranchTargetALU && !data_ind_timing_i) ? branch_set_d : branch_set_q;
669: // Use the speculative branch signal when BTALU is enabled
670: assign branch_set_spec = (BranchTargetALU && !data_ind_timing_i) ? branch_spec : branch_set_q;
671: end
672:
673: // Branch condition is calculated in the first cycle and flopped for use in the second cycle
674: // (only used in fixed time execution mode to determine branch destination).
675: if (DataIndTiming) begin : g_sec_branch_taken
676: logic branch_taken_q;
677:
678: always_ff @(posedge clk_i or negedge rst_ni) begin
679: if (!rst_ni) begin
680: branch_taken_q <= 1'b0;
681: end else begin
682: branch_taken_q <= branch_decision_i;
683: end
684: end
685:
686: assign branch_taken = ~data_ind_timing_i | branch_taken_q;
687:
688: end else begin : g_nosec_branch_taken
689:
690: // Signal unused without fixed time execution mode - only taken branches will trigger branch_set
691: assign branch_taken = 1'b1;
692:
693: end
694:
695: // Holding branch_set/jump_set high for more than one cycle may not cause a functional issue but
696: // could generate needless prefetch buffer flushes and instruction fetches. ID/EX is designed such
697: // that this shouldn't ever happen.
698: `ASSERT(NeverDoubleBranch, branch_set |=> ~branch_set)
699: `ASSERT(NeverDoubleJump, jump_set |=> ~jump_set)
700:
701: ///////////////
702: // ID-EX FSM //
703: ///////////////
704:
705: typedef enum logic { FIRST_CYCLE, MULTI_CYCLE } id_fsm_e;
706: id_fsm_e id_fsm_q, id_fsm_d;
707:
708: always_ff @(posedge clk_i or negedge rst_ni) begin : id_pipeline_reg
709: if (!rst_ni) begin
710: id_fsm_q <= FIRST_CYCLE;
711: end else begin
712: id_fsm_q <= id_fsm_d;
713: end
714: end
715:
716: // ID/EX stage can be in two states, FIRST_CYCLE and MULTI_CYCLE. An instruction enters
717: // MULTI_CYCLE if it requires multiple cycles to complete regardless of stalls and other
718: // considerations. An instruction may be held in FIRST_CYCLE if it's unable to begin executing
719: // (this is controlled by instr_executing).
720:
721: always_comb begin
722: id_fsm_d = id_fsm_q;
723: rf_we_raw = rf_we_dec;
724: stall_multdiv = 1'b0;
725: stall_jump = 1'b0;
726: stall_branch = 1'b0;
727: stall_alu = 1'b0;
728: branch_set_d = 1'b0;
729: branch_spec = 1'b0;
730: jump_set = 1'b0;
731: perf_branch_o = 1'b0;
732:
733: if (instr_executing) begin
734: unique case (id_fsm_q)
735: FIRST_CYCLE: begin
736: unique case (1'b1)
737: lsu_req_dec: begin
738: if (!WritebackStage) begin
739: // LSU operation
740: id_fsm_d = MULTI_CYCLE;
741: end else begin
742: if(~lsu_req_done_i) begin
743: id_fsm_d = MULTI_CYCLE;
744: end
745: end
746: end
747: multdiv_en_dec: begin
748: // MUL or DIV operation
749: if (~ex_valid_i) begin
750: // When single-cycle multiply is configured mul can finish in the first cycle so
751: // only enter MULTI_CYCLE state if a result isn't immediately available
752: id_fsm_d = MULTI_CYCLE;
753: rf_we_raw = 1'b0;
754: stall_multdiv = 1'b1;
755: end
756: end
757: branch_in_dec: begin
758: // cond branch operation
759: // All branches take two cycles in fixed time execution mode, regardless of branch
760: // condition.
761: id_fsm_d = (data_ind_timing_i || (!BranchTargetALU && branch_decision_i)) ?
762: MULTI_CYCLE : FIRST_CYCLE;
763: stall_branch = (~BranchTargetALU & branch_decision_i) | data_ind_timing_i;
764: branch_set_d = branch_decision_i | data_ind_timing_i;
765: // Speculative branch (excludes branch_decision_i)
766: branch_spec = SpecBranch ? 1'b1 : branch_decision_i;
767: perf_branch_o = 1'b1;
768: end
769: jump_in_dec: begin
770: // uncond branch operation
771: // BTALU means jumps only need one cycle
772: id_fsm_d = BranchTargetALU ? FIRST_CYCLE : MULTI_CYCLE;
773: stall_jump = ~BranchTargetALU;
774: jump_set = jump_set_dec;
775: end
776: alu_multicycle_dec: begin
777: stall_alu = 1'b1;
778: id_fsm_d = MULTI_CYCLE;
779: rf_we_raw = 1'b0;
780: end
781: default: begin
782: id_fsm_d = FIRST_CYCLE;
783: end
784: endcase
785: end
786:
787: MULTI_CYCLE: begin
788: if(multdiv_en_dec) begin
789: rf_we_raw = rf_we_dec & ex_valid_i;
790: end
791:
792: if (multicycle_done & ready_wb_i) begin
793: id_fsm_d = FIRST_CYCLE;
794: end else begin
795: stall_multdiv = multdiv_en_dec;
796: stall_branch = branch_in_dec;
797: stall_jump = jump_in_dec;
798: end
799: end
800:
801: default: begin
802: id_fsm_d = FIRST_CYCLE;
803: end
804: endcase
805: end
806: end
807:
808: // Note for the two-stage configuration ready_wb_i is always set
809: assign multdiv_ready_id_o = ready_wb_i;
810:
811: `ASSERT(StallIDIfMulticycle, (id_fsm_q == FIRST_CYCLE) & (id_fsm_d == MULTI_CYCLE) |-> stall_id)
812:
813: // Stall ID/EX stage for reason that relates to instruction in ID/EX
814: assign stall_id = stall_ld_hz | stall_mem | stall_multdiv | stall_jump | stall_branch |
815: stall_alu;
816:
817: assign instr_done = ~stall_id & ~flush_id & instr_executing;
818:
819: if (WritebackStage) begin
820: assign multicycle_done = lsu_req_dec ? ~stall_mem : ex_valid_i;
821: end else begin
822: assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i;
823: end
824:
825: // Signal instruction in ID is in it's first cycle. It can remain in its
826: // first cycle if it is stalled.
827: assign instr_first_cycle = instr_valid_i & (id_fsm_q == FIRST_CYCLE);
828: // Used by RVFI to know when to capture register read data
829: // Used by ALU to access RS3 if ternary instruction.
830: assign instr_first_cycle_id_o = instr_first_cycle;
831:
832: if (WritebackStage) begin : gen_stall_mem
833: // Register read address matches write address in WB
834: logic rf_rd_a_wb_match;
835: logic rf_rd_b_wb_match;
836: // Hazard between registers being read and written
837: logic rf_rd_a_hz;
838: logic rf_rd_b_hz;
839:
840: logic outstanding_memory_access;
841:
842: logic instr_kill;
843:
844: // Is a memory access ongoing that isn't finishing this cycle
845: assign outstanding_memory_access = (outstanding_load_wb_i | outstanding_store_wb_i) &
846: ~lsu_resp_valid_i;
847:
848: // Can start a new memory access if any previous one has finished or is finishing
849: assign data_req_allowed = ~outstanding_memory_access;
850:
851: // Instruction won't execute because:
852: // - There is a pending exception in writeback
853: // The instruction in ID/EX will be flushed and the core will jump to an exception handler
854: // - The controller isn't running instructions
855: // This either happens in preparation for a flush and jump to an exception handler e.g. in
856: // response to an IRQ or debug request or whilst the core is sleeping or resetting/fetching
857: // first instruction in which case any valid instruction in ID/EX should be ignored.
858: // - There was an error on instruction fetch
859: assign instr_kill = instr_fetch_err_i |
860: wb_exception |
861: ~controller_run;
862:
863: // With writeback stage instructions must be prevented from executing if there is:
864: // - A load hazard
865: // - A pending memory access
866: // If it receives an error response this results in a precise exception from WB so ID/EX
867: // instruction must not execute until error response is known).
868: // - A load/store error
869: // This will cause a precise exception for the instruction in WB so ID/EX instruction must not
870: // execute
871: assign instr_executing = instr_valid_i &
872: ~instr_kill &
873: ~stall_ld_hz &
874: ~outstanding_memory_access;
875:
876: `ASSERT(IbexStallIfValidInstrNotExecuting,
877: instr_valid_i & ~instr_kill & ~instr_executing |-> stall_id)
878:
879: // Stall for reasons related to memory:
880: // * There is an outstanding memory access that won't resolve this cycle (need to wait to allow
881: // precise exceptions)
882: // * There is a load/store request not being granted or which is unaligned and waiting to issue
883: // a second request (needs to stay in ID for the address calculation)
884: assign stall_mem = instr_valid_i & (outstanding_memory_access | (lsu_req_dec & ~lsu_req_done_i));
885:
886: // If we stall a load in ID for any reason, it must not make an LSU request
887: // (otherwide we might issue two requests for the same instruction)
888: `ASSERT(IbexStallMemNoRequest,
889: instr_valid_i & lsu_req_dec & ~instr_done |-> ~lsu_req_done_i)
890:
891: // Indicate to the controller that an lsu req is in ID stage - we cannot handle interrupts or
892: // debug requests until the load/store completes
893: assign lsu_req_in_id = instr_valid_i & lsu_req_dec;
894:
895: assign rf_rd_a_wb_match = (rf_waddr_wb_i == rf_raddr_a_o) & |rf_raddr_a_o;
896: assign rf_rd_b_wb_match = (rf_waddr_wb_i == rf_raddr_b_o) & |rf_raddr_b_o;
897:
898: // If instruction is reading register that load will be writing stall in
899: // ID until load is complete. No need to stall when reading zero register.
900: assign rf_rd_a_hz = rf_rd_a_wb_match & rf_ren_a;
901: assign rf_rd_b_hz = rf_rd_b_wb_match & rf_ren_b;
902:
903: // If instruction is read register that writeback is writing forward writeback data to read
904: // data. Note this doesn't factor in load data as it arrives too late, such hazards are
905: // resolved via a stall (see above).
906: assign rf_rdata_a_fwd = rf_rd_a_wb_match & rf_write_wb_i ? rf_wdata_fwd_wb_i : rf_rdata_a_i;
907: assign rf_rdata_b_fwd = rf_rd_b_wb_match & rf_write_wb_i ? rf_wdata_fwd_wb_i : rf_rdata_b_i;
908:
909: assign stall_ld_hz = outstanding_load_wb_i & (rf_rd_a_hz | rf_rd_b_hz);
910:
911: assign instr_type_wb_o = ~lsu_req_dec ? WB_INSTR_OTHER :
912: lsu_we ? WB_INSTR_STORE :
913: WB_INSTR_LOAD;
914:
915: assign en_wb_o = instr_done;
916:
917: assign instr_id_done_o = en_wb_o & ready_wb_i;
918:
919: // Stall ID/EX as instruction in ID/EX cannot proceed to writeback yet
920: assign stall_wb = en_wb_o & ~ready_wb_i;
921:
922: assign perf_dside_wait_o = instr_valid_i & ~instr_kill & (outstanding_memory_access | stall_ld_hz);
923: end else begin
924:
925: assign data_req_allowed = instr_first_cycle;
926:
927: // Without Writeback Stage always stall the first cycle of a load/store.
928: // Then stall until it is complete
929: assign stall_mem = instr_valid_i & (lsu_req_dec & (~lsu_resp_valid_i | instr_first_cycle));
930:
931: // No load hazards without Writeback Stage
932: assign stall_ld_hz = 1'b0;
933: assign lsu_req_in_id = 1'b0;
934:
935: // Without writeback stage any valid instruction that hasn't seen an error will execute
936: assign instr_executing = instr_valid_i & ~instr_fetch_err_i & controller_run;
937:
938: `ASSERT(IbexStallIfValidInstrNotExecuting,
939: instr_valid_i & ~instr_fetch_err_i & ~instr_executing & controller_run |-> stall_id)
940:
941: // No data forwarding without writeback stage so always take source register data direct from
942: // register file
943: assign rf_rdata_a_fwd = rf_rdata_a_i;
944: assign rf_rdata_b_fwd = rf_rdata_b_i;
945:
946: // Unused Writeback stage only IO & wiring
947: // Assign inputs and internal wiring to unused signals to satisfy lint checks
948: // Tie-off outputs to constant values
949: logic unused_data_req_done_ex;
950: logic unused_lsu_load;
951: logic [4:0] unused_rf_waddr_wb;
952: logic unused_rf_write_wb;
953: logic unused_outstanding_load_wb;
954: logic unused_outstanding_store_wb;
955: logic unused_wb_exception;
956: logic unused_rf_ren_a, unused_rf_ren_b;
957: logic [31:0] unused_rf_wdata_fwd_wb;
958:
959: assign unused_data_req_done_ex = lsu_req_done_i;
960: assign unused_rf_waddr_wb = rf_waddr_wb_i;
961: assign unused_rf_write_wb = rf_write_wb_i;
962: assign unused_outstanding_load_wb = outstanding_load_wb_i;
963: assign unused_outstanding_store_wb = outstanding_store_wb_i;
964: assign unused_wb_exception = wb_exception;
965: assign unused_rf_ren_a = rf_ren_a;
966: assign unused_rf_ren_b = rf_ren_b;
967: assign unused_rf_wdata_fwd_wb = rf_wdata_fwd_wb_i;
968:
969: assign instr_type_wb_o = WB_INSTR_OTHER;
970: assign stall_wb = 1'b0;
971:
972: assign perf_dside_wait_o = instr_executing & lsu_req_dec & ~lsu_resp_valid_i;
973:
974: assign en_wb_o = 1'b0;
975: assign instr_id_done_o = instr_done;
976: end
977:
978: assign perf_mul_wait_o = stall_multdiv & mult_en_dec;
979: assign perf_div_wait_o = stall_multdiv & div_en_dec;
980:
981: assign instr_id_done_compressed_o = instr_id_done_o & instr_is_compressed_i;
982:
983: ////////////////
984: // Assertions //
985: ////////////////
986:
987: // Selectors must be known/valid.
988: `ASSERT_KNOWN_IF(IbexAluOpMuxSelKnown, alu_op_a_mux_sel, instr_valid_i)
989: `ASSERT(IbexAluAOpMuxSelValid, instr_valid_i |-> alu_op_a_mux_sel inside {
990: OP_A_REG_A,
991: OP_A_FWD,
992: OP_A_CURRPC,
993: OP_A_IMM})
994: `ASSERT_KNOWN_IF(IbexBTAluAOpMuxSelKnown, bt_a_mux_sel, instr_valid_i)
995: `ASSERT(IbexBTAluAOpMuxSelValid, instr_valid_i |-> bt_a_mux_sel inside {
996: OP_A_REG_A,
997: OP_A_CURRPC})
998: `ASSERT_KNOWN_IF(IbexBTAluBOpMuxSelKnown, bt_b_mux_sel, instr_valid_i)
999: `ASSERT(IbexBTAluBOpMuxSelValid, instr_valid_i |-> bt_b_mux_sel inside {
1000: IMM_B_I,
1001: IMM_B_B,
1002: IMM_B_J,
1003: IMM_B_INCR_PC})
1004: `ASSERT(IbexRegfileWdataSelValid, instr_valid_i |-> rf_wdata_sel inside {
1005: RF_WD_EX,
1006: RF_WD_CSR})
1007: `ASSERT_KNOWN(IbexWbStateKnown, id_fsm_q)
1008:
1009: // Branch decision must be valid when jumping.
1010: `ASSERT_KNOWN_IF(IbexBranchDecisionValid, branch_decision_i,
1011: instr_valid_i && !(illegal_csr_insn_i || instr_fetch_err_i))
1012:
1013: // Instruction delivered to ID stage can not contain X.
1014: `ASSERT_KNOWN_IF(IbexIdInstrKnown, instr_rdata_i,
1015: instr_valid_i && !(illegal_c_insn_i || instr_fetch_err_i))
1016:
1017: // Instruction delivered to ID stage can not contain X.
1018: `ASSERT_KNOWN_IF(IbexIdInstrALUKnown, instr_rdata_alu_i,
1019: instr_valid_i && !(illegal_c_insn_i || instr_fetch_err_i))
1020:
1021: // Multicycle enable signals must be unique.
1022: `ASSERT(IbexMulticycleEnableUnique,
1023: $onehot0({lsu_req_dec, multdiv_en_dec, branch_in_dec, jump_in_dec}))
1024:
1025: // Duplicated instruction flops must match
1026: // === as DV environment can produce instructions with Xs in, so must use precise match that
1027: // includes Xs
1028: `ASSERT(IbexDuplicateInstrMatch, instr_valid_i |-> instr_rdata_i === instr_rdata_alu_i)
1029:
1030: `ifdef CHECK_MISALIGNED
1031: `ASSERT(IbexMisalignedMemoryAccess, !lsu_addr_incr_req_i)
1032: `endif
1033:
1034: endmodule
1035: