mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
uartbone+crossover: add dynamic mux so that programs can boot into full-bandwidth UART, but enable debuggability as needed
This commit is contained in:
parent
76a704377f
commit
a47bbb28f5
3 changed files with 65 additions and 17 deletions
|
@ -474,12 +474,53 @@ class UARTCrossover(UART):
|
|||
|
||||
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.
|
||||
|
||||
If a pad_phy is provided, a debug_en register is created that enables a
|
||||
mux to interpose the pads. When debug_en is 0, then the internal UART
|
||||
is routed to the pads (and the crossover UART is unused); when debug_en
|
||||
is 1, then the pad_phy is passed through to its original destination,
|
||||
and the crossover is also passed through as usual (i.e., the behavior as
|
||||
if no pad_phy were provided).
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
def __init__(self, pad_phy=None, **kwargs):
|
||||
assert kwargs.get("phy", None) == None
|
||||
UART.__init__(self, **kwargs)
|
||||
self.xover = UART(tx_fifo_depth=1, rx_fifo_depth=16, rx_fifo_rx_we=True)
|
||||
self.comb += [
|
||||
self.source.connect(self.xover.sink),
|
||||
self.xover.source.connect(self.sink)
|
||||
]
|
||||
|
||||
if pad_phy is not None:
|
||||
# Steal the pads from the pad_phy.
|
||||
replaced_source = stream.Endpoint([("data", 8)])
|
||||
replaced_sink = stream.Endpoint([("data", 8)])
|
||||
|
||||
self.debug_en = CSRStorage(1, reset=1)
|
||||
# debug_en = 0:
|
||||
# pad_phy <-> self
|
||||
# xover dangles, uartbone_phy dangles
|
||||
# debug_en = 1:
|
||||
# xover <-> self
|
||||
# pad_phy <-> uartbone_phy
|
||||
|
||||
self.comb += If(self.debug_en.storage == 0,
|
||||
pad_phy.source.connect(self.sink),
|
||||
self.source.connect(pad_phy.sink),
|
||||
self.xover.source.ready.eq(0),
|
||||
self.xover.sink.valid.eq(0),
|
||||
replaced_source.valid.eq(0),
|
||||
replaced_sink.ready.eq(0),
|
||||
).Else(
|
||||
replaced_source.valid.eq(pad_phy.source.valid),
|
||||
replaced_source.data.eq(pad_phy.source.data),
|
||||
pad_phy.source.ready.eq(replaced_source.ready),
|
||||
pad_phy.sink.valid.eq(replaced_sink.valid),
|
||||
pad_phy.sink.data.eq(replaced_sink.data),
|
||||
replaced_sink.ready.eq(pad_phy.sink.ready),
|
||||
self.source.connect(self.xover.sink),
|
||||
self.xover.source.connect(self.sink),
|
||||
)
|
||||
pad_phy.source = replaced_source
|
||||
pad_phy.sink = replaced_sink
|
||||
else:
|
||||
self.comb += [
|
||||
self.source.connect(self.xover.sink),
|
||||
self.xover.source.connect(self.sink)
|
||||
]
|
||||
|
|
|
@ -1512,8 +1512,7 @@ class LiteXSoC(SoC):
|
|||
|
||||
# Crossover + UARTBone.
|
||||
elif uart_name in ["crossover+uartbone"]:
|
||||
self.add_uartbone(baudrate=baudrate)
|
||||
uart = UARTCrossover(**uart_kwargs)
|
||||
uart = self.add_uartbone(baudrate=baudrate, with_crossover=True, **uart_kwargs)
|
||||
|
||||
# JTAG UART.
|
||||
elif uart_name in ["jtag_uart"]:
|
||||
|
@ -1566,16 +1565,21 @@ class LiteXSoC(SoC):
|
|||
self.add_constant("UART_POLLING")
|
||||
|
||||
# Add UARTbone ---------------------------------------------------------------------------------
|
||||
def add_uartbone(self, name="uartbone", uart_name="serial", clk_freq=None, baudrate=115200, cd="sys"):
|
||||
def add_uartbone(self, name="uartbone", uart_name="serial", clk_freq=None, baudrate=115200, cd="sys", with_crossover=False, **uart_kwargs):
|
||||
# Imports.
|
||||
from litex.soc.cores import uart
|
||||
|
||||
# Core.
|
||||
if clk_freq is None:
|
||||
clk_freq = self.sys_clk_freq
|
||||
|
||||
self.check_if_exists(name)
|
||||
uartbone_phy = uart.UARTPHY(self.platform.request(uart_name), clk_freq, baudrate)
|
||||
uartbone = uart.UARTBone(
|
||||
|
||||
if with_crossover:
|
||||
crossover = uart.UARTCrossover(pad_phy=uartbone_phy, **uart_kwargs)
|
||||
|
||||
uartbone = uart.UARTBone(
|
||||
phy = uartbone_phy,
|
||||
clk_freq = clk_freq,
|
||||
cd = cd,
|
||||
|
@ -1584,6 +1588,9 @@ class LiteXSoC(SoC):
|
|||
self.add_module(name=name, module=uartbone)
|
||||
self.bus.add_master(name=name, master=uartbone.wishbone)
|
||||
|
||||
if with_crossover:
|
||||
return crossover
|
||||
|
||||
# Add JTAGbone ---------------------------------------------------------------------------------
|
||||
def add_jtagbone(self, name="jtagbone", chain=1):
|
||||
# Imports.
|
||||
|
|
|
@ -187,14 +187,14 @@ class SoCCore(LiteXSoC):
|
|||
|
||||
if with_uart:
|
||||
# crossover+uartbone is kept as backward compatibility
|
||||
if uart_name == "crossover+uartbone":
|
||||
self.logger.warning("{} UART: is deprecated {}".format(
|
||||
colorer(uart_name, color="yellow"),
|
||||
colorer("please use --uart-name=\"crossover\" --with-uartbone", color="red")))
|
||||
time.sleep(2)
|
||||
# Already configured.
|
||||
self._uartbone = True
|
||||
uart_name = "crossover"
|
||||
#if uart_name == "crossover+uartbone":
|
||||
# self.logger.warning("{} UART: is deprecated {}".format(
|
||||
# colorer(uart_name, color="yellow"),
|
||||
# colorer("please use --uart-name=\"crossover\" --with-uartbone", color="red")))
|
||||
# time.sleep(2)
|
||||
# # Already configured.
|
||||
# self._uartbone = True
|
||||
# uart_name = "crossover"
|
||||
|
||||
# JTAGBone and jtag_uart can't be used at the same time.
|
||||
assert not (with_jtagbone and uart_name == "jtag_uart")
|
||||
|
|
Loading…
Reference in a new issue