From e9bdbaddd623b3ab92bb8d4257dacad509235918 Mon Sep 17 00:00:00 2001 From: Pirmin Vogel Date: Thu, 27 Jun 2019 14:35:44 +0100 Subject: [PATCH] Make `mtvec` CSR compliant to spec The LSBs indicate the vector mode. They are set to vectored for Ibex. --- doc/cs_registers.rst | 6 +++++- rtl/ibex_core.sv | 12 ++++++------ rtl/ibex_cs_registers.sv | 8 ++++---- rtl/ibex_if_stage.sv | 17 +++++++++++------ 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/doc/cs_registers.rst b/doc/cs_registers.rst index 2da4fe36..85c77243 100644 --- a/doc/cs_registers.rst +++ b/doc/cs_registers.rst @@ -12,7 +12,7 @@ Ibex implements all the Control and Status Registers (CSRs) listed in the follow +---------+--------------------+--------+-----------------------------------------------+ | 0x301 | ``misa`` | WARL | Machine ISA and Extensions | +---------+--------------------+--------+-----------------------------------------------+ -| 0x305 | ``mtvec`` | WARL | Machine Trap-Handler Base Address | +| 0x305 | ``mtvec`` | R | Machine Trap-Vector Base Address | +---------+--------------------+--------+-----------------------------------------------+ | 0x320 | ``mcountinhibit`` | RW | Machine Counter-Inhibit Register | +---------+--------------------+--------+-----------------------------------------------+ @@ -90,6 +90,7 @@ CSR Address: ``0x305`` When an exception is encountered, the core jumps to the corresponding handler using the content of ``mtvec`` as base address. It is a read-only register which contains the boot address. +Its LSBs (mode field) are set to 2'b01 to indicate vectored interrupt handling. Machine Exception PC (mepc) @@ -119,6 +120,9 @@ Reset Value: ``0x0000_0000`` | 4:0 | R | **Exception Code** | +-------+-----+------------------------------------------------------------------+ +When an exception is encountered, the corresponding exception code is stored in this register. + + Machine Trap Value (mtval) -------------------------- diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index b50f1fb1..eba90238 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -206,6 +206,7 @@ module ibex_core #( logic csr_save_cause; exc_cause_e csr_cause; logic [31:0] csr_mtval; + logic [31:0] csr_mtvec; // debug mode and dcsr configuration dbg_cause_e debug_cause; @@ -302,11 +303,8 @@ module ibex_core #( .clk_i ( clk ), .rst_ni ( rst_ni ), - // boot address (trap vector location) .boot_addr_i ( boot_addr_i ), - - // instruction request control - .req_i ( instr_req_int ), + .req_i ( instr_req_int ), // instruction request control // instruction cache interface .instr_req_o ( instr_req_o ), @@ -336,6 +334,8 @@ module ibex_core #( // Jump targets .jump_target_ex_i ( jump_target_ex ), + .csr_mtvec_o ( csr_mtvec ), // trap-vector base address + // pipeline stalls .halt_if_i ( halt_if ), .id_ready_i ( id_ready ), @@ -572,8 +572,7 @@ module ibex_core #( // Core and Cluster ID from outside .core_id_i ( core_id_i ), .cluster_id_i ( cluster_id_i ), - // boot address - .boot_addr_i ( boot_addr_i ), + // Interface to CSRs (SRAM like) .csr_access_i ( csr_access ), @@ -603,6 +602,7 @@ module ibex_core #( .csr_save_cause_i ( csr_save_cause ), .csr_cause_i ( csr_cause ), .csr_mtval_i ( csr_mtval ), + .csr_mtvec_i ( csr_mtvec ), .illegal_csr_insn_o ( illegal_csr_insn_id ), // performance counter related signals diff --git a/rtl/ibex_cs_registers.sv b/rtl/ibex_cs_registers.sv index 9bd0a60b..001a7ed7 100644 --- a/rtl/ibex_cs_registers.sv +++ b/rtl/ibex_cs_registers.sv @@ -39,8 +39,6 @@ module ibex_cs_registers #( input logic [3:0] core_id_i, input logic [5:0] cluster_id_i, - input logic [31:0] boot_addr_i, - // Interface to registers (SRAM like) input logic csr_access_i, input ibex_defines::csr_num_e csr_addr_i, @@ -68,6 +66,7 @@ module ibex_cs_registers #( input logic csr_restore_dret_i, input logic csr_save_cause_i, input logic [31:0] csr_mtval_i, + input logic [31:0] csr_mtvec_i, input ibex_defines::exc_cause_e csr_cause_i, output logic illegal_csr_insn_o, // access to non-existent CSR, @@ -160,6 +159,7 @@ module ibex_cs_registers #( logic [31:0] depc_q, depc_n; logic [31:0] dscratch0_q, dscratch0_n; logic [31:0] dscratch1_q, dscratch1_n; + // Hardware performance monitor signals logic [31:0] mcountinhibit_n, mcountinhibit_q, mcountinhibit; logic [31:0] mcountinhibit_force; @@ -221,8 +221,8 @@ module ibex_cs_registers #( // misa CSR_MISA: csr_rdata_int = MISA_VALUE; - // mtvec: machine trap-handler base address - CSR_MTVEC: csr_rdata_int = boot_addr_i; + // mtvec: trap-vector base address + CSR_MTVEC: csr_rdata_int = csr_mtvec_i; // mepc: exception program counter CSR_MEPC: csr_rdata_int = mepc_q; diff --git a/rtl/ibex_if_stage.sv b/rtl/ibex_if_stage.sv index bd87c1b7..c5218371 100644 --- a/rtl/ibex_if_stage.sv +++ b/rtl/ibex_if_stage.sv @@ -36,10 +36,9 @@ module ibex_if_stage #( ) ( input logic clk_i, input logic rst_ni, - // the boot address is used to calculate the exception offsets - input logic [31:0] boot_addr_i, - // instruction request control - input logic req_i, + + input logic [31:0] boot_addr_i, // also used for mtvec + input logic req_i, // instruction request control // instruction cache interface output logic instr_req_o, @@ -76,14 +75,17 @@ module ibex_if_stage #( // jump and branch target and decision input logic [31:0] jump_target_ex_i, // jump target address + // CSRs + output logic [31:0] csr_mtvec_o, + // pipeline stall input logic halt_if_i, input logic id_ready_i, output logic if_valid_o, // misc signals - output logic if_busy_o, // IF stage is busy fetching instr - output logic perf_imiss_o // instr fetch miss + output logic if_busy_o, // IF stage is busy fetching instr + output logic perf_imiss_o // instr fetch miss ); import ibex_defines::*; @@ -103,6 +105,9 @@ module ibex_if_stage #( logic [31:0] exc_pc; + // trap-vector base address, mtvec.MODE set to vectored + assign csr_mtvec_o = {boot_addr_i[31:8], 6'b0, 2'b01}; + // exception PC selection mux always_comb begin : exc_pc_mux // TODO: The behavior below follows an outdated (pre-1.10) RISC-V Privileged