uart: support async phys
authorRobert Jordens <jordens@gmail.com>
Sun, 19 Jul 2015 07:23:35 +0000 (01:23 -0600)
committerSebastien Bourdeauducq <sb@m-labs.hk>
Sun, 19 Jul 2015 21:37:00 +0000 (23:37 +0200)
misoclib/com/uart/__init__.py

index 16160ebb2d08005d899cf40d5da44895d77f1d99..981ad841ea8ee219a2c52d3726bb5615442a8365 100644 (file)
@@ -2,14 +2,14 @@ from migen.fhdl.std import *
 from migen.bank.description import *
 from migen.bank.eventmanager import *
 from migen.genlib.record import Record
-from migen.flow.actor import Sink, Source
-from migen.actorlib.fifo import SyncFIFO
+from migen.actorlib.fifo import SyncFIFO, AsyncFIFO
 
 
 class UART(Module, AutoCSR):
     def __init__(self, phy,
                  tx_fifo_depth=16,
-                 rx_fifo_depth=16):
+                 rx_fifo_depth=16,
+                 phy_cd="sys"):
         self._rxtx = CSR(8)
         self._txfull = CSRStatus()
         self._rxempty = CSRStatus()
@@ -21,27 +21,30 @@ class UART(Module, AutoCSR):
 
         # # #
 
-        tx_fifo = SyncFIFO([("data", 8)], tx_fifo_depth)
-        self.submodules += tx_fifo
+        if phy_cd == "sys":
+            tx_fifo = SyncFIFO([("data", 8)], tx_fifo_depth)
+            rx_fifo = SyncFIFO([("data", 8)], rx_fifo_depth)
+            # Generate TX IRQ when tx_fifo becomes empty
+            tx_irq = tx_fifo.source.stb
+        else:
+            tx_fifo = ClockDomainsRenamer({"write": "sys", "read": phy_cd})(
+                AsyncFIFO([("data", 8)], tx_fifo_depth))
+            rx_fifo = ClockDomainsRenamer({"write": phy_cd, "read": "sys"})(
+                AsyncFIFO([("data", 8)], rx_fifo_depth))
+            # Generate TX IRQ when tx_fifo becomes non-full
+            tx_irq = ~tx_fifo.sink.ack
+        self.submodules += tx_fifo, rx_fifo
         self.comb += [
             tx_fifo.sink.stb.eq(self._rxtx.re),
             tx_fifo.sink.data.eq(self._rxtx.r),
             self._txfull.status.eq(~tx_fifo.sink.ack),
-            Record.connect(tx_fifo.source, phy.sink)
-        ]
+            Record.connect(tx_fifo.source, phy.sink),
+            self.ev.tx.trigger.eq(tx_irq),
 
-        rx_fifo = SyncFIFO([("data", 8)], rx_fifo_depth)
-        self.submodules += rx_fifo
-        self.comb += [
             Record.connect(phy.source, rx_fifo.sink),
             self._rxempty.status.eq(~rx_fifo.source.stb),
             self._rxtx.w.eq(rx_fifo.source.data),
-            rx_fifo.source.ack.eq(self.ev.rx.clear)
-        ]
-
-        self.comb += [
-            # Generate TX IRQ when tx_fifo becomes empty
-            self.ev.tx.trigger.eq(tx_fifo.source.stb),
+            rx_fifo.source.ack.eq(self.ev.rx.clear),
             # Generate RX IRQ when rx_fifo becomes non-empty
             self.ev.rx.trigger.eq(~rx_fifo.source.stb),
         ]