Skip to content

Commit 1183ec9

Browse files
committed
[adc_ctrl,dv] Expand comments a bit and tidy up adc_ctrl_fsm_sva_if
There is no functional change, but dropping the ASSERT macro makes things a little easier to read. The hardware reset assertions should now be a little more efficient. I don't think we really need to bother asserting that the signals don't magically start changing somewhere in the middle of a reset(!), so I've restructured them slightly to check the first clock after the start of a reset. I also carefully explained how these assertions worked: the multiple clock trick is quite clever and I didn't immediately understand how it worked (until watching a YouTube video from Cadence!). Fortunately, it's dramatically easier to understand once you get rid of the macro and remove the artificial distinction between the two clock signals. Signed-off-by: Rupert Swarbrick <[email protected]>
1 parent 53ab2e5 commit 1183ec9

File tree

1 file changed

+46
-26
lines changed

1 file changed

+46
-26
lines changed

hw/ip/adc_ctrl/dv/sva/adc_ctrl_fsm_sva_if.sv

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,64 @@
22
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
33
// SPDX-License-Identifier: Apache-2.0
44
// System verilog assertions for the adc_ctrl_fsm module
5+
6+
// An interface that is bound into adc_ctrl_fsm, capturing ports with .* (so the input ports are
7+
// named to match signals inside that module).
8+
59
interface adc_ctrl_fsm_sva_if
610
import adc_ctrl_pkg::*;
7-
(
11+
(
812
// adc_ctrl_fsm ports
913
input logic clk_aon_i,
1014
input logic rst_aon_ni,
1115
input logic cfg_fsm_rst_i,
16+
1217
// adc_ctrl_fsm signals
13-
input fsm_state_e fsm_state_q,
14-
input logic [3:0] pwrup_timer_cnt_q,
18+
input fsm_state_e fsm_state_q,
19+
input logic [3:0] pwrup_timer_cnt_q,
1520
input logic [23:0] wakeup_timer_cnt_q,
1621
input logic [15:0] np_sample_cnt_q,
17-
input logic [7:0] lp_sample_cnt_q
22+
input logic [7:0] lp_sample_cnt_q
1823
);
1924

2025
localparam fsm_state_e FsmResetState = PWRDN;
2126

22-
// FSM software reset
23-
`ASSERT(FsmStateSwReset_A, cfg_fsm_rst_i |=> fsm_state_q == FsmResetState, clk_aon_i, !rst_aon_ni)
24-
`ASSERT(PwrupTimerCntSwReset_A, cfg_fsm_rst_i |=> pwrup_timer_cnt_q == 0, clk_aon_i, !rst_aon_ni)
25-
`ASSERT(WakeupTimerCntSwReset_A, cfg_fsm_rst_i |=> wakeup_timer_cnt_q == 0, clk_aon_i,
26-
!rst_aon_ni)
27-
`ASSERT(NpSampleCntSwReset_A, cfg_fsm_rst_i |=> np_sample_cnt_q == 0, clk_aon_i, !rst_aon_ni)
28-
`ASSERT(LpSampleCntSwReset_A, cfg_fsm_rst_i |=> lp_sample_cnt_q == 0, clk_aon_i, !rst_aon_ni)
29-
30-
31-
// FSM hardware reset - checks first clk_aon_i after every hardware reset
32-
`ASSERT(FsmStateHwReset_A, 1 |=> (@(posedge clk_aon_i) fsm_state_q == FsmResetState), !rst_aon_ni,
33-
0)
34-
`ASSERT(PwrupTimerCntHwReset_A, 1 |=> (@(posedge clk_aon_i) pwrup_timer_cnt_q == 0), !rst_aon_ni,
35-
0)
36-
`ASSERT(WakeupTimerCntHwReset_A, 1 |=> (@(posedge clk_aon_i) wakeup_timer_cnt_q == 0),
37-
!rst_aon_ni, 0)
38-
`ASSERT(NpSampleCntHwReset_A, 1 |=> (@(posedge clk_aon_i) np_sample_cnt_q == 0), !rst_aon_ni, 0)
39-
`ASSERT(LpSampleCntHwReset_A, 1 |=> (@(posedge clk_aon_i) lp_sample_cnt_q == 0), !rst_aon_ni, 0)
40-
41-
// Check connectivity of the state output register (this is used for debug only).
42-
`ASSERT(FsmDebugOut_A, fsm_state_q === tb.dut.u_reg.hw2reg.adc_fsm_state.d,
43-
clk_aon_i, !rst_aon_ni)
27+
if (1) begin : gen_aon_assertions
28+
default disable iff !rst_aon_ni;
29+
default clocking @(posedge clk_aon_i); endclocking
30+
31+
// FSM software reset
32+
FsmStateSwReset_A: assert property (cfg_fsm_rst_i |=> fsm_state_q == FsmResetState);
33+
PwrupTimerCntSwReset_A: assert property (cfg_fsm_rst_i |=> pwrup_timer_cnt_q == 0);
34+
WakeupTimerCntSwReset_A: assert property (cfg_fsm_rst_i |=> wakeup_timer_cnt_q == 0);
35+
NpSampleCntSwReset_A: assert property (cfg_fsm_rst_i |=> np_sample_cnt_q == 0);
36+
LpSampleCntSwReset_A: assert property (cfg_fsm_rst_i |=> lp_sample_cnt_q == 0);
37+
38+
// Check connectivity of the state output register (this is used for debug only).
39+
FsmDebugOut_A: assert property (fsm_state_q === tb.dut.u_reg.hw2reg.adc_fsm_state.d);
40+
end
41+
42+
// FSM hardware reset
43+
//
44+
// These assertions contain properties that have a check on the first posedge of clk_aon_i after
45+
// the hardware reset is applied. Note that this clock edge may happen during or after the reset
46+
// (and the assertions are expected to be true either way).
47+
//
48+
// To avoid lots of overlapping matches for the properties, they are expressed in terms of
49+
// @(negedge rst_aon_ni) (note that this matches even at the start of the simulation) and then the
50+
// |=> finds the first posedge on a different clock (clk_aon_i).
51+
FsmStateHwReset_A: assert property (@(negedge rst_aon_ni) 1 |=>
52+
@(posedge clk_aon_i) (fsm_state_q == FsmResetState));
53+
54+
PwrupTimerCntHwReset_A: assert property (@(negedge rst_aon_ni) 1 |=>
55+
@(posedge clk_aon_i) (pwrup_timer_cnt_q == 0));
56+
57+
WakeupTimerCntHwReset_A: assert property (@(negedge rst_aon_ni) 1 |=>
58+
@(posedge clk_aon_i) (wakeup_timer_cnt_q == 0));
59+
60+
NpSampleCntHwReset_A: assert property (@(negedge rst_aon_ni) 1 |=>
61+
@(posedge clk_aon_i) (np_sample_cnt_q == 0));
4462

63+
LpSampleCntHwReset_A: assert property (@(negedge rst_aon_ni) 1 |=>
64+
@(posedge clk_aon_i) (lp_sample_cnt_q == 0));
4565
endinterface

0 commit comments

Comments
 (0)