diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index 293bd9b2..d97954f9 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -139,6 +139,8 @@ module ibex_core #( csr_num_e csr_addr; logic [31:0] csr_rdata; logic [31:0] csr_wdata; + logic illegal_csr_insn_id; // CSR access to non-existent register, + // with wrong priviledge level, or missing write permissions // Data Memory Control logic data_we_ex; @@ -345,6 +347,7 @@ module ibex_core #( .csr_restore_mret_id_o ( csr_restore_mret_id ), // control signal to restore pc .csr_restore_dret_id_o ( csr_restore_dret_id ), // control signal to restore pc .csr_save_cause_o ( csr_save_cause ), + .illegal_csr_insn_i ( illegal_csr_insn_id ), // LSU .data_req_ex_o ( data_req_ex ), // to load store unit @@ -520,7 +523,7 @@ module ibex_core #( .csr_restore_dret_i ( csr_restore_dret_id ), .csr_cause_i ( csr_cause ), .csr_save_cause_i ( csr_save_cause ), - + .illegal_csr_insn_o ( illegal_csr_insn_id ), // performance counter related signals .insn_ret_i ( insn_ret ), diff --git a/rtl/ibex_cs_registers.sv b/rtl/ibex_cs_registers.sv index 24190668..2d252e2a 100644 --- a/rtl/ibex_cs_registers.sv +++ b/rtl/ibex_cs_registers.sv @@ -71,6 +71,9 @@ module ibex_cs_registers #( input ibex_defines::exc_cause_e csr_cause_i, input logic csr_save_cause_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 if_valid_i, // IF stage gives a new instr @@ -79,7 +82,7 @@ module ibex_cs_registers #( input logic is_decoding_i, // controller is in DECODE state input logic imiss_i, // instr fetch - input logic pc_set_i, // pc was set to a new value + 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 @@ -200,6 +203,11 @@ module ibex_cs_registers #( Status_t mstatus_q, mstatus_n; logic [31:0] exception_pc; + // Access violation signals + logic illegal_csr; + logic illegal_csr_priv; + logic illegal_csr_write; + ///////////// // CSR reg // ///////////// @@ -208,9 +216,14 @@ module ibex_cs_registers #( assign csr_addr = {csr_addr_i}; assign mhpmcounter_idx = csr_addr[4:0]; + assign illegal_csr_priv = 1'b0; // we only support M-mode + assign illegal_csr_write = (csr_addr[11:10] == 2'b11) && csr_we_int; + assign illegal_csr_insn_o = illegal_csr | illegal_csr_write | illegal_csr_priv; + // read logic always_comb begin csr_rdata_int = '0; + illegal_csr = 1'b0; unique case (csr_addr_i) // mstatus: always M-mode, contains IE bit @@ -256,10 +269,32 @@ module ibex_cs_registers #( default: begin if (csr_addr_i == CSR_MCOUNTER_SETUP_MASK) begin csr_rdata_int = mhpmevent[mhpmcounter_idx]; + // check access to non-existent or already covered CSRs + if ((csr_addr[4:0] == 5'b00000) || // CSR_MCOUNTINHIBIT + (csr_addr[4:0] == 5'b00001) || + (csr_addr[4:0] == 5'b00010)) begin + illegal_csr = csr_access_i; + end + end else if (csr_addr_i == CSR_MCOUNTER_MASK) begin csr_rdata_int = mhpmcounter_q[mhpmcounter_idx][31: 0]; + // check access to non-existent or already covered CSRs + if ((csr_addr[4:0] == 5'b00000) || // CSR_MCYCLE + (csr_addr[4:0] == 5'b00001) || + (csr_addr[4:0] == 5'b00010)) begin // CSR_MINSTRET + illegal_csr = csr_access_i; + end + end else if (csr_addr_i == CSR_MCOUNTERH_MASK) begin csr_rdata_int = mhpmcounter_q[mhpmcounter_idx][63:32]; + // check access to non-existent or already covered CSRs + if ((csr_addr[4:0] == 5'b00000) || // CSR_MCYCLEH + (csr_addr[4:0] == 5'b00001) || + (csr_addr[4:0] == 5'b00010)) begin // CSR_MINSTRETH + illegal_csr = csr_access_i; + end + end else begin + illegal_csr = csr_access_i; end end endcase diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 09cbbd44..2e13091e 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -96,7 +96,6 @@ module ibex_decoder #( logic branch_in_id; logic jump_in_id; - csr_op_e csr_op; logic csr_illegal; opcode_e opcode; @@ -125,7 +124,7 @@ module ibex_decoder #( csr_access_o = 1'b0; csr_status_o = 1'b0; csr_illegal = 1'b0; - csr_op = CSR_OP_NONE; + csr_op_o = CSR_OP_NONE; data_we_o = 1'b0; data_type_o = 2'b00; @@ -496,9 +495,9 @@ module ibex_decoder #( end unique case (instr_rdata_i[13:12]) - 2'b01: csr_op = CSR_OP_WRITE; - 2'b10: csr_op = CSR_OP_SET; - 2'b11: csr_op = CSR_OP_CLEAR; + 2'b01: csr_op_o = CSR_OP_WRITE; + 2'b10: csr_op_o = CSR_OP_SET; + 2'b11: csr_op_o = CSR_OP_CLEAR; default: csr_illegal = 1'b1; endcase @@ -514,7 +513,6 @@ module ibex_decoder #( end illegal_insn_o = csr_illegal; - end end @@ -549,7 +547,6 @@ module ibex_decoder #( assign mult_int_en_o = RV32M ? ((deassert_we_i) ? 1'b0 : mult_int_en) : 1'b0; assign div_int_en_o = RV32M ? ((deassert_we_i) ? 1'b0 : div_int_en ) : 1'b0; assign data_req_o = (deassert_we_i) ? 1'b0 : data_req; - assign csr_op_o = (deassert_we_i) ? CSR_OP_NONE : csr_op; assign jump_in_id_o = (deassert_we_i) ? 1'b0 : jump_in_id; assign branch_in_id_o = (deassert_we_i) ? 1'b0 : branch_in_id; diff --git a/rtl/ibex_id_stage.sv b/rtl/ibex_id_stage.sv index b4e25de8..ce8521bc 100644 --- a/rtl/ibex_id_stage.sv +++ b/rtl/ibex_id_stage.sv @@ -94,6 +94,7 @@ module ibex_id_stage #( output logic csr_restore_mret_id_o, output logic csr_restore_dret_id_o, output logic csr_save_cause_o, + input logic illegal_csr_insn_i, // Interface to load store unit output logic data_req_ex_o, @@ -407,7 +408,7 @@ module ibex_id_stage #( //////////////// // Controller // //////////////// - assign illegal_insn_o = illegal_insn_dec | illegal_reg_rv32e; + assign illegal_insn_o = illegal_insn_dec | illegal_reg_rv32e | illegal_csr_insn_i; ibex_controller controller_i ( .clk_i ( clk_i ),