Skip to content

Commit 2d42d64

Browse files
wanda-phiwhitequark
authored andcommitted
tests: stop using implicit ports.
1 parent 18e5bcd commit 2d42d64

File tree

3 files changed

+77
-41
lines changed

3 files changed

+77
-41
lines changed

tests/test_lib_coding.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,33 +75,39 @@ def process():
7575

7676

7777
class ReversibleSpec(Elaboratable):
78-
def __init__(self, encoder_cls, decoder_cls, args):
78+
def __init__(self, encoder_cls, decoder_cls, i_width, args):
7979
self.encoder_cls = encoder_cls
8080
self.decoder_cls = decoder_cls
8181
self.coder_args = args
82+
self.i = Signal(i_width)
8283

8384
def elaborate(self, platform):
8485
m = Module()
8586
enc, dec = self.encoder_cls(*self.coder_args), self.decoder_cls(*self.coder_args)
8687
m.submodules += enc, dec
8788
m.d.comb += [
89+
enc.i.eq(self.i),
8890
dec.i.eq(enc.o),
8991
Assert(enc.i == dec.o)
9092
]
9193
return m
9294

9395

9496
class HammingDistanceSpec(Elaboratable):
95-
def __init__(self, distance, encoder_cls, args):
97+
def __init__(self, distance, encoder_cls, i_width, args):
9698
self.distance = distance
9799
self.encoder_cls = encoder_cls
98100
self.coder_args = args
101+
self.i1 = Signal(i_width)
102+
self.i2 = Signal(i_width)
99103

100104
def elaborate(self, platform):
101105
m = Module()
102106
enc1, enc2 = self.encoder_cls(*self.coder_args), self.encoder_cls(*self.coder_args)
103107
m.submodules += enc1, enc2
104108
m.d.comb += [
109+
enc1.i.eq(self.i1),
110+
enc2.i.eq(self.i2),
105111
Assume(enc1.i + 1 == enc2.i),
106112
Assert(sum(enc1.o ^ enc2.o) == self.distance)
107113
]
@@ -110,9 +116,10 @@ def elaborate(self, platform):
110116

111117
class GrayCoderTestCase(FHDLTestCase):
112118
def test_reversible(self):
113-
spec = ReversibleSpec(encoder_cls=GrayEncoder, decoder_cls=GrayDecoder, args=(16,))
114-
self.assertFormal(spec, mode="prove")
119+
spec = ReversibleSpec(encoder_cls=GrayEncoder, decoder_cls=GrayDecoder, i_width=16,
120+
args=(16,))
121+
self.assertFormal(spec, [spec.i], mode="prove")
115122

116123
def test_distance(self):
117-
spec = HammingDistanceSpec(distance=1, encoder_cls=GrayEncoder, args=(16,))
118-
self.assertFormal(spec, mode="prove")
124+
spec = HammingDistanceSpec(distance=1, encoder_cls=GrayEncoder, i_width=16, args=(16,))
125+
self.assertFormal(spec, [spec.i1, spec.i2], mode="prove")

tests/test_lib_fifo.py

Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,31 @@ class FIFOModelEquivalenceSpec(Elaboratable):
123123
signals, the behavior of the implementation under test exactly matches the ideal model,
124124
except for behavior not defined by the model.
125125
"""
126-
def __init__(self, fifo, r_domain, w_domain):
126+
def __init__(self, fifo, *, is_async=False):
127127
self.fifo = fifo
128+
self.is_async = is_async
128129

129-
self.r_domain = r_domain
130-
self.w_domain = w_domain
130+
if is_async:
131+
self.cd_read = ClockDomain()
132+
self.cd_write = ClockDomain()
133+
else:
134+
self.cd_sync = ClockDomain()
135+
self.cd_read = self.cd_write = self.cd_sync
131136

132137
@_ignore_deprecated
133138
def elaborate(self, platform):
134139
m = Module()
140+
141+
if self.is_async:
142+
m.domains += self.cd_read
143+
m.domains += self.cd_write
144+
else:
145+
m.domains += self.cd_sync
146+
135147
m.submodules.dut = dut = self.fifo
136148
m.submodules.gold = gold = FIFOModel(width=dut.width, depth=dut.depth,
137-
r_domain=self.r_domain, w_domain=self.w_domain)
149+
r_domain=self.cd_read.name,
150+
w_domain=self.cd_write.name)
138151

139152
m.d.comb += [
140153
gold.r_en.eq(dut.r_rdy & dut.r_en),
@@ -158,30 +171,35 @@ class FIFOContractSpec(Elaboratable):
158171
consecutively, they must be read out consecutively at some later point, no matter all other
159172
circumstances, with the exception of reset.
160173
"""
161-
def __init__(self, fifo, *, r_domain, w_domain, bound):
174+
def __init__(self, fifo, *, is_async=False, bound):
162175
self.fifo = fifo
163-
self.r_domain = r_domain
164-
self.w_domain = w_domain
176+
self.is_async = is_async
165177
self.bound = bound
166178

179+
self.cd_sync = ClockDomain()
180+
if is_async:
181+
self.cd_read = ClockDomain()
182+
self.cd_write = ClockDomain()
183+
else:
184+
self.cd_read = self.cd_write = self.cd_sync
185+
167186
@_ignore_deprecated
168187
def elaborate(self, platform):
169188
m = Module()
170189
m.submodules.dut = fifo = self.fifo
171190

172-
m.domains += ClockDomain("sync")
173-
m.d.comb += ResetSignal().eq(0)
174-
if self.w_domain != "sync":
175-
m.domains += ClockDomain(self.w_domain)
176-
m.d.comb += ResetSignal(self.w_domain).eq(0)
177-
if self.r_domain != "sync":
178-
m.domains += ClockDomain(self.r_domain)
179-
m.d.comb += ResetSignal(self.r_domain).eq(0)
191+
m.domains += self.cd_sync
192+
m.d.comb += self.cd_sync.rst.eq(0)
193+
if self.is_async:
194+
m.domains += self.cd_read
195+
m.domains += self.cd_write
196+
m.d.comb += self.cd_write.rst.eq(0)
197+
m.d.comb += self.cd_read.rst.eq(0)
180198

181199
entry_1 = AnyConst(fifo.width)
182200
entry_2 = AnyConst(fifo.width)
183201

184-
with m.FSM(domain=self.w_domain) as write_fsm:
202+
with m.FSM(domain=self.cd_write.name) as write_fsm:
185203
with m.State("WRITE-1"):
186204
with m.If(fifo.w_rdy):
187205
m.d.comb += [
@@ -199,7 +217,7 @@ def elaborate(self, platform):
199217
with m.State("DONE"):
200218
pass
201219

202-
with m.FSM(domain=self.r_domain) as read_fsm:
220+
with m.FSM(domain=self.cd_read.name) as read_fsm:
203221
read_1 = Signal(fifo.width)
204222
read_2 = Signal(fifo.width)
205223
with m.State("READ"):
@@ -225,18 +243,18 @@ def elaborate(self, platform):
225243
with m.If(cycle == self.bound):
226244
m.d.comb += Assert(read_fsm.ongoing("DONE"))
227245

228-
with m.If(ResetSignal(domain=self.w_domain)):
246+
with m.If(self.cd_write.rst):
229247
m.d.comb += Assert(~fifo.r_rdy)
230248

231-
if self.w_domain != "sync" or self.r_domain != "sync":
232-
# rose_w_domain_clk = Rose(ClockSignal(self.w_domain))
249+
if self.is_async:
250+
# rose_w_domain_clk = Rose(self.cd_write.clk)
233251
past_w_domain_clk = Signal()
234-
m.d.sync += past_w_domain_clk.eq(ClockSignal(self.w_domain))
235-
rose_w_domain_clk = (past_w_domain_clk == 0) & (ClockSignal(self.w_domain) == 1)
236-
# rose_r_domain_clk = Rose(ClockSignal(self.r_domain))
252+
m.d.sync += past_w_domain_clk.eq(self.cd_write.clk)
253+
rose_w_domain_clk = (past_w_domain_clk == 0) & (self.cd_write.clk == 1)
254+
# rose_r_domain_clk = Rose(self.cd_read.clk)
237255
past_r_domain_clk = Signal()
238-
m.d.sync += past_r_domain_clk.eq(ClockSignal(self.r_domain))
239-
rose_r_domain_clk = (past_r_domain_clk == 0) & (ClockSignal(self.r_domain) == 1)
256+
m.d.sync += past_r_domain_clk.eq(self.cd_read.clk)
257+
rose_r_domain_clk = (past_r_domain_clk == 0) & (self.cd_read.clk == 1)
240258

241259
m.d.comb += Assume(rose_w_domain_clk | rose_r_domain_clk)
242260

@@ -245,10 +263,13 @@ def elaborate(self, platform):
245263

246264
class FIFOFormalCase(FHDLTestCase):
247265
def check_sync_fifo(self, fifo):
248-
self.assertFormal(FIFOModelEquivalenceSpec(fifo, r_domain="sync", w_domain="sync"),
249-
mode="bmc", depth=fifo.depth + 1)
250-
self.assertFormal(FIFOContractSpec(fifo, r_domain="sync", w_domain="sync",
251-
bound=fifo.depth * 2 + 1),
266+
spec_equiv = FIFOModelEquivalenceSpec(fifo, is_async=False)
267+
self.assertFormal(spec_equiv, [
268+
spec_equiv.cd_sync.clk, spec_equiv.cd_sync.rst,
269+
fifo.w_en, fifo.w_data, fifo.r_en,
270+
], mode="bmc", depth=fifo.depth + 1)
271+
spec_contract = FIFOContractSpec(fifo, is_async=False, bound=fifo.depth * 2 + 1)
272+
self.assertFormal(spec_contract, [spec_contract.cd_sync.clk],
252273
mode="hybrid", depth=fifo.depth * 2 + 1)
253274

254275
def test_sync_pot(self):
@@ -272,11 +293,19 @@ def test_sync_buffered_one(self):
272293
def check_async_fifo(self, fifo):
273294
# TODO: properly doing model equivalence checking on this likely requires multiclock,
274295
# which is not really documented nor is it clear how to use it.
275-
# self.assertFormal(FIFOModelEquivalenceSpec(fifo, r_domain="read", w_domain="write"),
296+
# spec_equiv = FIFOModelEquivalenceSpec(fifo, is_async=True)
297+
# self.assertFormal(spec_equiv, [
298+
# spec_equiv.cd_write.clk, spec_equiv.cd_write.rst,
299+
# spec_equiv.cd_read.clk, spec_equiv.cd_read.rst,
300+
# fifo.w_en, fifo.w_data, fifo.r_en,
301+
# ],
276302
# mode="bmc", depth=fifo.depth * 3 + 1)
277-
self.assertFormal(FIFOContractSpec(fifo, r_domain="read", w_domain="write",
278-
bound=fifo.depth * 4 + 1),
279-
mode="hybrid", depth=fifo.depth * 4 + 1)
303+
spec_contract = FIFOContractSpec(fifo, is_async=True, bound=fifo.depth * 4 + 1)
304+
self.assertFormal(spec_contract, [
305+
spec_contract.cd_sync.clk,
306+
spec_contract.cd_write.clk,
307+
spec_contract.cd_read.clk,
308+
], mode="hybrid", depth=fifo.depth * 4 + 1)
280309

281310
def test_async(self):
282311
self.check_async_fifo(AsyncFIFO(width=8, depth=4))

tests/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def prepare_repr(repr_str):
2626
return repr_str.strip()
2727
self.assertEqual(prepare_repr(repr(obj)), prepare_repr(repr_str))
2828

29-
def assertFormal(self, spec, mode="bmc", depth=1):
29+
def assertFormal(self, spec, ports=None, mode="bmc", depth=1):
3030
stack = traceback.extract_stack()
3131
for frame in reversed(stack):
3232
if os.path.dirname(__file__) not in frame.filename:
@@ -72,7 +72,7 @@ def assertFormal(self, spec, mode="bmc", depth=1):
7272
mode=mode,
7373
depth=depth,
7474
script=script,
75-
rtlil=rtlil.convert_fragment(Fragment.get(spec, platform="formal").prepare())[0]
75+
rtlil=rtlil.convert(spec, ports=ports, platform="formal"),
7676
)
7777
with subprocess.Popen(
7878
[require_tool("sby"), "-f", "-d", spec_name],

0 commit comments

Comments
 (0)