From: Florent Kermarrec Date: Mon, 13 Jan 2020 08:20:40 +0000 (+0100) Subject: cores/uart/UART: add stream interface (phy=None), add connect method and use this... X-Git-Tag: 24jan2021_ls180~757 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2f03d3234e1585da5614d49229e94885444ee9c8;p=litex.git cores/uart/UART: add stream interface (phy=None), add connect method and use this for UART Stub/Crossover. 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) --- diff --git a/litex/soc/cores/uart.py b/litex/soc/cores/uart.py index 70e36c31..d9c0ea7e 100644 --- a/litex/soc/cores/uart.py +++ b/litex/soc/cores/uart.py @@ -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) - ] diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 8ce16d56..898ccb31 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -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