Skip to content

Commit d8273a1

Browse files
anuejnawygle
andauthored
lib.fifo.AsyncFIFO: fix incorrect latency of r_level.
Co-authored-by: Andrew Wygle <[email protected]>
1 parent ca6fa03 commit d8273a1

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

nmigen/lib/fifo.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ def elaborate(self, platform):
369369
produce_dec = m.submodules.produce_dec = \
370370
GrayDecoder(self._ctr_bits)
371371
m.d.comb += produce_dec.i.eq(produce_r_gry),
372-
m.d[self._r_domain] += produce_r_bin.eq(produce_dec.o)
372+
m.d.comb += produce_r_bin.eq(produce_dec.o)
373373

374374
w_full = Signal()
375375
r_empty = Signal()
@@ -381,7 +381,7 @@ def elaborate(self, platform):
381381
]
382382

383383
m.d[self._w_domain] += self.w_level.eq((produce_w_bin - consume_w_bin)[:self._ctr_bits-1])
384-
m.d[self._r_domain] += self.r_level.eq((produce_r_bin - consume_r_bin)[:self._ctr_bits-1])
384+
m.d.comb += self.r_level.eq((produce_r_bin - consume_r_bin)[:self._ctr_bits-1])
385385

386386
storage = Memory(width=self.width, depth=self.depth)
387387
w_port = m.submodules.w_port = storage.write_port(domain=self._w_domain)
@@ -509,12 +509,13 @@ def elaborate(self, platform):
509509
self.w_level.eq(fifo.w_level),
510510
]
511511

512+
m.d[self._r_domain] += self.r_level.eq(fifo.r_level + self.r_rdy - self.r_en)
513+
512514
with m.If(self.r_en | ~self.r_rdy):
513515
m.d[self._r_domain] += [
514516
self.r_data.eq(fifo.r_data),
515517
self.r_rdy.eq(fifo.r_rdy),
516518
self.r_rst.eq(fifo.r_rst),
517-
self.r_level.eq(fifo.r_level),
518519
]
519520
m.d.comb += [
520521
fifo.r_en.eq(1)

tests/test_lib_fifo.py

+23
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,26 @@ def test_async(self):
280280

281281
def test_async_buffered(self):
282282
self.check_async_fifo(AsyncFIFOBuffered(width=8, depth=4))
283+
284+
285+
class AsyncFIFOSimCase(FHDLTestCase):
286+
def test_async_fifo_r_level_latency(self):
287+
fifo = AsyncFIFO(width=32, depth=10, r_domain="sync", w_domain="sync")
288+
289+
ff_syncronizer_latency = 2
290+
291+
def testbench():
292+
for i in range(10):
293+
yield fifo.w_data.eq(i)
294+
yield fifo.w_en.eq(1)
295+
yield
296+
297+
if (i - ff_syncronizer_latency) > 0:
298+
self.assertEqual((yield fifo.r_level), i - ff_syncronizer_latency)
299+
else:
300+
self.assertEqual((yield fifo.r_level), 0)
301+
302+
simulator = Simulator(fifo)
303+
simulator.add_clock(100e-6)
304+
simulator.add_sync_process(testbench)
305+
simulator.run()

0 commit comments

Comments
 (0)