Skip to content

Commit

Permalink
lib.fifo: add custom domain to sync FIFOs
Browse files Browse the repository at this point in the history
  • Loading branch information
slan committed Apr 9, 2021
1 parent c84d4af commit 62b4d67
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions nmigen/lib/fifo.py
Expand Up @@ -106,6 +106,8 @@ class SyncFIFO(Elaboratable, FIFOInterface):
First-word fallthrough. If set, when the queue is empty and an entry is written into it,
that entry becomes available on the output on the same clock cycle. Otherwise, it is
necessary to assert ``r_en`` for ``r_data`` to become valid.
domain : str
Clock domain.
""".strip(),
r_data_valid="""
For FWFT queues, valid if ``r_rdy`` is asserted. For non-FWFT queues, valid on the next
Expand All @@ -115,10 +117,11 @@ class SyncFIFO(Elaboratable, FIFOInterface):
r_attributes="",
w_attributes="")

def __init__(self, *, width, depth, fwft=True):
def __init__(self, *, width, depth, fwft=True, domain="sync"):
super().__init__(width=width, depth=depth, fwft=fwft)

self.level = Signal(range(depth + 1))
self._domain = domain

def elaborate(self, platform):
m = Module()
Expand Down Expand Up @@ -152,7 +155,7 @@ def elaborate(self, platform):
w_port.en.eq(self.w_en & self.w_rdy),
]
with m.If(do_write):
m.d.sync += produce.eq(_incr(produce, self.depth))
m.d[self._domain] += produce.eq(_incr(produce, self.depth))

m.d.comb += [
r_port.addr.eq(consume),
Expand All @@ -161,12 +164,12 @@ def elaborate(self, platform):
if not self.fwft:
m.d.comb += r_port.en.eq(self.r_en)
with m.If(do_read):
m.d.sync += consume.eq(_incr(consume, self.depth))
m.d[self._domain] += consume.eq(_incr(consume, self.depth))

with m.If(do_write & ~do_read):
m.d.sync += self.level.eq(self.level + 1)
m.d[self._domain] += self.level.eq(self.level + 1)
with m.If(do_read & ~do_write):
m.d.sync += self.level.eq(self.level - 1)
m.d[self._domain] += self.level.eq(self.level - 1)

if platform == "formal":
# TODO: move this logic to SymbiYosys
Expand Down Expand Up @@ -210,6 +213,8 @@ class SyncFIFOBuffered(Elaboratable, FIFOInterface):
parameters="""
fwft : bool
Always set.
domain : str
Clock domain.
""".strip(),
attributes="",
r_data_valid="Valid if ``r_rdy`` is asserted.",
Expand All @@ -219,10 +224,11 @@ class SyncFIFOBuffered(Elaboratable, FIFOInterface):
""".strip(),
w_attributes="")

def __init__(self, *, width, depth):
def __init__(self, *, width, depth, domain="sync"):
super().__init__(width=width, depth=depth, fwft=True)

self.level = Signal(range(depth + 1))
self._domain = domain

def elaborate(self, platform):
m = Module()
Expand All @@ -236,7 +242,7 @@ def elaborate(self, platform):
# Effectively, this queue treats the output register of the non-FWFT inner queue as
# an additional storage element.
m.submodules.unbuffered = fifo = SyncFIFO(width=self.width, depth=self.depth - 1,
fwft=False)
fwft=False, domain=self._domain)

m.d.comb += [
fifo.w_data.eq(self.w_data),
Expand All @@ -249,9 +255,9 @@ def elaborate(self, platform):
fifo.r_en.eq(fifo.r_rdy & (~self.r_rdy | self.r_en)),
]
with m.If(fifo.r_en):
m.d.sync += self.r_rdy.eq(1)
m.d[self._domain] += self.r_rdy.eq(1)
with m.Elif(self.r_en):
m.d.sync += self.r_rdy.eq(0)
m.d[self._domain] += self.r_rdy.eq(0)

m.d.comb += [
self.level.eq(fifo.level + self.r_rdy),
Expand Down

0 comments on commit 62b4d67

Please sign in to comment.