cores/uart/UART: add stream interface (phy=None), add connect method and use this...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 13 Jan 2020 08:20:40 +0000 (09:20 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 13 Jan 2020 08:20:40 +0000 (09:20 +0100)
A bridged/crossover UART can now just be created by:
- passing uart_name="stream" to SoCCore/SoCSDRAM.
- adding a crossover UART core to the design:

# UART Crossover (over Wishbone Bridge
from litex.soc.cores.uart import UART
self.submodules.uart_xover = UART(tx_fifo_depth=2, rx_fifo_depth=2)
self.add_csr("uart_xover")
self.comb += self.uart.connect(self.uart_xover)

litex/soc/cores/uart.py
litex/soc/integration/soc_core.py

index 70e36c3155b53be58493068cec268bfafc8184a4..d9c0ea7eafaac432688980174a8c3f665c948aeb 100644 (file)
@@ -13,11 +13,22 @@ from litex.soc.interconnect.csr_eventmanager import *
 from litex.soc.interconnect import stream
 from litex.soc.interconnect.wishbonebridge import WishboneStreamingBridge
 
+# Common -------------------------------------------------------------------------------------------
+
+def UARTPads():
+    return Record([("tx", 1), ("rx", 1)])
+
 class UARTInterface:
     def __init__(self):
         self.sink   = stream.Endpoint([("data", 8)])
         self.source = stream.Endpoint([("data", 8)])
 
+    def connect(self, other):
+        return [
+            other.source.connect(self.sink),
+            self.source.connect(other.sink)
+        ]
+
 # RS232 PHY ----------------------------------------------------------------------------------------
 
 class RS232PHYInterface(UARTInterface):
@@ -182,8 +193,8 @@ def UARTPHY(pads, clk_freq, baudrate):
     else:
         return  RS232PHY(pads, clk_freq, baudrate)
 
-class UART(Module, AutoCSR):
-    def __init__(self, phy,
+class UART(Module, AutoCSR, UARTInterface):
+    def __init__(self, phy=None,
                  tx_fifo_depth=16,
                  rx_fifo_depth=16,
                  phy_cd="sys"):
@@ -198,6 +209,15 @@ class UART(Module, AutoCSR):
 
         # # #
 
+        UARTInterface.__init__(self)
+
+        # PHY
+        if phy is not None:
+            self.comb += [
+                phy.source.connect(self.sink),
+                self.source.connect(phy.sink)
+            ]
+
         # TX
         tx_fifo = _get_uart_fifo(tx_fifo_depth, source_cd=phy_cd)
         self.submodules += tx_fifo
@@ -206,7 +226,7 @@ class UART(Module, AutoCSR):
             tx_fifo.sink.valid.eq(self._rxtx.re),
             tx_fifo.sink.data.eq(self._rxtx.r),
             self._txfull.status.eq(~tx_fifo.sink.ready),
-            tx_fifo.source.connect(phy.sink),
+            tx_fifo.source.connect(self.source),
             # Generate TX IRQ when tx_fifo becomes non-full
             self.ev.tx.trigger.eq(~tx_fifo.sink.ready)
         ]
@@ -216,7 +236,7 @@ class UART(Module, AutoCSR):
         self.submodules += rx_fifo
 
         self.comb += [
-            phy.source.connect(rx_fifo.sink),
+            self.sink.connect(rx_fifo.sink),
             self._rxempty.status.eq(~rx_fifo.source.valid),
             self._rxtx.w.eq(rx_fifo.source.data),
             rx_fifo.source.ready.eq(self.ev.rx.clear),
@@ -224,37 +244,12 @@ class UART(Module, AutoCSR):
             self.ev.rx.trigger.eq(~rx_fifo.source.valid)
         ]
 
-
-class UARTStub(Module, AutoCSR):
-    def __init__(self):
-        self._rxtx = CSR(8)
-        self._txfull = CSRStatus()
-        self._rxempty = CSRStatus()
-
-        self.submodules.ev = EventManager()
-        self.ev.tx = EventSourceProcess()
-        self.ev.rx = EventSourceProcess()
-        self.ev.finalize()
-
-        # # #
-
-        self.comb += [
-            self._txfull.status.eq(0),
-            self.ev.tx.trigger.eq(~(self._rxtx.re & self._rxtx.r)),
-            self._rxempty.status.eq(1)
-        ]
-
-
 class UARTWishboneBridge(WishboneStreamingBridge):
     def __init__(self, pads, clk_freq, baudrate=115200):
         self.submodules.phy = RS232PHY(pads, clk_freq, baudrate)
         WishboneStreamingBridge.__init__(self, self.phy, clk_freq)
 
-# UART Mutltiplexer --------------------------------------------------------------------------------
-
-def UARTPads():
-    return Record([("tx", 1), ("rx", 1)])
-
+# UART Multiplexer ---------------------------------------------------------------------------------
 
 class UARTMultiplexer(Module):
     def __init__(self, uarts, uart):
@@ -269,22 +264,3 @@ class UARTMultiplexer(Module):
                 uarts[n].rx.eq(uart.rx)
             ]
         self.comb += Case(self.sel, cases)
-
-# UART Emulator ------------------------------------------------------------------------------------
-
-class UARTEmulator(UART):
-    """
-    UART emulation over Wishbone bridge.
-
-    Creates a fully compatible UART that can be used by the CPU as a regular UART and adds a second
-    UART, cross-connected to the main one to allow terminal emulation over a Wishbone bridge.
-    """
-    def __init__(self, **kwargs):
-        uart_phy = UARTInterface()
-        emul_phy = UARTInterface()
-        UART.__init__(self, uart_phy, **kwargs)
-        self.submodules.emul = UART(emul_phy)
-        self.comb += [
-            uart_phy.source.connect(emul_phy.sink),
-            emul_phy.source.connect(uart_phy.sink)
-        ]
index 8ce16d562bf52eca38a3b28681bdc50d03d6c790..898ccb31c1fee780cf001f2028a4913b2780ba1a 100644 (file)
@@ -95,7 +95,7 @@ class SoCCore(Module):
                 # Identifier parameters
                 ident="", ident_version=False,
                 # UART parameters
-                with_uart=True, uart_name="serial", uart_baudrate=115200, uart_stub=False,
+                with_uart=True, uart_name="serial", uart_baudrate=115200,
                 # Timer parameters
                 with_timer=True,
                 # Controller parameters
@@ -239,10 +239,10 @@ class SoCCore(Module):
 
         # Add UART
         if with_uart:
-            if uart_stub:
-                self.submodules.uart = uart.UARTStub()
-            elif uart_name == "emulator":
-                self.submodules.uart = uart.UARTEmulator()
+            if uart_name in ["stub", "stream"]:
+                self.submodules.uart = uart.UART()
+                if uart_name == "stub":
+                    self.comb += uart.sink.ready.eq(1)
             else:
                 if uart_name == "jtag_atlantic":
                     from litex.soc.cores.jtag import JTAGAtlantic