From: anuejn Date: Sat, 24 Oct 2020 14:58:23 +0000 (+0200) Subject: lib.fifo.AsyncFIFO: fix incorrect latency of r_level. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6730dac4118e86144a14f29320ae9a1e5f388c36;p=nmigen.git lib.fifo.AsyncFIFO: fix incorrect latency of r_level. Co-authored-by: Andrew Wygle --- diff --git a/nmigen/lib/fifo.py b/nmigen/lib/fifo.py index fa5b265..d0b79bd 100644 --- a/nmigen/lib/fifo.py +++ b/nmigen/lib/fifo.py @@ -369,7 +369,7 @@ class AsyncFIFO(Elaboratable, FIFOInterface): 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() @@ -381,7 +381,7 @@ class AsyncFIFO(Elaboratable, FIFOInterface): ] 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) @@ -509,12 +509,13 @@ class AsyncFIFOBuffered(Elaboratable, FIFOInterface): 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) diff --git a/tests/test_lib_fifo.py b/tests/test_lib_fifo.py index 4722318..7de265f 100644 --- a/tests/test_lib_fifo.py +++ b/tests/test_lib_fifo.py @@ -280,3 +280,26 @@ class FIFOFormalCase(FHDLTestCase): 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() \ No newline at end of file