Skip to content

Commit

Permalink
Fix async fifo CDC bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Wren6991 committed Mar 3, 2019
1 parent 342bdbe commit 78b6cd0
Showing 1 changed file with 27 additions and 15 deletions.
42 changes: 27 additions & 15 deletions nmigen/lib/fifo.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ def elaborate(self, platform):

return m


class AsyncFIFO(FIFOInterface):
__doc__ = FIFOInterface._doc_template.format(
description="""
Expand Down Expand Up @@ -297,29 +296,46 @@ def elaborate(self, platform):

m = Module()

do_write = self.writable & self.we
do_read = self.readable & self.re

produce_w_bin = Signal(self._ctr_bits)
produce_w_gry = Signal(self._ctr_bits)
produce_r_gry = Signal(self._ctr_bits)
produce_w_gry = Signal(self._ctr_bits, attrs={"no_retiming": True})
produce_w_bin_next = Signal(self._ctr_bits)
produce_w_gry_next = Signal(self._ctr_bits)
produce_enc = m.submodules.produce_enc = \
GrayEncoder(self._ctr_bits)
produce_cdc = m.submodules.produce_cdc = \
MultiReg(produce_w_gry, produce_r_gry, odomain="read")
m.d.comb += [
produce_w_bin_next.eq(produce_w_bin + do_write),
produce_enc.i.eq(produce_w_bin),
produce_w_gry.eq(produce_enc.o),
produce_w_gry_next.eq(produce_enc.o),
]
m.d.write += [
produce_w_bin.eq(produce_w_bin_next),
produce_w_gry.eq(produce_w_gry_next)
]
produce_r_gry = Signal(self._ctr_bits)
produce_cdc = m.submodules.produce_cdc = \
MultiReg(produce_w_gry, produce_r_gry, odomain="read")

consume_r_bin = Signal(self._ctr_bits)
consume_r_gry = Signal(self._ctr_bits)
consume_w_gry = Signal(self._ctr_bits)
consume_r_gry = Signal(self._ctr_bits, attrs={"no_retiming": True})
consume_r_bin_next = Signal(self._ctr_bits)
consume_r_gry_next = Signal(self._ctr_bits)
consume_enc = m.submodules.consume_enc = \
GrayEncoder(self._ctr_bits)
consume_cdc = m.submodules.consume_cdc = \
MultiReg(consume_r_gry, consume_w_gry, odomain="write")
m.d.comb += [
consume_r_bin_next.eq(consume_r_bin + do_read),
consume_enc.i.eq(consume_r_bin),
consume_r_gry.eq(consume_enc.o),
consume_r_gry_next.eq(consume_enc.o),
]
m.d.read += [
consume_r_bin.eq(consume_r_bin_next),
consume_r_gry.eq(consume_r_gry_next)
]
consume_w_gry = Signal(self._ctr_bits)
consume_cdc = m.submodules.consume_cdc = \
MultiReg(consume_r_gry, consume_w_gry, odomain="write")

m.d.comb += [
self.writable.eq(
Expand All @@ -329,10 +345,6 @@ def elaborate(self, platform):
self.readable.eq(consume_r_gry != produce_r_gry)
]

do_write = self.writable & self.we
do_read = self.readable & self.re
m.d.write += produce_w_bin.eq(produce_w_bin + do_write)
m.d.read += consume_r_bin.eq(consume_r_bin + do_read)

storage = Memory(self.width, self.depth)
wrport = m.submodules.wrport = storage.write_port(domain="write")
Expand Down

0 comments on commit 78b6cd0

Please sign in to comment.