Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions rtl/cv32e40x_alignment_buffer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*;
output logic [31:0] fetch_branch_addr_o,
output logic fetch_ptr_access_o,
input logic fetch_ptr_access_i,
output privlvl_t fetch_priv_lvl_o,
input privlvl_t fetch_priv_lvl_i,

// Resp interface
input logic resp_valid_i,
Expand All @@ -56,6 +58,7 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*;
input logic instr_ready_i,
output inst_resp_t instr_instr_o,
output logic [31:0] instr_addr_o,
output privlvl_t instr_priv_lvl_o,
output logic instr_is_clic_ptr_o, // True CLIC pointer after taking a CLIC SHV interrupt
output logic instr_is_mret_ptr_o, // CLIC pointer due to restarting pionter fetch during mret
output logic instr_is_tbljmp_ptr_o,
Expand Down Expand Up @@ -580,4 +583,10 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*;

// Signal that a pointer is about to be fetched
assign fetch_ptr_access_o = (ctrl_fsm_i.pc_set && (ctrl_fsm_i.pc_set_clicv || ctrl_fsm_i.pc_set_tbljmp));

// Set privilege level to prefetcher
assign fetch_priv_lvl_o = PRIV_LVL_M;

// Set privilege level to IF stage
assign instr_priv_lvl_o = fetch_priv_lvl_i;
endmodule
3 changes: 3 additions & 0 deletions rtl/cv32e40x_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ module cv32e40x_core import cv32e40x_pkg::*;

logic [31:0] pc_if; // Program counter in IF stage
logic ptr_in_if; // IF stage contains a pointer
privlvl_t priv_lvl_if; // IF stage privilege level

// Jump and branch target and decision (EX->IF)
logic [31:0] jump_target_id;
Expand Down Expand Up @@ -463,6 +464,7 @@ module cv32e40x_core import cv32e40x_pkg::*;
.csr_mtvec_init_o ( csr_mtvec_init_if ),
.if_busy_o ( if_busy ),
.ptr_in_if_o ( ptr_in_if ),
.priv_lvl_if_o ( priv_lvl_if ),

.first_op_o ( first_op_if ),
.last_op_o ( last_op_if ),
Expand Down Expand Up @@ -817,6 +819,7 @@ module cv32e40x_core import cv32e40x_pkg::*;
.etrigger_wb_o ( etrigger_wb ),
.pc_if_i ( pc_if ),
.ptr_in_if_i ( ptr_in_if ),
.priv_lvl_if_i ( priv_lvl_if ),
.lsu_valid_ex_i ( lsu_valid_ex ),
.lsu_addr_ex_i ( lsu_addr_ex ),
.lsu_we_ex_i ( lsu_we_ex ),
Expand Down
57 changes: 29 additions & 28 deletions rtl/cv32e40x_cs_registers.sv
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
// Debug
input logic [31:0] pc_if_i,
input logic ptr_in_if_i,
input privlvl_t priv_lvl_if_i,
output logic trigger_match_if_o,
output logic trigger_match_ex_o,
output logic etrigger_wb_o,
Expand Down Expand Up @@ -1499,48 +1500,48 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*;
)
debug_triggers_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.clk ( clk ),
.rst_n ( rst_n ),

// CSR inputs write inputs
.csr_wdata_i ( csr_wdata_int),
.tselect_we_i ( tselect_we ),
.tdata1_we_i ( tdata1_we ),
.tdata2_we_i ( tdata2_we ),
.tdata3_we_i ( tdata3_we ),
.tinfo_we_i ( tinfo_we ),
.tcontrol_we_i ( tcontrol_we ),
.csr_wdata_i ( csr_wdata_int ),
.tselect_we_i ( tselect_we ),
.tdata1_we_i ( tdata1_we ),
.tdata2_we_i ( tdata2_we ),
.tdata3_we_i ( tdata3_we ),
.tinfo_we_i ( tinfo_we ),
.tcontrol_we_i ( tcontrol_we ),

// CSR read data outputs
.tselect_rdata_o ( tselect_rdata ),
.tdata1_rdata_o ( tdata1_rdata ),
.tdata2_rdata_o ( tdata2_rdata ),
.tdata3_rdata_o ( tdata3_rdata ),
.tinfo_rdata_o ( tinfo_rdata ),
.tcontrol_rdata_o ( tcontrol_rdata),
.tselect_rdata_o ( tselect_rdata ),
.tdata1_rdata_o ( tdata1_rdata ),
.tdata2_rdata_o ( tdata2_rdata ),
.tdata3_rdata_o ( tdata3_rdata ),
.tinfo_rdata_o ( tinfo_rdata ),
.tcontrol_rdata_o ( tcontrol_rdata ),

// IF stage inputs
.pc_if_i ( pc_if_i ),
.ptr_in_if_i ( ptr_in_if_i ),
.priv_lvl_if_i ( PRIV_LVL_M ),
.pc_if_i ( pc_if_i ),
.ptr_in_if_i ( ptr_in_if_i ),
.priv_lvl_if_i ( priv_lvl_if_i ),

// LSU inputs
.lsu_valid_ex_i ( lsu_valid_ex_i),
.lsu_addr_ex_i ( lsu_addr_ex_i ),
.lsu_we_ex_i ( lsu_we_ex_i ),
.lsu_be_ex_i ( lsu_be_ex_i ),
.priv_lvl_ex_i ( PRIV_LVL_M ),
.lsu_valid_ex_i ( lsu_valid_ex_i ),
.lsu_addr_ex_i ( lsu_addr_ex_i ),
.lsu_we_ex_i ( lsu_we_ex_i ),
.lsu_be_ex_i ( lsu_be_ex_i ),
.priv_lvl_ex_i ( id_ex_pipe_i.priv_lvl ),

// WB inputs
.priv_lvl_wb_i ( PRIV_LVL_M ),
.priv_lvl_wb_i ( ex_wb_pipe_i.priv_lvl ),

// Controller inputs
.ctrl_fsm_i ( ctrl_fsm_i ),
.ctrl_fsm_i ( ctrl_fsm_i ),

// Trigger match outputs
.trigger_match_if_o ( trigger_match_if_o ),
.trigger_match_ex_o ( trigger_match_ex_o ),
.etrigger_wb_o ( etrigger_wb_o )
.trigger_match_if_o ( trigger_match_if_o ),
.trigger_match_ex_o ( trigger_match_ex_o ),
.etrigger_wb_o ( etrigger_wb_o )
);


Expand Down
4 changes: 3 additions & 1 deletion rtl/cv32e40x_ex_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,14 @@ module cv32e40x_ex_stage import cv32e40x_pkg::*;
ex_wb_pipe_o.first_op <= 1'b0;
ex_wb_pipe_o.last_op <= 1'b0;
ex_wb_pipe_o.abort_op <= 1'b0;

ex_wb_pipe_o.priv_lvl <= PRIV_LVL_M;
end
else
begin
if (ex_valid_o && wb_ready_i) begin
ex_wb_pipe_o.instr_valid <= 1'b1;

ex_wb_pipe_o.priv_lvl <= id_ex_pipe_i.priv_lvl;
ex_wb_pipe_o.last_op <= last_op_o;
ex_wb_pipe_o.first_op <= first_op_o;
ex_wb_pipe_o.abort_op <= id_ex_pipe_i.abort_op; // MPU exceptions and watchpoint triggers have WB timing and will not impact ex_wb_pipe.abort_op
Expand Down
2 changes: 2 additions & 0 deletions rtl/cv32e40x_id_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
id_ex_pipe_o.xif_en <= 1'b0;
id_ex_pipe_o.xif_meta <= '0;

id_ex_pipe_o.priv_lvl <= PRIV_LVL_M;
id_ex_pipe_o.illegal_insn <= 1'b0;

id_ex_pipe_o.rf_we <= 1'b0;
Expand All @@ -568,6 +569,7 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
end else begin
// normal pipeline unstall case
if (id_valid_o && ex_ready_i) begin
id_ex_pipe_o.priv_lvl <= if_id_pipe_i.priv_lvl;
id_ex_pipe_o.instr_valid <= 1'b1;
id_ex_pipe_o.last_op <= last_op_o;
id_ex_pipe_o.first_op <= first_op_o;
Expand Down
12 changes: 10 additions & 2 deletions rtl/cv32e40x_if_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
output logic csr_mtvec_init_o, // Tell CS regfile to init mtvec
output logic if_busy_o, // Is the IF stage busy fetching instructions?
output logic ptr_in_if_o, // The IF stage currently holds a pointer
output privlvl_t priv_lvl_if_o, // Privilege level of the instruction currently in IF

output logic first_op_o,
output logic last_op_o,
Expand Down Expand Up @@ -98,6 +99,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
logic prefetch_valid;
logic prefetch_ready;
inst_resp_t prefetch_instr;
privlvl_t prefetch_priv_lvl;

logic prefetch_is_clic_ptr;
logic prefetch_is_mret_ptr;
Expand Down Expand Up @@ -195,6 +197,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
.prefetch_valid_o ( prefetch_valid ),
.prefetch_instr_o ( prefetch_instr ),
.prefetch_addr_o ( pc_if_o ),
.prefetch_priv_lvl_o ( prefetch_priv_lvl ),
.prefetch_is_clic_ptr_o ( prefetch_is_clic_ptr ),
.prefetch_is_mret_ptr_o ( prefetch_is_mret_ptr ),
.prefetch_is_tbljmp_ptr_o ( prefetch_is_tbljmp_ptr ),
Expand All @@ -219,7 +222,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
assign core_trans.addr = prefetch_trans_addr;
assign core_trans.dbg = ctrl_fsm_i.debug_mode_if;
assign core_trans.prot[0] = 1'b0; // Transfers from IF stage all instruction fetches
assign core_trans.prot[2:1] = PRIV_LVL_M; // Machine mode
assign core_trans.prot[2:1] = prefetch_priv_lvl; // Machine mode
assign core_trans.memtype = 2'b00; // memtype is assigned in the MPU, tie off.

cv32e40x_mpu
Expand Down Expand Up @@ -325,6 +328,9 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
// Set flag to indicate that instruction/sequence will be aborted due to known exceptions or trigger match
assign abort_op_o = instr_decompressed.bus_resp.err || (instr_decompressed.mpu_status != MPU_OK) || trigger_match_i;

// Signal current privilege level of IF
assign priv_lvl_if_o = prefetch_priv_lvl;

// Populate instruction meta data
// Fields 'compressed' and 'tbljmp' keep their old value by default.
// - In case of a table jump we need the fields to stay as 'compressed=1' and 'tbljmp=1'
Expand All @@ -350,6 +356,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
if_id_pipe_o.pc <= '0;
if_id_pipe_o.illegal_c_insn <= 1'b0;
if_id_pipe_o.compressed_instr <= '0;
if_id_pipe_o.priv_lvl <= PRIV_LVL_M;
if_id_pipe_o.trigger_match <= 1'b0;
if_id_pipe_o.xif_id <= '0;
if_id_pipe_o.ptr <= '0;
Expand All @@ -362,11 +369,12 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
if (if_valid_o && id_ready_i) begin
if_id_pipe_o.instr_valid <= 1'b1;
if_id_pipe_o.instr_meta <= instr_meta_n;

// seq_valid implies no illegal instruction, sequencer successfully decoded an instruction.
// compressed decoder will still raise illegal_c_insn as it doesn't (currently) recognize Zc push/pop/dmove
if_id_pipe_o.illegal_c_insn <= seq_valid ? 1'b0 : illegal_c_insn;


if_id_pipe_o.priv_lvl <= prefetch_priv_lvl;
if_id_pipe_o.trigger_match <= trigger_match_i;
if_id_pipe_o.xif_id <= xif_id;
if_id_pipe_o.last_op <= last_op_o;
Expand Down
9 changes: 8 additions & 1 deletion rtl/cv32e40x_prefetch_unit.sv
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module cv32e40x_prefetch_unit import cv32e40x_pkg::*;
output logic prefetch_valid_o,
output inst_resp_t prefetch_instr_o,
output logic [31:0] prefetch_addr_o,
output privlvl_t prefetch_priv_lvl_o,
output logic prefetch_is_clic_ptr_o,
output logic prefetch_is_mret_ptr_o,
output logic prefetch_is_tbljmp_ptr_o,
Expand All @@ -70,6 +71,8 @@ module cv32e40x_prefetch_unit import cv32e40x_pkg::*;
logic [31:0] fetch_branch_addr;
logic fetch_ptr_access;
logic fetch_ptr_resp;
privlvl_t fetch_priv_lvl_access;
privlvl_t fetch_priv_lvl_resp;



Expand All @@ -92,7 +95,8 @@ module cv32e40x_prefetch_unit import cv32e40x_pkg::*;
.fetch_ready_o ( fetch_ready ),
.fetch_ptr_access_i ( fetch_ptr_access ),
.fetch_ptr_access_o ( fetch_ptr_resp ),

.fetch_priv_lvl_access_i ( fetch_priv_lvl_access),
.fetch_priv_lvl_access_o ( fetch_priv_lvl_resp ),
.trans_valid_o ( trans_valid_o ),
.trans_ready_i ( trans_ready_i ),
.trans_addr_o ( trans_addr_o )
Expand Down Expand Up @@ -121,6 +125,8 @@ module cv32e40x_prefetch_unit import cv32e40x_pkg::*;
.fetch_branch_addr_o ( fetch_branch_addr ),
.fetch_ptr_access_o ( fetch_ptr_access ),
.fetch_ptr_access_i ( fetch_ptr_resp ),
.fetch_priv_lvl_o ( fetch_priv_lvl_access ),
.fetch_priv_lvl_i ( fetch_priv_lvl_resp ),

.resp_valid_i ( resp_valid_i ),
.resp_i ( resp_i ),
Expand All @@ -132,6 +138,7 @@ module cv32e40x_prefetch_unit import cv32e40x_pkg::*;
.instr_ready_i ( prefetch_ready_i ),
.instr_instr_o ( prefetch_instr_o ),
.instr_addr_o ( prefetch_addr_o ),
.instr_priv_lvl_o ( prefetch_priv_lvl_o ),
.instr_is_clic_ptr_o ( prefetch_is_clic_ptr_o ),
.instr_is_mret_ptr_o ( prefetch_is_mret_ptr_o ),
.instr_is_tbljmp_ptr_o ( prefetch_is_tbljmp_ptr_o)
Expand Down
11 changes: 9 additions & 2 deletions rtl/cv32e40x_prefetcher.sv
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
// //
////////////////////////////////////////////////////////////////////////////////

module cv32e40x_prefetcher
module cv32e40x_prefetcher import cv32e40x_pkg::*;
#(
parameter bit SMCLIC = 1'b0
)
Expand All @@ -52,6 +52,8 @@ module cv32e40x_prefetcher
output logic fetch_ready_o,
input logic fetch_ptr_access_i, // Access is data access (CLIC) // todo: add similar for table jump
output logic fetch_ptr_access_o, // Handshake is for a pointer access (CLIC and Zc)
input privlvl_t fetch_priv_lvl_access_i, // Priv level of access
output privlvl_t fetch_priv_lvl_access_o, // Priv level for handshake
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which handshake?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated comment to explain it


// Transaction request interface
output logic trans_valid_o, // Transaction request valid (to bus interface adapter)
Expand All @@ -61,13 +63,13 @@ module cv32e40x_prefetcher

);

import cv32e40x_pkg::*;

prefetch_state_e state_q, next_state;

// Transaction address
logic [31:0] trans_addr_q, trans_addr_incr;
logic trans_ptr_access_q;
privlvl_t trans_priv_lvl_q;

// Increment address (address will be made word aligned at core level)
assign trans_addr_incr = {trans_addr_q[31:1], 1'b0} + 32'd4;
Expand All @@ -86,6 +88,7 @@ module cv32e40x_prefetcher
next_state = state_q;
trans_addr_o = trans_addr_q;
fetch_ptr_access_o = trans_ptr_access_q;
fetch_priv_lvl_access_o = trans_priv_lvl_q;

case(state_q)
// Default state (pass on branch target address or transaction with incremented address)
Expand All @@ -96,9 +99,11 @@ module cv32e40x_prefetcher
if (fetch_branch_i) begin
trans_addr_o = fetch_branch_addr_i;
fetch_ptr_access_o = fetch_ptr_access_i;
fetch_priv_lvl_access_o = fetch_priv_lvl_access_i;
end else begin
trans_addr_o = trans_addr_incr;
fetch_ptr_access_o = 1'b0; // No incremental pointer fetches
fetch_priv_lvl_access_o = fetch_priv_lvl_access_i;
end
end
if ((fetch_branch_i) && !(trans_valid_o && trans_ready_i)) begin
Expand All @@ -114,6 +119,7 @@ module cv32e40x_prefetcher
// yet have its target address accepted by the bus interface adapter.
trans_addr_o = fetch_branch_i ? fetch_branch_addr_i : trans_addr_q;
fetch_ptr_access_o = fetch_branch_i ? fetch_ptr_access_i : trans_ptr_access_q;
fetch_priv_lvl_access_o = fetch_branch_i ? fetch_priv_lvl_access_i : trans_priv_lvl_q;
if (trans_valid_o && trans_ready_i) begin
// Transaction with branch target address has been accepted. Start regular prefetch again.
next_state = IDLE;
Expand Down Expand Up @@ -143,6 +149,7 @@ module cv32e40x_prefetcher
if (fetch_branch_i || (trans_valid_o && trans_ready_i)) begin
trans_addr_q <= trans_addr_o;
trans_ptr_access_q <= fetch_ptr_access_o;
trans_priv_lvl_q <= fetch_priv_lvl_access_o;
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions rtl/include/cv32e40x_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,7 @@ typedef struct packed {
logic [31:0] pc;
logic [15:0] compressed_instr;
logic illegal_c_insn;
privlvl_t priv_lvl;
logic trigger_match;
logic [31:0] xif_id; // ID of offloaded instruction
logic [31:0] ptr; // Flops to hold 32-bit pointer
Expand Down Expand Up @@ -1143,6 +1144,8 @@ typedef struct packed {
instr_meta_t instr_meta;
logic instr_valid; // instruction in EX is valid

privlvl_t priv_lvl;

// eXtension interface
logic xif_en; // Instruction has been offloaded via eXtension interface
xif_meta_t xif_meta; // xif meta struct
Expand Down Expand Up @@ -1184,6 +1187,8 @@ typedef struct packed {
logic instr_valid; // instruction in WB is valid
logic illegal_insn;

privlvl_t priv_lvl;

logic sys_en;
logic sys_dret_insn;
logic sys_ebrk_insn;
Expand Down