feat: refactor UART implementation to support flow control and enhance functionality

- Removed UART files from clusterip and updated file lists accordingly.
- Added new UART flow control module and interface to manage RTS/CTS signals.
- Updated UART formal verification files to include new flow control signals.
- Modified UART testbench to validate flow control behavior and updated test cases.
- Adjusted top-level design to integrate new UART interface and signal connections.
- Enhanced GPIO pin mapping to accommodate new UART control signals.
- Updated linting and formal generation scripts to reflect changes in UART structure.
This commit is contained in:
maksyuki committed 2026-08-11 14:17:33 +08:00
1 parent a215f2b9bb
commit 9314b5950f
37 files changed
+1182 -620

No files matched your search

-1
View File
@@ -76,7 +76,6 @@ jobs:
rtl/managed/clusterip/rng
rtl/managed/clusterip/rtc
rtl/managed/clusterip/spi
rtl/managed/clusterip/uart
rtl/managed/clusterip/wdg
rtl/managed/third_party
rtl/managed/mpw
-1
View File
@@ -35,7 +35,6 @@ jobs:
rtl/managed/clusterip/rng
rtl/managed/clusterip/rtc
rtl/managed/clusterip/spi
rtl/managed/clusterip/uart
rtl/managed/clusterip/wdg
rtl/managed/third_party
rtl/managed/mpw
+8 -4
View File
@@ -160,7 +160,7 @@ static bool rs_ci_smoke_gpio_v2(void) {
return rs_gpio_write(31U, false) == RS_OK;
}
static bool rs_ci_smoke_uart_v2(void) {
static bool rs_ci_smoke_uart_v3(void) {
const rs_uart_config_t config = {
.source_clock_hz = CPU_FREQ * UINT32_C(1000000),
.baud_rate = UART_BPS,
@@ -173,12 +173,16 @@ static bool rs_ci_smoke_uart_v2(void) {
.tx_enable = true,
.rx_enable = true,
.loopback_enable = true,
.auto_cts_enable = false,
.auto_rts_enable = false,
.rts_assert_level = 32U,
.rts_deassert_level = 48U,
};
const uint8_t transmitted = UINT8_C(0xA5);
rs_uart_rx_data_t received;
if ((RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, UINT32_C(0xF8)) != UINT32_C(0x00020000)) ||
(RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, UINT32_C(0xFC)) != UINT32_C(0x00FF4040)) ||
if ((RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, UINT32_C(0xF8)) != UINT32_C(0x00030000)) ||
(RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, UINT32_C(0xFC)) != UINT32_C(0x03FF4040)) ||
(rs_uart_configure(&config, RS_TIMEOUT_DEFAULT) != RS_OK) ||
(rs_uart_write(&transmitted, 1U, RS_TIMEOUT_DEFAULT) != RS_OK) ||
(rs_uart_read(&received, 1U, RS_TIMEOUT_DEFAULT) != RS_OK) ||
@@ -193,7 +197,7 @@ int main(void) {
rs_test_finish(RS_TEST_FAILED, 6U);
}
if (!rs_ci_smoke_uart_v2()) {
if (!rs_ci_smoke_uart_v3()) {
rs_test_finish(RS_TEST_FAILED, 7U);
}
-1
View File
@@ -72,7 +72,6 @@
"cluster_rng": {"url": "https://github.com/retroSoC/rng.git", "revision": "36f3e0774d8f3c4b597d3db8a96ca3992532b61e", "destination": "rtl/managed/clusterip/rng", "license": "MulanPSL-2.0"},
"cluster_rtc": {"url": "https://github.com/retroSoC/rtc.git", "revision": "32548c5cbcdf39e09d0880fb611f9dd47940ea88", "destination": "rtl/managed/clusterip/rtc", "license": "NOASSERTION"},
"cluster_spi": {"url": "https://github.com/retroSoC/spi.git", "revision": "515cb408806584525605b4747db5e890dbdf1928", "destination": "rtl/managed/clusterip/spi", "license": "NOASSERTION"},
"cluster_uart": {"url": "https://github.com/retroSoC/uart.git", "revision": "eca12213ba06f42e0a6dd0f27907fd4c447e2774", "destination": "rtl/managed/clusterip/uart", "license": "NOASSERTION"},
"cluster_wdg": {"url": "https://github.com/retroSoC/wdg.git", "revision": "134be4b884efa8683b1617ceb41f17399b4bb83f", "destination": "rtl/managed/clusterip/wdg", "license": "MulanPSL-2.0"}
},
"archives": {
+20 -11
View File
@@ -7,18 +7,23 @@
#include <retrosoc/core/status.h>
#define RS_UART_ERROR_PARITY UINT32_C(0x01)
#define RS_UART_ERROR_FRAME UINT32_C(0x02)
#define RS_UART_ERROR_BREAK UINT32_C(0x04)
#define RS_UART_ERROR_NOISE UINT32_C(0x08)
#define RS_UART_ERROR_PARITY UINT32_C(0x01)
#define RS_UART_ERROR_FRAME UINT32_C(0x02)
#define RS_UART_ERROR_BREAK UINT32_C(0x04)
#define RS_UART_ERROR_NOISE UINT32_C(0x08)
#define RS_UART_INTR_RX_WATERMARK UINT32_C(0x01)
#define RS_UART_INTR_RX_TIMEOUT UINT32_C(0x02)
#define RS_UART_INTR_TX_WATERMARK UINT32_C(0x04)
#define RS_UART_INTR_TX_DONE UINT32_C(0x08)
#define RS_UART_INTR_RX_ERROR UINT32_C(0x10)
#define RS_UART_INTR_BREAK UINT32_C(0x20)
#define RS_UART_INTR_ALL UINT32_C(0x3F)
#define RS_UART_INTR_RX_WATERMARK UINT32_C(0x01)
#define RS_UART_INTR_RX_TIMEOUT UINT32_C(0x02)
#define RS_UART_INTR_TX_WATERMARK UINT32_C(0x04)
#define RS_UART_INTR_TX_DONE UINT32_C(0x08)
#define RS_UART_INTR_RX_ERROR UINT32_C(0x10)
#define RS_UART_INTR_BREAK UINT32_C(0x20)
#define RS_UART_INTR_CTS_CHANGE UINT32_C(0x40)
#define RS_UART_INTR_ALL UINT32_C(0x7F)
#define RS_UART_STATUS_CTS_ASSERTED (UINT32_C(1) << 12U)
#define RS_UART_STATUS_RTS_ASSERTED (UINT32_C(1) << 13U)
#define RS_UART_STATUS_TX_FLOW_BLOCKED (UINT32_C(1) << 14U)
typedef enum {
RS_UART_PARITY_NONE = 0,
@@ -38,6 +43,10 @@ typedef struct {
bool tx_enable;
bool rx_enable;
bool loopback_enable;
bool auto_cts_enable;
bool auto_rts_enable;
uint8_t rts_assert_level;
uint8_t rts_deassert_level;
} rs_uart_config_t;
typedef struct {
+90 -32
View File
@@ -2,41 +2,50 @@
#include <retrosoc/core/soc.h>
#include <retrosoc/hal/dma.h>
#include <retrosoc/hal/gpio.h>
#include <retrosoc/hal/uart.h>
#define RS_UART_REG(offset) RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, (offset))
#define RS_UART_REG(offset) RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, (offset))
#define RS_UART_BAUD_INT RS_UART_REG(UINT32_C(0x00))
#define RS_UART_BAUD_FRAC RS_UART_REG(UINT32_C(0x04))
#define RS_UART_LINE_CTRL RS_UART_REG(UINT32_C(0x08))
#define RS_UART_CTRL RS_UART_REG(UINT32_C(0x0C))
#define RS_UART_TXDATA RS_UART_REG(UINT32_C(0x10))
#define RS_UART_RXDATA RS_UART_REG(UINT32_C(0x14))
#define RS_UART_STATUS RS_UART_REG(UINT32_C(0x18))
#define RS_UART_FIFO_LEVEL RS_UART_REG(UINT32_C(0x1C))
#define RS_UART_FIFO_CTRL RS_UART_REG(UINT32_C(0x20))
#define RS_UART_TX_WATERMARK RS_UART_REG(UINT32_C(0x24))
#define RS_UART_RX_WATERMARK RS_UART_REG(UINT32_C(0x28))
#define RS_UART_RX_TIMEOUT RS_UART_REG(UINT32_C(0x2C))
#define RS_UART_ERROR_STATUS RS_UART_REG(UINT32_C(0x30))
#define RS_UART_INTR_STATE RS_UART_REG(UINT32_C(0x34))
#define RS_UART_INTR_ENABLE RS_UART_REG(UINT32_C(0x38))
#define RS_UART_INTR_TEST RS_UART_REG(UINT32_C(0x40))
#define RS_UART_DMA_CTRL RS_UART_REG(UINT32_C(0x44))
#define RS_UART_BAUD_INT RS_UART_REG(UINT32_C(0x00))
#define RS_UART_BAUD_FRAC RS_UART_REG(UINT32_C(0x04))
#define RS_UART_LINE_CTRL RS_UART_REG(UINT32_C(0x08))
#define RS_UART_CTRL RS_UART_REG(UINT32_C(0x0C))
#define RS_UART_TXDATA RS_UART_REG(UINT32_C(0x10))
#define RS_UART_RXDATA RS_UART_REG(UINT32_C(0x14))
#define RS_UART_STATUS RS_UART_REG(UINT32_C(0x18))
#define RS_UART_FIFO_LEVEL RS_UART_REG(UINT32_C(0x1C))
#define RS_UART_FIFO_CTRL RS_UART_REG(UINT32_C(0x20))
#define RS_UART_TX_WATERMARK RS_UART_REG(UINT32_C(0x24))
#define RS_UART_RX_WATERMARK RS_UART_REG(UINT32_C(0x28))
#define RS_UART_RX_TIMEOUT RS_UART_REG(UINT32_C(0x2C))
#define RS_UART_ERROR_STATUS RS_UART_REG(UINT32_C(0x30))
#define RS_UART_INTR_STATE RS_UART_REG(UINT32_C(0x34))
#define RS_UART_INTR_ENABLE RS_UART_REG(UINT32_C(0x38))
#define RS_UART_INTR_TEST RS_UART_REG(UINT32_C(0x40))
#define RS_UART_DMA_CTRL RS_UART_REG(UINT32_C(0x44))
#define RS_UART_FLOW_CTRL RS_UART_REG(UINT32_C(0x48))
#define RS_UART_RTS_WATERMARK RS_UART_REG(UINT32_C(0x4C))
#define RS_UART_CTRL_TX_ENABLE UINT32_C(0x01)
#define RS_UART_CTRL_RX_ENABLE UINT32_C(0x02)
#define RS_UART_CTRL_LOOPBACK UINT32_C(0x04)
#define RS_UART_STATUS_TX_BUSY UINT32_C(0x04)
#define RS_UART_STATUS_RX_BUSY UINT32_C(0x08)
#define RS_UART_STATUS_TX_FULL UINT32_C(0x20)
#define RS_UART_STATUS_RX_EMPTY UINT32_C(0x40)
#define RS_UART_STATUS_CONFIG_VALID UINT32_C(0x100)
#define RS_UART_FIFO_TX_FLUSH UINT32_C(0x01)
#define RS_UART_FIFO_RX_FLUSH UINT32_C(0x02)
#define RS_UART_ERROR_ALL UINT32_C(0x7F)
#define RS_UART_DMA_TX_ENABLE UINT32_C(0x01)
#define RS_UART_DMA_RX_ENABLE UINT32_C(0x02)
#define RS_UART_CTRL_TX_ENABLE UINT32_C(0x01)
#define RS_UART_CTRL_RX_ENABLE UINT32_C(0x02)
#define RS_UART_CTRL_LOOPBACK UINT32_C(0x04)
#define RS_UART_STATUS_TX_BUSY UINT32_C(0x04)
#define RS_UART_STATUS_RX_BUSY UINT32_C(0x08)
#define RS_UART_STATUS_TX_FULL UINT32_C(0x20)
#define RS_UART_STATUS_RX_EMPTY UINT32_C(0x40)
#define RS_UART_STATUS_CONFIG_VALID UINT32_C(0x100)
#define RS_UART_FIFO_TX_FLUSH UINT32_C(0x01)
#define RS_UART_FIFO_RX_FLUSH UINT32_C(0x02)
#define RS_UART_ERROR_ALL UINT32_C(0x7F)
#define RS_UART_DMA_TX_ENABLE UINT32_C(0x01)
#define RS_UART_DMA_RX_ENABLE UINT32_C(0x02)
#define RS_UART_FLOW_AUTO_CTS UINT32_C(0x01)
#define RS_UART_FLOW_AUTO_RTS UINT32_C(0x02)
#define RS_UART_CTS_GPIO UINT32_C(0)
#define RS_UART_RTS_GPIO UINT32_C(1)
#define RS_UART_RTS_ASSERT_DEFAULT UINT32_C(32)
#define RS_UART_RTS_DEASSERT_DEFAULT UINT32_C(48)
static uint32_t rs_uart_control_from_config(const rs_uart_config_t *config) {
uint32_t control = 0U;
@@ -57,12 +66,40 @@ static bool rs_uart_config_valid(const rs_uart_config_t *config) {
return (config != NULL) && (config->data_bits >= 5U) && (config->data_bits <= 8U) &&
((config->stop_bits == 1U) || (config->stop_bits == 2U)) &&
(config->parity <= RS_UART_PARITY_ODD) && (config->tx_watermark < 64U) &&
(config->rx_watermark > 0U) && (config->rx_watermark <= 64U);
(config->rx_watermark > 0U) && (config->rx_watermark <= 64U) &&
(!config->auto_rts_enable || ((config->rts_assert_level < config->rts_deassert_level) &&
(config->rts_deassert_level <= 64U)));
}
static rs_status_t rs_uart_flow_gpio_configure(const rs_uart_config_t *config) {
const rs_gpio_config_t pin_config = {
.mode = RS_GPIO_MODE_ALT0,
.pull = RS_GPIO_PULL_NONE,
.trigger = RS_GPIO_TRIGGER_NONE,
.output_high = true,
.open_drain = false,
.input_cmos = false,
.filter_enable = false,
.interrupt_enable = false,
};
rs_status_t status = RS_OK;
if (config->auto_cts_enable) {
status = rs_gpio_configure(RS_UART_CTS_GPIO, &pin_config);
}
if ((status == RS_OK) && config->auto_rts_enable) {
status = rs_gpio_configure(RS_UART_RTS_GPIO, &pin_config);
}
return status;
}
rs_status_t rs_uart_configure(const rs_uart_config_t *config, rs_timeout_t timeout) {
rs_uart_timing_t timing;
rs_status_t status;
uint32_t flow_control = 0U;
uint32_t line_control;
uint32_t rts_assert_level;
uint32_t rts_deassert_level;
if (!rs_uart_config_valid(config) ||
(rs_uart_timing_calculate(config->source_clock_hz, config->baud_rate, &timing) != RS_OK)) {
@@ -78,6 +115,11 @@ rs_status_t rs_uart_configure(const rs_uart_config_t *config, rs_timeout_t timeo
return RS_ETIMEOUT;
}
status = rs_uart_flow_gpio_configure(config);
if (status != RS_OK) {
return status;
}
RS_UART_FIFO_CTRL = RS_UART_FIFO_TX_FLUSH | RS_UART_FIFO_RX_FLUSH;
RS_UART_ERROR_STATUS = RS_UART_ERROR_ALL;
RS_UART_INTR_STATE = RS_UART_INTR_ALL;
@@ -90,6 +132,18 @@ rs_status_t rs_uart_configure(const rs_uart_config_t *config, rs_timeout_t timeo
RS_UART_RX_WATERMARK = config->rx_watermark;
RS_UART_RX_TIMEOUT = config->rx_timeout_bits;
RS_UART_DMA_CTRL = 0U;
if (config->auto_cts_enable) {
flow_control |= RS_UART_FLOW_AUTO_CTS;
}
if (config->auto_rts_enable) {
flow_control |= RS_UART_FLOW_AUTO_RTS;
}
rts_assert_level =
config->auto_rts_enable ? config->rts_assert_level : RS_UART_RTS_ASSERT_DEFAULT;
rts_deassert_level =
config->auto_rts_enable ? config->rts_deassert_level : RS_UART_RTS_DEASSERT_DEFAULT;
RS_UART_RTS_WATERMARK = rts_assert_level | (rts_deassert_level << 16U);
RS_UART_FLOW_CTRL = flow_control;
RS_UART_CTRL = rs_uart_control_from_config(config);
return ((RS_UART_STATUS & RS_UART_STATUS_CONFIG_VALID) != 0U) ? RS_OK : RS_EIO;
@@ -108,6 +162,10 @@ rs_status_t rs_uart_init(uint32_t source_clock_hz, uint32_t baud_rate) {
.tx_enable = true,
.rx_enable = true,
.loopback_enable = false,
.auto_cts_enable = false,
.auto_rts_enable = false,
.rts_assert_level = (uint8_t)RS_UART_RTS_ASSERT_DEFAULT,
.rts_deassert_level = (uint8_t)RS_UART_RTS_DEASSERT_DEFAULT,
};
return rs_uart_configure(&config, RS_TIMEOUT_DEFAULT);
}
+2 -2
View File
@@ -28,8 +28,8 @@ the root README and subsystem guides.
timebase, RV32 access rules, interrupt behavior, and verification contract.
- [ip/gpio.md](ip/gpio.md) defines the GPIO V2 dual-window ABI, pad ownership,
filtering, interrupts, PDK capabilities, HAL, and verification contract.
- [ip/uart.md](ip/uart.md) defines the UART V2 framing, FIFO, error, interrupt,
DMA, HAL, and verification contracts.
- [ip/uart.md](ip/uart.md) defines the UART V3 framing, FIFO, RTS/CTS flow
control, error, interrupt, DMA, HAL, and verification contracts.
- [ip/i2c.md](ip/i2c.md) defines the dual I2C V2 command, timing, error,
recovery, DMA, HAL, and verification contracts.
- [ip/ps2.md](ip/ps2.md) defines the Mini SoC PS/2 V2 APB, GPIO pad,
+1 -1
View File
@@ -7,7 +7,7 @@ verification documentation for self-owned retroSoC peripheral IP.
- [ws2812.md](ws2812.md) defines the WS2812 transmitter.
- [clint.md](clint.md) defines the management-hart software and timer interrupt block.
- [gpio.md](gpio.md) defines the dual-window GPIO controller.
- [uart.md](uart.md) defines the RIBP UART V2 controller.
- [uart.md](uart.md) defines the RIBP UART V3 controller.
- [i2c.md](i2c.md) defines the dual RIBP I2C V2 controllers.
The corresponding RTL and HAL implementations remain the executable sources
+58 -20
View File
@@ -1,10 +1,10 @@
# RIBP UART V2
# RIBP UART V3
UART0 is the Mini SoC management console and a general-purpose full-duplex
serial port. UART V2 provides independent 64-byte transmit and receive FIFOs,
serial port. UART V3 provides independent 64-byte transmit and receive FIFOs,
fractional baud-rate generation, configurable framing, receive diagnostics,
watermark and timeout interrupts, internal loopback, break generation, and
generic-DMA request pacing.
watermark and timeout interrupts, internal loopback, break generation,
generic-DMA request pacing, and automatic active-low RTS/CTS flow control.
## Integration
@@ -15,11 +15,13 @@ generic-DMA request pacing.
| RIBP interrupt group bit | 2 |
| Management-core interrupt | 2 |
| DMA modes | 5 UART TX, 6 UART RX |
| External signals | `uart0_tx`, `uart0_rx` |
| Dedicated signals | `uart0_tx`, `uart0_rx` |
| Flow-control signals | GPIO0 ALT0 `uart0_cts_n`, GPIO1 ALT0 `uart0_rts_n` |
UART0 and the generic DMA share the SoC clock domain. The existing `uart_if`
continues to own the physical RX, TX, and IRQ signals; DMA readiness is a
separate internal connection.
UART0 and the generic DMA share the SoC clock domain. The self-owned `uart_if`
contains RX, TX, active-low CTS/RTS, and IRQ. RX/TX retain their dedicated
package pads. CTS/RTS reuse GPIO0/1 ALT0, while GPIO0/1 ALT1 remains the PS/2
clock/data route. DMA readiness is a separate internal connection.
## Register ABI
@@ -43,13 +45,15 @@ require the low byte lane; selected upper lanes must contain zero.
| `0x028` | `RX_WATERMARK` | RW | High-water threshold, 1 through 64; reset value 32. |
| `0x02C` | `RX_TIMEOUT_BITS` | RW | Idle bit periods before timeout; zero disables, reset value 32. |
| `0x030` | `ERROR_STATUS` | RW1C | Overrun, parity, frame, break, noise, config, command. |
| `0x034` | `INTR_STATE` | RW1C | RX water/timeout, TX water/done, RX error, break. |
| `0x034` | `INTR_STATE` | RW1C | RX water/timeout, TX water/done, RX error, break, CTS change. |
| `0x038` | `INTR_ENABLE` | RW | Interrupt enable mask. |
| `0x03C` | `INTR_STATUS` | RO | `INTR_STATE & INTR_ENABLE`. |
| `0x040` | `INTR_TEST` | WO | Write-one interrupt injection. |
| `0x044` | `DMA_CTRL` | RW | TX and RX DMA request enables. |
| `0x0F8` | `IP_VERSION` | RO | `0x00020000`, ABI 2.0. |
| `0x0FC` | `CAPABILITY` | RO | `0x00FF4040`, depths and implemented features. |
| `0x048` | `FLOW_CTRL` | RW | Bit 0 enables automatic CTS; bit 1 enables automatic RTS. |
| `0x04C` | `RTS_WATERMARK` | RW | Assert/ready level at bits 6:0 and deassert/halt level at bits 22:16. |
| `0x0F8` | `IP_VERSION` | RO | `0x00030000`, ABI 3.0. |
| `0x0FC` | `CAPABILITY` | RO | `0x03FF4040`, depths and implemented features. |
`LINE_CTRL.DATA_BITS` values 0 through 3 select 5 through 8 bits. Bit 2
selects two stop bits. Bits 4:3 select none, even, or odd parity; value 3 is
@@ -60,6 +64,18 @@ break.
error, break, and inconsistent majority samples. A full RX FIFO drops the new
character and sets global overrun. An empty `RXDATA` read returns `resp_err`.
`STATUS[12]` reports synchronized CTS asserted, `STATUS[13]` reports RTS
asserted, and `STATUS[14]` reports that queued TX data is waiting for CTS.
Interrupt bit 6 is sticky on either synchronized CTS edge while automatic CTS
is enabled. All interrupt state, enable, status, test, and clear masks are
seven bits in V3.
`RTS_WATERMARK` resets to assert/ready level 32 and deassert/halt level 48.
Software must program `assert < deassert <= 64`. UART configuration registers,
including both flow-control registers, can change only while TX/RX are disabled
and both engines are idle. Illegal thresholds or an active-engine update return
`resp_err` and set the configuration error bit.
## Timing and transfer behavior
The programmed bit period is `BAUD_INT + BAUD_FRAC / 256`. A phase accumulator
@@ -74,6 +90,20 @@ but lets the current frame finish; clearing RX enable aborts a partial frame.
TX break is accepted only while the transmitter is idle. FIFO contents are
preserved by enable changes and are discarded only by an accepted flush.
With automatic CTS enabled, synchronized low `cts_n` permits the transmitter
to remove a character from the TX FIFO and start a frame. CTS deassertion never
truncates an active frame; it prevents only the next frame. Internal loopback
bypasses CTS so production test cannot deadlock on an unconnected pad. The CTS
synchronizer resets to not-clear-to-send, which is fail-safe when flow control
is enabled before a valid external level arrives.
With automatic RTS enabled and RX enabled, `rts_n` is low while the receiver can
accept data. At or above the deassert watermark it rises to request that the
peer stop. It remains high until software drains the FIFO to or below the
assert watermark, providing hysteresis. The output releases high immediately
when automatic RTS or RX is disabled. FIFO push/pop changes affect the
registered hysteresis state at the following SoC-clock boundary.
A full `TXDATA` write applies RIBP backpressure while the enabled transmitter
can make progress. A full write while disabled is rejected, avoiding an
unbounded bus wait. TX-done is raised when a transmitted character leaves both
@@ -94,16 +124,24 @@ status and interrupt control, FIFO flush, and UART-paced DMA transfers.
`putch()` remains the internal formatted-output sink, while applications use
`rs_uart_init()` or `rs_uart_configure()` instead of raw registers.
Enabling automatic CTS or RTS through `rs_uart_configure()` selects GPIO0 or
GPIO1 ALT0 respectively. Disabling flow control leaves that GPIO mux selection
unchanged so another driver is never enabled implicitly; software must
explicitly reconfigure a pin before reusing it. Default initialization leaves
both automatic functions disabled, preserving console behavior on boards that
do not route flow-control signals.
## Verification and current scope
The self-checking RTL test covers the versioned ABI, access errors, FIFO depth,
8N1 loopback, external frame errors, W1C interrupt behavior, and DMA request
gating. The SBY target proves FIFO bounds, IRQ composition, disabled-DMA
gating, and TX idle/break levels, and covers bus error, TX/RX activity, error,
and IRQ paths. Host tests cover exact fractional timing and invalid ranges;
the CI smoke firmware verifies capability registers and loopback through the
public HAL.
8N1 loopback, external frame errors, CTS frame-boundary gating, loopback bypass,
RTS hysteresis, CTS-change interrupt behavior, and DMA request gating. The SBY
target proves FIFO bounds, IRQ composition, disabled-DMA gating, RTS release,
flow-block consistency, forbidden TX FIFO pops, and TX idle/break levels, and
covers bus error, TX/RX activity, flow blocking, RTS assertion, error, and IRQ
paths. Host tests cover exact fractional timing and invalid ranges; the CI smoke
firmware verifies V3 capability registers and loopback through the public HAL.
Hardware RTS/CTS, IrDA, RS485 direction control, automatic baud detection, and
low-power wakeup are outside UART V2. Adding one requires a versioned ABI and,
where applicable, explicit pad and clock/reset integration.
IrDA, RS485 direction control, automatic baud detection, modem-status inputs,
and low-power wakeup are outside UART V3. Adding one requires a versioned ABI
and, where applicable, explicit pad and clock/reset integration.
+2 -1
View File
@@ -132,7 +132,7 @@ digraph mini_soc_block_diagram {
];
uart0 [
fillcolor="#F9E1E7",
label="UART0 V2\n64-byte TX/RX FIFOs, fractional baud\nframing/errors, IRQ2, DMA-paced"
label="UART0 V3\n64-byte TX/RX FIFOs, fractional baud\nauto RTS/CTS, framing/errors, IRQ2, DMA-paced"
];
i2c_controllers [
fillcolor="#F9E1E7",
@@ -245,6 +245,7 @@ digraph mini_soc_block_diagram {
dma -> ws2812 [label="TXDATA writes", style=dashed];
ws2812 -> irq [label="IRQ17"];
dma -> uart0 [label="TX/RX data", style=dashed];
uart0 -> gpio_controller [dir=both, label="GPIO0/1 ALT0\nCTS_n / RTS_n"];
uart0 -> irq [label="IRQ2"];
i2c_controllers -> gpio_controller [label="GPIO3/4 ALT1\nGPIO7/8 ALT0"];
dma -> i2c_controllers [label="DATA_CMD / RXDATA", style=dashed];
+322 -313
View File
@@ -4,19 +4,19 @@
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: mini_soc_block_diagram Pages: 1 -->
<svg width="3995pt" height="905pt"
viewBox="0.00 0.00 3995.00 905.48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg width="3982pt" height="905pt"
viewBox="0.00 0.00 3982.00 905.48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 901.48)">
<title>mini_soc_block_diagram</title>
<text text-anchor="middle" x="132" y="-879.08" font-family="Arial" font-size="18.00">retroSoC Mini SoC Architecture</text>
<g id="clust1" class="cluster">
<title>cluster_asic</title>
<path fill="transparent" stroke="#111827" d="M160,-85C160,-85 3967,-85 3967,-85 3973,-85 3979,-91 3979,-97 3979,-97 3979,-781.48 3979,-781.48 3979,-787.48 3973,-793.48 3967,-793.48 3967,-793.48 160,-793.48 160,-793.48 154,-793.48 148,-787.48 148,-781.48 148,-781.48 148,-97 148,-97 148,-91 154,-85 160,-85"/>
<path fill="transparent" stroke="#111827" d="M160,-85C160,-85 3954,-85 3954,-85 3960,-85 3966,-91 3966,-97 3966,-97 3966,-781.48 3966,-781.48 3966,-787.48 3960,-793.48 3954,-793.48 3954,-793.48 160,-793.48 160,-793.48 154,-793.48 148,-787.48 148,-781.48 148,-781.48 148,-97 148,-97 148,-91 154,-85 160,-85"/>
<text text-anchor="middle" x="196.5" y="-778.28" font-family="Arial" font-size="14.00" fill="#111827">retrosoc_asic</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_soc</title>
<path fill="transparent" stroke="#94a3b8" stroke-dasharray="5,2" d="M390,-103C390,-103 3949,-103 3949,-103 3955,-103 3961,-109 3961,-115 3961,-115 3961,-738.48 3961,-738.48 3961,-744.48 3955,-750.48 3949,-750.48 3949,-750.48 390,-750.48 390,-750.48 384,-750.48 378,-744.48 378,-738.48 378,-738.48 378,-115 378,-115 378,-109 384,-103 390,-103"/>
<path fill="transparent" stroke="#94a3b8" stroke-dasharray="5,2" d="M390,-103C390,-103 3936,-103 3936,-103 3942,-103 3948,-109 3948,-115 3948,-115 3948,-738.48 3948,-738.48 3948,-744.48 3942,-750.48 3936,-750.48 3936,-750.48 390,-750.48 390,-750.48 384,-750.48 378,-744.48 378,-738.48 378,-738.48 378,-115 378,-115 378,-109 384,-103 390,-103"/>
<text text-anchor="middle" x="407.5" y="-736.88" font-family="Arial" font-size="12.00" fill="#334155">retrosoc</text>
</g>
<!-- ext_clock -->
@@ -44,374 +44,374 @@
<!-- ext_io -->
<g id="node2" class="node">
<title>ext_io</title>
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M3059,-45C3059,-45 2839,-45 2839,-45 2833,-45 2827,-39 2827,-33 2827,-33 2827,-12 2827,-12 2827,-6 2833,0 2839,0 2839,0 3059,0 3059,0 3065,0 3071,-6 3071,-12 3071,-12 3071,-33 3071,-33 3071,-39 3065,-45 3059,-45"/>
<text text-anchor="middle" x="2949" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
<text text-anchor="middle" x="2949" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, PS/2, XPI Flash, SDRAM, PSRAM</text>
<text text-anchor="middle" x="2949" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP, WS2812 and PWM V2</text>
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M3211,-45C3211,-45 2991,-45 2991,-45 2985,-45 2979,-39 2979,-33 2979,-33 2979,-12 2979,-12 2979,-6 2985,0 2991,0 2991,0 3211,0 3211,0 3217,0 3223,-6 3223,-12 3223,-12 3223,-33 3223,-33 3223,-39 3217,-45 3211,-45"/>
<text text-anchor="middle" x="3101" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
<text text-anchor="middle" x="3101" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, PS/2, XPI Flash, SDRAM, PSRAM</text>
<text text-anchor="middle" x="3101" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP, WS2812 and PWM V2</text>
</g>
<!-- ext_jtag -->
<g id="node3" class="node">
<title>ext_jtag</title>
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M2998.5,-869.48C2998.5,-869.48 2867.5,-869.48 2867.5,-869.48 2861.5,-869.48 2855.5,-863.48 2855.5,-857.48 2855.5,-857.48 2855.5,-845.48 2855.5,-845.48 2855.5,-839.48 2861.5,-833.48 2867.5,-833.48 2867.5,-833.48 2998.5,-833.48 2998.5,-833.48 3004.5,-833.48 3010.5,-839.48 3010.5,-845.48 3010.5,-845.48 3010.5,-857.48 3010.5,-857.48 3010.5,-863.48 3004.5,-869.48 2998.5,-869.48"/>
<text text-anchor="middle" x="2933" y="-854.48" font-family="Arial" font-size="10.00" fill="#111827">Management JTAG</text>
<text text-anchor="middle" x="2933" y="-843.48" font-family="Arial" font-size="10.00" fill="#111827">TCK, TMS, TDI, TRST_n, TDO</text>
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M2579.5,-869.48C2579.5,-869.48 2448.5,-869.48 2448.5,-869.48 2442.5,-869.48 2436.5,-863.48 2436.5,-857.48 2436.5,-857.48 2436.5,-845.48 2436.5,-845.48 2436.5,-839.48 2442.5,-833.48 2448.5,-833.48 2448.5,-833.48 2579.5,-833.48 2579.5,-833.48 2585.5,-833.48 2591.5,-839.48 2591.5,-845.48 2591.5,-845.48 2591.5,-857.48 2591.5,-857.48 2591.5,-863.48 2585.5,-869.48 2579.5,-869.48"/>
<text text-anchor="middle" x="2514" y="-854.48" font-family="Arial" font-size="10.00" fill="#111827">Management JTAG</text>
<text text-anchor="middle" x="2514" y="-843.48" font-family="Arial" font-size="10.00" fill="#111827">TCK, TMS, TDI, TRST_n, TDO</text>
</g>
<!-- jtag_dtm -->
<g id="node6" class="node">
<title>jtag_dtm</title>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M3008,-687.98C3008,-687.98 2858,-687.98 2858,-687.98 2852,-687.98 2846,-681.98 2846,-675.98 2846,-675.98 2846,-663.98 2846,-663.98 2846,-657.98 2852,-651.98 2858,-651.98 2858,-651.98 3008,-651.98 3008,-651.98 3014,-651.98 3020,-657.98 3020,-663.98 3020,-663.98 3020,-675.98 3020,-675.98 3020,-681.98 3014,-687.98 3008,-687.98"/>
<text text-anchor="middle" x="2933" y="-672.98" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 JTAG DTM</text>
<text text-anchor="middle" x="2933" y="-661.98" font-family="Arial" font-size="10.00" fill="#111827">10 MHz asynchronous TCK domain</text>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M2589,-687.98C2589,-687.98 2439,-687.98 2439,-687.98 2433,-687.98 2427,-681.98 2427,-675.98 2427,-675.98 2427,-663.98 2427,-663.98 2427,-657.98 2433,-651.98 2439,-651.98 2439,-651.98 2589,-651.98 2589,-651.98 2595,-651.98 2601,-657.98 2601,-663.98 2601,-663.98 2601,-675.98 2601,-675.98 2601,-681.98 2595,-687.98 2589,-687.98"/>
<text text-anchor="middle" x="2514" y="-672.98" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 JTAG DTM</text>
<text text-anchor="middle" x="2514" y="-661.98" font-family="Arial" font-size="10.00" fill="#111827">10 MHz asynchronous TCK domain</text>
</g>
<!-- ext_jtag&#45;&gt;jtag_dtm -->
<g id="edge2" class="edge">
<title>ext_jtag&#45;&gt;jtag_dtm</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2933,-833.27C2933,-801.24 2933,-732.39 2933,-695.51"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2935.45,-695.14 2933,-688.14 2930.55,-695.14 2935.45,-695.14"/>
<text text-anchor="middle" x="2953" y="-804.08" font-family="Arial" font-size="8.00" fill="#374151">JTAG pads</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2514,-833.27C2514,-801.24 2514,-732.39 2514,-695.51"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2516.45,-695.14 2514,-688.14 2511.55,-695.14 2516.45,-695.14"/>
<text text-anchor="middle" x="2534" y="-804.08" font-family="Arial" font-size="8.00" fill="#374151">JTAG pads</text>
</g>
<!-- fabric -->
<g id="node11" class="node">
<title>fabric</title>
<path fill="#dcecf8" stroke="#4b5563" stroke-width="1.1" d="M2907.66,-460.31C2907.66,-460.31 2839.98,-488.16 2839.98,-488.16 2834.43,-490.45 2822.88,-492.73 2816.88,-492.73 2816.88,-492.73 2661.12,-492.73 2661.12,-492.73 2655.12,-492.73 2643.57,-490.45 2638.02,-488.16 2638.02,-488.16 2570.34,-460.31 2570.34,-460.31 2564.79,-458.03 2564.79,-453.46 2570.34,-451.18 2570.34,-451.18 2638.02,-423.32 2638.02,-423.32 2643.57,-421.04 2655.12,-418.76 2661.12,-418.76 2661.12,-418.76 2816.88,-418.76 2816.88,-418.76 2822.88,-418.76 2834.43,-421.04 2839.98,-423.32 2839.98,-423.32 2907.66,-451.18 2907.66,-451.18 2913.21,-453.46 2913.21,-458.03 2907.66,-460.31"/>
<text text-anchor="middle" x="2739" y="-464.24" font-family="Arial" font-size="10.00" fill="#111827">RIB fabric</text>
<text text-anchor="middle" x="2739" y="-453.24" font-family="Arial" font-size="10.00" fill="#111827">3&#45;master round&#45;robin arbitration</text>
<text text-anchor="middle" x="2739" y="-442.24" font-family="Arial" font-size="10.00" fill="#111827">INCR1 / INCR4, access policy, fault reporting</text>
<path fill="#dcecf8" stroke="#4b5563" stroke-width="1.1" d="M2743.66,-460.31C2743.66,-460.31 2675.98,-488.16 2675.98,-488.16 2670.43,-490.45 2658.88,-492.73 2652.88,-492.73 2652.88,-492.73 2497.12,-492.73 2497.12,-492.73 2491.12,-492.73 2479.57,-490.45 2474.02,-488.16 2474.02,-488.16 2406.34,-460.31 2406.34,-460.31 2400.79,-458.03 2400.79,-453.46 2406.34,-451.18 2406.34,-451.18 2474.02,-423.32 2474.02,-423.32 2479.57,-421.04 2491.12,-418.76 2497.12,-418.76 2497.12,-418.76 2652.88,-418.76 2652.88,-418.76 2658.88,-418.76 2670.43,-421.04 2675.98,-423.32 2675.98,-423.32 2743.66,-451.18 2743.66,-451.18 2749.21,-453.46 2749.21,-458.03 2743.66,-460.31"/>
<text text-anchor="middle" x="2575" y="-464.24" font-family="Arial" font-size="10.00" fill="#111827">RIB fabric</text>
<text text-anchor="middle" x="2575" y="-453.24" font-family="Arial" font-size="10.00" fill="#111827">3&#45;master round&#45;robin arbitration</text>
<text text-anchor="middle" x="2575" y="-442.24" font-family="Arial" font-size="10.00" fill="#111827">INCR1 / INCR4, access policy, fault reporting</text>
</g>
<!-- rcu&#45;&gt;fabric -->
<g id="edge3" class="edge">
<title>rcu&#45;&gt;fabric</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M362.03,-549.47C368.2,-548.24 372,-547.48 372,-547.48 372,-547.48 2555,-492.48 2555,-492.48 2555,-492.48 2579.75,-487.68 2611.1,-481.59"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2611.92,-483.92 2618.32,-480.18 2610.98,-479.11 2611.92,-483.92"/>
<text text-anchor="middle" x="1629" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">system clock / reset</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M362.03,-549.47C368.2,-548.24 372,-547.48 372,-547.48 372,-547.48 2391,-492.48 2391,-492.48 2391,-492.48 2415.75,-487.68 2447.1,-481.59"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2447.92,-483.92 2454.32,-480.18 2446.98,-479.11 2447.92,-483.92"/>
<text text-anchor="middle" x="1537" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">system clock / reset</text>
</g>
<!-- clint -->
<g id="node17" class="node">
<title>clint</title>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1104.5,-255C1104.5,-255 983.5,-255 983.5,-255 977.5,-255 971.5,-249 971.5,-243 971.5,-243 971.5,-222 971.5,-222 971.5,-216 977.5,-210 983.5,-210 983.5,-210 1104.5,-210 1104.5,-210 1110.5,-210 1116.5,-216 1116.5,-222 1116.5,-222 1116.5,-243 1116.5,-243 1116.5,-249 1110.5,-255 1104.5,-255"/>
<text text-anchor="middle" x="1044" y="-241" font-family="Arial" font-size="10.00" fill="#111827">CLINT</text>
<text text-anchor="middle" x="1044" y="-230" font-family="Arial" font-size="10.00" fill="#111827">standard 64 KiB register map</text>
<text text-anchor="middle" x="1044" y="-219" font-family="Arial" font-size="10.00" fill="#111827">mtime, mtimecmp and MSIP</text>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1369.5,-255C1369.5,-255 1248.5,-255 1248.5,-255 1242.5,-255 1236.5,-249 1236.5,-243 1236.5,-243 1236.5,-222 1236.5,-222 1236.5,-216 1242.5,-210 1248.5,-210 1248.5,-210 1369.5,-210 1369.5,-210 1375.5,-210 1381.5,-216 1381.5,-222 1381.5,-222 1381.5,-243 1381.5,-243 1381.5,-249 1375.5,-255 1369.5,-255"/>
<text text-anchor="middle" x="1309" y="-241" font-family="Arial" font-size="10.00" fill="#111827">CLINT</text>
<text text-anchor="middle" x="1309" y="-230" font-family="Arial" font-size="10.00" fill="#111827">standard 64 KiB register map</text>
<text text-anchor="middle" x="1309" y="-219" font-family="Arial" font-size="10.00" fill="#111827">mtime, mtimecmp and MSIP</text>
</g>
<!-- rcu&#45;&gt;clint -->
<g id="edge8" class="edge">
<title>rcu&#45;&gt;clint</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M312.93,-547.47C364.4,-524.84 438,-492.48 438,-492.48 438,-492.48 837,-278 837,-278 837,-278 958,-255 958,-255 958,-255 960.43,-254.39 964.46,-253.38"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="965.24,-255.72 971.44,-251.64 964.05,-250.96 965.24,-255.72"/>
<text text-anchor="middle" x="650.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">1 MHz tick</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M362.03,-549.47C368.2,-548.24 372,-547.48 372,-547.48 372,-547.48 545,-524.48 545,-524.48 545,-524.48 1149,-278 1149,-278 1149,-278 1189.35,-266.78 1229.53,-255.6"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1230.4,-257.9 1236.49,-253.67 1229.09,-253.18 1230.4,-257.9"/>
<text text-anchor="middle" x="899.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">1 MHz tick</text>
</g>
<!-- wdg -->
<g id="node26" class="node">
<title>wdg</title>
<path fill="#fde68a" stroke="#4b5563" stroke-width="1.1" d="M560,-255C560,-255 406,-255 406,-255 400,-255 394,-249 394,-243 394,-243 394,-222 394,-222 394,-216 400,-210 406,-210 406,-210 560,-210 560,-210 566,-210 572,-216 572,-222 572,-222 572,-243 572,-243 572,-249 566,-255 560,-255"/>
<text text-anchor="middle" x="483" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WDG V2</text>
<text text-anchor="middle" x="483" y="-230" font-family="Arial" font-size="10.00" fill="#111827">independent&#45;clock window watchdog</text>
<text text-anchor="middle" x="483" y="-219" font-family="Arial" font-size="10.00" fill="#111827">early IRQ14, retained cause/count</text>
<path fill="#fde68a" stroke="#4b5563" stroke-width="1.1" d="M801,-255C801,-255 647,-255 647,-255 641,-255 635,-249 635,-243 635,-243 635,-222 635,-222 635,-216 641,-210 647,-210 647,-210 801,-210 801,-210 807,-210 813,-216 813,-222 813,-222 813,-243 813,-243 813,-249 807,-255 801,-255"/>
<text text-anchor="middle" x="724" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WDG V2</text>
<text text-anchor="middle" x="724" y="-230" font-family="Arial" font-size="10.00" fill="#111827">independent&#45;clock window watchdog</text>
<text text-anchor="middle" x="724" y="-219" font-family="Arial" font-size="10.00" fill="#111827">early IRQ14, retained cause/count</text>
</g>
<!-- rcu&#45;&gt;wdg -->
<g id="edge54" class="edge">
<g id="edge55" class="edge">
<title>rcu&#45;&gt;wdg</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M270.76,-547.39C285.86,-499.19 321,-387 321,-387 321,-387 408.6,-304 454.96,-260.07"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="456.74,-261.76 460.13,-255.17 453.37,-258.2 456.74,-261.76"/>
<text text-anchor="middle" x="376" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">independent 18.432 MHz clock</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M362.03,-549.47C368.2,-548.24 372,-547.48 372,-547.48 372,-547.48 536,-524.48 536,-524.48 536,-524.48 658.63,-334.67 705.81,-261.65"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="708.13,-262.58 709.87,-255.37 704.01,-259.92 708.13,-262.58"/>
<text text-anchor="middle" x="678" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">independent 18.432 MHz clock</text>
</g>
<!-- rtc -->
<g id="node28" class="node">
<title>rtc</title>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M801,-255C801,-255 611,-255 611,-255 605,-255 599,-249 599,-243 599,-243 599,-222 599,-222 599,-216 605,-210 611,-210 611,-210 801,-210 801,-210 807,-210 813,-216 813,-222 813,-222 813,-243 813,-243 813,-249 807,-255 801,-255"/>
<text text-anchor="middle" x="706" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RTC V2</text>
<text text-anchor="middle" x="706" y="-230" font-family="Arial" font-size="10.00" fill="#111827">64&#45;bit Epoch + 1/256&#45;second time</text>
<text text-anchor="middle" x="706" y="-219" font-family="Arial" font-size="10.00" fill="#111827">dual alarm, periodic wake, calibration, IRQ13</text>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M596,-255C596,-255 406,-255 406,-255 400,-255 394,-249 394,-243 394,-243 394,-222 394,-222 394,-216 400,-210 406,-210 406,-210 596,-210 596,-210 602,-210 608,-216 608,-222 608,-222 608,-243 608,-243 608,-249 602,-255 596,-255"/>
<text text-anchor="middle" x="501" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RTC V2</text>
<text text-anchor="middle" x="501" y="-230" font-family="Arial" font-size="10.00" fill="#111827">64&#45;bit Epoch + 1/256&#45;second time</text>
<text text-anchor="middle" x="501" y="-219" font-family="Arial" font-size="10.00" fill="#111827">dual alarm, periodic wake, calibration, IRQ13</text>
</g>
<!-- rcu&#45;&gt;rtc -->
<g id="edge51" class="edge">
<g id="edge52" class="edge">
<title>rcu&#45;&gt;rtc</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M296.9,-547.47C331.51,-524.84 381,-492.48 381,-492.48 381,-492.48 516,-396 516,-396 516,-396 621.7,-305.6 675.42,-259.65"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="677.04,-261.49 680.77,-255.08 673.86,-257.77 677.04,-261.49"/>
<text text-anchor="middle" x="567.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">18.432 MHz audio clock</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M279.37,-547.23C320.9,-488.43 435.37,-326.4 481.43,-261.2"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="483.63,-262.34 485.67,-255.2 479.63,-259.51 483.63,-262.34"/>
<text text-anchor="middle" x="432.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">18.432 MHz audio clock</text>
</g>
<!-- mgmt_core -->
<g id="node5" class="node">
<title>mgmt_core</title>
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M3213,-692.48C3213,-692.48 3059,-692.48 3059,-692.48 3053,-692.48 3047,-686.48 3047,-680.48 3047,-680.48 3047,-659.48 3047,-659.48 3047,-653.48 3053,-647.48 3059,-647.48 3059,-647.48 3213,-647.48 3213,-647.48 3219,-647.48 3225,-653.48 3225,-659.48 3225,-659.48 3225,-680.48 3225,-680.48 3225,-686.48 3219,-692.48 3213,-692.48"/>
<text text-anchor="middle" x="3136" y="-678.48" font-family="Arial" font-size="10.00" fill="#111827">Management core</text>
<text text-anchor="middle" x="3136" y="-667.48" font-family="Arial" font-size="10.00" fill="#111827">Fixed Hazard3, branch predictor</text>
<text text-anchor="middle" x="3136" y="-656.48" font-family="Arial" font-size="10.00" fill="#111827">JTAG Debug Module always present</text>
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M2794,-692.48C2794,-692.48 2640,-692.48 2640,-692.48 2634,-692.48 2628,-686.48 2628,-680.48 2628,-680.48 2628,-659.48 2628,-659.48 2628,-653.48 2634,-647.48 2640,-647.48 2640,-647.48 2794,-647.48 2794,-647.48 2800,-647.48 2806,-653.48 2806,-659.48 2806,-659.48 2806,-680.48 2806,-680.48 2806,-686.48 2800,-692.48 2794,-692.48"/>
<text text-anchor="middle" x="2717" y="-678.48" font-family="Arial" font-size="10.00" fill="#111827">Management core</text>
<text text-anchor="middle" x="2717" y="-667.48" font-family="Arial" font-size="10.00" fill="#111827">Fixed Hazard3, branch predictor</text>
<text text-anchor="middle" x="2717" y="-656.48" font-family="Arial" font-size="10.00" fill="#111827">JTAG Debug Module always present</text>
</g>
<!-- mgmt_adapter -->
<g id="node8" class="node">
<title>mgmt_adapter</title>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M3156.5,-587.98C3156.5,-587.98 3115.5,-587.98 3115.5,-587.98 3109.5,-587.98 3103.5,-581.98 3103.5,-575.98 3103.5,-575.98 3103.5,-563.98 3103.5,-563.98 3103.5,-557.98 3109.5,-551.98 3115.5,-551.98 3115.5,-551.98 3156.5,-551.98 3156.5,-551.98 3162.5,-551.98 3168.5,-557.98 3168.5,-563.98 3168.5,-563.98 3168.5,-575.98 3168.5,-575.98 3168.5,-581.98 3162.5,-587.98 3156.5,-587.98"/>
<text text-anchor="middle" x="3136" y="-567.48" font-family="Arial" font-size="10.00" fill="#111827">RIBP2RIB</text>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M2737.5,-587.98C2737.5,-587.98 2696.5,-587.98 2696.5,-587.98 2690.5,-587.98 2684.5,-581.98 2684.5,-575.98 2684.5,-575.98 2684.5,-563.98 2684.5,-563.98 2684.5,-557.98 2690.5,-551.98 2696.5,-551.98 2696.5,-551.98 2737.5,-551.98 2737.5,-551.98 2743.5,-551.98 2749.5,-557.98 2749.5,-563.98 2749.5,-563.98 2749.5,-575.98 2749.5,-575.98 2749.5,-581.98 2743.5,-587.98 2737.5,-587.98"/>
<text text-anchor="middle" x="2717" y="-567.48" font-family="Arial" font-size="10.00" fill="#111827">RIBP2RIB</text>
</g>
<!-- mgmt_core&#45;&gt;mgmt_adapter -->
<g id="edge9" class="edge">
<title>mgmt_core&#45;&gt;mgmt_adapter</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3136,-647.24C3136,-631.92 3136,-611.4 3136,-595.51"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3138.45,-595.12 3136,-588.12 3133.55,-595.12 3138.45,-595.12"/>
<text text-anchor="middle" x="3145.5" y="-618.08" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2717,-647.24C2717,-631.92 2717,-611.4 2717,-595.51"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2719.45,-595.12 2717,-588.12 2714.55,-595.12 2719.45,-595.12"/>
<text text-anchor="middle" x="2726.5" y="-618.08" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
</g>
<!-- debug_module -->
<g id="node7" class="node">
<title>debug_module</title>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M3503.5,-692.48C3503.5,-692.48 3382.5,-692.48 3382.5,-692.48 3376.5,-692.48 3370.5,-686.48 3370.5,-680.48 3370.5,-680.48 3370.5,-659.48 3370.5,-659.48 3370.5,-653.48 3376.5,-647.48 3382.5,-647.48 3382.5,-647.48 3503.5,-647.48 3503.5,-647.48 3509.5,-647.48 3515.5,-653.48 3515.5,-659.48 3515.5,-659.48 3515.5,-680.48 3515.5,-680.48 3515.5,-686.48 3509.5,-692.48 3503.5,-692.48"/>
<text text-anchor="middle" x="3443" y="-678.48" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 Debug Module</text>
<text text-anchor="middle" x="3443" y="-667.48" font-family="Arial" font-size="10.00" fill="#111827">abstract commands, no SBA</text>
<text text-anchor="middle" x="3443" y="-656.48" font-family="Arial" font-size="10.00" fill="#111827">management&#45;hart&#45;only reset</text>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M3084.5,-692.48C3084.5,-692.48 2963.5,-692.48 2963.5,-692.48 2957.5,-692.48 2951.5,-686.48 2951.5,-680.48 2951.5,-680.48 2951.5,-659.48 2951.5,-659.48 2951.5,-653.48 2957.5,-647.48 2963.5,-647.48 2963.5,-647.48 3084.5,-647.48 3084.5,-647.48 3090.5,-647.48 3096.5,-653.48 3096.5,-659.48 3096.5,-659.48 3096.5,-680.48 3096.5,-680.48 3096.5,-686.48 3090.5,-692.48 3084.5,-692.48"/>
<text text-anchor="middle" x="3024" y="-678.48" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 Debug Module</text>
<text text-anchor="middle" x="3024" y="-667.48" font-family="Arial" font-size="10.00" fill="#111827">abstract commands, no SBA</text>
<text text-anchor="middle" x="3024" y="-656.48" font-family="Arial" font-size="10.00" fill="#111827">management&#45;hart&#45;only reset</text>
</g>
<!-- jtag_dtm&#45;&gt;debug_module -->
<g id="edge4" class="edge">
<title>jtag_dtm&#45;&gt;debug_module</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2951.06,-688.13C2980.11,-717.33 3034,-771.48 3034,-771.48 3034,-771.48 3239,-771.48 3239,-771.48 3239,-771.48 3330.81,-725.8 3391.25,-695.73"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3392.55,-697.82 3397.73,-692.51 3390.37,-693.44 3392.55,-697.82"/>
<text text-anchor="middle" x="3195" y="-804.08" font-family="Arial" font-size="8.00" fill="#374151">DMI, asynchronous CDC</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2532.06,-688.13C2561.11,-717.33 2615,-771.48 2615,-771.48 2615,-771.48 2820,-771.48 2820,-771.48 2820,-771.48 2911.81,-725.8 2972.25,-695.73"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2973.55,-697.82 2978.73,-692.51 2971.37,-693.44 2973.55,-697.82"/>
<text text-anchor="middle" x="2776" y="-804.08" font-family="Arial" font-size="8.00" fill="#374151">DMI, asynchronous CDC</text>
</g>
<!-- debug_module&#45;&gt;mgmt_core -->
<g id="edge5" class="edge">
<title>debug_module&#45;&gt;mgmt_core</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3370.11,-669.98C3328.89,-669.98 3276.84,-669.98 3232.29,-669.98"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3232.21,-667.53 3225.21,-669.98 3232.21,-672.43 3232.21,-667.53"/>
<text text-anchor="middle" x="3297.75" y="-675.58" font-family="Arial" font-size="8.00" fill="#374151">halt, resume, abstract commands</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2951.11,-669.98C2909.89,-669.98 2857.84,-669.98 2813.29,-669.98"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2813.21,-667.53 2806.21,-669.98 2813.21,-672.43 2813.21,-667.53"/>
<text text-anchor="middle" x="2878.75" y="-675.58" font-family="Arial" font-size="8.00" fill="#374151">halt, resume, abstract commands</text>
</g>
<!-- debug_module&#45;&gt;mgmt_adapter -->
<g id="edge6" class="edge">
<title>debug_module&#45;&gt;mgmt_adapter</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M3370.23,-647.57C3293.31,-624.94 3183,-592.48 3183,-592.48 3183,-592.48 3179.87,-591.05 3175.22,-588.93"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3176.03,-586.6 3168.64,-585.92 3173.99,-591.06 3176.03,-586.6"/>
<text text-anchor="middle" x="3327" y="-618.08" font-family="Arial" font-size="8.00" fill="#374151">reset after bridge idle</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M2956.63,-647.48C2895.43,-627.94 2807.24,-599.79 2756.67,-583.65"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2757.21,-581.25 2749.79,-581.45 2755.72,-585.92 2757.21,-581.25"/>
<text text-anchor="middle" x="2917" y="-618.08" font-family="Arial" font-size="8.00" fill="#374151">reset after bridge idle</text>
</g>
<!-- timers -->
<g id="node22" class="node">
<title>timers</title>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3933.5,-255C3933.5,-255 3752.5,-255 3752.5,-255 3746.5,-255 3740.5,-249 3740.5,-243 3740.5,-243 3740.5,-222 3740.5,-222 3740.5,-216 3746.5,-210 3752.5,-210 3752.5,-210 3933.5,-210 3933.5,-210 3939.5,-210 3945.5,-216 3945.5,-222 3945.5,-222 3945.5,-243 3945.5,-243 3945.5,-249 3939.5,-255 3933.5,-255"/>
<text text-anchor="middle" x="3843" y="-241" font-family="Arial" font-size="10.00" fill="#111827">General timers 0/1</text>
<text text-anchor="middle" x="3843" y="-230" font-family="Arial" font-size="10.00" fill="#111827">32&#45;bit counter, 16&#45;bit prescaler</text>
<text text-anchor="middle" x="3843" y="-219" font-family="Arial" font-size="10.00" fill="#111827">periodic / one&#45;shot, compare, debug freeze</text>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3235.5,-255C3235.5,-255 3054.5,-255 3054.5,-255 3048.5,-255 3042.5,-249 3042.5,-243 3042.5,-243 3042.5,-222 3042.5,-222 3042.5,-216 3048.5,-210 3054.5,-210 3054.5,-210 3235.5,-210 3235.5,-210 3241.5,-210 3247.5,-216 3247.5,-222 3247.5,-222 3247.5,-243 3247.5,-243 3247.5,-249 3241.5,-255 3235.5,-255"/>
<text text-anchor="middle" x="3145" y="-241" font-family="Arial" font-size="10.00" fill="#111827">General timers 0/1</text>
<text text-anchor="middle" x="3145" y="-230" font-family="Arial" font-size="10.00" fill="#111827">32&#45;bit counter, 16&#45;bit prescaler</text>
<text text-anchor="middle" x="3145" y="-219" font-family="Arial" font-size="10.00" fill="#111827">periodic / one&#45;shot, compare, debug freeze</text>
</g>
<!-- debug_module&#45;&gt;timers -->
<g id="edge7" class="edge">
<title>debug_module&#45;&gt;timers</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M3461.64,-647.24C3486.39,-618.36 3527,-570.98 3527,-570.98 3527,-570.98 3527,-570.98 3527,-345 3527,-345 3681.95,-290.33 3774.84,-257.55"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3775.91,-259.77 3781.7,-255.13 3774.28,-255.15 3775.91,-259.77"/>
<text text-anchor="middle" x="3538" y="-453.84" font-family="Arial" font-size="8.00" fill="#374151">halted</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M3050.55,-647.48C3086.17,-618.63 3145,-570.98 3145,-570.98 3145,-570.98 3145,-570.98 3145,-345 3145,-345 3145,-295.48 3145,-262.45"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3147.45,-262.26 3145,-255.26 3142.55,-262.26 3147.45,-262.26"/>
<text text-anchor="middle" x="3156" y="-453.84" font-family="Arial" font-size="8.00" fill="#374151">halted</text>
</g>
<!-- mgmt_adapter&#45;&gt;fabric -->
<g id="edge10" class="edge">
<title>mgmt_adapter&#45;&gt;fabric</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3103.45,-551.91C3073.6,-536.25 3034,-515.48 3034,-515.48 3034,-515.48 2945.74,-497.91 2865.78,-481.99"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2865.91,-479.51 2858.56,-480.55 2864.95,-484.32 2865.91,-479.51"/>
<text text-anchor="middle" x="3058" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2700.58,-551.76C2685.67,-536.12 2666,-515.48 2666,-515.48 2666,-515.48 2652.91,-507.04 2636.67,-496.55"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2637.77,-494.34 2630.56,-492.61 2635.11,-498.46 2637.77,-494.34"/>
<text text-anchor="middle" x="2681" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
</g>
<!-- user_core -->
<g id="node9" class="node">
<title>user_core</title>
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M3284,-592.48C3284,-592.48 3208,-592.48 3208,-592.48 3202,-592.48 3196,-586.48 3196,-580.48 3196,-580.48 3196,-559.48 3196,-559.48 3196,-553.48 3202,-547.48 3208,-547.48 3208,-547.48 3284,-547.48 3284,-547.48 3290,-547.48 3296,-553.48 3296,-559.48 3296,-559.48 3296,-580.48 3296,-580.48 3296,-586.48 3290,-592.48 3284,-592.48"/>
<text text-anchor="middle" x="3246" y="-578.48" font-family="Arial" font-size="10.00" fill="#111827">Selected user core</text>
<text text-anchor="middle" x="3246" y="-567.48" font-family="Arial" font-size="10.00" fill="#111827">C0&#45;C5, one active</text>
<text text-anchor="middle" x="3246" y="-556.48" font-family="Arial" font-size="10.00" fill="#111827">PicoRV32 at C5</text>
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M2905,-592.48C2905,-592.48 2829,-592.48 2829,-592.48 2823,-592.48 2817,-586.48 2817,-580.48 2817,-580.48 2817,-559.48 2817,-559.48 2817,-553.48 2823,-547.48 2829,-547.48 2829,-547.48 2905,-547.48 2905,-547.48 2911,-547.48 2917,-553.48 2917,-559.48 2917,-559.48 2917,-580.48 2917,-580.48 2917,-586.48 2911,-592.48 2905,-592.48"/>
<text text-anchor="middle" x="2867" y="-578.48" font-family="Arial" font-size="10.00" fill="#111827">Selected user core</text>
<text text-anchor="middle" x="2867" y="-567.48" font-family="Arial" font-size="10.00" fill="#111827">C0&#45;C5, one active</text>
<text text-anchor="middle" x="2867" y="-556.48" font-family="Arial" font-size="10.00" fill="#111827">PicoRV32 at C5</text>
</g>
<!-- user_core&#45;&gt;fabric -->
<g id="edge11" class="edge">
<title>user_core&#45;&gt;fabric</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3195.89,-552.15C3187.79,-549.43 3182,-547.48 3182,-547.48 3182,-547.48 3071,-515.48 3071,-515.48 3071,-515.48 2962.88,-496.35 2870.04,-479.93"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2870.42,-477.51 2863.1,-478.7 2869.56,-482.33 2870.42,-477.51"/>
<text text-anchor="middle" x="3107" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2854.39,-547.22C2845.81,-532.41 2836,-515.48 2836,-515.48 2836,-515.48 2764.85,-499.47 2696.85,-484.17"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2697.23,-481.74 2689.86,-482.59 2696.15,-486.52 2697.23,-481.74"/>
<text text-anchor="middle" x="2848" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
</g>
<!-- dma -->
<g id="node10" class="node">
<title>dma</title>
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M3064,-587.98C3064,-587.98 2946,-587.98 2946,-587.98 2940,-587.98 2934,-581.98 2934,-575.98 2934,-575.98 2934,-563.98 2934,-563.98 2934,-557.98 2940,-551.98 2946,-551.98 2946,-551.98 3064,-551.98 3064,-551.98 3070,-551.98 3076,-557.98 3076,-563.98 3076,-563.98 3076,-575.98 3076,-575.98 3076,-581.98 3070,-587.98 3064,-587.98"/>
<text text-anchor="middle" x="3005" y="-572.98" font-family="Arial" font-size="10.00" fill="#111827">DMA</text>
<text text-anchor="middle" x="3005" y="-561.98" font-family="Arial" font-size="10.00" fill="#111827">RIB master and RIBP target</text>
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M3543,-587.98C3543,-587.98 3425,-587.98 3425,-587.98 3419,-587.98 3413,-581.98 3413,-575.98 3413,-575.98 3413,-563.98 3413,-563.98 3413,-557.98 3419,-551.98 3425,-551.98 3425,-551.98 3543,-551.98 3543,-551.98 3549,-551.98 3555,-557.98 3555,-563.98 3555,-563.98 3555,-575.98 3555,-575.98 3555,-581.98 3549,-587.98 3543,-587.98"/>
<text text-anchor="middle" x="3484" y="-572.98" font-family="Arial" font-size="10.00" fill="#111827">DMA</text>
<text text-anchor="middle" x="3484" y="-561.98" font-family="Arial" font-size="10.00" fill="#111827">RIB master and RIBP target</text>
</g>
<!-- dma&#45;&gt;fabric -->
<g id="edge12" class="edge">
<title>dma&#45;&gt;fabric</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3008.45,-551.91C3010.99,-539.36 3014,-524.48 3014,-524.48 3014,-524.48 3014,-515.48 3014,-515.48 3014,-515.48 2935.99,-498.82 2863.06,-483.24"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2863.38,-480.81 2856.02,-481.74 2862.36,-485.6 2863.38,-480.81"/>
<text text-anchor="middle" x="3021" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3412.86,-561.09C3236.82,-541.54 2795,-492.48 2795,-492.48 2795,-492.48 2755.18,-486.02 2709.43,-478.58"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2709.64,-476.13 2702.34,-477.43 2708.85,-480.97 2709.64,-476.13"/>
<text text-anchor="middle" x="3084" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
</g>
<!-- uart0 -->
<g id="node19" class="node">
<title>uart0</title>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M2965,-255C2965,-255 2805,-255 2805,-255 2799,-255 2793,-249 2793,-243 2793,-243 2793,-222 2793,-222 2793,-216 2799,-210 2805,-210 2805,-210 2965,-210 2965,-210 2971,-210 2977,-216 2977,-222 2977,-222 2977,-243 2977,-243 2977,-249 2971,-255 2965,-255"/>
<text text-anchor="middle" x="2885" y="-241" font-family="Arial" font-size="10.00" fill="#111827">UART0 V2</text>
<text text-anchor="middle" x="2885" y="-230" font-family="Arial" font-size="10.00" fill="#111827">64&#45;byte TX/RX FIFOs, fractional baud</text>
<text text-anchor="middle" x="2885" y="-219" font-family="Arial" font-size="10.00" fill="#111827">framing/errors, IRQ2, DMA&#45;paced</text>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3920,-255C3920,-255 3708,-255 3708,-255 3702,-255 3696,-249 3696,-243 3696,-243 3696,-222 3696,-222 3696,-216 3702,-210 3708,-210 3708,-210 3920,-210 3920,-210 3926,-210 3932,-216 3932,-222 3932,-222 3932,-243 3932,-243 3932,-249 3926,-255 3920,-255"/>
<text text-anchor="middle" x="3814" y="-241" font-family="Arial" font-size="10.00" fill="#111827">UART0 V3</text>
<text text-anchor="middle" x="3814" y="-230" font-family="Arial" font-size="10.00" fill="#111827">64&#45;byte TX/RX FIFOs, fractional baud</text>
<text text-anchor="middle" x="3814" y="-219" font-family="Arial" font-size="10.00" fill="#111827">auto RTS/CTS, framing/errors, IRQ2, DMA&#45;paced</text>
</g>
<!-- dma&#45;&gt;uart0 -->
<g id="edge41" class="edge">
<title>dma&#45;&gt;uart0</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M3005.77,-551.91C3006.33,-539.36 3007,-524.48 3007,-524.48 3007,-524.48 3007,-515.48 3007,-515.48 3007,-515.48 2546,-492.48 2546,-492.48 2546,-492.48 2546,-419 2546,-419 2546,-419 2585,-396 2585,-396 2585,-396 2621,-278 2621,-278 2621,-278 2779,-255 2779,-255 2779,-255 2781.57,-254.48 2785.91,-253.6"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2786.48,-255.98 2792.86,-252.19 2785.51,-251.18 2786.48,-255.98"/>
<text text-anchor="middle" x="2608.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">TX/RX data</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M3500.82,-551.89C3554.47,-497.34 3721.88,-327.15 3787.37,-260.58"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3789.48,-261.92 3792.64,-255.21 3785.99,-258.49 3789.48,-261.92"/>
<text text-anchor="middle" x="3681.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">TX/RX data</text>
</g>
<!-- i2c_controllers -->
<g id="node20" class="node">
<title>i2c_controllers</title>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M2753.5,-255C2753.5,-255 2568.5,-255 2568.5,-255 2562.5,-255 2556.5,-249 2556.5,-243 2556.5,-243 2556.5,-222 2556.5,-222 2556.5,-216 2562.5,-210 2568.5,-210 2568.5,-210 2753.5,-210 2753.5,-210 2759.5,-210 2765.5,-216 2765.5,-222 2765.5,-222 2765.5,-243 2765.5,-243 2765.5,-249 2759.5,-255 2753.5,-255"/>
<text text-anchor="middle" x="2661" y="-241" font-family="Arial" font-size="10.00" fill="#111827">I2C0 / I2C1 V2</text>
<text text-anchor="middle" x="2661" y="-230" font-family="Arial" font-size="10.00" fill="#111827">16&#45;entry command/RX FIFOs, Sm/Fm/Fm+</text>
<text text-anchor="middle" x="2661" y="-219" font-family="Arial" font-size="10.00" fill="#111827">7/10&#45;bit, IRQ7/19, DMA&#45;paced</text>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3471.5,-255C3471.5,-255 3286.5,-255 3286.5,-255 3280.5,-255 3274.5,-249 3274.5,-243 3274.5,-243 3274.5,-222 3274.5,-222 3274.5,-216 3280.5,-210 3286.5,-210 3286.5,-210 3471.5,-210 3471.5,-210 3477.5,-210 3483.5,-216 3483.5,-222 3483.5,-222 3483.5,-243 3483.5,-243 3483.5,-249 3477.5,-255 3471.5,-255"/>
<text text-anchor="middle" x="3379" y="-241" font-family="Arial" font-size="10.00" fill="#111827">I2C0 / I2C1 V2</text>
<text text-anchor="middle" x="3379" y="-230" font-family="Arial" font-size="10.00" fill="#111827">16&#45;entry command/RX FIFOs, Sm/Fm/Fm+</text>
<text text-anchor="middle" x="3379" y="-219" font-family="Arial" font-size="10.00" fill="#111827">7/10&#45;bit, IRQ7/19, DMA&#45;paced</text>
</g>
<!-- dma&#45;&gt;i2c_controllers -->
<g id="edge44" class="edge">
<g id="edge45" class="edge">
<title>dma&#45;&gt;i2c_controllers</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M3003.39,-551.76C3001.93,-536.12 3000,-515.48 3000,-515.48 3000,-515.48 2540,-492.48 2540,-492.48 2540,-492.48 2497,-396 2497,-396 2497,-396 2497,-387 2497,-387 2497,-387 2507,-278 2507,-278 2507,-278 2542.47,-267.75 2579.36,-257.09"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2580.21,-259.4 2586.26,-255.1 2578.85,-254.69 2580.21,-259.4"/>
<text text-anchor="middle" x="2538" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">DATA_CMD / RXDATA</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M3478.65,-551.89C3461.71,-497.78 3409.16,-329.87 3387.98,-262.2"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3390.22,-261.16 3385.8,-255.21 3385.55,-262.63 3390.22,-261.16"/>
<text text-anchor="middle" x="3470" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">DATA_CMD / RXDATA</text>
</g>
<!-- ws2812 -->
<g id="node23" class="node">
<title>ws2812</title>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M2517,-255C2517,-255 2383,-255 2383,-255 2377,-255 2371,-249 2371,-243 2371,-243 2371,-222 2371,-222 2371,-216 2377,-210 2383,-210 2383,-210 2517,-210 2517,-210 2523,-210 2529,-216 2529,-222 2529,-222 2529,-243 2529,-243 2529,-249 2523,-255 2517,-255"/>
<text text-anchor="middle" x="2450" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WS2812 TX</text>
<text text-anchor="middle" x="2450" y="-230" font-family="Arial" font-size="10.00" fill="#111827">24&#45;bit MSB&#45;first serializer</text>
<text text-anchor="middle" x="2450" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16&#45;word FIFO, IRQ17, DMA&#45;fed</text>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3657,-255C3657,-255 3523,-255 3523,-255 3517,-255 3511,-249 3511,-243 3511,-243 3511,-222 3511,-222 3511,-216 3517,-210 3523,-210 3523,-210 3657,-210 3657,-210 3663,-210 3669,-216 3669,-222 3669,-222 3669,-243 3669,-243 3669,-249 3663,-255 3657,-255"/>
<text text-anchor="middle" x="3590" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WS2812 TX</text>
<text text-anchor="middle" x="3590" y="-230" font-family="Arial" font-size="10.00" fill="#111827">24&#45;bit MSB&#45;first serializer</text>
<text text-anchor="middle" x="3590" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16&#45;word FIFO, IRQ17, DMA&#45;fed</text>
</g>
<!-- dma&#45;&gt;ws2812 -->
<g id="edge39" class="edge">
<title>dma&#45;&gt;ws2812</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M2945.54,-551.94C2936.44,-549.33 2930,-547.48 2930,-547.48 2930,-547.48 2501,-492.48 2501,-492.48 2501,-492.48 2364,-396 2364,-396 2364,-396 2364,-387 2364,-387 2364,-387 2409.56,-305.68 2434.36,-261.41"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2436.58,-262.47 2437.86,-255.17 2432.3,-260.08 2436.58,-262.47"/>
<text text-anchor="middle" x="2391.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">TXDATA writes</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M3489.4,-551.89C3506.5,-497.78 3559.55,-329.87 3580.93,-262.2"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3583.37,-262.63 3583.14,-255.21 3578.69,-261.15 3583.37,-262.63"/>
<text text-anchor="middle" x="3567.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">TXDATA writes</text>
</g>
<!-- fault -->
<g id="node12" class="node">
<title>fault</title>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M3242.5,-473.74C3242.5,-473.74 3133.5,-473.74 3133.5,-473.74 3127.5,-473.74 3121.5,-467.74 3121.5,-461.74 3121.5,-461.74 3121.5,-449.74 3121.5,-449.74 3121.5,-443.74 3127.5,-437.74 3133.5,-437.74 3133.5,-437.74 3242.5,-437.74 3242.5,-437.74 3248.5,-437.74 3254.5,-443.74 3254.5,-449.74 3254.5,-449.74 3254.5,-461.74 3254.5,-461.74 3254.5,-467.74 3248.5,-473.74 3242.5,-473.74"/>
<text text-anchor="middle" x="3188" y="-458.74" font-family="Arial" font-size="10.00" fill="#111827">Error slave</text>
<text text-anchor="middle" x="3188" y="-447.74" font-family="Arial" font-size="10.00" fill="#111827">access and protocol faults</text>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M3078.5,-473.74C3078.5,-473.74 2969.5,-473.74 2969.5,-473.74 2963.5,-473.74 2957.5,-467.74 2957.5,-461.74 2957.5,-461.74 2957.5,-449.74 2957.5,-449.74 2957.5,-443.74 2963.5,-437.74 2969.5,-437.74 2969.5,-437.74 3078.5,-437.74 3078.5,-437.74 3084.5,-437.74 3090.5,-443.74 3090.5,-449.74 3090.5,-449.74 3090.5,-461.74 3090.5,-461.74 3090.5,-467.74 3084.5,-473.74 3078.5,-473.74"/>
<text text-anchor="middle" x="3024" y="-458.74" font-family="Arial" font-size="10.00" fill="#111827">Error slave</text>
<text text-anchor="middle" x="3024" y="-447.74" font-family="Arial" font-size="10.00" fill="#111827">access and protocol faults</text>
</g>
<!-- fabric&#45;&gt;fault -->
<g id="edge13" class="edge">
<title>fabric&#45;&gt;fault</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2852.37,-487.99C2900.41,-501.66 2945.5,-514.48 2945.5,-514.48 2945.5,-514.48 2998.5,-514.48 2998.5,-514.48 2998.5,-514.48 3108,-492.48 3108,-492.48 3108,-492.48 3124.11,-485.08 3141.88,-476.93"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2852.98,-485.62 2845.58,-486.06 2851.64,-490.33 2852.98,-485.62"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3143.13,-479.05 3148.47,-473.9 3141.08,-474.59 3143.13,-479.05"/>
<text text-anchor="middle" x="2972" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">invalid / denied</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2688.37,-487.99C2736.41,-501.66 2781.5,-514.48 2781.5,-514.48 2781.5,-514.48 2834.5,-514.48 2834.5,-514.48 2834.5,-514.48 2944,-492.48 2944,-492.48 2944,-492.48 2960.11,-485.08 2977.88,-476.93"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2688.98,-485.62 2681.58,-486.06 2687.64,-490.33 2688.98,-485.62"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2979.13,-479.05 2984.47,-473.9 2977.08,-474.59 2979.13,-479.05"/>
<text text-anchor="middle" x="2808" y="-518.08" font-family="Arial" font-size="8.00" fill="#374151">invalid / denied</text>
</g>
<!-- sram -->
<g id="node13" class="node">
<title>sram</title>
<path fill="#fff3c9" stroke="#4b5563" stroke-width="1.1" d="M3082,-473.74C3082,-473.74 2984,-473.74 2984,-473.74 2978,-473.74 2972,-467.74 2972,-461.74 2972,-461.74 2972,-449.74 2972,-449.74 2972,-443.74 2978,-437.74 2984,-437.74 2984,-437.74 3082,-437.74 3082,-437.74 3088,-437.74 3094,-443.74 3094,-449.74 3094,-449.74 3094,-461.74 3094,-461.74 3094,-467.74 3088,-473.74 3082,-473.74"/>
<text text-anchor="middle" x="3033" y="-458.74" font-family="Arial" font-size="10.00" fill="#111827">On&#45;chip SRAM</text>
<text text-anchor="middle" x="3033" y="-447.74" font-family="Arial" font-size="10.00" fill="#111827">optional RIB2RAM path</text>
<path fill="#fff3c9" stroke="#4b5563" stroke-width="1.1" d="M2918,-473.74C2918,-473.74 2820,-473.74 2820,-473.74 2814,-473.74 2808,-467.74 2808,-461.74 2808,-461.74 2808,-449.74 2808,-449.74 2808,-443.74 2814,-437.74 2820,-437.74 2820,-437.74 2918,-437.74 2918,-437.74 2924,-437.74 2930,-443.74 2930,-449.74 2930,-449.74 2930,-461.74 2930,-461.74 2930,-467.74 2924,-473.74 2918,-473.74"/>
<text text-anchor="middle" x="2869" y="-458.74" font-family="Arial" font-size="10.00" fill="#111827">On&#45;chip SRAM</text>
<text text-anchor="middle" x="2869" y="-447.74" font-family="Arial" font-size="10.00" fill="#111827">optional RIB2RAM path</text>
</g>
<!-- fabric&#45;&gt;sram -->
<g id="edge14" class="edge">
<title>fabric&#45;&gt;sram</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2918.91,-455.74C2934.95,-455.74 2950.44,-455.74 2964.56,-455.74"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2964.81,-458.19 2971.81,-455.74 2964.81,-453.29 2964.81,-458.19"/>
<text text-anchor="middle" x="2945.31" y="-461.34" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2754.91,-455.74C2770.95,-455.74 2786.44,-455.74 2800.56,-455.74"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2800.81,-458.19 2807.81,-455.74 2800.81,-453.29 2800.81,-458.19"/>
<text text-anchor="middle" x="2781.31" y="-461.34" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
</g>
<!-- ribp_adapter -->
<g id="node14" class="node">
<title>ribp_adapter</title>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M3029.5,-364C3029.5,-364 2988.5,-364 2988.5,-364 2982.5,-364 2976.5,-358 2976.5,-352 2976.5,-352 2976.5,-340 2976.5,-340 2976.5,-334 2982.5,-328 2988.5,-328 2988.5,-328 3029.5,-328 3029.5,-328 3035.5,-328 3041.5,-334 3041.5,-340 3041.5,-340 3041.5,-352 3041.5,-352 3041.5,-358 3035.5,-364 3029.5,-364"/>
<text text-anchor="middle" x="3009" y="-343.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M2921.5,-364C2921.5,-364 2880.5,-364 2880.5,-364 2874.5,-364 2868.5,-358 2868.5,-352 2868.5,-352 2868.5,-340 2868.5,-340 2868.5,-334 2874.5,-328 2880.5,-328 2880.5,-328 2921.5,-328 2921.5,-328 2927.5,-328 2933.5,-334 2933.5,-340 2933.5,-340 2933.5,-352 2933.5,-352 2933.5,-358 2927.5,-364 2921.5,-364"/>
<text text-anchor="middle" x="2901" y="-343.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
</g>
<!-- fabric&#45;&gt;ribp_adapter -->
<g id="edge15" class="edge">
<title>fabric&#45;&gt;ribp_adapter</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2828.91,-418.87C2876.71,-399.79 2933.03,-377.31 2969.8,-362.64"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2970.84,-364.87 2976.43,-360 2969.02,-360.32 2970.84,-364.87"/>
<text text-anchor="middle" x="2913" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2673.7,-422.12C2736.8,-401.27 2815.21,-375.35 2861.5,-360.05"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2862.5,-362.31 2868.37,-357.78 2860.96,-357.65 2862.5,-362.31"/>
<text text-anchor="middle" x="2783" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
</g>
<!-- apb_adapter -->
<g id="node15" class="node">
<title>apb_adapter</title>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M1504,-364C1504,-364 1434,-364 1434,-364 1428,-364 1422,-358 1422,-352 1422,-352 1422,-340 1422,-340 1422,-334 1428,-328 1434,-328 1434,-328 1504,-328 1504,-328 1510,-328 1516,-334 1516,-340 1516,-340 1516,-352 1516,-352 1516,-358 1510,-364 1504,-364"/>
<text text-anchor="middle" x="1469" y="-349" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
<text text-anchor="middle" x="1469" y="-338" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M1548,-364C1548,-364 1478,-364 1478,-364 1472,-364 1466,-358 1466,-352 1466,-352 1466,-340 1466,-340 1466,-334 1472,-328 1478,-328 1478,-328 1548,-328 1548,-328 1554,-328 1560,-334 1560,-340 1560,-340 1560,-352 1560,-352 1560,-358 1554,-364 1548,-364"/>
<text text-anchor="middle" x="1513" y="-349" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
<text text-anchor="middle" x="1513" y="-338" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
</g>
<!-- fabric&#45;&gt;apb_adapter -->
<g id="edge16" class="edge">
<title>fabric&#45;&gt;apb_adapter</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2620.61,-430.26C2542.69,-414.14 2455,-396 2455,-396 2455,-396 2425,-387 2425,-387 2425,-387 1725.89,-357.75 1523.36,-349.27"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1523.18,-346.81 1516.08,-348.97 1522.97,-351.71 1523.18,-346.81"/>
<text text-anchor="middle" x="2462" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2509.37,-418.89C2479.63,-402.64 2451,-387 2451,-387 2451,-387 1767.37,-357.85 1567.35,-349.32"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1567.26,-346.86 1560.16,-349.01 1567.05,-351.76 1567.26,-346.86"/>
<text text-anchor="middle" x="2473" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
</g>
<!-- sysctrl -->
<g id="node16" class="node">
<title>sysctrl</title>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3701.5,-255C3701.5,-255 3538.5,-255 3538.5,-255 3532.5,-255 3526.5,-249 3526.5,-243 3526.5,-243 3526.5,-222 3526.5,-222 3526.5,-216 3532.5,-210 3538.5,-210 3538.5,-210 3701.5,-210 3701.5,-210 3707.5,-210 3713.5,-216 3713.5,-222 3713.5,-222 3713.5,-243 3713.5,-243 3713.5,-249 3707.5,-255 3701.5,-255"/>
<text text-anchor="middle" x="3620" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL</text>
<text text-anchor="middle" x="3620" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user&#45;core select/reset/bus enable</text>
<text text-anchor="middle" x="3620" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M2747.5,-255C2747.5,-255 2584.5,-255 2584.5,-255 2578.5,-255 2572.5,-249 2572.5,-243 2572.5,-243 2572.5,-222 2572.5,-222 2572.5,-216 2578.5,-210 2584.5,-210 2584.5,-210 2747.5,-210 2747.5,-210 2753.5,-210 2759.5,-216 2759.5,-222 2759.5,-222 2759.5,-243 2759.5,-243 2759.5,-249 2753.5,-255 2747.5,-255"/>
<text text-anchor="middle" x="2666" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL</text>
<text text-anchor="middle" x="2666" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user&#45;core select/reset/bus enable</text>
<text text-anchor="middle" x="2666" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
</g>
<!-- ribp_adapter&#45;&gt;sysctrl -->
<g id="edge17" class="edge">
<title>ribp_adapter&#45;&gt;sysctrl</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3041.67,-339.69C3108.58,-328.81 3255,-305 3255,-305 3255,-305 3513,-255 3513,-255 3513,-255 3515.31,-254.54 3519.25,-253.74"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3519.74,-256.14 3526.12,-252.36 3518.77,-251.34 3519.74,-256.14"/>
<text text-anchor="middle" x="3400.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2868.48,-334.07C2833.25,-322.23 2782,-305 2782,-305 2782,-305 2740.58,-279.47 2707.24,-258.92"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2708.36,-256.73 2701.12,-255.15 2705.79,-260.91 2708.36,-256.73"/>
<text text-anchor="middle" x="2791.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
</g>
<!-- ribp_adapter&#45;&gt;clint -->
<g id="edge18" class="edge">
<title>ribp_adapter&#45;&gt;clint</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2976.29,-341.42C2886.7,-331.6 2644,-305 2644,-305 2644,-305 2615,-278 2615,-278 2615,-278 1131,-255 1131,-255 1131,-255 1128.14,-254.29 1123.46,-253.14"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1124.02,-250.75 1116.63,-251.45 1122.84,-255.51 1124.02,-250.75"/>
<text text-anchor="middle" x="2653.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2868.24,-341.89C2769.09,-332.5 2479,-305 2479,-305 2479,-305 2278,-278 2278,-278 2278,-278 1396,-255 1396,-255 1396,-255 1393.14,-254.29 1388.46,-253.14"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1389.02,-250.75 1381.63,-251.45 1387.84,-255.51 1389.02,-250.75"/>
<text text-anchor="middle" x="2488.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
</g>
<!-- ribp_targets -->
<g id="node18" class="node">
<title>ribp_targets</title>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3487.5,-255C3487.5,-255 3282.5,-255 3282.5,-255 3276.5,-255 3270.5,-249 3270.5,-243 3270.5,-243 3270.5,-222 3270.5,-222 3270.5,-216 3276.5,-210 3282.5,-210 3282.5,-210 3487.5,-210 3487.5,-210 3493.5,-210 3499.5,-216 3499.5,-222 3499.5,-222 3499.5,-243 3499.5,-243 3499.5,-249 3493.5,-255 3487.5,-255"/>
<text text-anchor="middle" x="3385" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
<text text-anchor="middle" x="3385" y="-230" font-family="Arial" font-size="10.00" fill="#111827">XPI/Flash, SDRAM, PSRAM, SPI&#45;SD and DVP</text>
<text text-anchor="middle" x="3385" y="-219" font-family="Arial" font-size="10.00" fill="#111827">I2S</text>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3003.5,-255C3003.5,-255 2798.5,-255 2798.5,-255 2792.5,-255 2786.5,-249 2786.5,-243 2786.5,-243 2786.5,-222 2786.5,-222 2786.5,-216 2792.5,-210 2798.5,-210 2798.5,-210 3003.5,-210 3003.5,-210 3009.5,-210 3015.5,-216 3015.5,-222 3015.5,-222 3015.5,-243 3015.5,-243 3015.5,-249 3009.5,-255 3003.5,-255"/>
<text text-anchor="middle" x="2901" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
<text text-anchor="middle" x="2901" y="-230" font-family="Arial" font-size="10.00" fill="#111827">XPI/Flash, SDRAM, PSRAM, SPI&#45;SD and DVP</text>
<text text-anchor="middle" x="2901" y="-219" font-family="Arial" font-size="10.00" fill="#111827">I2S</text>
</g>
<!-- ribp_adapter&#45;&gt;ribp_targets -->
<g id="edge19" class="edge">
<title>ribp_adapter&#45;&gt;ribp_targets</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3041.71,-335.3C3100.1,-317.98 3223.82,-281.3 3305.67,-257.02"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3306.46,-259.35 3312.48,-255.01 3305.07,-254.65 3306.46,-259.35"/>
<text text-anchor="middle" x="3239.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2901,-327.58C2901,-310.16 2901,-283.05 2901,-262.4"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2903.45,-262.4 2901,-255.4 2898.55,-262.4 2903.45,-262.4"/>
<text text-anchor="middle" x="2910.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
</g>
<!-- ribp_adapter&#45;&gt;uart0 -->
<g id="edge20" class="edge">
<title>ribp_adapter&#45;&gt;uart0</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3001.02,-327.75C2991.83,-307.89 2978,-278 2978,-278 2978,-278 2957.98,-268.42 2936.52,-258.15"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2937.51,-255.91 2930.14,-255.1 2935.39,-260.33 2937.51,-255.91"/>
<text text-anchor="middle" x="2998.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2933.51,-342.31C3042.03,-333.34 3385,-305 3385,-305 3385,-305 3562.17,-275.47 3688.8,-254.37"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3689.42,-256.75 3695.92,-253.18 3688.61,-251.91 3689.42,-256.75"/>
<text text-anchor="middle" x="3545.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
</g>
<!-- ribp_adapter&#45;&gt;i2c_controllers -->
<g id="edge21" class="edge">
<title>ribp_adapter&#45;&gt;i2c_controllers</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2976.3,-333C2944.19,-321.22 2900,-305 2900,-305 2900,-305 2870,-278 2870,-278 2870,-278 2820.07,-267.37 2769.01,-256.5"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2769.49,-254.09 2762.13,-255.03 2768.47,-258.89 2769.49,-254.09"/>
<text text-anchor="middle" x="2909.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2933.85,-337.34C3004.13,-320.94 3171.45,-281.91 3279.75,-256.65"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3280.54,-258.98 3286.8,-255.01 3279.43,-254.21 3280.54,-258.98"/>
<text text-anchor="middle" x="3191.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
</g>
<!-- gpio_controller -->
<g id="node21" class="node">
<title>gpio_controller</title>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M3166,-255C3166,-255 3016,-255 3016,-255 3010,-255 3004,-249 3004,-243 3004,-243 3004,-222 3004,-222 3004,-216 3010,-210 3016,-210 3016,-210 3166,-210 3166,-210 3172,-210 3178,-216 3178,-222 3178,-222 3178,-243 3178,-243 3178,-249 3172,-255 3166,-255"/>
<text text-anchor="middle" x="3091" y="-241" font-family="Arial" font-size="10.00" fill="#111827">GPIO V2</text>
<text text-anchor="middle" x="3091" y="-230" font-family="Arial" font-size="10.00" fill="#111827">user + management RIBP windows</text>
<text text-anchor="middle" x="3091" y="-219" font-family="Arial" font-size="10.00" fill="#111827">atomic I/O, filter, locks, IRQ18</text>
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M2533,-255C2533,-255 2383,-255 2383,-255 2377,-255 2371,-249 2371,-243 2371,-243 2371,-222 2371,-222 2371,-216 2377,-210 2383,-210 2383,-210 2533,-210 2533,-210 2539,-210 2545,-216 2545,-222 2545,-222 2545,-243 2545,-243 2545,-249 2539,-255 2533,-255"/>
<text text-anchor="middle" x="2458" y="-241" font-family="Arial" font-size="10.00" fill="#111827">GPIO V2</text>
<text text-anchor="middle" x="2458" y="-230" font-family="Arial" font-size="10.00" fill="#111827">user + management RIBP windows</text>
<text text-anchor="middle" x="2458" y="-219" font-family="Arial" font-size="10.00" fill="#111827">atomic I/O, filter, locks, IRQ18</text>
</g>
<!-- ribp_adapter&#45;&gt;gpio_controller -->
<g id="edge22" class="edge">
<title>ribp_adapter&#45;&gt;gpio_controller</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3021.81,-327.58C3034.91,-309.77 3055.43,-281.86 3070.73,-261.06"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3072.72,-262.49 3074.9,-255.4 3068.78,-259.58 3072.72,-262.49"/>
<text text-anchor="middle" x="3077" y="-294.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<text text-anchor="middle" x="3077" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">user/admin</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2868.4,-341.49C2777.87,-331.72 2530,-305 2530,-305 2530,-305 2505.5,-280.67 2485.08,-260.39"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2486.69,-258.53 2479.99,-255.34 2483.23,-262.01 2486.69,-258.53"/>
<text text-anchor="middle" x="2550" y="-294.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<text text-anchor="middle" x="2550" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">user/admin</text>
</g>
<!-- ribp_adapter&#45;&gt;timers -->
<g id="edge23" class="edge">
<title>ribp_adapter&#45;&gt;timers</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3041.62,-341.79C3138.2,-332.3 3416,-305 3416,-305 3416,-305 3501,-278 3501,-278 3501,-278 3727,-255 3727,-255 3727,-255 3729.33,-254.57 3733.33,-253.83"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3733.87,-256.22 3740.31,-252.53 3732.98,-251.4 3733.87,-256.22"/>
<text text-anchor="middle" x="3510.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2933.7,-329.12C2974.51,-309.31 3039,-278 3039,-278 3039,-278 3062.21,-268.26 3086.91,-257.89"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3088.05,-260.07 3093.55,-255.1 3086.15,-255.55 3088.05,-260.07"/>
<text text-anchor="middle" x="3048.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
</g>
<!-- ribp_adapter&#45;&gt;ws2812 -->
<g id="edge24" class="edge">
<title>ribp_adapter&#45;&gt;ws2812</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2976.41,-340.79C2896.82,-330.53 2699,-305 2699,-305 2699,-305 2669,-278 2669,-278 2669,-278 2543,-255 2543,-255 2543,-255 2540.42,-254.4 2536.12,-253.41"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2536.65,-251.02 2529.28,-251.83 2535.55,-255.79 2536.65,-251.02"/>
<text text-anchor="middle" x="2708.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2933.75,-340.72C3012.69,-330.4 3207,-305 3207,-305 3207,-305 3497,-255 3497,-255 3497,-255 3499.58,-254.4 3503.88,-253.41"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3504.45,-255.79 3510.72,-251.83 3503.35,-251.02 3504.45,-255.79"/>
<text text-anchor="middle" x="3369.5" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
</g>
<!-- apb_targets -->
<g id="node24" class="node">
@@ -423,53 +423,53 @@
<!-- apb_adapter&#45;&gt;apb_targets -->
<g id="edge32" class="edge">
<title>apb_adapter&#45;&gt;apb_targets</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1421.67,-329.22C1419.37,-328.46 1418,-328 1418,-328 1418,-328 958,-255 958,-255 958,-255 955.25,-254.1 950.87,-252.68"/>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1465.67,-329.22C1463.37,-328.46 1462,-328 1462,-328 1462,-328 1378,-305 1378,-305 1378,-305 1299,-278 1299,-278 1299,-278 958,-255 958,-255 958,-255 955.25,-254.1 950.87,-252.68"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="951.42,-250.28 944,-250.44 949.9,-254.94 951.42,-250.28"/>
<text text-anchor="middle" x="1277" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
<text text-anchor="middle" x="1386" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
</g>
<!-- pwm -->
<g id="node25" class="node">
<title>pwm</title>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1812,-255C1812,-255 1598,-255 1598,-255 1592,-255 1586,-249 1586,-243 1586,-243 1586,-222 1586,-222 1586,-216 1592,-210 1598,-210 1598,-210 1812,-210 1812,-210 1818,-210 1824,-216 1824,-222 1824,-222 1824,-243 1824,-243 1824,-249 1818,-255 1812,-255"/>
<text text-anchor="middle" x="1705" y="-241" font-family="Arial" font-size="10.00" fill="#111827">PWM V2</text>
<text text-anchor="middle" x="1705" y="-230" font-family="Arial" font-size="10.00" fill="#111827">2 timers, 4 action channels, 2 operators</text>
<text text-anchor="middle" x="1705" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fades, dead time, carrier, fault and capture, IRQ11</text>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1197,-255C1197,-255 983,-255 983,-255 977,-255 971,-249 971,-243 971,-243 971,-222 971,-222 971,-216 977,-210 983,-210 983,-210 1197,-210 1197,-210 1203,-210 1209,-216 1209,-222 1209,-222 1209,-243 1209,-243 1209,-249 1203,-255 1197,-255"/>
<text text-anchor="middle" x="1090" y="-241" font-family="Arial" font-size="10.00" fill="#111827">PWM V2</text>
<text text-anchor="middle" x="1090" y="-230" font-family="Arial" font-size="10.00" fill="#111827">2 timers, 4 action channels, 2 operators</text>
<text text-anchor="middle" x="1090" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fades, dead time, carrier, fault and capture, IRQ11</text>
</g>
<!-- apb_adapter&#45;&gt;pwm -->
<g id="edge31" class="edge">
<title>apb_adapter&#45;&gt;pwm</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1505.1,-327.94C1544.48,-309.34 1607.88,-279.38 1652.71,-258.21"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1653.9,-260.35 1659.18,-255.15 1651.81,-255.92 1653.9,-260.35"/>
<text text-anchor="middle" x="1616" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1484.19,-327.92C1450.71,-308.07 1400,-278 1400,-278 1400,-278 1223,-255 1223,-255 1223,-255 1220.51,-254.6 1216.2,-253.9"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1216.57,-251.48 1209.27,-252.78 1215.79,-256.32 1216.57,-251.48"/>
<text text-anchor="middle" x="1451" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
</g>
<!-- apb_adapter&#45;&gt;wdg -->
<g id="edge29" class="edge">
<title>apb_adapter&#45;&gt;wdg</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1421.67,-329.22C1419.37,-328.46 1418,-328 1418,-328 1418,-328 928,-305 928,-305 928,-305 843,-278 843,-278 843,-278 586,-255 586,-255 586,-255 583.41,-254.46 579.06,-253.55"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="579.46,-251.13 572.11,-252.1 578.46,-255.93 579.46,-251.13"/>
<text text-anchor="middle" x="936" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1465.67,-329.22C1463.37,-328.46 1462,-328 1462,-328 1462,-328 1277,-305 1277,-305 1277,-305 1208,-278 1208,-278 1208,-278 827,-255 827,-255 827,-255 824.41,-254.46 820.06,-253.55"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="820.46,-251.13 813.11,-252.1 819.46,-255.93 820.46,-251.13"/>
<text text-anchor="middle" x="1285" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
</g>
<!-- crc -->
<g id="node27" class="node">
<title>crc</title>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1340,-255C1340,-255 1156,-255 1156,-255 1150,-255 1144,-249 1144,-243 1144,-243 1144,-222 1144,-222 1144,-216 1150,-210 1156,-210 1156,-210 1340,-210 1340,-210 1346,-210 1352,-216 1352,-222 1352,-222 1352,-243 1352,-243 1352,-249 1346,-255 1340,-255"/>
<text text-anchor="middle" x="1248" y="-241" font-family="Arial" font-size="10.00" fill="#111827">CRC V2</text>
<text text-anchor="middle" x="1248" y="-230" font-family="Arial" font-size="10.00" fill="#111827">programmable 7/8/16/32&#45;bit streaming CRC</text>
<text text-anchor="middle" x="1248" y="-219" font-family="Arial" font-size="10.00" fill="#111827">byte, halfword and word APB feed</text>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1605,-255C1605,-255 1421,-255 1421,-255 1415,-255 1409,-249 1409,-243 1409,-243 1409,-222 1409,-222 1409,-216 1415,-210 1421,-210 1421,-210 1605,-210 1605,-210 1611,-210 1617,-216 1617,-222 1617,-222 1617,-243 1617,-243 1617,-249 1611,-255 1605,-255"/>
<text text-anchor="middle" x="1513" y="-241" font-family="Arial" font-size="10.00" fill="#111827">CRC V2</text>
<text text-anchor="middle" x="1513" y="-230" font-family="Arial" font-size="10.00" fill="#111827">programmable 7/8/16/32&#45;bit streaming CRC</text>
<text text-anchor="middle" x="1513" y="-219" font-family="Arial" font-size="10.00" fill="#111827">byte, halfword and word APB feed</text>
</g>
<!-- apb_adapter&#45;&gt;crc -->
<g id="edge30" class="edge">
<title>apb_adapter&#45;&gt;crc</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1434.95,-327.82C1398.1,-309.23 1338.99,-279.41 1297.12,-258.28"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1298.16,-256.06 1290.81,-255.1 1295.95,-260.44 1298.16,-256.06"/>
<text text-anchor="middle" x="1392" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1513,-327.58C1513,-310.16 1513,-283.05 1513,-262.4"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1515.45,-262.4 1513,-255.4 1510.55,-262.4 1515.45,-262.4"/>
<text text-anchor="middle" x="1521" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
</g>
<!-- apb_adapter&#45;&gt;rtc -->
<g id="edge28" class="edge">
<title>apb_adapter&#45;&gt;rtc</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1421.67,-329.22C1419.37,-328.46 1418,-328 1418,-328 1418,-328 1084,-305 1084,-305 1084,-305 931.28,-276.11 819.99,-255.06"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="820.39,-252.64 813.06,-253.75 819.48,-257.46 820.39,-252.64"/>
<text text-anchor="middle" x="1092" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1465.67,-329.22C1463.37,-328.46 1462,-328 1462,-328 1462,-328 1186,-305 1186,-305 1186,-305 1155,-278 1155,-278 1155,-278 622,-255 622,-255 622,-255 619.46,-254.55 615.1,-253.77"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="615.44,-251.35 608.12,-252.53 614.58,-256.17 615.44,-251.35"/>
<text text-anchor="middle" x="1194" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
</g>
<!-- archinfo -->
<g id="node29" class="node">
@@ -482,222 +482,231 @@
<!-- apb_adapter&#45;&gt;archinfo -->
<g id="edge25" class="edge">
<title>apb_adapter&#45;&gt;archinfo</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1516.12,-339.05C1604.42,-327.91 1786,-305 1786,-305 1786,-305 2103,-255 2103,-255 2103,-255 2105.09,-254.65 2108.72,-254.03"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2109.15,-256.44 2115.64,-252.86 2108.33,-251.61 2109.15,-256.44"/>
<text text-anchor="middle" x="1962" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1560.32,-340.98C1679.76,-330.84 1984,-305 1984,-305 1984,-305 2077.31,-277.88 2148.99,-257.04"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2149.82,-259.36 2155.86,-255.05 2148.45,-254.65 2149.82,-259.36"/>
<text text-anchor="middle" x="2078" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
</g>
<!-- rng -->
<g id="node30" class="node">
<title>rng</title>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M2077,-255C2077,-255 1863,-255 1863,-255 1857,-255 1851,-249 1851,-243 1851,-243 1851,-222 1851,-222 1851,-216 1857,-210 1863,-210 1863,-210 2077,-210 2077,-210 2083,-210 2089,-216 2089,-222 2089,-222 2089,-243 2089,-243 2089,-249 2083,-255 2077,-255"/>
<text text-anchor="middle" x="1970" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RNG V2 entropy controller</text>
<text text-anchor="middle" x="1970" y="-230" font-family="Arial" font-size="10.00" fill="#111827">8&#45;word FIFO, fail&#45;closed monitoring, IRQ16</text>
<text text-anchor="middle" x="1970" y="-219" font-family="Arial" font-size="10.00" fill="#111827">management&#45;only, deterministic source unqualified</text>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1870,-255C1870,-255 1656,-255 1656,-255 1650,-255 1644,-249 1644,-243 1644,-243 1644,-222 1644,-222 1644,-216 1650,-210 1656,-210 1656,-210 1870,-210 1870,-210 1876,-210 1882,-216 1882,-222 1882,-222 1882,-243 1882,-243 1882,-249 1876,-255 1870,-255"/>
<text text-anchor="middle" x="1763" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RNG V2 entropy controller</text>
<text text-anchor="middle" x="1763" y="-230" font-family="Arial" font-size="10.00" fill="#111827">8&#45;word FIFO, fail&#45;closed monitoring, IRQ16</text>
<text text-anchor="middle" x="1763" y="-219" font-family="Arial" font-size="10.00" fill="#111827">management&#45;only, deterministic source unqualified</text>
</g>
<!-- apb_adapter&#45;&gt;rng -->
<g id="edge26" class="edge">
<title>apb_adapter&#45;&gt;rng</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1516.13,-334.51C1595.74,-316.79 1758.65,-280.54 1866.08,-256.63"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1866.77,-258.98 1873.07,-255.07 1865.71,-254.2 1866.77,-258.98"/>
<text text-anchor="middle" x="1772" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1551.24,-327.94C1593.05,-309.3 1660.4,-279.26 1707.9,-258.08"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1709.07,-260.24 1714.46,-255.15 1707.07,-255.76 1709.07,-260.24"/>
<text text-anchor="middle" x="1668" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
</g>
<!-- ps2 -->
<g id="node31" class="node">
<title>ps2</title>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1547,-255C1547,-255 1391,-255 1391,-255 1385,-255 1379,-249 1379,-243 1379,-243 1379,-222 1379,-222 1379,-216 1385,-210 1391,-210 1391,-210 1547,-210 1547,-210 1553,-210 1559,-216 1559,-222 1559,-222 1559,-243 1559,-243 1559,-249 1553,-255 1547,-255"/>
<text text-anchor="middle" x="1469" y="-241" font-family="Arial" font-size="10.00" fill="#111827">PS/2 host V2</text>
<text text-anchor="middle" x="1469" y="-230" font-family="Arial" font-size="10.00" fill="#111827">bidirectional open&#45;drain transport</text>
<text text-anchor="middle" x="1469" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16&#45;byte RX/TX FIFOs, errors, IRQ12</text>
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M2077,-255C2077,-255 1921,-255 1921,-255 1915,-255 1909,-249 1909,-243 1909,-243 1909,-222 1909,-222 1909,-216 1915,-210 1921,-210 1921,-210 2077,-210 2077,-210 2083,-210 2089,-216 2089,-222 2089,-222 2089,-243 2089,-243 2089,-249 2083,-255 2077,-255"/>
<text text-anchor="middle" x="1999" y="-241" font-family="Arial" font-size="10.00" fill="#111827">PS/2 host V2</text>
<text text-anchor="middle" x="1999" y="-230" font-family="Arial" font-size="10.00" fill="#111827">bidirectional open&#45;drain transport</text>
<text text-anchor="middle" x="1999" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16&#45;byte RX/TX FIFOs, errors, IRQ12</text>
</g>
<!-- apb_adapter&#45;&gt;ps2 -->
<g id="edge27" class="edge">
<title>apb_adapter&#45;&gt;ps2</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1469,-327.58C1469,-310.16 1469,-283.05 1469,-262.4"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1471.45,-262.4 1469,-255.4 1466.55,-262.4 1471.45,-262.4"/>
<text text-anchor="middle" x="1477" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1560.14,-340.6C1671.58,-330.21 1942,-305 1942,-305 1942,-305 1961.07,-281.08 1977.15,-260.91"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1979.14,-262.34 1981.59,-255.34 1975.31,-259.29 1979.14,-262.34"/>
<text text-anchor="middle" x="1970" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
</g>
<!-- irq -->
<g id="node33" class="node">
<title>irq</title>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M2073,-155C2073,-155 1867,-155 1867,-155 1861,-155 1855,-149 1855,-143 1855,-143 1855,-131 1855,-131 1855,-125 1861,-119 1867,-119 1867,-119 2073,-119 2073,-119 2079,-119 2085,-125 2085,-131 2085,-131 2085,-143 2085,-143 2085,-149 2079,-155 2073,-155"/>
<text text-anchor="middle" x="1970" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
<text text-anchor="middle" x="1970" y="-129" font-family="Arial" font-size="10.00" fill="#111827">RIBP and APB target IRQs to management core</text>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M2102,-155C2102,-155 1896,-155 1896,-155 1890,-155 1884,-149 1884,-143 1884,-143 1884,-131 1884,-131 1884,-125 1890,-119 1896,-119 1896,-119 2102,-119 2102,-119 2108,-119 2114,-125 2114,-131 2114,-131 2114,-143 2114,-143 2114,-149 2108,-155 2102,-155"/>
<text text-anchor="middle" x="1999" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
<text text-anchor="middle" x="1999" y="-129" font-family="Arial" font-size="10.00" fill="#111827">RIBP and APB target IRQs to management core</text>
</g>
<!-- clint&#45;&gt;irq -->
<g id="edge37" class="edge">
<title>clint&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1116.63,-213.55C1125.22,-211.43 1131,-210 1131,-210 1131,-210 1614.62,-168.5 1847.5,-148.51"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1847.9,-150.94 1854.66,-147.9 1847.48,-146.06 1847.9,-150.94"/>
<text text-anchor="middle" x="1538.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">machine IRQ0 / IRQ1</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1381.63,-213.55C1390.22,-211.43 1396,-210 1396,-210 1396,-210 1700.59,-173.63 1876.81,-152.59"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1877.15,-155.02 1883.81,-151.75 1876.56,-150.15 1877.15,-155.02"/>
<text text-anchor="middle" x="1699.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">machine IRQ0 / IRQ1</text>
</g>
<!-- ribp_targets&#45;&gt;ext_io -->
<g id="edge58" class="edge">
<g id="edge59" class="edge">
<title>ribp_targets&#45;&gt;ext_io</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3333.02,-206.7C3249.04,-166.64 3084.5,-88.14 3000.71,-48.17"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3332.2,-209.03 3339.57,-209.83 3334.31,-204.6 3332.2,-209.03"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3001.7,-45.93 2994.32,-45.12 2999.59,-50.35 3001.7,-45.93"/>
<text text-anchor="middle" x="3254" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2995.87,-208.3C3040.05,-197.5 3083,-187 3083,-187 3083,-187 3092.65,-99.32 3097.82,-52.38"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2995.29,-205.92 2989.07,-209.97 2996.45,-210.68 2995.29,-205.92"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3100.28,-52.44 3098.61,-45.21 3095.41,-51.9 3100.28,-52.44"/>
<text text-anchor="middle" x="3124" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
</g>
<!-- ribp_targets&#45;&gt;gpio_controller -->
<g id="edge33" class="edge">
<title>ribp_targets&#45;&gt;gpio_controller</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3270.39,-232.5C3242.19,-232.5 3212.32,-232.5 3185.21,-232.5"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3185.02,-230.05 3178.02,-232.5 3185.02,-234.95 3185.02,-230.05"/>
<text text-anchor="middle" x="3224.25" y="-238.1" font-family="Arial" font-size="8.00" fill="#374151">alternate functions</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2793.79,-255.06C2722.53,-270.05 2642,-287 2642,-287 2642,-287 2576,-287 2576,-287 2576,-287 2544.13,-272.28 2513.52,-258.14"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2514.4,-255.85 2507.02,-255.14 2512.35,-260.3 2514.4,-255.85"/>
<text text-anchor="middle" x="2609" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">alternate functions</text>
</g>
<!-- uart0&#45;&gt;ext_io -->
<g id="edge59" class="edge">
<g id="edge60" class="edge">
<title>uart0&#45;&gt;ext_io</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2912.63,-204.77C2922.4,-195.32 2931,-187 2931,-187 2931,-187 2940.65,-99.32 2945.82,-52.38"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2910.79,-203.14 2907.46,-209.77 2914.2,-206.67 2910.79,-203.14"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2948.28,-52.44 2946.61,-45.21 2943.41,-51.9 2948.28,-52.44"/>
<text text-anchor="middle" x="2963" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">UART pads</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3733.1,-207.9C3595.85,-167.86 3318.92,-87.07 3181.76,-47.06"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3732.64,-210.32 3740.05,-209.93 3734.01,-205.61 3732.64,-210.32"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3182.34,-44.68 3174.93,-45.07 3180.97,-49.38 3182.34,-44.68"/>
<text text-anchor="middle" x="3572" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">UART pads</text>
</g>
<!-- uart0&#45;&gt;gpio_controller -->
<g id="edge42" class="edge">
<title>uart0&#45;&gt;gpio_controller</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3688.43,-254.07C3684.97,-254.66 3683,-255 3683,-255 3683,-255 2865,-291.5 2865,-291.5 2865,-291.5 2807,-291.5 2807,-291.5 2807,-291.5 2559,-255 2559,-255 2559,-255 2556.58,-254.46 2552.48,-253.55"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3689.08,-256.44 3695.56,-252.84 3688.25,-251.61 3689.08,-256.44"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2552.74,-251.1 2545.38,-251.97 2551.68,-255.88 2552.74,-251.1"/>
<text text-anchor="middle" x="2836" y="-294.1" font-family="Arial" font-size="8.00" fill="#374151">GPIO0/1 ALT0</text>
<text text-anchor="middle" x="2836" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">CTS_n / RTS_n</text>
</g>
<!-- uart0&#45;&gt;irq -->
<g id="edge42" class="edge">
<g id="edge43" class="edge">
<title>uart0&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2792.99,-211.73C2722.06,-196.49 2636,-178 2636,-178 2636,-178 2284.6,-156.9 2092.3,-145.35"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2092.38,-142.9 2085.25,-144.92 2092.09,-147.79 2092.38,-142.9"/>
<text text-anchor="middle" x="2686.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ2</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3695.56,-212.06C3687.8,-210.79 3683,-210 3683,-210 3683,-210 3027,-178 3027,-178 3027,-178 2394.25,-153.38 2121.6,-142.77"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2121.52,-140.32 2114.43,-142.49 2121.33,-145.21 2121.52,-140.32"/>
<text text-anchor="middle" x="3211.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ2</text>
</g>
<!-- i2c_controllers&#45;&gt;gpio_controller -->
<g id="edge43" class="edge">
<g id="edge44" class="edge">
<title>i2c_controllers&#45;&gt;gpio_controller</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2761.94,-255.06C2836.47,-271.71 2925,-291.5 2925,-291.5 2925,-291.5 2977,-291.5 2977,-291.5 2977,-291.5 3010.21,-274.31 3040.78,-258.49"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3042.16,-260.54 3047.25,-255.14 3039.91,-256.18 3042.16,-260.54"/>
<text text-anchor="middle" x="2951" y="-294.1" font-family="Arial" font-size="8.00" fill="#374151">GPIO3/4 ALT1</text>
<text text-anchor="middle" x="2951" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">GPIO7/8 ALT0</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3274.08,-252.51C3266.06,-254.04 3261,-255 3261,-255 3261,-255 2729,-291.5 2729,-291.5 2729,-291.5 2677,-291.5 2677,-291.5 2677,-291.5 2608.91,-273.16 2548.66,-256.92"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2549.13,-254.51 2541.73,-255.06 2547.85,-259.24 2549.13,-254.51"/>
<text text-anchor="middle" x="2703" y="-294.1" font-family="Arial" font-size="8.00" fill="#374151">GPIO3/4 ALT1</text>
<text text-anchor="middle" x="2703" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">GPIO7/8 ALT0</text>
</g>
<!-- i2c_controllers&#45;&gt;irq -->
<g id="edge45" class="edge">
<g id="edge46" class="edge">
<title>i2c_controllers&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2622.23,-209.89C2595.59,-195.05 2565,-178 2565,-178 2565,-178 2266.38,-157.92 2092.24,-146.22"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2092.22,-143.76 2085.07,-145.74 2091.89,-148.65 2092.22,-143.76"/>
<text text-anchor="middle" x="2605.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ7 / IRQ19</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3274.08,-212.38C3266.06,-210.92 3261,-210 3261,-210 3261,-210 2433,-187 2433,-187 2433,-187 2386,-178 2386,-178 2386,-178 2234.55,-162.35 2121.14,-150.62"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2121.28,-148.18 2114.06,-149.89 2120.78,-153.05 2121.28,-148.18"/>
<text text-anchor="middle" x="2457.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ7 / IRQ19</text>
</g>
<!-- gpio_bridge -->
<g id="node32" class="node">
<title>gpio_bridge</title>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M2880.5,-155C2880.5,-155 2745.5,-155 2745.5,-155 2739.5,-155 2733.5,-149 2733.5,-143 2733.5,-143 2733.5,-131 2733.5,-131 2733.5,-125 2739.5,-119 2745.5,-119 2745.5,-119 2880.5,-119 2880.5,-119 2886.5,-119 2892.5,-125 2892.5,-131 2892.5,-131 2892.5,-143 2892.5,-143 2892.5,-149 2886.5,-155 2880.5,-155"/>
<text text-anchor="middle" x="2813" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
<text text-anchor="middle" x="2813" y="-129" font-family="Arial" font-size="10.00" fill="#111827">PDK capability&#45;adapted controls</text>
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M3034.5,-155C3034.5,-155 2899.5,-155 2899.5,-155 2893.5,-155 2887.5,-149 2887.5,-143 2887.5,-143 2887.5,-131 2887.5,-131 2887.5,-125 2893.5,-119 2899.5,-119 2899.5,-119 3034.5,-119 3034.5,-119 3040.5,-119 3046.5,-125 3046.5,-131 3046.5,-131 3046.5,-143 3046.5,-143 3046.5,-149 3040.5,-155 3034.5,-155"/>
<text text-anchor="middle" x="2967" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
<text text-anchor="middle" x="2967" y="-129" font-family="Arial" font-size="10.00" fill="#111827">PDK capability&#45;adapted controls</text>
</g>
<!-- gpio_controller&#45;&gt;gpio_bridge -->
<g id="edge34" class="edge">
<title>gpio_controller&#45;&gt;gpio_bridge</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3003.67,-212.72C2995.96,-211.07 2991,-210 2991,-210 2991,-210 2812,-187 2812,-187 2812,-187 2812,-178 2812,-178 2812,-178 2812.18,-170.7 2812.39,-162.33"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2814.84,-162.25 2812.57,-155.2 2809.95,-162.13 2814.84,-162.25"/>
<text text-anchor="middle" x="2832" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2545.38,-212.9C2553.64,-211.14 2559,-210 2559,-210 2559,-210 2760.52,-174.44 2880.31,-153.3"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2880.9,-155.68 2887.36,-152.05 2880.05,-150.86 2880.9,-155.68"/>
<text text-anchor="middle" x="2758" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
</g>
<!-- gpio_controller&#45;&gt;irq -->
<g id="edge35" class="edge">
<title>gpio_controller&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3003.67,-212.72C2995.96,-211.07 2991,-210 2991,-210 2991,-210 2782,-187 2782,-187 2782,-187 2702,-178 2702,-178 2702,-178 2300.49,-156.06 2092.2,-144.68"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2092.3,-142.23 2085.18,-144.29 2092.04,-147.12 2092.3,-142.23"/>
<text text-anchor="middle" x="2794" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ18</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2370.67,-212.72C2362.96,-211.07 2358,-210 2358,-210 2358,-210 2197.37,-177.78 2091,-156.45"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2091.42,-154.04 2084.08,-155.06 2090.46,-158.84 2091.42,-154.04"/>
<text text-anchor="middle" x="2253" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ18</text>
</g>
<!-- timers&#45;&gt;irq -->
<g id="edge36" class="edge">
<title>timers&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3740.31,-212.47C3732.16,-210.96 3727,-210 3727,-210 3727,-210 2491.39,-159.37 2092.53,-143.02"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2092.38,-140.56 2085.28,-142.72 2092.18,-145.46 2092.38,-140.56"/>
<text text-anchor="middle" x="3180.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ3 / IRQ4</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3042.31,-212.47C3034.16,-210.96 3029,-210 3029,-210 3029,-210 2339,-187 2339,-187 2339,-187 2218.59,-169.65 2121.09,-155.59"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2121.39,-153.16 2114.11,-154.59 2120.69,-158.01 2121.39,-153.16"/>
<text text-anchor="middle" x="2361.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ3 / IRQ4</text>
</g>
<!-- ws2812&#45;&gt;gpio_bridge -->
<g id="edge38" class="edge">
<title>ws2812&#45;&gt;gpio_bridge</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2477.66,-209.74C2496.48,-194.93 2518,-178 2518,-178 2518,-178 2639.15,-161.57 2726.18,-149.77"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2726.56,-152.19 2733.17,-148.82 2725.9,-147.34 2726.56,-152.19"/>
<text text-anchor="middle" x="2540.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO2 ALT1</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3510.72,-213.17C3502.45,-211.26 3497,-210 3497,-210 3497,-210 2980,-187 2980,-187 2980,-187 2976.65,-174.38 2973.35,-161.94"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2975.71,-161.28 2971.55,-155.14 2970.97,-162.53 2975.71,-161.28"/>
<text text-anchor="middle" x="3002.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO2 ALT1</text>
</g>
<!-- ws2812&#45;&gt;irq -->
<g id="edge40" class="edge">
<title>ws2812&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2370.79,-212.99C2363.05,-211.18 2358,-210 2358,-210 2358,-210 2184.05,-177.72 2069.09,-156.39"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2069.28,-153.93 2061.95,-155.06 2068.39,-158.75 2069.28,-153.93"/>
<text text-anchor="middle" x="2244" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ17</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M3510.72,-213.17C3502.45,-211.26 3497,-210 3497,-210 3497,-210 2660,-187 2660,-187 2660,-187 2312.17,-161.22 2121.15,-147.05"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2121.3,-144.61 2114.14,-146.54 2120.94,-149.5 2121.3,-144.61"/>
<text text-anchor="middle" x="2672" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ17</text>
</g>
<!-- apb_targets&#45;&gt;gpio_controller -->
<g id="edge57" class="edge">
<g id="edge58" class="edge">
<title>apb_targets&#45;&gt;gpio_controller</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M944,-250.23C952.18,-253.02 958,-255 958,-255 958,-255 2509,-287 2509,-287 2509,-287 2545,-287 2545,-287 2545,-287 2991,-255 2991,-255 2991,-255 2993.14,-254.52 2996.78,-253.7"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2997.37,-256.08 3003.67,-252.15 2996.3,-251.3 2997.37,-256.08"/>
<text text-anchor="middle" x="2527" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M944,-250.23C952.18,-253.02 958,-255 958,-255 958,-255 1801,-287 1801,-287 1801,-287 1837,-287 1837,-287 1837,-287 2358,-255 2358,-255 2358,-255 2360.14,-254.52 2363.78,-253.7"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2364.37,-256.08 2370.67,-252.15 2363.3,-251.3 2364.37,-256.08"/>
<text text-anchor="middle" x="1819" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
</g>
<!-- pwm&#45;&gt;gpio_controller -->
<g id="edge49" class="edge">
<g id="edge50" class="edge">
<title>pwm&#45;&gt;gpio_controller</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1831.2,-253.85C1835.51,-254.58 1838,-255 1838,-255 1838,-255 2781,-296 2781,-296 2781,-296 2869,-296 2869,-296 2869,-296 2942.82,-274.89 3005.32,-257.01"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1831.58,-251.43 1824.27,-252.68 1830.76,-256.26 1831.58,-251.43"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3006.05,-259.35 3012.11,-255.07 3004.7,-254.64 3006.05,-259.35"/>
<text text-anchor="middle" x="2825" y="-298.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO3&#45;6 output</text>
<text text-anchor="middle" x="2825" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO2 sync, GPIO9 fault</text>
<text text-anchor="middle" x="2825" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO30/31 capture</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1216.2,-253.85C1220.51,-254.58 1223,-255 1223,-255 1223,-255 1848,-296 1848,-296 1848,-296 1936,-296 1936,-296 1936,-296 2358,-255 2358,-255 2358,-255 2360.14,-254.52 2363.78,-253.7"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1216.58,-251.43 1209.27,-252.68 1215.76,-256.26 1216.58,-251.43"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2364.37,-256.08 2370.67,-252.15 2363.3,-251.3 2364.37,-256.08"/>
<text text-anchor="middle" x="1892" y="-298.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO3&#45;6 output</text>
<text text-anchor="middle" x="1892" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO2 sync, GPIO9 fault</text>
<text text-anchor="middle" x="1892" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO30/31 capture</text>
</g>
<!-- pwm&#45;&gt;irq -->
<g id="edge50" class="edge">
<g id="edge51" class="edge">
<title>pwm&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1766.13,-209.93C1810.96,-194.11 1871.33,-172.81 1914.73,-157.5"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1915.76,-159.74 1921.54,-155.1 1914.13,-155.12 1915.76,-159.74"/>
<text text-anchor="middle" x="1865" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ11</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1209.27,-212.22C1217.72,-210.85 1223,-210 1223,-210 1223,-210 1561,-178 1561,-178 1561,-178 1747.05,-161.01 1876.63,-149.18"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1877.17,-151.59 1883.92,-148.51 1876.73,-146.71 1877.17,-151.59"/>
<text text-anchor="middle" x="1573" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ11</text>
</g>
<!-- wdg&#45;&gt;rcu -->
<g id="edge56" class="edge">
<g id="edge57" class="edge">
<title>wdg&#45;&gt;rcu</title>
<path fill="none" stroke="#b91c1c" stroke-width="2" d="M476.36,-255.08C462.76,-299.28 433,-396 433,-396 433,-396 337.46,-493.8 290.05,-542.32"/>
<polygon fill="#b91c1c" stroke="#b91c1c" stroke-width="2" points="288.2,-540.71 285.06,-547.43 291.71,-544.13 288.2,-540.71"/>
<text text-anchor="middle" x="472.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">system reset request</text>
<path fill="none" stroke="#b91c1c" stroke-width="2" d="M694.24,-255.2C612.97,-314.48 387.48,-478.93 299.66,-542.98"/>
<polygon fill="#b91c1c" stroke="#b91c1c" stroke-width="2" points="298.04,-541.13 293.83,-547.23 300.93,-545.09 298.04,-541.13"/>
<text text-anchor="middle" x="546.5" y="-389.6" font-family="Arial" font-size="8.00" fill="#374151">system reset request</text>
</g>
<!-- wdg&#45;&gt;irq -->
<g id="edge55" class="edge">
<g id="edge56" class="edge">
<title>wdg&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M572.11,-212.9C580.53,-211.14 586,-210 586,-210 586,-210 1116,-178 1116,-178 1116,-178 1611.4,-154.8 1847.57,-143.73"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1847.95,-146.17 1854.83,-143.39 1847.72,-141.27 1847.95,-146.17"/>
<text text-anchor="middle" x="1153" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">early warning IRQ14</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M813.11,-212.9C821.53,-211.14 827,-210 827,-210 827,-210 1576.81,-163.94 1876.95,-145.5"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1877.12,-147.94 1883.95,-145.07 1876.82,-143.05 1877.12,-147.94"/>
<text text-anchor="middle" x="1379" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">early warning IRQ14</text>
</g>
<!-- rtc&#45;&gt;sysctrl -->
<g id="edge53" class="edge">
<g id="edge54" class="edge">
<title>rtc&#45;&gt;sysctrl</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M813.12,-252.42C821.62,-254 827,-255 827,-255 827,-255 2551,-287 2551,-287 2551,-287 2609,-287 2609,-287 2609,-287 3513,-255 3513,-255 3513,-255 3515.31,-254.51 3519.25,-253.68"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3519.77,-256.08 3526.12,-252.24 3518.77,-251.28 3519.77,-256.08"/>
<text text-anchor="middle" x="2580" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">wake live / sticky</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M608.12,-252.42C616.62,-254 622,-255 622,-255 622,-255 1726,-287 1726,-287 1726,-287 1784,-287 1784,-287 1784,-287 2559,-255 2559,-255 2559,-255 2561.31,-254.51 2565.25,-253.68"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2565.77,-256.08 2572.12,-252.24 2564.77,-251.28 2565.77,-256.08"/>
<text text-anchor="middle" x="1755" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">wake live / sticky</text>
</g>
<!-- rtc&#45;&gt;irq -->
<g id="edge52" class="edge">
<g id="edge53" class="edge">
<title>rtc&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M813.12,-212.47C821.62,-210.96 827,-210 827,-210 827,-210 1552.67,-164.29 1847.59,-145.71"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1848.08,-148.14 1854.91,-145.25 1847.77,-143.24 1848.08,-148.14"/>
<text text-anchor="middle" x="1342" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ13</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M608.12,-212.47C616.62,-210.96 622,-210 622,-210 622,-210 1176,-178 1176,-178 1176,-178 1647.38,-155.09 1876.65,-143.95"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1876.83,-146.39 1883.7,-143.6 1876.59,-141.5 1876.83,-146.39"/>
<text text-anchor="middle" x="1188" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ13</text>
</g>
<!-- rng&#45;&gt;irq -->
<g id="edge46" class="edge">
<g id="edge47" class="edge">
<title>rng&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1970,-209.81C1970,-195.66 1970,-177.17 1970,-162.49"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1972.45,-162.2 1970,-155.2 1967.55,-162.2 1972.45,-162.2"/>
<text text-anchor="middle" x="1982" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ16</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1817.44,-209.93C1857.2,-194.18 1910.69,-172.99 1949.3,-157.69"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1950.24,-159.95 1955.85,-155.1 1948.44,-155.4 1950.24,-159.95"/>
<text text-anchor="middle" x="1907" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ16</text>
</g>
<!-- ps2&#45;&gt;gpio_controller -->
<g id="edge47" class="edge">
<g id="edge48" class="edge">
<title>ps2&#45;&gt;gpio_controller</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1559.4,-252.06C1567.66,-253.85 1573,-255 1573,-255 1573,-255 2724,-291.5 2724,-291.5 2724,-291.5 2776,-291.5 2776,-291.5 2776,-291.5 2991,-255 2991,-255 2991,-255 2993.14,-254.52 2996.78,-253.7"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2997.37,-256.08 3003.67,-252.15 2996.3,-251.3 2997.37,-256.08"/>
<text text-anchor="middle" x="2750" y="-294.1" font-family="Arial" font-size="8.00" fill="#374151">GPIO0/1 ALT1</text>
<text text-anchor="middle" x="2750" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">open drain</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2083.5,-255.06C2145.89,-271.71 2220,-291.5 2220,-291.5 2220,-291.5 2272,-291.5 2272,-291.5 2272,-291.5 2329.13,-273.38 2380.07,-257.22"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2380.95,-259.51 2386.89,-255.06 2379.47,-254.84 2380.95,-259.51"/>
<text text-anchor="middle" x="2246" y="-294.1" font-family="Arial" font-size="8.00" fill="#374151">GPIO0/1 ALT1</text>
<text text-anchor="middle" x="2246" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">open drain</text>
</g>
<!-- ps2&#45;&gt;irq -->
<g id="edge48" class="edge">
<g id="edge49" class="edge">
<title>ps2&#45;&gt;irq</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1559.4,-212.81C1567.66,-211.1 1573,-210 1573,-210 1573,-210 1751.6,-177.61 1869.21,-156.28"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1869.72,-158.68 1876.17,-155.02 1868.84,-153.86 1869.72,-158.68"/>
<text text-anchor="middle" x="1759" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ12</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1999,-209.81C1999,-195.66 1999,-177.17 1999,-162.49"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2001.45,-162.2 1999,-155.2 1996.55,-162.2 2001.45,-162.2"/>
<text text-anchor="middle" x="2011" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ12</text>
</g>
<!-- gpio_bridge&#45;&gt;ext_io -->
<g id="edge60" class="edge">
<g id="edge61" class="edge">
<title>gpio_bridge&#45;&gt;ext_io</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2837.65,-113.95C2859.84,-94.09 2889,-68 2889,-68 2889,-68 2900.85,-59.21 2914.01,-49.45"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2835.76,-112.35 2832.18,-118.84 2839.03,-116 2835.76,-112.35"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2915.54,-51.37 2919.7,-45.23 2912.62,-47.43 2915.54,-51.37"/>
<text text-anchor="middle" x="2909" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2991,-113.95C3012.61,-94.09 3041,-68 3041,-68 3041,-68 3052.85,-59.21 3066.01,-49.45"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2989.17,-112.3 2985.67,-118.84 2992.49,-115.91 2989.17,-112.3"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3067.54,-51.37 3071.7,-45.23 3064.62,-47.43 3067.54,-51.37"/>
<text text-anchor="middle" x="3061" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 60 KiB

+17 -1
View File
@@ -22,10 +22,26 @@ feature, and every profile binding in the JSON map. Use `null` for an open
binding. The generator rejects duplicate pad names, unknown profile bindings,
unsupported features, and unapproved connection syntax.
SoC wrappers use the existing clusterIP interfaces for protocol boundaries.
SoC wrappers use the existing clusterIP interfaces for protocol boundaries,
except for the self-owned UART0 `uart_if` under `rtl/ip/ribp/serial`.
`apb4_if_bridge` only adapts `apb4_pure_if` to `apb4_if`, and `gpio_pad_bridge`
only exposes the pad-side subset of `gpio_if`; neither module contains state.
## UART flow-control alternate functions
UART0 keeps dedicated RX and TX package pads. Optional active-low hardware flow
control uses GPIO0 ALT0 for the CTS input and GPIO1 ALT0 for the RTS output.
The UART owns synchronization and fail-safe CTS behavior; GPIO supplies only
the pad mux and resolved pad input. GPIO0/1 ALT1 remains assigned to the PS/2
clock/data pair, so software cannot use PS/2 and UART0 flow control on the same
pins simultaneously.
`rs_uart_configure()` selects each ALT0 route when the corresponding automatic
flow-control function is enabled. Disabling UART flow control does not reclaim
the GPIO pin. Software must explicitly choose a new GPIO mode before assigning
that physical pad to another function. See [uart.md](ip/uart.md) for the V3
register and timing contract.
## I2C alternate functions
The two I2C V2 controllers reuse GPIO pads rather than dedicated package pins.
+88 -46
View File
@@ -24,8 +24,13 @@ module ribp_uart #(
logic s_rx_enable;
logic s_loopback;
logic s_break;
logic s_auto_cts_enable;
logic s_auto_rts_enable;
logic [ 6:0] s_rts_assert_level;
logic [ 6:0] s_rts_deassert_level;
logic s_tx_data_valid;
logic [ 7:0] s_tx_data;
logic [ 6:0] s_rx_level;
logic s_tx_data_pop;
logic s_tx_busy;
logic s_tx_done;
@@ -35,6 +40,11 @@ module ribp_uart #(
logic s_bit_tick;
logic s_irq;
logic s_tx;
logic s_cts_asserted;
logic s_rts_asserted;
logic s_tx_start_allowed;
logic s_tx_flow_blocked;
logic s_cts_change;
assign uart.tx_o = s_tx;
assign uart.irq_o = s_irq;
@@ -43,55 +53,87 @@ module ribp_uart #(
.TX_FIFO_DEPTH(TX_FIFO_DEPTH),
.RX_FIFO_DEPTH(RX_FIFO_DEPTH)
) u_uart_reg (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.ribp (ribp),
.baud_int_o (s_baud_int),
.baud_frac_o (s_baud_frac),
.data_bits_o (s_data_bits),
.stop2_o (s_stop2),
.parity_o (s_parity),
.tx_enable_o (s_tx_enable),
.rx_enable_o (s_rx_enable),
.loopback_o (s_loopback),
.break_o (s_break),
.tx_data_valid_o(s_tx_data_valid),
.tx_data_o (s_tx_data),
.tx_data_pop_i (s_tx_data_pop),
.tx_busy_i (s_tx_busy),
.tx_done_i (s_tx_done),
.rx_active_i (s_rx_active),
.rx_data_valid_i(s_rx_data_valid),
.rx_data_i (s_rx_data),
.bit_tick_i (s_bit_tick),
.dma_tx_stall_o (dma_tx_stall_o),
.dma_rx_stall_o (dma_rx_stall_o),
.irq_o (s_irq)
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.ribp (ribp),
.baud_int_o (s_baud_int),
.baud_frac_o (s_baud_frac),
.data_bits_o (s_data_bits),
.stop2_o (s_stop2),
.parity_o (s_parity),
.tx_enable_o (s_tx_enable),
.rx_enable_o (s_rx_enable),
.loopback_o (s_loopback),
.break_o (s_break),
.auto_cts_enable_o (s_auto_cts_enable),
.auto_rts_enable_o (s_auto_rts_enable),
.rts_assert_level_o (s_rts_assert_level),
.rts_deassert_level_o(s_rts_deassert_level),
.tx_data_valid_o (s_tx_data_valid),
.tx_data_o (s_tx_data),
.rx_level_o (s_rx_level),
.tx_data_pop_i (s_tx_data_pop),
.tx_busy_i (s_tx_busy),
.tx_done_i (s_tx_done),
.rx_active_i (s_rx_active),
.rx_data_valid_i (s_rx_data_valid),
.rx_data_i (s_rx_data),
.bit_tick_i (s_bit_tick),
.cts_asserted_i (s_cts_asserted),
.rts_asserted_i (s_rts_asserted),
.tx_flow_blocked_i (s_tx_flow_blocked),
.cts_change_i (s_cts_change),
.dma_tx_stall_o (dma_tx_stall_o),
.dma_rx_stall_o (dma_rx_stall_o),
.irq_o (s_irq)
);
uart_core u_uart_core (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.baud_int_i (s_baud_int),
.baud_frac_i (s_baud_frac),
.data_bits_i (s_data_bits),
.stop2_i (s_stop2),
.parity_i (s_parity),
.tx_enable_i (s_tx_enable),
.rx_enable_i (s_rx_enable),
.loopback_i (s_loopback),
.break_i (s_break),
.tx_data_valid_i(s_tx_data_valid),
.tx_data_i (s_tx_data),
.tx_data_pop_o (s_tx_data_pop),
.tx_busy_o (s_tx_busy),
.tx_done_o (s_tx_done),
.rx_active_o (s_rx_active),
.rx_data_valid_o(s_rx_data_valid),
.rx_data_o (s_rx_data),
.bit_tick_o (s_bit_tick),
.rx_i (uart.rx_i),
.tx_o (s_tx)
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.baud_int_i (s_baud_int),
.baud_frac_i (s_baud_frac),
.data_bits_i (s_data_bits),
.stop2_i (s_stop2),
.parity_i (s_parity),
.tx_enable_i (s_tx_enable),
.rx_enable_i (s_rx_enable),
.loopback_i (s_loopback),
.tx_start_allowed_i(s_tx_start_allowed),
.break_i (s_break),
.tx_data_valid_i (s_tx_data_valid),
.tx_data_i (s_tx_data),
.tx_data_pop_o (s_tx_data_pop),
.tx_busy_o (s_tx_busy),
.tx_done_o (s_tx_done),
.rx_active_o (s_rx_active),
.rx_data_valid_o (s_rx_data_valid),
.rx_data_o (s_rx_data),
.bit_tick_o (s_bit_tick),
.rx_i (uart.rx_i),
.tx_o (s_tx)
);
uart_flow_ctrl u_uart_flow_ctrl (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.cts_n_async_i (uart.cts_n_i),
.auto_cts_enable_i (s_auto_cts_enable),
.auto_rts_enable_i (s_auto_rts_enable),
.tx_enable_i (s_tx_enable),
.rx_enable_i (s_rx_enable),
.loopback_i (s_loopback),
.tx_data_valid_i (s_tx_data_valid),
.tx_busy_i (s_tx_busy),
.rx_level_i (s_rx_level),
.rts_assert_level_i (s_rts_assert_level),
.rts_deassert_level_i(s_rts_deassert_level),
.cts_asserted_o (s_cts_asserted),
.rts_asserted_o (s_rts_asserted),
.tx_start_allowed_o (s_tx_start_allowed),
.tx_flow_blocked_o (s_tx_flow_blocked),
.cts_change_o (s_cts_change),
.rts_n_o (uart.rts_n_o)
);
endmodule
+12
View File
@@ -23,6 +23,8 @@
`define RIBP_UART_INTR_STATUS 8'h3C
`define RIBP_UART_INTR_TEST 8'h40
`define RIBP_UART_DMA_CTRL 8'h44
`define RIBP_UART_FLOW_CTRL 8'h48
`define RIBP_UART_RTS_WATERMARK 8'h4C
`define RIBP_UART_IP_VERSION 8'hF8
`define RIBP_UART_CAPABILITY 8'hFC
@@ -50,6 +52,9 @@
`define UART_STATUS_BREAK_ACTIVE 9
`define UART_STATUS_TX_DMA_REQ 10
`define UART_STATUS_RX_DMA_REQ 11
`define UART_STATUS_CTS_ASSERTED 12
`define UART_STATUS_RTS_ASSERTED 13
`define UART_STATUS_TX_FLOW_BLOCKED 14
`define UART_RXDATA_PARITY_ERROR 8
`define UART_RXDATA_FRAME_ERROR 9
@@ -70,9 +75,16 @@
`define UART_INTR_TX_DONE 3
`define UART_INTR_RX_ERROR 4
`define UART_INTR_BREAK 5
`define UART_INTR_CTS_CHANGE 6
`define UART_DMA_TX_ENABLE 0
`define UART_DMA_RX_ENABLE 1
`define UART_FLOW_AUTO_CTS_ENABLE 0
`define UART_FLOW_AUTO_RTS_ENABLE 1
`define UART_RTS_ASSERT_LEVEL 0
`define UART_RTS_DEASSERT_LEVEL 16
// verilog_format: on
`endif
+3 -1
View File
@@ -7,6 +7,7 @@ module ribp_uart_tx (
input logic rst_n_i,
input logic sample_tick_i,
input logic enable_i,
input logic start_allowed_i,
input logic break_i,
input logic [1:0] data_bits_i,
input logic stop2_i,
@@ -68,7 +69,8 @@ module ribp_uart_tx (
data_pop_o = 1'b0;
done_o = 1'b0;
if ((s_state_q == STATE_IDLE) && enable_i && !break_i && data_valid_i && sample_tick_i) begin
if ((s_state_q == STATE_IDLE) && enable_i && start_allowed_i && !break_i && data_valid_i &&
sample_tick_i) begin
s_state_d = STATE_START;
s_sample_d = '0;
s_bit_d = '0;
+16 -14
View File
@@ -13,6 +13,7 @@ module uart_core (
input logic tx_enable_i,
input logic rx_enable_i,
input logic loopback_i,
input logic tx_start_allowed_i,
input logic break_i,
input logic tx_data_valid_i,
input logic [ 7:0] tx_data_i,
@@ -46,20 +47,21 @@ module uart_core (
);
ribp_uart_tx u_ribp_uart_tx (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.sample_tick_i(s_sample_tick),
.enable_i (tx_enable_i),
.break_i (break_i),
.data_bits_i (data_bits_i),
.stop2_i (stop2_i),
.parity_i (parity_i),
.data_valid_i (tx_data_valid_i),
.data_i (tx_data_i),
.data_pop_o (tx_data_pop_o),
.busy_o (tx_busy_o),
.done_o (tx_done_o),
.tx_o (s_tx)
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.sample_tick_i (s_sample_tick),
.enable_i (tx_enable_i),
.start_allowed_i(tx_start_allowed_i),
.break_i (break_i),
.data_bits_i (data_bits_i),
.stop2_i (stop2_i),
.parity_i (parity_i),
.data_valid_i (tx_data_valid_i),
.data_i (tx_data_i),
.data_pop_o (tx_data_pop_o),
.busy_o (tx_busy_o),
.done_o (tx_done_o),
.tx_o (s_tx)
);
ribp_uart_rx u_ribp_uart_rx (
+70
View File
@@ -0,0 +1,70 @@
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
module uart_flow_ctrl (
// verilog_format: off
input logic clk_i,
input logic rst_n_i,
input logic cts_n_async_i,
input logic auto_cts_enable_i,
input logic auto_rts_enable_i,
input logic tx_enable_i,
input logic rx_enable_i,
input logic loopback_i,
input logic tx_data_valid_i,
input logic tx_busy_i,
input logic [6:0] rx_level_i,
input logic [6:0] rts_assert_level_i,
input logic [6:0] rts_deassert_level_i,
output logic cts_asserted_o,
output logic rts_asserted_o,
output logic tx_start_allowed_o,
output logic tx_flow_blocked_o,
output logic cts_change_o,
output logic rts_n_o
// verilog_format: on
);
logic s_cts_rise;
logic s_cts_fall;
logic s_rts_asserted_d, s_rts_asserted_q;
// Synchronize the logical asserted state so reset is fail-safe: not clear to send.
edge_det #(
.STAGE (2),
.DATA_WIDTH(1)
) u_cts_edge_det (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (~cts_n_async_i),
.dat_o (cts_asserted_o),
.re_o (s_cts_rise),
.fe_o (s_cts_fall)
);
always_comb begin
s_rts_asserted_d = s_rts_asserted_q;
if (!auto_rts_enable_i || !rx_enable_i) begin
s_rts_asserted_d = 1'b0;
end else if (rx_level_i >= rts_deassert_level_i) begin
s_rts_asserted_d = 1'b0;
end else if (rx_level_i <= rts_assert_level_i) begin
s_rts_asserted_d = 1'b1;
end
end
dffr #(1) u_rts_asserted_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_rts_asserted_d),
.dat_o (s_rts_asserted_q)
);
assign rts_asserted_o = auto_rts_enable_i && rx_enable_i && s_rts_asserted_q;
assign rts_n_o = ~rts_asserted_o;
assign tx_start_allowed_o = loopback_i || !auto_cts_enable_i || cts_asserted_o;
assign tx_flow_blocked_o = auto_cts_enable_i && tx_enable_i && tx_data_valid_i &&
!tx_busy_i && !cts_asserted_o && !loopback_i;
assign cts_change_o = auto_cts_enable_i && (s_cts_rise || s_cts_fall);
endmodule
+14
View File
@@ -0,0 +1,14 @@
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
interface uart_if ();
logic rx_i;
logic cts_n_i;
logic tx_o;
logic rts_n_o;
logic irq_o;
modport dut(input rx_i, input cts_n_i, output tx_o, output rts_n_o, output irq_o);
modport tb(output rx_i, output cts_n_i, input tx_o, input rts_n_o, input irq_o);
endinterface
+164 -78
View File
@@ -22,8 +22,13 @@ module uart_reg #(
output logic rx_enable_o,
output logic loopback_o,
output logic break_o,
output logic auto_cts_enable_o,
output logic auto_rts_enable_o,
output logic [ 6:0] rts_assert_level_o,
output logic [ 6:0] rts_deassert_level_o,
output logic tx_data_valid_o,
output logic [ 7:0] tx_data_o,
output logic [ 6:0] rx_level_o,
input logic tx_data_pop_i,
input logic tx_busy_i,
input logic tx_done_i,
@@ -31,6 +36,10 @@ module uart_reg #(
input logic rx_data_valid_i,
input logic [11:0] rx_data_i,
input logic bit_tick_i,
input logic cts_asserted_i,
input logic rts_asserted_i,
input logic tx_flow_blocked_i,
input logic cts_change_i,
output logic dma_tx_stall_o,
output logic dma_rx_stall_o,
output logic irq_o
@@ -41,8 +50,10 @@ module uart_reg #(
localparam logic [31:0] RX_WATERMARK_RESET = 32'd32;
localparam logic [31:0] RX_TIMEOUT_RESET = 32'd32;
localparam logic [31:0] LINE_CTRL_RESET = 32'd3;
localparam logic [31:0] IP_VERSION = 32'h0002_0000;
localparam logic [31:0] CAPABILITY = 32'h00FF_4040;
localparam logic [31:0] RTS_ASSERT_LEVEL_RESET = 32'd32;
localparam logic [31:0] RTS_DEASSERT_LEVEL_RESET = 32'd48;
localparam logic [31:0] IP_VERSION = 32'h0003_0000;
localparam logic [31:0] CAPABILITY = 32'h03FF_4040;
logic s_req;
logic s_write;
@@ -67,9 +78,14 @@ module uart_reg #(
logic s_rx_timeout_en;
logic [15:0] s_rx_timeout_d, s_rx_timeout_q;
logic s_intr_enable_en;
logic [5:0] s_intr_enable_d, s_intr_enable_q;
logic [6:0] s_intr_enable_d, s_intr_enable_q;
logic s_dma_ctrl_en;
logic [1:0] s_dma_ctrl_d, s_dma_ctrl_q;
logic s_flow_ctrl_en;
logic [1:0] s_flow_ctrl_d, s_flow_ctrl_q;
logic s_rts_watermark_en;
logic [6:0] s_rts_assert_level_d, s_rts_assert_level_q;
logic [6:0] s_rts_deassert_level_d, s_rts_deassert_level_q;
logic s_tx_flush;
logic s_tx_push;
@@ -86,10 +102,10 @@ module uart_reg #(
logic [RX_FIFO_LOG_DEPTH:0] s_rx_count;
logic [6:0] s_error_status_d, s_error_status_q;
logic [5:0] s_intr_state_d, s_intr_state_q;
logic [6:0] s_intr_state_d, s_intr_state_q;
logic [6:0] s_error_clear;
logic [5:0] s_intr_clear;
logic [5:0] s_intr_test;
logic [6:0] s_intr_clear;
logic [6:0] s_intr_test;
logic s_config_error_event;
logic s_command_error_event;
logic s_overrun_event;
@@ -123,7 +139,7 @@ module uart_reg #(
initial begin
if ((TX_FIFO_DEPTH != 64) || (RX_FIFO_DEPTH != 64)) begin
$fatal(1, "uart_reg: UART V2 requires 64-entry FIFOs");
$fatal(1, "uart_reg: UART V3 requires 64-entry FIFOs");
end
end
@@ -142,8 +158,13 @@ module uart_reg #(
assign rx_enable_o = s_ctrl_q[`UART_CTRL_RX_ENABLE];
assign loopback_o = s_ctrl_q[`UART_CTRL_LOOPBACK];
assign break_o = s_ctrl_q[`UART_CTRL_TX_BREAK];
assign auto_cts_enable_o = s_flow_ctrl_q[`UART_FLOW_AUTO_CTS_ENABLE];
assign auto_rts_enable_o = s_flow_ctrl_q[`UART_FLOW_AUTO_RTS_ENABLE];
assign rts_assert_level_o = s_rts_assert_level_q;
assign rts_deassert_level_o = s_rts_deassert_level_q;
assign tx_data_valid_o = !s_tx_empty;
assign tx_data_o = s_tx_pop_data;
assign rx_level_o = 7'(s_rx_count);
assign s_config_valid = (s_baud_int_q >= 24'd16) && (s_line_ctrl_q[4:3] != 2'd3);
assign s_tx_dma_req = s_dma_ctrl_q[`UART_DMA_TX_ENABLE] && tx_enable_o &&
@@ -156,56 +177,64 @@ module uart_reg #(
assign irq_o = |(s_intr_state_q & s_intr_enable_q);
always_comb begin
s_status = '0;
s_status[`UART_STATUS_TX_ENABLED] = tx_enable_o;
s_status[`UART_STATUS_RX_ENABLED] = rx_enable_o;
s_status[`UART_STATUS_TX_BUSY] = tx_busy_i;
s_status[`UART_STATUS_RX_ACTIVE] = rx_active_i;
s_status[`UART_STATUS_TX_EMPTY] = s_tx_empty;
s_status[`UART_STATUS_TX_FULL] = s_tx_full;
s_status[`UART_STATUS_RX_EMPTY] = s_rx_empty;
s_status[`UART_STATUS_RX_FULL] = s_rx_full;
s_status[`UART_STATUS_CONFIG_VALID] = s_config_valid;
s_status[`UART_STATUS_BREAK_ACTIVE] = break_o;
s_status[`UART_STATUS_TX_DMA_REQ] = s_tx_dma_req;
s_status[`UART_STATUS_RX_DMA_REQ] = s_rx_dma_req;
s_fifo_level = '0;
s_fifo_level[6:0] = 7'(s_tx_count);
s_fifo_level[22:16] = 7'(s_rx_count);
s_status = '0;
s_status[`UART_STATUS_TX_ENABLED] = tx_enable_o;
s_status[`UART_STATUS_RX_ENABLED] = rx_enable_o;
s_status[`UART_STATUS_TX_BUSY] = tx_busy_i;
s_status[`UART_STATUS_RX_ACTIVE] = rx_active_i;
s_status[`UART_STATUS_TX_EMPTY] = s_tx_empty;
s_status[`UART_STATUS_TX_FULL] = s_tx_full;
s_status[`UART_STATUS_RX_EMPTY] = s_rx_empty;
s_status[`UART_STATUS_RX_FULL] = s_rx_full;
s_status[`UART_STATUS_CONFIG_VALID] = s_config_valid;
s_status[`UART_STATUS_BREAK_ACTIVE] = break_o;
s_status[`UART_STATUS_TX_DMA_REQ] = s_tx_dma_req;
s_status[`UART_STATUS_RX_DMA_REQ] = s_rx_dma_req;
s_status[`UART_STATUS_CTS_ASSERTED] = cts_asserted_i;
s_status[`UART_STATUS_RTS_ASSERTED] = rts_asserted_i;
s_status[`UART_STATUS_TX_FLOW_BLOCKED] = tx_flow_blocked_i;
s_fifo_level = '0;
s_fifo_level[6:0] = 7'(s_tx_count);
s_fifo_level[22:16] = 7'(s_rx_count);
end
always_comb begin
s_req_accept = s_req;
s_access_error = 1'b0;
s_baud_int_en = 1'b0;
s_baud_frac_en = 1'b0;
s_line_ctrl_en = 1'b0;
s_ctrl_en = 1'b0;
s_tx_watermark_en = 1'b0;
s_rx_watermark_en = 1'b0;
s_rx_timeout_en = 1'b0;
s_intr_enable_en = 1'b0;
s_dma_ctrl_en = 1'b0;
s_baud_int_d = s_baud_int_q;
s_baud_frac_d = s_baud_frac_q;
s_line_ctrl_d = s_line_ctrl_q;
s_ctrl_d = s_ctrl_q;
s_tx_watermark_d = s_tx_watermark_q;
s_rx_watermark_d = s_rx_watermark_q;
s_rx_timeout_d = s_rx_timeout_q;
s_intr_enable_d = s_intr_enable_q;
s_dma_ctrl_d = s_dma_ctrl_q;
s_tx_flush = 1'b0;
s_rx_flush = 1'b0;
s_tx_push = 1'b0;
s_rx_pop = 1'b0;
s_error_clear = '0;
s_intr_clear = '0;
s_intr_test = '0;
s_config_error_event = 1'b0;
s_command_error_event = 1'b0;
s_ribp_rdata_d = '0;
s_merge_value = '0;
s_req_accept = s_req;
s_access_error = 1'b0;
s_baud_int_en = 1'b0;
s_baud_frac_en = 1'b0;
s_line_ctrl_en = 1'b0;
s_ctrl_en = 1'b0;
s_tx_watermark_en = 1'b0;
s_rx_watermark_en = 1'b0;
s_rx_timeout_en = 1'b0;
s_intr_enable_en = 1'b0;
s_dma_ctrl_en = 1'b0;
s_flow_ctrl_en = 1'b0;
s_rts_watermark_en = 1'b0;
s_baud_int_d = s_baud_int_q;
s_baud_frac_d = s_baud_frac_q;
s_line_ctrl_d = s_line_ctrl_q;
s_ctrl_d = s_ctrl_q;
s_tx_watermark_d = s_tx_watermark_q;
s_rx_watermark_d = s_rx_watermark_q;
s_rx_timeout_d = s_rx_timeout_q;
s_intr_enable_d = s_intr_enable_q;
s_dma_ctrl_d = s_dma_ctrl_q;
s_flow_ctrl_d = s_flow_ctrl_q;
s_rts_assert_level_d = s_rts_assert_level_q;
s_rts_deassert_level_d = s_rts_deassert_level_q;
s_tx_flush = 1'b0;
s_rx_flush = 1'b0;
s_tx_push = 1'b0;
s_rx_pop = 1'b0;
s_error_clear = '0;
s_intr_clear = '0;
s_intr_test = '0;
s_config_error_event = 1'b0;
s_command_error_event = 1'b0;
s_ribp_rdata_d = '0;
s_merge_value = '0;
if (s_req) begin
if ((ribp.addr[11:8] != 4'd0) || (ribp.addr[1:0] != 2'b00)) begin
@@ -325,26 +354,26 @@ module uart_reg #(
end
end
`RIBP_UART_INTR_STATE: begin
if (!ribp.wstrb[0] || (ribp.wdata[31:6] != 26'd0)) begin
if (!ribp.wstrb[0] || (ribp.wdata[31:7] != 25'd0)) begin
s_access_error = 1'b1;
end else begin
s_intr_clear = ribp.wdata[5:0];
s_intr_clear = ribp.wdata[6:0];
end
end
`RIBP_UART_INTR_ENABLE: begin
s_merge_value = merge_wstrb({26'd0, s_intr_enable_q}, ribp.wdata, ribp.wstrb);
if (s_merge_value[31:6] != 26'd0) begin
s_merge_value = merge_wstrb({25'd0, s_intr_enable_q}, ribp.wdata, ribp.wstrb);
if (s_merge_value[31:7] != 25'd0) begin
s_access_error = 1'b1;
end else begin
s_intr_enable_en = 1'b1;
s_intr_enable_d = s_merge_value[5:0];
s_intr_enable_d = s_merge_value[6:0];
end
end
`RIBP_UART_INTR_TEST: begin
if (!ribp.wstrb[0] || (ribp.wdata[31:6] != 26'd0)) begin
if (!ribp.wstrb[0] || (ribp.wdata[31:7] != 25'd0)) begin
s_access_error = 1'b1;
end else begin
s_intr_test = ribp.wdata[5:0];
s_intr_test = ribp.wdata[6:0];
end
end
`RIBP_UART_DMA_CTRL: begin
@@ -357,14 +386,40 @@ module uart_reg #(
s_dma_ctrl_d = s_merge_value[1:0];
end
end
`RIBP_UART_FLOW_CTRL: begin
s_merge_value = merge_wstrb({30'd0, s_flow_ctrl_q}, ribp.wdata, ribp.wstrb);
if (tx_enable_o || rx_enable_o || tx_busy_i || rx_active_i ||
(s_merge_value[31:2] != 30'd0)) begin
s_access_error = 1'b1;
s_config_error_event = 1'b1;
end else begin
s_flow_ctrl_en = 1'b1;
s_flow_ctrl_d = s_merge_value[1:0];
end
end
`RIBP_UART_RTS_WATERMARK: begin
s_merge_value = merge_wstrb({9'd0, s_rts_deassert_level_q, 9'd0, s_rts_assert_level_q},
ribp.wdata, ribp.wstrb);
if (tx_enable_o || rx_enable_o || tx_busy_i || rx_active_i ||
(s_merge_value[31:23] != 9'd0) || (s_merge_value[15:7] != 9'd0) ||
(s_merge_value[22:16] > 7'(RX_FIFO_DEPTH)) ||
(s_merge_value[6:0] >= s_merge_value[22:16])) begin
s_access_error = 1'b1;
s_config_error_event = 1'b1;
end else begin
s_rts_watermark_en = 1'b1;
s_rts_assert_level_d = s_merge_value[6:0];
s_rts_deassert_level_d = s_merge_value[22:16];
end
end
default: s_access_error = 1'b1;
endcase
end else begin
unique case (ribp.addr[7:0])
`RIBP_UART_BAUD_INT: s_ribp_rdata_d = {8'd0, s_baud_int_q};
`RIBP_UART_BAUD_FRAC: s_ribp_rdata_d = {24'd0, s_baud_frac_q};
`RIBP_UART_LINE_CTRL: s_ribp_rdata_d = {27'd0, s_line_ctrl_q};
`RIBP_UART_CTRL: s_ribp_rdata_d = {28'd0, s_ctrl_q};
`RIBP_UART_BAUD_INT: s_ribp_rdata_d = {8'd0, s_baud_int_q};
`RIBP_UART_BAUD_FRAC: s_ribp_rdata_d = {24'd0, s_baud_frac_q};
`RIBP_UART_LINE_CTRL: s_ribp_rdata_d = {27'd0, s_line_ctrl_q};
`RIBP_UART_CTRL: s_ribp_rdata_d = {28'd0, s_ctrl_q};
`RIBP_UART_RXDATA: begin
if (s_rx_empty) begin
s_access_error = 1'b1;
@@ -374,18 +429,21 @@ module uart_reg #(
s_rx_pop = 1'b1;
end
end
`RIBP_UART_STATUS: s_ribp_rdata_d = s_status;
`RIBP_UART_FIFO_LEVEL: s_ribp_rdata_d = s_fifo_level;
`RIBP_UART_TX_WATERMARK: s_ribp_rdata_d = {25'd0, s_tx_watermark_q};
`RIBP_UART_RX_WATERMARK: s_ribp_rdata_d = {25'd0, s_rx_watermark_q};
`RIBP_UART_STATUS: s_ribp_rdata_d = s_status;
`RIBP_UART_FIFO_LEVEL: s_ribp_rdata_d = s_fifo_level;
`RIBP_UART_TX_WATERMARK: s_ribp_rdata_d = {25'd0, s_tx_watermark_q};
`RIBP_UART_RX_WATERMARK: s_ribp_rdata_d = {25'd0, s_rx_watermark_q};
`RIBP_UART_RX_TIMEOUT_BITS: s_ribp_rdata_d = {16'd0, s_rx_timeout_q};
`RIBP_UART_ERROR_STATUS: s_ribp_rdata_d = {25'd0, s_error_status_q};
`RIBP_UART_INTR_STATE: s_ribp_rdata_d = {26'd0, s_intr_state_q};
`RIBP_UART_INTR_ENABLE: s_ribp_rdata_d = {26'd0, s_intr_enable_q};
`RIBP_UART_INTR_STATUS: s_ribp_rdata_d = {26'd0, (s_intr_state_q & s_intr_enable_q)};
`RIBP_UART_DMA_CTRL: s_ribp_rdata_d = {30'd0, s_dma_ctrl_q};
`RIBP_UART_IP_VERSION: s_ribp_rdata_d = IP_VERSION;
`RIBP_UART_CAPABILITY: s_ribp_rdata_d = CAPABILITY;
`RIBP_UART_ERROR_STATUS: s_ribp_rdata_d = {25'd0, s_error_status_q};
`RIBP_UART_INTR_STATE: s_ribp_rdata_d = {25'd0, s_intr_state_q};
`RIBP_UART_INTR_ENABLE: s_ribp_rdata_d = {25'd0, s_intr_enable_q};
`RIBP_UART_INTR_STATUS: s_ribp_rdata_d = {25'd0, (s_intr_state_q & s_intr_enable_q)};
`RIBP_UART_DMA_CTRL: s_ribp_rdata_d = {30'd0, s_dma_ctrl_q};
`RIBP_UART_FLOW_CTRL: s_ribp_rdata_d = {30'd0, s_flow_ctrl_q};
`RIBP_UART_RTS_WATERMARK:
s_ribp_rdata_d = {9'd0, s_rts_deassert_level_q, 9'd0, s_rts_assert_level_q};
`RIBP_UART_IP_VERSION: s_ribp_rdata_d = IP_VERSION;
`RIBP_UART_CAPABILITY: s_ribp_rdata_d = CAPABILITY;
default: begin
s_access_error = 1'b1;
s_ribp_rdata_d = '0;
@@ -483,7 +541,7 @@ module uart_reg #(
.dat_i (s_rx_timeout_d),
.dat_o (s_rx_timeout_q)
);
dffer #(6) u_intr_enable_dffer (
dffer #(7) u_intr_enable_dffer (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.en_i (s_intr_enable_en),
@@ -497,6 +555,33 @@ module uart_reg #(
.dat_i (s_dma_ctrl_d),
.dat_o (s_dma_ctrl_q)
);
dffer #(2) u_flow_ctrl_dffer (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.en_i (s_flow_ctrl_en),
.dat_i (s_flow_ctrl_d),
.dat_o (s_flow_ctrl_q)
);
dfferc #(
.DATA_WIDTH(7),
.RESET_VAL (7'(RTS_ASSERT_LEVEL_RESET))
) u_rts_assert_level_dfferc (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.en_i (s_rts_watermark_en),
.dat_i (s_rts_assert_level_d),
.dat_o (s_rts_assert_level_q)
);
dfferc #(
.DATA_WIDTH(7),
.RESET_VAL (7'(RTS_DEASSERT_LEVEL_RESET))
) u_rts_deassert_level_dfferc (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.en_i (s_rts_watermark_en),
.dat_i (s_rts_deassert_level_d),
.dat_o (s_rts_deassert_level_q)
);
fifo #(
.DATA_WIDTH (8),
@@ -580,8 +665,9 @@ module uart_reg #(
if (tx_done_i && s_tx_empty) s_intr_state_d[`UART_INTR_TX_DONE] = 1'b1;
if (s_rx_error_event || s_overrun_event) s_intr_state_d[`UART_INTR_RX_ERROR] = 1'b1;
if (s_rx_push && rx_data_i[`UART_RXDATA_BREAK]) s_intr_state_d[`UART_INTR_BREAK] = 1'b1;
if (cts_change_i) s_intr_state_d[`UART_INTR_CTS_CHANGE] = 1'b1;
end
dffr #(6) u_intr_state_dffr (
dffr #(7) u_intr_state_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_intr_state_d),
+71
View File
@@ -0,0 +1,71 @@
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
`timescale 1ns / 1ps
module uart_model #(
parameter int BAUD_RATE = 115200,
parameter bit LOOPBACK = 1'b0,
parameter bit FLOW_CONTROL = 1'b0
) (
// verilog_format: off
input logic uart_tx_i,
input logic uart_rts_n_i,
output logic uart_rx_o,
output logic uart_cts_n_o
// verilog_format: on
);
localparam time BIT_PERIOD_NS = 1_000_000_000 / BAUD_RATE;
logic [7:0] s_data;
initial begin
uart_rx_o = 1'b1;
uart_cts_n_o = FLOW_CONTROL ? 1'b0 : 1'bz;
end
always @(negedge uart_tx_i) begin
receive(s_data);
$write("%c", s_data);
if (LOOPBACK) begin
send(s_data);
end
end
task automatic receive(output logic [7:0] value);
begin
value = '0;
#(BIT_PERIOD_NS + (BIT_PERIOD_NS / 2));
for (int bit_index = 0; bit_index < 8; bit_index++) begin
value[bit_index] = uart_tx_i;
#(BIT_PERIOD_NS);
end
end
endtask
task automatic send(input logic [7:0] value);
begin
if (FLOW_CONTROL) begin
wait (uart_rts_n_i === 1'b0);
end
uart_rx_o = 1'b0;
#(BIT_PERIOD_NS);
for (int bit_index = 0; bit_index < 8; bit_index++) begin
uart_rx_o = value[bit_index];
#(BIT_PERIOD_NS);
end
uart_rx_o = 1'b1;
#(BIT_PERIOD_NS);
end
endtask
task automatic set_cts(input logic asserted);
begin
if (FLOW_CONTROL) begin
uart_cts_n_o = ~asserted;
end
end
endtask
endmodule
+10 -7
View File
@@ -33,8 +33,7 @@ module retrosoc_tb;
wire s_jtag_tdi;
wire s_jtag_trst_n;
wire s_uart0_tx;
// for handle x-prop issue
wire s_uart0_rx = 1'b1;
wire s_uart0_rx;
tri1 s_gpio_0_io;
tri1 s_gpio_1_io;
wire s_psram_sck;
@@ -135,11 +134,15 @@ module retrosoc_tb;
);
rs232 #(
.BAUD_RATE(921600)
) u_rs232_0 (
.rs232_rx_i(s_uart0_tx),
.rs232_tx_o()
uart_model #(
.BAUD_RATE (921600),
.LOOPBACK (1'b0),
.FLOW_CONTROL(1'b0)
) u_uart_model_0 (
.uart_tx_i (s_uart0_tx),
.uart_rts_n_i(s_gpio_1_io),
.uart_rx_o (s_uart0_rx),
.uart_cts_n_o(s_gpio_0_io)
);
-1
View File
@@ -4,7 +4,6 @@
/clusterip/rng/rtl/rng_reg.sv
/clusterip/rng/rtl/rng_deterministic_source.sv
/clusterip/rng/rtl/apb4_rng.sv
/clusterip/uart/rtl/uart_if.sv
/clusterip/pwm/rtl/pwm_pkg.sv
/clusterip/pwm/rtl/pwm_tickgen.sv
/clusterip/pwm/rtl/pwm_timer.sv
-1
View File
@@ -7,7 +7,6 @@
+incdir+/clusterip/common/rtl/utils
+incdir+/clusterip/archinfo/rtl
+incdir+/clusterip/rng/rtl
+incdir+/clusterip/uart/rtl
+incdir+/clusterip/pwm/rtl
+incdir+/clusterip/ps2/rtl
+incdir+/clusterip/i2c/rtl
+2
View File
@@ -25,9 +25,11 @@
/ip/ribp/serial/ws2812_reg.sv
/ip/ribp/serial/ws2812_core.sv
/ip/ribp/serial/ribp_ws2812.sv
/ip/ribp/serial/uart_if.sv
/ip/ribp/serial/uart_baudgen.sv
/ip/ribp/serial/ribp_uart_tx.sv
/ip/ribp/serial/ribp_uart_rx.sv
/ip/ribp/serial/uart_flow_ctrl.sv
/ip/ribp/serial/uart_core.sv
/ip/ribp/serial/uart_reg.sv
/ip/ribp/serial/ribp_uart.sv
+1 -1
View File
@@ -1,6 +1,6 @@
/clusterip/ps2/dv/model/ps2_device_model.sv
/clusterip/i2c/model/at24cxxx.sv
/clusterip/uart/model/rs232.sv
/model/uart_model.sv
/clusterip/i2s/model/mic.sv
/clusterip/spi/model/w25q128jvxim.sv
/model/ESP_PSRAM64H.sv
+4 -1
View File
@@ -111,12 +111,15 @@ def source_files(target: str) -> list[Path]:
if target == "uart":
return [
COMMON_RTL / "interface/ribp_if.sv",
COMMON_RTL / "cdc/cdc_sync.sv",
COMMON_RTL / "utils/register.sv",
COMMON_RTL / "utils/edge_det.sv",
COMMON_RTL / "utils/fifo.sv",
ROOT / "rtl/managed/clusterip/uart/rtl/uart_if.sv",
SERIAL / "uart_if.sv",
SERIAL / "uart_baudgen.sv",
SERIAL / "ribp_uart_tx.sv",
SERIAL / "ribp_uart_rx.sv",
SERIAL / "uart_flow_ctrl.sv",
SERIAL / "uart_core.sv",
SERIAL / "uart_reg.sv",
SERIAL / "ribp_uart.sv",
+43 -25
View File
@@ -15,16 +15,24 @@ module uart_formal_design (
output logic [ 6:0] tx_count,
output logic [ 6:0] rx_count,
output logic [ 6:0] error_status,
output logic [ 5:0] intr_state,
output logic [ 5:0] intr_enable,
output logic [ 6:0] intr_state,
output logic [ 6:0] intr_enable,
output logic tx_enable,
output logic rx_enable,
output logic tx_busy,
output logic rx_active,
output logic break_active,
output logic auto_cts_enable,
output logic auto_rts_enable,
output logic cts_asserted,
output logic rts_asserted,
output logic tx_start_allowed,
output logic tx_flow_blocked,
output logic tx_data_pop,
output logic tx_dma_stall,
output logic rx_dma_stall,
output logic tx,
output logic rts_n,
output logic irq
// verilog_format: on
);
@@ -37,31 +45,41 @@ module uart_formal_design (
(* anyseq *)logic [31:0] f_rib_wdata;
(* anyseq *)logic [ 3:0] f_rib_wstrb;
(* anyseq *)logic f_uart_rx;
(* anyseq *)logic f_uart_cts_n;
assign ribp.valid = f_rib_valid;
assign ribp.addr = f_rib_addr;
assign ribp.wdata = f_rib_wdata;
assign ribp.wstrb = f_rib_wstrb;
assign uart.rx_i = f_uart_rx;
assign ribp.valid = f_rib_valid;
assign ribp.addr = f_rib_addr;
assign ribp.wdata = f_rib_wdata;
assign ribp.wstrb = f_rib_wstrb;
assign uart.rx_i = f_uart_rx;
assign uart.cts_n_i = f_uart_cts_n;
assign rib_valid = ribp.valid;
assign rib_addr = ribp.addr;
assign rib_wdata = ribp.wdata;
assign rib_wstrb = ribp.wstrb;
assign rib_ready = ribp.ready;
assign rib_resp_err = ribp.resp_err;
assign tx_count = u_dut.u_uart_reg.s_tx_count;
assign rx_count = u_dut.u_uart_reg.s_rx_count;
assign error_status = u_dut.u_uart_reg.s_error_status_q;
assign intr_state = u_dut.u_uart_reg.s_intr_state_q;
assign intr_enable = u_dut.u_uart_reg.s_intr_enable_q;
assign tx_enable = u_dut.s_tx_enable;
assign rx_enable = u_dut.s_rx_enable;
assign tx_busy = u_dut.s_tx_busy;
assign rx_active = u_dut.s_rx_active;
assign break_active = u_dut.s_break;
assign tx = uart.tx_o;
assign irq = uart.irq_o;
assign rib_valid = ribp.valid;
assign rib_addr = ribp.addr;
assign rib_wdata = ribp.wdata;
assign rib_wstrb = ribp.wstrb;
assign rib_ready = ribp.ready;
assign rib_resp_err = ribp.resp_err;
assign tx_count = u_dut.u_uart_reg.s_tx_count;
assign rx_count = u_dut.u_uart_reg.s_rx_count;
assign error_status = u_dut.u_uart_reg.s_error_status_q;
assign intr_state = u_dut.u_uart_reg.s_intr_state_q;
assign intr_enable = u_dut.u_uart_reg.s_intr_enable_q;
assign tx_enable = u_dut.s_tx_enable;
assign rx_enable = u_dut.s_rx_enable;
assign tx_busy = u_dut.s_tx_busy;
assign rx_active = u_dut.s_rx_active;
assign break_active = u_dut.s_break;
assign auto_cts_enable = u_dut.s_auto_cts_enable;
assign auto_rts_enable = u_dut.s_auto_rts_enable;
assign cts_asserted = u_dut.s_cts_asserted;
assign rts_asserted = u_dut.s_rts_asserted;
assign tx_start_allowed = u_dut.s_tx_start_allowed;
assign tx_flow_blocked = u_dut.s_tx_flow_blocked;
assign tx_data_pop = u_dut.s_tx_data_pop;
assign tx = uart.tx_o;
assign rts_n = uart.rts_n_o;
assign irq = uart.irq_o;
ribp_uart u_dut (
.clk_i (clk_i),
+51 -25
View File
@@ -14,42 +14,58 @@ module uart_formal;
wire [ 6:0] tx_count;
wire [ 6:0] rx_count;
wire [ 6:0] error_status;
wire [ 5:0] intr_state;
wire [ 5:0] intr_enable;
wire [ 6:0] intr_state;
wire [ 6:0] intr_enable;
wire tx_enable;
wire rx_enable;
wire tx_busy;
wire rx_active;
wire break_active;
wire auto_cts_enable;
wire auto_rts_enable;
wire cts_asserted;
wire rts_asserted;
wire tx_start_allowed;
wire tx_flow_blocked;
wire tx_data_pop;
wire tx_dma_stall;
wire rx_dma_stall;
wire tx;
wire rts_n;
wire irq;
uart_formal_design u_design (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.f_past_valid(f_past_valid),
.rib_valid (rib_valid),
.rib_addr (rib_addr),
.rib_wdata (rib_wdata),
.rib_wstrb (rib_wstrb),
.rib_ready (rib_ready),
.rib_resp_err(rib_resp_err),
.tx_count (tx_count),
.rx_count (rx_count),
.error_status(error_status),
.intr_state (intr_state),
.intr_enable (intr_enable),
.tx_enable (tx_enable),
.rx_enable (rx_enable),
.tx_busy (tx_busy),
.rx_active (rx_active),
.break_active(break_active),
.tx_dma_stall(tx_dma_stall),
.rx_dma_stall(rx_dma_stall),
.tx (tx),
.irq (irq)
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.f_past_valid (f_past_valid),
.rib_valid (rib_valid),
.rib_addr (rib_addr),
.rib_wdata (rib_wdata),
.rib_wstrb (rib_wstrb),
.rib_ready (rib_ready),
.rib_resp_err (rib_resp_err),
.tx_count (tx_count),
.rx_count (rx_count),
.error_status (error_status),
.intr_state (intr_state),
.intr_enable (intr_enable),
.tx_enable (tx_enable),
.rx_enable (rx_enable),
.tx_busy (tx_busy),
.rx_active (rx_active),
.break_active (break_active),
.auto_cts_enable (auto_cts_enable),
.auto_rts_enable (auto_rts_enable),
.cts_asserted (cts_asserted),
.rts_asserted (rts_asserted),
.tx_start_allowed(tx_start_allowed),
.tx_flow_blocked (tx_flow_blocked),
.tx_data_pop (tx_data_pop),
.tx_dma_stall (tx_dma_stall),
.rx_dma_stall (rx_dma_stall),
.tx (tx),
.rts_n (rts_n),
.irq (irq)
);
always @(posedge clk_i) begin
@@ -68,11 +84,21 @@ module uart_formal;
if (!break_active && !tx_busy) assert (tx);
if (!tx_enable) assert (tx_dma_stall);
if (!rx_enable) assert (rx_dma_stall);
assert (rts_n == !rts_asserted);
if (!auto_rts_enable || !rx_enable) assert (!rts_asserted);
if (tx_data_pop) assert (tx_start_allowed);
if (tx_flow_blocked) begin
assert (auto_cts_enable);
assert (!cts_asserted);
assert (!tx_busy);
end
cover (rib_ready && rib_resp_err);
cover (tx_busy);
cover (rx_active);
cover (irq);
cover (error_status != 7'd0);
cover (tx_flow_blocked);
cover (rts_asserted);
end
end
+2 -2
View File
@@ -67,8 +67,8 @@
{"slot": 7, "name": "user_ip", "timed_interface": "u_user_ip_apb_if", "pure_interface": "u_user_ip_apb_pure_if", "region": "APB_USER_IP"}
],
"gpio_alt_functions": [
{"pin": 0, "alt0": {"inputs": [], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": ["u_ps2_if.ps2_clk_i"], "do": "u_ps2_if.ps2_clk_o", "oe": "u_ps2_if.ps2_clk_oe_o"}},
{"pin": 1, "alt0": {"inputs": [], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": ["u_ps2_if.ps2_dat_i"], "do": "u_ps2_if.ps2_dat_o", "oe": "u_ps2_if.ps2_dat_oe_o"}},
{"pin": 0, "alt0": {"inputs": ["u_uart0_if.cts_n_i"], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": ["u_ps2_if.ps2_clk_i"], "do": "u_ps2_if.ps2_clk_o", "oe": "u_ps2_if.ps2_clk_oe_o"}},
{"pin": 1, "alt0": {"inputs": [], "do": "u_uart0_if.rts_n_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_ps2_if.ps2_dat_i"], "do": "u_ps2_if.ps2_dat_o", "oe": "u_ps2_if.ps2_dat_oe_o"}},
{"pin": 2, "alt0": {"inputs": ["u_pwm_if.sync_i"], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": [], "do": "u_ws2812_if.dat_o", "oe": "1'b1"}},
{"pin": 3, "alt0": {"inputs": [], "do": "u_pwm_if.pwm_o[0]", "oe": "u_pwm_if.oe_o[0]"}, "alt1": {"inputs": ["u_i2c1_if.scl_i"], "do": "u_i2c1_if.scl_o", "oe": "u_i2c1_if.scl_oe_o"}},
{"pin": 4, "alt0": {"inputs": [], "do": "u_pwm_if.pwm_o[1]", "oe": "u_pwm_if.oe_o[1]"}, "alt1": {"inputs": ["u_i2c1_if.sda_i"], "do": "u_i2c1_if.sda_o", "oe": "u_i2c1_if.sda_oe_o"}},
+1 -1
View File
@@ -1,5 +1,5 @@
{
+lint=all;
-file=/hazard3/arith/hazard3_muldiv_seq.v,/hazard3/hazard3_frontend.v,/hazard3/arith/hazard3_onehot_encode.v,/hazard3/hazard3_instr_decompress.v,/pdk/icsprout55-pdk/IP/IO/ICsprout_55LLULP1233_IO_251013/verilog/icsIOA_N55_3P3.v,/pdk/icsprout55-pdk/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CR/verilog/ics55_LLSC_H7CR.v,/pdk/icsprout55-pdk/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CL/verilog/ics55_LLSC_H7CL.v,/pdk/icsprout55-pdk/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CH/verilog/ics55_LLSC_H7CH.v,/pdk/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_stdcell/verilog/sg13g2_stdcell.v,/clusterip/i2c/model/at24cxxx.sv,/clusterip/spi/model/w25q128jvxim.sv,/clusterip/common/rtl/cdc/cdc_2phase.sv,/clusterip/common/rtl/utils/register.sv,/clusterip/uart/model/rs232.sv,/tb/retrosoc_tb.sv,/clusterip/i2s/model/mic.sv,/model/ESP_PSRAM64H.sv,/third_party/model/sdram/sdr.v;
-file=/hazard3/arith/hazard3_muldiv_seq.v,/hazard3/hazard3_frontend.v,/hazard3/arith/hazard3_onehot_encode.v,/hazard3/hazard3_instr_decompress.v,/pdk/icsprout55-pdk/IP/IO/ICsprout_55LLULP1233_IO_251013/verilog/icsIOA_N55_3P3.v,/pdk/icsprout55-pdk/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CR/verilog/ics55_LLSC_H7CR.v,/pdk/icsprout55-pdk/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CL/verilog/ics55_LLSC_H7CL.v,/pdk/icsprout55-pdk/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CH/verilog/ics55_LLSC_H7CH.v,/pdk/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_stdcell/verilog/sg13g2_stdcell.v,/clusterip/i2c/model/at24cxxx.sv,/clusterip/spi/model/w25q128jvxim.sv,/clusterip/common/rtl/cdc/cdc_2phase.sv,/clusterip/common/rtl/utils/register.sv,/model/uart_model.sv,/tb/retrosoc_tb.sv,/clusterip/i2s/model/mic.sv,/model/ESP_PSRAM64H.sv,/third_party/model/sdram/sdr.v;
}
{ +warn=all; }
+2 -1
View File
@@ -56,13 +56,14 @@ FORMAL_SOURCE_FILES := $(RTL_PATH)/formal/bus_formal.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/ws2812_reg.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/ws2812_core.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/ribp_ws2812.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/uart_if.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/uart_baudgen.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/ribp_uart_tx.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/ribp_uart_rx.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/uart_flow_ctrl.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/uart_core.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/uart_reg.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/ribp_uart.sv \
$(ROOT_PATH)/rtl/managed/clusterip/uart/rtl/uart_if.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/i2c_filter.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/i2c_core.sv \
$(ROOT_PATH)/rtl/ip/ribp/serial/i2c_reg.sv \
+2 -2
View File
@@ -59,14 +59,14 @@
"kind": "tri_output",
"direction": "output",
"ports": [
{"name": "uart0_tx_o_pad", "signal": "u_uart0_if.tx_o"}
{"name": "uart0_tx_o_pad", "signal": "s_uart0_tx"}
]
},
{
"kind": "tri_input",
"direction": "inout",
"ports": [
{"name": "uart0_rx_i_pad", "signal": "u_uart0_if.rx_i"}
{"name": "uart0_rx_i_pad", "signal": "s_uart0_rx"}
]
},
{
+6 -2
View File
@@ -25,7 +25,8 @@ module retrosoc (
ram_if.master ram,
`endif
gpio_if.soc_pad gpio,
uart_if.dut uart0,
input logic uart_rx_i,
output logic uart_tx_o,
xpi_if.dut xpi,
sdram_if.dut sdram,
input logic jtag_tck_i,
@@ -46,6 +47,7 @@ module retrosoc (
user_gpio_if u_user_gpio_if ();
// ip interface
gpio_if u_gpio_if ();
uart_if u_uart0_if ();
psram_if u_psram_if ();
spi_if u_spisd_if ();
i2c_if u_i2c0_if ();
@@ -101,6 +103,8 @@ module retrosoc (
assign u_sysctrl_if.perf_psram_wait_i = s_perf_psram_wait;
assign u_sysctrl_if.perf_flash_wait_i = s_perf_flash_wait;
assign u_sysctrl_if.rtc_wake_i = s_rtc_wake;
assign u_uart0_if.rx_i = uart_rx_i;
assign uart_tx_o = u_uart0_if.tx_o;
gpio_pad_bridge u_gpio_pad_bridge (
.inner(u_gpio_if),
@@ -174,7 +178,7 @@ core_wrapper u_core_wrapper (
`include "ip_ribp_wrapper_fabric.svh"
.gpio (u_gpio_if),
.user_gpio (u_user_gpio_if),
.uart (uart0),
.uart (u_uart0_if),
.psram (u_psram_if),
.spisd (u_spisd_if),
.i2c0 (u_i2c0_if),
+6 -4
View File
@@ -18,8 +18,8 @@
//
// GPIO ALT0 DIR ALT1 DIR
// ------ --------------------------- ------ ---------------------- ------
// GPIO00 TIE_OFF - PS2_CLK BIDI
// GPIO01 TIE_OFF - PS2_DATA BIDI
// GPIO00 UART0_CTS_N IN PS2_CLK BIDI
// GPIO01 UART0_RTS_N OUT PS2_DATA BIDI
// GPIO02 PWM_SYNC IN WS2812_DATA OUT
// GPIO03 PWM0 OUT I2C1_SCL BIDI
// GPIO04 PWM1 OUT I2C1_SDA BIDI
@@ -71,6 +71,8 @@ module retrosoc_asic (
logic s_jtag_tdi;
logic s_jtag_trst_n;
logic s_jtag_tdo;
logic s_uart0_rx;
logic s_uart0_tx;
(* keep = "true" *)logic s_test_done;
(* keep = "true" *)logic s_test_pass;
(* keep = "true" *)logic [7:0] s_test_code;
@@ -80,7 +82,6 @@ module retrosoc_asic (
`endif
gpio_if u_gpio_if ();
uart_if u_uart0_if ();
xpi_if u_xpi_if ();
sdram_if u_sdram_if ();
pll_ctrl_if u_pll_ctrl_if ();
@@ -125,7 +126,8 @@ rcu #(
.ram (u_ram_if),
`endif
.gpio (u_gpio_if),
.uart0 (u_uart0_if),
.uart_rx_i (s_uart0_rx),
.uart_tx_o (s_uart0_tx),
.xpi (u_xpi_if),
.sdram (u_sdram_if),
.jtag_tck_i (s_jtag_tck),
+83 -13
View File
@@ -69,7 +69,10 @@ module uart_tb;
end
endtask
task automatic configure_uart(input logic [4:0] line_control, input logic [3:0] control);
task automatic configure_uart_flow(input logic [4:0] line_control, input logic [1:0] flow_control,
input logic [6:0] rts_assert_level,
input logic [6:0] rts_deassert_level,
input logic [3:0] control);
begin
write_ok(`RIBP_UART_CTRL, 0);
repeat (4) @(posedge clk_i);
@@ -77,10 +80,18 @@ module uart_tb;
write_ok(`RIBP_UART_BAUD_INT, 16);
write_ok(`RIBP_UART_BAUD_FRAC, 0);
write_ok(`RIBP_UART_LINE_CTRL, line_control);
write_ok(`RIBP_UART_RTS_WATERMARK, {9'd0, rts_deassert_level, 9'd0, rts_assert_level});
write_ok(`RIBP_UART_FLOW_CTRL, flow_control);
write_ok(`RIBP_UART_CTRL, control);
end
endtask
task automatic configure_uart(input logic [4:0] line_control, input logic [3:0] control);
begin
configure_uart_flow(line_control, 2'd0, 7'd32, 7'd48, control);
end
endtask
task automatic send_external_8n1(input logic [7:0] data, input logic bad_stop);
integer bit_index;
begin
@@ -101,23 +112,30 @@ module uart_tb;
logic [31:0] value;
integer index;
ribp.valid = 1'b0;
ribp.addr = '0;
ribp.wdata = '0;
ribp.wstrb = '0;
uart.rx_i = 1'b1;
ribp.valid = 1'b0;
ribp.addr = '0;
ribp.wdata = '0;
ribp.wstrb = '0;
uart.rx_i = 1'b1;
uart.cts_n_i = 1'b1;
repeat (4) @(posedge clk_i);
rst_n_i = 1'b1;
repeat (4) @(posedge clk_i);
if (uart.rts_n_o !== 1'b1) $fatal(1, "UART RTS_n was not released after reset");
ribp_read(`RIBP_UART_IP_VERSION, 1'b0, value);
if (value != 32'h0002_0000) $fatal(1, "UART IP version mismatch");
if (value != 32'h0003_0000) $fatal(1, "UART IP version mismatch");
ribp_read(`RIBP_UART_CAPABILITY, 1'b0, value);
if (value != 32'h00FF_4040) $fatal(1, "UART capability mismatch");
if (value != 32'h03FF_4040) $fatal(1, "UART capability mismatch");
ribp_read(32'h0000_0002, 1'b1, value);
ribp_read(`RIBP_UART_RXDATA, 1'b1, value);
configure_uart(5'd3, 4'b0111);
ribp_write(`RIBP_UART_RTS_WATERMARK, 32'h0002_0002, 4'hF, 1'b1);
ribp_read(`RIBP_UART_ERROR_STATUS, 1'b0, value);
if (!value[`UART_ERROR_CONFIG]) $fatal(1, "UART invalid RTS watermark was not reported");
write_ok(`RIBP_UART_ERROR_STATUS, 7'h7F);
configure_uart_flow(5'd3, 2'b01, 7'd32, 7'd48, 4'b0111);
write_ok(`RIBP_UART_TXDATA, 8'hA5);
repeat (220) @(posedge clk_i);
ribp_read(`RIBP_UART_RXDATA, 1'b0, value);
@@ -135,11 +153,48 @@ module uart_tb;
$fatal(1, "UART TX did not finish its active frame after disable: %h", value);
end
write_ok(`RIBP_UART_INTR_ENABLE, 6'h3F);
write_ok(`RIBP_UART_INTR_TEST, 6'h20);
write_ok(`RIBP_UART_INTR_ENABLE, 7'h7F);
write_ok(`RIBP_UART_INTR_TEST, 7'h20);
ribp_read(`RIBP_UART_INTR_STATUS, 1'b0, value);
if (!value[`UART_INTR_BREAK] || !uart.irq_o) $fatal(1, "UART interrupt test failed");
write_ok(`RIBP_UART_INTR_STATE, 6'h3F);
write_ok(`RIBP_UART_INTR_STATE, 7'h7F);
configure_uart_flow(5'd3, 2'b01, 7'd32, 7'd48, 4'b0001);
write_ok(`RIBP_UART_INTR_ENABLE, 7'h40);
write_ok(`RIBP_UART_TXDATA, 8'hC3);
write_ok(`RIBP_UART_TXDATA, 8'h5C);
repeat (32) @(posedge clk_i);
ribp_read(`RIBP_UART_STATUS, 1'b0, value);
if (!value[`UART_STATUS_TX_FLOW_BLOCKED] || value[`UART_STATUS_TX_BUSY] ||
value[`UART_STATUS_CTS_ASSERTED]) begin
$fatal(1, "UART CTS did not block a new frame: %h", value);
end
ribp_read(`RIBP_UART_FIFO_LEVEL, 1'b0, value);
if (value[6:0] != 7'd2) $fatal(1, "UART CTS-blocked FIFO count mismatch: %h", value);
uart.cts_n_i = 1'b0;
repeat (32) @(posedge clk_i);
ribp_read(`RIBP_UART_STATUS, 1'b0, value);
if (!value[`UART_STATUS_CTS_ASSERTED] || !value[`UART_STATUS_TX_BUSY]) begin
$fatal(1, "UART did not start after CTS assertion: %h", value);
end
uart.cts_n_i = 1'b1;
repeat (200) @(posedge clk_i);
ribp_read(`RIBP_UART_STATUS, 1'b0, value);
if (!value[`UART_STATUS_TX_FLOW_BLOCKED] || value[`UART_STATUS_TX_BUSY]) begin
$fatal(1, "UART CTS did not stop at the frame boundary: %h", value);
end
ribp_read(`RIBP_UART_FIFO_LEVEL, 1'b0, value);
if (value[6:0] != 7'd1) $fatal(1, "UART frame-boundary FIFO count mismatch: %h", value);
ribp_read(`RIBP_UART_INTR_STATUS, 1'b0, value);
if (!value[`UART_INTR_CTS_CHANGE] || !uart.irq_o) begin
$fatal(1, "UART CTS change interrupt failed: %h", value);
end
write_ok(`RIBP_UART_INTR_STATE, 7'h7F);
uart.cts_n_i = 1'b0;
repeat (220) @(posedge clk_i);
ribp_read(`RIBP_UART_FIFO_LEVEL, 1'b0, value);
if (value[6:0] != 7'd0) $fatal(1, "UART did not resume after CTS assertion: %h", value);
configure_uart(5'd3, 4'b0010);
fork
@@ -150,6 +205,21 @@ module uart_tb;
$fatal(1, "UART frame error was not retained: %h", value);
end
configure_uart_flow(5'd3, 2'b10, 7'd1, 7'd2, 4'b0010);
repeat (4) @(posedge clk_i);
if (uart.rts_n_o !== 1'b0) $fatal(1, "UART RTS_n was not asserted for an empty RX FIFO");
send_external_8n1(8'h12, 1'b0);
if (uart.rts_n_o !== 1'b0) $fatal(1, "UART RTS_n asserted state did not hold below watermark");
send_external_8n1(8'h34, 1'b0);
if (uart.rts_n_o !== 1'b1) $fatal(1, "UART RTS_n was not released at high watermark");
ribp_read(`RIBP_UART_RXDATA, 1'b0, value);
repeat (2) @(posedge clk_i);
if ((value[7:0] != 8'h12) || (uart.rts_n_o !== 1'b0)) begin
$fatal(1, "UART RTS hysteresis did not reassert below low watermark: %h", value);
end
ribp_read(`RIBP_UART_RXDATA, 1'b0, value);
if (value[7:0] != 8'h34) $fatal(1, "UART RTS test RX ordering mismatch: %h", value);
write_ok(`RIBP_UART_CTRL, 0);
repeat (4) @(posedge clk_i);
write_ok(`RIBP_UART_FIFO_CTRL, 3);
@@ -164,7 +234,7 @@ module uart_tb;
write_ok(`RIBP_UART_DMA_CTRL, 3);
if (!dma_tx_stall || !dma_rx_stall) $fatal(1, "Disabled UART asserted a DMA request");
$display("UART V2 register, FIFO, loopback, error, interrupt, and DMA test passed");
$display("UART V3 register, FIFO, loopback, flow-control, interrupt, and DMA test passed");
$finish;
end
+3 -2
View File
@@ -83,10 +83,11 @@ def test_topology_generates_complete_rib_apb_and_gpio_bindings(tmp_path: Path) -
assert "assign u_sdio_ribp_if.valid = 1'b0;" in routes
assert gpio.count("// GPIO") == 64
assert "u_uart1_if" not in gpio
assert "assign u_uart0_if.cts_n_i = u_gpio_if.di_i[0];" in gpio
assert "assign u_gpio_if.alt0_do_i[0] = 1'b0;" in gpio
assert "assign u_gpio_if.alt0_oe_i[0] = 1'b0;" in gpio
assert "assign u_gpio_if.alt0_do_i[1] = 1'b0;" in gpio
assert "assign u_gpio_if.alt0_oe_i[1] = 1'b0;" in gpio
assert "assign u_gpio_if.alt0_do_i[1] = u_uart0_if.rts_n_o;" in gpio
assert "assign u_gpio_if.alt0_oe_i[1] = 1'b1;" in gpio
assert "assign u_gpio_if.alt1_do_i[0] = u_ps2_if.ps2_clk_o;" in gpio
assert "assign u_gpio_if.alt1_oe_i[0] = u_ps2_if.ps2_clk_oe_o;" in gpio
assert "assign u_gpio_if.alt1_do_i[1] = u_ps2_if.ps2_dat_o;" in gpio
+8 -5
View File
@@ -1,4 +1,4 @@
"""UART V2 register, FIFO, framing, interrupt, and DMA request tests."""
"""UART V3 register, FIFO, framing, flow-control, interrupt, and DMA tests."""
from __future__ import annotations
@@ -11,7 +11,7 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
def test_uart_v2_register_fifo_loopback_and_errors(tmp_path: Path) -> None:
def test_uart_v3_register_fifo_loopback_flow_control_and_errors(tmp_path: Path) -> None:
iverilog = shutil.which("iverilog")
vvp = shutil.which("vvp")
if iverilog is None or vvp is None:
@@ -19,7 +19,6 @@ def test_uart_v2_register_fifo_loopback_and_errors(tmp_path: Path) -> None:
common = ROOT / "rtl/managed/clusterip/common/rtl"
serial = ROOT / "rtl/ip/ribp/serial"
cluster_uart = ROOT / "rtl/managed/clusterip/uart/rtl"
source_list = tmp_path / "uart.fl"
source_list.write_text(
"\n".join(
@@ -27,15 +26,19 @@ def test_uart_v2_register_fifo_loopback_and_errors(tmp_path: Path) -> None:
"+define+SV_ASSRT_DISABLE",
f"+incdir+{common}",
f"+incdir+{common / 'interface'}",
f"+incdir+{common / 'cdc'}",
f"+incdir+{common / 'utils'}",
f"+incdir+{serial}",
str(common / "interface/ribp_if.sv"),
str(common / "cdc/cdc_sync.sv"),
str(common / "utils/register.sv"),
str(common / "utils/edge_det.sv"),
str(common / "utils/fifo.sv"),
str(cluster_uart / "uart_if.sv"),
str(serial / "uart_if.sv"),
str(serial / "uart_baudgen.sv"),
str(serial / "ribp_uart_tx.sv"),
str(serial / "ribp_uart_rx.sv"),
str(serial / "uart_flow_ctrl.sv"),
str(serial / "uart_core.sv"),
str(serial / "uart_reg.sv"),
str(serial / "ribp_uart.sv"),
@@ -63,4 +66,4 @@ def test_uart_v2_register_fifo_loopback_and_errors(tmp_path: Path) -> None:
check=True,
)
result = subprocess.run([vvp, str(simulation)], text=True, capture_output=True, check=True)
assert "UART V2 register, FIFO, loopback, error, interrupt, and DMA test passed" in result.stdout
assert "UART V3 register, FIFO, loopback, flow-control, interrupt, and DMA test passed" in result.stdout