Skip to content

Commit

Permalink
lib.fifo.AsyncFIFO: fix incorrect latency of r_level.
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Wygle <awygle@gmail.com>
  • Loading branch information
anuejn and awygle committed Oct 24, 2020
1 parent ca6fa03 commit d8273a1
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
7 changes: 4 additions & 3 deletions nmigen/lib/fifo.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ def elaborate(self, platform):
produce_dec = m.submodules.produce_dec = \
GrayDecoder(self._ctr_bits)
m.d.comb += produce_dec.i.eq(produce_r_gry),
m.d[self._r_domain] += produce_r_bin.eq(produce_dec.o)
m.d.comb += produce_r_bin.eq(produce_dec.o)

w_full = Signal()
r_empty = Signal()
Expand All @@ -381,7 +381,7 @@ def elaborate(self, platform):
]

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

storage = Memory(width=self.width, depth=self.depth)
w_port = m.submodules.w_port = storage.write_port(domain=self._w_domain)
Expand Down Expand Up @@ -509,12 +509,13 @@ def elaborate(self, platform):
self.w_level.eq(fifo.w_level),
]

m.d[self._r_domain] += self.r_level.eq(fifo.r_level + self.r_rdy - self.r_en)

with m.If(self.r_en | ~self.r_rdy):
m.d[self._r_domain] += [
self.r_data.eq(fifo.r_data),
self.r_rdy.eq(fifo.r_rdy),
self.r_rst.eq(fifo.r_rst),
self.r_level.eq(fifo.r_level),
]
m.d.comb += [
fifo.r_en.eq(1)
Expand Down
23 changes: 23 additions & 0 deletions tests/test_lib_fifo.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,26 @@ def test_async(self):

def test_async_buffered(self):
self.check_async_fifo(AsyncFIFOBuffered(width=8, depth=4))


class AsyncFIFOSimCase(FHDLTestCase):
def test_async_fifo_r_level_latency(self):
fifo = AsyncFIFO(width=32, depth=10, r_domain="sync", w_domain="sync")

ff_syncronizer_latency = 2

def testbench():
for i in range(10):
yield fifo.w_data.eq(i)
yield fifo.w_en.eq(1)
yield

if (i - ff_syncronizer_latency) > 0:
self.assertEqual((yield fifo.r_level), i - ff_syncronizer_latency)
else:
self.assertEqual((yield fifo.r_level), 0)

simulator = Simulator(fifo)
simulator.add_clock(100e-6)
simulator.add_sync_process(testbench)
simulator.run()

0 comments on commit d8273a1

Please sign in to comment.