Skip to content

Commit dbb06c3

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. The first syntax I used for this (which is equivalent to the previous version, but without noise from the macro) uses two "clocks" and is of the form @(negedge rst_aon_ni) 1 |=> @(posedge clk_aon_i) XYZ Here, the |=> waits for the event on the right hand side, so it means "On the first clock edge after reset is asserted, XYZ". Very nice! Unfortunately, this isn't actually supported by Verible's SystemVerilog front-end. Grr! I was very annoyed at first, but realised that there's actually an even cleaner way to do it. Because this is a bound-in interface, we can easily define a helper signal. This commit defines a "start_of_reset" flag, which set when reset is asserted and then cleared on the first clock. Now, the properties can be very simple, looking like: start_of_reset -> XYZ (checked on the positive edge of clk_aon_i because of the default clocking statement). That's even shorter! Yippee! When I initially wrote this, I worried about the scheduling because we clear start_of_reset on the clock edge and look at the value at the same time. Fortunately, this is ok: the value tested in the expression is its value from the preponed region (see IEEE 1800, 16.5.1), so we'll get the value that hasn't yet been cleared. Signed-off-by: Rupert Swarbrick <[email protected]>
1 parent 80db9bb commit dbb06c3

File tree

1 file changed

+44
-26
lines changed

1 file changed

+44
-26
lines changed

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

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,62 @@
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+
default clocking @(posedge clk_aon_i); endclocking
28+
29+
if (1) begin : gen_aon_assertions
30+
default disable iff !rst_aon_ni;
31+
32+
// FSM software reset
33+
FsmStateSwReset_A: assert property (cfg_fsm_rst_i |=> fsm_state_q == FsmResetState);
34+
PwrupTimerCntSwReset_A: assert property (cfg_fsm_rst_i |=> pwrup_timer_cnt_q == 0);
35+
WakeupTimerCntSwReset_A: assert property (cfg_fsm_rst_i |=> wakeup_timer_cnt_q == 0);
36+
NpSampleCntSwReset_A: assert property (cfg_fsm_rst_i |=> np_sample_cnt_q == 0);
37+
LpSampleCntSwReset_A: assert property (cfg_fsm_rst_i |=> lp_sample_cnt_q == 0);
38+
39+
// Check connectivity of the state output register (this is used for debug only).
40+
FsmDebugOut_A: assert property (fsm_state_q === tb.dut.u_reg.hw2reg.adc_fsm_state.d);
41+
end
42+
43+
// FSM hardware reset
44+
//
45+
// These assertions contain properties that have a check on the first posedge of clk_aon_i after
46+
// the hardware reset is applied. Note that this clock edge may happen during or after the reset
47+
// (and the assertions are expected to be true either way).
48+
49+
bit start_of_reset;
50+
always @(negedge rst_aon_ni) begin
51+
start_of_reset <= 1;
52+
end
53+
always @(posedge clk_aon_i) begin
54+
start_of_reset <= 0;
55+
end
56+
57+
FsmStateHwReset_A: assert property (start_of_reset -> fsm_state_q == FsmResetState);
58+
PwrupTimerCntHwReset_A: assert property (start_of_reset -> pwrup_timer_cnt_q == 0);
59+
WakeupTimerCntHwReset_A: assert property (start_of_reset -> wakeup_timer_cnt_q == 0);
60+
NpSampleCntHwReset_A: assert property (start_of_reset -> np_sample_cnt_q == 0);
61+
LpSampleCntHwReset_A: assert property (start_of_reset -> lp_sample_cnt_q == 0);
4462

4563
endinterface

0 commit comments

Comments
 (0)