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
|
@ -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
|
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.
|
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
|
assert kwargs.get("phy", None) == None
|
||||||
UART.__init__(self, **kwargs)
|
UART.__init__(self, **kwargs)
|
||||||
self.xover = UART(tx_fifo_depth=1, rx_fifo_depth=16, rx_fifo_rx_we=True)
|
self.xover = UART(tx_fifo_depth=1, rx_fifo_depth=16, rx_fifo_rx_we=True)
|
||||||
self.comb += [
|
|
||||||
self.source.connect(self.xover.sink),
|
if pad_phy is not None:
|
||||||
self.xover.source.connect(self.sink)
|
# 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.
|
# Crossover + UARTBone.
|
||||||
elif uart_name in ["crossover+uartbone"]:
|
elif uart_name in ["crossover+uartbone"]:
|
||||||
self.add_uartbone(baudrate=baudrate)
|
uart = self.add_uartbone(baudrate=baudrate, with_crossover=True, **uart_kwargs)
|
||||||
uart = UARTCrossover(**uart_kwargs)
|
|
||||||
|
|
||||||
# JTAG UART.
|
# JTAG UART.
|
||||||
elif uart_name in ["jtag_uart"]:
|
elif uart_name in ["jtag_uart"]:
|
||||||
|
@ -1566,16 +1565,21 @@ class LiteXSoC(SoC):
|
||||||
self.add_constant("UART_POLLING")
|
self.add_constant("UART_POLLING")
|
||||||
|
|
||||||
# Add UARTbone ---------------------------------------------------------------------------------
|
# 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.
|
# Imports.
|
||||||
from litex.soc.cores import uart
|
from litex.soc.cores import uart
|
||||||
|
|
||||||
# Core.
|
# Core.
|
||||||
if clk_freq is None:
|
if clk_freq is None:
|
||||||
clk_freq = self.sys_clk_freq
|
clk_freq = self.sys_clk_freq
|
||||||
|
|
||||||
self.check_if_exists(name)
|
self.check_if_exists(name)
|
||||||
uartbone_phy = uart.UARTPHY(self.platform.request(uart_name), clk_freq, baudrate)
|
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,
|
phy = uartbone_phy,
|
||||||
clk_freq = clk_freq,
|
clk_freq = clk_freq,
|
||||||
cd = cd,
|
cd = cd,
|
||||||
|
@ -1584,6 +1588,9 @@ class LiteXSoC(SoC):
|
||||||
self.add_module(name=name, module=uartbone)
|
self.add_module(name=name, module=uartbone)
|
||||||
self.bus.add_master(name=name, master=uartbone.wishbone)
|
self.bus.add_master(name=name, master=uartbone.wishbone)
|
||||||
|
|
||||||
|
if with_crossover:
|
||||||
|
return crossover
|
||||||
|
|
||||||
# Add JTAGbone ---------------------------------------------------------------------------------
|
# Add JTAGbone ---------------------------------------------------------------------------------
|
||||||
def add_jtagbone(self, name="jtagbone", chain=1):
|
def add_jtagbone(self, name="jtagbone", chain=1):
|
||||||
# Imports.
|
# Imports.
|
||||||
|
|
|
@ -187,14 +187,14 @@ class SoCCore(LiteXSoC):
|
||||||
|
|
||||||
if with_uart:
|
if with_uart:
|
||||||
# crossover+uartbone is kept as backward compatibility
|
# crossover+uartbone is kept as backward compatibility
|
||||||
if uart_name == "crossover+uartbone":
|
#if uart_name == "crossover+uartbone":
|
||||||
self.logger.warning("{} UART: is deprecated {}".format(
|
# self.logger.warning("{} UART: is deprecated {}".format(
|
||||||
colorer(uart_name, color="yellow"),
|
# colorer(uart_name, color="yellow"),
|
||||||
colorer("please use --uart-name=\"crossover\" --with-uartbone", color="red")))
|
# colorer("please use --uart-name=\"crossover\" --with-uartbone", color="red")))
|
||||||
time.sleep(2)
|
# time.sleep(2)
|
||||||
# Already configured.
|
# # Already configured.
|
||||||
self._uartbone = True
|
# self._uartbone = True
|
||||||
uart_name = "crossover"
|
# uart_name = "crossover"
|
||||||
|
|
||||||
# JTAGBone and jtag_uart can't be used at the same time.
|
# JTAGBone and jtag_uart can't be used at the same time.
|
||||||
assert not (with_jtagbone and uart_name == "jtag_uart")
|
assert not (with_jtagbone and uart_name == "jtag_uart")
|
||||||
|
|
Loading…
Reference in New Issue