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 import stream
|
||||||
from litex.soc.interconnect.wishbonebridge import WishboneStreamingBridge
|
from litex.soc.interconnect.wishbonebridge import WishboneStreamingBridge
|
||||||
|
|
||||||
|
# Common -------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def UARTPads():
|
||||||
|
return Record([("tx", 1), ("rx", 1)])
|
||||||
|
|
||||||
class UARTInterface:
|
class UARTInterface:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sink = stream.Endpoint([("data", 8)])
|
self.sink = stream.Endpoint([("data", 8)])
|
||||||
self.source = 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 ----------------------------------------------------------------------------------------
|
# RS232 PHY ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class RS232PHYInterface(UARTInterface):
|
class RS232PHYInterface(UARTInterface):
|
||||||
|
@ -182,8 +193,8 @@ def UARTPHY(pads, clk_freq, baudrate):
|
||||||
else:
|
else:
|
||||||
return RS232PHY(pads, clk_freq, baudrate)
|
return RS232PHY(pads, clk_freq, baudrate)
|
||||||
|
|
||||||
class UART(Module, AutoCSR):
|
class UART(Module, AutoCSR, UARTInterface):
|
||||||
def __init__(self, phy,
|
def __init__(self, phy=None,
|
||||||
tx_fifo_depth=16,
|
tx_fifo_depth=16,
|
||||||
rx_fifo_depth=16,
|
rx_fifo_depth=16,
|
||||||
phy_cd="sys"):
|
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
|
||||||
tx_fifo = _get_uart_fifo(tx_fifo_depth, source_cd=phy_cd)
|
tx_fifo = _get_uart_fifo(tx_fifo_depth, source_cd=phy_cd)
|
||||||
self.submodules += tx_fifo
|
self.submodules += tx_fifo
|
||||||
|
@ -206,7 +226,7 @@ class UART(Module, AutoCSR):
|
||||||
tx_fifo.sink.valid.eq(self._rxtx.re),
|
tx_fifo.sink.valid.eq(self._rxtx.re),
|
||||||
tx_fifo.sink.data.eq(self._rxtx.r),
|
tx_fifo.sink.data.eq(self._rxtx.r),
|
||||||
self._txfull.status.eq(~tx_fifo.sink.ready),
|
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
|
# Generate TX IRQ when tx_fifo becomes non-full
|
||||||
self.ev.tx.trigger.eq(~tx_fifo.sink.ready)
|
self.ev.tx.trigger.eq(~tx_fifo.sink.ready)
|
||||||
]
|
]
|
||||||
|
@ -216,7 +236,7 @@ class UART(Module, AutoCSR):
|
||||||
self.submodules += rx_fifo
|
self.submodules += rx_fifo
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
phy.source.connect(rx_fifo.sink),
|
self.sink.connect(rx_fifo.sink),
|
||||||
self._rxempty.status.eq(~rx_fifo.source.valid),
|
self._rxempty.status.eq(~rx_fifo.source.valid),
|
||||||
self._rxtx.w.eq(rx_fifo.source.data),
|
self._rxtx.w.eq(rx_fifo.source.data),
|
||||||
rx_fifo.source.ready.eq(self.ev.rx.clear),
|
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)
|
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):
|
class UARTWishboneBridge(WishboneStreamingBridge):
|
||||||
def __init__(self, pads, clk_freq, baudrate=115200):
|
def __init__(self, pads, clk_freq, baudrate=115200):
|
||||||
self.submodules.phy = RS232PHY(pads, clk_freq, baudrate)
|
self.submodules.phy = RS232PHY(pads, clk_freq, baudrate)
|
||||||
WishboneStreamingBridge.__init__(self, self.phy, clk_freq)
|
WishboneStreamingBridge.__init__(self, self.phy, clk_freq)
|
||||||
|
|
||||||
# UART Mutltiplexer --------------------------------------------------------------------------------
|
# UART Multiplexer ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
def UARTPads():
|
|
||||||
return Record([("tx", 1), ("rx", 1)])
|
|
||||||
|
|
||||||
|
|
||||||
class UARTMultiplexer(Module):
|
class UARTMultiplexer(Module):
|
||||||
def __init__(self, uarts, uart):
|
def __init__(self, uarts, uart):
|
||||||
|
@ -269,22 +264,3 @@ class UARTMultiplexer(Module):
|
||||||
uarts[n].rx.eq(uart.rx)
|
uarts[n].rx.eq(uart.rx)
|
||||||
]
|
]
|
||||||
self.comb += Case(self.sel, cases)
|
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
|
# Identifier parameters
|
||||||
ident="", ident_version=False,
|
ident="", ident_version=False,
|
||||||
# UART parameters
|
# 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
|
# Timer parameters
|
||||||
with_timer=True,
|
with_timer=True,
|
||||||
# Controller parameters
|
# Controller parameters
|
||||||
|
@ -239,10 +239,10 @@ class SoCCore(Module):
|
||||||
|
|
||||||
# Add UART
|
# Add UART
|
||||||
if with_uart:
|
if with_uart:
|
||||||
if uart_stub:
|
if uart_name in ["stub", "stream"]:
|
||||||
self.submodules.uart = uart.UARTStub()
|
self.submodules.uart = uart.UART()
|
||||||
elif uart_name == "emulator":
|
if uart_name == "stub":
|
||||||
self.submodules.uart = uart.UARTEmulator()
|
self.comb += uart.sink.ready.eq(1)
|
||||||
else:
|
else:
|
||||||
if uart_name == "jtag_atlantic":
|
if uart_name == "jtag_atlantic":
|
||||||
from litex.soc.cores.jtag import JTAGAtlantic
|
from litex.soc.cores.jtag import JTAGAtlantic
|
||||||
|
|
Loading…
Reference in a new issue