mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
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)
This commit is contained in:
parent
d92bd8ffaa
commit
2f03d3234e
2 changed files with 30 additions and 54 deletions
|
@ -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)
|
||||
]
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue