mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: add UART V2 support with formal verification and test cases
- Updated filelist to include new UART source files. - Enhanced formal file generation script to support UART target. - Introduced formal verification module and properties for UART. - Modified makefiles to include UART in formal targets and source files. - Added UART-related source files to software build. - Updated top-level wrapper to integrate UART DMA signals. - Implemented UART testbench for comprehensive testing of functionality. - Created Python test script for UART V2 register, FIFO, and interrupt tests. - Added UART helper functions in C test runtime. - Updated DMA error testbench to handle UART signals. - Ensured WS2812 DMA testbench accommodates UART signals.
This commit is contained in:
44 files changed
+2591
-446
No files matched your search
@@ -252,7 +252,7 @@ endif
|
||||
benchmark-report coremark-report \
|
||||
pin-map check-pin-map soc-topology check-soc-topology user-extensions check-user-extensions \
|
||||
check-clock-reset-domains tech-cell-test rtl-lint check-rtl-lint \
|
||||
formal formal-bus formal-rib-adapter formal-rib2apb formal-gpio formal-ws2812 formal-timer formal-clean formal-doctor
|
||||
formal formal-bus formal-rib-adapter formal-rib2apb formal-gpio formal-ws2812 formal-uart formal-timer formal-clean formal-doctor
|
||||
.NOTPARALLEL: setup
|
||||
|
||||
help:
|
||||
@@ -280,7 +280,7 @@ help:
|
||||
' check-clock-reset-domains validate the root clock/reset and CDC inventory' \
|
||||
' rtl-lint | check-rtl-lint run/check strict Verilator RTL lint warnings' \
|
||||
' formal | formal-bus | formal-rib-adapter | formal-rib2apb run SBY protocol proofs' \
|
||||
' formal-sysctrl | formal-pll-rcu | formal-gpio | formal-ws2812 | formal-timer | formal-clint run peripheral proofs' \
|
||||
' formal-sysctrl | formal-pll-rcu | formal-gpio | formal-ws2812 | formal-uart | formal-timer | formal-clint run peripheral proofs' \
|
||||
' formal-doctor check the SBY, Yosys, sv2v, and Bitwuzla formal toolchain' \
|
||||
' benchmark-report run the memory/DMA profile and write meta/performance.json' \
|
||||
' coremark-report run the quick CoreMark profile and write meta/coremark.json' \
|
||||
|
||||
@@ -227,7 +227,9 @@ int main(void) {
|
||||
uint64_t cycle_start;
|
||||
uint64_t cycles;
|
||||
|
||||
uart0_init(CPU_FREQ, UART_BPS);
|
||||
if (rs_uart_init(CPU_FREQ * UINT32_C(1000000), UART_BPS) != RS_OK) {
|
||||
rs_test_finish(RS_TEST_FAILED, 5U);
|
||||
}
|
||||
rs_benchmark_puts("retroSoC: A Customized ASIC for Retro Stuff\n");
|
||||
|
||||
if (!rs_benchmark_memory("sram", sram, RS_BENCHMARK_SRAM_SEED)) {
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#include <retrosoc/service/test.h>
|
||||
|
||||
int main(void) {
|
||||
uart0_init(CPU_FREQ, UART_BPS);
|
||||
if (rs_uart_init(CPU_FREQ * UINT32_C(1000000), UART_BPS) != RS_OK) {
|
||||
return 1;
|
||||
}
|
||||
rs_app_info();
|
||||
ip_archinfo_test(0, 0);
|
||||
rs_test_finish(RS_TEST_PASSED, 0U);
|
||||
|
||||
@@ -136,8 +136,42 @@ static bool rs_ci_smoke_gpio_v2(void) {
|
||||
return rs_gpio_write(31U, false) == RS_OK;
|
||||
}
|
||||
|
||||
static bool rs_ci_smoke_uart_v2(void) {
|
||||
const rs_uart_config_t config = {
|
||||
.source_clock_hz = CPU_FREQ * UINT32_C(1000000),
|
||||
.baud_rate = UART_BPS,
|
||||
.data_bits = 8U,
|
||||
.stop_bits = 1U,
|
||||
.parity = RS_UART_PARITY_NONE,
|
||||
.tx_watermark = 16U,
|
||||
.rx_watermark = 1U,
|
||||
.rx_timeout_bits = 32U,
|
||||
.tx_enable = true,
|
||||
.rx_enable = true,
|
||||
.loopback_enable = true,
|
||||
};
|
||||
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)) ||
|
||||
(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) ||
|
||||
(received.data != transmitted) || (received.errors != 0U)) {
|
||||
return false;
|
||||
}
|
||||
return rs_uart_init(CPU_FREQ * UINT32_C(1000000), UART_BPS) == RS_OK;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uart0_init(CPU_FREQ, UART_BPS);
|
||||
if (rs_uart_init(CPU_FREQ * UINT32_C(1000000), UART_BPS) != RS_OK) {
|
||||
rs_test_finish(RS_TEST_FAILED, 6U);
|
||||
}
|
||||
|
||||
if (!rs_ci_smoke_uart_v2()) {
|
||||
rs_test_finish(RS_TEST_FAILED, 7U);
|
||||
}
|
||||
|
||||
if (!rs_ci_smoke_archinfo_matches_reset_values()) {
|
||||
rs_test_finish(RS_TEST_FAILED, 1U);
|
||||
@@ -159,7 +193,7 @@ int main(void) {
|
||||
rs_test_finish(RS_TEST_FAILED, 5U);
|
||||
}
|
||||
|
||||
printf("ci_smoke: archinfo, CLINT, timer, and GPIO tests passed\n");
|
||||
printf("ci_smoke: UART, archinfo, CLINT, timer, and GPIO tests passed\n");
|
||||
rs_test_finish(RS_TEST_PASSED, 0U);
|
||||
return 0;
|
||||
}
|
||||
@@ -19,7 +19,9 @@ int main(void) {
|
||||
int result;
|
||||
uint32_t cycles;
|
||||
|
||||
uart0_init(CPU_FREQ, UART_BPS);
|
||||
if (rs_uart_init(CPU_FREQ * UINT32_C(1000000), UART_BPS) != RS_OK) {
|
||||
rs_test_finish(RS_TEST_FAILED, 2U);
|
||||
}
|
||||
result = core_main();
|
||||
cycles = (uint32_t)get_time();
|
||||
printf("COREMARK_RESULT mode=%s qualified=%u memory=sram iterations=%u cycles=%u cpu_hz=%u\n",
|
||||
|
||||
@@ -29,7 +29,9 @@ static void rs_app_info_command(int argc, char **argv) {
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uart0_init(CPU_FREQ, UART_BPS);
|
||||
if (rs_uart_init(CPU_FREQ * UINT32_C(1000000), UART_BPS) != RS_OK) {
|
||||
return 1;
|
||||
}
|
||||
rs_booter();
|
||||
if (rs_i2c0_init((uint8_t)(CPU_FREQ / 2 - 1)) != RS_OK) {
|
||||
return 1;
|
||||
|
||||
+10
-5
@@ -3,10 +3,15 @@
|
||||
.global _start
|
||||
_start:
|
||||
UART_INIT:
|
||||
lui a4, 0x10001
|
||||
# li a5, 625 # 72M 115200bps
|
||||
li a5, 78 # 72M 921600ps
|
||||
li a4, RS_SOC_RIBP_UART0_BASE
|
||||
li a5, 78 # 72 MHz / 921600 baud = 78.125 clocks
|
||||
sw a5, 0(a4)
|
||||
li a5, 32
|
||||
sw a5, 4(a4)
|
||||
li a5, 3 # 8 data bits, no parity, one stop bit
|
||||
sw a5, 8(a4)
|
||||
li a5, 3 # Enable TX and RX
|
||||
sw a5, 12(a4)
|
||||
HELLO_INIT:
|
||||
la s0, msg_hello
|
||||
li a0, 72
|
||||
@@ -169,8 +174,8 @@ END:
|
||||
j END
|
||||
|
||||
PUTC:
|
||||
lui a4, 0x10001
|
||||
sw a0, 4(a4)
|
||||
li a4, RS_SOC_RIBP_UART0_BASE
|
||||
sw a0, 16(a4)
|
||||
ret
|
||||
|
||||
.section .data
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
|
||||
#define RS_SOC_REG32(base, offset) (*(volatile uint32_t *)(uintptr_t)((base) + (offset)))
|
||||
|
||||
// uart0
|
||||
#define reg_uart0_clkdiv RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, UINT32_C(0x00))
|
||||
#define reg_uart0_data RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, UINT32_C(0x04))
|
||||
// psram
|
||||
#define reg_psram_wait RS_SOC_REG32(RS_SOC_RIBP_PSRAM_BASE, UINT32_C(0x00))
|
||||
#define reg_psram_chd RS_SOC_REG32(RS_SOC_RIBP_PSRAM_BASE, UINT32_C(0x04))
|
||||
|
||||
@@ -10,6 +10,14 @@ typedef struct {
|
||||
uintptr_t address;
|
||||
} rs_dma_error_t;
|
||||
|
||||
#define RS_DMA_MODE_SOFTWARE UINT32_C(0)
|
||||
#define RS_DMA_MODE_I2S_TX UINT32_C(1)
|
||||
#define RS_DMA_MODE_I2S_RX UINT32_C(2)
|
||||
#define RS_DMA_MODE_QSPI_TX UINT32_C(3)
|
||||
#define RS_DMA_MODE_QSPI_RX UINT32_C(4)
|
||||
#define RS_DMA_MODE_UART_TX UINT32_C(5)
|
||||
#define RS_DMA_MODE_UART_RX UINT32_C(6)
|
||||
|
||||
rs_status_t rs_dma_config(uint32_t mode, uintptr_t source, uint32_t source_increment,
|
||||
uintptr_t destination, uint32_t destination_increment,
|
||||
uint32_t transfer_words);
|
||||
|
||||
@@ -1,9 +1,76 @@
|
||||
#ifndef RETROSOC_HAL_UART_H
|
||||
#define RETROSOC_HAL_UART_H
|
||||
|
||||
#ifndef RETROSOC_UART_H
|
||||
#define RETROSOC_UART_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void uart0_init(uint32_t freq, uint32_t bps);
|
||||
#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_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)
|
||||
|
||||
typedef enum {
|
||||
RS_UART_PARITY_NONE = 0,
|
||||
RS_UART_PARITY_EVEN = 1,
|
||||
RS_UART_PARITY_ODD = 2,
|
||||
} rs_uart_parity_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t source_clock_hz;
|
||||
uint32_t baud_rate;
|
||||
uint8_t data_bits;
|
||||
uint8_t stop_bits;
|
||||
rs_uart_parity_t parity;
|
||||
uint8_t tx_watermark;
|
||||
uint8_t rx_watermark;
|
||||
uint16_t rx_timeout_bits;
|
||||
bool tx_enable;
|
||||
bool rx_enable;
|
||||
bool loopback_enable;
|
||||
} rs_uart_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t baud_integer;
|
||||
uint32_t baud_fraction;
|
||||
} rs_uart_timing_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t data;
|
||||
uint8_t errors;
|
||||
} rs_uart_rx_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t flags;
|
||||
uint32_t tx_level;
|
||||
uint32_t rx_level;
|
||||
uint32_t errors;
|
||||
uint32_t interrupt_state;
|
||||
} rs_uart_status_t;
|
||||
|
||||
rs_status_t rs_uart_timing_calculate(uint32_t source_clock_hz, uint32_t baud_rate,
|
||||
rs_uart_timing_t *timing);
|
||||
rs_status_t rs_uart_init(uint32_t source_clock_hz, uint32_t baud_rate);
|
||||
rs_status_t rs_uart_configure(const rs_uart_config_t *config, rs_timeout_t timeout);
|
||||
rs_status_t rs_uart_write(const uint8_t *data, size_t length, rs_timeout_t timeout);
|
||||
rs_status_t rs_uart_read(rs_uart_rx_data_t *data, size_t length, rs_timeout_t timeout);
|
||||
rs_status_t rs_uart_flush(bool flush_tx, bool flush_rx, rs_timeout_t timeout);
|
||||
rs_status_t rs_uart_get_status(rs_uart_status_t *status);
|
||||
rs_status_t rs_uart_irq_enable(uint32_t mask);
|
||||
rs_status_t rs_uart_irq_ack(uint32_t mask);
|
||||
rs_status_t rs_uart_irq_test(uint32_t mask);
|
||||
rs_status_t rs_uart_write_dma(const uint32_t *words, size_t count, rs_timeout_t timeout);
|
||||
rs_status_t rs_uart_read_dma(uint32_t *words, size_t count, rs_timeout_t timeout);
|
||||
void putch(char ch);
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -6,8 +6,8 @@
|
||||
rs_status_t rs_dma_config(uint32_t mode, uintptr_t source, uint32_t source_increment,
|
||||
uintptr_t destination, uint32_t destination_increment,
|
||||
uint32_t transfer_words) {
|
||||
if ((mode > 4U) || (source == 0U) || (destination == 0U) || (transfer_words == 0U) ||
|
||||
(source_increment > 1U) || (destination_increment > 1U)) {
|
||||
if ((mode > RS_DMA_MODE_UART_RX) || (source == 0U) || (destination == 0U) ||
|
||||
(transfer_words == 0U) || (source_increment > 1U) || (destination_increment > 1U)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
+263
-7
@@ -1,14 +1,270 @@
|
||||
#include <limits.h>
|
||||
|
||||
#include <retrosoc/core/soc.h>
|
||||
#include <retrosoc/hal/dma.h>
|
||||
#include <retrosoc/hal/uart.h>
|
||||
|
||||
void uart0_init(uint32_t freq, uint32_t bps) {
|
||||
reg_uart0_clkdiv = (uint32_t)(freq * 1000000 / bps);
|
||||
#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_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)
|
||||
|
||||
static uint32_t rs_uart_control_from_config(const rs_uart_config_t *config) {
|
||||
uint32_t control = 0U;
|
||||
|
||||
if (config->tx_enable) {
|
||||
control |= RS_UART_CTRL_TX_ENABLE;
|
||||
}
|
||||
if (config->rx_enable) {
|
||||
control |= RS_UART_CTRL_RX_ENABLE;
|
||||
}
|
||||
if (config->loopback_enable) {
|
||||
control |= RS_UART_CTRL_LOOPBACK;
|
||||
}
|
||||
return control;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_configure(const rs_uart_config_t *config, rs_timeout_t timeout) {
|
||||
rs_uart_timing_t timing;
|
||||
uint32_t line_control;
|
||||
|
||||
if (!rs_uart_config_valid(config) ||
|
||||
(rs_uart_timing_calculate(config->source_clock_hz, config->baud_rate, &timing) != RS_OK)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
|
||||
RS_UART_CTRL = 0U;
|
||||
while (((RS_UART_STATUS & (RS_UART_STATUS_TX_BUSY | RS_UART_STATUS_RX_BUSY)) != 0U) &&
|
||||
(timeout != 0U)) {
|
||||
timeout--;
|
||||
}
|
||||
if ((RS_UART_STATUS & (RS_UART_STATUS_TX_BUSY | RS_UART_STATUS_RX_BUSY)) != 0U) {
|
||||
return RS_ETIMEOUT;
|
||||
}
|
||||
|
||||
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;
|
||||
RS_UART_BAUD_INT = timing.baud_integer;
|
||||
RS_UART_BAUD_FRAC = timing.baud_fraction;
|
||||
line_control = ((uint32_t)config->data_bits - 5U) | (((uint32_t)config->stop_bits - 1U) << 2U) |
|
||||
((uint32_t)config->parity << 3U);
|
||||
RS_UART_LINE_CTRL = line_control;
|
||||
RS_UART_TX_WATERMARK = config->tx_watermark;
|
||||
RS_UART_RX_WATERMARK = config->rx_watermark;
|
||||
RS_UART_RX_TIMEOUT = config->rx_timeout_bits;
|
||||
RS_UART_DMA_CTRL = 0U;
|
||||
RS_UART_CTRL = rs_uart_control_from_config(config);
|
||||
|
||||
return ((RS_UART_STATUS & RS_UART_STATUS_CONFIG_VALID) != 0U) ? RS_OK : RS_EIO;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_init(uint32_t source_clock_hz, uint32_t baud_rate) {
|
||||
const rs_uart_config_t config = {
|
||||
.source_clock_hz = source_clock_hz,
|
||||
.baud_rate = baud_rate,
|
||||
.data_bits = 8U,
|
||||
.stop_bits = 1U,
|
||||
.parity = RS_UART_PARITY_NONE,
|
||||
.tx_watermark = 16U,
|
||||
.rx_watermark = 32U,
|
||||
.rx_timeout_bits = 32U,
|
||||
.tx_enable = true,
|
||||
.rx_enable = true,
|
||||
.loopback_enable = false,
|
||||
};
|
||||
return rs_uart_configure(&config, RS_TIMEOUT_DEFAULT);
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_write(const uint8_t *data, size_t length, rs_timeout_t timeout) {
|
||||
size_t index;
|
||||
|
||||
if ((data == NULL) && (length != 0U)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
for (index = 0U; index < length; index++) {
|
||||
while ((RS_UART_STATUS & RS_UART_STATUS_TX_FULL) != 0U) {
|
||||
if (timeout == 0U) {
|
||||
return RS_ETIMEOUT;
|
||||
}
|
||||
timeout--;
|
||||
}
|
||||
RS_UART_TXDATA = data[index];
|
||||
}
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_read(rs_uart_rx_data_t *data, size_t length, rs_timeout_t timeout) {
|
||||
size_t index;
|
||||
|
||||
if ((data == NULL) && (length != 0U)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
for (index = 0U; index < length; index++) {
|
||||
uint32_t value;
|
||||
|
||||
while ((RS_UART_STATUS & RS_UART_STATUS_RX_EMPTY) != 0U) {
|
||||
if (timeout == 0U) {
|
||||
return RS_ETIMEOUT;
|
||||
}
|
||||
timeout--;
|
||||
}
|
||||
value = RS_UART_RXDATA;
|
||||
data[index].data = (uint8_t)value;
|
||||
data[index].errors = (uint8_t)((value >> 8U) & UINT32_C(0x0F));
|
||||
}
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_flush(bool flush_tx, bool flush_rx, rs_timeout_t timeout) {
|
||||
const uint32_t old_control = RS_UART_CTRL;
|
||||
uint32_t control = old_control;
|
||||
uint32_t command = 0U;
|
||||
|
||||
if (!flush_tx && !flush_rx) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
if (flush_tx) {
|
||||
control &= ~RS_UART_CTRL_TX_ENABLE;
|
||||
command |= RS_UART_FIFO_TX_FLUSH;
|
||||
}
|
||||
if (flush_rx) {
|
||||
control &= ~RS_UART_CTRL_RX_ENABLE;
|
||||
command |= RS_UART_FIFO_RX_FLUSH;
|
||||
}
|
||||
RS_UART_CTRL = control;
|
||||
while (((RS_UART_STATUS & (RS_UART_STATUS_TX_BUSY | RS_UART_STATUS_RX_BUSY)) != 0U) &&
|
||||
(timeout != 0U)) {
|
||||
timeout--;
|
||||
}
|
||||
if ((RS_UART_STATUS & (RS_UART_STATUS_TX_BUSY | RS_UART_STATUS_RX_BUSY)) != 0U) {
|
||||
return RS_ETIMEOUT;
|
||||
}
|
||||
RS_UART_FIFO_CTRL = command;
|
||||
RS_UART_CTRL = old_control;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_get_status(rs_uart_status_t *status) {
|
||||
uint32_t levels;
|
||||
|
||||
if (status == NULL) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
levels = RS_UART_FIFO_LEVEL;
|
||||
status->flags = RS_UART_STATUS;
|
||||
status->tx_level = levels & UINT32_C(0x7F);
|
||||
status->rx_level = (levels >> 16U) & UINT32_C(0x7F);
|
||||
status->errors = RS_UART_ERROR_STATUS;
|
||||
status->interrupt_state = RS_UART_INTR_STATE;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_irq_enable(uint32_t mask) {
|
||||
if ((mask & ~RS_UART_INTR_ALL) != 0U) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
RS_UART_INTR_ENABLE = mask;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_irq_ack(uint32_t mask) {
|
||||
if ((mask == 0U) || ((mask & ~RS_UART_INTR_ALL) != 0U)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
RS_UART_INTR_STATE = mask;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_irq_test(uint32_t mask) {
|
||||
if ((mask == 0U) || ((mask & ~RS_UART_INTR_ALL) != 0U)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
RS_UART_INTR_TEST = mask;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_write_dma(const uint32_t *words, size_t count, rs_timeout_t timeout) {
|
||||
size_t index;
|
||||
rs_status_t status;
|
||||
|
||||
if ((words == NULL) || (count == 0U) || (count > UINT32_MAX)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
for (index = 0U; index < count; index++) {
|
||||
if ((words[index] & UINT32_C(0xFFFFFF00)) != 0U) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
}
|
||||
RS_UART_DMA_CTRL = RS_UART_DMA_TX_ENABLE;
|
||||
status = rs_dma_config(RS_DMA_MODE_UART_TX, (uintptr_t)words, 1U,
|
||||
RS_SOC_RIBP_UART0_BASE + UINT32_C(0x10), 0U, (uint32_t)count);
|
||||
if (status == RS_OK) {
|
||||
status = rs_dma_start();
|
||||
}
|
||||
if (status == RS_OK) {
|
||||
status = rs_dma_wait(timeout);
|
||||
}
|
||||
RS_UART_DMA_CTRL = 0U;
|
||||
return status;
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_read_dma(uint32_t *words, size_t count, rs_timeout_t timeout) {
|
||||
rs_status_t status;
|
||||
|
||||
if ((words == NULL) || (count == 0U) || (count > UINT32_MAX)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
RS_UART_DMA_CTRL = RS_UART_DMA_RX_ENABLE;
|
||||
status = rs_dma_config(RS_DMA_MODE_UART_RX, RS_SOC_RIBP_UART0_BASE + UINT32_C(0x14), 0U,
|
||||
(uintptr_t)words, 1U, (uint32_t)count);
|
||||
if (status == RS_OK) {
|
||||
status = rs_dma_start();
|
||||
}
|
||||
if (status == RS_OK) {
|
||||
status = rs_dma_wait(timeout);
|
||||
}
|
||||
RS_UART_DMA_CTRL = 0U;
|
||||
return status;
|
||||
}
|
||||
|
||||
void putch(char ch) {
|
||||
// while (((reg_uart1_lsr & 0x100) >> 8) == 1)
|
||||
// ;
|
||||
// reg_uart1_trx = (uint32_t)ch;
|
||||
|
||||
reg_uart0_data = ch;
|
||||
const uint8_t value = (uint8_t)ch;
|
||||
(void)rs_uart_write(&value, 1U, RS_TIMEOUT_DEFAULT);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <limits.h>
|
||||
|
||||
#include <retrosoc/hal/uart.h>
|
||||
|
||||
rs_status_t rs_uart_timing_calculate(uint32_t source_clock_hz, uint32_t baud_rate,
|
||||
rs_uart_timing_t *timing) {
|
||||
uint64_t scaled_period;
|
||||
|
||||
if ((source_clock_hz == 0U) || (baud_rate == 0U) || (timing == NULL)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
|
||||
scaled_period =
|
||||
(((uint64_t)source_clock_hz * UINT64_C(256)) + ((uint64_t)baud_rate / UINT64_C(2))) /
|
||||
(uint64_t)baud_rate;
|
||||
if ((scaled_period < UINT64_C(4096)) ||
|
||||
(scaled_period > ((UINT64_C(0xFFFFFF) * UINT64_C(256)) + UINT64_C(255)))) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
|
||||
timing->baud_integer = (uint32_t)(scaled_period >> 8U);
|
||||
timing->baud_fraction = (uint32_t)(scaled_period & UINT64_C(0xFF));
|
||||
return RS_OK;
|
||||
}
|
||||
@@ -1,17 +1,22 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include <retrosoc/core/soc.h>
|
||||
#include <retrosoc/core/status.h>
|
||||
#include <retrosoc/hal/uart.h>
|
||||
#include <retrosoc/lib/console.h>
|
||||
|
||||
void putchar(char c) {
|
||||
if (c == '\n') {
|
||||
reg_uart0_data = '\r';
|
||||
putch('\r');
|
||||
}
|
||||
reg_uart0_data = c;
|
||||
putch(c);
|
||||
}
|
||||
|
||||
char getchar(void) {
|
||||
return reg_uart0_data;
|
||||
rs_uart_rx_data_t data;
|
||||
|
||||
while (rs_uart_read(&data, 1U, RS_TIMEOUT_DEFAULT) != RS_OK) {
|
||||
}
|
||||
return (char)data.data;
|
||||
}
|
||||
|
||||
void print(const char *p) {
|
||||
|
||||
@@ -97,7 +97,8 @@ void rs_app_info(void) {
|
||||
printf("Memory Map IO Device:\n");
|
||||
printf(" 1 x GPIO(32PIN) @%p\n",
|
||||
(void *)(uintptr_t)RS_SOC_RIBP_GPIO_ADMIN_BASE);
|
||||
printf(" 1 x UART0 @%p\n", (void *)®_uart0_clkdiv);
|
||||
printf(" 1 x UART0 @%p\n",
|
||||
(void *)(uintptr_t)RS_SOC_RIBP_UART0_BASE);
|
||||
printf(" 2 x TIMER(0,1) @%p,%p\n",
|
||||
(void *)(uintptr_t)RS_SOC_RIBP_TIM0_BASE, (void *)(uintptr_t)RS_SOC_RIBP_TIM1_BASE);
|
||||
printf(" 1 x PSRAM @%p\n", (void *)®_psram_wait);
|
||||
|
||||
@@ -28,6 +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.
|
||||
- [soc-integration-wiring.md](soc-integration-wiring.md) defines the generated
|
||||
pin-map workflow and SoC integration boundary.
|
||||
- [mini-soc-block-diagram.svg](mini-soc-block-diagram.svg) is the Mini SoC
|
||||
|
||||
+3
-2
@@ -131,7 +131,7 @@ Verilator regressions.
|
||||
`make CONFIG=configs/ci/ihp130.mk formal` proves selected
|
||||
protocol invariants with SymbiYosys, Yosys, `sv2v`, and Bitwuzla. The current
|
||||
targets are `bus`, `rib_adapter`, `rib2apb`, `sysctrl`, `pll_rcu`, `gpio`,
|
||||
and `ws2812`; each uses the SBY `prove` task for bounded model
|
||||
`ws2812`, `uart`, `timer`, and `clint`; each uses the SBY `prove` task for bounded model
|
||||
checking and k-induction, plus a `cover` task. The default depth is 20;
|
||||
`ws2812` uses depth 120 and a 120-second per-task limit to cover a complete
|
||||
serialized word and reset path. `sysctrl` checks register side effects, sticky terminal-test status, PLL request
|
||||
@@ -141,7 +141,8 @@ ownership, locks, handoff, open-drain safety, and mux behavior. `rib_adapter`
|
||||
checks both single-word compatibility adapters
|
||||
under backpressure. `ws2812` checks RIBP response stability, FIFO bounds,
|
||||
waveform idle safety, sticky error and interrupt propagation, abort, and
|
||||
underflow preconditions. Direct Common utility proofs, including `spill_register`,
|
||||
underflow preconditions. `uart` checks FIFO bounds, interrupt composition,
|
||||
DMA gating, and idle/break line safety. Direct Common utility proofs, including `spill_register`,
|
||||
are maintained in the Common repository.
|
||||
`FORMAL_DEPTH` and `FORMAL_TIMEOUT` set the proof bound and per-task
|
||||
wall-clock limit. Use `make CONFIG=<profile> formal-doctor` before a local
|
||||
|
||||
@@ -7,6 +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.
|
||||
|
||||
The corresponding RTL and HAL implementations remain the executable sources
|
||||
of truth. Update the affected document whenever an IP interface or register ABI
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
# RIBP UART V2
|
||||
|
||||
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,
|
||||
fractional baud-rate generation, configurable framing, receive diagnostics,
|
||||
watermark and timeout interrupts, internal loopback, break generation, and
|
||||
generic-DMA request pacing.
|
||||
|
||||
## Integration
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| RIBP base address | `0x10001000` |
|
||||
| TX/RX FIFO depth | 64 entries each |
|
||||
| RIBP interrupt group bit | 2 |
|
||||
| Management-core interrupt | 2 |
|
||||
| DMA modes | 5 UART TX, 6 UART RX |
|
||||
| External signals | `uart0_tx`, `uart0_rx` |
|
||||
|
||||
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. APB UART1 is independent and is not affected by
|
||||
this ABI.
|
||||
|
||||
## Register ABI
|
||||
|
||||
All registers are 32-bit and naturally aligned. Unmapped, unaligned,
|
||||
direction-invalid, reserved-field, and semantically illegal accesses complete
|
||||
with `resp_err`. RW registers support byte strobes. Command and data registers
|
||||
require the low byte lane; selected upper lanes must contain zero.
|
||||
|
||||
| Offset | Name | Access | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `0x000` | `BAUD_INT` | RW | Integer clocks per serial bit, 24 bits; minimum 16. |
|
||||
| `0x004` | `BAUD_FRAC` | RW | Fractional clocks per bit in units of 1/256. |
|
||||
| `0x008` | `LINE_CTRL` | RW | Data width, stop count, and parity. |
|
||||
| `0x00C` | `CTRL` | RW | TX/RX enable, internal loopback, and TX break. |
|
||||
| `0x010` | `TXDATA` | WO | Push one character from bits 7:0. |
|
||||
| `0x014` | `RXDATA` | RO/pop | Character plus parity, frame, break, and noise flags. |
|
||||
| `0x018` | `STATUS` | RO | Enable, activity, FIFO, configuration, break, and DMA state. |
|
||||
| `0x01C` | `FIFO_LEVEL` | RO | TX count at bits 6:0 and RX count at bits 22:16. |
|
||||
| `0x020` | `FIFO_CTRL` | WO | Bits 0/1 flush the disabled, idle TX/RX FIFO. |
|
||||
| `0x024` | `TX_WATERMARK` | RW | Low-water threshold, 0 through 63; reset value 16. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
|
||||
`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
|
||||
reserved. `CTRL` bits 0 through 3 are TX enable, RX enable, loopback, and TX
|
||||
break.
|
||||
|
||||
`RXDATA[7:0]` is the character. Bits 8 through 11 report parity error, frame
|
||||
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`.
|
||||
|
||||
## Timing and transfer behavior
|
||||
|
||||
The programmed bit period is `BAUD_INT + BAUD_FRAC / 256`. A phase accumulator
|
||||
generates a 16-times sample clock without accumulating whole-bit rounding
|
||||
error. RX synchronizes the pad and votes three samples around each bit center;
|
||||
mixed samples set the character noise flag. Start bits are confirmed before
|
||||
data collection, and invalid starts return directly to idle.
|
||||
|
||||
Baud and line format can change only while TX/RX are disabled and both state
|
||||
machines are idle. Clearing TX enable prevents a new character from starting
|
||||
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.
|
||||
|
||||
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
|
||||
the serializer and FIFO empty. Watermark conditions reassert their interrupt
|
||||
state while the condition remains true, even after a software clear.
|
||||
|
||||
## DMA and software contract
|
||||
|
||||
The DMA transfers one 32-bit word per character. UART TX mode uses an
|
||||
incrementing memory source and fixed `TXDATA` destination; bits 31:8 must be
|
||||
zero. UART RX mode uses fixed `RXDATA` source and an incrementing memory
|
||||
destination; bits 11:8 retain per-character errors. RX overrun remains global
|
||||
because the dropped character cannot carry metadata.
|
||||
|
||||
The public HAL exposes structured configuration, bounded CPU reads/writes,
|
||||
status and interrupt control, FIFO flush, and UART-paced DMA transfers.
|
||||
`rs_uart_timing_calculate()` uses 64-bit arithmetic and nearest rounding.
|
||||
`putch()` remains the internal formatted-output sink, while applications use
|
||||
`rs_uart_init()` or `rs_uart_configure()` instead of raw registers.
|
||||
|
||||
## 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.
|
||||
|
||||
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.
|
||||
@@ -128,7 +128,11 @@ digraph mini_soc_block_diagram {
|
||||
];
|
||||
ribp_targets [
|
||||
fillcolor="#F9E1E7",
|
||||
label="RIBP target wrapper\nXPI/Flash, SDRAM, PSRAM, SPI-SD and DVP\nUART0, I2C and I2S"
|
||||
label="RIBP target wrapper\nXPI/Flash, SDRAM, PSRAM, SPI-SD and DVP\nI2C and I2S"
|
||||
];
|
||||
uart0 [
|
||||
fillcolor="#F9E1E7",
|
||||
label="UART0 V2\n64-byte TX/RX FIFOs, fractional baud\nframing/errors, IRQ2, DMA-paced"
|
||||
];
|
||||
gpio_controller [
|
||||
fillcolor="#F9E1E7",
|
||||
@@ -161,7 +165,7 @@ digraph mini_soc_block_diagram {
|
||||
{ rank=same; user_core; dma; }
|
||||
{ rank=same; fault; fabric; sram; }
|
||||
{ rank=same; ribp_adapter; apb_adapter; }
|
||||
{ rank=same; sysctrl; clint; ribp_targets; gpio_controller; timers; ws2812; apb_targets; }
|
||||
{ rank=same; sysctrl; clint; ribp_targets; uart0; gpio_controller; timers; ws2812; apb_targets; }
|
||||
{ rank=same; gpio_bridge; irq; }
|
||||
|
||||
ext_clock -> rcu [label="clock / reset"];
|
||||
@@ -186,6 +190,7 @@ digraph mini_soc_block_diagram {
|
||||
ribp_adapter -> sysctrl [label="RIBP"];
|
||||
ribp_adapter -> clint [label="RIBP"];
|
||||
ribp_adapter -> ribp_targets [label="RIBP"];
|
||||
ribp_adapter -> uart0 [label="RIBP"];
|
||||
ribp_adapter -> gpio_controller [label="RIBP\nuser/admin"];
|
||||
ribp_adapter -> timers [label="RIBP"];
|
||||
ribp_adapter -> ws2812 [label="RIBP"];
|
||||
@@ -199,7 +204,10 @@ digraph mini_soc_block_diagram {
|
||||
ws2812 -> gpio_bridge [label="GPIO2 ALT1"];
|
||||
dma -> ws2812 [label="TXDATA writes", style=dashed];
|
||||
ws2812 -> irq [label="IRQ17"];
|
||||
dma -> uart0 [label="TX/RX data", style=dashed];
|
||||
uart0 -> irq [label="IRQ2"];
|
||||
apb_targets -> gpio_controller [label="user_gpio"];
|
||||
ribp_targets -> ext_io [dir=both, label="device interfaces"];
|
||||
uart0 -> ext_io [dir=both, label="UART pads"];
|
||||
gpio_bridge -> ext_io [dir=both, label="pad control"];
|
||||
}
|
||||
+241
-204
@@ -4,19 +4,19 @@
|
||||
<!-- Generated by graphviz version 2.43.0 (0)
|
||||
-->
|
||||
<!-- Title: mini_soc_block_diagram Pages: 1 -->
|
||||
<svg width="1986pt" height="896pt"
|
||||
viewBox="0.00 0.00 1986.00 896.48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg width="2197pt" height="896pt"
|
||||
viewBox="0.00 0.00 2197.00 896.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 892.48)">
|
||||
<title>mini_soc_block_diagram</title>
|
||||
<text text-anchor="middle" x="132" y="-870.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 1958,-85 1958,-85 1964,-85 1970,-91 1970,-97 1970,-97 1970,-772.48 1970,-772.48 1970,-778.48 1964,-784.48 1958,-784.48 1958,-784.48 160,-784.48 160,-784.48 154,-784.48 148,-778.48 148,-772.48 148,-772.48 148,-97 148,-97 148,-91 154,-85 160,-85"/>
|
||||
<path fill="transparent" stroke="#111827" d="M160,-85C160,-85 2169,-85 2169,-85 2175,-85 2181,-91 2181,-97 2181,-97 2181,-772.48 2181,-772.48 2181,-778.48 2175,-784.48 2169,-784.48 2169,-784.48 160,-784.48 160,-784.48 154,-784.48 148,-778.48 148,-772.48 148,-772.48 148,-97 148,-97 148,-91 154,-85 160,-85"/>
|
||||
<text text-anchor="middle" x="196.5" y="-769.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 1940,-103 1940,-103 1946,-103 1952,-109 1952,-115 1952,-115 1952,-729.48 1952,-729.48 1952,-735.48 1946,-741.48 1940,-741.48 1940,-741.48 390,-741.48 390,-741.48 384,-741.48 378,-735.48 378,-729.48 378,-729.48 378,-115 378,-115 378,-109 384,-103 390,-103"/>
|
||||
<path fill="transparent" stroke="#94a3b8" stroke-dasharray="5,2" d="M390,-103C390,-103 2151,-103 2151,-103 2157,-103 2163,-109 2163,-115 2163,-115 2163,-729.48 2163,-729.48 2163,-735.48 2157,-741.48 2151,-741.48 2151,-741.48 390,-741.48 390,-741.48 384,-741.48 378,-735.48 378,-729.48 378,-729.48 378,-115 378,-115 378,-109 384,-103 390,-103"/>
|
||||
<text text-anchor="middle" x="407.5" y="-727.88" font-family="Arial" font-size="12.00" fill="#334155">retrosoc</text>
|
||||
</g>
|
||||
<!-- ext_clock -->
|
||||
@@ -44,401 +44,438 @@
|
||||
<!-- ext_io -->
|
||||
<g id="node2" class="node">
|
||||
<title>ext_io</title>
|
||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M1063,-45C1063,-45 871,-45 871,-45 865,-45 859,-39 859,-33 859,-33 859,-12 859,-12 859,-6 865,0 871,0 871,0 1063,0 1063,0 1069,0 1075,-6 1075,-12 1075,-12 1075,-33 1075,-33 1075,-39 1069,-45 1063,-45"/>
|
||||
<text text-anchor="middle" x="967" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
|
||||
<text text-anchor="middle" x="967" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, XPI Flash, SDRAM, PSRAM</text>
|
||||
<text text-anchor="middle" x="967" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP and WS2812</text>
|
||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M1678,-45C1678,-45 1486,-45 1486,-45 1480,-45 1474,-39 1474,-33 1474,-33 1474,-12 1474,-12 1474,-6 1480,0 1486,0 1486,0 1678,0 1678,0 1684,0 1690,-6 1690,-12 1690,-12 1690,-33 1690,-33 1690,-39 1684,-45 1678,-45"/>
|
||||
<text text-anchor="middle" x="1582" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
|
||||
<text text-anchor="middle" x="1582" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, XPI Flash, SDRAM, PSRAM</text>
|
||||
<text text-anchor="middle" x="1582" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP and WS2812</text>
|
||||
</g>
|
||||
<!-- ext_jtag -->
|
||||
<g id="node3" class="node">
|
||||
<title>ext_jtag</title>
|
||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M1078.5,-860.48C1078.5,-860.48 947.5,-860.48 947.5,-860.48 941.5,-860.48 935.5,-854.48 935.5,-848.48 935.5,-848.48 935.5,-836.48 935.5,-836.48 935.5,-830.48 941.5,-824.48 947.5,-824.48 947.5,-824.48 1078.5,-824.48 1078.5,-824.48 1084.5,-824.48 1090.5,-830.48 1090.5,-836.48 1090.5,-836.48 1090.5,-848.48 1090.5,-848.48 1090.5,-854.48 1084.5,-860.48 1078.5,-860.48"/>
|
||||
<text text-anchor="middle" x="1013" y="-845.48" font-family="Arial" font-size="10.00" fill="#111827">Management JTAG</text>
|
||||
<text text-anchor="middle" x="1013" y="-834.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="M777.5,-860.48C777.5,-860.48 646.5,-860.48 646.5,-860.48 640.5,-860.48 634.5,-854.48 634.5,-848.48 634.5,-848.48 634.5,-836.48 634.5,-836.48 634.5,-830.48 640.5,-824.48 646.5,-824.48 646.5,-824.48 777.5,-824.48 777.5,-824.48 783.5,-824.48 789.5,-830.48 789.5,-836.48 789.5,-836.48 789.5,-848.48 789.5,-848.48 789.5,-854.48 783.5,-860.48 777.5,-860.48"/>
|
||||
<text text-anchor="middle" x="712" y="-845.48" font-family="Arial" font-size="10.00" fill="#111827">Management JTAG</text>
|
||||
<text text-anchor="middle" x="712" y="-834.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="M1088,-678.98C1088,-678.98 938,-678.98 938,-678.98 932,-678.98 926,-672.98 926,-666.98 926,-666.98 926,-654.98 926,-654.98 926,-648.98 932,-642.98 938,-642.98 938,-642.98 1088,-642.98 1088,-642.98 1094,-642.98 1100,-648.98 1100,-654.98 1100,-654.98 1100,-666.98 1100,-666.98 1100,-672.98 1094,-678.98 1088,-678.98"/>
|
||||
<text text-anchor="middle" x="1013" y="-663.98" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 JTAG DTM</text>
|
||||
<text text-anchor="middle" x="1013" y="-652.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="M787,-678.98C787,-678.98 637,-678.98 637,-678.98 631,-678.98 625,-672.98 625,-666.98 625,-666.98 625,-654.98 625,-654.98 625,-648.98 631,-642.98 637,-642.98 637,-642.98 787,-642.98 787,-642.98 793,-642.98 799,-648.98 799,-654.98 799,-654.98 799,-666.98 799,-666.98 799,-672.98 793,-678.98 787,-678.98"/>
|
||||
<text text-anchor="middle" x="712" y="-663.98" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 JTAG DTM</text>
|
||||
<text text-anchor="middle" x="712" y="-652.98" font-family="Arial" font-size="10.00" fill="#111827">10 MHz asynchronous TCK domain</text>
|
||||
</g>
|
||||
<!-- ext_jtag->jtag_dtm -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>ext_jtag->jtag_dtm</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1013,-824.27C1013,-792.24 1013,-723.39 1013,-686.51"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1015.45,-686.14 1013,-679.14 1010.55,-686.14 1015.45,-686.14"/>
|
||||
<text text-anchor="middle" x="1033" y="-795.08" font-family="Arial" font-size="8.00" fill="#374151">JTAG pads</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M712,-824.27C712,-792.24 712,-723.39 712,-686.51"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="714.45,-686.14 712,-679.14 709.55,-686.14 714.45,-686.14"/>
|
||||
<text text-anchor="middle" x="732" y="-795.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="M1086.66,-451.31C1086.66,-451.31 1018.98,-479.16 1018.98,-479.16 1013.43,-481.45 1001.88,-483.73 995.88,-483.73 995.88,-483.73 840.12,-483.73 840.12,-483.73 834.12,-483.73 822.57,-481.45 817.02,-479.16 817.02,-479.16 749.34,-451.31 749.34,-451.31 743.79,-449.03 743.79,-444.46 749.34,-442.18 749.34,-442.18 817.02,-414.32 817.02,-414.32 822.57,-412.04 834.12,-409.76 840.12,-409.76 840.12,-409.76 995.88,-409.76 995.88,-409.76 1001.88,-409.76 1013.43,-412.04 1018.98,-414.32 1018.98,-414.32 1086.66,-442.18 1086.66,-442.18 1092.21,-444.46 1092.21,-449.03 1086.66,-451.31"/>
|
||||
<text text-anchor="middle" x="918" y="-455.24" font-family="Arial" font-size="10.00" fill="#111827">RIB fabric</text>
|
||||
<text text-anchor="middle" x="918" y="-444.24" font-family="Arial" font-size="10.00" fill="#111827">3-master round-robin arbitration</text>
|
||||
<text text-anchor="middle" x="918" y="-433.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="M1083.66,-451.31C1083.66,-451.31 1015.98,-479.16 1015.98,-479.16 1010.43,-481.45 998.88,-483.73 992.88,-483.73 992.88,-483.73 837.12,-483.73 837.12,-483.73 831.12,-483.73 819.57,-481.45 814.02,-479.16 814.02,-479.16 746.34,-451.31 746.34,-451.31 740.79,-449.03 740.79,-444.46 746.34,-442.18 746.34,-442.18 814.02,-414.32 814.02,-414.32 819.57,-412.04 831.12,-409.76 837.12,-409.76 837.12,-409.76 992.88,-409.76 992.88,-409.76 998.88,-409.76 1010.43,-412.04 1015.98,-414.32 1015.98,-414.32 1083.66,-442.18 1083.66,-442.18 1089.21,-444.46 1089.21,-449.03 1083.66,-451.31"/>
|
||||
<text text-anchor="middle" x="915" y="-455.24" font-family="Arial" font-size="10.00" fill="#111827">RIB fabric</text>
|
||||
<text text-anchor="middle" x="915" y="-444.24" font-family="Arial" font-size="10.00" fill="#111827">3-master round-robin arbitration</text>
|
||||
<text text-anchor="middle" x="915" y="-433.24" font-family="Arial" font-size="10.00" fill="#111827">INCR1 / INCR4, access policy, fault reporting</text>
|
||||
</g>
|
||||
<!-- rcu->fabric -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>rcu->fabric</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M362.03,-540.47C368.2,-539.24 372,-538.48 372,-538.48 372,-538.48 734,-483.48 734,-483.48 734,-483.48 758.75,-478.68 790.1,-472.59"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="790.92,-474.92 797.32,-471.18 789.98,-470.11 790.92,-474.92"/>
|
||||
<text text-anchor="middle" x="609" y="-509.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,-540.47C368.2,-539.24 372,-538.48 372,-538.48 372,-538.48 731,-483.48 731,-483.48 731,-483.48 755.75,-478.68 787.1,-472.59"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="787.92,-474.92 794.32,-471.18 786.98,-470.11 787.92,-474.92"/>
|
||||
<text text-anchor="middle" x="607" y="-509.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="M527.5,-255C527.5,-255 406.5,-255 406.5,-255 400.5,-255 394.5,-249 394.5,-243 394.5,-243 394.5,-222 394.5,-222 394.5,-216 400.5,-210 406.5,-210 406.5,-210 527.5,-210 527.5,-210 533.5,-210 539.5,-216 539.5,-222 539.5,-222 539.5,-243 539.5,-243 539.5,-249 533.5,-255 527.5,-255"/>
|
||||
<text text-anchor="middle" x="467" y="-241" font-family="Arial" font-size="10.00" fill="#111827">CLINT</text>
|
||||
<text text-anchor="middle" x="467" y="-230" font-family="Arial" font-size="10.00" fill="#111827">standard 64 KiB register map</text>
|
||||
<text text-anchor="middle" x="467" 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="M769.5,-255C769.5,-255 648.5,-255 648.5,-255 642.5,-255 636.5,-249 636.5,-243 636.5,-243 636.5,-222 636.5,-222 636.5,-216 642.5,-210 648.5,-210 648.5,-210 769.5,-210 769.5,-210 775.5,-210 781.5,-216 781.5,-222 781.5,-222 781.5,-243 781.5,-243 781.5,-249 775.5,-255 769.5,-255"/>
|
||||
<text text-anchor="middle" x="709" y="-241" font-family="Arial" font-size="10.00" fill="#111827">CLINT</text>
|
||||
<text text-anchor="middle" x="709" y="-230" font-family="Arial" font-size="10.00" fill="#111827">standard 64 KiB register map</text>
|
||||
<text text-anchor="middle" x="709" y="-219" font-family="Arial" font-size="10.00" fill="#111827">mtime, mtimecmp and MSIP</text>
|
||||
</g>
|
||||
<!-- rcu->clint -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>rcu->clint</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M277.48,-538.31C313.09,-481.03 409.7,-325.66 449.5,-261.65"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="451.78,-262.62 453.4,-255.38 447.62,-260.03 451.78,-262.62"/>
|
||||
<text text-anchor="middle" x="392.5" y="-380.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="M286.04,-538.33C353.25,-472.3 551,-278 551,-278 551,-278 590.26,-266.94 629.65,-255.85"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="630.4,-258.18 636.47,-253.93 629.07,-253.47 630.4,-258.18"/>
|
||||
<text text-anchor="middle" x="464.5" y="-380.6" font-family="Arial" font-size="8.00" fill="#374151">1 MHz tick</text>
|
||||
</g>
|
||||
<!-- mgmt_core -->
|
||||
<g id="node5" class="node">
|
||||
<title>mgmt_core</title>
|
||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M1293,-683.48C1293,-683.48 1139,-683.48 1139,-683.48 1133,-683.48 1127,-677.48 1127,-671.48 1127,-671.48 1127,-650.48 1127,-650.48 1127,-644.48 1133,-638.48 1139,-638.48 1139,-638.48 1293,-638.48 1293,-638.48 1299,-638.48 1305,-644.48 1305,-650.48 1305,-650.48 1305,-671.48 1305,-671.48 1305,-677.48 1299,-683.48 1293,-683.48"/>
|
||||
<text text-anchor="middle" x="1216" y="-669.48" font-family="Arial" font-size="10.00" fill="#111827">Management core</text>
|
||||
<text text-anchor="middle" x="1216" y="-658.48" font-family="Arial" font-size="10.00" fill="#111827">Fixed Hazard3, branch predictor</text>
|
||||
<text text-anchor="middle" x="1216" y="-647.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="M992,-683.48C992,-683.48 838,-683.48 838,-683.48 832,-683.48 826,-677.48 826,-671.48 826,-671.48 826,-650.48 826,-650.48 826,-644.48 832,-638.48 838,-638.48 838,-638.48 992,-638.48 992,-638.48 998,-638.48 1004,-644.48 1004,-650.48 1004,-650.48 1004,-671.48 1004,-671.48 1004,-677.48 998,-683.48 992,-683.48"/>
|
||||
<text text-anchor="middle" x="915" y="-669.48" font-family="Arial" font-size="10.00" fill="#111827">Management core</text>
|
||||
<text text-anchor="middle" x="915" y="-658.48" font-family="Arial" font-size="10.00" fill="#111827">Fixed Hazard3, branch predictor</text>
|
||||
<text text-anchor="middle" x="915" y="-647.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="M1236.5,-578.98C1236.5,-578.98 1195.5,-578.98 1195.5,-578.98 1189.5,-578.98 1183.5,-572.98 1183.5,-566.98 1183.5,-566.98 1183.5,-554.98 1183.5,-554.98 1183.5,-548.98 1189.5,-542.98 1195.5,-542.98 1195.5,-542.98 1236.5,-542.98 1236.5,-542.98 1242.5,-542.98 1248.5,-548.98 1248.5,-554.98 1248.5,-554.98 1248.5,-566.98 1248.5,-566.98 1248.5,-572.98 1242.5,-578.98 1236.5,-578.98"/>
|
||||
<text text-anchor="middle" x="1216" y="-558.48" font-family="Arial" font-size="10.00" fill="#111827">RIBP2RIB</text>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M935.5,-578.98C935.5,-578.98 894.5,-578.98 894.5,-578.98 888.5,-578.98 882.5,-572.98 882.5,-566.98 882.5,-566.98 882.5,-554.98 882.5,-554.98 882.5,-548.98 888.5,-542.98 894.5,-542.98 894.5,-542.98 935.5,-542.98 935.5,-542.98 941.5,-542.98 947.5,-548.98 947.5,-554.98 947.5,-554.98 947.5,-566.98 947.5,-566.98 947.5,-572.98 941.5,-578.98 935.5,-578.98"/>
|
||||
<text text-anchor="middle" x="915" y="-558.48" font-family="Arial" font-size="10.00" fill="#111827">RIBP2RIB</text>
|
||||
</g>
|
||||
<!-- mgmt_core->mgmt_adapter -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>mgmt_core->mgmt_adapter</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1216,-638.24C1216,-622.92 1216,-602.4 1216,-586.51"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1218.45,-586.12 1216,-579.12 1213.55,-586.12 1218.45,-586.12"/>
|
||||
<text text-anchor="middle" x="1225.5" y="-609.08" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M915,-638.24C915,-622.92 915,-602.4 915,-586.51"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="917.45,-586.12 915,-579.12 912.55,-586.12 917.45,-586.12"/>
|
||||
<text text-anchor="middle" x="924.5" y="-609.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="M1583.5,-683.48C1583.5,-683.48 1462.5,-683.48 1462.5,-683.48 1456.5,-683.48 1450.5,-677.48 1450.5,-671.48 1450.5,-671.48 1450.5,-650.48 1450.5,-650.48 1450.5,-644.48 1456.5,-638.48 1462.5,-638.48 1462.5,-638.48 1583.5,-638.48 1583.5,-638.48 1589.5,-638.48 1595.5,-644.48 1595.5,-650.48 1595.5,-650.48 1595.5,-671.48 1595.5,-671.48 1595.5,-677.48 1589.5,-683.48 1583.5,-683.48"/>
|
||||
<text text-anchor="middle" x="1523" y="-669.48" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 Debug Module</text>
|
||||
<text text-anchor="middle" x="1523" y="-658.48" font-family="Arial" font-size="10.00" fill="#111827">abstract commands, no SBA</text>
|
||||
<text text-anchor="middle" x="1523" y="-647.48" font-family="Arial" font-size="10.00" fill="#111827">management-hart-only reset</text>
|
||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M1282.5,-683.48C1282.5,-683.48 1161.5,-683.48 1161.5,-683.48 1155.5,-683.48 1149.5,-677.48 1149.5,-671.48 1149.5,-671.48 1149.5,-650.48 1149.5,-650.48 1149.5,-644.48 1155.5,-638.48 1161.5,-638.48 1161.5,-638.48 1282.5,-638.48 1282.5,-638.48 1288.5,-638.48 1294.5,-644.48 1294.5,-650.48 1294.5,-650.48 1294.5,-671.48 1294.5,-671.48 1294.5,-677.48 1288.5,-683.48 1282.5,-683.48"/>
|
||||
<text text-anchor="middle" x="1222" y="-669.48" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 Debug Module</text>
|
||||
<text text-anchor="middle" x="1222" y="-658.48" font-family="Arial" font-size="10.00" fill="#111827">abstract commands, no SBA</text>
|
||||
<text text-anchor="middle" x="1222" y="-647.48" font-family="Arial" font-size="10.00" fill="#111827">management-hart-only reset</text>
|
||||
</g>
|
||||
<!-- jtag_dtm->debug_module -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>jtag_dtm->debug_module</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1031.06,-679.13C1060.11,-708.33 1114,-762.48 1114,-762.48 1114,-762.48 1319,-762.48 1319,-762.48 1319,-762.48 1410.81,-716.8 1471.25,-686.73"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1472.55,-688.82 1477.73,-683.51 1470.37,-684.44 1472.55,-688.82"/>
|
||||
<text text-anchor="middle" x="1275" y="-795.08" font-family="Arial" font-size="8.00" fill="#374151">DMI, asynchronous CDC</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M730.06,-679.13C759.11,-708.33 813,-762.48 813,-762.48 813,-762.48 1018,-762.48 1018,-762.48 1018,-762.48 1109.81,-716.8 1170.25,-686.73"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1171.55,-688.82 1176.73,-683.51 1169.37,-684.44 1171.55,-688.82"/>
|
||||
<text text-anchor="middle" x="974" y="-795.08" font-family="Arial" font-size="8.00" fill="#374151">DMI, asynchronous CDC</text>
|
||||
</g>
|
||||
<!-- debug_module->mgmt_core -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>debug_module->mgmt_core</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1450.11,-660.98C1408.89,-660.98 1356.84,-660.98 1312.29,-660.98"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1312.21,-658.53 1305.21,-660.98 1312.21,-663.43 1312.21,-658.53"/>
|
||||
<text text-anchor="middle" x="1377.75" y="-666.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="M1149.11,-660.98C1107.89,-660.98 1055.84,-660.98 1011.29,-660.98"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1011.21,-658.53 1004.21,-660.98 1011.21,-663.43 1011.21,-658.53"/>
|
||||
<text text-anchor="middle" x="1076.75" y="-666.58" font-family="Arial" font-size="8.00" fill="#374151">halt, resume, abstract commands</text>
|
||||
</g>
|
||||
<!-- debug_module->mgmt_adapter -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>debug_module->mgmt_adapter</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M1450.23,-638.57C1373.31,-615.94 1263,-583.48 1263,-583.48 1263,-583.48 1259.87,-582.05 1255.22,-579.93"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1256.03,-577.6 1248.64,-576.92 1253.99,-582.06 1256.03,-577.6"/>
|
||||
<text text-anchor="middle" x="1407" y="-609.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="M1149.23,-638.57C1072.31,-615.94 962,-583.48 962,-583.48 962,-583.48 958.87,-582.05 954.22,-579.93"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="955.03,-577.6 947.64,-576.92 952.99,-582.06 955.03,-577.6"/>
|
||||
<text text-anchor="middle" x="1106" y="-609.08" font-family="Arial" font-size="8.00" fill="#374151">reset after bridge idle</text>
|
||||
</g>
|
||||
<!-- timers -->
|
||||
<g id="node20" class="node">
|
||||
<g id="node21" class="node">
|
||||
<title>timers</title>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1681.5,-255C1681.5,-255 1500.5,-255 1500.5,-255 1494.5,-255 1488.5,-249 1488.5,-243 1488.5,-243 1488.5,-222 1488.5,-222 1488.5,-216 1494.5,-210 1500.5,-210 1500.5,-210 1681.5,-210 1681.5,-210 1687.5,-210 1693.5,-216 1693.5,-222 1693.5,-222 1693.5,-243 1693.5,-243 1693.5,-249 1687.5,-255 1681.5,-255"/>
|
||||
<text text-anchor="middle" x="1591" y="-241" font-family="Arial" font-size="10.00" fill="#111827">General timers 0/1</text>
|
||||
<text text-anchor="middle" x="1591" y="-230" font-family="Arial" font-size="10.00" fill="#111827">32-bit counter, 16-bit prescaler</text>
|
||||
<text text-anchor="middle" x="1591" y="-219" font-family="Arial" font-size="10.00" fill="#111827">periodic / one-shot, compare, debug freeze</text>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1923.5,-255C1923.5,-255 1742.5,-255 1742.5,-255 1736.5,-255 1730.5,-249 1730.5,-243 1730.5,-243 1730.5,-222 1730.5,-222 1730.5,-216 1736.5,-210 1742.5,-210 1742.5,-210 1923.5,-210 1923.5,-210 1929.5,-210 1935.5,-216 1935.5,-222 1935.5,-222 1935.5,-243 1935.5,-243 1935.5,-249 1929.5,-255 1923.5,-255"/>
|
||||
<text text-anchor="middle" x="1833" y="-241" font-family="Arial" font-size="10.00" fill="#111827">General timers 0/1</text>
|
||||
<text text-anchor="middle" x="1833" y="-230" font-family="Arial" font-size="10.00" fill="#111827">32-bit counter, 16-bit prescaler</text>
|
||||
<text text-anchor="middle" x="1833" y="-219" font-family="Arial" font-size="10.00" fill="#111827">periodic / one-shot, compare, debug freeze</text>
|
||||
</g>
|
||||
<!-- debug_module->timers -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>debug_module->timers</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M1530.32,-638.24C1540.05,-609.36 1556,-561.98 1556,-561.98 1556,-561.98 1556,-561.98 1556,-336 1556,-336 1570.96,-292.2 1581.31,-261.86"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1583.63,-262.65 1583.58,-255.24 1579,-261.07 1583.63,-262.65"/>
|
||||
<text text-anchor="middle" x="1567" y="-444.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="M1294.55,-648.31C1456.04,-622.32 1831,-561.98 1831,-561.98 1831,-561.98 1831,-561.98 1831,-336 1831,-336 1831.85,-292.57 1832.44,-262.25"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1834.89,-262.28 1832.58,-255.24 1829.99,-262.19 1834.89,-262.28"/>
|
||||
<text text-anchor="middle" x="1842" y="-444.84" font-family="Arial" font-size="8.00" fill="#374151">halted</text>
|
||||
</g>
|
||||
<!-- mgmt_adapter->fabric -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>mgmt_adapter->fabric</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1197.65,-542.76C1180.99,-527.12 1159,-506.48 1159,-506.48 1159,-506.48 1097.55,-491.51 1036.71,-476.68"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1037.06,-474.24 1029.68,-474.96 1035.9,-479 1037.06,-474.24"/>
|
||||
<text text-anchor="middle" x="1175" y="-509.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M915,-542.94C915,-529.08 915,-508.91 915,-490.69"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="917.45,-490.57 915,-483.57 912.55,-490.57 917.45,-490.57"/>
|
||||
<text text-anchor="middle" x="922" y="-509.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="M1364,-583.48C1364,-583.48 1288,-583.48 1288,-583.48 1282,-583.48 1276,-577.48 1276,-571.48 1276,-571.48 1276,-550.48 1276,-550.48 1276,-544.48 1282,-538.48 1288,-538.48 1288,-538.48 1364,-538.48 1364,-538.48 1370,-538.48 1376,-544.48 1376,-550.48 1376,-550.48 1376,-571.48 1376,-571.48 1376,-577.48 1370,-583.48 1364,-583.48"/>
|
||||
<text text-anchor="middle" x="1326" y="-569.48" font-family="Arial" font-size="10.00" fill="#111827">Selected user core</text>
|
||||
<text text-anchor="middle" x="1326" y="-558.48" font-family="Arial" font-size="10.00" fill="#111827">C0-C5, one active</text>
|
||||
<text text-anchor="middle" x="1326" y="-547.48" font-family="Arial" font-size="10.00" fill="#111827">PicoRV32 at C5</text>
|
||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M1063,-583.48C1063,-583.48 987,-583.48 987,-583.48 981,-583.48 975,-577.48 975,-571.48 975,-571.48 975,-550.48 975,-550.48 975,-544.48 981,-538.48 987,-538.48 987,-538.48 1063,-538.48 1063,-538.48 1069,-538.48 1075,-544.48 1075,-550.48 1075,-550.48 1075,-571.48 1075,-571.48 1075,-577.48 1069,-583.48 1063,-583.48"/>
|
||||
<text text-anchor="middle" x="1025" y="-569.48" font-family="Arial" font-size="10.00" fill="#111827">Selected user core</text>
|
||||
<text text-anchor="middle" x="1025" y="-558.48" font-family="Arial" font-size="10.00" fill="#111827">C0-C5, one active</text>
|
||||
<text text-anchor="middle" x="1025" y="-547.48" font-family="Arial" font-size="10.00" fill="#111827">PicoRV32 at C5</text>
|
||||
</g>
|
||||
<!-- user_core->fabric -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>user_core->fabric</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1275.79,-540.52C1236.33,-525.22 1188,-506.48 1188,-506.48 1188,-506.48 1112.22,-490 1040.95,-474.49"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1041.43,-472.09 1034.07,-473 1040.39,-476.88 1041.43,-472.09"/>
|
||||
<text text-anchor="middle" x="1218" y="-509.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1003.79,-538.34C990.1,-524.37 971.85,-505.75 955.45,-489.02"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="957.08,-487.18 950.43,-483.89 953.58,-490.61 957.08,-487.18"/>
|
||||
<text text-anchor="middle" x="986" y="-509.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="M957,-578.98C957,-578.98 839,-578.98 839,-578.98 833,-578.98 827,-572.98 827,-566.98 827,-566.98 827,-554.98 827,-554.98 827,-548.98 833,-542.98 839,-542.98 839,-542.98 957,-542.98 957,-542.98 963,-542.98 969,-548.98 969,-554.98 969,-554.98 969,-566.98 969,-566.98 969,-572.98 963,-578.98 957,-578.98"/>
|
||||
<text text-anchor="middle" x="898" y="-563.98" font-family="Arial" font-size="10.00" fill="#111827">DMA</text>
|
||||
<text text-anchor="middle" x="898" y="-552.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="M1544,-578.98C1544,-578.98 1426,-578.98 1426,-578.98 1420,-578.98 1414,-572.98 1414,-566.98 1414,-566.98 1414,-554.98 1414,-554.98 1414,-548.98 1420,-542.98 1426,-542.98 1426,-542.98 1544,-542.98 1544,-542.98 1550,-542.98 1556,-548.98 1556,-554.98 1556,-554.98 1556,-566.98 1556,-566.98 1556,-572.98 1550,-578.98 1544,-578.98"/>
|
||||
<text text-anchor="middle" x="1485" y="-563.98" font-family="Arial" font-size="10.00" fill="#111827">DMA</text>
|
||||
<text text-anchor="middle" x="1485" y="-552.98" font-family="Arial" font-size="10.00" fill="#111827">RIB master and RIBP target</text>
|
||||
</g>
|
||||
<!-- dma->fabric -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>dma->fabric</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M969,-546.87C1040.09,-533.75 1139,-515.48 1139,-515.48 1139,-515.48 1139,-506.48 1139,-506.48 1139,-506.48 1086.59,-492.55 1032.81,-478.26"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1033.3,-475.86 1025.91,-476.43 1032.05,-480.59 1033.3,-475.86"/>
|
||||
<text text-anchor="middle" x="1146" y="-509.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1413.75,-545.15C1337.69,-529.32 1228,-506.48 1228,-506.48 1228,-506.48 1130.17,-488.12 1043.89,-471.93"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1044.24,-469.51 1036.91,-470.62 1043.34,-474.32 1044.24,-469.51"/>
|
||||
<text text-anchor="middle" x="1278" y="-509.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="M2135,-255C2135,-255 1975,-255 1975,-255 1969,-255 1963,-249 1963,-243 1963,-243 1963,-222 1963,-222 1963,-216 1969,-210 1975,-210 1975,-210 2135,-210 2135,-210 2141,-210 2147,-216 2147,-222 2147,-222 2147,-243 2147,-243 2147,-249 2141,-255 2135,-255"/>
|
||||
<text text-anchor="middle" x="2055" y="-241" font-family="Arial" font-size="10.00" fill="#111827">UART0 V2</text>
|
||||
<text text-anchor="middle" x="2055" y="-230" font-family="Arial" font-size="10.00" fill="#111827">64-byte TX/RX FIFOs, fractional baud</text>
|
||||
<text text-anchor="middle" x="2055" y="-219" font-family="Arial" font-size="10.00" fill="#111827">framing/errors, IRQ2, DMA-paced</text>
|
||||
</g>
|
||||
<!-- dma->uart0 -->
|
||||
<g id="edge33" class="edge">
|
||||
<title>dma->uart0</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M1512.85,-542.86C1586.53,-497.56 1781,-378 1781,-378 1781,-378 1929.1,-299.9 2007.53,-258.53"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2008.93,-260.57 2013.98,-255.13 2006.64,-256.23 2008.93,-260.57"/>
|
||||
<text text-anchor="middle" x="1802.5" y="-380.6" font-family="Arial" font-size="8.00" fill="#374151">TX/RX data</text>
|
||||
</g>
|
||||
<!-- ws2812 -->
|
||||
<g id="node21" class="node">
|
||||
<g id="node22" class="node">
|
||||
<title>ws2812</title>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M713,-255C713,-255 579,-255 579,-255 573,-255 567,-249 567,-243 567,-243 567,-222 567,-222 567,-216 573,-210 579,-210 579,-210 713,-210 713,-210 719,-210 725,-216 725,-222 725,-222 725,-243 725,-243 725,-249 719,-255 713,-255"/>
|
||||
<text text-anchor="middle" x="646" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WS2812 TX</text>
|
||||
<text text-anchor="middle" x="646" y="-230" font-family="Arial" font-size="10.00" fill="#111827">24-bit MSB-first serializer</text>
|
||||
<text text-anchor="middle" x="646" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16-word FIFO, IRQ17, DMA-fed</text>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1478,-255C1478,-255 1344,-255 1344,-255 1338,-255 1332,-249 1332,-243 1332,-243 1332,-222 1332,-222 1332,-216 1338,-210 1344,-210 1344,-210 1478,-210 1478,-210 1484,-210 1490,-216 1490,-222 1490,-222 1490,-243 1490,-243 1490,-249 1484,-255 1478,-255"/>
|
||||
<text text-anchor="middle" x="1411" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WS2812 TX</text>
|
||||
<text text-anchor="middle" x="1411" y="-230" font-family="Arial" font-size="10.00" fill="#111827">24-bit MSB-first serializer</text>
|
||||
<text text-anchor="middle" x="1411" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16-word FIFO, IRQ17, DMA-fed</text>
|
||||
</g>
|
||||
<!-- dma->ws2812 -->
|
||||
<g id="edge30" class="edge">
|
||||
<g id="edge31" class="edge">
|
||||
<title>dma->ws2812</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M859.18,-542.82C808.17,-520.26 725,-483.48 725,-483.48 725,-483.48 689,-278 689,-278 689,-278 681.11,-269.83 672.08,-260.49"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="673.62,-258.56 667,-255.23 670.1,-261.96 673.62,-258.56"/>
|
||||
<text text-anchor="middle" x="734.5" y="-380.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="M1484.69,-542.77C1483.61,-481.55 1480,-278 1480,-278 1480,-278 1466.13,-269.06 1450.83,-259.19"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1451.9,-256.96 1444.69,-255.23 1449.25,-261.08 1451.9,-256.96"/>
|
||||
<text text-anchor="middle" x="1508.5" y="-380.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="M1298.5,-464.74C1298.5,-464.74 1189.5,-464.74 1189.5,-464.74 1183.5,-464.74 1177.5,-458.74 1177.5,-452.74 1177.5,-452.74 1177.5,-440.74 1177.5,-440.74 1177.5,-434.74 1183.5,-428.74 1189.5,-428.74 1189.5,-428.74 1298.5,-428.74 1298.5,-428.74 1304.5,-428.74 1310.5,-434.74 1310.5,-440.74 1310.5,-440.74 1310.5,-452.74 1310.5,-452.74 1310.5,-458.74 1304.5,-464.74 1298.5,-464.74"/>
|
||||
<text text-anchor="middle" x="1244" y="-449.74" font-family="Arial" font-size="10.00" fill="#111827">Error slave</text>
|
||||
<text text-anchor="middle" x="1244" y="-438.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="M1295.5,-464.74C1295.5,-464.74 1186.5,-464.74 1186.5,-464.74 1180.5,-464.74 1174.5,-458.74 1174.5,-452.74 1174.5,-452.74 1174.5,-440.74 1174.5,-440.74 1174.5,-434.74 1180.5,-428.74 1186.5,-428.74 1186.5,-428.74 1295.5,-428.74 1295.5,-428.74 1301.5,-428.74 1307.5,-434.74 1307.5,-440.74 1307.5,-440.74 1307.5,-452.74 1307.5,-452.74 1307.5,-458.74 1301.5,-464.74 1295.5,-464.74"/>
|
||||
<text text-anchor="middle" x="1241" y="-449.74" font-family="Arial" font-size="10.00" fill="#111827">Error slave</text>
|
||||
<text text-anchor="middle" x="1241" y="-438.74" font-family="Arial" font-size="10.00" fill="#111827">access and protocol faults</text>
|
||||
</g>
|
||||
<!-- fabric->fault -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>fabric->fault</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1104.98,-446.74C1127.93,-446.74 1150.24,-446.74 1170.02,-446.74"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1104.69,-444.29 1097.69,-446.74 1104.69,-449.19 1104.69,-444.29"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1170.19,-449.19 1177.19,-446.74 1170.19,-444.29 1170.19,-449.19"/>
|
||||
<text text-anchor="middle" x="1137.56" y="-452.34" font-family="Arial" font-size="8.00" fill="#374151">invalid / denied</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1101.98,-446.74C1124.93,-446.74 1147.24,-446.74 1167.02,-446.74"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1101.69,-444.29 1094.69,-446.74 1101.69,-449.19 1101.69,-444.29"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1167.19,-449.19 1174.19,-446.74 1167.19,-444.29 1167.19,-449.19"/>
|
||||
<text text-anchor="middle" x="1134.56" y="-452.34" 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="M1448,-464.74C1448,-464.74 1350,-464.74 1350,-464.74 1344,-464.74 1338,-458.74 1338,-452.74 1338,-452.74 1338,-440.74 1338,-440.74 1338,-434.74 1344,-428.74 1350,-428.74 1350,-428.74 1448,-428.74 1448,-428.74 1454,-428.74 1460,-434.74 1460,-440.74 1460,-440.74 1460,-452.74 1460,-452.74 1460,-458.74 1454,-464.74 1448,-464.74"/>
|
||||
<text text-anchor="middle" x="1399" y="-449.74" font-family="Arial" font-size="10.00" fill="#111827">On-chip SRAM</text>
|
||||
<text text-anchor="middle" x="1399" y="-438.74" font-family="Arial" font-size="10.00" fill="#111827">optional RIB2RAM path</text>
|
||||
<path fill="#fff3c9" stroke="#4b5563" stroke-width="1.1" d="M1445,-464.74C1445,-464.74 1347,-464.74 1347,-464.74 1341,-464.74 1335,-458.74 1335,-452.74 1335,-452.74 1335,-440.74 1335,-440.74 1335,-434.74 1341,-428.74 1347,-428.74 1347,-428.74 1445,-428.74 1445,-428.74 1451,-428.74 1457,-434.74 1457,-440.74 1457,-440.74 1457,-452.74 1457,-452.74 1457,-458.74 1451,-464.74 1445,-464.74"/>
|
||||
<text text-anchor="middle" x="1396" y="-449.74" font-family="Arial" font-size="10.00" fill="#111827">On-chip SRAM</text>
|
||||
<text text-anchor="middle" x="1396" y="-438.74" font-family="Arial" font-size="10.00" fill="#111827">optional RIB2RAM path</text>
|
||||
</g>
|
||||
<!-- fabric->sram -->
|
||||
<g id="edge14" class="edge">
|
||||
<title>fabric->sram</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1024.32,-477.06C1074.69,-491.42 1124,-505.48 1124,-505.48 1124,-505.48 1138,-505.48 1138,-505.48 1138,-505.48 1324,-483.48 1324,-483.48 1324,-483.48 1338.84,-476.21 1355.32,-468.14"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1356.73,-470.18 1361.94,-464.9 1354.58,-465.78 1356.73,-470.18"/>
|
||||
<text text-anchor="middle" x="1131" y="-509.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1036.29,-471.06C1116.9,-487.22 1208,-505.48 1208,-505.48 1208,-505.48 1222,-505.48 1222,-505.48 1222,-505.48 1321,-483.48 1321,-483.48 1321,-483.48 1335.84,-476.21 1352.32,-468.14"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1353.73,-470.18 1358.94,-464.9 1351.58,-465.78 1353.73,-470.18"/>
|
||||
<text text-anchor="middle" x="1215" y="-509.08" 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="M938.5,-355C938.5,-355 897.5,-355 897.5,-355 891.5,-355 885.5,-349 885.5,-343 885.5,-343 885.5,-331 885.5,-331 885.5,-325 891.5,-319 897.5,-319 897.5,-319 938.5,-319 938.5,-319 944.5,-319 950.5,-325 950.5,-331 950.5,-331 950.5,-343 950.5,-343 950.5,-349 944.5,-355 938.5,-355"/>
|
||||
<text text-anchor="middle" x="918" y="-334.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M1253.5,-355C1253.5,-355 1212.5,-355 1212.5,-355 1206.5,-355 1200.5,-349 1200.5,-343 1200.5,-343 1200.5,-331 1200.5,-331 1200.5,-325 1206.5,-319 1212.5,-319 1212.5,-319 1253.5,-319 1253.5,-319 1259.5,-319 1265.5,-325 1265.5,-331 1265.5,-331 1265.5,-343 1265.5,-343 1265.5,-349 1259.5,-355 1253.5,-355"/>
|
||||
<text text-anchor="middle" x="1233" y="-334.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
||||
</g>
|
||||
<!-- fabric->ribp_adapter -->
|
||||
<g id="edge15" class="edge">
|
||||
<title>fabric->ribp_adapter</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M918,-409.87C918,-394.27 918,-376.39 918,-362.38"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="920.45,-362.02 918,-355.02 915.55,-362.02 920.45,-362.02"/>
|
||||
<text text-anchor="middle" x="925" y="-380.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1012.57,-412.68C1073.53,-392.03 1148.71,-366.56 1193.65,-351.33"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1194.49,-353.64 1200.33,-349.07 1192.91,-349 1194.49,-353.64"/>
|
||||
<text text-anchor="middle" x="1118" y="-380.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="M1395,-355C1395,-355 1325,-355 1325,-355 1319,-355 1313,-349 1313,-343 1313,-343 1313,-331 1313,-331 1313,-325 1319,-319 1325,-319 1325,-319 1395,-319 1395,-319 1401,-319 1407,-325 1407,-331 1407,-331 1407,-343 1407,-343 1407,-349 1401,-355 1395,-355"/>
|
||||
<text text-anchor="middle" x="1360" y="-340" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
|
||||
<text text-anchor="middle" x="1360" y="-329" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M662,-355C662,-355 592,-355 592,-355 586,-355 580,-349 580,-343 580,-343 580,-331 580,-331 580,-325 586,-319 592,-319 592,-319 662,-319 662,-319 668,-319 674,-325 674,-331 674,-331 674,-343 674,-343 674,-349 668,-355 662,-355"/>
|
||||
<text text-anchor="middle" x="627" y="-340" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
|
||||
<text text-anchor="middle" x="627" y="-329" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
|
||||
</g>
|
||||
<!-- fabric->apb_adapter -->
|
||||
<g id="edge16" class="edge">
|
||||
<title>fabric->apb_adapter</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1029.54,-418.55C1117.93,-397.01 1237.57,-367.84 1306,-351.16"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1306.64,-353.53 1312.86,-349.49 1305.48,-348.77 1306.64,-353.53"/>
|
||||
<text text-anchor="middle" x="1198" y="-380.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M846.72,-409.89C815.78,-393.64 786,-378 786,-378 786,-378 727.32,-363.24 681.26,-351.65"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="681.66,-349.22 674.27,-349.89 680.47,-353.98 681.66,-349.22"/>
|
||||
<text text-anchor="middle" x="808" y="-380.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="M1449.5,-255C1449.5,-255 1286.5,-255 1286.5,-255 1280.5,-255 1274.5,-249 1274.5,-243 1274.5,-243 1274.5,-222 1274.5,-222 1274.5,-216 1280.5,-210 1286.5,-210 1286.5,-210 1449.5,-210 1449.5,-210 1455.5,-210 1461.5,-216 1461.5,-222 1461.5,-222 1461.5,-243 1461.5,-243 1461.5,-249 1455.5,-255 1449.5,-255"/>
|
||||
<text text-anchor="middle" x="1368" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL</text>
|
||||
<text text-anchor="middle" x="1368" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user-core select/reset/bus enable</text>
|
||||
<text text-anchor="middle" x="1368" 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="M1691.5,-255C1691.5,-255 1528.5,-255 1528.5,-255 1522.5,-255 1516.5,-249 1516.5,-243 1516.5,-243 1516.5,-222 1516.5,-222 1516.5,-216 1522.5,-210 1528.5,-210 1528.5,-210 1691.5,-210 1691.5,-210 1697.5,-210 1703.5,-216 1703.5,-222 1703.5,-222 1703.5,-243 1703.5,-243 1703.5,-249 1697.5,-255 1691.5,-255"/>
|
||||
<text text-anchor="middle" x="1610" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL</text>
|
||||
<text text-anchor="middle" x="1610" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user-core select/reset/bus enable</text>
|
||||
<text text-anchor="middle" x="1610" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->sysctrl -->
|
||||
<g id="edge17" class="edge">
|
||||
<title>ribp_adapter->sysctrl</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M950.67,-331.33C1024.53,-320.78 1198,-296 1198,-296 1198,-296 1254.85,-275.1 1302.8,-257.47"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1303.77,-259.72 1309.5,-255.01 1302.08,-255.12 1303.77,-259.72"/>
|
||||
<text text-anchor="middle" x="1252.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1265.56,-320C1300.48,-302.83 1351,-278 1351,-278 1351,-278 1504,-255 1504,-255 1504,-255 1505.94,-254.61 1509.28,-253.93"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1509.79,-256.33 1516.16,-252.53 1508.81,-251.52 1509.79,-256.33"/>
|
||||
<text text-anchor="middle" x="1360.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->clint -->
|
||||
<g id="edge18" class="edge">
|
||||
<title>ribp_adapter->clint</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M885.32,-320.57C883.27,-319.6 882,-319 882,-319 882,-319 740,-296 740,-296 740,-296 708,-278 708,-278 708,-278 554,-255 554,-255 554,-255 551.14,-254.29 546.46,-253.14"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="547.02,-250.75 539.63,-251.45 545.84,-255.51 547.02,-250.75"/>
|
||||
<text text-anchor="middle" x="749.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1200.18,-333.65C1080.57,-325.07 675,-296 675,-296 675,-296 675,-278 675,-278 675,-278 681.01,-270.13 687.98,-261.01"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="690.1,-262.28 692.4,-255.23 686.2,-259.3 690.1,-262.28"/>
|
||||
<text text-anchor="middle" x="684.5" y="-285.1" 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="M1235.5,-255C1235.5,-255 1030.5,-255 1030.5,-255 1024.5,-255 1018.5,-249 1018.5,-243 1018.5,-243 1018.5,-222 1018.5,-222 1018.5,-216 1024.5,-210 1030.5,-210 1030.5,-210 1235.5,-210 1235.5,-210 1241.5,-210 1247.5,-216 1247.5,-222 1247.5,-222 1247.5,-243 1247.5,-243 1247.5,-249 1241.5,-255 1235.5,-255"/>
|
||||
<text text-anchor="middle" x="1133" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
|
||||
<text text-anchor="middle" x="1133" y="-230" font-family="Arial" font-size="10.00" fill="#111827">XPI/Flash, SDRAM, PSRAM, SPI-SD and DVP</text>
|
||||
<text text-anchor="middle" x="1133" y="-219" font-family="Arial" font-size="10.00" fill="#111827">UART0, I2C and I2S</text>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1292.5,-255C1292.5,-255 1087.5,-255 1087.5,-255 1081.5,-255 1075.5,-249 1075.5,-243 1075.5,-243 1075.5,-222 1075.5,-222 1075.5,-216 1081.5,-210 1087.5,-210 1087.5,-210 1292.5,-210 1292.5,-210 1298.5,-210 1304.5,-216 1304.5,-222 1304.5,-222 1304.5,-243 1304.5,-243 1304.5,-249 1298.5,-255 1292.5,-255"/>
|
||||
<text text-anchor="middle" x="1190" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
|
||||
<text text-anchor="middle" x="1190" y="-230" font-family="Arial" font-size="10.00" fill="#111827">XPI/Flash, SDRAM, PSRAM, SPI-SD and DVP</text>
|
||||
<text text-anchor="middle" x="1190" y="-219" font-family="Arial" font-size="10.00" fill="#111827">I2C and I2S</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->ribp_targets -->
|
||||
<g id="edge19" class="edge">
|
||||
<title>ribp_adapter->ribp_targets</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M950.65,-320.43C985.33,-303.9 1040.64,-277.53 1081.26,-258.17"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1082.38,-260.35 1087.65,-255.12 1080.28,-255.92 1082.38,-260.35"/>
|
||||
<text text-anchor="middle" x="1047.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1225.71,-318.61C1219.18,-303.05 1209.48,-279.94 1201.84,-261.72"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1204.1,-260.77 1199.13,-255.26 1199.58,-262.66 1204.1,-260.77"/>
|
||||
<text text-anchor="middle" x="1224.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->uart0 -->
|
||||
<g id="edge20" class="edge">
|
||||
<title>ribp_adapter->uart0</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1265.81,-331C1358.23,-316.94 1614,-278 1614,-278 1614,-278 1949,-255 1949,-255 1949,-255 1951.57,-254.48 1955.91,-253.6"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1956.48,-255.98 1962.86,-252.19 1955.51,-251.18 1956.48,-255.98"/>
|
||||
<text text-anchor="middle" x="1623.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- gpio_controller -->
|
||||
<g id="node19" class="node">
|
||||
<g id="node20" class="node">
|
||||
<title>gpio_controller</title>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M914,-255C914,-255 764,-255 764,-255 758,-255 752,-249 752,-243 752,-243 752,-222 752,-222 752,-216 758,-210 764,-210 764,-210 914,-210 914,-210 920,-210 926,-216 926,-222 926,-222 926,-243 926,-243 926,-249 920,-255 914,-255"/>
|
||||
<text text-anchor="middle" x="839" y="-241" font-family="Arial" font-size="10.00" fill="#111827">GPIO V2</text>
|
||||
<text text-anchor="middle" x="839" y="-230" font-family="Arial" font-size="10.00" fill="#111827">user + management RIBP windows</text>
|
||||
<text text-anchor="middle" x="839" 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="M971,-255C971,-255 821,-255 821,-255 815,-255 809,-249 809,-243 809,-243 809,-222 809,-222 809,-216 815,-210 821,-210 821,-210 971,-210 971,-210 977,-210 983,-216 983,-222 983,-222 983,-243 983,-243 983,-249 977,-255 971,-255"/>
|
||||
<text text-anchor="middle" x="896" y="-241" font-family="Arial" font-size="10.00" fill="#111827">GPIO V2</text>
|
||||
<text text-anchor="middle" x="896" y="-230" font-family="Arial" font-size="10.00" fill="#111827">user + management RIBP windows</text>
|
||||
<text text-anchor="middle" x="896" y="-219" font-family="Arial" font-size="10.00" fill="#111827">atomic I/O, filter, locks, IRQ18</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->gpio_controller -->
|
||||
<g id="edge20" class="edge">
|
||||
<g id="edge21" class="edge">
|
||||
<title>ribp_adapter->gpio_controller</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M904.6,-318.61C892.5,-302.91 874.48,-279.53 860.38,-261.25"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="861.98,-259.31 855.77,-255.26 858.1,-262.3 861.98,-259.31"/>
|
||||
<text text-anchor="middle" x="905" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<text text-anchor="middle" x="905" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">user/admin</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1200.46,-333.56C1084.74,-324.87 700,-296 700,-296 700,-296 700,-278 700,-278 700,-278 751.58,-266.29 801.82,-254.88"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="802.61,-257.22 808.89,-253.28 801.52,-252.44 802.61,-257.22"/>
|
||||
<text text-anchor="middle" x="720" y="-289.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<text text-anchor="middle" x="720" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">user/admin</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->timers -->
|
||||
<g id="edge21" class="edge">
|
||||
<g id="edge22" class="edge">
|
||||
<title>ribp_adapter->timers</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M950.61,-332.27C1037.5,-322.34 1268,-296 1268,-296 1268,-296 1387.71,-272.84 1481.38,-254.71"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1481.95,-257.1 1488.36,-253.36 1481.02,-252.29 1481.95,-257.1"/>
|
||||
<text text-anchor="middle" x="1363.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1265.59,-326.62C1306.67,-314.8 1372,-296 1372,-296 1372,-296 1406,-278 1406,-278 1406,-278 1717,-255 1717,-255 1717,-255 1719.33,-254.57 1723.33,-253.83"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1723.87,-256.22 1730.31,-252.53 1722.98,-251.4 1723.87,-256.22"/>
|
||||
<text text-anchor="middle" x="1415.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->ws2812 -->
|
||||
<g id="edge22" class="edge">
|
||||
<g id="edge23" class="edge">
|
||||
<title>ribp_adapter->ws2812</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M885.46,-323.74C842.24,-307.45 764.93,-278.32 709.85,-257.56"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="710.66,-255.25 703.25,-255.07 708.94,-259.84 710.66,-255.25"/>
|
||||
<text text-anchor="middle" x="815.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1250.38,-318.91C1267.79,-301.8 1292,-278 1292,-278 1292,-278 1318.5,-268.09 1346.5,-257.62"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1347.54,-259.84 1353.24,-255.1 1345.83,-255.26 1347.54,-259.84"/>
|
||||
<text text-anchor="middle" x="1301.5" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- apb_targets -->
|
||||
<g id="node22" class="node">
|
||||
<g id="node23" class="node">
|
||||
<title>apb_targets</title>
|
||||
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1923.5,-255C1923.5,-255 1732.5,-255 1732.5,-255 1726.5,-255 1720.5,-249 1720.5,-243 1720.5,-243 1720.5,-222 1720.5,-222 1720.5,-216 1726.5,-210 1732.5,-210 1732.5,-210 1923.5,-210 1923.5,-210 1929.5,-210 1935.5,-216 1935.5,-222 1935.5,-222 1935.5,-243 1935.5,-243 1935.5,-249 1929.5,-255 1923.5,-255"/>
|
||||
<text text-anchor="middle" x="1828" y="-241" font-family="Arial" font-size="10.00" fill="#111827">APB target wrapper</text>
|
||||
<text text-anchor="middle" x="1828" y="-230" font-family="Arial" font-size="10.00" fill="#111827">Archinfo, RNG, UART1, PWM, PS/2, RTC</text>
|
||||
<text text-anchor="middle" x="1828" y="-219" font-family="Arial" font-size="10.00" fill="#111827">watchdog, CRC, advanced timer and user IP</text>
|
||||
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M597.5,-255C597.5,-255 406.5,-255 406.5,-255 400.5,-255 394.5,-249 394.5,-243 394.5,-243 394.5,-222 394.5,-222 394.5,-216 400.5,-210 406.5,-210 406.5,-210 597.5,-210 597.5,-210 603.5,-210 609.5,-216 609.5,-222 609.5,-222 609.5,-243 609.5,-243 609.5,-249 603.5,-255 597.5,-255"/>
|
||||
<text text-anchor="middle" x="502" y="-241" font-family="Arial" font-size="10.00" fill="#111827">APB target wrapper</text>
|
||||
<text text-anchor="middle" x="502" y="-230" font-family="Arial" font-size="10.00" fill="#111827">Archinfo, RNG, UART1, PWM, PS/2, RTC</text>
|
||||
<text text-anchor="middle" x="502" y="-219" font-family="Arial" font-size="10.00" fill="#111827">watchdog, CRC, advanced timer and user IP</text>
|
||||
</g>
|
||||
<!-- apb_adapter->apb_targets -->
|
||||
<g id="edge23" class="edge">
|
||||
<g id="edge24" class="edge">
|
||||
<title>apb_adapter->apb_targets</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1407.02,-325.7C1480.36,-309.64 1623.83,-278.22 1722.74,-256.55"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1723.47,-258.9 1729.78,-255.01 1722.42,-254.12 1723.47,-258.9"/>
|
||||
<text text-anchor="middle" x="1630" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M606.08,-318.84C586.47,-302.77 556.88,-278.5 534.25,-259.95"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="535.63,-257.9 528.66,-255.36 532.52,-261.69 535.63,-257.9"/>
|
||||
<text text-anchor="middle" x="583" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
|
||||
</g>
|
||||
<!-- irq -->
|
||||
<g id="node24" class="node">
|
||||
<g id="node25" class="node">
|
||||
<title>irq</title>
|
||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M749,-155C749,-155 543,-155 543,-155 537,-155 531,-149 531,-143 531,-143 531,-131 531,-131 531,-125 537,-119 543,-119 543,-119 749,-119 749,-119 755,-119 761,-125 761,-131 761,-131 761,-143 761,-143 761,-149 755,-155 749,-155"/>
|
||||
<text text-anchor="middle" x="646" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
|
||||
<text text-anchor="middle" x="646" 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="M1515,-155C1515,-155 1309,-155 1309,-155 1303,-155 1297,-149 1297,-143 1297,-143 1297,-131 1297,-131 1297,-125 1303,-119 1309,-119 1309,-119 1515,-119 1515,-119 1521,-119 1527,-125 1527,-131 1527,-131 1527,-143 1527,-143 1527,-149 1521,-155 1515,-155"/>
|
||||
<text text-anchor="middle" x="1412" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
|
||||
<text text-anchor="middle" x="1412" y="-129" font-family="Arial" font-size="10.00" fill="#111827">RIBP and APB target IRQs to management core</text>
|
||||
</g>
|
||||
<!-- clint->irq -->
|
||||
<g id="edge28" class="edge">
|
||||
<g id="edge29" class="edge">
|
||||
<title>clint->irq</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M505.77,-209.89C532.41,-195.05 563,-178 563,-178 563,-178 583.39,-168.18 603.95,-158.26"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="605.08,-160.44 610.32,-155.2 602.95,-156.03 605.08,-160.44"/>
|
||||
<text text-anchor="middle" x="601.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="M781.63,-213.55C790.22,-211.43 796,-210 796,-210 796,-210 960,-178 960,-178 960,-178 1284,-155 1284,-155 1284,-155 1286.1,-154.72 1289.77,-154.23"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1290.12,-156.66 1296.74,-153.31 1289.48,-151.8 1290.12,-156.66"/>
|
||||
<text text-anchor="middle" x="998.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">machine IRQ0 / IRQ1</text>
|
||||
</g>
|
||||
<!-- ribp_targets->ext_io -->
|
||||
<g id="edge33" class="edge">
|
||||
<g id="edge36" class="edge">
|
||||
<title>ribp_targets->ext_io</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1111.03,-203.97C1079.15,-164.03 1020.42,-90.44 988.7,-50.69"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1109.27,-205.69 1115.55,-209.63 1113.1,-202.63 1109.27,-205.69"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="990.5,-49.02 984.22,-45.07 986.67,-52.07 990.5,-49.02"/>
|
||||
<text text-anchor="middle" x="1101" 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="M1311.9,-211.18C1316.39,-210.44 1319,-210 1319,-210 1319,-210 1564,-187 1564,-187 1564,-187 1573.65,-99.32 1578.82,-52.38"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1311.2,-208.82 1304.7,-212.38 1312.01,-213.65 1311.2,-208.82"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1581.28,-52.44 1579.61,-45.21 1576.41,-51.9 1581.28,-52.44"/>
|
||||
<text text-anchor="middle" x="1605" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
|
||||
</g>
|
||||
<!-- ribp_targets->gpio_controller -->
|
||||
<g id="edge24" class="edge">
|
||||
<g id="edge25" class="edge">
|
||||
<title>ribp_targets->gpio_controller</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1018.39,-232.5C990.19,-232.5 960.32,-232.5 933.21,-232.5"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="933.02,-230.05 926.02,-232.5 933.02,-234.95 933.02,-230.05"/>
|
||||
<text text-anchor="middle" x="972.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="M1075.39,-232.5C1047.19,-232.5 1017.32,-232.5 990.21,-232.5"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="990.02,-230.05 983.02,-232.5 990.02,-234.95 990.02,-230.05"/>
|
||||
<text text-anchor="middle" x="1029.25" y="-238.1" font-family="Arial" font-size="8.00" fill="#374151">alternate functions</text>
|
||||
</g>
|
||||
<!-- uart0->ext_io -->
|
||||
<g id="edge37" class="edge">
|
||||
<title>uart0->ext_io</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1999.17,-206.95C1908.15,-166.92 1728.85,-88.08 1637.83,-48.05"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1998.33,-209.25 2005.72,-209.83 2000.3,-204.77 1998.33,-209.25"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1638.56,-45.7 1631.17,-45.12 1636.59,-50.18 1638.56,-45.7"/>
|
||||
<text text-anchor="middle" x="1901" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">UART pads</text>
|
||||
</g>
|
||||
<!-- uart0->irq -->
|
||||
<g id="edge34" class="edge">
|
||||
<title>uart0->irq</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1962.86,-212.81C1954.44,-211.1 1949,-210 1949,-210 1949,-210 1692.67,-175.63 1534.2,-154.38"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1534.46,-151.95 1527.2,-153.45 1533.81,-156.8 1534.46,-151.95"/>
|
||||
<text text-anchor="middle" x="1784.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ2</text>
|
||||
</g>
|
||||
<!-- gpio_bridge -->
|
||||
<g id="node23" class="node">
|
||||
<g id="node24" class="node">
|
||||
<title>gpio_bridge</title>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M935.5,-155C935.5,-155 800.5,-155 800.5,-155 794.5,-155 788.5,-149 788.5,-143 788.5,-143 788.5,-131 788.5,-131 788.5,-125 794.5,-119 800.5,-119 800.5,-119 935.5,-119 935.5,-119 941.5,-119 947.5,-125 947.5,-131 947.5,-131 947.5,-143 947.5,-143 947.5,-149 941.5,-155 935.5,-155"/>
|
||||
<text text-anchor="middle" x="868" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
|
||||
<text text-anchor="middle" x="868" y="-129" font-family="Arial" font-size="10.00" fill="#111827">PDK capability-adapted controls</text>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M1258.5,-155C1258.5,-155 1123.5,-155 1123.5,-155 1117.5,-155 1111.5,-149 1111.5,-143 1111.5,-143 1111.5,-131 1111.5,-131 1111.5,-125 1117.5,-119 1123.5,-119 1123.5,-119 1258.5,-119 1258.5,-119 1264.5,-119 1270.5,-125 1270.5,-131 1270.5,-131 1270.5,-143 1270.5,-143 1270.5,-149 1264.5,-155 1258.5,-155"/>
|
||||
<text text-anchor="middle" x="1191" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
|
||||
<text text-anchor="middle" x="1191" y="-129" font-family="Arial" font-size="10.00" fill="#111827">PDK capability-adapted controls</text>
|
||||
</g>
|
||||
<!-- gpio_controller->gpio_bridge -->
|
||||
<g id="edge25" class="edge">
|
||||
<g id="edge26" class="edge">
|
||||
<title>gpio_controller->gpio_bridge</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M845.73,-209.81C850.15,-195.54 855.96,-176.83 860.53,-162.09"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="862.93,-162.62 862.66,-155.2 858.25,-161.16 862.93,-162.62"/>
|
||||
<text text-anchor="middle" x="875" 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="M964.05,-209.93C1014.27,-194.02 1082,-172.55 1130.36,-157.22"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1131.12,-159.55 1137.06,-155.1 1129.64,-154.88 1131.12,-159.55"/>
|
||||
<text text-anchor="middle" x="1081" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
|
||||
</g>
|
||||
<!-- gpio_controller->irq -->
|
||||
<g id="edge26" class="edge">
|
||||
<g id="edge27" class="edge">
|
||||
<title>gpio_controller->irq</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M780.27,-209.9C749.44,-198.56 718,-187 718,-187 718,-187 696.6,-172.44 677.14,-159.19"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="678.35,-157.05 671.18,-155.14 675.59,-161.1 678.35,-157.05"/>
|
||||
<text text-anchor="middle" x="730" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ18</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M983.24,-215.69C1073.8,-199.28 1215.3,-173.64 1310.73,-156.35"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1311.35,-158.73 1317.8,-155.07 1310.48,-153.91 1311.35,-158.73"/>
|
||||
<text text-anchor="middle" x="1196" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ18</text>
|
||||
</g>
|
||||
<!-- timers->irq -->
|
||||
<g id="edge27" class="edge">
|
||||
<g id="edge28" class="edge">
|
||||
<title>timers->irq</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1488.31,-212.47C1480.16,-210.96 1475,-210 1475,-210 1475,-210 775,-155 775,-155 775,-155 772.48,-154.67 768.16,-154.1"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="768.45,-151.67 761.19,-153.18 767.81,-156.52 768.45,-151.67"/>
|
||||
<text text-anchor="middle" x="1188.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="M1730.31,-212.47C1722.16,-210.96 1717,-210 1717,-210 1717,-210 1466,-187 1466,-187 1466,-187 1450.5,-172.93 1436.11,-159.88"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1437.72,-158.03 1430.89,-155.14 1434.42,-161.66 1437.72,-158.03"/>
|
||||
<text text-anchor="middle" x="1488.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ3 / IRQ4</text>
|
||||
</g>
|
||||
<!-- ws2812->gpio_bridge -->
|
||||
<g id="edge29" class="edge">
|
||||
<g id="edge30" class="edge">
|
||||
<title>ws2812->gpio_bridge</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M697.21,-209.93C734.46,-194.24 784.51,-173.16 820.8,-157.88"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="821.91,-160.07 827.41,-155.1 820,-155.56 821.91,-160.07"/>
|
||||
<text text-anchor="middle" x="792.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="M1360.25,-209.93C1323.34,-194.24 1273.74,-173.16 1237.78,-157.88"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1238.63,-155.58 1231.23,-155.1 1236.71,-160.09 1238.63,-155.58"/>
|
||||
<text text-anchor="middle" x="1323.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO2 ALT1</text>
|
||||
</g>
|
||||
<!-- ws2812->irq -->
|
||||
<g id="edge31" class="edge">
|
||||
<g id="edge32" class="edge">
|
||||
<title>ws2812->irq</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M646,-209.81C646,-195.66 646,-177.17 646,-162.49"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="648.45,-162.2 646,-155.2 643.55,-162.2 648.45,-162.2"/>
|
||||
<text text-anchor="middle" x="658" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ17</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1410.51,-209.77C1410.26,-198.48 1410,-187 1410,-187 1410,-187 1410,-178 1410,-178 1410,-178 1410.37,-170.7 1410.78,-162.33"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1413.24,-162.31 1411.14,-155.2 1408.34,-162.06 1413.24,-162.31"/>
|
||||
<text text-anchor="middle" x="1422" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ17</text>
|
||||
</g>
|
||||
<!-- apb_targets->gpio_controller -->
|
||||
<g id="edge32" class="edge">
|
||||
<g id="edge35" class="edge">
|
||||
<title>apb_targets->gpio_controller</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1720.41,-252.51C1712.19,-254.04 1707,-255 1707,-255 1707,-255 1192,-282.5 1192,-282.5 1192,-282.5 1156,-282.5 1156,-282.5 1156,-282.5 1026.45,-262.07 932.99,-247.32"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="933.34,-244.9 926.04,-246.23 932.57,-249.74 933.34,-244.9"/>
|
||||
<text text-anchor="middle" x="1174" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M609.73,-254.58C675.1,-267.97 746,-282.5 746,-282.5 746,-282.5 782,-282.5 782,-282.5 782,-282.5 809.78,-270.32 837.91,-257.98"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="839.24,-260.07 844.67,-255.01 837.27,-255.58 839.24,-260.07"/>
|
||||
<text text-anchor="middle" x="764" y="-285.1" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
|
||||
</g>
|
||||
<!-- gpio_bridge->ext_io -->
|
||||
<g id="edge34" class="edge">
|
||||
<g id="edge38" class="edge">
|
||||
<title>gpio_bridge->ext_io</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M887.73,-113.58C903.67,-95.47 926.16,-69.91 943.11,-50.65"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="885.82,-112.04 883.04,-118.91 889.5,-115.28 885.82,-112.04"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="944.95,-52.26 947.74,-45.39 941.27,-49.03 944.95,-52.26"/>
|
||||
<text text-anchor="middle" x="946" 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="M1228.68,-115.34C1254.46,-101.2 1284,-85 1284,-85 1284,-85 1386.02,-63.94 1470.68,-46.47"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1227.19,-113.36 1222.23,-118.88 1229.54,-117.66 1227.19,-113.36"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1471.41,-48.82 1477.77,-45.01 1470.42,-44.03 1471.41,-48.82"/>
|
||||
<text text-anchor="middle" x="1383" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 40 KiB |
@@ -32,8 +32,17 @@ interface dma_hw_trg_if ();
|
||||
logic i2s_rx_proc;
|
||||
logic qspi_tx_proc;
|
||||
logic qspi_rx_proc;
|
||||
logic uart_tx_proc;
|
||||
logic uart_rx_proc;
|
||||
|
||||
modport dut(input i2s_tx_proc, input i2s_rx_proc, input qspi_tx_proc, input qspi_rx_proc);
|
||||
modport dut(
|
||||
input i2s_tx_proc,
|
||||
input i2s_rx_proc,
|
||||
input qspi_tx_proc,
|
||||
input qspi_rx_proc,
|
||||
input uart_tx_proc,
|
||||
input uart_rx_proc
|
||||
);
|
||||
endinterface
|
||||
|
||||
`endif
|
||||
|
||||
@@ -39,6 +39,8 @@ module dma_core (
|
||||
localparam logic [2:0] HWT_I2S_RX_TRG = 3'd2;
|
||||
localparam logic [2:0] HWT_QSPI_TX_TRG = 3'd3;
|
||||
localparam logic [2:0] HWT_QSPI_RX_TRG = 3'd4;
|
||||
localparam logic [2:0] HWT_UART_TX_TRG = 3'd5;
|
||||
localparam logic [2:0] HWT_UART_RX_TRG = 3'd6;
|
||||
|
||||
localparam logic [2:0] FSM_IDLE = 3'd0;
|
||||
localparam logic [2:0] FSM_RD_CMD = 3'd1;
|
||||
@@ -86,6 +88,7 @@ module dma_core (
|
||||
unique case (mode_i)
|
||||
HWT_I2S_RX_TRG: s_read_trigger = hw_trg.i2s_rx_proc;
|
||||
HWT_QSPI_RX_TRG: s_read_trigger = hw_trg.qspi_rx_proc;
|
||||
HWT_UART_RX_TRG: s_read_trigger = hw_trg.uart_rx_proc;
|
||||
default: s_read_trigger = 1'b1;
|
||||
endcase
|
||||
end
|
||||
@@ -95,6 +98,7 @@ module dma_core (
|
||||
unique case (mode_i)
|
||||
HWT_I2S_TX_TRG: s_write_trigger = hw_trg.i2s_tx_proc;
|
||||
HWT_QSPI_TX_TRG: s_write_trigger = hw_trg.qspi_tx_proc;
|
||||
HWT_UART_TX_TRG: s_write_trigger = hw_trg.uart_tx_proc;
|
||||
default: s_write_trigger = 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module ribp_uart #(
|
||||
parameter int TX_FIFO_DEPTH = 64,
|
||||
parameter int RX_FIFO_DEPTH = 64
|
||||
) (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
output logic dma_tx_stall_o,
|
||||
output logic dma_rx_stall_o,
|
||||
ribp_if.slave ribp,
|
||||
uart_if.dut uart
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
logic [23:0] s_baud_int;
|
||||
logic [ 7:0] s_baud_frac;
|
||||
logic [ 1:0] s_data_bits;
|
||||
logic s_stop2;
|
||||
logic [ 1:0] s_parity;
|
||||
logic s_tx_enable;
|
||||
logic s_rx_enable;
|
||||
logic s_loopback;
|
||||
logic s_break;
|
||||
logic s_tx_data_valid;
|
||||
logic [ 7:0] s_tx_data;
|
||||
logic s_tx_data_pop;
|
||||
logic s_tx_busy;
|
||||
logic s_tx_done;
|
||||
logic s_rx_active;
|
||||
logic s_rx_data_valid;
|
||||
logic [11:0] s_rx_data;
|
||||
logic s_bit_tick;
|
||||
logic s_irq;
|
||||
logic s_tx;
|
||||
|
||||
assign uart.tx_o = s_tx;
|
||||
assign uart.irq_o = s_irq;
|
||||
|
||||
uart_reg #(
|
||||
.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)
|
||||
);
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
`ifndef RIBP_UART_DEFINE_SVH
|
||||
`define RIBP_UART_DEFINE_SVH
|
||||
|
||||
// verilog_format: off
|
||||
`define RIBP_UART_BAUD_INT 8'h00
|
||||
`define RIBP_UART_BAUD_FRAC 8'h04
|
||||
`define RIBP_UART_LINE_CTRL 8'h08
|
||||
`define RIBP_UART_CTRL 8'h0C
|
||||
`define RIBP_UART_TXDATA 8'h10
|
||||
`define RIBP_UART_RXDATA 8'h14
|
||||
`define RIBP_UART_STATUS 8'h18
|
||||
`define RIBP_UART_FIFO_LEVEL 8'h1C
|
||||
`define RIBP_UART_FIFO_CTRL 8'h20
|
||||
`define RIBP_UART_TX_WATERMARK 8'h24
|
||||
`define RIBP_UART_RX_WATERMARK 8'h28
|
||||
`define RIBP_UART_RX_TIMEOUT_BITS 8'h2C
|
||||
`define RIBP_UART_ERROR_STATUS 8'h30
|
||||
`define RIBP_UART_INTR_STATE 8'h34
|
||||
`define RIBP_UART_INTR_ENABLE 8'h38
|
||||
`define RIBP_UART_INTR_STATUS 8'h3C
|
||||
`define RIBP_UART_INTR_TEST 8'h40
|
||||
`define RIBP_UART_DMA_CTRL 8'h44
|
||||
`define RIBP_UART_IP_VERSION 8'hF8
|
||||
`define RIBP_UART_CAPABILITY 8'hFC
|
||||
|
||||
`define UART_LINE_DATA_BITS 0
|
||||
`define UART_LINE_STOP2 2
|
||||
`define UART_LINE_PARITY 3
|
||||
|
||||
`define UART_CTRL_TX_ENABLE 0
|
||||
`define UART_CTRL_RX_ENABLE 1
|
||||
`define UART_CTRL_LOOPBACK 2
|
||||
`define UART_CTRL_TX_BREAK 3
|
||||
|
||||
`define UART_FIFO_CTRL_TX_FLUSH 0
|
||||
`define UART_FIFO_CTRL_RX_FLUSH 1
|
||||
|
||||
`define UART_STATUS_TX_ENABLED 0
|
||||
`define UART_STATUS_RX_ENABLED 1
|
||||
`define UART_STATUS_TX_BUSY 2
|
||||
`define UART_STATUS_RX_ACTIVE 3
|
||||
`define UART_STATUS_TX_EMPTY 4
|
||||
`define UART_STATUS_TX_FULL 5
|
||||
`define UART_STATUS_RX_EMPTY 6
|
||||
`define UART_STATUS_RX_FULL 7
|
||||
`define UART_STATUS_CONFIG_VALID 8
|
||||
`define UART_STATUS_BREAK_ACTIVE 9
|
||||
`define UART_STATUS_TX_DMA_REQ 10
|
||||
`define UART_STATUS_RX_DMA_REQ 11
|
||||
|
||||
`define UART_RXDATA_PARITY_ERROR 8
|
||||
`define UART_RXDATA_FRAME_ERROR 9
|
||||
`define UART_RXDATA_BREAK 10
|
||||
`define UART_RXDATA_NOISE 11
|
||||
|
||||
`define UART_ERROR_OVERRUN 0
|
||||
`define UART_ERROR_PARITY 1
|
||||
`define UART_ERROR_FRAME 2
|
||||
`define UART_ERROR_BREAK 3
|
||||
`define UART_ERROR_NOISE 4
|
||||
`define UART_ERROR_CONFIG 5
|
||||
`define UART_ERROR_COMMAND 6
|
||||
|
||||
`define UART_INTR_RX_WATERMARK 0
|
||||
`define UART_INTR_RX_TIMEOUT 1
|
||||
`define UART_INTR_TX_WATERMARK 2
|
||||
`define UART_INTR_TX_DONE 3
|
||||
`define UART_INTR_RX_ERROR 4
|
||||
`define UART_INTR_BREAK 5
|
||||
|
||||
`define UART_DMA_TX_ENABLE 0
|
||||
`define UART_DMA_RX_ENABLE 1
|
||||
// verilog_format: on
|
||||
|
||||
`endif
|
||||
@@ -0,0 +1,239 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module ribp_uart_rx (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
input logic sample_tick_i,
|
||||
input logic enable_i,
|
||||
input logic [ 1:0] data_bits_i,
|
||||
input logic stop2_i,
|
||||
input logic [ 1:0] parity_i,
|
||||
input logic rx_i,
|
||||
output logic active_o,
|
||||
output logic data_valid_o,
|
||||
output logic [11:0] data_o
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
localparam logic [2:0] STATE_IDLE = 3'd0;
|
||||
localparam logic [2:0] STATE_START = 3'd1;
|
||||
localparam logic [2:0] STATE_DATA = 3'd2;
|
||||
localparam logic [2:0] STATE_PARITY = 3'd3;
|
||||
localparam logic [2:0] STATE_STOP1 = 3'd4;
|
||||
localparam logic [2:0] STATE_STOP2 = 3'd5;
|
||||
|
||||
logic s_rx_meta_d, s_rx_meta_q;
|
||||
logic s_rx_sync_d, s_rx_sync_q;
|
||||
logic [2:0] s_state_d, s_state_q;
|
||||
logic [3:0] s_sample_d, s_sample_q;
|
||||
logic [2:0] s_bit_d, s_bit_q;
|
||||
logic [1:0] s_sample_sum_d, s_sample_sum_q;
|
||||
logic s_sample_and_d, s_sample_and_q;
|
||||
logic s_sample_or_d, s_sample_or_q;
|
||||
logic s_sample_value_d, s_sample_value_q;
|
||||
logic [7:0] s_data_d, s_data_q;
|
||||
logic s_parity_error_d, s_parity_error_q;
|
||||
logic s_frame_error_d, s_frame_error_q;
|
||||
logic s_noise_d, s_noise_q;
|
||||
logic [2:0] s_last_bit;
|
||||
logic [7:0] s_data_mask;
|
||||
logic s_majority;
|
||||
logic s_samples_mixed;
|
||||
logic s_expected_parity;
|
||||
|
||||
assign s_rx_meta_d = rx_i;
|
||||
assign s_rx_sync_d = s_rx_meta_q;
|
||||
assign s_last_bit = 3'd4 + {1'b0, data_bits_i};
|
||||
assign s_majority = (s_sample_sum_q + s_rx_sync_q) >= 2'd2;
|
||||
assign s_samples_mixed = (s_sample_and_q & s_rx_sync_q) != (s_sample_or_q | s_rx_sync_q);
|
||||
assign active_o = s_state_q != STATE_IDLE;
|
||||
|
||||
always_comb begin
|
||||
unique case (data_bits_i)
|
||||
2'd0: s_data_mask = 8'h1F;
|
||||
2'd1: s_data_mask = 8'h3F;
|
||||
2'd2: s_data_mask = 8'h7F;
|
||||
default: s_data_mask = 8'hFF;
|
||||
endcase
|
||||
end
|
||||
assign s_expected_parity = (parity_i == 2'd2) ? ~^(s_data_q & s_data_mask) :
|
||||
^(s_data_q & s_data_mask);
|
||||
|
||||
always_comb begin
|
||||
s_state_d = s_state_q;
|
||||
s_sample_d = s_sample_q;
|
||||
s_bit_d = s_bit_q;
|
||||
s_sample_sum_d = s_sample_sum_q;
|
||||
s_sample_and_d = s_sample_and_q;
|
||||
s_sample_or_d = s_sample_or_q;
|
||||
s_sample_value_d = s_sample_value_q;
|
||||
s_data_d = s_data_q;
|
||||
s_parity_error_d = s_parity_error_q;
|
||||
s_frame_error_d = s_frame_error_q;
|
||||
s_noise_d = s_noise_q;
|
||||
data_valid_o = 1'b0;
|
||||
data_o = {
|
||||
s_noise_q,
|
||||
(s_frame_error_q && (s_data_q == 8'd0)),
|
||||
s_frame_error_q,
|
||||
s_parity_error_q,
|
||||
s_data_q
|
||||
};
|
||||
|
||||
if (!enable_i) begin
|
||||
s_state_d = STATE_IDLE;
|
||||
s_sample_d = '0;
|
||||
s_bit_d = '0;
|
||||
s_parity_error_d = 1'b0;
|
||||
s_frame_error_d = 1'b0;
|
||||
s_noise_d = 1'b0;
|
||||
end else if ((s_state_q == STATE_IDLE) && !s_rx_sync_q) begin
|
||||
s_state_d = STATE_START;
|
||||
s_sample_d = '0;
|
||||
s_bit_d = '0;
|
||||
s_data_d = '0;
|
||||
s_parity_error_d = 1'b0;
|
||||
s_frame_error_d = 1'b0;
|
||||
s_noise_d = 1'b0;
|
||||
end else if ((s_state_q != STATE_IDLE) && sample_tick_i) begin
|
||||
if (s_sample_q == 4'd7) begin
|
||||
s_sample_sum_d = {1'b0, s_rx_sync_q};
|
||||
s_sample_and_d = s_rx_sync_q;
|
||||
s_sample_or_d = s_rx_sync_q;
|
||||
end else if (s_sample_q == 4'd8) begin
|
||||
s_sample_sum_d = s_sample_sum_q + s_rx_sync_q;
|
||||
s_sample_and_d = s_sample_and_q & s_rx_sync_q;
|
||||
s_sample_or_d = s_sample_or_q | s_rx_sync_q;
|
||||
end else if (s_sample_q == 4'd9) begin
|
||||
s_sample_value_d = s_majority;
|
||||
s_noise_d = s_noise_q | s_samples_mixed;
|
||||
unique case (s_state_q)
|
||||
STATE_DATA: s_data_d[s_bit_q] = s_majority;
|
||||
STATE_PARITY: s_parity_error_d = s_majority != s_expected_parity;
|
||||
STATE_STOP1: s_frame_error_d = !s_majority;
|
||||
STATE_STOP2: s_frame_error_d = s_frame_error_q | !s_majority;
|
||||
default: begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (s_sample_q != 4'd15) begin
|
||||
s_sample_d = s_sample_q + 1'b1;
|
||||
end else begin
|
||||
s_sample_d = '0;
|
||||
unique case (s_state_q)
|
||||
STATE_START: begin
|
||||
if (s_sample_value_q) begin
|
||||
s_state_d = STATE_IDLE;
|
||||
end else begin
|
||||
s_state_d = STATE_DATA;
|
||||
end
|
||||
end
|
||||
STATE_DATA: begin
|
||||
if (s_bit_q == s_last_bit) begin
|
||||
s_state_d = (parity_i == 2'd0) ? STATE_STOP1 : STATE_PARITY;
|
||||
end else begin
|
||||
s_bit_d = s_bit_q + 1'b1;
|
||||
end
|
||||
end
|
||||
STATE_PARITY: s_state_d = STATE_STOP1;
|
||||
STATE_STOP1: begin
|
||||
if (stop2_i) begin
|
||||
s_state_d = STATE_STOP2;
|
||||
end else begin
|
||||
s_state_d = STATE_IDLE;
|
||||
data_valid_o = 1'b1;
|
||||
end
|
||||
end
|
||||
STATE_STOP2: begin
|
||||
s_state_d = STATE_IDLE;
|
||||
data_valid_o = 1'b1;
|
||||
end
|
||||
default: s_state_d = STATE_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dffr #(1) u_rx_meta_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_rx_meta_d),
|
||||
.dat_o (s_rx_meta_q)
|
||||
);
|
||||
dffr #(1) u_rx_sync_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_rx_sync_d),
|
||||
.dat_o (s_rx_sync_q)
|
||||
);
|
||||
dffr #(3) u_state_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_state_d),
|
||||
.dat_o (s_state_q)
|
||||
);
|
||||
dffr #(4) u_sample_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_sample_d),
|
||||
.dat_o (s_sample_q)
|
||||
);
|
||||
dffr #(3) u_bit_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_bit_d),
|
||||
.dat_o (s_bit_q)
|
||||
);
|
||||
dffr #(2) u_sample_sum_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_sample_sum_d),
|
||||
.dat_o (s_sample_sum_q)
|
||||
);
|
||||
dffr #(1) u_sample_and_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_sample_and_d),
|
||||
.dat_o (s_sample_and_q)
|
||||
);
|
||||
dffr #(1) u_sample_or_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_sample_or_d),
|
||||
.dat_o (s_sample_or_q)
|
||||
);
|
||||
dffr #(1) u_sample_value_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_sample_value_d),
|
||||
.dat_o (s_sample_value_q)
|
||||
);
|
||||
dffr #(8) u_data_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_data_d),
|
||||
.dat_o (s_data_q)
|
||||
);
|
||||
dffr #(1) u_parity_error_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_parity_error_d),
|
||||
.dat_o (s_parity_error_q)
|
||||
);
|
||||
dffr #(1) u_frame_error_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_frame_error_d),
|
||||
.dat_o (s_frame_error_q)
|
||||
);
|
||||
dffr #(1) u_noise_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_noise_d),
|
||||
.dat_o (s_noise_q)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,143 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module ribp_uart_tx (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
input logic sample_tick_i,
|
||||
input logic enable_i,
|
||||
input logic break_i,
|
||||
input logic [1:0] data_bits_i,
|
||||
input logic stop2_i,
|
||||
input logic [1:0] parity_i,
|
||||
input logic data_valid_i,
|
||||
input logic [7:0] data_i,
|
||||
output logic data_pop_o,
|
||||
output logic busy_o,
|
||||
output logic done_o,
|
||||
output logic tx_o
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
localparam logic [2:0] STATE_IDLE = 3'd0;
|
||||
localparam logic [2:0] STATE_START = 3'd1;
|
||||
localparam logic [2:0] STATE_DATA = 3'd2;
|
||||
localparam logic [2:0] STATE_PARITY = 3'd3;
|
||||
localparam logic [2:0] STATE_STOP1 = 3'd4;
|
||||
localparam logic [2:0] STATE_STOP2 = 3'd5;
|
||||
|
||||
logic [2:0] s_state_d, s_state_q;
|
||||
logic [3:0] s_sample_d, s_sample_q;
|
||||
logic [2:0] s_bit_d, s_bit_q;
|
||||
logic [7:0] s_shift_d, s_shift_q;
|
||||
logic s_parity_d, s_parity_q;
|
||||
logic [2:0] s_last_bit;
|
||||
logic [7:0] s_data_mask;
|
||||
|
||||
always_comb begin
|
||||
unique case (data_bits_i)
|
||||
2'd0: s_data_mask = 8'h1F;
|
||||
2'd1: s_data_mask = 8'h3F;
|
||||
2'd2: s_data_mask = 8'h7F;
|
||||
default: s_data_mask = 8'hFF;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign s_last_bit = 3'd4 + {1'b0, data_bits_i};
|
||||
assign busy_o = s_state_q != STATE_IDLE;
|
||||
|
||||
always_comb begin
|
||||
unique case (s_state_q)
|
||||
STATE_START: tx_o = 1'b0;
|
||||
STATE_DATA: tx_o = s_shift_q[0];
|
||||
STATE_PARITY: tx_o = s_parity_q;
|
||||
default: tx_o = 1'b1;
|
||||
endcase
|
||||
if (break_i) begin
|
||||
tx_o = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
s_state_d = s_state_q;
|
||||
s_sample_d = s_sample_q;
|
||||
s_bit_d = s_bit_q;
|
||||
s_shift_d = s_shift_q;
|
||||
s_parity_d = s_parity_q;
|
||||
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
|
||||
s_state_d = STATE_START;
|
||||
s_sample_d = '0;
|
||||
s_bit_d = '0;
|
||||
s_shift_d = data_i;
|
||||
s_parity_d = (parity_i == 2'd2) ? ~^(data_i & s_data_mask) : ^(data_i & s_data_mask);
|
||||
data_pop_o = 1'b1;
|
||||
end else if ((s_state_q != STATE_IDLE) && sample_tick_i) begin
|
||||
if (s_sample_q != 4'd15) begin
|
||||
s_sample_d = s_sample_q + 1'b1;
|
||||
end else begin
|
||||
s_sample_d = '0;
|
||||
unique case (s_state_q)
|
||||
STATE_START: s_state_d = STATE_DATA;
|
||||
STATE_DATA: begin
|
||||
s_shift_d = {1'b0, s_shift_q[7:1]};
|
||||
if (s_bit_q == s_last_bit) begin
|
||||
s_state_d = (parity_i == 2'd0) ? STATE_STOP1 : STATE_PARITY;
|
||||
end else begin
|
||||
s_bit_d = s_bit_q + 1'b1;
|
||||
end
|
||||
end
|
||||
STATE_PARITY: s_state_d = STATE_STOP1;
|
||||
STATE_STOP1: begin
|
||||
if (stop2_i) begin
|
||||
s_state_d = STATE_STOP2;
|
||||
end else begin
|
||||
s_state_d = STATE_IDLE;
|
||||
done_o = 1'b1;
|
||||
end
|
||||
end
|
||||
STATE_STOP2: begin
|
||||
s_state_d = STATE_IDLE;
|
||||
done_o = 1'b1;
|
||||
end
|
||||
default: s_state_d = STATE_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dffr #(3) u_state_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_state_d),
|
||||
.dat_o (s_state_q)
|
||||
);
|
||||
dffr #(4) u_sample_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_sample_d),
|
||||
.dat_o (s_sample_q)
|
||||
);
|
||||
dffr #(3) u_bit_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_bit_d),
|
||||
.dat_o (s_bit_q)
|
||||
);
|
||||
dffr #(8) u_shift_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_shift_d),
|
||||
.dat_o (s_shift_q)
|
||||
);
|
||||
dffr #(1) u_parity_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_parity_d),
|
||||
.dat_o (s_parity_q)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Ravenna - A full example SoC using PicoRV32 in ASIC
|
||||
*
|
||||
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
|
||||
* Copyright (C) 2018,2019 Tim Edwards <tim@efabless.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
// -- Adaptable modifications are redistributed under compatible License --
|
||||
//
|
||||
// Copyright (c) 2023-2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
// You may obtain a copy of Mulan PSL v2 at:
|
||||
// http://license.coscl.org.cn/MulanPSL2
|
||||
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
// See the Mulan PSL v2 for more details.
|
||||
|
||||
`ifndef RIBP_UART_DEF_SV
|
||||
`define RIBP_UART_DEF_SV
|
||||
|
||||
// verilog_format: off
|
||||
`define RIBP_UART_DIV 8'h00
|
||||
`define RIBP_UART_DAT 8'h04
|
||||
// verilog_format: on
|
||||
|
||||
`endif
|
||||
|
||||
module ribp_uart (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
ribp_if.slave ribp,
|
||||
uart_if.dut uart
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
logic s_ribp_wr_hdshk, s_ribp_rd_hdshk;
|
||||
logic s_ribp_ready_d, s_ribp_ready_q;
|
||||
logic s_ribp_rdata_en;
|
||||
logic [31:0] s_ribp_rdata_d, s_ribp_rdata_q;
|
||||
|
||||
logic s_uart_div_en;
|
||||
logic [31:0] s_uart_div_d, s_uart_div_q;
|
||||
logic s_send_dat_wait;
|
||||
logic s_uart_dat_en;
|
||||
// register
|
||||
logic [ 3:0] r_recv_state;
|
||||
logic [31:0] r_recv_divcnt;
|
||||
logic [ 7:0] r_recv_pattern;
|
||||
logic [ 7:0] r_recv_buf_data;
|
||||
logic r_recv_buf_valid;
|
||||
logic [ 9:0] r_send_pattern;
|
||||
logic [ 3:0] r_send_bitcnt;
|
||||
logic [31:0] r_send_divcnt;
|
||||
logic r_send_dummy;
|
||||
|
||||
|
||||
assign s_ribp_wr_hdshk = ribp.valid && (~s_ribp_ready_q) && (|ribp.wstrb);
|
||||
assign s_ribp_rd_hdshk = ribp.valid && (~s_ribp_ready_q) && (~(|ribp.wstrb));
|
||||
assign ribp.ready = s_ribp_ready_q;
|
||||
assign ribp.resp_err = 1'b0;
|
||||
assign ribp.rdata = s_ribp_rdata_q;
|
||||
|
||||
assign uart.tx_o = r_send_pattern[0];
|
||||
assign uart.irq_o = r_recv_buf_valid;
|
||||
|
||||
assign s_uart_div_en = s_ribp_wr_hdshk && ribp.addr[7:0] == `RIBP_UART_DIV;
|
||||
always_comb begin
|
||||
s_uart_div_d = s_uart_div_q;
|
||||
if (ribp.wstrb[0]) s_uart_div_d[7:0] = ribp.wdata[7:0];
|
||||
if (ribp.wstrb[1]) s_uart_div_d[15:8] = ribp.wdata[15:8];
|
||||
if (ribp.wstrb[2]) s_uart_div_d[23:16] = ribp.wdata[23:16];
|
||||
if (ribp.wstrb[3]) s_uart_div_d[31:24] = ribp.wdata[31:24];
|
||||
end
|
||||
dfferh #(32) u_uart_div_dfferh (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_uart_div_en,
|
||||
s_uart_div_d,
|
||||
s_uart_div_q
|
||||
);
|
||||
|
||||
assign s_uart_dat_en = s_ribp_wr_hdshk && ribp.addr[7:0] == `RIBP_UART_DAT;
|
||||
assign s_send_dat_wait = s_uart_dat_en && ribp.wstrb[0] && ((|r_send_bitcnt) || r_send_dummy);
|
||||
assign s_ribp_ready_d = ribp.valid && (~s_ribp_ready_q) && (~s_send_dat_wait);
|
||||
dffr #(1) u_ribp_ready_dffr (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_ribp_ready_d,
|
||||
s_ribp_ready_q
|
||||
);
|
||||
|
||||
assign s_ribp_rdata_en = s_ribp_rd_hdshk;
|
||||
always_comb begin
|
||||
s_ribp_rdata_d = s_ribp_rdata_q;
|
||||
unique case (ribp.addr[7:0])
|
||||
`RIBP_UART_DIV: s_ribp_rdata_d = s_uart_div_q;
|
||||
`RIBP_UART_DAT: s_ribp_rdata_d = r_recv_buf_valid ? {24'd0, r_recv_buf_data} : '1;
|
||||
default: s_ribp_rdata_d = s_ribp_rdata_q;
|
||||
endcase
|
||||
end
|
||||
dffer #(32) u_ribp_rdata_dffer (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_ribp_rdata_en,
|
||||
s_ribp_rdata_d,
|
||||
s_ribp_rdata_q
|
||||
);
|
||||
|
||||
|
||||
always_ff @(posedge clk_i, negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
r_recv_state <= '0;
|
||||
r_recv_divcnt <= '0;
|
||||
r_recv_pattern <= '0;
|
||||
r_recv_buf_data <= '0;
|
||||
r_recv_buf_valid <= '0;
|
||||
end else begin
|
||||
r_recv_divcnt <= r_recv_divcnt + 1'b1;
|
||||
if (s_uart_dat_en) r_recv_buf_valid <= '0;
|
||||
case (r_recv_state)
|
||||
4'd0: begin
|
||||
if (!uart.rx_i) r_recv_state <= 4'b1;
|
||||
r_recv_divcnt <= '0;
|
||||
end
|
||||
4'd1: begin
|
||||
if (2 * r_recv_divcnt > s_uart_div_q) begin
|
||||
r_recv_state <= 4'd2;
|
||||
r_recv_divcnt <= '0;
|
||||
end
|
||||
end
|
||||
4'd10: begin
|
||||
if (r_recv_divcnt > s_uart_div_q) begin
|
||||
r_recv_buf_data <= r_recv_pattern;
|
||||
r_recv_buf_valid <= 1'b1;
|
||||
r_recv_state <= '0;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
if (r_recv_divcnt > s_uart_div_q) begin
|
||||
r_recv_pattern <= {uart.rx_i, r_recv_pattern[7:1]};
|
||||
r_recv_state <= r_recv_state + 1'b1;
|
||||
r_recv_divcnt <= '0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i, negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
r_send_pattern <= '1;
|
||||
r_send_bitcnt <= '0;
|
||||
r_send_divcnt <= '0;
|
||||
r_send_dummy <= 1'b1;
|
||||
end else begin
|
||||
if (s_uart_div_en) r_send_dummy <= 1'b1;
|
||||
r_send_divcnt <= r_send_divcnt + 1'b1;
|
||||
|
||||
if (r_send_dummy && (~(|r_send_bitcnt))) begin
|
||||
r_send_pattern <= '1;
|
||||
r_send_bitcnt <= 4'd15;
|
||||
r_send_divcnt <= '0;
|
||||
r_send_dummy <= '0;
|
||||
end else if (s_uart_dat_en && ribp.wstrb[0] && (~(|r_send_bitcnt))) begin
|
||||
r_send_pattern <= {1'b1, ribp.wdata[7:0], 1'b0};
|
||||
`ifndef SYNTHESIS
|
||||
`ifdef SIMU_VERILATOR
|
||||
$write("%c", ribp.wdata[7:0]); // NOTE: just for verilator sim
|
||||
`endif
|
||||
`endif
|
||||
r_send_bitcnt <= 4'd10;
|
||||
r_send_divcnt <= '0;
|
||||
end else if (r_send_divcnt > s_uart_div_q && (|r_send_bitcnt)) begin
|
||||
r_send_pattern <= {1'b1, r_send_pattern[9:1]};
|
||||
r_send_bitcnt <= r_send_bitcnt - 1'b1;
|
||||
r_send_divcnt <= '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module uart_baudgen (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
input logic enable_i,
|
||||
input logic [23:0] baud_int_i,
|
||||
input logic [ 7:0] baud_frac_i,
|
||||
output logic sample_tick_o,
|
||||
output logic bit_tick_o
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
localparam logic [31:0] SAMPLE_STEP = 32'd4096;
|
||||
|
||||
logic [31:0] s_period;
|
||||
logic [31:0] s_phase_d, s_phase_q;
|
||||
logic [3:0] s_sample_count_d, s_sample_count_q;
|
||||
logic [32:0] s_phase_sum;
|
||||
|
||||
assign s_period = {baud_int_i, baud_frac_i};
|
||||
assign s_phase_sum = {1'b0, s_phase_q} + {1'b0, SAMPLE_STEP};
|
||||
assign sample_tick_o = enable_i && (s_period >= SAMPLE_STEP) && (s_phase_sum >= {1'b0, s_period});
|
||||
assign bit_tick_o = sample_tick_o && (s_sample_count_q == 4'd15);
|
||||
|
||||
always_comb begin
|
||||
s_phase_d = s_phase_q;
|
||||
s_sample_count_d = s_sample_count_q;
|
||||
if (!enable_i || (s_period < SAMPLE_STEP)) begin
|
||||
s_phase_d = '0;
|
||||
s_sample_count_d = '0;
|
||||
end else if (sample_tick_o) begin
|
||||
s_phase_d = 32'(s_phase_sum - {1'b0, s_period});
|
||||
s_sample_count_d = s_sample_count_q + 1'b1;
|
||||
end else begin
|
||||
s_phase_d = 32'(s_phase_sum);
|
||||
end
|
||||
end
|
||||
|
||||
dffr #(32) u_phase_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_phase_d),
|
||||
.dat_o (s_phase_q)
|
||||
);
|
||||
|
||||
dffr #(4) u_sample_count_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_sample_count_d),
|
||||
.dat_o (s_sample_count_q)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module uart_core (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
input logic [23:0] baud_int_i,
|
||||
input logic [ 7:0] baud_frac_i,
|
||||
input logic [ 1:0] data_bits_i,
|
||||
input logic stop2_i,
|
||||
input logic [ 1:0] parity_i,
|
||||
input logic tx_enable_i,
|
||||
input logic rx_enable_i,
|
||||
input logic loopback_i,
|
||||
input logic break_i,
|
||||
input logic tx_data_valid_i,
|
||||
input logic [ 7:0] tx_data_i,
|
||||
output logic tx_data_pop_o,
|
||||
output logic tx_busy_o,
|
||||
output logic tx_done_o,
|
||||
output logic rx_active_o,
|
||||
output logic rx_data_valid_o,
|
||||
output logic [11:0] rx_data_o,
|
||||
output logic bit_tick_o,
|
||||
input logic rx_i,
|
||||
output logic tx_o
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
logic s_sample_tick;
|
||||
logic s_tx;
|
||||
logic s_rx;
|
||||
|
||||
assign s_rx = loopback_i ? s_tx : rx_i;
|
||||
assign tx_o = s_tx;
|
||||
|
||||
uart_baudgen u_uart_baudgen (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.enable_i (tx_enable_i || rx_enable_i || tx_busy_o),
|
||||
.baud_int_i (baud_int_i),
|
||||
.baud_frac_i (baud_frac_i),
|
||||
.sample_tick_o(s_sample_tick),
|
||||
.bit_tick_o (bit_tick_o)
|
||||
);
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
ribp_uart_rx u_ribp_uart_rx (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.sample_tick_i(s_sample_tick),
|
||||
.enable_i (rx_enable_i),
|
||||
.data_bits_i (data_bits_i),
|
||||
.stop2_i (stop2_i),
|
||||
.parity_i (parity_i),
|
||||
.rx_i (s_rx),
|
||||
.active_o (rx_active_o),
|
||||
.data_valid_o (rx_data_valid_o),
|
||||
.data_o (rx_data_o)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,601 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
`include "ribp_uart_define.svh"
|
||||
|
||||
module uart_reg #(
|
||||
parameter int TX_FIFO_DEPTH = 64,
|
||||
parameter int RX_FIFO_DEPTH = 64,
|
||||
parameter int TX_FIFO_LOG_DEPTH = $clog2(TX_FIFO_DEPTH),
|
||||
parameter int RX_FIFO_LOG_DEPTH = $clog2(RX_FIFO_DEPTH)
|
||||
) (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
ribp_if.slave ribp,
|
||||
output logic [23:0] baud_int_o,
|
||||
output logic [ 7:0] baud_frac_o,
|
||||
output logic [ 1:0] data_bits_o,
|
||||
output logic stop2_o,
|
||||
output logic [ 1:0] parity_o,
|
||||
output logic tx_enable_o,
|
||||
output logic rx_enable_o,
|
||||
output logic loopback_o,
|
||||
output logic break_o,
|
||||
output logic tx_data_valid_o,
|
||||
output logic [ 7:0] tx_data_o,
|
||||
input logic tx_data_pop_i,
|
||||
input logic tx_busy_i,
|
||||
input logic tx_done_i,
|
||||
input logic rx_active_i,
|
||||
input logic rx_data_valid_i,
|
||||
input logic [11:0] rx_data_i,
|
||||
input logic bit_tick_i,
|
||||
output logic dma_tx_stall_o,
|
||||
output logic dma_rx_stall_o,
|
||||
output logic irq_o
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
localparam logic [31:0] TX_WATERMARK_RESET = 32'd16;
|
||||
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;
|
||||
|
||||
logic s_req;
|
||||
logic s_write;
|
||||
logic s_req_accept;
|
||||
logic s_access_error;
|
||||
logic s_ribp_ready_d, s_ribp_ready_q;
|
||||
logic s_ribp_resp_err_d, s_ribp_resp_err_q;
|
||||
logic [31:0] s_ribp_rdata_d, s_ribp_rdata_q;
|
||||
|
||||
logic s_baud_int_en;
|
||||
logic [23:0] s_baud_int_d, s_baud_int_q;
|
||||
logic s_baud_frac_en;
|
||||
logic [7:0] s_baud_frac_d, s_baud_frac_q;
|
||||
logic s_line_ctrl_en;
|
||||
logic [4:0] s_line_ctrl_d, s_line_ctrl_q;
|
||||
logic s_ctrl_en;
|
||||
logic [3:0] s_ctrl_d, s_ctrl_q;
|
||||
logic s_tx_watermark_en;
|
||||
logic [6:0] s_tx_watermark_d, s_tx_watermark_q;
|
||||
logic s_rx_watermark_en;
|
||||
logic [6:0] s_rx_watermark_d, s_rx_watermark_q;
|
||||
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 s_dma_ctrl_en;
|
||||
logic [1:0] s_dma_ctrl_d, s_dma_ctrl_q;
|
||||
|
||||
logic s_tx_flush;
|
||||
logic s_tx_push;
|
||||
logic s_tx_empty;
|
||||
logic s_tx_full;
|
||||
logic [ 7:0] s_tx_pop_data;
|
||||
logic [TX_FIFO_LOG_DEPTH:0] s_tx_count;
|
||||
logic s_rx_flush;
|
||||
logic s_rx_push;
|
||||
logic s_rx_pop;
|
||||
logic s_rx_empty;
|
||||
logic s_rx_full;
|
||||
logic [ 11:0] s_rx_pop_data;
|
||||
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_error_clear;
|
||||
logic [5:0] s_intr_clear;
|
||||
logic [5:0] s_intr_test;
|
||||
logic s_config_error_event;
|
||||
logic s_command_error_event;
|
||||
logic s_overrun_event;
|
||||
logic s_rx_error_event;
|
||||
logic s_rx_timeout_event;
|
||||
logic [15:0] s_rx_timeout_count_d, s_rx_timeout_count_q;
|
||||
|
||||
logic [31:0] s_status;
|
||||
logic [31:0] s_fifo_level;
|
||||
logic [31:0] s_merge_value;
|
||||
logic s_config_valid;
|
||||
logic s_tx_dma_req;
|
||||
logic s_rx_dma_req;
|
||||
logic s_tx_watermark_active;
|
||||
logic s_rx_watermark_active;
|
||||
|
||||
function automatic logic [31:0] merge_wstrb(input logic [31:0] current, input logic [31:0] value,
|
||||
input logic [3:0] strobe);
|
||||
logic [31:0] merged;
|
||||
integer byte_index;
|
||||
begin
|
||||
merged = current;
|
||||
for (byte_index = 0; byte_index < 4; byte_index = byte_index + 1) begin
|
||||
if (strobe[byte_index]) begin
|
||||
merged[byte_index*8+:8] = value[byte_index*8+:8];
|
||||
end
|
||||
end
|
||||
return merged;
|
||||
end
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
if ((TX_FIFO_DEPTH != 64) || (RX_FIFO_DEPTH != 64)) begin
|
||||
$fatal(1, "uart_reg: UART V2 requires 64-entry FIFOs");
|
||||
end
|
||||
end
|
||||
|
||||
assign s_req = ribp.valid && !s_ribp_ready_q;
|
||||
assign s_write = |ribp.wstrb;
|
||||
assign ribp.ready = s_ribp_ready_q;
|
||||
assign ribp.resp_err = s_ribp_resp_err_q;
|
||||
assign ribp.rdata = s_ribp_rdata_q;
|
||||
|
||||
assign baud_int_o = s_baud_int_q;
|
||||
assign baud_frac_o = s_baud_frac_q;
|
||||
assign data_bits_o = s_line_ctrl_q[1:0];
|
||||
assign stop2_o = s_line_ctrl_q[`UART_LINE_STOP2];
|
||||
assign parity_o = s_line_ctrl_q[4:3];
|
||||
assign tx_enable_o = s_ctrl_q[`UART_CTRL_TX_ENABLE];
|
||||
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 tx_data_valid_o = !s_tx_empty;
|
||||
assign tx_data_o = s_tx_pop_data;
|
||||
|
||||
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 &&
|
||||
s_config_valid && !s_tx_full;
|
||||
assign s_rx_dma_req = s_dma_ctrl_q[`UART_DMA_RX_ENABLE] && rx_enable_o && !s_rx_empty;
|
||||
assign dma_tx_stall_o = !s_tx_dma_req;
|
||||
assign dma_rx_stall_o = !s_rx_dma_req;
|
||||
assign s_tx_watermark_active = tx_enable_o && (s_tx_count <= s_tx_watermark_q);
|
||||
assign s_rx_watermark_active = rx_enable_o && (s_rx_count >= s_rx_watermark_q);
|
||||
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);
|
||||
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;
|
||||
|
||||
if (s_req) begin
|
||||
if ((ribp.addr[11:8] != 4'd0) || (ribp.addr[1:0] != 2'b00)) begin
|
||||
s_access_error = 1'b1;
|
||||
end else if (s_write) begin
|
||||
unique case (ribp.addr[7:0])
|
||||
`RIBP_UART_BAUD_INT: begin
|
||||
s_merge_value = merge_wstrb({8'd0, s_baud_int_q}, ribp.wdata, ribp.wstrb);
|
||||
if (tx_enable_o || rx_enable_o || tx_busy_i || rx_active_i ||
|
||||
(s_merge_value[31:24] != 8'd0) || (s_merge_value[23:0] < 24'd16)) begin
|
||||
s_access_error = 1'b1;
|
||||
s_config_error_event = 1'b1;
|
||||
end else begin
|
||||
s_baud_int_en = 1'b1;
|
||||
s_baud_int_d = s_merge_value[23:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_BAUD_FRAC: begin
|
||||
s_merge_value = merge_wstrb({24'd0, s_baud_frac_q}, ribp.wdata, ribp.wstrb);
|
||||
if (tx_enable_o || rx_enable_o || tx_busy_i || rx_active_i ||
|
||||
(s_merge_value[31:8] != 24'd0)) begin
|
||||
s_access_error = 1'b1;
|
||||
s_config_error_event = 1'b1;
|
||||
end else begin
|
||||
s_baud_frac_en = 1'b1;
|
||||
s_baud_frac_d = s_merge_value[7:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_LINE_CTRL: begin
|
||||
s_merge_value = merge_wstrb({27'd0, s_line_ctrl_q}, ribp.wdata, ribp.wstrb);
|
||||
if (tx_enable_o || rx_enable_o || tx_busy_i || rx_active_i ||
|
||||
(s_merge_value[31:5] != 27'd0) || (s_merge_value[4:3] == 2'd3)) begin
|
||||
s_access_error = 1'b1;
|
||||
s_config_error_event = 1'b1;
|
||||
end else begin
|
||||
s_line_ctrl_en = 1'b1;
|
||||
s_line_ctrl_d = s_merge_value[4:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_CTRL: begin
|
||||
s_merge_value = merge_wstrb({28'd0, s_ctrl_q}, ribp.wdata, ribp.wstrb);
|
||||
if ((s_merge_value[31:4] != 28'd0) ||
|
||||
((s_merge_value[1:0] != 2'd0) && !s_config_valid) ||
|
||||
(s_merge_value[`UART_CTRL_TX_BREAK] && tx_busy_i) ||
|
||||
((s_merge_value[`UART_CTRL_LOOPBACK] != loopback_o) &&
|
||||
(tx_busy_i || rx_active_i))) begin
|
||||
s_access_error = 1'b1;
|
||||
s_config_error_event = 1'b1;
|
||||
end else begin
|
||||
s_ctrl_en = 1'b1;
|
||||
s_ctrl_d = s_merge_value[3:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_TXDATA: begin
|
||||
if (!ribp.wstrb[0] ||
|
||||
(|(ribp.wdata[31:8] & {{8{ribp.wstrb[3]}}, {8{ribp.wstrb[2]}},
|
||||
{8{ribp.wstrb[1]}}}))) begin
|
||||
s_access_error = 1'b1;
|
||||
s_command_error_event = 1'b1;
|
||||
end else if (s_tx_full && tx_enable_o && s_config_valid) begin
|
||||
s_req_accept = 1'b0;
|
||||
end else if (s_tx_full) begin
|
||||
s_access_error = 1'b1;
|
||||
s_command_error_event = 1'b1;
|
||||
end else begin
|
||||
s_tx_push = 1'b1;
|
||||
end
|
||||
end
|
||||
`RIBP_UART_FIFO_CTRL: begin
|
||||
if (!ribp.wstrb[0] || (ribp.wdata[31:2] != 30'd0) ||
|
||||
(ribp.wdata[1:0] == 2'd0) ||
|
||||
(ribp.wdata[`UART_FIFO_CTRL_TX_FLUSH] && (tx_enable_o || tx_busy_i)) ||
|
||||
(ribp.wdata[`UART_FIFO_CTRL_RX_FLUSH] && (rx_enable_o || rx_active_i))) begin
|
||||
s_access_error = 1'b1;
|
||||
s_command_error_event = 1'b1;
|
||||
end else begin
|
||||
s_tx_flush = ribp.wdata[`UART_FIFO_CTRL_TX_FLUSH];
|
||||
s_rx_flush = ribp.wdata[`UART_FIFO_CTRL_RX_FLUSH];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_TX_WATERMARK: begin
|
||||
s_merge_value = merge_wstrb({25'd0, s_tx_watermark_q}, ribp.wdata, ribp.wstrb);
|
||||
if ((s_merge_value[31:7] != 25'd0) || (s_merge_value[6:0] >= 7'(TX_FIFO_DEPTH))) begin
|
||||
s_access_error = 1'b1;
|
||||
s_command_error_event = 1'b1;
|
||||
end else begin
|
||||
s_tx_watermark_en = 1'b1;
|
||||
s_tx_watermark_d = s_merge_value[6:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_RX_WATERMARK: begin
|
||||
s_merge_value = merge_wstrb({25'd0, s_rx_watermark_q}, ribp.wdata, ribp.wstrb);
|
||||
if ((s_merge_value[31:7] != 25'd0) || (s_merge_value[6:0] == 7'd0) ||
|
||||
(s_merge_value[6:0] > 7'(RX_FIFO_DEPTH))) begin
|
||||
s_access_error = 1'b1;
|
||||
s_command_error_event = 1'b1;
|
||||
end else begin
|
||||
s_rx_watermark_en = 1'b1;
|
||||
s_rx_watermark_d = s_merge_value[6:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_RX_TIMEOUT_BITS: begin
|
||||
s_merge_value = merge_wstrb({16'd0, s_rx_timeout_q}, ribp.wdata, ribp.wstrb);
|
||||
if (s_merge_value[31:16] != 16'd0) begin
|
||||
s_access_error = 1'b1;
|
||||
s_command_error_event = 1'b1;
|
||||
end else begin
|
||||
s_rx_timeout_en = 1'b1;
|
||||
s_rx_timeout_d = s_merge_value[15:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_ERROR_STATUS: begin
|
||||
if (!ribp.wstrb[0] || (ribp.wdata[31:7] != 25'd0)) begin
|
||||
s_access_error = 1'b1;
|
||||
end else begin
|
||||
s_error_clear = ribp.wdata[6:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_INTR_STATE: begin
|
||||
if (!ribp.wstrb[0] || (ribp.wdata[31:6] != 26'd0)) begin
|
||||
s_access_error = 1'b1;
|
||||
end else begin
|
||||
s_intr_clear = ribp.wdata[5: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_access_error = 1'b1;
|
||||
end else begin
|
||||
s_intr_enable_en = 1'b1;
|
||||
s_intr_enable_d = s_merge_value[5:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_INTR_TEST: begin
|
||||
if (!ribp.wstrb[0] || (ribp.wdata[31:6] != 26'd0)) begin
|
||||
s_access_error = 1'b1;
|
||||
end else begin
|
||||
s_intr_test = ribp.wdata[5:0];
|
||||
end
|
||||
end
|
||||
`RIBP_UART_DMA_CTRL: begin
|
||||
s_merge_value = merge_wstrb({30'd0, s_dma_ctrl_q}, ribp.wdata, ribp.wstrb);
|
||||
if (s_merge_value[31:2] != 30'd0) begin
|
||||
s_access_error = 1'b1;
|
||||
s_command_error_event = 1'b1;
|
||||
end else begin
|
||||
s_dma_ctrl_en = 1'b1;
|
||||
s_dma_ctrl_d = s_merge_value[1:0];
|
||||
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_RXDATA: begin
|
||||
if (s_rx_empty) begin
|
||||
s_access_error = 1'b1;
|
||||
s_command_error_event = 1'b1;
|
||||
end else begin
|
||||
s_ribp_rdata_d = {20'd0, s_rx_pop_data};
|
||||
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_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;
|
||||
default: begin
|
||||
s_access_error = 1'b1;
|
||||
s_ribp_rdata_d = '0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign s_ribp_ready_d = s_req_accept;
|
||||
assign s_ribp_resp_err_d = s_access_error;
|
||||
assign s_rx_push = rx_data_valid_i && !s_rx_full;
|
||||
assign s_overrun_event = rx_data_valid_i && s_rx_full;
|
||||
assign s_rx_error_event = s_rx_push && (|rx_data_i[11:8]);
|
||||
|
||||
dffr #(1) u_ribp_ready_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_ribp_ready_d),
|
||||
.dat_o (s_ribp_ready_q)
|
||||
);
|
||||
dffer #(1) u_ribp_resp_err_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_req_accept),
|
||||
.dat_i (s_ribp_resp_err_d),
|
||||
.dat_o (s_ribp_resp_err_q)
|
||||
);
|
||||
dffer #(32) u_ribp_rdata_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_req_accept),
|
||||
.dat_i (s_ribp_rdata_d),
|
||||
.dat_o (s_ribp_rdata_q)
|
||||
);
|
||||
|
||||
dffer #(24) u_baud_int_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_baud_int_en),
|
||||
.dat_i (s_baud_int_d),
|
||||
.dat_o (s_baud_int_q)
|
||||
);
|
||||
dffer #(8) u_baud_frac_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_baud_frac_en),
|
||||
.dat_i (s_baud_frac_d),
|
||||
.dat_o (s_baud_frac_q)
|
||||
);
|
||||
dfferc #(
|
||||
.DATA_WIDTH(5),
|
||||
.RESET_VAL (5'(LINE_CTRL_RESET))
|
||||
) u_line_ctrl_dfferc (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_line_ctrl_en),
|
||||
.dat_i (s_line_ctrl_d),
|
||||
.dat_o (s_line_ctrl_q)
|
||||
);
|
||||
dffer #(4) u_ctrl_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_ctrl_en),
|
||||
.dat_i (s_ctrl_d),
|
||||
.dat_o (s_ctrl_q)
|
||||
);
|
||||
dfferc #(
|
||||
.DATA_WIDTH(7),
|
||||
.RESET_VAL (7'(TX_WATERMARK_RESET))
|
||||
) u_tx_watermark_dfferc (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_tx_watermark_en),
|
||||
.dat_i (s_tx_watermark_d),
|
||||
.dat_o (s_tx_watermark_q)
|
||||
);
|
||||
dfferc #(
|
||||
.DATA_WIDTH(7),
|
||||
.RESET_VAL (7'(RX_WATERMARK_RESET))
|
||||
) u_rx_watermark_dfferc (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_rx_watermark_en),
|
||||
.dat_i (s_rx_watermark_d),
|
||||
.dat_o (s_rx_watermark_q)
|
||||
);
|
||||
dfferc #(
|
||||
.DATA_WIDTH(16),
|
||||
.RESET_VAL (16'(RX_TIMEOUT_RESET))
|
||||
) u_rx_timeout_dfferc (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_rx_timeout_en),
|
||||
.dat_i (s_rx_timeout_d),
|
||||
.dat_o (s_rx_timeout_q)
|
||||
);
|
||||
dffer #(6) u_intr_enable_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_intr_enable_en),
|
||||
.dat_i (s_intr_enable_d),
|
||||
.dat_o (s_intr_enable_q)
|
||||
);
|
||||
dffer #(2) u_dma_ctrl_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_dma_ctrl_en),
|
||||
.dat_i (s_dma_ctrl_d),
|
||||
.dat_o (s_dma_ctrl_q)
|
||||
);
|
||||
|
||||
fifo #(
|
||||
.DATA_WIDTH (8),
|
||||
.BUFFER_DEPTH (TX_FIFO_DEPTH),
|
||||
.LOG_BUFFER_DEPTH(TX_FIFO_LOG_DEPTH)
|
||||
) u_tx_fifo (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.flush_i(s_tx_flush),
|
||||
.push_i (s_tx_push),
|
||||
.full_o (s_tx_full),
|
||||
.dat_i (ribp.wdata[7:0]),
|
||||
.pop_i (tx_data_pop_i),
|
||||
.empty_o(s_tx_empty),
|
||||
.dat_o (s_tx_pop_data),
|
||||
.cnt_o (s_tx_count)
|
||||
);
|
||||
|
||||
fifo #(
|
||||
.DATA_WIDTH (12),
|
||||
.BUFFER_DEPTH (RX_FIFO_DEPTH),
|
||||
.LOG_BUFFER_DEPTH(RX_FIFO_LOG_DEPTH)
|
||||
) u_rx_fifo (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.flush_i(s_rx_flush),
|
||||
.push_i (s_rx_push),
|
||||
.full_o (s_rx_full),
|
||||
.dat_i (rx_data_i),
|
||||
.pop_i (s_rx_pop),
|
||||
.empty_o(s_rx_empty),
|
||||
.dat_o (s_rx_pop_data),
|
||||
.cnt_o (s_rx_count)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
s_rx_timeout_count_d = s_rx_timeout_count_q;
|
||||
s_rx_timeout_event = 1'b0;
|
||||
if (s_rx_empty || s_rx_push || s_rx_pop || (s_rx_timeout_q == 16'd0)) begin
|
||||
s_rx_timeout_count_d = '0;
|
||||
end else if (bit_tick_i) begin
|
||||
if (s_rx_timeout_count_q >= (s_rx_timeout_q - 1'b1)) begin
|
||||
s_rx_timeout_count_d = '0;
|
||||
s_rx_timeout_event = 1'b1;
|
||||
end else begin
|
||||
s_rx_timeout_count_d = s_rx_timeout_count_q + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
dffr #(16) u_rx_timeout_count_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_rx_timeout_count_d),
|
||||
.dat_o (s_rx_timeout_count_q)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
s_error_status_d = s_error_status_q & ~s_error_clear;
|
||||
if (s_overrun_event) s_error_status_d[`UART_ERROR_OVERRUN] = 1'b1;
|
||||
if (s_rx_push && rx_data_i[`UART_RXDATA_PARITY_ERROR])
|
||||
s_error_status_d[`UART_ERROR_PARITY] = 1'b1;
|
||||
if (s_rx_push && rx_data_i[`UART_RXDATA_FRAME_ERROR])
|
||||
s_error_status_d[`UART_ERROR_FRAME] = 1'b1;
|
||||
if (s_rx_push && rx_data_i[`UART_RXDATA_BREAK]) s_error_status_d[`UART_ERROR_BREAK] = 1'b1;
|
||||
if (s_rx_push && rx_data_i[`UART_RXDATA_NOISE]) s_error_status_d[`UART_ERROR_NOISE] = 1'b1;
|
||||
if (s_config_error_event) s_error_status_d[`UART_ERROR_CONFIG] = 1'b1;
|
||||
if (s_command_error_event) s_error_status_d[`UART_ERROR_COMMAND] = 1'b1;
|
||||
end
|
||||
dffr #(7) u_error_status_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_error_status_d),
|
||||
.dat_o (s_error_status_q)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
s_intr_state_d = (s_intr_state_q & ~s_intr_clear) | s_intr_test;
|
||||
if (s_rx_watermark_active) s_intr_state_d[`UART_INTR_RX_WATERMARK] = 1'b1;
|
||||
if (s_rx_timeout_event) s_intr_state_d[`UART_INTR_RX_TIMEOUT] = 1'b1;
|
||||
if (s_tx_watermark_active) s_intr_state_d[`UART_INTR_TX_WATERMARK] = 1'b1;
|
||||
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;
|
||||
end
|
||||
dffr #(6) u_intr_state_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_intr_state_d),
|
||||
.dat_o (s_intr_state_q)
|
||||
);
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
`ifdef SIMU_VERILATOR
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (s_tx_push && !loopback_o) begin
|
||||
$write("%c", ribp.wdata[7:0]);
|
||||
end
|
||||
end
|
||||
`endif
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
@@ -23,6 +23,12 @@
|
||||
/ip/ribp/serial/ws2812_reg.sv
|
||||
/ip/ribp/serial/ws2812_core.sv
|
||||
/ip/ribp/serial/ribp_ws2812.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_core.sv
|
||||
/ip/ribp/serial/uart_reg.sv
|
||||
/ip/ribp/serial/ribp_uart.sv
|
||||
/ip/ribp/storage/xpi_reg.sv
|
||||
/ip/ribp/storage/xpi_mm.sv
|
||||
/ip/ribp/storage/xpi_clkgen.sv
|
||||
@@ -46,7 +52,6 @@
|
||||
/ip/ribp/peripheral/timer_core.sv
|
||||
/ip/ribp/peripheral/timer_reg.sv
|
||||
/ip/ribp/peripheral/ribp_timer.sv
|
||||
/ip/ribp/serial/uart.sv
|
||||
/ip/ribp/peripheral/gpio_if.sv
|
||||
/ip/ribp/peripheral/user_gpio_if.sv
|
||||
/ip/ribp/peripheral/gpio_core.sv
|
||||
|
||||
@@ -107,6 +107,20 @@ def source_files(target: str) -> list[Path]:
|
||||
SERIAL / "ribp_ws2812.sv",
|
||||
SCRIPT_DIR / "ws2812_formal.sv",
|
||||
]
|
||||
if target == "uart":
|
||||
return [
|
||||
COMMON_RTL / "interface/ribp_if.sv",
|
||||
COMMON_RTL / "utils/register.sv",
|
||||
COMMON_RTL / "utils/fifo.sv",
|
||||
ROOT / "rtl/managed/clusterip/uart/rtl/uart_if.sv",
|
||||
SERIAL / "uart_baudgen.sv",
|
||||
SERIAL / "ribp_uart_tx.sv",
|
||||
SERIAL / "ribp_uart_rx.sv",
|
||||
SERIAL / "uart_core.sv",
|
||||
SERIAL / "uart_reg.sv",
|
||||
SERIAL / "ribp_uart.sv",
|
||||
SCRIPT_DIR / "uart_formal.sv",
|
||||
]
|
||||
if target == "timer":
|
||||
return [
|
||||
COMMON_RTL / "interface/ribp_if.sv",
|
||||
@@ -169,6 +183,7 @@ def parse_args() -> argparse.Namespace:
|
||||
"pll_rcu",
|
||||
"gpio",
|
||||
"ws2812",
|
||||
"uart",
|
||||
"timer",
|
||||
"clint",
|
||||
),
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module uart_formal_design (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
output logic rst_n_i,
|
||||
output logic f_past_valid,
|
||||
output logic rib_valid,
|
||||
output logic [31:0] rib_addr,
|
||||
output logic [31:0] rib_wdata,
|
||||
output logic [ 3:0] rib_wstrb,
|
||||
output logic rib_ready,
|
||||
output logic rib_resp_err,
|
||||
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 tx_enable,
|
||||
output logic rx_enable,
|
||||
output logic tx_busy,
|
||||
output logic rx_active,
|
||||
output logic break_active,
|
||||
output logic tx_dma_stall,
|
||||
output logic rx_dma_stall,
|
||||
output logic tx,
|
||||
output logic irq
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
ribp_if ribp ();
|
||||
uart_if uart ();
|
||||
|
||||
(* anyseq *)logic f_rib_valid;
|
||||
(* anyseq *)logic [31:0] f_rib_addr;
|
||||
(* anyseq *)logic [31:0] f_rib_wdata;
|
||||
(* anyseq *)logic [ 3:0] f_rib_wstrb;
|
||||
(* anyseq *)logic 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 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;
|
||||
|
||||
ribp_uart u_dut (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.dma_tx_stall_o(tx_dma_stall),
|
||||
.dma_rx_stall_o(rx_dma_stall),
|
||||
.ribp (ribp),
|
||||
.uart (uart)
|
||||
);
|
||||
|
||||
initial begin
|
||||
rst_n_i = 1'b0;
|
||||
f_past_valid = 1'b0;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
rst_n_i <= 1'b1;
|
||||
f_past_valid <= 1'b1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module uart_formal;
|
||||
(* anyseq *) (* gclk *)reg clk_i;
|
||||
wire rst_n_i;
|
||||
wire f_past_valid;
|
||||
wire rib_valid;
|
||||
wire [31:0] rib_addr;
|
||||
wire [31:0] rib_wdata;
|
||||
wire [ 3:0] rib_wstrb;
|
||||
wire rib_ready;
|
||||
wire rib_resp_err;
|
||||
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 tx_enable;
|
||||
wire rx_enable;
|
||||
wire tx_busy;
|
||||
wire rx_active;
|
||||
wire break_active;
|
||||
wire tx_dma_stall;
|
||||
wire rx_dma_stall;
|
||||
wire tx;
|
||||
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)
|
||||
);
|
||||
|
||||
always @(posedge clk_i) begin
|
||||
if (f_past_valid && $past(rst_n_i && rib_valid && !rib_ready)) begin
|
||||
assume (rib_valid);
|
||||
assume (rib_addr == $past(rib_addr));
|
||||
assume (rib_wdata == $past(rib_wdata));
|
||||
assume (rib_wstrb == $past(rib_wstrb));
|
||||
end
|
||||
|
||||
if (rst_n_i) begin
|
||||
assert (tx_count <= 7'd64);
|
||||
assert (rx_count <= 7'd64);
|
||||
assert (irq == |(intr_state & intr_enable));
|
||||
if (break_active) assert (!tx);
|
||||
if (!break_active && !tx_busy) assert (tx);
|
||||
if (!tx_enable) assert (tx_dma_stall);
|
||||
if (!rx_enable) assert (rx_dma_stall);
|
||||
cover (rib_ready && rib_resp_err);
|
||||
cover (tx_busy);
|
||||
cover (rx_active);
|
||||
cover (irq);
|
||||
cover (error_status != 7'd0);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
+13
-2
@@ -9,7 +9,7 @@ FORMAL_WS2812_DEPTH ?= 120
|
||||
FORMAL_CLINT_DEPTH ?= 32
|
||||
FORMAL_TIMEOUT ?= 60
|
||||
FORMAL_WS2812_TIMEOUT ?= 120
|
||||
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio ws2812 timer clint
|
||||
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio ws2812 uart timer clint
|
||||
FORMAL_FILELIST_GENERATOR := $(RTL_PATH)/formal/generate_formal_filelist.py
|
||||
FORMAL_SBY_GENERATOR := $(RTL_PATH)/formal/generate_sby_config.py
|
||||
FORMAL_RESULT_GENERATOR := $(RTL_PATH)/formal/formal_results.py
|
||||
@@ -27,6 +27,8 @@ FORMAL_SOURCE_FILES := $(RTL_PATH)/formal/bus_formal.sv \
|
||||
$(RTL_PATH)/formal/gpio_formal_props.sv \
|
||||
$(RTL_PATH)/formal/ws2812_formal.sv \
|
||||
$(RTL_PATH)/formal/ws2812_formal_props.sv \
|
||||
$(RTL_PATH)/formal/uart_formal.sv \
|
||||
$(RTL_PATH)/formal/uart_formal_props.sv \
|
||||
$(RTL_PATH)/formal/timer_formal.sv \
|
||||
$(RTL_PATH)/formal/timer_formal_props.sv \
|
||||
$(RTL_PATH)/formal/clint_formal.sv \
|
||||
@@ -50,6 +52,13 @@ 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_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_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/peripheral/timer_core.sv \
|
||||
$(ROOT_PATH)/rtl/ip/ribp/peripheral/timer_define.svh \
|
||||
$(ROOT_PATH)/rtl/ip/ribp/peripheral/timer_reg.sv \
|
||||
@@ -154,6 +163,8 @@ formal-gpio: $(FORMAL_DIR)/gpio/.stamp | manifest
|
||||
|
||||
formal-ws2812: $(FORMAL_DIR)/ws2812/.stamp | manifest
|
||||
|
||||
formal-uart: $(FORMAL_DIR)/uart/.stamp | manifest
|
||||
|
||||
formal-timer: $(FORMAL_DIR)/timer/.stamp | manifest
|
||||
|
||||
formal-clint: $(FORMAL_DIR)/clint/.stamp | manifest
|
||||
@@ -164,4 +175,4 @@ formal-doctor:
|
||||
formal-clean:
|
||||
python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(FORMAL_DIR)
|
||||
|
||||
.PHONY: formal formal-bus formal-rib-adapter formal-rib2apb formal-sysctrl formal-pll-rcu formal-gpio formal-ws2812 formal-timer formal-clint formal-doctor formal-clean
|
||||
.PHONY: formal formal-bus formal-rib-adapter formal-rib2apb formal-sysctrl formal-pll-rcu formal-gpio formal-ws2812 formal-uart formal-timer formal-clint formal-doctor formal-clean
|
||||
@@ -67,6 +67,7 @@ CRT_SRCS := $(ROOT_PATH)/crt/arch/riscv/startup.S \
|
||||
$(ROOT_PATH)/crt/src/service/test.c \
|
||||
$(ROOT_PATH)/crt/src/hal/clint.c \
|
||||
$(ROOT_PATH)/crt/src/hal/clock.c \
|
||||
$(ROOT_PATH)/crt/src/hal/uart_math.c \
|
||||
$(ROOT_PATH)/crt/src/hal/uart.c \
|
||||
$(ROOT_PATH)/crt/src/hal/gpio_math.c \
|
||||
$(ROOT_PATH)/crt/src/hal/gpio.c \
|
||||
|
||||
@@ -58,6 +58,7 @@ module ip_ribp_wrapper (
|
||||
|
||||
logic s_dma_i2s_tx_stall, s_dma_i2s_rx_stall;
|
||||
logic s_dma_xpi_tx_stall, s_dma_xpi_rx_stall;
|
||||
logic s_dma_uart_tx_stall, s_dma_uart_rx_stall;
|
||||
logic s_dma_xfer_done;
|
||||
logic s_tim0_irq, s_tim1_irq;
|
||||
|
||||
@@ -93,6 +94,8 @@ module ip_ribp_wrapper (
|
||||
assign u_dma_hw_trg_if.i2s_rx_proc = ~s_dma_i2s_rx_stall;
|
||||
assign u_dma_hw_trg_if.qspi_tx_proc = ~s_dma_xpi_tx_stall;
|
||||
assign u_dma_hw_trg_if.qspi_rx_proc = ~s_dma_xpi_rx_stall;
|
||||
assign u_dma_hw_trg_if.uart_tx_proc = ~s_dma_uart_tx_stall;
|
||||
assign u_dma_hw_trg_if.uart_rx_proc = ~s_dma_uart_rx_stall;
|
||||
|
||||
// Uses ClusterIP common ribp_if and register.sv dffr through generated bindings.
|
||||
`include "ribp_routes.svh"
|
||||
@@ -117,10 +120,12 @@ module ip_ribp_wrapper (
|
||||
// verilog_format: on
|
||||
|
||||
ribp_uart u_rib_uart (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.ribp (u_uart_ribp_if),
|
||||
.uart (uart)
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.dma_tx_stall_o(s_dma_uart_tx_stall),
|
||||
.dma_rx_stall_o(s_dma_uart_rx_stall),
|
||||
.ribp (u_uart_ribp_if),
|
||||
.uart (uart)
|
||||
);
|
||||
|
||||
ribp_timer u_rib_timer0 (
|
||||
|
||||
@@ -22,6 +22,7 @@ TEST_SOURCES = (
|
||||
"crt/src/lib/string.c",
|
||||
"crt/src/hal/gpio_math.c",
|
||||
"crt/src/hal/ws2812_math.c",
|
||||
"crt/src/hal/uart_math.c",
|
||||
"crt/src/hal/timer_math.c",
|
||||
"app/media/src/video_player.c",
|
||||
"app/media/src/wav_audio.c",
|
||||
|
||||
+23
-1
@@ -7,6 +7,7 @@
|
||||
#include <retrosoc/hal/lcd.h>
|
||||
#include <retrosoc/hal/spisd.h>
|
||||
#include <retrosoc/hal/timer.h>
|
||||
#include <retrosoc/hal/uart.h>
|
||||
#include <retrosoc/hal/ws2812.h>
|
||||
#include <retrosoc/lib/printf.h>
|
||||
#include <retrosoc/lib/stdlib.h>
|
||||
@@ -190,6 +191,26 @@ static int test_timer_helpers(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_uart_helpers(void) {
|
||||
rs_uart_timing_t timing;
|
||||
|
||||
if ((rs_uart_timing_calculate(72000000U, 921600U, &timing) != RS_OK) ||
|
||||
(timing.baud_integer != 78U) || (timing.baud_fraction != 32U)) {
|
||||
return 1;
|
||||
}
|
||||
if ((rs_uart_timing_calculate(16000000U, 1000000U, &timing) != RS_OK) ||
|
||||
(timing.baud_integer != 16U) || (timing.baud_fraction != 0U)) {
|
||||
return 2;
|
||||
}
|
||||
if ((rs_uart_timing_calculate(0U, 115200U, &timing) != RS_EINVAL) ||
|
||||
(rs_uart_timing_calculate(72000000U, 0U, &timing) != RS_EINVAL) ||
|
||||
(rs_uart_timing_calculate(1000000U, 1000000U, &timing) != RS_EINVAL) ||
|
||||
(rs_uart_timing_calculate(72000000U, 115200U, NULL) != RS_EINVAL)) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_gpio_helpers(void) {
|
||||
rs_gpio_filter_timing_t timing;
|
||||
|
||||
@@ -252,7 +273,8 @@ int main(void) {
|
||||
const int results[] = {
|
||||
test_string_helpers(), test_formatter(), test_compiler_helpers(),
|
||||
test_wait_helper(), test_ws2812_helpers(), test_timer_helpers(),
|
||||
test_gpio_helpers(), test_wav_parser(), test_video_parser(),
|
||||
test_uart_helpers(), test_gpio_helpers(), test_wav_parser(),
|
||||
test_video_parser(),
|
||||
};
|
||||
|
||||
for (size_t index = 0U; index < (sizeof(results) / sizeof(results[0])); ++index) {
|
||||
|
||||
@@ -143,6 +143,8 @@ module dma_error_tb;
|
||||
hw_trg.i2s_rx_proc = 1'b0;
|
||||
hw_trg.qspi_tx_proc = 1'b0;
|
||||
hw_trg.qspi_rx_proc = 1'b0;
|
||||
hw_trg.uart_tx_proc = 1'b0;
|
||||
hw_trg.uart_rx_proc = 1'b0;
|
||||
repeat (2) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
`include "ribp_uart_define.svh"
|
||||
|
||||
module uart_tb;
|
||||
logic clk_i = 1'b0;
|
||||
logic rst_n_i = 1'b0;
|
||||
logic dma_tx_stall;
|
||||
logic dma_rx_stall;
|
||||
ribp_if ribp ();
|
||||
uart_if uart ();
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
|
||||
ribp_uart u_dut (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.dma_tx_stall_o(dma_tx_stall),
|
||||
.dma_rx_stall_o(dma_rx_stall),
|
||||
.ribp (ribp),
|
||||
.uart (uart)
|
||||
);
|
||||
|
||||
task automatic ribp_write(input logic [31:0] address, input logic [31:0] data,
|
||||
input logic [3:0] strobe, input logic expected_error);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
ribp.addr = address;
|
||||
ribp.wdata = data;
|
||||
ribp.wstrb = strobe;
|
||||
ribp.valid = 1'b1;
|
||||
while (!ribp.ready) begin
|
||||
@(posedge clk_i);
|
||||
#1;
|
||||
end
|
||||
if (ribp.resp_err !== expected_error) begin
|
||||
$fatal(1, "UART write %h error=%b expected=%b", address, ribp.resp_err, expected_error);
|
||||
end
|
||||
@(negedge clk_i);
|
||||
ribp.valid = 1'b0;
|
||||
ribp.wstrb = '0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic ribp_read(input logic [31:0] address, input logic expected_error,
|
||||
output logic [31:0] data);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
ribp.addr = address;
|
||||
ribp.wdata = '0;
|
||||
ribp.wstrb = '0;
|
||||
ribp.valid = 1'b1;
|
||||
while (!ribp.ready) begin
|
||||
@(posedge clk_i);
|
||||
#1;
|
||||
end
|
||||
if (ribp.resp_err !== expected_error) begin
|
||||
$fatal(1, "UART read %h error=%b expected=%b", address, ribp.resp_err, expected_error);
|
||||
end
|
||||
data = ribp.rdata;
|
||||
@(negedge clk_i);
|
||||
ribp.valid = 1'b0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic write_ok(input logic [31:0] address, input logic [31:0] data);
|
||||
begin
|
||||
ribp_write(address, data, 4'hF, 1'b0);
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic configure_uart(input logic [4:0] line_control, input logic [3:0] control);
|
||||
begin
|
||||
write_ok(`RIBP_UART_CTRL, 0);
|
||||
repeat (4) @(posedge clk_i);
|
||||
write_ok(`RIBP_UART_FIFO_CTRL, 3);
|
||||
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_CTRL, control);
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic send_external_8n1(input logic [7:0] data, input logic bad_stop);
|
||||
integer bit_index;
|
||||
begin
|
||||
uart.rx_i = 1'b0;
|
||||
repeat (16) @(posedge clk_i);
|
||||
for (bit_index = 0; bit_index < 8; bit_index = bit_index + 1) begin
|
||||
uart.rx_i = data[bit_index];
|
||||
repeat (16) @(posedge clk_i);
|
||||
end
|
||||
uart.rx_i = !bad_stop;
|
||||
repeat (16) @(posedge clk_i);
|
||||
uart.rx_i = 1'b1;
|
||||
repeat (24) @(posedge clk_i);
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
logic [31:0] value;
|
||||
integer index;
|
||||
|
||||
ribp.valid = 1'b0;
|
||||
ribp.addr = '0;
|
||||
ribp.wdata = '0;
|
||||
ribp.wstrb = '0;
|
||||
uart.rx_i = 1'b1;
|
||||
repeat (4) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
repeat (4) @(posedge clk_i);
|
||||
|
||||
ribp_read(`RIBP_UART_IP_VERSION, 1'b0, value);
|
||||
if (value != 32'h0002_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");
|
||||
ribp_read(32'h0000_0002, 1'b1, value);
|
||||
ribp_read(`RIBP_UART_RXDATA, 1'b1, value);
|
||||
|
||||
configure_uart(5'd3, 4'b0111);
|
||||
write_ok(`RIBP_UART_TXDATA, 8'hA5);
|
||||
repeat (220) @(posedge clk_i);
|
||||
ribp_read(`RIBP_UART_RXDATA, 1'b0, value);
|
||||
if (value[11:0] != 12'h0A5) $fatal(1, "UART 8N1 loopback mismatch: %h", value);
|
||||
|
||||
configure_uart(5'd3, 4'b0001);
|
||||
write_ok(`RIBP_UART_TXDATA, 8'h5A);
|
||||
repeat (24) @(posedge clk_i);
|
||||
ribp_read(`RIBP_UART_STATUS, 1'b0, value);
|
||||
if (!value[`UART_STATUS_TX_BUSY]) $fatal(1, "UART TX did not start before disable");
|
||||
write_ok(`RIBP_UART_CTRL, 0);
|
||||
repeat (180) @(posedge clk_i);
|
||||
ribp_read(`RIBP_UART_STATUS, 1'b0, value);
|
||||
if (value[`UART_STATUS_TX_BUSY] || !value[`UART_STATUS_TX_EMPTY]) begin
|
||||
$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);
|
||||
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);
|
||||
|
||||
configure_uart(5'd3, 4'b0010);
|
||||
fork
|
||||
send_external_8n1(8'h3C, 1'b1);
|
||||
join
|
||||
ribp_read(`RIBP_UART_RXDATA, 1'b0, value);
|
||||
if ((value[7:0] != 8'h3C) || !value[`UART_RXDATA_FRAME_ERROR]) begin
|
||||
$fatal(1, "UART frame error was not retained: %h", value);
|
||||
end
|
||||
|
||||
write_ok(`RIBP_UART_CTRL, 0);
|
||||
repeat (4) @(posedge clk_i);
|
||||
write_ok(`RIBP_UART_FIFO_CTRL, 3);
|
||||
for (index = 0; index < 64; index = index + 1) begin
|
||||
write_ok(`RIBP_UART_TXDATA, index);
|
||||
end
|
||||
ribp_write(`RIBP_UART_TXDATA, 32'h55, 4'hF, 1'b1);
|
||||
ribp_read(`RIBP_UART_FIFO_LEVEL, 1'b0, value);
|
||||
if (value[6:0] != 7'd64) $fatal(1, "UART TX FIFO depth mismatch: %h", value);
|
||||
|
||||
write_ok(`RIBP_UART_FIFO_CTRL, 3);
|
||||
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");
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
repeat (20000) @(posedge clk_i);
|
||||
$fatal(1, "UART test timeout");
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -217,6 +217,8 @@ module ws2812_dma_tb;
|
||||
hw_trg.i2s_rx_proc = 1'b0;
|
||||
hw_trg.qspi_tx_proc = 1'b0;
|
||||
hw_trg.qspi_rx_proc = 1'b0;
|
||||
hw_trg.uart_tx_proc = 1'b0;
|
||||
hw_trg.uart_rx_proc = 1'b0;
|
||||
|
||||
repeat (3) @(posedge clk_i);
|
||||
rst_n_i = 1'b1;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
"""UART V2 register, FIFO, framing, interrupt, and DMA request tests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_uart_v2_register_fifo_loopback_and_errors(tmp_path: Path) -> None:
|
||||
iverilog = shutil.which("iverilog")
|
||||
vvp = shutil.which("vvp")
|
||||
if iverilog is None or vvp is None:
|
||||
return
|
||||
|
||||
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(
|
||||
[
|
||||
"+define+SV_ASSRT_DISABLE",
|
||||
f"+incdir+{common}",
|
||||
f"+incdir+{common / 'interface'}",
|
||||
f"+incdir+{common / 'utils'}",
|
||||
f"+incdir+{serial}",
|
||||
str(common / "interface/ribp_if.sv"),
|
||||
str(common / "utils/register.sv"),
|
||||
str(common / "utils/fifo.sv"),
|
||||
str(cluster_uart / "uart_if.sv"),
|
||||
str(serial / "uart_baudgen.sv"),
|
||||
str(serial / "ribp_uart_tx.sv"),
|
||||
str(serial / "ribp_uart_rx.sv"),
|
||||
str(serial / "uart_core.sv"),
|
||||
str(serial / "uart_reg.sv"),
|
||||
str(serial / "ribp_uart.sv"),
|
||||
str(ROOT / "tests/rtl/uart_tb.sv"),
|
||||
"",
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
converted = tmp_path / "uart_tb.v"
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(ROOT / "rtl/mini/script/convt_sv2v.py"),
|
||||
"-f",
|
||||
str(source_list),
|
||||
"--output",
|
||||
str(converted),
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
simulation = tmp_path / "uart_tb"
|
||||
subprocess.run(
|
||||
[iverilog, "-g2012", "-s", "uart_tb", "-o", str(simulation), str(converted)],
|
||||
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
|
||||
Reference in new issue
Block a user