hw/vendor/lowrisc_ibex/rtl/ibex_core.sv Cov: 94.8%
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: * Top level module of the ibex RISC-V core
12: */
13: module ibex_core #(
14: parameter bit PMPEnable = 1'b0,
15: parameter int unsigned PMPGranularity = 0,
16: parameter int unsigned PMPNumRegions = 4,
17: parameter int unsigned MHPMCounterNum = 0,
18: parameter int unsigned MHPMCounterWidth = 40,
19: parameter bit RV32E = 1'b0,
20: parameter bit RV32M = 1'b1,
21: parameter MultiplierImplementation = "fast",
22: parameter bit DbgTriggerEn = 1'b0,
23: parameter int unsigned DmHaltAddr = 32'h1A110800,
24: parameter int unsigned DmExceptionAddr = 32'h1A110808
25: ) (
26: // Clock and Reset
27: input logic clk_i,
28: input logic rst_ni,
29:
30: input logic test_en_i, // enable all clock gates for testing
31:
32: input logic [31:0] hart_id_i,
33: input logic [31:0] boot_addr_i,
34:
35: // Instruction memory interface
36: output logic instr_req_o,
37: input logic instr_gnt_i,
38: input logic instr_rvalid_i,
39: output logic [31:0] instr_addr_o,
40: input logic [31:0] instr_rdata_i,
41: input logic instr_err_i,
42:
43: // Data memory interface
44: output logic data_req_o,
45: input logic data_gnt_i,
46: input logic data_rvalid_i,
47: output logic data_we_o,
48: output logic [3:0] data_be_o,
49: output logic [31:0] data_addr_o,
50: output logic [31:0] data_wdata_o,
51: input logic [31:0] data_rdata_i,
52: input logic data_err_i,
53:
54: // Interrupt inputs
55: input logic irq_software_i,
56: input logic irq_timer_i,
57: input logic irq_external_i,
58: input logic [14:0] irq_fast_i,
59: input logic irq_nm_i, // non-maskeable interrupt
60:
61: // Debug Interface
62: input logic debug_req_i,
63:
64: // RISC-V Formal Interface
65: // Does not comply with the coding standards of _i/_o suffixes, but follows
66: // the convention of RISC-V Formal Interface Specification.
67: `ifdef RVFI
68: output logic rvfi_valid,
69: output logic [63:0] rvfi_order,
70: output logic [31:0] rvfi_insn,
71: output logic rvfi_trap,
72: output logic rvfi_halt,
73: output logic rvfi_intr,
74: output logic [ 1:0] rvfi_mode,
75: output logic [ 4:0] rvfi_rs1_addr,
76: output logic [ 4:0] rvfi_rs2_addr,
77: output logic [31:0] rvfi_rs1_rdata,
78: output logic [31:0] rvfi_rs2_rdata,
79: output logic [ 4:0] rvfi_rd_addr,
80: output logic [31:0] rvfi_rd_wdata,
81: output logic [31:0] rvfi_pc_rdata,
82: output logic [31:0] rvfi_pc_wdata,
83: output logic [31:0] rvfi_mem_addr,
84: output logic [ 3:0] rvfi_mem_rmask,
85: output logic [ 3:0] rvfi_mem_wmask,
86: output logic [31:0] rvfi_mem_rdata,
87: output logic [31:0] rvfi_mem_wdata,
88: `endif
89:
90: // CPU Control Signals
91: input logic fetch_enable_i,
92: output logic core_sleep_o
93: );
94:
95: import ibex_pkg::*;
96:
97: localparam int unsigned PMP_NUM_CHAN = 2;
98:
99: // IF/ID signals
100: logic instr_valid_id;
101: logic instr_new_id;
102: logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
103: logic [15:0] instr_rdata_c_id; // Compressed instruction sampled inside IF stage
104: logic instr_is_compressed_id;
105: logic instr_fetch_err; // Bus error on instr fetch
106: logic illegal_c_insn_id; // Illegal compressed instruction sent to ID stage
107: logic [31:0] pc_if; // Program counter in IF stage
108: logic [31:0] pc_id; // Program counter in ID stage
109:
110: logic instr_valid_clear;
111: logic pc_set;
112: pc_sel_e pc_mux_id; // Mux selector for next PC
113: exc_pc_sel_e exc_pc_mux_id; // Mux selector for exception PC
114: exc_cause_e exc_cause; // Exception cause
115:
116: logic lsu_load_err;
117: logic lsu_store_err;
118:
119: // LSU signals
120: logic lsu_addr_incr_req;
121: logic [31:0] lsu_addr_last;
122:
123: // Jump and branch target and decision (EX->IF)
124: logic [31:0] jump_target_ex;
125: logic branch_decision;
126:
127: // Core busy signals
128: logic ctrl_busy;
129: logic if_busy;
130: logic lsu_busy;
131: logic core_busy_d, core_busy_q;
132:
133: // ALU Control
134: alu_op_e alu_operator_ex;
135: logic [31:0] alu_operand_a_ex;
136: logic [31:0] alu_operand_b_ex;
137:
138: logic [31:0] alu_adder_result_ex; // Used to forward computed address to LSU
139: logic [31:0] regfile_wdata_ex;
140:
141: // Multiplier Control
142: logic mult_en_ex;
143: logic div_en_ex;
144: md_op_e multdiv_operator_ex;
145: logic [1:0] multdiv_signed_mode_ex;
146: logic [31:0] multdiv_operand_a_ex;
147: logic [31:0] multdiv_operand_b_ex;
148:
149: // CSR control
150: logic csr_access;
151: logic valid_csr_id;
152: csr_op_e csr_op;
153: csr_num_e csr_addr;
154: logic [31:0] csr_rdata;
155: logic [31:0] csr_wdata;
156: logic illegal_csr_insn_id; // CSR access to non-existent register,
157: // with wrong priviledge level,
158: // or missing write permissions
159:
160: // Data Memory Control
161: logic data_we_ex;
162: logic [1:0] data_type_ex;
163: logic data_sign_ext_ex;
164: logic data_req_ex;
165: logic [31:0] data_wdata_ex;
166: logic [31:0] regfile_wdata_lsu;
167:
168: // stall control
169: logic id_in_ready;
170: logic ex_valid;
171:
172: logic lsu_data_valid;
173:
174: // Signals between instruction core interface and pipe (if and id stages)
175: logic instr_req_int; // Id stage asserts a req to instruction core interface
176:
177: // Interrupts
178: logic irq_pending;
179: logic nmi_mode;
180: logic csr_msip;
181: logic csr_mtip;
182: logic csr_meip;
183: logic [14:0] csr_mfip;
184: logic csr_mstatus_mie;
185: logic [31:0] csr_mepc, csr_depc;
186:
187: // PMP signals
188: logic [33:0] csr_pmp_addr [PMPNumRegions];
189: pmp_cfg_t csr_pmp_cfg [PMPNumRegions];
190: logic pmp_req_err [PMP_NUM_CHAN];
191: logic instr_req_out;
192: logic data_req_out;
193:
194: logic csr_save_if;
195: logic csr_save_id;
196: logic csr_restore_mret_id;
197: logic csr_restore_dret_id;
198: logic csr_save_cause;
199: logic csr_mtvec_init;
200: logic [31:0] csr_mtvec;
201: logic [31:0] csr_mtval;
202: logic csr_mstatus_tw;
203: priv_lvl_e priv_mode_id;
204: priv_lvl_e priv_mode_if;
205: priv_lvl_e priv_mode_lsu;
206:
207: // debug mode and dcsr configuration
208: logic debug_mode;
209: dbg_cause_e debug_cause;
210: logic debug_csr_save;
211: logic debug_single_step;
212: logic debug_ebreakm;
213: logic debug_ebreaku;
214: logic trigger_match;
215:
216: // performance counter related signals
217: logic instr_ret;
218: logic instr_ret_compressed;
219: logic perf_imiss;
220: logic perf_jump;
221: logic perf_branch;
222: logic perf_tbranch;
223: logic perf_load;
224: logic perf_store;
225:
226: // for RVFI
227: logic illegal_insn_id, unused_illegal_insn_id; // ID stage sees an illegal instruction
228:
229: // RISC-V Formal Interface signals
230: `ifdef RVFI
231: logic rvfi_intr_d;
232: logic rvfi_set_trap_pc_d;
233: logic rvfi_set_trap_pc_q;
234: logic [31:0] rvfi_insn_id;
235: logic [4:0] rvfi_rs1_addr_id;
236: logic [4:0] rvfi_rs2_addr_id;
237: logic [31:0] rvfi_rs1_data_d;
238: logic [31:0] rvfi_rs1_data_id;
239: logic [31:0] rvfi_rs1_data_q;
240: logic [31:0] rvfi_rs2_data_d;
241: logic [31:0] rvfi_rs2_data_id;
242: logic [31:0] rvfi_rs2_data_q;
243: logic [4:0] rvfi_rd_addr_id;
244: logic [4:0] rvfi_rd_addr_q;
245: logic [4:0] rvfi_rd_addr_d;
246: logic [31:0] rvfi_rd_wdata_id;
247: logic [31:0] rvfi_rd_wdata_d;
248: logic [31:0] rvfi_rd_wdata_q;
249: logic rvfi_rd_we_id;
250: logic rvfi_insn_new_d;
251: logic rvfi_insn_new_q;
252: logic [3:0] rvfi_mem_mask_int;
253: logic [31:0] rvfi_mem_rdata_d;
254: logic [31:0] rvfi_mem_rdata_q;
255: logic [31:0] rvfi_mem_wdata_d;
256: logic [31:0] rvfi_mem_wdata_q;
257: logic [31:0] rvfi_mem_addr_d;
258: logic [31:0] rvfi_mem_addr_q;
259: `endif
260:
261: //////////////////////
262: // Clock management //
263: //////////////////////
264:
265: logic clk;
266:
267: logic clock_en;
268:
269: // Before going to sleep, wait for I- and D-side
270: // interfaces to finish ongoing operations.
271: assign core_busy_d = ctrl_busy | if_busy | lsu_busy;
272:
273: always_ff @(posedge clk_i or negedge rst_ni) begin
274: if (!rst_ni) begin
275: core_busy_q <= 1'b0;
276: end else begin
277: core_busy_q <= core_busy_d;
278: end
279: end
280:
281: assign clock_en = core_busy_q | debug_req_i | irq_pending | irq_nm_i;
282: assign core_sleep_o = ~clock_en;
283:
284: // main clock gate of the core
285: // generates all clocks except the one for the debug unit which is
286: // independent
287: prim_clock_gating core_clock_gate_i (
288: .clk_i ( clk_i ),
289: .en_i ( clock_en ),
290: .test_en_i ( test_en_i ),
291: .clk_o ( clk )
292: );
293:
294: //////////////
295: // IF stage //
296: //////////////
297:
298: ibex_if_stage #(
299: .DmHaltAddr ( DmHaltAddr ),
300: .DmExceptionAddr ( DmExceptionAddr )
301: ) if_stage_i (
302: .clk_i ( clk ),
303: .rst_ni ( rst_ni ),
304:
305: .boot_addr_i ( boot_addr_i ),
306: .req_i ( instr_req_int ), // instruction request control
307:
308: // instruction cache interface
309: .instr_req_o ( instr_req_out ),
310: .instr_addr_o ( instr_addr_o ),
311: .instr_gnt_i ( instr_gnt_i ),
312: .instr_rvalid_i ( instr_rvalid_i ),
313: .instr_rdata_i ( instr_rdata_i ),
314: .instr_err_i ( instr_err_i ),
315: .instr_pmp_err_i ( pmp_req_err[PMP_I] ),
316:
317: // outputs to ID stage
318: .instr_valid_id_o ( instr_valid_id ),
319: .instr_new_id_o ( instr_new_id ),
320: .instr_rdata_id_o ( instr_rdata_id ),
321: .instr_rdata_c_id_o ( instr_rdata_c_id ),
322: .instr_is_compressed_id_o ( instr_is_compressed_id ),
323: .instr_fetch_err_o ( instr_fetch_err ),
324: .illegal_c_insn_id_o ( illegal_c_insn_id ),
325: .pc_if_o ( pc_if ),
326: .pc_id_o ( pc_id ),
327:
328: // control signals
329: .instr_valid_clear_i ( instr_valid_clear ),
330: .pc_set_i ( pc_set ),
331: .pc_mux_i ( pc_mux_id ),
332: .exc_pc_mux_i ( exc_pc_mux_id ),
333: .exc_cause ( exc_cause ),
334:
335: // jump targets
336: .jump_target_ex_i ( jump_target_ex ),
337:
338: // CSRs
339: .csr_mepc_i ( csr_mepc ), // exception return address
340: .csr_depc_i ( csr_depc ), // debug return address
341: .csr_mtvec_i ( csr_mtvec ), // trap-vector base address
342: .csr_mtvec_init_o ( csr_mtvec_init ),
343:
344: // pipeline stalls
345: .id_in_ready_i ( id_in_ready ),
346:
347: .if_busy_o ( if_busy ),
348: .perf_imiss_o ( perf_imiss )
349: );
350:
351: // Qualify the instruction request with PMP error
352: assign instr_req_o = instr_req_out & ~pmp_req_err[PMP_I];
353:
354: //////////////
355: // ID stage //
356: //////////////
357:
358: ibex_id_stage #(
359: .RV32E ( RV32E ),
360: .RV32M ( RV32M )
361: ) id_stage_i (
362: .clk_i ( clk ),
363: .rst_ni ( rst_ni ),
364:
365: .test_en_i ( test_en_i ),
366:
367: // Processor Enable
368: .fetch_enable_i ( fetch_enable_i ),
369: .ctrl_busy_o ( ctrl_busy ),
370: .illegal_insn_o ( illegal_insn_id ),
371:
372: // from/to IF-ID pipeline register
373: .instr_valid_i ( instr_valid_id ),
374: .instr_new_i ( instr_new_id ),
375: .instr_rdata_i ( instr_rdata_id ),
376: .instr_rdata_c_i ( instr_rdata_c_id ),
377: .instr_is_compressed_i ( instr_is_compressed_id ),
378:
379: // Jumps and branches
380: .branch_decision_i ( branch_decision ),
381:
382: // IF and ID control signals
383: .id_in_ready_o ( id_in_ready ),
384: .instr_valid_clear_o ( instr_valid_clear ),
385: .instr_req_o ( instr_req_int ),
386: .pc_set_o ( pc_set ),
387: .pc_mux_o ( pc_mux_id ),
388: .exc_pc_mux_o ( exc_pc_mux_id ),
389: .exc_cause_o ( exc_cause ),
390:
391: .instr_fetch_err_i ( instr_fetch_err ),
392: .illegal_c_insn_i ( illegal_c_insn_id ),
393:
394: .pc_id_i ( pc_id ),
395:
396: // Stalls
397: .ex_valid_i ( ex_valid ),
398: .lsu_valid_i ( lsu_data_valid ),
399:
400: .alu_operator_ex_o ( alu_operator_ex ),
401: .alu_operand_a_ex_o ( alu_operand_a_ex ),
402: .alu_operand_b_ex_o ( alu_operand_b_ex ),
403:
404: .mult_en_ex_o ( mult_en_ex ),
405: .div_en_ex_o ( div_en_ex ),
406: .multdiv_operator_ex_o ( multdiv_operator_ex ),
407: .multdiv_signed_mode_ex_o ( multdiv_signed_mode_ex ),
408: .multdiv_operand_a_ex_o ( multdiv_operand_a_ex ),
409: .multdiv_operand_b_ex_o ( multdiv_operand_b_ex ),
410:
411: // CSR ID/EX
412: .csr_access_o ( csr_access ),
413: .csr_op_o ( csr_op ),
414: .csr_save_if_o ( csr_save_if ), // control signal to save PC
415: .csr_save_id_o ( csr_save_id ), // control signal to save PC
416: .csr_restore_mret_id_o ( csr_restore_mret_id ), // restore mstatus upon DRET
417: .csr_restore_dret_id_o ( csr_restore_dret_id ), // restore mstatus upon MRET
418: .csr_save_cause_o ( csr_save_cause ),
419: .csr_mtval_o ( csr_mtval ),
420: .priv_mode_i ( priv_mode_id ),
421: .csr_mstatus_tw_i ( csr_mstatus_tw ),
422: .illegal_csr_insn_i ( illegal_csr_insn_id ),
423:
424: // LSU
425: .data_req_ex_o ( data_req_ex ), // to load store unit
426: .data_we_ex_o ( data_we_ex ), // to load store unit
427: .data_type_ex_o ( data_type_ex ), // to load store unit
428: .data_sign_ext_ex_o ( data_sign_ext_ex ), // to load store unit
429: .data_wdata_ex_o ( data_wdata_ex ), // to load store unit
430:
431: .lsu_addr_incr_req_i ( lsu_addr_incr_req ),
432: .lsu_addr_last_i ( lsu_addr_last ),
433:
434: .lsu_load_err_i ( lsu_load_err ),
435: .lsu_store_err_i ( lsu_store_err ),
436:
437: // Interrupt Signals
438: .csr_mstatus_mie_i ( csr_mstatus_mie ),
439: .csr_msip_i ( csr_msip ),
440: .csr_mtip_i ( csr_mtip ),
441: .csr_meip_i ( csr_meip ),
442: .csr_mfip_i ( csr_mfip ),
443: .irq_pending_i ( irq_pending ),
444: .irq_nm_i ( irq_nm_i ),
445: .nmi_mode_o ( nmi_mode ),
446:
447: // Debug Signal
448: .debug_mode_o ( debug_mode ),
449: .debug_cause_o ( debug_cause ),
450: .debug_csr_save_o ( debug_csr_save ),
451: .debug_req_i ( debug_req_i ),
452: .debug_single_step_i ( debug_single_step ),
453: .debug_ebreakm_i ( debug_ebreakm ),
454: .debug_ebreaku_i ( debug_ebreaku ),
455: .trigger_match_i ( trigger_match ),
456:
457: // write data to commit in the register file
458: .regfile_wdata_lsu_i ( regfile_wdata_lsu ),
459: .regfile_wdata_ex_i ( regfile_wdata_ex ),
460: .csr_rdata_i ( csr_rdata ),
461:
462: `ifdef RVFI
463: .rfvi_reg_raddr_ra_o ( rvfi_rs1_addr_id ),
464: .rfvi_reg_rdata_ra_o ( rvfi_rs1_data_id ),
465: .rfvi_reg_raddr_rb_o ( rvfi_rs2_addr_id ),
466: .rfvi_reg_rdata_rb_o ( rvfi_rs2_data_id ),
467: .rfvi_reg_waddr_rd_o ( rvfi_rd_addr_id ),
468: .rfvi_reg_wdata_rd_o ( rvfi_rd_wdata_id ),
469: .rfvi_reg_we_o ( rvfi_rd_we_id ),
470: `endif
471:
472: // Performance Counters
473: .perf_jump_o ( perf_jump ),
474: .perf_branch_o ( perf_branch ),
475: .perf_tbranch_o ( perf_tbranch ),
476: .instr_ret_o ( instr_ret ),
477: .instr_ret_compressed_o ( instr_ret_compressed )
478: );
479:
480: // for RVFI only
481: assign unused_illegal_insn_id = illegal_insn_id;
482:
483: ibex_ex_block #(
484: .RV32M ( RV32M ),
485: .MultiplierImplementation ( MultiplierImplementation )
486: ) ex_block_i (
487: .clk_i ( clk ),
488: .rst_ni ( rst_ni ),
489:
490: // ALU signal from ID stage
491: .alu_operator_i ( alu_operator_ex ),
492: .alu_operand_a_i ( alu_operand_a_ex ),
493: .alu_operand_b_i ( alu_operand_b_ex ),
494:
495: // Multipler/Divider signal from ID stage
496: .multdiv_operator_i ( multdiv_operator_ex ),
497: .mult_en_i ( mult_en_ex ),
498: .div_en_i ( div_en_ex ),
499: .multdiv_signed_mode_i ( multdiv_signed_mode_ex ),
500: .multdiv_operand_a_i ( multdiv_operand_a_ex ),
501: .multdiv_operand_b_i ( multdiv_operand_b_ex ),
502:
503: // Outputs
504: .alu_adder_result_ex_o ( alu_adder_result_ex ), // to LSU
505: .regfile_wdata_ex_o ( regfile_wdata_ex ), // to ID
506:
507: .jump_target_o ( jump_target_ex ), // to IF
508: .branch_decision_o ( branch_decision ), // to ID
509:
510: .ex_valid_o ( ex_valid )
511: );
512:
513: /////////////////////
514: // Load/store unit //
515: /////////////////////
516:
517: assign data_req_o = data_req_out & ~pmp_req_err[PMP_D];
518:
519: ibex_load_store_unit load_store_unit_i (
520: .clk_i ( clk ),
521: .rst_ni ( rst_ni ),
522:
523: // data interface
524: .data_req_o ( data_req_out ),
525: .data_gnt_i ( data_gnt_i ),
526: .data_rvalid_i ( data_rvalid_i ),
527: .data_err_i ( data_err_i ),
528: .data_pmp_err_i ( pmp_req_err[PMP_D] ),
529:
530: .data_addr_o ( data_addr_o ),
531: .data_we_o ( data_we_o ),
532: .data_be_o ( data_be_o ),
533: .data_wdata_o ( data_wdata_o ),
534: .data_rdata_i ( data_rdata_i ),
535:
536: // signals to/from ID/EX stage
537: .data_we_ex_i ( data_we_ex ),
538: .data_type_ex_i ( data_type_ex ),
539: .data_wdata_ex_i ( data_wdata_ex ),
540: .data_sign_ext_ex_i ( data_sign_ext_ex ),
541:
542: .data_rdata_ex_o ( regfile_wdata_lsu ),
543: .data_req_ex_i ( data_req_ex ),
544:
545: .adder_result_ex_i ( alu_adder_result_ex ),
546:
547: .addr_incr_req_o ( lsu_addr_incr_req ),
548: .addr_last_o ( lsu_addr_last ),
549: .data_valid_o ( lsu_data_valid ),
550:
551: // exception signals
552: .load_err_o ( lsu_load_err ),
553: .store_err_o ( lsu_store_err ),
554:
555: .busy_o ( lsu_busy )
556: );
557:
558:
559: /////////////////////////////////////////
560: // CSRs (Control and Status Registers) //
561: /////////////////////////////////////////
562:
563: assign csr_wdata = alu_operand_a_ex;
564: assign csr_addr = csr_num_e'(csr_access ? alu_operand_b_ex[11:0] : 12'b0);
565:
566: assign perf_load = data_req_o & data_gnt_i & (~data_we_o);
567: assign perf_store = data_req_o & data_gnt_i & data_we_o;
568:
569: // CSR access is qualified by instruction fetch error
570: assign valid_csr_id = instr_new_id & ~instr_fetch_err;
571:
572: ibex_cs_registers #(
573: .DbgTriggerEn ( DbgTriggerEn ),
574: .MHPMCounterNum ( MHPMCounterNum ),
575: .MHPMCounterWidth ( MHPMCounterWidth ),
576: .PMPEnable ( PMPEnable ),
577: .PMPGranularity ( PMPGranularity ),
578: .PMPNumRegions ( PMPNumRegions ),
579: .RV32E ( RV32E ),
580: .RV32M ( RV32M )
581: ) cs_registers_i (
582: .clk_i ( clk ),
583: .rst_ni ( rst_ni ),
584:
585: // Hart ID from outside
586: .hart_id_i ( hart_id_i ),
587: .priv_mode_id_o ( priv_mode_id ),
588: .priv_mode_if_o ( priv_mode_if ),
589: .priv_mode_lsu_o ( priv_mode_lsu ),
590:
591: // mtvec
592: .csr_mtvec_o ( csr_mtvec ),
593: .csr_mtvec_init_i ( csr_mtvec_init ),
594: .boot_addr_i ( boot_addr_i ),
595:
596: // Interface to CSRs (SRAM like)
597: .csr_access_i ( csr_access ),
598: .csr_addr_i ( csr_addr ),
599: .csr_wdata_i ( csr_wdata ),
600: .csr_op_i ( csr_op ),
601: .csr_rdata_o ( csr_rdata ),
602:
603: // Interrupt related control signals
604: .irq_software_i ( irq_software_i ),
605: .irq_timer_i ( irq_timer_i ),
606: .irq_external_i ( irq_external_i ),
607: .irq_fast_i ( irq_fast_i ),
608: .irq_pending_o ( irq_pending ),
609: .nmi_mode_i ( nmi_mode ),
610: .csr_msip_o ( csr_msip ),
611: .csr_mtip_o ( csr_mtip ),
612: .csr_meip_o ( csr_meip ),
613: .csr_mfip_o ( csr_mfip ),
614: .csr_mstatus_mie_o ( csr_mstatus_mie ),
615: .csr_mstatus_tw_o ( csr_mstatus_tw ),
616: .csr_mepc_o ( csr_mepc ),
617:
618: // PMP
619: .csr_pmp_cfg_o ( csr_pmp_cfg ),
620: .csr_pmp_addr_o ( csr_pmp_addr ),
621:
622: // debug
623: .csr_depc_o ( csr_depc ),
624: .debug_mode_i ( debug_mode ),
625: .debug_cause_i ( debug_cause ),
626: .debug_csr_save_i ( debug_csr_save ),
627: .debug_single_step_o ( debug_single_step ),
628: .debug_ebreakm_o ( debug_ebreakm ),
629: .debug_ebreaku_o ( debug_ebreaku ),
630: .trigger_match_o ( trigger_match ),
631:
632: .pc_if_i ( pc_if ),
633: .pc_id_i ( pc_id ),
634:
635: .csr_save_if_i ( csr_save_if ),
636: .csr_save_id_i ( csr_save_id ),
637: .csr_restore_mret_i ( csr_restore_mret_id ),
638: .csr_restore_dret_i ( csr_restore_dret_id ),
639: .csr_save_cause_i ( csr_save_cause ),
640: .csr_mcause_i ( exc_cause ),
641: .csr_mtval_i ( csr_mtval ),
642: .illegal_csr_insn_o ( illegal_csr_insn_id ),
643:
644: .instr_new_id_i ( valid_csr_id ),
645:
646: // performance counter related signals
647: .instr_ret_i ( instr_ret ),
648: .instr_ret_compressed_i ( instr_ret_compressed ),
649: .imiss_i ( perf_imiss ),
650: .pc_set_i ( pc_set ),
651: .jump_i ( perf_jump ),
652: .branch_i ( perf_branch ),
653: .branch_taken_i ( perf_tbranch ),
654: .mem_load_i ( perf_load ),
655: .mem_store_i ( perf_store ),
656: .lsu_busy_i ( lsu_busy )
657: );
658:
659: if (PMPEnable) begin : g_pmp
660: logic [33:0] pmp_req_addr [PMP_NUM_CHAN];
661: pmp_req_e pmp_req_type [PMP_NUM_CHAN];
662: priv_lvl_e pmp_priv_lvl [PMP_NUM_CHAN];
663:
664: assign pmp_req_addr[PMP_I] = {2'b00,instr_addr_o[31:0]};
665: assign pmp_req_type[PMP_I] = PMP_ACC_EXEC;
666: assign pmp_priv_lvl[PMP_I] = priv_mode_if;
667: assign pmp_req_addr[PMP_D] = {2'b00,data_addr_o[31:0]};
668: assign pmp_req_type[PMP_D] = data_we_o ? PMP_ACC_WRITE : PMP_ACC_READ;
669: assign pmp_priv_lvl[PMP_D] = priv_mode_lsu;
670:
671: ibex_pmp #(
672: .PMPGranularity ( PMPGranularity ),
673: .PMPNumChan ( PMP_NUM_CHAN ),
674: .PMPNumRegions ( PMPNumRegions )
675: ) pmp_i (
676: .clk_i ( clk ),
677: .rst_ni ( rst_ni ),
678: // Interface to CSRs
679: .csr_pmp_cfg_i ( csr_pmp_cfg ),
680: .csr_pmp_addr_i ( csr_pmp_addr ),
681: .priv_mode_i ( pmp_priv_lvl ),
682: // Access checking channels
683: .pmp_req_addr_i ( pmp_req_addr ),
684: .pmp_req_type_i ( pmp_req_type ),
685: .pmp_req_err_o ( pmp_req_err )
686: );
687: end else begin : g_no_pmp
688: // Unused signal tieoff
689: priv_lvl_e unused_priv_lvl_if, unused_priv_lvl_ls;
690: logic [33:0] unused_csr_pmp_addr [PMPNumRegions];
691: pmp_cfg_t unused_csr_pmp_cfg [PMPNumRegions];
692: assign unused_priv_lvl_if = priv_mode_if;
693: assign unused_priv_lvl_ls = priv_mode_lsu;
694: assign unused_csr_pmp_addr = csr_pmp_addr;
695: assign unused_csr_pmp_cfg = csr_pmp_cfg;
696:
697: // Output tieoff
698: assign pmp_req_err[PMP_I] = 1'b0;
699: assign pmp_req_err[PMP_D] = 1'b0;
700: end
701:
702: `ifdef RVFI
703: always_ff @(posedge clk or negedge rst_ni) begin
704: if (!rst_ni) begin
705: rvfi_halt <= '0;
706: rvfi_trap <= '0;
707: rvfi_intr <= '0;
708: rvfi_order <= '0;
709: rvfi_insn <= '0;
710: rvfi_mode <= {PRIV_LVL_M};
711: rvfi_rs1_addr <= '0;
712: rvfi_rs2_addr <= '0;
713: rvfi_pc_rdata <= '0;
714: rvfi_pc_wdata <= '0;
715: rvfi_mem_rmask <= '0;
716: rvfi_mem_wmask <= '0;
717: rvfi_valid <= '0;
718: rvfi_rs1_rdata <= '0;
719: rvfi_rs2_rdata <= '0;
720: rvfi_rd_wdata <= '0;
721: rvfi_rd_addr <= '0;
722: rvfi_mem_rdata <= '0;
723: rvfi_mem_wdata <= '0;
724: rvfi_mem_addr <= '0;
725: end else begin
726: rvfi_halt <= '0;
727: rvfi_trap <= illegal_insn_id;
728: rvfi_intr <= rvfi_intr_d;
729: rvfi_order <= rvfi_order + 64'(rvfi_valid);
730: rvfi_insn <= rvfi_insn_id;
731: rvfi_mode <= {priv_mode_id};
732: rvfi_rs1_addr <= rvfi_rs1_addr_id;
733: rvfi_rs2_addr <= rvfi_rs2_addr_id;
734: rvfi_pc_rdata <= pc_id;
735: rvfi_pc_wdata <= pc_if;
736: rvfi_mem_rmask <= rvfi_mem_mask_int;
737: rvfi_mem_wmask <= data_we_o ? rvfi_mem_mask_int : 4'b0000;
738: rvfi_valid <= instr_ret;
739: rvfi_rs1_rdata <= rvfi_rs1_data_d;
740: rvfi_rs2_rdata <= rvfi_rs2_data_d;
741: rvfi_rd_wdata <= rvfi_rd_wdata_d;
742: rvfi_rd_addr <= rvfi_rd_addr_d;
743: rvfi_mem_rdata <= rvfi_mem_rdata_d;
744: rvfi_mem_wdata <= rvfi_mem_wdata_d;
745: rvfi_mem_addr <= rvfi_mem_addr_d;
746: end
747: end
748:
749: // Keep the mem data stable for each instruction cycle
750: always_comb begin
751: if (rvfi_insn_new_d && lsu_data_valid) begin
752: rvfi_mem_addr_d = alu_adder_result_ex;
753: rvfi_mem_rdata_d = regfile_wdata_lsu;
754: rvfi_mem_wdata_d = data_wdata_ex;
755: end else begin
756: rvfi_mem_addr_d = rvfi_mem_addr_q;
757: rvfi_mem_rdata_d = rvfi_mem_rdata_q;
758: rvfi_mem_wdata_d = rvfi_mem_wdata_q;
759: end
760: end
761: always_ff @(posedge clk or negedge rst_ni) begin
762: if (!rst_ni) begin
763: rvfi_mem_addr_q <= '0;
764: rvfi_mem_rdata_q <= '0;
765: rvfi_mem_wdata_q <= '0;
766: end else begin
767: rvfi_mem_addr_q <= rvfi_mem_addr_d;
768: rvfi_mem_rdata_q <= rvfi_mem_rdata_d;
769: rvfi_mem_wdata_q <= rvfi_mem_wdata_d;
770: end
771: end
772: // Byte enable based on data type
773: always_comb begin
774: unique case (data_type_ex)
775: 2'b00: rvfi_mem_mask_int = 4'b1111;
776: 2'b01: rvfi_mem_mask_int = 4'b0011;
777: 2'b10: rvfi_mem_mask_int = 4'b0001;
778: default: rvfi_mem_mask_int = 4'b0000;
779: endcase
780: end
781:
782: always_comb begin
783: if (instr_is_compressed_id) begin
784: rvfi_insn_id = {16'b0, instr_rdata_c_id};
785: end else begin
786: rvfi_insn_id = instr_rdata_id;
787: end
788: end
789:
790: // Source register data are kept stable for each instruction cycle
791: always_comb begin
792: if (instr_new_id) begin
793: rvfi_rs1_data_d = rvfi_rs1_data_id;
794: rvfi_rs2_data_d = rvfi_rs2_data_id;
795: end else begin
796: rvfi_rs1_data_d = rvfi_rs1_data_q;
797: rvfi_rs2_data_d = rvfi_rs2_data_q;
798: end
799: end
800: always_ff @(posedge clk or negedge rst_ni) begin
801: if (!rst_ni) begin
802: rvfi_rs1_data_q <= '0;
803: rvfi_rs2_data_q <= '0;
804: end else begin
805: rvfi_rs1_data_q <= rvfi_rs1_data_d;
806: rvfi_rs2_data_q <= rvfi_rs2_data_d;
807: end
808: end
809:
810: // RD write register is refreshed only once per cycle and
811: // then it is kept stable for the cycle.
812: always_comb begin
813: if (rvfi_insn_new_d) begin
814: if (!rvfi_rd_we_id) begin
815: rvfi_rd_addr_d = '0;
816: rvfi_rd_wdata_d = '0;
817: end else begin
818: rvfi_rd_addr_d = rvfi_rd_addr_id;
819: if (rvfi_rd_addr_id == 5'h0) begin
820: rvfi_rd_wdata_d = '0;
821: end else begin
822: rvfi_rd_wdata_d = rvfi_rd_wdata_id;
823: end
824: end
825: end else begin
826: rvfi_rd_addr_d = rvfi_rd_addr_q;
827: rvfi_rd_wdata_d = rvfi_rd_wdata_q;
828: end
829: end
830: always_ff @(posedge clk or negedge rst_ni) begin
831: if (!rst_ni) begin
832: rvfi_rd_addr_q <= '0;
833: rvfi_rd_wdata_q <= '0;
834: end else begin
835: rvfi_rd_addr_q <= rvfi_rd_addr_d;
836: rvfi_rd_wdata_q <= rvfi_rd_wdata_d;
837: end
838: end
839:
840: always_comb begin
841: if (instr_new_id) begin
842: rvfi_insn_new_d = 1'b1;
843: end else begin
844: rvfi_insn_new_d = rvfi_insn_new_q;
845: end
846: end
847: always_ff @(posedge clk or negedge rst_ni) begin
848: if (!rst_ni) begin
849: rvfi_insn_new_q <= 1'b0;
850: end else begin
851: if (instr_ret) begin
852: rvfi_insn_new_q <= 1'b0;
853: end else begin
854: rvfi_insn_new_q <= rvfi_insn_new_d;
855: end
856: end
857: end
858:
859: // generate rvfi_intr_d
860: assign rvfi_intr_d = rvfi_set_trap_pc_q & rvfi_insn_new_d;
861:
862: always_comb begin
863: rvfi_set_trap_pc_d = rvfi_set_trap_pc_q;
864:
865: if (pc_set && pc_mux_id == PC_EXC &&
866: (exc_pc_mux_id == EXC_PC_EXC || exc_pc_mux_id == EXC_PC_IRQ)) begin
867: // PC is set to enter a trap handler
868: rvfi_set_trap_pc_d = 1'b1;
869: end else if (rvfi_set_trap_pc_q && instr_ret) begin
870: // first instruction has been executed after PC is set to trap handler
871: rvfi_set_trap_pc_d = 1'b0;
872: end
873: end
874:
875: always_ff @(posedge clk or negedge rst_ni) begin
876: if (!rst_ni) begin
877: rvfi_set_trap_pc_q <= 1'b0;
878: end else begin
879: rvfi_set_trap_pc_q <= rvfi_set_trap_pc_d;
880: end
881: end
882:
883: `endif
884:
885: endmodule
886: