Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge from CV32E40X #455

Merged
72 changes: 34 additions & 38 deletions bhv/cv32e40s_rvfi.sv
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ module cv32e40s_rvfi
input logic csr_mscratchcsw_in_wb_i,
input logic csr_mscratchcswl_in_wb_i,
input logic csr_mnxti_in_wb_i,
input logic wpt_match_wb_i,
input logic [31:0] wpt_match_wb_i,
input mpu_status_e mpu_status_wb_i,
input align_status_e align_status_wb_i,

Expand Down Expand Up @@ -198,15 +198,9 @@ module cv32e40s_rvfi
input logic [31:0] csr_tdata2_n_i,
input logic [31:0] csr_tdata2_q_i,
input logic csr_tdata2_we_i,
input logic [31:0] csr_tdata3_n_i,
input logic [31:0] csr_tdata3_q_i,
input logic csr_tdata3_we_i,
input logic [31:0] csr_tinfo_n_i,
input logic [31:0] csr_tinfo_q_i,
input logic csr_tinfo_we_i,
input logic [31:0] csr_tcontrol_n_i,
input logic [31:0] csr_tcontrol_q_i,
input logic csr_tcontrol_we_i,
input logic [31:0] csr_tselect_n_i,
input logic [31:0] csr_tselect_q_i,
input logic csr_tselect_we_i,
Expand Down Expand Up @@ -309,6 +303,8 @@ module cv32e40s_rvfi
output logic [63:0] rvfi_order,
output logic [31:0] rvfi_insn,
output logic [2:0] rvfi_instr_prot,
output logic [1:0] rvfi_instr_memtype,
output logic rvfi_instr_dbg,
output rvfi_trap_t rvfi_trap,
output logic [ 0:0] rvfi_halt,
output rvfi_intr_t rvfi_intr,
Expand All @@ -335,6 +331,9 @@ module cv32e40s_rvfi
output logic [32*NMEM-1:0] rvfi_mem_rdata,
output logic [32*NMEM-1:0] rvfi_mem_wdata,
output logic [ 3*NMEM-1:0] rvfi_mem_prot,
output logic [ 6*NMEM-1:0] rvfi_mem_atop,
output logic [ 2*NMEM-1:0] rvfi_mem_memtype,
output logic [ NMEM-1 :0] rvfi_mem_dbg,

output logic [32*32-1:0] rvfi_gpr_rdata,
output logic [31:0] rvfi_gpr_rmask,
Expand Down Expand Up @@ -423,18 +422,14 @@ module cv32e40s_rvfi
output logic [31:0] rvfi_csr_tselect_wmask,
output logic [31:0] rvfi_csr_tselect_rdata,
output logic [31:0] rvfi_csr_tselect_wdata,
output logic [ 3:0] [31:0] rvfi_csr_tdata_rmask, // 1-3 implemented
output logic [ 3:0] [31:0] rvfi_csr_tdata_wmask,
output logic [ 3:0] [31:0] rvfi_csr_tdata_rdata,
output logic [ 3:0] [31:0] rvfi_csr_tdata_wdata,
output logic [ 2:0] [31:0] rvfi_csr_tdata_rmask, // 1-2 implemented
output logic [ 2:0] [31:0] rvfi_csr_tdata_wmask,
output logic [ 2:0] [31:0] rvfi_csr_tdata_rdata,
output logic [ 2:0] [31:0] rvfi_csr_tdata_wdata,
output logic [31:0] rvfi_csr_tinfo_rmask,
output logic [31:0] rvfi_csr_tinfo_wmask,
output logic [31:0] rvfi_csr_tinfo_rdata,
output logic [31:0] rvfi_csr_tinfo_wdata,
output logic [31:0] rvfi_csr_tcontrol_rmask,
output logic [31:0] rvfi_csr_tcontrol_wmask,
output logic [31:0] rvfi_csr_tcontrol_rdata,
output logic [31:0] rvfi_csr_tcontrol_wdata,
output logic [31:0] rvfi_csr_dcsr_rmask,
output logic [31:0] rvfi_csr_dcsr_wmask,
output logic [31:0] rvfi_csr_dcsr_rdata,
Expand Down Expand Up @@ -606,7 +601,7 @@ module cv32e40s_rvfi
logic [4:0] debug_mode;
logic [4:0] [ 2:0] debug_cause;
logic [4:0] instr_pmp_err;
logic [4:0] [2:0] instr_prot;
obi_inst_req_t [4:0] instr_req;
rvfi_intr_t [4:0] in_trap;
logic [4:0] [ 4:0] rs1_addr;
logic [4:0] [ 4:0] rs2_addr;
Expand Down Expand Up @@ -834,7 +829,7 @@ module cv32e40s_rvfi

// Indicate that a data transfer was blocked before reaching the bus.
logic mem_access_blocked_wb;
assign mem_access_blocked_wb = wpt_match_wb_i ||
assign mem_access_blocked_wb = |wpt_match_wb_i ||
(mpu_status_wb_i != MPU_OK) ||
(align_status_wb_i != ALIGN_OK);

Expand Down Expand Up @@ -959,7 +954,7 @@ module cv32e40s_rvfi
debug_mode <= '0;
debug_cause <= '0;
instr_pmp_err <= '0;
instr_prot <= '0;
instr_req <= '0;
rs1_addr <= '0;
rs2_addr <= '0;
rs1_rdata <= '0;
Expand All @@ -975,6 +970,8 @@ module cv32e40s_rvfi
rvfi_order <= '0;
rvfi_insn <= '0;
rvfi_instr_prot <= '0;
rvfi_instr_memtype <= '0;
rvfi_instr_dbg <= '0;
rvfi_pc_rdata <= '0;
rvfi_pc_wdata <= '0;
rvfi_trap <= '0;
Expand All @@ -995,6 +992,9 @@ module cv32e40s_rvfi
rvfi_mem_wmask <= '0;
rvfi_mem_wdata <= '0;
rvfi_mem_prot <= '0;
rvfi_mem_memtype <= '0;
rvfi_mem_atop <= '0;
rvfi_mem_dbg <= '0;
rvfi_gpr_rdata <= '0;
rvfi_gpr_rmask <= '0;
rvfi_gpr_wdata <= '0;
Expand Down Expand Up @@ -1047,7 +1047,7 @@ module cv32e40s_rvfi
end

// Capture OBI prot for the instruction fetch
instr_prot[STAGE_ID] <= obi_instr_if.req_payload.prot;
instr_req[STAGE_ID] <= obi_instr_if.req_payload;

end else begin
// Clear in trap if trap reached rvfi outputs or we insert a bubble into the ID stage
Expand Down Expand Up @@ -1121,7 +1121,7 @@ module cv32e40s_rvfi
debug_mode [STAGE_EX] <= debug_mode [STAGE_ID];
debug_cause[STAGE_EX] <= debug_cause[STAGE_ID];
instr_pmp_err[STAGE_EX] <= instr_pmp_err[STAGE_ID];
instr_prot[STAGE_EX] <= instr_prot[STAGE_ID];
instr_req[STAGE_EX] <= instr_req[STAGE_ID];

// Only update rs1/rs2 on the first part of a multi operation instruction.
// Jumps may actually use rs1 before (id_valid && ex_ready), an assertion exists to check that
Expand Down Expand Up @@ -1168,7 +1168,7 @@ module cv32e40s_rvfi
debug_mode [STAGE_WB] <= debug_mode [STAGE_EX];
debug_cause[STAGE_WB] <= debug_cause [STAGE_EX];
instr_pmp_err[STAGE_WB] <= instr_pmp_err [STAGE_EX];
instr_prot [STAGE_WB] <= instr_prot [STAGE_EX];
instr_req [STAGE_WB] <= instr_req [STAGE_EX];
rs1_addr [STAGE_WB] <= rs1_addr [STAGE_EX];
rs2_addr [STAGE_WB] <= rs2_addr [STAGE_EX];
rs1_rdata [STAGE_WB] <= rs1_rdata [STAGE_EX];
Expand Down Expand Up @@ -1239,7 +1239,10 @@ module cv32e40s_rvfi
rvfi_rs2_addr <= mret_ptr_wb ? rs2_addr [STAGE_WB_PAST] : rs2_addr [STAGE_WB];
rvfi_rs1_rdata <= mret_ptr_wb ? rs1_rdata[STAGE_WB_PAST] : rs1_rdata [STAGE_WB];
rvfi_rs2_rdata <= mret_ptr_wb ? rs2_rdata[STAGE_WB_PAST] : rs2_rdata [STAGE_WB];
rvfi_instr_prot<= mret_ptr_wb ? instr_prot[STAGE_WB_PAST] : instr_prot[STAGE_WB];

rvfi_instr_prot <= mret_ptr_wb ? instr_req[STAGE_WB_PAST].prot : instr_req[STAGE_WB].prot;
rvfi_instr_memtype <= mret_ptr_wb ? instr_req[STAGE_WB_PAST].memtype : instr_req[STAGE_WB].memtype;
rvfi_instr_dbg <= mret_ptr_wb ? instr_req[STAGE_WB_PAST].dbg : instr_req[STAGE_WB].dbg;

rvfi_mode <= priv_lvl_i;

Expand All @@ -1263,7 +1266,7 @@ module cv32e40s_rvfi
rs2_rdata[STAGE_WB_PAST] <= rs1_rdata[STAGE_WB];
debug_cause [STAGE_WB_PAST] <= debug_cause [STAGE_WB];
debug_mode [STAGE_WB_PAST] <= debug_mode[STAGE_WB];
instr_prot[STAGE_WB_PAST] <= instr_prot[STAGE_WB];
instr_req[STAGE_WB_PAST] <= instr_req[STAGE_WB];
pc_wb_past <= pc_wb_i;
instr_rdata_wb_past <= instr_rdata_wb_i;
rd_addr_wb_past <= rd_addr_wb;
Expand All @@ -1277,6 +1280,9 @@ module cv32e40s_rvfi
rvfi_mem_wmask <= '0;
rvfi_mem_wdata <= '0;
rvfi_mem_prot <= '0;
rvfi_mem_atop <= '0;
rvfi_mem_memtype <= '0;
rvfi_mem_dbg <= '0;

rvfi_gpr_rdata <= '0;
rvfi_gpr_rmask <= '0;
Expand All @@ -1295,6 +1301,10 @@ module cv32e40s_rvfi
rvfi_mem_wdata[(32*(memop_cnt+1))-1 -: 32] <= ex_mem_trans.wdata;
// Using (2*memop_cnt+memop_cnt) rather than 3*memop_cnt. This is a workaround to avoid blackboxed multiplier in the slice boundary calculations
rvfi_mem_prot [(2*memop_cnt + memop_cnt) +: 3] <= ex_mem_trans.prot;
// Using (4*memop_cnt) + (2*memop_cnt) rather than 6*memop_cnt. This is a workaround to avoid blackboxed multiplier in the slice boundary calculations.
rvfi_mem_atop [ ((4*memop_cnt) + (2*memop_cnt)) +: 6] <= 6'd0;
rvfi_mem_memtype [ (2*(memop_cnt+1))-1 -: 2] <= ex_mem_trans.memtype;
rvfi_mem_dbg [ (1*(memop_cnt+1))-1 -: 1] <= ex_mem_trans.dbg;
end
else if (lsu_split_2nd_xfer_wb && mem_access_blocked_wb) begin
// 2nd transfer of a split misaligned is blocked. Clear related bits in rmask/wmask
Expand Down Expand Up @@ -1546,21 +1556,11 @@ module cv32e40s_rvfi
assign rvfi_csr_wdata_d.tdata[2] = csr_tdata2_n_i;
assign rvfi_csr_wmask_d.tdata[2] = csr_tdata2_we_i ? '1 : '0;

assign rvfi_csr_rdata_d.tdata[3] = csr_tdata3_q_i;
assign rvfi_csr_rmask_d.tdata[3] = '1;
assign rvfi_csr_wdata_d.tdata[3] = csr_tdata3_n_i;
assign rvfi_csr_wmask_d.tdata[3] = csr_tdata3_we_i ? '1 : '0;

assign rvfi_csr_rdata_d.tinfo = csr_tinfo_q_i;
assign rvfi_csr_rmask_d.tinfo = '1;
assign rvfi_csr_wdata_d.tinfo = csr_tinfo_n_i;
assign rvfi_csr_wmask_d.tinfo = csr_tinfo_we_i ? '1 : '0;

assign rvfi_csr_rdata_d.tcontrol = csr_tcontrol_q_i;
assign rvfi_csr_rmask_d.tcontrol = '1;
assign rvfi_csr_wdata_d.tcontrol = csr_tcontrol_n_i;
assign rvfi_csr_wmask_d.tcontrol = csr_tcontrol_we_i ? '1 : '0;

// Debug / Trace
assign ex_csr_rdata_d.nmip = csr_dcsr_q_i[3]; // dcsr.nmip is autonomous. Propagate read value from EX stage
assign rvfi_csr_rdata_d.dcsr = {csr_dcsr_q_i[31:4], ex_csr_rdata.nmip, csr_dcsr_q_i[2:0]};
Expand Down Expand Up @@ -1900,17 +1900,13 @@ module cv32e40s_rvfi
assign rvfi_csr_tselect_wmask = rvfi_csr_wmask.tselect;
assign rvfi_csr_tdata_rdata = rvfi_csr_rdata.tdata;
assign rvfi_csr_tdata_rmask[0] = '0; // Does not exist
assign rvfi_csr_tdata_rmask[3:1] = rvfi_csr_rmask.tdata[3:1];
assign rvfi_csr_tdata_rmask[2:1] = rvfi_csr_rmask.tdata[2:1];
assign rvfi_csr_tdata_wdata = rvfi_csr_wdata.tdata;
assign rvfi_csr_tdata_wmask = rvfi_csr_wmask.tdata;
assign rvfi_csr_tinfo_rdata = rvfi_csr_rdata.tinfo;
assign rvfi_csr_tinfo_rmask = rvfi_csr_rmask.tinfo;
assign rvfi_csr_tinfo_wdata = rvfi_csr_wdata.tinfo;
assign rvfi_csr_tinfo_wmask = rvfi_csr_wmask.tinfo;
assign rvfi_csr_tcontrol_rdata = rvfi_csr_rdata.tcontrol;
assign rvfi_csr_tcontrol_rmask = rvfi_csr_rmask.tcontrol;
assign rvfi_csr_tcontrol_wdata = rvfi_csr_wdata.tcontrol;
assign rvfi_csr_tcontrol_wmask = rvfi_csr_wmask.tcontrol;
assign rvfi_csr_dcsr_rdata = rvfi_csr_rdata.dcsr;
assign rvfi_csr_dcsr_rmask = rvfi_csr_rmask.dcsr;
assign rvfi_csr_dcsr_wdata = rvfi_csr_wdata.dcsr;
Expand Down
12 changes: 5 additions & 7 deletions bhv/cv32e40s_wrapper.sv
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ module cv32e40s_wrapper
.tselect_q (core_i.cs_registers_i.debug_triggers_i.gen_triggers.tselect_q),
.tdata1_q (core_i.cs_registers_i.debug_triggers_i.gen_triggers.tdata1_q),
.tdata2_q (core_i.cs_registers_i.debug_triggers_i.gen_triggers.tdata2_q),
.trigger_match_if_wb (core_i.ex_wb_pipe.trigger_match),
.trigger_match_ex_wb (core_i.wpt_match_wb),
.wb_valid_i (core_i.wb_valid),
.*);
end
endgenerate
Expand Down Expand Up @@ -369,7 +372,8 @@ module cv32e40s_wrapper
#(.DEBUG (DEBUG),
.PMA_NUM_REGIONS(PMA_NUM_REGIONS),
.CLIC(CLIC),
.REGFILE_NUM_READ_PORTS(core_i.REGFILE_NUM_READ_PORTS))
.REGFILE_NUM_READ_PORTS(core_i.REGFILE_NUM_READ_PORTS),
.DBG_NUM_TRIGGERS(DBG_NUM_TRIGGERS))
core_sva (// probed cs_registers signals
.cs_registers_mie_q (core_i.cs_registers_i.mie_q),
.cs_registers_mepc_n (core_i.cs_registers_i.mepc_n),
Expand Down Expand Up @@ -731,9 +735,6 @@ endgenerate
.csr_tdata2_n_i ( core_i.cs_registers_i.debug_triggers_i.tdata2_n_r ),
.csr_tdata2_q_i ( core_i.cs_registers_i.tdata2_rdata ),
.csr_tdata2_we_i ( core_i.cs_registers_i.debug_triggers_i.tdata2_we_r ),
.csr_tdata3_n_i ( core_i.cs_registers_i.debug_triggers_i.tdata3_n ),
.csr_tdata3_q_i ( core_i.cs_registers_i.tdata3_rdata ),
.csr_tdata3_we_i ( core_i.cs_registers_i.tdata3_we ),
.csr_tinfo_n_i ( core_i.cs_registers_i.debug_triggers_i.tinfo_n ),
.csr_tinfo_q_i ( core_i.cs_registers_i.tinfo_rdata ),
.csr_tinfo_we_i ( core_i.cs_registers_i.tinfo_we ),
Expand Down Expand Up @@ -761,9 +762,6 @@ endgenerate
.csr_mstatush_n_i ( core_i.cs_registers_i.mstatush_n ),
.csr_mstatush_q_i ( core_i.cs_registers_i.mstatush_rdata ),
.csr_mstatush_we_i ( core_i.cs_registers_i.mstatush_we ),
.csr_tcontrol_n_i ( core_i.cs_registers_i.debug_triggers_i.tcontrol_n ),
.csr_tcontrol_q_i ( core_i.cs_registers_i.tcontrol_rdata ),
.csr_tcontrol_we_i ( core_i.cs_registers_i.tcontrol_we ),
.csr_tselect_n_i ( core_i.cs_registers_i.debug_triggers_i.tselect_n ),
.csr_tselect_q_i ( core_i.cs_registers_i.tselect_rdata ),
.csr_tselect_we_i ( core_i.cs_registers_i.tselect_we ),
Expand Down
4 changes: 0 additions & 4 deletions bhv/include/cv32e40s_wrapper.vh
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,6 @@
.rvfi_csr_tinfo_wmask(),\
.rvfi_csr_tinfo_rdata(),\
.rvfi_csr_tinfo_wdata(),\
.rvfi_csr_tcontrol_rmask(),\
.rvfi_csr_tcontrol_wmask(),\
.rvfi_csr_tcontrol_rdata(),\
.rvfi_csr_tcontrol_wdata(),\
.rvfi_csr_dcsr_rmask(),\
.rvfi_csr_dcsr_wmask(),\
.rvfi_csr_dcsr_rdata(),\
Expand Down
2 changes: 1 addition & 1 deletion rtl/cv32e40s_controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ module cv32e40s_controller import cv32e40s_pkg::*;

input ex_wb_pipe_t ex_wb_pipe_i,
input mpu_status_e mpu_status_wb_i, // MPU status (WB stage)
input logic wpt_match_wb_i, // LSU watchpoint trigger in WB
input logic [31:0] wpt_match_wb_i, // LSU watchpoint trigger in WB
input align_status_e align_status_wb_i, // Aligned status (atomics and mret pointers) in WB

// Last operation bits
Expand Down
15 changes: 12 additions & 3 deletions rtl/cv32e40s_controller_fsm.sv
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ module cv32e40s_controller_fsm import cv32e40s_pkg::*;
input logic abort_op_wb_i, // WB stage contains an (to be) aborted instruction or sequence
input mpu_status_e mpu_status_wb_i, // MPU status (WB timing)
input align_status_e align_status_wb_i, // Aligned status (atomics) in WB
input logic wpt_match_wb_i, // LSU watchpoint trigger (WB)
input logic [31:0] wpt_match_wb_i, // LSU watchpoint trigger (WB)


// From LSU (WB)
Expand Down Expand Up @@ -183,7 +183,7 @@ module cv32e40s_controller_fsm import cv32e40s_pkg::*;
logic mret_ptr_in_wb; // CLIC pointer caused by mret is in WB
logic dret_in_wb;
logic ebreak_in_wb;
logic trigger_match_in_wb; // mcontrol6 trigger in WB
logic trigger_match_in_wb; // mcontrol2/6 trigger in WB
logic etrigger_in_wb; // exception trigger in WB
logic clic_ptr_in_wb; // CLIC pointer caused by directly acking an SHV is in WB (no mret)

Expand Down Expand Up @@ -447,7 +447,7 @@ module cv32e40s_controller_fsm import cv32e40s_pkg::*;

// Trigger match in wb
// Trigger_match during debug mode is masked in the trigger logic inside cs_registers.sv
assign trigger_match_in_wb = ((ex_wb_pipe_i.trigger_match || wpt_match_wb_i) && ex_wb_pipe_i.instr_valid);
assign trigger_match_in_wb = ((|ex_wb_pipe_i.trigger_match) || (|wpt_match_wb_i)) && ex_wb_pipe_i.instr_valid;

// Only set the etrigger_in_wb flag when wb_valid is true (WB is not halted or killed).
// If a higher priority event than taking an exception (NMI, external debug or interrupts) are present, wb_valid_i will be
Expand Down Expand Up @@ -719,6 +719,8 @@ module cv32e40s_controller_fsm import cv32e40s_pkg::*;
debug_cause_n = DBG_CAUSE_NONE;
debug_mode_n = debug_mode_q;
ctrl_fsm_o.debug_csr_save = 1'b0;
ctrl_fsm_o.debug_trigger_hit = '0; // Mask of which triggers did hit.
ctrl_fsm_o.debug_trigger_hit_update = 1'b0; // Signal that hit bits of mcontrol6 shall be written.
ctrl_fsm_o.block_data_addr = 1'b0;

// Single step halting of IF
Expand Down Expand Up @@ -1184,6 +1186,13 @@ module cv32e40s_controller_fsm import cv32e40s_pkg::*;
ctrl_fsm_o.csr_save_cause = !(ebreak_in_wb && debug_mode_q); // No CSR update for ebreak in debug mode
ctrl_fsm_o.debug_csr_save = 1'b1;

// If a trigger was hit, signal that mcontrol6 hit1 and hit0 bits should be written.
// Only triggers configured as mcontrol6 will perform the actual write within debug_triggers.
if (debug_cause_q == DBG_CAUSE_TRIGGER) begin
ctrl_fsm_o.debug_trigger_hit_update = 1'b1;
ctrl_fsm_o.debug_trigger_hit = ex_wb_pipe_i.trigger_match | wpt_match_wb_i;
end

// debug_cause_q set when decision was made to enter debug
if (debug_cause_q != DBG_CAUSE_STEP) begin
// Kill pipeline
Expand Down
Loading