lib.fifo: adjust for new CDC primitive conventions.
authorwhitequark <whitequark@whitequark.org>
Thu, 12 Sep 2019 20:01:28 +0000 (20:01 +0000)
committerwhitequark <whitequark@whitequark.org>
Fri, 13 Sep 2019 12:36:51 +0000 (12:36 +0000)
Fixes #97.

nmigen/lib/fifo.py

index cb847de2f7330fef2e88dea56fac615d5b7eb9f9..fc9e32d696bedc7468fdeea2dc71368086376837 100644 (file)
@@ -291,21 +291,29 @@ class AsyncFIFO(Elaboratable, FIFOInterface):
     description="""
     Asynchronous first in, first out queue.
 
-    Read and write interfaces are accessed from different clock domains, called ``read``
-    and ``write``; use :class:`DomainRenamer` to rename them as appropriate for the design.
+    Read and write interfaces are accessed from different clock domains, which can be set when
+    constructing the FIFO.
     """.strip(),
     parameters="""
+    r_domain : str
+        Read clock domain.
+    w_domain : str
+        Write clock domain.
+    """.strip(),
+    attributes="""
     fwft : bool
         Always set.
     """.strip(),
-    attributes="",
     r_data_valid="Valid if ``r_rdy`` is asserted.",
     r_attributes="",
     w_attributes="")
 
-    def __init__(self, width, depth):
+    def __init__(self, width, depth, *, r_domain="read", w_domain="write"):
         super().__init__(width, depth, fwft=True)
 
+        self._r_domain = r_domain
+        self._w_domain = w_domain
+
         try:
             self._ctr_bits = log2_int(depth, need_pow2=True) + 1
         except ValueError as e:
@@ -324,31 +332,31 @@ class AsyncFIFO(Elaboratable, FIFOInterface):
         # TODO: extract this pattern into lib.cdc.GrayCounter
         produce_w_bin = Signal(self._ctr_bits)
         produce_w_nxt = Signal(self._ctr_bits)
-        m.d.comb  += produce_w_nxt.eq(produce_w_bin + do_write)
-        m.d.write += produce_w_bin.eq(produce_w_nxt)
+        m.d.comb += produce_w_nxt.eq(produce_w_bin + do_write)
+        m.d[self._w_domain] += produce_w_bin.eq(produce_w_nxt)
 
         consume_r_bin = Signal(self._ctr_bits)
         consume_r_nxt = Signal(self._ctr_bits)
-        m.d.comb  += consume_r_nxt.eq(consume_r_bin + do_read)
-        m.d.read  += consume_r_bin.eq(consume_r_nxt)
+        m.d.comb += consume_r_nxt.eq(consume_r_bin + do_read)
+        m.d[self._r_domain] += consume_r_bin.eq(consume_r_nxt)
 
         produce_w_gry = Signal(self._ctr_bits)
         produce_r_gry = 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, o_domain="read")
-        m.d.comb  += produce_enc.i.eq(produce_w_nxt),
-        m.d.write += produce_w_gry.eq(produce_enc.o)
+            MultiReg(produce_w_gry, produce_r_gry, o_domain=self._r_domain)
+        m.d.comb += produce_enc.i.eq(produce_w_nxt),
+        m.d[self._w_domain] += produce_w_gry.eq(produce_enc.o)
 
         consume_r_gry = Signal(self._ctr_bits)
         consume_w_gry = 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, o_domain="write")
-        m.d.comb  += consume_enc.i.eq(consume_r_nxt)
-        m.d.read  += consume_r_gry.eq(consume_enc.o)
+            MultiReg(consume_r_gry, consume_w_gry, o_domain=self._w_domain)
+        m.d.comb += consume_enc.i.eq(consume_r_nxt)
+        m.d[self._r_domain] += consume_r_gry.eq(consume_enc.o)
 
         m.d.comb += [
             self.w_rdy.eq(
@@ -359,8 +367,8 @@ class AsyncFIFO(Elaboratable, FIFOInterface):
         ]
 
         storage = Memory(self.width, self.depth)
-        w_port  = m.submodules.w_port = storage.write_port(domain="write")
-        r_port  = m.submodules.r_port = storage.read_port (domain="read")
+        w_port  = m.submodules.w_port = storage.write_port(domain=self._w_domain)
+        r_port  = m.submodules.r_port = storage.read_port (domain=self._r_domain)
         m.d.comb += [
             w_port.addr.eq(produce_w_bin[:-1]),
             w_port.data.eq(self.w_data),
@@ -384,6 +392,9 @@ class AsyncFIFOBuffered(Elaboratable, FIFOInterface):
     description="""
     Buffered asynchronous first in, first out queue.
 
+    Read and write interfaces are accessed from different clock domains, which can be set when
+    constructing the FIFO.
+
     This queue's interface is identical to :class:`AsyncFIFO`, but it has an additional register
     on the output, improving timing in case of block RAM that has large clock-to-output delay.
 
@@ -391,20 +402,29 @@ class AsyncFIFOBuffered(Elaboratable, FIFOInterface):
     becoming available on the output is increased to one cycle.
     """.strip(),
     parameters="""
+    r_domain : str
+        Read clock domain.
+    w_domain : str
+        Write clock domain.
+    """.strip(),
+    attributes="""
     fwft : bool
         Always set.
     """.strip(),
-    attributes="",
     r_data_valid="Valid if ``r_rdy`` is asserted.",
     r_attributes="",
     w_attributes="")
 
-    def __init__(self, width, depth):
+    def __init__(self, width, depth, *, r_domain="read", w_domain="write"):
         super().__init__(width, depth, fwft=True)
 
+        self._r_domain = r_domain
+        self._w_domain = w_domain
+
     def elaborate(self, platform):
         m = Module()
-        m.submodules.unbuffered = fifo = AsyncFIFO(self.width, self.depth - 1)
+        m.submodules.unbuffered = fifo = AsyncFIFO(self.width, self.depth - 1,
+            r_domain=self._r_domain, w_domain=self._w_domain)
 
         m.d.comb += [
             fifo.w_data.eq(self.w_data),
@@ -413,11 +433,12 @@ class AsyncFIFOBuffered(Elaboratable, FIFOInterface):
         ]
 
         with m.If(self.r_en | ~self.r_rdy):
-            m.d.read += [
+            m.d[self._r_domain] += [
                 self.r_data.eq(fifo.r_data),
-                self.r_rdy.eq(fifo.r_rdy)
+                self.r_rdy.eq(fifo.r_rdy),
             ]
-            m.d.comb += \
+            m.d.comb += [
                 fifo.r_en.eq(1)
+            ]
 
         return m