Skip to content

Commit 32e8406

Browse files
Merge pull request #747 from silabs-oysteink/silabs-oysteink_issue-410
Fix for issue #410
2 parents aa34a2a + 95b1fec commit 32e8406

7 files changed

+70
-29
lines changed

bhv/cv32e40x_wrapper.sv

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ module cv32e40x_wrapper
231231
.lsu_trans_valid_i (core_i.load_store_unit_i.trans_valid),
232232
.csr_en_id_i (core_i.id_stage_i.csr_en),
233233
.ptr_in_if_i (core_i.if_stage_i.ptr_in_if_o),
234+
.instr_req_o (core_i.instr_req_o),
235+
.instr_dbg_o (core_i.instr_dbg_o),
234236
.*);
235237
bind cv32e40x_cs_registers:
236238
core_i.cs_registers_i
@@ -266,7 +268,10 @@ module cv32e40x_wrapper
266268
core_i.if_stage_i.prefetch_unit_i
267269
cv32e40x_prefetch_unit_sva
268270
#(.SMCLIC(SMCLIC))
269-
prefetch_unit_sva (.*);
271+
prefetch_unit_sva (
272+
.ctrl_fsm_cs (core_i.controller_i.controller_fsm_i.ctrl_fsm_cs),
273+
.debug_req_i (core_i.debug_req_i),
274+
.*);
270275

271276
generate
272277
if(M_EXT == M) begin: div_sva

rtl/cv32e40x_controller_fsm.sv

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -669,17 +669,20 @@ module cv32e40x_controller_fsm import cv32e40x_pkg::*;
669669
RESET: begin
670670
ctrl_fsm_o.instr_req = 1'b0;
671671
if (fetch_enable_i) begin
672-
ctrl_fsm_ns = BOOT_SET;
672+
if (debug_req_i) begin
673+
// Not raising instr_req to prevent fetching until we are in debug mode
674+
ctrl_fsm_o.instr_req = 1'b0;
675+
ctrl_fsm_o.pc_mux = PC_BOOT;
676+
ctrl_fsm_o.pc_set = 1'b1; // pc_set is required for propagating boot address to dpc (from IF stage)
677+
ctrl_fsm_ns = DEBUG_TAKEN;
678+
end else begin
679+
ctrl_fsm_o.instr_req = 1'b1;
680+
ctrl_fsm_o.pc_mux = PC_BOOT;
681+
ctrl_fsm_o.pc_set = 1'b1;
682+
ctrl_fsm_ns = FUNCTIONAL;
683+
end
673684
end
674685
end
675-
// BOOT_SET state required to prevent (timing) path from
676-
// fetch_enable_i via pc_set to instruction interface outputs
677-
BOOT_SET: begin
678-
ctrl_fsm_o.instr_req = 1'b1;
679-
ctrl_fsm_o.pc_mux = PC_BOOT;
680-
ctrl_fsm_o.pc_set = 1'b1;
681-
ctrl_fsm_ns = FUNCTIONAL;
682-
end
683686
FUNCTIONAL: begin
684687
// NMI
685688
if (pending_nmi && nmi_allowed) begin
@@ -1346,7 +1349,7 @@ module cv32e40x_controller_fsm import cv32e40x_pkg::*;
13461349

13471350
case (debug_fsm_cs)
13481351
HAVERESET: begin
1349-
if (debug_mode_n || (ctrl_fsm_ns == BOOT_SET)) begin
1352+
if (debug_mode_n || (ctrl_fsm_ns == FUNCTIONAL)) begin
13501353
if (debug_mode_n) begin
13511354
debug_fsm_ns = HALTED;
13521355
end else begin

rtl/include/cv32e40x_pkg.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ typedef enum logic [DIV_OP_WIDTH-1:0]
169169
} div_opcode_e;
170170

171171
// FSM state encoding
172-
typedef enum logic [2:0] { RESET, BOOT_SET, FUNCTIONAL, SLEEP, DEBUG_TAKEN} ctrl_state_e;
172+
typedef enum logic [1:0] { RESET, FUNCTIONAL, SLEEP, DEBUG_TAKEN} ctrl_state_e;
173173

174174
// Debug FSM state encoding
175175
// State encoding done one-hot to ensure that debug_havereset_o, debug_running_o, debug_halted_o

sva/cv32e40x_alignment_buffer_sva.sv

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,6 @@ module cv32e40x_alignment_buffer_sva
186186
`uvm_error("Alignment buffer SVA",
187187
$sformatf("Wrong PC after branch"))
188188

189-
// Check that a taken branch can only occur if fetching is requested
190-
property p_branch_implies_req;
191-
@(posedge clk) disable iff (!rst_n) (ctrl_fsm_i.pc_set) |-> (ctrl_fsm_i.instr_req);
192-
endproperty
193-
194-
a_branch_implies_req:
195-
assert property(p_branch_implies_req)
196-
else
197-
`uvm_error("Alignment buffer SVA",
198-
$sformatf("Taken branch occurs while fetching is not requested"))
199189

200190
// Check that we never exceed two outstanding transactions
201191
property p_max_outstanding;

sva/cv32e40x_controller_fsm_sva.sv

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ module cv32e40x_controller_fsm_sva
108108
input pipe_pc_mux_e pipe_pc_mux_ctrl,
109109
input logic ptr_in_if_i,
110110
input logic etrigger_in_wb,
111-
input logic lsu_wpt_match_wb_i
111+
input logic lsu_wpt_match_wb_i,
112+
input logic debug_req_i,
113+
input logic fetch_enable_i,
114+
input logic instr_req_o,
115+
input logic instr_dbg_o
112116
);
113117

114118

@@ -198,11 +202,11 @@ module cv32e40x_controller_fsm_sva
198202
(ctrl_fsm_o.kill_wb) |-> (!csr_we_i) )
199203
else `uvm_error("controller", "csr written while kill_wb is asserted")
200204

201-
// Check that no stages have valid instructions using RESET or BOOT_SET
205+
// Check that no stages have valid instructions using RESET
202206
a_reset_if_csr :
203207
assert property (@(posedge clk) disable iff (!rst_n)
204-
((ctrl_fsm_cs == RESET) || (ctrl_fsm_cs == BOOT_SET)) |-> (!if_valid_i && !if_id_pipe_i.instr_valid && !id_ex_pipe_i.instr_valid && !ex_wb_pipe_i.instr_valid) )
205-
else `uvm_error("controller", "Instruction valid during RESET or BOOT_SET")
208+
((ctrl_fsm_cs == RESET)) |-> (!if_valid_i && !if_id_pipe_i.instr_valid && !id_ex_pipe_i.instr_valid && !ex_wb_pipe_i.instr_valid) )
209+
else `uvm_error("controller", "Instruction valid during RESET")
206210

207211
// Check that no LSU insn can be in EX when there is a WFI or WFE in WB
208212
a_wfi_wfe_lsu_csr :
@@ -870,5 +874,9 @@ end
870874
|->
871875
(abort_op_wb_i && (ctrl_fsm_ns == DEBUG_TAKEN)))
872876
else `uvm_error("controller", "Debug not entered on a WPT match")
877+
878+
879+
880+
873881
endmodule
874882

sva/cv32e40x_core_sva.sv

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ module cv32e40x_core_sva
3232
)
3333
(
3434
input logic clk,
35+
input logic clk_i,
3536
input logic rst_ni,
3637

3738
input ctrl_fsm_t ctrl_fsm,
@@ -54,6 +55,9 @@ module cv32e40x_core_sva
5455
input logic branch_taken_in_ex,
5556
input logic last_op_wb,
5657

58+
input logic fetch_enable_i,
59+
input logic debug_req_i,
60+
5761
input alu_op_a_mux_e alu_op_a_mux_sel_id_i,
5862
input alu_op_b_mux_e alu_op_b_mux_sel_id_i,
5963
input logic [31:0] operand_a_id_i,
@@ -69,6 +73,8 @@ module cv32e40x_core_sva
6973
// probed OBI signals
7074
input logic [31:0] instr_addr_o,
7175
input logic [1:0] instr_memtype_o,
76+
input logic instr_req_o,
77+
input logic instr_dbg_o,
7278
input logic [1:0] data_memtype_o,
7379
input logic data_req_o,
7480
input logic data_we_o,
@@ -554,5 +560,29 @@ endproperty;
554560

555561
a_no_irq_after_lsu: assert property(p_no_irq_after_lsu)
556562
else `uvm_error("core", "Interrupt taken after disabling");
557-
endmodule // cv32e40x_core_sva
558563

564+
// If debug_req_i is asserted when fetch_enable_i gets asserted we should not execute any
565+
// instruction until the core is in debug mode.
566+
a_reset_into_debug:
567+
assert property (@(posedge clk_i) disable iff (!rst_ni)
568+
(ctrl_fsm_cs == RESET) &&
569+
fetch_enable_i &&
570+
debug_req_i
571+
##1
572+
debug_req_i // Controller gets a one cycle delayed fetch enable, must keep debug_req_i asserted for two cycles
573+
|->
574+
!wb_valid until (wb_valid && ctrl_fsm.debug_mode))
575+
else `uvm_error("controller", "Debug out of reset but executed instruction outside debug mode")
576+
577+
// When entering debug out of reset, the first fetch must also flag debug on the instruction OBI interface
578+
a_first_fetch_debug:
579+
assert property (@(posedge clk_i) disable iff (!rst_ni)
580+
(ctrl_fsm_cs == RESET) &&
581+
fetch_enable_i &&
582+
debug_req_i
583+
##1
584+
debug_req_i // Controller gets a one cycle delayed fetch enable, must keep debug_req_i asserted for two cycles
585+
|->
586+
!instr_req_o until (instr_req_o && instr_dbg_o))
587+
else `uvm_error("controller", "Debug out of reset but fetched without setting instr_dbg_o")
588+
endmodule // cv32e40x_core_sva

sva/cv32e40x_prefetch_unit_sva.sv

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ module cv32e40x_prefetch_unit_sva import cv32e40x_pkg::*;
3232
input logic prefetch_ready_i,
3333
input logic trans_valid_o,
3434
input logic trans_ready_i,
35-
input logic fetch_ptr_resp
35+
input logic fetch_ptr_resp,
36+
input ctrl_state_e ctrl_fsm_cs,
37+
input logic debug_req_i
3638

3739
);
3840

@@ -46,8 +48,11 @@ module cv32e40x_prefetch_unit_sva import cv32e40x_pkg::*;
4648
else `uvm_error("prefetch_buffer", "Assertion a_branch_halfword_aligned failed")
4749

4850
// Check that a taken branch can only occur if fetching is requested
51+
// Exception while in RESET state and debug_request_i is high - in that case we want to
52+
// do a pc_set to update the IF stage PC without actually fetching anything. This is to ensure
53+
// that dpc gets the correct (boot) address when going from reset to debug.
4954
property p_branch_implies_req;
50-
@(posedge clk) (ctrl_fsm_i.pc_set) |-> (ctrl_fsm_i.instr_req);
55+
@(posedge clk) (ctrl_fsm_i.pc_set) && !((ctrl_fsm_cs == RESET) && debug_req_i) |-> (ctrl_fsm_i.instr_req);
5156
endproperty
5257

5358
a_branch_implies_req : assert property(p_branch_implies_req)

0 commit comments

Comments
 (0)