diff --git a/rtl/ibex_controller.sv b/rtl/ibex_controller.sv index fa80c9de..a6bcd583 100644 --- a/rtl/ibex_controller.sv +++ b/rtl/ibex_controller.sv @@ -30,7 +30,6 @@ module ibex_controller ( input logic fetch_enable_i, // start decoding output logic ctrl_busy_o, // core is busy processing instrs output logic first_fetch_o, // core is at the FIRST FETCH stage - output logic is_decoding_o, // core is in decoding state // decoder related signals input logic illegal_insn_i, // decoder has an invalid instr @@ -137,7 +136,7 @@ module ibex_controller ( // glitches always_ff @(negedge clk_i) begin // print warning in case of decoding errors - if (is_decoding_o && illegal_insn_i) begin + if ((ctrl_fsm_cs == DECODE) && instr_valid_i && illegal_insn_i) begin $display("%t: Illegal instruction (core %0d) at PC 0x%h: 0x%h", $time, ibex_core.core_id_i, ibex_id_stage.pc_id_i, ibex_id_stage.instr_rdata_i); end @@ -183,7 +182,6 @@ module ibex_controller ( ctrl_fsm_ns = ctrl_fsm_cs; ctrl_busy_o = 1'b1; - is_decoding_o = 1'b0; first_fetch_o = 1'b0; halt_if = 1'b0; @@ -273,8 +271,6 @@ module ibex_controller ( // 3. interrupt requests if (instr_valid_i) begin - // analyze current instruction in ID stage - is_decoding_o = 1'b1; // set PC in IF stage to branch or jump target if (branch_set_i || jump_set_i) begin diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index 4bfe5cc7..3eb60dce 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -127,9 +127,6 @@ module ibex_core #( logic lsu_load_err; logic lsu_store_err; - // ID performance counter signals - logic is_decoding; - // LSU signals logic lsu_addr_incr_req; logic [31:0] lsu_addr_last; @@ -185,7 +182,6 @@ module ibex_core #( logic ex_valid; logic if_id_pipe_reg_we; - logic id_out_valid; logic lsu_data_valid; @@ -211,7 +207,8 @@ module ibex_core #( logic debug_ebreakm; // performance counter related signals - logic insn_ret; + logic instr_ret; + logic instr_ret_compressed; logic perf_imiss; logic perf_jump; logic perf_branch; @@ -219,6 +216,9 @@ module ibex_core #( logic perf_load; logic perf_store; + // for RVFI + logic id_out_valid, unused_id_out_valid; + // RISC-V Formal Interface signals `ifdef RVFI logic [31:0] rvfi_insn_opcode; @@ -360,7 +360,6 @@ module ibex_core #( .fetch_enable_i ( fetch_enable_i ), .ctrl_busy_o ( ctrl_busy ), .core_ctrl_firstfetch_o ( core_ctrl_firstfetch ), - .is_decoding_o ( is_decoding ), .illegal_insn_o ( illegal_insn_id ), // from/to IF-ID pipeline register @@ -463,6 +462,8 @@ module ibex_core #( .perf_tbranch_o ( perf_tbranch ) ); + // for RVFI only + assign unused_id_out_valid = id_out_valid; ibex_ex_block #( .RV32M ( RV32M ) @@ -549,7 +550,8 @@ module ibex_core #( // An instruction has been executed and retired if the ID stage gets a new instruction and // the previously seen instruction was valid. - assign insn_ret = if_id_pipe_reg_we & ~illegal_insn_id; + assign instr_ret = if_id_pipe_reg_we & ~illegal_insn_id; + assign instr_ret_compressed = instr_ret & instr_is_compressed_id; ibex_cs_registers #( .MHPMCounterNum ( MHPMCounterNum ), @@ -564,7 +566,6 @@ module ibex_core #( .core_id_i ( core_id_i ), .cluster_id_i ( cluster_id_i ), - // Interface to CSRs (SRAM like) .csr_access_i ( csr_access ), .csr_addr_i ( csr_addr ), @@ -596,12 +597,11 @@ module ibex_core #( .csr_mtval_i ( csr_mtval ), .illegal_csr_insn_o ( illegal_csr_insn_id ), - // performance counter related signals - .insn_ret_i ( insn_ret ), - .id_out_valid_i ( id_out_valid ), - .instr_is_compressed_i ( instr_is_compressed_id ), - .is_decoding_i ( is_decoding ), + .instr_new_id_i ( instr_new_id ), + // performance counter related signals + .instr_ret_i ( instr_ret ), + .instr_ret_compressed_i ( instr_ret_compressed ), .imiss_i ( perf_imiss ), .pc_set_i ( pc_set ), .jump_i ( perf_jump ), diff --git a/rtl/ibex_cs_registers.sv b/rtl/ibex_cs_registers.sv index 638e1867..55ec65b0 100644 --- a/rtl/ibex_cs_registers.sv +++ b/rtl/ibex_cs_registers.sv @@ -32,60 +32,58 @@ module ibex_cs_registers #( parameter bit RV32M = 0 ) ( // Clock and Reset - input logic clk_i, - input logic rst_ni, + input logic clk_i, + input logic rst_ni, // Core and Cluster ID - input logic [3:0] core_id_i, - input logic [5:0] cluster_id_i, + input logic [3:0] core_id_i, + input logic [5:0] cluster_id_i, // Interface to registers (SRAM like) - input logic csr_access_i, - input ibex_defines::csr_num_e csr_addr_i, - input logic [31:0] csr_wdata_i, - input ibex_defines::csr_op_e csr_op_i, - output logic [31:0] csr_rdata_o, + input logic csr_access_i, + input ibex_defines::csr_num_e csr_addr_i, + input logic [31:0] csr_wdata_i, + input ibex_defines::csr_op_e csr_op_i, + output logic [31:0] csr_rdata_o, // Interrupts - output logic m_irq_enable_o, - output logic [31:0] csr_mepc_o, + output logic m_irq_enable_o, + output logic [31:0] csr_mepc_o, // debug - input ibex_defines::dbg_cause_e debug_cause_i, - input logic debug_csr_save_i, - output logic [31:0] csr_depc_o, - output logic debug_single_step_o, - output logic debug_ebreakm_o, + input ibex_defines::dbg_cause_e debug_cause_i, + input logic debug_csr_save_i, + output logic [31:0] csr_depc_o, + output logic debug_single_step_o, + output logic debug_ebreakm_o, - input logic [31:0] pc_if_i, - input logic [31:0] pc_id_i, + input logic [31:0] pc_if_i, + input logic [31:0] pc_id_i, - input logic csr_save_if_i, - input logic csr_save_id_i, - input logic csr_restore_mret_i, - input logic csr_restore_dret_i, - input logic csr_save_cause_i, - input logic [31:0] csr_mtvec_i, - input ibex_defines::exc_cause_e csr_mcause_i, - input logic [31:0] csr_mtval_i, - - output logic illegal_csr_insn_o, // access to non-existent CSR, + input logic csr_save_if_i, + input logic csr_save_id_i, + input logic csr_restore_mret_i, + input logic csr_restore_dret_i, + input logic csr_save_cause_i, + input logic [31:0] csr_mtvec_i, + input ibex_defines::exc_cause_e csr_mcause_i, + input logic [31:0] csr_mtval_i, + output logic illegal_csr_insn_o, // access to non-existent CSR, // with wrong priviledge level, or // missing write permissions - // Performance Counters - input logic insn_ret_i, // instr retired in ID/EX stage - input logic id_out_valid_i, // ID stage is done - input logic instr_is_compressed_i, // compressed instr in ID - input logic is_decoding_i, // controller is in DECODE state + input logic instr_new_id_i, // ID stage sees a new instr - input logic imiss_i, // instr fetch - input logic pc_set_i, // PC was set to a new value - input logic jump_i, // jump instr seen (j, jr, jal, jalr) - input logic branch_i, // branch instr seen (bf, bnf) - input logic branch_taken_i, // branch was taken - input logic mem_load_i, // load from memory in this cycle - input logic mem_store_i, // store to memory in this cycle - input logic lsu_busy_i + // Performance Counters + input logic instr_ret_i, // instr retired in ID/EX stage + input logic instr_ret_compressed_i, // compressed instr retired + input logic imiss_i, // instr fetch + input logic pc_set_i, // PC was set to a new value + input logic jump_i, // jump instr seen (j, jr, jal, jalr) + input logic branch_i, // branch instr seen (bf, bnf) + input logic branch_taken_i, // branch was taken + input logic mem_load_i, // load from memory in this cycle + input logic mem_store_i, // store to memory in this cycle + input logic lsu_busy_i ); import ibex_defines::*; @@ -466,7 +464,7 @@ module ibex_cs_registers #( end // only write CSRs during one clock cycle - assign csr_we_int = csr_wreq & is_decoding_i; + assign csr_we_int = csr_wreq & instr_new_id_i; assign csr_rdata_o = csr_rdata_int; @@ -539,19 +537,18 @@ module ibex_cs_registers #( always_comb begin : gen_mhpmcounter_incr // active counters - mhpmcounter_incr[0] = 1'b1; // mcycle - mhpmcounter_incr[1] = 1'b0; // reserved - mhpmcounter_incr[2] = insn_ret_i; // minstret - mhpmcounter_incr[3] = lsu_busy_i; // cycles waiting for data memory - mhpmcounter_incr[4] = imiss_i & ~pc_set_i; // cycles waiting for instr fetches ex. - // jumps and branches - mhpmcounter_incr[5] = mem_load_i; // num of loads - mhpmcounter_incr[6] = mem_store_i; // num of stores - mhpmcounter_incr[7] = jump_i; // num of jumps (unconditional) - mhpmcounter_incr[8] = branch_i; // num of branches (conditional) - mhpmcounter_incr[9] = branch_taken_i; // num of taken branches (conditional) - mhpmcounter_incr[10] = is_decoding_i // num of compressed instr - & id_out_valid_i & instr_is_compressed_i; + mhpmcounter_incr[0] = 1'b1; // mcycle + mhpmcounter_incr[1] = 1'b0; // reserved + mhpmcounter_incr[2] = instr_ret_i; // minstret + mhpmcounter_incr[3] = lsu_busy_i; // cycles waiting for data memory + mhpmcounter_incr[4] = imiss_i & ~pc_set_i; // cycles waiting for instr fetches + // excl. jump and branch set cycles + mhpmcounter_incr[5] = mem_load_i; // num of loads + mhpmcounter_incr[6] = mem_store_i; // num of stores + mhpmcounter_incr[7] = jump_i; // num of jumps (unconditional) + mhpmcounter_incr[8] = branch_i; // num of branches (conditional) + mhpmcounter_incr[9] = branch_taken_i; // num of taken branches (conditional) + mhpmcounter_incr[10] = instr_ret_compressed_i; // num of compressed instr // inactive counters for (int unsigned i=3+MHPMCounterNum; i<32; i++) begin : gen_mhpmcounter_incr_inactive diff --git a/rtl/ibex_id_stage.sv b/rtl/ibex_id_stage.sv index 90861c8e..66a0d3e4 100644 --- a/rtl/ibex_id_stage.sv +++ b/rtl/ibex_id_stage.sv @@ -43,7 +43,6 @@ module ibex_id_stage #( input logic fetch_enable_i, output logic ctrl_busy_o, output logic core_ctrl_firstfetch_o, - output logic is_decoding_o, output logic illegal_insn_o, // Interface to IF stage @@ -407,7 +406,6 @@ module ibex_id_stage #( .fetch_enable_i ( fetch_enable_i ), .ctrl_busy_o ( ctrl_busy_o ), .first_fetch_o ( core_ctrl_firstfetch_o ), - .is_decoding_o ( is_decoding_o ), // decoder related signals .illegal_insn_i ( illegal_insn_o ),