Skip to content

Commit

Permalink
Merge pull request #756 from silabs-oysteink/silabs-oysteink_tablejum…
Browse files Browse the repository at this point in the history
…p-adder

Fix for issue #751. Changed JVT alignment from 1k to 64 Bytes
  • Loading branch information
Silabs-ArjanB authored Jan 9, 2023
2 parents cd55e3a + 2644b3e commit c4ec570
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 37 deletions.
4 changes: 0 additions & 4 deletions rtl/cv32e40x_controller_fsm.sv
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,6 @@ module cv32e40x_controller_fsm import cv32e40x_pkg::*;
// CLIC mode vectored PC mux is always the same as exc_cause.
assign ctrl_fsm_o.mtvt_pc_mux = exc_cause[9:0];

// Mux selector for table jumps
// index for table jumps taken from instruction word in ID stage.
assign ctrl_fsm_o.jvt_pc_mux = if_id_pipe_i.instr.bus_resp.rdata[19:12];

// Set which mtvec index to jump to when an NMI is taken
// index 0 for non-vectored CLINT mode and CLIC mode, 0xF for vectored CLINT mode
assign ctrl_fsm_o.nmi_mtvec_index = (mtvec_mode_i == 2'b01) ? 5'hF : 5'h0;
Expand Down
2 changes: 1 addition & 1 deletion rtl/cv32e40x_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,6 @@ module cv32e40x_core import cv32e40x_pkg::*;
.mepc_i ( mepc ), // Exception PC (restore upon return from exception/interrupt)
.mtvec_addr_i ( mtvec_addr ), // Exception/interrupt address (MSBs only)
.mtvt_addr_i ( mtvt_addr ), // CLIC vector base
.jvt_addr_i ( jvt_addr ),

.m_c_obi_instr_if ( m_c_obi_instr_if ), // Instruction bus interface

Expand Down Expand Up @@ -520,6 +519,7 @@ module cv32e40x_core import cv32e40x_pkg::*;
.ctrl_fsm_i ( ctrl_fsm ),

.mcause_i ( mcause ),
.jvt_addr_i ( jvt_addr ),

// Register file write back and forwards
.rf_wdata_ex_i ( rf_wdata_ex ),
Expand Down
7 changes: 4 additions & 3 deletions rtl/cv32e40x_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,10 @@ module cv32e40x_decoder import cv32e40x_pkg::*;
)
i_decoder_i
(
.instr_rdata_i ( instr_rdata ),
.ctrl_fsm_i ( ctrl_fsm_i ),
.decoder_ctrl_o ( decoder_i_ctrl_int )
.instr_rdata_i ( instr_rdata ),
.tbljmp_i ( if_id_pipe_i.instr_meta.tbljmp ),
.ctrl_fsm_i ( ctrl_fsm_i ),
.decoder_ctrl_o ( decoder_i_ctrl_int )
);

assign dec_i_rf_illegal_addr = (decoder_i_ctrl_int.rf_re[0] && rf_illegal_raddr_o[0]) ||
Expand Down
4 changes: 2 additions & 2 deletions rtl/cv32e40x_i_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module cv32e40x_i_decoder import cv32e40x_pkg::*;
(
// from IF/ID pipeline
input logic [31:0] instr_rdata_i,

input logic tbljmp_i, // instruction is a tablejump, mapped to JAL
input ctrl_fsm_t ctrl_fsm_i, // todo:low each use of this signal needs a comment explaining why the signal from the controller is safe to be used with ID timing (probably add comment in FSM)
output decoder_ctrl_t decoder_ctrl_o
);
Expand Down Expand Up @@ -71,7 +71,7 @@ module cv32e40x_i_decoder import cv32e40x_pkg::*;
decoder_ctrl_o.rf_we = 1'b1; // Write LR
decoder_ctrl_o.rf_re[0] = 1'b0; // Calculate jump target (= PC + UJ imm)
decoder_ctrl_o.rf_re[1] = 1'b0; // Calculate jump target (= PC + UJ imm)
decoder_ctrl_o.bch_jmp_mux_sel = CT_JAL;
decoder_ctrl_o.bch_jmp_mux_sel = tbljmp_i ? CT_TBLJMP : CT_JAL; // Zc tablejumps are mapped to JAL, but require their own mux selector for target computation.
end

OPCODE_JALR: begin // Jump and Link Register
Expand Down
8 changes: 8 additions & 0 deletions rtl/cv32e40x_id_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
input ctrl_fsm_t ctrl_fsm_i,

input mcause_t mcause_i,
input logic [JVT_ADDR_WIDTH-1:0] jvt_addr_i,

// Register file write data from WB stage
input logic [31:0] rf_wdata_wb_i,
Expand Down Expand Up @@ -213,6 +214,9 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
// Signal for detection of first operation (of two) of table jumps.
logic tbljmp_first;

// Current index for JVT instructions
logic [7:0] jvt_index;

assign instr_valid = if_id_pipe_i.instr_valid && !ctrl_fsm_i.kill_id && !ctrl_fsm_i.halt_id;

assign sys_mret_insn_o = sys_mret_insn;
Expand Down Expand Up @@ -281,6 +285,8 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
// |_| |___/ //
//////////////////////////////////////////////////////////////////

assign jvt_index = if_id_pipe_i.instr.bus_resp.rdata[19:12];

cv32e40x_pc_target cv32e40x_pc_target_i
(
.bch_jmp_mux_sel_i ( bch_jmp_mux_sel ),
Expand All @@ -289,6 +295,8 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
.imm_sb_type_i ( imm_sb_type ),
.imm_i_type_i ( imm_i_type ),
.jalr_fw_i ( jalr_fw ),
.jvt_addr_i ( jvt_addr_i ),
.jvt_index_i ( jvt_index ),
.bch_target_o ( bch_target ),
.jmp_target_o ( jmp_target_o )
);
Expand Down
4 changes: 1 addition & 3 deletions rtl/cv32e40x_if_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;

input logic [MTVT_ADDR_WIDTH-1:0] mtvt_addr_i, // Base address for CLIC vectoring

input logic [JVT_ADDR_WIDTH-1:0] jvt_addr_i,

input ctrl_fsm_t ctrl_fsm_i,
input logic trigger_match_i,

Expand Down Expand Up @@ -168,7 +166,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
// CLIC and Zc* spec requires to clear bit 0. This clearing is done in the alignment buffer.
PC_POINTER : branch_addr_n = if_id_pipe_o.ptr;
// JVT + (index << 2)
PC_TBLJUMP : branch_addr_n = {jvt_addr_i, ctrl_fsm_i.jvt_pc_mux[7:0], 2'b00};
PC_TBLJUMP : branch_addr_n = jump_target_id_i; // Tablejumps reuse jump target adder in the ID stage.

default:;
endcase
Expand Down
35 changes: 19 additions & 16 deletions rtl/cv32e40x_pc_target.sv
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Copyright 2021 Silicon Labs, Inc.
//
//
// This file, and derivatives thereof are licensed under the
// Solderpad License, Version 2.0 (the "License");
// Use of this file means you agree to the terms and conditions
// of the license and are in full compliance with the License.
// You may obtain a copy of the License at
//
//
// https://solderpad.org/licenses/SHL-2.0/
//
//
// Unless required by applicable law or agreed to in writing, software
// and hardware implementations thereof
// distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -25,27 +25,30 @@

module cv32e40x_pc_target import cv32e40x_pkg::*;
(
input bch_jmp_mux_e bch_jmp_mux_sel_i,
input logic [31:0] pc_id_i,
input logic [31:0] imm_uj_type_i,
input logic [31:0] imm_sb_type_i,
input logic [31:0] imm_i_type_i,
input logic [31:0] jalr_fw_i,
output logic [31:0] bch_target_o,
output logic [31:0] jmp_target_o
input bch_jmp_mux_e bch_jmp_mux_sel_i,
input logic [31:0] pc_id_i,
input logic [31:0] imm_uj_type_i,
input logic [31:0] imm_sb_type_i,
input logic [31:0] imm_i_type_i,
input logic [31:0] jalr_fw_i,
input logic [JVT_ADDR_WIDTH-1:0] jvt_addr_i,
input logic [7:0] jvt_index_i,
output logic [31:0] bch_target_o,
output logic [31:0] jmp_target_o
);

logic [31:0] pc_target;

assign bch_target_o = pc_target;
assign jmp_target_o = pc_target;
assign jmp_target_o = pc_target; // Used for both regular jumps and tablejumps

always_comb begin : pc_target_mux
unique case (bch_jmp_mux_sel_i)
CT_JAL: pc_target = pc_id_i + imm_uj_type_i;
CT_BCH: pc_target = pc_id_i + imm_sb_type_i;
CT_JALR: pc_target = jalr_fw_i + imm_i_type_i; // Forward from WB, but only of ALU result
default: pc_target = jalr_fw_i + imm_i_type_i;
CT_TBLJMP: pc_target = {jvt_addr_i, {(32-JVT_ADDR_WIDTH){1'b0}}} + {22'd0, jvt_index_i, 2'b00};
CT_JAL: pc_target = pc_id_i + imm_uj_type_i;
CT_BCH: pc_target = pc_id_i + imm_sb_type_i;
CT_JALR: pc_target = jalr_fw_i + imm_i_type_i; // Forward from WB, but only of ALU result
default: pc_target = jalr_fw_i + imm_i_type_i;
endcase
end
endmodule
14 changes: 6 additions & 8 deletions rtl/include/cv32e40x_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ typedef enum logic[11:0] {
} csr_num_e;

// CSR Bit Implementation Masks
parameter CSR_JVT_MASK = 32'hFFFFFC00;
parameter CSR_JVT_MASK = 32'hFFFFFFC0;
parameter CSR_MEPC_MASK = 32'hFFFFFFFE;
parameter CSR_DPC_MASK = 32'hFFFFFFFE;

Expand Down Expand Up @@ -501,9 +501,7 @@ typedef struct packed {
logic [5: 0] mode;
} jvt_t;

// todo: Might change this is Zc TG changes spec to allow some
// bits of the jvt.base to be WARL
parameter JVT_ADDR_WIDTH = 22;
parameter JVT_ADDR_WIDTH = 26;

typedef struct packed {
logic sd; // State dirty
Expand Down Expand Up @@ -775,9 +773,10 @@ typedef enum logic[1:0] {

// Control transfer (branch/jump) target mux
typedef enum logic[1:0] {
CT_JAL = 2'b01,
CT_JALR = 2'b10,
CT_BCH = 2'b11
CT_TBLJMP = 2'b00,
CT_JAL = 2'b01,
CT_JALR = 2'b10,
CT_BCH = 2'b11
} bch_jmp_mux_e;

// Atomic operations
Expand Down Expand Up @@ -1279,7 +1278,6 @@ typedef struct packed {
logic [4:0] mtvec_pc_mux; // Id of taken basic mode irq (to IF, EXC_PC_MUX, zeroed if mtvec_mode==0)
logic [9:0] mtvt_pc_mux; // Id of taken CLIC irq (to IF, EXC_PC_MUX, zeroed if not shv)
// Setting to 11 bits (max), unused bits will be tied off
logic [7:0] jvt_pc_mux; // Index for table jumps
logic [4:0] nmi_mtvec_index; // Offset into mtvec when taking an NMI

// To WB stage
Expand Down

0 comments on commit c4ec570

Please sign in to comment.