Skip to content

Commit 010138d

Browse files
Merge pull request #2466 from dd-baoshan/cv32e40p/dev
Fix issue found in random tests
2 parents 7693225 + c9d4bfe commit 010138d

File tree

1 file changed

+58
-42
lines changed

1 file changed

+58
-42
lines changed

cv32e40p/env/uvme/cov/uvme_rv32x_hwloop_covg.sv

+58-42
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class uvme_rv32x_hwloop_covg # (
9999
local bit [(ILEN-1):0] insn_list_in_hwloop_``TYPE [HWLOOP_NB][$]; \
100100
local bit [(ILEN-1):0] mc_insn_list_in_hwloop_``TYPE [HWLOOP_NB][$]; \
101101
local bit [31:0] irq_vect_``TYPE [HWLOOP_NB][$]; \
102-
local bit lpend_has_pending_irq_``TYPE [HWLOOP_NB] = '{default:0}; \
102+
local bit prev_is_lpend_``TYPE [HWLOOP_NB] = '{default:0}; \
103103
local bit done_insn_list_capture_``TYPE [HWLOOP_NB] = '{default:0}; \
104104
local bit done_insn_list_capture_d1_``TYPE [HWLOOP_NB] = '{default:0}; \
105105
local s_hwloop_cov hwloop_cov_``TYPE [HWLOOP_NB] = '{default:0};
@@ -121,9 +121,12 @@ class uvme_rv32x_hwloop_covg # (
121121
int enter_hwloop_sub_cnt = 0;
122122
bit pending_irq = 0;
123123
bit pending_irq_ack = 0;
124+
bit is_init_mmode_mret = 0;
124125
logic [31:0] valid_irq_prev = 32'h0;
125126
logic [31:0] prev_irq_onehot_priority = 0, prev_irq_onehot_priority_always = 0;
126127
bit prev_irq_onehot_priority_is_0 = 0;
128+
bit prev_is_trap = 0;
129+
bit irq_period = 0; // track irq handling period throught the simulation
127130

128131
dcsr_cause_t dcsr_cause;
129132
exception_code_t exception_code;
@@ -485,11 +488,14 @@ class uvme_rv32x_hwloop_covg # (
485488
end // UPDATE_HWLOOP_STAT \
486489
for (int i=0; i<HWLOOP_NB; i++) begin : COLLECT_INSTR \
487490
if (hwloop_stat_``TYPE``.execute_instr_in_hwloop[i]) begin \
488-
lpend_has_pending_irq_``TYPE``[i] = 0; \
491+
prev_is_lpend_``TYPE``[i] = 0; \
489492
done_insn_list_capture_d1_``TYPE``[i] = done_insn_list_capture_``TYPE``[i]; \
490493
unique case (i) \
491494
0 : begin // nested or single is the same \
492-
if (!done_insn_list_capture_``TYPE``[i]) begin \
495+
if (!done_insn_list_capture_``TYPE``[i] && has_trap_due2_dbg_match_trig) begin \
496+
// bypass and do nothing \
497+
end \
498+
else if (!done_insn_list_capture_``TYPE``[i]) begin \
493499
if (is_illegal) insn_list_in_hwloop_``TYPE``[i].push_back(INSN_ILLEGAL); \
494500
else if (is_ebreakm) insn_list_in_hwloop_``TYPE``[i].push_back(INSN_EBREAKM); \
495501
else insn_list_in_hwloop_``TYPE``[i].push_back(cv32e40p_rvvi_vif.insn); \
@@ -510,7 +516,7 @@ class uvme_rv32x_hwloop_covg # (
510516
check_ebreakm_entry(i); \
511517
end \
512518
if (is_pc_equal_lpend(hwloop_stat_``TYPE``.hwloop_csr, i, 0, cv32e40p_rvvi_vif.pc_rdata) && hwloop_stat_``TYPE``.track_lp_cnt[i] != 0) begin \
513-
if (pending_irq_ack && cv32e40p_rvvi_vif.trap) lpend_has_pending_irq_``TYPE``[i] = 1; \
519+
prev_is_lpend_``TYPE``[i] = 1; \
514520
hwloop_stat_``TYPE``.track_lp_cnt[i]--; \
515521
done_insn_list_capture_``TYPE``[i] = 1; \
516522
assert(hwloop_stat_``TYPE``.track_lp_cnt[i] >= 0); \
@@ -524,7 +530,10 @@ class uvme_rv32x_hwloop_covg # (
524530
else if (hwloop_stat_``TYPE``.hwloop_type == NESTED && hwloop_stat_``TYPE``.track_lp_cnt[0] == 0 && in_nested_loop0) begin \
525531
in_nested_loop0 = 0; continue; \
526532
end \
527-
if (!done_insn_list_capture_``TYPE``[i]) begin \
533+
if (!done_insn_list_capture_``TYPE``[i] && has_trap_due2_dbg_match_trig) begin \
534+
// bypass and do nothing \
535+
end \
536+
else if (!done_insn_list_capture_``TYPE``[i]) begin \
528537
if (is_illegal) insn_list_in_hwloop_``TYPE``[i].push_back(INSN_ILLEGAL); \
529538
else if (is_ebreakm) insn_list_in_hwloop_``TYPE``[i].push_back(INSN_EBREAKM); \
530539
else insn_list_in_hwloop_``TYPE``[i].push_back(cv32e40p_rvvi_vif.insn); \
@@ -545,7 +554,7 @@ class uvme_rv32x_hwloop_covg # (
545554
check_ebreakm_entry(i); \
546555
end \
547556
if (is_pc_equal_lpend(hwloop_stat_``TYPE``.hwloop_csr, i, 0, cv32e40p_rvvi_vif.pc_rdata) && hwloop_stat_``TYPE``.track_lp_cnt[i] != 0) begin \
548-
if (pending_irq_ack && cv32e40p_rvvi_vif.trap) lpend_has_pending_irq_``TYPE``[i] = 1; \
557+
prev_is_lpend_``TYPE``[i] = 1; \
549558
hwloop_stat_``TYPE``.track_lp_cnt[i]--; \
550559
done_insn_list_capture_``TYPE``[i] = 1; \
551560
assert(hwloop_stat_``TYPE``.track_lp_cnt[i] >= 0); \
@@ -747,7 +756,7 @@ class uvme_rv32x_hwloop_covg # (
747756
end \
748757
hwloop_evt_loc_``TYPE``[i][MC_INSN].delete(); \
749758
hwloop_cov_``TYPE``[i].en_cov_mc_insn = 0; \
750-
lpend_has_pending_irq_``TYPE``[i] = 0; \
759+
prev_is_lpend_``TYPE``[i] = 0; \
751760
done_insn_list_capture_``TYPE``[i] = 0; \
752761
done_insn_list_capture_d1_``TYPE``[i] = 0; \
753762
hwloop_cov_``TYPE``[i] = hwloop_cov_init[i]; \
@@ -783,7 +792,7 @@ class uvme_rv32x_hwloop_covg # (
783792
endfunction : check_exception_entry
784793

785794
function void check_ebreakm_entry(int lp_idx);
786-
if (cv32e40p_rvvi_vif.csr_dcsr_ebreakm && cv32e40p_rvvi_vif.insn == TB_INSTR_EBREAK) begin
795+
if (is_ebreakm) begin
787796
if (lp_idx) begin `IF_CURRENT_IS_MAIN_HWLOOP(1, DBG_EBREAKM) end
788797
else begin `IF_CURRENT_IS_MAIN_HWLOOP(0, DBG_EBREAKM) end
789798
end
@@ -821,8 +830,8 @@ class uvme_rv32x_hwloop_covg # (
821830
cv32e40p_rvvi_vif.csr_trig_execute && cv32e40p_rvvi_vif.csr_trig_pc == cv32e40p_rvvi_vif.pc_rdata // debug trig match assert trap
822831
) begin
823832
is_trap = 0;
824-
wait (!cv32e40p_rvvi_vif.trap); // bypass and do nothing
825833
has_trap_due2_dbg_match_trig = 1;
834+
wait (!cv32e40p_rvvi_vif.trap); // bypass and do nothing
826835
end
827836
else if ((cv32e40p_rvvi_vif.csr_dcsr_step || !pending_irq_ack) && !is_dbg_mode && !is_irq) begin // set excep flag only if no pending irq is serving, not in irq and not in dbg mode
828837
is_trap = 1;
@@ -850,7 +859,7 @@ class uvme_rv32x_hwloop_covg # (
850859
end
851860
forever begin : SET_PENDING_IRQ_ACK
852861
@(cv32e40p_rvvi_vif.valid_irq);
853-
if (cv32e40p_rvvi_vif.valid_irq < valid_irq_prev) begin
862+
if (cv32e40p_rvvi_vif.valid_irq < valid_irq_prev && !irq_period) begin // currently not cover on nested irq
854863
pending_irq_ack = 1;
855864
end
856865
valid_irq_prev = cv32e40p_rvvi_vif.valid_irq;
@@ -888,20 +897,24 @@ class uvme_rv32x_hwloop_covg # (
888897
is_irq = 0;
889898
end
890899
end // IRQ_EXIT
891-
forever begin : SIGNALS_CHG_WHEN_IS_IRQ_ASSERT
892-
@(posedge is_irq);
893-
if (is_ebreakm) begin // TBD: will ebreakm assert trap?
894-
for (int j=0; j<HWLOOP_NB; j++) begin
895-
logic [31:0] discarded_insn;
896-
if (hwloop_stat_main.execute_instr_in_hwloop[j] && lpend_has_pending_irq_main[j]) begin
897-
discarded_insn = insn_list_in_hwloop_main[j].pop_back();
898-
assert(discarded_insn == INSN_EBREAKM);
899-
void'(hwloop_evt_loc_main[j][DBG_EBREAKM].pop_back());
900-
hwloop_stat_main.track_lp_cnt[j]++; lpend_has_pending_irq_main[j] = 0;
901-
end
902-
end // for
900+
forever begin : INIT_MACHINE_MODE
901+
@(posedge cv32e40p_rvvi_vif.clk);
902+
if (cv32e40p_rvvi_vif.valid && cv32e40p_rvvi_vif.insn == TB_INSTR_MRET) begin
903+
if (cv32e40p_rvvi_vif.pc_rdata < cv32e40p_rvvi_vif.mtvec_base_addr) is_init_mmode_mret = 1;
903904
end
904-
end // SIGNALS_CHG_WHEN_IS_IRQ_ASSERT
905+
// revert pending_irq_ack that triggered during init_machine_mode
906+
if (is_init_mmode_mret && pending_irq_ack) begin
907+
is_init_mmode_mret = 0;
908+
pending_irq_ack = 0;
909+
end
910+
end // INIT_MACHINE_MODE
911+
forever begin : IRQ_PERIOD
912+
@(posedge cv32e40p_rvvi_vif.clk);
913+
if (cv32e40p_rvvi_vif.valid) begin
914+
if (pc_is_mtvec_addr() && is_mcause_irq()) irq_period = 1;
915+
if (irq_period && cv32e40p_rvvi_vif.insn == TB_INSTR_MRET) irq_period = 0;
916+
end
917+
end // IRQ_PERIOD
905918

906919
forever begin : DBG_ENTRY
907920
// wait (hwloop_stat_main.execute_instr_in_hwloop[0] | hwloop_stat_main.execute_instr_in_hwloop[1]);
@@ -936,19 +949,14 @@ class uvme_rv32x_hwloop_covg # (
936949
is_dbg_mode = 0; is_ebreakm = 0;
937950
end
938951
end // DBG_EXIT
939-
forever begin : SIGNALS_CHG_WHEN_IS_DBG_MODE_ASSERT
940-
@(posedge is_dbg_mode);
941-
lpend_has_pending_irq_main[0] = 0;
942-
lpend_has_pending_irq_main[1] = 0;
943-
end // SIGNALS_CHG_WHEN_IS_DBG_MODE_ASSERT
944952

945953
join_none // Background threads - END
946954

947955
forever begin
948956
@(posedge cv32e40p_rvvi_vif.clk);
949957
if (cv32e40p_rvvi_vif.valid) begin : VALID_IS_HIGH
950958

951-
if (enter_hwloop_sub) begin
959+
if (enter_hwloop_sub) begin : ENTER_HWLOOP_SUB
952960
enter_hwloop_sub_cnt++;
953961
if (is_trap && is_dbg_mode && !cv32e40p_rvvi_vif.csr_dcsr_step && enter_hwloop_sub_cnt == 1) begin : TRAP_DUETO_DBG_ENTRY // exception trap and debug are b2b cycles (except debug step)
954962
has_pending_trap_due2_dbg = 1;
@@ -969,9 +977,10 @@ class uvme_rv32x_hwloop_covg # (
969977
else if (pc_is_mtvec_addr() && is_mcause_irq()) begin : IRQ_ENTRY
970978
if (hwloop_stat_main.execute_instr_in_hwloop[0] | hwloop_stat_main.execute_instr_in_hwloop[1]) begin
971979
if (is_trap && enter_hwloop_sub_cnt == 1) begin : TRAP_DUETO_IRQ_ENTRY // exception trap and irq are b2b cycles
972-
if (hwloop_stat_main.execute_instr_in_hwloop[0] && lpend_has_pending_irq_main[0]) begin hwloop_stat_main.track_lp_cnt[0]++; lpend_has_pending_irq_main[0] = 0; end // revert lp_cnt
973-
if (hwloop_stat_main.execute_instr_in_hwloop[1] && lpend_has_pending_irq_main[1]) begin hwloop_stat_main.track_lp_cnt[1]++; lpend_has_pending_irq_main[1] = 0; end // revert lp_cnt
974-
has_pending_trap_due2_irq = 1; is_trap = 0;
980+
if (prev_is_lpend_main[0] && prev_is_trap) hwloop_stat_main.track_lp_cnt[0]++;
981+
if (prev_is_lpend_main[1] && prev_is_trap) hwloop_stat_main.track_lp_cnt[1]++;
982+
has_pending_trap_due2_irq = 1;
983+
is_ebreak = 0; is_ecall = 0; is_illegal = 0; is_trap = 0;
975984
enter_hwloop_sub = 0; enter_hwloop_sub_cnt = 0;
976985
pending_irq = 0;
977986
`uvm_info(_header, $sformatf("DEBUG - EXCEPTION Entry is replaced with IRQ Entry (higher priority)"), UVM_DEBUG);
@@ -998,41 +1007,48 @@ class uvme_rv32x_hwloop_covg # (
9981007
is_ebreak = 0; is_ecall = 0; is_illegal = 0; is_trap = 0;
9991008
end
10001009
prev_pc_rdata_sub = cv32e40p_rvvi_vif.pc_rdata;
1001-
end
10021010

1003-
else begin : MAIN
1011+
end // ENTER_HWLOOP_SUB
1012+
1013+
else begin : ENTER_HWLOOP_MAIN
10041014
if (pc_is_mtvec_addr() && is_mcause_irq()) begin : IRQ_ENTRY
10051015
if (hwloop_stat_main.execute_instr_in_hwloop[0] | hwloop_stat_main.execute_instr_in_hwloop[1]) begin
10061016
pending_irq = 0;
10071017
`IF_CURRENT_IS_MAIN_HWLOOP(0, IS_IRQ)
10081018
`IF_CURRENT_IS_MAIN_HWLOOP(1, IS_IRQ)
10091019
update_prev_irq_onehot_priority();
10101020
`uvm_info(_header, $sformatf("DEBUG - IRQ Entry"), UVM_DEBUG);
1011-
if (lpend_has_pending_irq_main[0]) begin hwloop_stat_main.track_lp_cnt[0]++; lpend_has_pending_irq_main[0] = 0; end // revert lp_cnt
1012-
if (lpend_has_pending_irq_main[1]) begin hwloop_stat_main.track_lp_cnt[1]++; lpend_has_pending_irq_main[1] = 0; end // revert lp_cnt
1021+
if (prev_is_lpend_main[0] && prev_is_trap) hwloop_stat_main.track_lp_cnt[0]++;
1022+
if (prev_is_lpend_main[1] && prev_is_trap) hwloop_stat_main.track_lp_cnt[1]++;
10131023
is_irq = 1; wait (!is_irq); continue;
10141024
end
10151025
end // IRQ_ENTRY
1016-
if (has_pending_trap_due2_irq) begin
1026+
if (has_pending_trap_due2_irq) begin
10171027
assert(prev_pc_rdata_main == cv32e40p_rvvi_vif.pc_rdata);
10181028
if (pc_is_mtvec_addr() || (cv32e40p_rvvi_vif.trap && is_trap)) begin is_trap = 1; enter_hwloop_sub = 1; has_pending_trap_due2_irq = 0; continue; end // if pc is exception related
10191029
else begin is_ebreak = 0; is_ecall = 0; is_illegal = 0; is_trap = 0; enter_hwloop_sub = 0; has_pending_trap_due2_irq = 0; continue; end // if pc is non-exception related
10201030
end
1021-
if (is_dbg_mode) begin wait (!is_dbg_mode); continue; end
1031+
if (is_dbg_mode) begin
1032+
if (prev_is_lpend_main[0] && prev_is_trap && !is_ebreakm) hwloop_stat_main.track_lp_cnt[0]++;
1033+
if (prev_is_lpend_main[1] && prev_is_trap && !is_ebreakm) hwloop_stat_main.track_lp_cnt[1]++;
1034+
wait (!is_dbg_mode); continue;
1035+
end
10221036
if (has_pending_trap_due2_dbg) begin // e.g exception event intercept with debug step
10231037
assert (!dcsr_cause_t'(cv32e40p_rvvi_vif.csr_dcsr_cause) != STEP); // this is not mean for step debug
10241038
if (pc_is_mtvec_addr() || (cv32e40p_rvvi_vif.trap && is_trap)) begin is_trap = 1; enter_hwloop_sub = 1; has_pending_trap_due2_dbg = 0; continue; end // if pc is exception related
10251039
else begin is_ebreak = 0; is_ecall = 0; is_illegal = 0; is_trap = 0; enter_hwloop_sub = 0; has_pending_trap_due2_dbg = 0; continue; end // if pc is non-exception related
10261040
end
1027-
if (has_trap_due2_dbg_match_trig) begin // e.g exception event intercept with debug trigger
1028-
has_trap_due2_dbg_match_trig = 0;
1029-
end
10301041
if (cv32e40p_rvvi_vif.csr_dcsr_ebreakm && cv32e40p_rvvi_vif.insn == TB_INSTR_EBREAK) is_ebreakm = 1; else is_ebreakm = 0;
1042+
if (cv32e40p_rvvi_vif.trap) prev_is_trap = 1; else prev_is_trap = 0;
10311043
`CHECK_N_SAMPLE_CSR_HWLOOP(main);
10321044
`CHECK_N_SAMPLE_HWLOOP(main);
1045+
if (has_trap_due2_dbg_match_trig) begin // e.g exception event intercept with debug trigger
1046+
has_trap_due2_dbg_match_trig = 0;
1047+
end
10331048
if (is_ebreak || is_ecall || is_illegal) enter_hwloop_sub = 1;
10341049
prev_pc_rdata_main = cv32e40p_rvvi_vif.pc_rdata;
1035-
end
1050+
1051+
end // ENTER_HWLOOP_MAIN
10361052

10371053
end // VALID_DETECTED
10381054
end // forever

0 commit comments

Comments
 (0)