4 from nmigen
import Elaboratable
, Signal
, Module
5 from nmigen
.asserts
import Assume
, Cover
, Past
, Stable
6 from nmigen
.cli
import rtlil
8 from nmutil
.formaltest
import FHDLTestCase
9 from nmutil
.gtkw
import write_gtkw
11 from soc
.experiment
.alu_fsm
import Shifter
14 # This defines a module to drive the device under test and assert
15 # properties about its outputs
16 class Driver(Elaboratable
):
27 m
.submodules
.dut
= dut
= Shifter(8)
28 # Coverage condition (one bit for each coverage case)
30 # input data to the shifter
34 # transaction count for each port
37 # keep data and valid stable, until accepted
38 with m
.If(Past(dut
.p
.valid_i
) & ~
Past(dut
.p
.ready_o
)):
40 Assume(Stable(dut
.op
.sdir
)),
41 Assume(Stable(dut
.p
.data_i
.data
)),
42 Assume(Stable(dut
.p
.data_i
.shift
)),
43 Assume(Stable(dut
.p
.valid_i
)),
45 # capture transferred input data
46 with m
.If(dut
.p
.ready_o
& dut
.p
.valid_i
):
48 data_i
.eq(dut
.p
.data_i
.data
),
49 shift_i
.eq(dut
.p
.data_i
.shift
),
50 op_sdir
.eq(dut
.op
.sdir
),
51 # increment write counter
52 write_cnt
.eq(write_cnt
+ 1),
54 # check coverage as output data is accepted
55 with m
.If(dut
.n
.ready_i
& dut
.n
.valid_o
):
56 # increment read counter
57 sync
+= read_cnt
.eq(read_cnt
+ 1)
58 # cover zero data, with zero and non-zero shift
60 with m
.If(data_i
== 0):
61 with m
.If(shift_i
== 0):
63 with m
.If(shift_i
[0:2].any() & ~shift_i
[3]):
65 # cover non-zero data, with zero and non-zero shift
67 with m
.If(data_i
!= 0):
68 with m
.If(shift_i
== 0):
70 with m
.If(shift_i
[0:2].any() & ~shift_i
[3]):
76 with m
.If(shift_i
[3] != 0):
78 # cover non-zero shift giving non-zero result
79 with m
.If(data_i
.any() & shift_i
.any() & dut
.n
.data_o
.data
.any()):
81 # dummy condition, to avoid optimizing-out the counters
82 with m
.If((write_cnt
!= 0) |
(read_cnt
!= 0)):
84 # check that each condition above occurred at least once
85 comb
+= Cover(cov
.all())
89 class ALUFSMTestCase(FHDLTestCase
):
90 def test_formal(self
):
93 'p_data_i[7:0]', 'p_shift_i[7:0]', 'op__sdir',
94 'p_valid_i', 'p_ready_o',
96 'n_valid_o', 'n_ready_i',
97 ('formal', {'module': 'top'}, [
98 'write_cnt[3:0]', 'read_cnt[3:0]', 'cov[7:0]'
102 'test_formal_alu_fsm.gtkw',
103 os
.path
.dirname(__file__
) +
104 '/proof_alu_fsm_formal/engine_0/trace0.vcd',
110 self
.assertFormal(module
, mode
="cover", depth
=32)
115 vl
= rtlil
.convert(dut
, ports
=[])
116 with
open("alu_fsm.il", "w") as f
:
120 if __name__
== '__main__':