mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: add RIBP Timer V2 support with formal verification and tests
- Updated filelist to include new timer peripheral files. - Enhanced formal file generation script to support timer target. - Created timer formal design and properties for formal verification. - Modified formal makefile to include timer targets and source files. - Added timer-related source files to software makefile. - Updated core and management wrappers to include debug halted signal. - Implemented timer testbench for RTL simulation. - Added regression tests for timer functionality in Python. - Introduced timer helper functions in C tests for validation.
This commit is contained in:
46 files changed
+1877
-465
No files matched your search
@@ -20,6 +20,8 @@ truth wins.
|
|||||||
GitHub workflows define the active build and regression behavior.
|
GitHub workflows define the active build and regression behavior.
|
||||||
- `quality/embedded_c_policy.json`, `quality/warnings/`, and
|
- `quality/embedded_c_policy.json`, `quality/warnings/`, and
|
||||||
`quality/metrics/policy.json` define the active quality policy.
|
`quality/metrics/policy.json` define the active quality policy.
|
||||||
|
- [rtl/README.md](rtl/README.md) defines the self-owned SystemVerilog naming,
|
||||||
|
register-state, macro, and formatting conventions.
|
||||||
|
|
||||||
Do not guess a profile, tool version, dependency revision, or generated-file
|
Do not guess a profile, tool version, dependency revision, or generated-file
|
||||||
location. Inspect the corresponding source of truth first.
|
location. Inspect the corresponding source of truth first.
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ endif
|
|||||||
benchmark-report coremark-report \
|
benchmark-report coremark-report \
|
||||||
pin-map check-pin-map soc-topology check-soc-topology user-extensions check-user-extensions \
|
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 \
|
check-clock-reset-domains tech-cell-test rtl-lint check-rtl-lint \
|
||||||
formal formal-bus formal-rib-adapter formal-rib2apb formal-ws2812 formal-clean formal-doctor
|
formal formal-bus formal-rib-adapter formal-rib2apb formal-ws2812 formal-timer formal-clean formal-doctor
|
||||||
.NOTPARALLEL: setup
|
.NOTPARALLEL: setup
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@@ -261,7 +261,7 @@ help:
|
|||||||
' check-clock-reset-domains validate the root clock/reset and CDC inventory' \
|
' check-clock-reset-domains validate the root clock/reset and CDC inventory' \
|
||||||
' rtl-lint | check-rtl-lint run/check strict Verilator RTL lint warnings' \
|
' 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 | formal-bus | formal-rib-adapter | formal-rib2apb run SBY protocol proofs' \
|
||||||
' formal-sysctrl | formal-pll-rcu | formal-gpio-user | formal-ws2812 run peripheral proofs' \
|
' formal-sysctrl | formal-pll-rcu | formal-gpio-user | formal-ws2812 | formal-timer run peripheral proofs' \
|
||||||
' formal-doctor check the SBY, Yosys, sv2v, and Bitwuzla formal toolchain' \
|
' formal-doctor check the SBY, Yosys, sv2v, and Bitwuzla formal toolchain' \
|
||||||
' benchmark-report run the memory/DMA profile and write meta/performance.json' \
|
' benchmark-report run the memory/DMA profile and write meta/performance.json' \
|
||||||
' coremark-report run the quick CoreMark profile and write meta/coremark.json' \
|
' coremark-report run the quick CoreMark profile and write meta/coremark.json' \
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ under the [Mulan Permissive Software License, Version 2](LICENSE).
|
|||||||
core, with a reproducible Verilator, OpenOCD, and GDB acceptance flow.
|
core, with a reproducible Verilator, OpenOCD, and GDB acceptance flow.
|
||||||
- Configurable GF180, SKY130, IHP130, and ICS55 implementation targets with
|
- Configurable GF180, SKY130, IHP130, and ICS55 implementation targets with
|
||||||
open-source CI coverage.
|
open-source CI coverage.
|
||||||
- A memory-mapped peripheral subsystem with GPIO, UART, timers, PWM, I2C, I2S, PS2,
|
- A memory-mapped peripheral subsystem with GPIO, UART,
|
||||||
|
[dual general timers](docs/ip/timer.md), PWM, I2C, I2S, PS2,
|
||||||
WS2812, SPI/QSPI, SDIO, PSRAM/OPI-PSRAM, SDRAM, DMA, LCD, RTC, watchdog, RNG, and CRC
|
WS2812, SPI/QSPI, SDIO, PSRAM/OPI-PSRAM, SDRAM, DMA, LCD, RTC, watchdog, RNG, and CRC
|
||||||
support. Available interfaces depend on the selected SoC configuration.
|
support. Available interfaces depend on the selected SoC configuration.
|
||||||
- A standalone RISC-V runtime, HAL, board support, middleware, and `benchmark`, `bringup`,
|
- A standalone RISC-V runtime, HAL, board support, middleware, and `benchmark`, `bringup`,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <retrosoc/core/soc.h>
|
#include <retrosoc/core/soc.h>
|
||||||
|
#include <retrosoc/hal/timer.h>
|
||||||
#include <retrosoc/hal/uart.h>
|
#include <retrosoc/hal/uart.h>
|
||||||
#include <retrosoc/lib/printf.h>
|
#include <retrosoc/lib/printf.h>
|
||||||
#include <retrosoc/service/test.h>
|
#include <retrosoc/service/test.h>
|
||||||
@@ -12,14 +13,89 @@ static bool rs_ci_smoke_archinfo_matches_reset_values(void) {
|
|||||||
(archinfo_idh == UINT32_C(0x00FFFFFF));
|
(archinfo_idh == UINT32_C(0x00FFFFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool rs_ci_smoke_timer_one_shot(void) {
|
||||||
|
const rs_timer_config_t config = {
|
||||||
|
.mode = RS_TIMER_MODE_ONE_SHOT,
|
||||||
|
.direction = RS_TIMER_DIRECTION_DOWN,
|
||||||
|
.prescale = 0U,
|
||||||
|
.load = 8U,
|
||||||
|
.compare0 = 4U,
|
||||||
|
.compare1 = 0U,
|
||||||
|
.interrupt_enable = RS_TIMER_INTERRUPT_TIMEOUT | RS_TIMER_INTERRUPT_COMPARE0,
|
||||||
|
.freeze_in_debug = true,
|
||||||
|
.compare0_enable = true,
|
||||||
|
.compare1_enable = false,
|
||||||
|
};
|
||||||
|
rs_timer_status_t status;
|
||||||
|
|
||||||
|
if ((rs_timer_configure(RS_TIMER_0, &config) != RS_OK) ||
|
||||||
|
(rs_timer_start(RS_TIMER_0) != RS_OK)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (rs_timeout_t timeout = 1000U; timeout != 0U; --timeout) {
|
||||||
|
if (rs_timer_get_status(RS_TIMER_0, &status) != RS_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!status.active) {
|
||||||
|
return (status.value == 0U) &&
|
||||||
|
((status.interrupt_state &
|
||||||
|
(RS_TIMER_INTERRUPT_TIMEOUT | RS_TIMER_INTERRUPT_COMPARE0)) ==
|
||||||
|
(RS_TIMER_INTERRUPT_TIMEOUT | RS_TIMER_INTERRUPT_COMPARE0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rs_ci_smoke_timer_periodic(void) {
|
||||||
|
const rs_timer_config_t config = {
|
||||||
|
.mode = RS_TIMER_MODE_PERIODIC,
|
||||||
|
.direction = RS_TIMER_DIRECTION_UP,
|
||||||
|
.prescale = 0U,
|
||||||
|
.load = 7U,
|
||||||
|
.compare0 = 0U,
|
||||||
|
.compare1 = 3U,
|
||||||
|
.interrupt_enable = RS_TIMER_INTERRUPT_TIMEOUT | RS_TIMER_INTERRUPT_COMPARE1,
|
||||||
|
.freeze_in_debug = true,
|
||||||
|
.compare0_enable = false,
|
||||||
|
.compare1_enable = true,
|
||||||
|
};
|
||||||
|
rs_timer_status_t status;
|
||||||
|
bool passed = false;
|
||||||
|
|
||||||
|
if ((rs_timer_configure(RS_TIMER_1, &config) != RS_OK) ||
|
||||||
|
(rs_timer_start(RS_TIMER_1) != RS_OK)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (rs_timeout_t timeout = 1000U; timeout != 0U; --timeout) {
|
||||||
|
if (rs_timer_get_status(RS_TIMER_1, &status) != RS_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((status.interrupt_state & (RS_TIMER_INTERRUPT_TIMEOUT | RS_TIMER_INTERRUPT_COMPARE1)) ==
|
||||||
|
(RS_TIMER_INTERRUPT_TIMEOUT | RS_TIMER_INTERRUPT_COMPARE1)) {
|
||||||
|
passed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rs_timer_stop(RS_TIMER_1) != RS_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return passed;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
uart0_init(CPU_FREQ, UART_BPS);
|
uart0_init(CPU_FREQ, UART_BPS);
|
||||||
|
|
||||||
if (!rs_ci_smoke_archinfo_matches_reset_values()) {
|
if (!rs_ci_smoke_archinfo_matches_reset_values()) {
|
||||||
rs_test_finish(RS_TEST_FAILED, 1U);
|
rs_test_finish(RS_TEST_FAILED, 1U);
|
||||||
}
|
}
|
||||||
|
if (!rs_ci_smoke_timer_one_shot()) {
|
||||||
|
rs_test_finish(RS_TEST_FAILED, 2U);
|
||||||
|
}
|
||||||
|
if (!rs_ci_smoke_timer_periodic()) {
|
||||||
|
rs_test_finish(RS_TEST_FAILED, 3U);
|
||||||
|
}
|
||||||
|
|
||||||
printf("ci_smoke: archinfo readback passed\n");
|
printf("ci_smoke: archinfo and timer tests passed\n");
|
||||||
rs_test_finish(RS_TEST_PASSED, 0U);
|
rs_test_finish(RS_TEST_PASSED, 0U);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,6 @@ int main(void) {
|
|||||||
lcd_init();
|
lcd_init();
|
||||||
|
|
||||||
// lv_init();
|
// lv_init();
|
||||||
// tim1_init();
|
|
||||||
// lv_tick_set_cb(my_get_millis);
|
// lv_tick_set_cb(my_get_millis);
|
||||||
|
|
||||||
// lv_port_disp_init();
|
// lv_port_disp_init();
|
||||||
@@ -49,7 +48,6 @@ int main(void) {
|
|||||||
|
|
||||||
// while(1) {
|
// while(1) {
|
||||||
// lv_timer_handler();
|
// lv_timer_handler();
|
||||||
// delay_ms(5);
|
|
||||||
// printf("hello\n");
|
// printf("hello\n");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@@ -57,7 +55,7 @@ int main(void) {
|
|||||||
(void)rs_shell_register("app", "app info", true, rs_app_info_command);
|
(void)rs_shell_register("app", "app info", true, rs_app_info_command);
|
||||||
(void)rs_shell_register("arch", "archinfo test", true, ip_archinfo_test);
|
(void)rs_shell_register("arch", "archinfo test", true, ip_archinfo_test);
|
||||||
(void)rs_shell_register("ws2812", "ws2812 test", true, ip_ws2812_test);
|
(void)rs_shell_register("ws2812", "ws2812 test", true, ip_ws2812_test);
|
||||||
(void)rs_shell_register("tim", "timer test", true, ip_tim_test);
|
(void)rs_shell_register("tim", "timer test", true, rs_timer_shell_test);
|
||||||
(void)rs_shell_register("gpio", "gpio test", true, ip_gpio_test);
|
(void)rs_shell_register("gpio", "gpio test", true, ip_gpio_test);
|
||||||
(void)rs_shell_register("pwm", "pwm test", true, ip_pwm_test);
|
(void)rs_shell_register("pwm", "pwm test", true, ip_pwm_test);
|
||||||
(void)rs_shell_register("rtc", "rtc test", true, ip_rtc_test);
|
(void)rs_shell_register("rtc", "rtc test", true, ip_rtc_test);
|
||||||
|
|||||||
@@ -78,7 +78,10 @@ void pcf8563b_test(int argc, char **argv) {
|
|||||||
printf("[PCF8563B] %d-%d-%d %d %d:%d:%d\n", rd_info.date.year, rd_info.date.month,
|
printf("[PCF8563B] %d-%d-%d %d %d:%d:%d\n", rd_info.date.year, rd_info.date.month,
|
||||||
rd_info.date.day, rd_info.date.weekday, rd_info.time.hour, rd_info.time.minute,
|
rd_info.date.day, rd_info.date.weekday, rd_info.time.hour, rd_info.time.minute,
|
||||||
rd_info.time.second);
|
rd_info.time.second);
|
||||||
delay_ms(1000);
|
if (rs_timer_delay_ms(RS_TIMER_0, 1000U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("PCF8563B timer delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PCF8563B_info_t init2_info = {.time.second = 23,
|
PCF8563B_info_t init2_info = {.time.second = 23,
|
||||||
@@ -94,7 +97,10 @@ void pcf8563b_test(int argc, char **argv) {
|
|||||||
printf("[PCF8563B] %d-%d-%d %d %d:%d:%d\n", rd_info.date.year, rd_info.date.month,
|
printf("[PCF8563B] %d-%d-%d %d %d:%d:%d\n", rd_info.date.year, rd_info.date.month,
|
||||||
rd_info.date.day, rd_info.date.weekday, rd_info.time.hour, rd_info.time.minute,
|
rd_info.date.day, rd_info.date.weekday, rd_info.time.hour, rd_info.time.minute,
|
||||||
rd_info.time.second);
|
rd_info.time.second);
|
||||||
delay_ms(1000);
|
if (rs_timer_delay_ms(RS_TIMER_0, 1000U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("PCF8563B timer delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("PCF8563B test done\n");
|
printf("PCF8563B test done\n");
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ void userip_main(int argc, char **argv) {
|
|||||||
reg_user_ip_reg1 = (uint32_t)0xfffe;
|
reg_user_ip_reg1 = (uint32_t)0xfffe;
|
||||||
printf("do val: %x\n", reg_user_ip_reg5);
|
printf("do val: %x\n", reg_user_ip_reg5);
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
delay_ms(1);
|
if (rs_timer_delay_ms(RS_TIMER_0, 1U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("timer delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
reg_user_ip_reg5 = ~reg_user_ip_reg5;
|
reg_user_ip_reg5 = ~reg_user_ip_reg5;
|
||||||
printf("[%d]do val: %x\n", i, reg_user_ip_reg5);
|
printf("[%d]do val: %x\n", i, reg_user_ip_reg5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,14 +50,6 @@
|
|||||||
// uart0
|
// uart0
|
||||||
#define reg_uart0_clkdiv RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, UINT32_C(0x00))
|
#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))
|
#define reg_uart0_data RS_SOC_REG32(RS_SOC_RIBP_UART0_BASE, UINT32_C(0x04))
|
||||||
// tim0
|
|
||||||
#define reg_tim0_cfg RS_SOC_REG32(RS_SOC_RIBP_TIM0_BASE, UINT32_C(0x00))
|
|
||||||
#define reg_tim0_rld RS_SOC_REG32(RS_SOC_RIBP_TIM0_BASE, UINT32_C(0x04))
|
|
||||||
#define reg_tim0_val RS_SOC_REG32(RS_SOC_RIBP_TIM0_BASE, UINT32_C(0x08))
|
|
||||||
// tim1
|
|
||||||
#define reg_tim1_cfg RS_SOC_REG32(RS_SOC_RIBP_TIM1_BASE, UINT32_C(0x00))
|
|
||||||
#define reg_tim1_rld RS_SOC_REG32(RS_SOC_RIBP_TIM1_BASE, UINT32_C(0x04))
|
|
||||||
#define reg_tim1_val RS_SOC_REG32(RS_SOC_RIBP_TIM1_BASE, UINT32_C(0x08))
|
|
||||||
// psram
|
// psram
|
||||||
#define reg_psram_wait RS_SOC_REG32(RS_SOC_RIBP_PSRAM_BASE, UINT32_C(0x00))
|
#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))
|
#define reg_psram_chd RS_SOC_REG32(RS_SOC_RIBP_PSRAM_BASE, UINT32_C(0x04))
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ typedef struct {
|
|||||||
} rs_clock_status_t;
|
} rs_clock_status_t;
|
||||||
|
|
||||||
rs_status_t rs_clock_get_status(rs_clock_status_t *status);
|
rs_status_t rs_clock_get_status(rs_clock_status_t *status);
|
||||||
|
rs_status_t rs_clock_frequency_hz(rs_clock_frequency_t frequency, uint32_t *frequency_hz);
|
||||||
|
rs_status_t rs_clock_get_active_hz(uint32_t *frequency_hz);
|
||||||
rs_status_t rs_clock_set_frequency(rs_clock_frequency_t frequency, rs_timeout_t timeout);
|
rs_status_t rs_clock_set_frequency(rs_clock_frequency_t frequency, rs_timeout_t timeout);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,10 +1,72 @@
|
|||||||
#ifndef RETROSOC_TIM_H
|
#ifndef RETROSOC_HAL_TIMER_H
|
||||||
#define RETROSOC_TIM_H
|
#define RETROSOC_HAL_TIMER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void delay_ms(uint32_t val);
|
#include <retrosoc/core/status.h>
|
||||||
void tim1_init(void);
|
|
||||||
uint32_t tim1_get_value(void);
|
#define RS_TIMER_INTERRUPT_TIMEOUT UINT32_C(0x00000001)
|
||||||
void ip_tim_test(int argc, char **argv);
|
#define RS_TIMER_INTERRUPT_COMPARE0 UINT32_C(0x00000002)
|
||||||
|
#define RS_TIMER_INTERRUPT_COMPARE1 UINT32_C(0x00000004)
|
||||||
|
#define RS_TIMER_INTERRUPT_ALL UINT32_C(0x00000007)
|
||||||
|
#define RS_TIMER_DELAY_TIMEOUT ((rs_timeout_t)UINT32_MAX)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RS_TIMER_0 = 0,
|
||||||
|
RS_TIMER_1 = 1,
|
||||||
|
} rs_timer_id_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RS_TIMER_MODE_FREE_RUNNING = 0,
|
||||||
|
RS_TIMER_MODE_PERIODIC = 1,
|
||||||
|
RS_TIMER_MODE_ONE_SHOT = 2,
|
||||||
|
} rs_timer_mode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RS_TIMER_DIRECTION_UP = 0,
|
||||||
|
RS_TIMER_DIRECTION_DOWN = 1,
|
||||||
|
} rs_timer_direction_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rs_timer_mode_t mode;
|
||||||
|
rs_timer_direction_t direction;
|
||||||
|
uint16_t prescale;
|
||||||
|
uint32_t load;
|
||||||
|
uint32_t compare0;
|
||||||
|
uint32_t compare1;
|
||||||
|
uint32_t interrupt_enable;
|
||||||
|
bool freeze_in_debug;
|
||||||
|
bool compare0_enable;
|
||||||
|
bool compare1_enable;
|
||||||
|
} rs_timer_config_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t value;
|
||||||
|
uint32_t interrupt_state;
|
||||||
|
bool active;
|
||||||
|
bool debug_frozen;
|
||||||
|
} rs_timer_status_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t prescale;
|
||||||
|
uint32_t load;
|
||||||
|
} rs_timer_period_t;
|
||||||
|
|
||||||
|
rs_status_t rs_timer_period_from_ms(uint32_t source_clock_hz, uint32_t milliseconds,
|
||||||
|
rs_timer_period_t *period);
|
||||||
|
rs_status_t rs_timer_configure(rs_timer_id_t timer, const rs_timer_config_t *config);
|
||||||
|
rs_status_t rs_timer_start(rs_timer_id_t timer);
|
||||||
|
rs_status_t rs_timer_stop(rs_timer_id_t timer);
|
||||||
|
rs_status_t rs_timer_set_load(rs_timer_id_t timer, uint32_t load);
|
||||||
|
rs_status_t rs_timer_set_background_load(rs_timer_id_t timer, uint32_t load);
|
||||||
|
rs_status_t rs_timer_set_compare(rs_timer_id_t timer, uint32_t channel, uint32_t compare);
|
||||||
|
rs_status_t rs_timer_get_value(rs_timer_id_t timer, uint32_t *value);
|
||||||
|
rs_status_t rs_timer_get_status(rs_timer_id_t timer, rs_timer_status_t *status);
|
||||||
|
rs_status_t rs_timer_interrupt_enable(rs_timer_id_t timer, uint32_t mask);
|
||||||
|
rs_status_t rs_timer_interrupt_clear(rs_timer_id_t timer, uint32_t mask);
|
||||||
|
rs_status_t rs_timer_interrupt_test(rs_timer_id_t timer, uint32_t mask);
|
||||||
|
rs_status_t rs_timer_delay_ms(rs_timer_id_t timer, uint32_t milliseconds, rs_timeout_t timeout);
|
||||||
|
void rs_timer_shell_test(int argc, char **argv);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+3
-1
@@ -35,7 +35,9 @@ static rs_status_t rs_irq_wait_for_count(volatile uint32_t *counter, uint32_t ta
|
|||||||
if (*counter >= target) {
|
if (*counter >= target) {
|
||||||
return RS_OK;
|
return RS_OK;
|
||||||
}
|
}
|
||||||
delay_ms(1U);
|
if (rs_timer_delay_ms(RS_TIMER_0, 1U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
return RS_ETIMEOUT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return RS_ETIMEOUT;
|
return RS_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,33 @@ rs_status_t rs_clock_get_status(rs_clock_status_t *status) {
|
|||||||
return RS_OK;
|
return RS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_clock_frequency_hz(rs_clock_frequency_t frequency, uint32_t *frequency_hz) {
|
||||||
|
if (!rs_clock_frequency_valid(frequency) || (frequency_hz == NULL)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
*frequency_hz = ((uint32_t)frequency + 1U) * UINT32_C(24000000);
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_clock_get_active_hz(uint32_t *frequency_hz) {
|
||||||
|
rs_clock_status_t status;
|
||||||
|
|
||||||
|
if (frequency_hz == NULL) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
if (rs_clock_get_status(&status) != RS_OK) {
|
||||||
|
return RS_EIO;
|
||||||
|
}
|
||||||
|
if (!status.capable) {
|
||||||
|
*frequency_hz = CPU_FREQ * UINT32_C(1000000);
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
if (!status.active_valid || status.busy) {
|
||||||
|
return RS_EIO;
|
||||||
|
}
|
||||||
|
return rs_clock_frequency_hz(status.active_frequency, frequency_hz);
|
||||||
|
}
|
||||||
|
|
||||||
rs_status_t rs_clock_set_frequency(rs_clock_frequency_t frequency, rs_timeout_t timeout) {
|
rs_status_t rs_clock_set_frequency(rs_clock_frequency_t frequency, rs_timeout_t timeout) {
|
||||||
rs_clock_status_t status;
|
rs_clock_status_t status;
|
||||||
bool busy_observed = false;
|
bool busy_observed = false;
|
||||||
|
|||||||
+8
-2
@@ -22,7 +22,10 @@ void ip_gpio_test(int argc, char **argv) {
|
|||||||
|
|
||||||
printf("led output test\n");
|
printf("led output test\n");
|
||||||
for (int i = 0; i < 50; ++i) {
|
for (int i = 0; i < 50; ++i) {
|
||||||
delay_ms(300);
|
if (rs_timer_delay_ms(RS_TIMER_0, 300U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("timer delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (reg_gpio_do == 0b00)
|
if (reg_gpio_do == 0b00)
|
||||||
reg_gpio_do = (uint32_t)0b01;
|
reg_gpio_do = (uint32_t)0b01;
|
||||||
else
|
else
|
||||||
@@ -38,7 +41,10 @@ void ip_gpio_test(int argc, char **argv) {
|
|||||||
for (int i = 0; i < 60; ++i) {
|
for (int i = 0; i < 60; ++i) {
|
||||||
uint32_t led_val = 0b00;
|
uint32_t led_val = 0b00;
|
||||||
if (((reg_gpio_do & 0b10) >> 1) == 0b0) {
|
if (((reg_gpio_do & 0b10) >> 1) == 0b0) {
|
||||||
delay_ms(100); // debouncing
|
if (rs_timer_delay_ms(RS_TIMER_0, 100U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("timer delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (((reg_gpio_do & 0b10) >> 1) == 0b0) {
|
if (((reg_gpio_do & 0b10) >> 1) == 0b0) {
|
||||||
printf("key detect\n");
|
printf("key detect\n");
|
||||||
if (led_val == 0b00) {
|
if (led_val == 0b00) {
|
||||||
|
|||||||
+8
-4
@@ -75,9 +75,15 @@ static void lcd_wr_data32(uint32_t *dat, uint32_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void lcd_init(void) {
|
void lcd_init(void) {
|
||||||
delay_ms(500);
|
if (rs_timer_delay_ms(RS_TIMER_0, 500U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("LCD reset delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
lcd_wr_dc_cmd(0x11);
|
lcd_wr_dc_cmd(0x11);
|
||||||
delay_ms(120);
|
if (rs_timer_delay_ms(RS_TIMER_0, 120U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("LCD sleep-exit delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
lcd_wr_dc_cmd(0x36);
|
lcd_wr_dc_cmd(0x36);
|
||||||
if (USE_HORIZONTAL == 0)
|
if (USE_HORIZONTAL == 0)
|
||||||
lcd_wr_dc_data8(0x00);
|
lcd_wr_dc_data8(0x00);
|
||||||
@@ -344,8 +350,6 @@ void ip_lcd_test(int argc, char **argv) {
|
|||||||
// }
|
// }
|
||||||
// lcd_frame(0, pref_cnt);
|
// lcd_frame(0, pref_cnt);
|
||||||
|
|
||||||
// delay_ms(1000);
|
|
||||||
|
|
||||||
// for (int i = 0; i < 100; ++i)
|
// for (int i = 0; i < 100; ++i)
|
||||||
// {
|
// {
|
||||||
// lcd_fill_video(0, 0, 240, 135, only_my_railgun[i]);
|
// lcd_fill_video(0, 0, 240, 135, only_my_railgun[i]);
|
||||||
|
|||||||
+8
-2
@@ -20,7 +20,10 @@ void ip_pwm_test(int argc, char **argv) {
|
|||||||
reg_pwm_cr0 = j;
|
reg_pwm_cr0 = j;
|
||||||
reg_pwm_ctrl = (uint32_t)3;
|
reg_pwm_ctrl = (uint32_t)3;
|
||||||
reg_pwm_pscr = 49;
|
reg_pwm_pscr = 49;
|
||||||
delay_ms(1);
|
if (rs_timer_delay_ms(RS_TIMER_0, 1U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("timer delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 990; j >= 10; --j) {
|
for (int j = 990; j >= 10; --j) {
|
||||||
@@ -28,7 +31,10 @@ void ip_pwm_test(int argc, char **argv) {
|
|||||||
reg_pwm_cr0 = j;
|
reg_pwm_cr0 = j;
|
||||||
reg_pwm_ctrl = (uint32_t)3;
|
reg_pwm_ctrl = (uint32_t)3;
|
||||||
reg_pwm_pscr = 49;
|
reg_pwm_pscr = 49;
|
||||||
delay_ms(1);
|
if (rs_timer_delay_ms(RS_TIMER_0, 1U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("timer delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf("[PWM]: %d/6\n", i + 1);
|
printf("[PWM]: %d/6\n", i + 1);
|
||||||
}
|
}
|
||||||
|
|||||||
+238
-36
@@ -1,49 +1,251 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <retrosoc/core/soc.h>
|
#include <retrosoc/core/soc.h>
|
||||||
#include <retrosoc/lib/printf.h>
|
#include <retrosoc/hal/clock.h>
|
||||||
#include <retrosoc/hal/timer.h>
|
#include <retrosoc/hal/timer.h>
|
||||||
|
#include <retrosoc/lib/printf.h>
|
||||||
|
|
||||||
void delay_ms(uint32_t val) {
|
#define RS_TIMER_CTRL_OFFSET UINT32_C(0x000)
|
||||||
reg_tim0_val = (uint32_t)(CPU_FREQ * val * 1000 - 1);
|
#define RS_TIMER_LOAD_OFFSET UINT32_C(0x004)
|
||||||
reg_tim0_cfg = (uint32_t)0b0011; // irq disable, count down, oneshot mode, timer enable
|
#define RS_TIMER_VALUE_OFFSET UINT32_C(0x008)
|
||||||
while (reg_tim0_val)
|
#define RS_TIMER_BGLOAD_OFFSET UINT32_C(0x00C)
|
||||||
;
|
#define RS_TIMER_PRESCALE_OFFSET UINT32_C(0x010)
|
||||||
reg_tim0_cfg = (uint32_t)0b0000;
|
#define RS_TIMER_COMPARE0_OFFSET UINT32_C(0x014)
|
||||||
|
#define RS_TIMER_COMPARE1_OFFSET UINT32_C(0x018)
|
||||||
|
#define RS_TIMER_STATUS_OFFSET UINT32_C(0x01C)
|
||||||
|
#define RS_TIMER_INTR_STATE_OFFSET UINT32_C(0x020)
|
||||||
|
#define RS_TIMER_INTR_ENABLE_OFFSET UINT32_C(0x024)
|
||||||
|
#define RS_TIMER_INTR_TEST_OFFSET UINT32_C(0x02C)
|
||||||
|
|
||||||
|
#define RS_TIMER_CTRL_ENABLE_SHIFT 0U
|
||||||
|
#define RS_TIMER_CTRL_MODE_SHIFT 1U
|
||||||
|
#define RS_TIMER_CTRL_DIRECTION_SHIFT 3U
|
||||||
|
#define RS_TIMER_CTRL_ENABLE_MASK UINT32_C(0x00000001)
|
||||||
|
#define RS_TIMER_CTRL_DEBUG_FREEZE_MASK UINT32_C(0x00000010)
|
||||||
|
#define RS_TIMER_CTRL_COMPARE0_ENABLE_MASK UINT32_C(0x00000020)
|
||||||
|
#define RS_TIMER_CTRL_COMPARE1_ENABLE_MASK UINT32_C(0x00000040)
|
||||||
|
#define RS_TIMER_STATUS_ACTIVE_MASK UINT32_C(0x00000001)
|
||||||
|
#define RS_TIMER_STATUS_DEBUG_FROZEN_MASK UINT32_C(0x00000002)
|
||||||
|
|
||||||
|
static bool rs_timer_id_valid(rs_timer_id_t timer) {
|
||||||
|
return (timer == RS_TIMER_0) || (timer == RS_TIMER_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tim1_init(void) {
|
static uintptr_t rs_timer_base(rs_timer_id_t timer) {
|
||||||
reg_tim1_cfg = (uint32_t)0b0000;
|
return timer == RS_TIMER_0 ? RS_SOC_RIBP_TIM0_BASE : RS_SOC_RIBP_TIM1_BASE;
|
||||||
reg_tim1_rld = (uint32_t)0xFFFFFFFF;
|
|
||||||
reg_tim1_val = (uint32_t)0;
|
|
||||||
// printf("tim1 cfg: %x\n", reg_tim1_cfg);
|
|
||||||
// printf("tim1 rld: %x\n", reg_tim1_rld);
|
|
||||||
// printf("tim1 val: %x\n", reg_tim1_val);
|
|
||||||
reg_tim1_cfg = (uint32_t)0b0111;
|
|
||||||
// printf("tim1 cfg: %d\n", reg_tim1_cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tim1_get_value(void) {
|
static volatile uint32_t *rs_timer_register(rs_timer_id_t timer, uint32_t offset) {
|
||||||
return reg_tim1_val;
|
return (volatile uint32_t *)(rs_timer_base(timer) + (uintptr_t)offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip_tim_test(int argc, char **argv) {
|
static uint32_t rs_timer_ctrl_from_config(const rs_timer_config_t *config) {
|
||||||
|
uint32_t control = ((uint32_t)config->mode << RS_TIMER_CTRL_MODE_SHIFT) |
|
||||||
|
((uint32_t)config->direction << RS_TIMER_CTRL_DIRECTION_SHIFT);
|
||||||
|
|
||||||
|
if (config->freeze_in_debug) {
|
||||||
|
control |= RS_TIMER_CTRL_DEBUG_FREEZE_MASK;
|
||||||
|
}
|
||||||
|
if (config->compare0_enable) {
|
||||||
|
control |= RS_TIMER_CTRL_COMPARE0_ENABLE_MASK;
|
||||||
|
}
|
||||||
|
if (config->compare1_enable) {
|
||||||
|
control |= RS_TIMER_CTRL_COMPARE1_ENABLE_MASK;
|
||||||
|
}
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rs_timer_config_valid(const rs_timer_config_t *config) {
|
||||||
|
return (config != NULL) && ((uint32_t)config->mode <= (uint32_t)RS_TIMER_MODE_ONE_SHOT) &&
|
||||||
|
((uint32_t)config->direction <= (uint32_t)RS_TIMER_DIRECTION_DOWN) &&
|
||||||
|
((config->interrupt_enable & ~RS_TIMER_INTERRUPT_ALL) == 0U);
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_configure(rs_timer_id_t timer, const rs_timer_config_t *config) {
|
||||||
|
volatile uint32_t *control;
|
||||||
|
uint32_t control_value;
|
||||||
|
|
||||||
|
if (!rs_timer_id_valid(timer) || !rs_timer_config_valid(config)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
control = rs_timer_register(timer, RS_TIMER_CTRL_OFFSET);
|
||||||
|
*control &= ~RS_TIMER_CTRL_ENABLE_MASK;
|
||||||
|
control_value = rs_timer_ctrl_from_config(config);
|
||||||
|
*control = control_value;
|
||||||
|
*rs_timer_register(timer, RS_TIMER_PRESCALE_OFFSET) = (uint32_t)config->prescale;
|
||||||
|
*rs_timer_register(timer, RS_TIMER_COMPARE0_OFFSET) = config->compare0;
|
||||||
|
*rs_timer_register(timer, RS_TIMER_COMPARE1_OFFSET) = config->compare1;
|
||||||
|
*rs_timer_register(timer, RS_TIMER_LOAD_OFFSET) = config->load;
|
||||||
|
*rs_timer_register(timer, RS_TIMER_INTR_STATE_OFFSET) = RS_TIMER_INTERRUPT_ALL;
|
||||||
|
*rs_timer_register(timer, RS_TIMER_INTR_ENABLE_OFFSET) = config->interrupt_enable;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_start(rs_timer_id_t timer) {
|
||||||
|
volatile uint32_t *control;
|
||||||
|
|
||||||
|
if (!rs_timer_id_valid(timer)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
control = rs_timer_register(timer, RS_TIMER_CTRL_OFFSET);
|
||||||
|
*control |= RS_TIMER_CTRL_ENABLE_MASK;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_stop(rs_timer_id_t timer) {
|
||||||
|
volatile uint32_t *control;
|
||||||
|
|
||||||
|
if (!rs_timer_id_valid(timer)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
control = rs_timer_register(timer, RS_TIMER_CTRL_OFFSET);
|
||||||
|
*control &= ~RS_TIMER_CTRL_ENABLE_MASK;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_set_load(rs_timer_id_t timer, uint32_t load) {
|
||||||
|
if (!rs_timer_id_valid(timer)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
*rs_timer_register(timer, RS_TIMER_LOAD_OFFSET) = load;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_set_background_load(rs_timer_id_t timer, uint32_t load) {
|
||||||
|
if (!rs_timer_id_valid(timer)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
*rs_timer_register(timer, RS_TIMER_BGLOAD_OFFSET) = load;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_set_compare(rs_timer_id_t timer, uint32_t channel, uint32_t compare) {
|
||||||
|
if (!rs_timer_id_valid(timer) || (channel > 1U)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
*rs_timer_register(timer, channel == 0U ? RS_TIMER_COMPARE0_OFFSET : RS_TIMER_COMPARE1_OFFSET) =
|
||||||
|
compare;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_get_value(rs_timer_id_t timer, uint32_t *value) {
|
||||||
|
if (!rs_timer_id_valid(timer) || (value == NULL)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
*value = *rs_timer_register(timer, RS_TIMER_VALUE_OFFSET);
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_get_status(rs_timer_id_t timer, rs_timer_status_t *status) {
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
if (!rs_timer_id_valid(timer) || (status == NULL)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
value = *rs_timer_register(timer, RS_TIMER_STATUS_OFFSET);
|
||||||
|
status->value = *rs_timer_register(timer, RS_TIMER_VALUE_OFFSET);
|
||||||
|
status->interrupt_state = *rs_timer_register(timer, RS_TIMER_INTR_STATE_OFFSET);
|
||||||
|
status->active = (value & RS_TIMER_STATUS_ACTIVE_MASK) != 0U;
|
||||||
|
status->debug_frozen = (value & RS_TIMER_STATUS_DEBUG_FROZEN_MASK) != 0U;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_interrupt_enable(rs_timer_id_t timer, uint32_t mask) {
|
||||||
|
if (!rs_timer_id_valid(timer) || ((mask & ~RS_TIMER_INTERRUPT_ALL) != 0U)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
*rs_timer_register(timer, RS_TIMER_INTR_ENABLE_OFFSET) = mask;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_interrupt_clear(rs_timer_id_t timer, uint32_t mask) {
|
||||||
|
if (!rs_timer_id_valid(timer) || ((mask & ~RS_TIMER_INTERRUPT_ALL) != 0U)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
*rs_timer_register(timer, RS_TIMER_INTR_STATE_OFFSET) = mask;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_interrupt_test(rs_timer_id_t timer, uint32_t mask) {
|
||||||
|
if (!rs_timer_id_valid(timer) || ((mask & ~RS_TIMER_INTERRUPT_ALL) != 0U)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
*rs_timer_register(timer, RS_TIMER_INTR_TEST_OFFSET) = mask;
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_status_t rs_timer_delay_ms(rs_timer_id_t timer, uint32_t milliseconds, rs_timeout_t timeout) {
|
||||||
|
rs_timer_config_t config = {
|
||||||
|
.mode = RS_TIMER_MODE_ONE_SHOT,
|
||||||
|
.direction = RS_TIMER_DIRECTION_DOWN,
|
||||||
|
.prescale = 0U,
|
||||||
|
.load = 0U,
|
||||||
|
.compare0 = 0U,
|
||||||
|
.compare1 = 0U,
|
||||||
|
.interrupt_enable = 0U,
|
||||||
|
.freeze_in_debug = true,
|
||||||
|
.compare0_enable = false,
|
||||||
|
.compare1_enable = false,
|
||||||
|
};
|
||||||
|
rs_timer_period_t period;
|
||||||
|
uint32_t frequency_hz;
|
||||||
|
|
||||||
|
if (!rs_timer_id_valid(timer)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
if (milliseconds == 0U) {
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
if ((rs_clock_get_active_hz(&frequency_hz) != RS_OK) ||
|
||||||
|
(rs_timer_period_from_ms(frequency_hz, milliseconds, &period) != RS_OK)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
config.prescale = period.prescale;
|
||||||
|
config.load = period.load;
|
||||||
|
if ((rs_timer_configure(timer, &config) != RS_OK) || (rs_timer_start(timer) != RS_OK)) {
|
||||||
|
return RS_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (timeout-- != 0U) {
|
||||||
|
if ((*rs_timer_register(timer, RS_TIMER_STATUS_OFFSET) & RS_TIMER_STATUS_ACTIVE_MASK) ==
|
||||||
|
0U) {
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(void)rs_timer_stop(timer);
|
||||||
|
return RS_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rs_timer_shell_test(int argc, char **argv) {
|
||||||
|
rs_timer_config_t config = {
|
||||||
|
.mode = RS_TIMER_MODE_PERIODIC,
|
||||||
|
.direction = RS_TIMER_DIRECTION_UP,
|
||||||
|
.prescale = 0U,
|
||||||
|
.load = UINT32_C(0x00FFFFFF),
|
||||||
|
.compare0 = UINT32_C(0x0000FFFF),
|
||||||
|
.compare1 = UINT32_C(0x000FFFFF),
|
||||||
|
.interrupt_enable = 0U,
|
||||||
|
.freeze_in_debug = true,
|
||||||
|
.compare0_enable = true,
|
||||||
|
.compare1_enable = true,
|
||||||
|
};
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
printf("[RIBP IP] general timer test\n");
|
||||||
printf("[RIB IP] counter timer test\n");
|
if ((rs_timer_configure(RS_TIMER_1, &config) != RS_OK) ||
|
||||||
printf("[tim0 reload] %x\n", reg_tim0_rld);
|
(rs_timer_start(RS_TIMER_1) != RS_OK)) {
|
||||||
printf("[tim0 config] %x\n", reg_tim0_cfg);
|
printf("timer configuration failed\n");
|
||||||
printf("[tim1 reload] %x\n", reg_tim1_rld);
|
return;
|
||||||
printf("[tim1 config] %x\n", reg_tim1_cfg);
|
|
||||||
|
|
||||||
reg_tim0_rld = (uint32_t)0xffffffff;
|
|
||||||
reg_tim0_cfg = (uint32_t)0b0001; // irq disable, count down, continuous mode, timer enable
|
|
||||||
|
|
||||||
reg_tim1_rld = (uint32_t)0x00ffffff;
|
|
||||||
reg_tim1_val = (uint32_t)0;
|
|
||||||
reg_tim1_cfg = (uint32_t)0b0101; // irq disable, count up, continuous mode, timer enable
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
printf("[tim0 val] %x\n", reg_tim0_val);
|
|
||||||
printf("[tim1 val] %x\n", reg_tim1_val);
|
|
||||||
}
|
}
|
||||||
|
for (uint32_t index = 0U; index < 10U; ++index) {
|
||||||
|
if (rs_timer_get_value(RS_TIMER_1, &value) != RS_OK) {
|
||||||
|
printf("timer read failed\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("[timer1 value] %x\n", value);
|
||||||
|
}
|
||||||
|
(void)rs_timer_stop(RS_TIMER_1);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <retrosoc/hal/timer.h>
|
||||||
|
|
||||||
|
#define RS_MILLISECONDS_PER_SECOND UINT64_C(1000)
|
||||||
|
#define RS_TIMER_MAX_DIVIDER UINT64_C(65536)
|
||||||
|
#define RS_TIMER_COUNTER_VALUES (UINT64_C(1) << 32U)
|
||||||
|
|
||||||
|
rs_status_t rs_timer_period_from_ms(uint32_t source_clock_hz, uint32_t milliseconds,
|
||||||
|
rs_timer_period_t *period) {
|
||||||
|
uint64_t product;
|
||||||
|
uint64_t cycles;
|
||||||
|
uint64_t divider;
|
||||||
|
uint64_t ticks;
|
||||||
|
|
||||||
|
if ((source_clock_hz == 0U) || (milliseconds == 0U) || (period == NULL)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
product = (uint64_t)source_clock_hz * (uint64_t)milliseconds;
|
||||||
|
if (product > (UINT64_MAX - (RS_MILLISECONDS_PER_SECOND - 1U))) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
cycles = (product + (RS_MILLISECONDS_PER_SECOND - 1U)) / RS_MILLISECONDS_PER_SECOND;
|
||||||
|
divider = (cycles + (RS_TIMER_COUNTER_VALUES - 1U)) / RS_TIMER_COUNTER_VALUES;
|
||||||
|
if (divider == 0U) {
|
||||||
|
divider = 1U;
|
||||||
|
}
|
||||||
|
if (divider > RS_TIMER_MAX_DIVIDER) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
ticks = (cycles + (divider - 1U)) / divider;
|
||||||
|
if ((ticks == 0U) || (ticks > RS_TIMER_COUNTER_VALUES)) {
|
||||||
|
return RS_EINVAL;
|
||||||
|
}
|
||||||
|
period->prescale = (uint16_t)(divider - 1U);
|
||||||
|
period->load = (uint32_t)(ticks - 1U);
|
||||||
|
return RS_OK;
|
||||||
|
}
|
||||||
@@ -97,8 +97,8 @@ void rs_app_info(void) {
|
|||||||
printf("Memory Map IO Device:\n");
|
printf("Memory Map IO Device:\n");
|
||||||
printf(" 1 x GPIO(32PIN) @%p\n", (void *)®_gpio_oe);
|
printf(" 1 x GPIO(32PIN) @%p\n", (void *)®_gpio_oe);
|
||||||
printf(" 1 x UART0 @%p\n", (void *)®_uart0_clkdiv);
|
printf(" 1 x UART0 @%p\n", (void *)®_uart0_clkdiv);
|
||||||
printf(" 2 x TIMER(0,1) @%p,%p\n", (void *)®_tim0_cfg,
|
printf(" 2 x TIMER(0,1) @%p,%p\n",
|
||||||
(void *)®_tim1_cfg);
|
(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);
|
printf(" 1 x PSRAM @%p\n", (void *)®_psram_wait);
|
||||||
printf(" 1 x SPISD @%p\n", (void *)®_spisd_mode);
|
printf(" 1 x SPISD @%p\n", (void *)®_spisd_mode);
|
||||||
printf(" 1 x I2C0 @%p\n", (void *)®_i2c0_clkdiv);
|
printf(" 1 x I2C0 @%p\n", (void *)®_i2c0_clkdiv);
|
||||||
@@ -181,7 +181,10 @@ static uint8_t rs_booter_check_key(void) {
|
|||||||
uint8_t enter_boot_delay = 6, enter_shell = 0;
|
uint8_t enter_boot_delay = 6, enter_shell = 0;
|
||||||
for (uint8_t i = 1; i <= enter_boot_delay; ++i) {
|
for (uint8_t i = 1; i <= enter_boot_delay; ++i) {
|
||||||
printf("delay %ds...[all %ds]\n", i, enter_boot_delay);
|
printf("delay %ds...[all %ds]\n", i, enter_boot_delay);
|
||||||
delay_ms(1000);
|
if (rs_timer_delay_ms(RS_TIMER_0, 1000U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("booter timer delay failed\n");
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
// if(i == 5) enter_shell = 1; // mock the oper
|
// if(i == 5) enter_shell = 1; // mock the oper
|
||||||
if (enter_shell) {
|
if (enter_shell) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|||||||
@@ -629,7 +629,10 @@ static void rs_shell_app_image_cmd(int argc, char **argv) {
|
|||||||
uint32_t *frame_data = file_buffer_words + (video_info.payload_offset / sizeof(uint32_t)) +
|
uint32_t *frame_data = file_buffer_words + (video_info.payload_offset / sizeof(uint32_t)) +
|
||||||
(frame * frame_words);
|
(frame * frame_words);
|
||||||
lcd_fill_image(0U, 0U, (uint16_t)video_info.width, (uint16_t)video_info.height, frame_data);
|
lcd_fill_image(0U, 0U, (uint16_t)video_info.width, (uint16_t)video_info.height, frame_data);
|
||||||
delay_ms(3000U);
|
if (rs_timer_delay_ms(RS_TIMER_0, 3000U, RS_TIMER_DELAY_TIMEOUT) != RS_OK) {
|
||||||
|
printf("video frame delay failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,17 +648,11 @@ static void rs_shell_app_audio_cmd(int argc, char **argv) {
|
|||||||
(void)argv;
|
(void)argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// val * 1000 / CPU_FREQ / 1000 / 1000
|
|
||||||
// uint32_t my_get_millis(void) {
|
|
||||||
// return reg_tim1_val / CPU_FREQ / 1000;
|
|
||||||
// }
|
|
||||||
|
|
||||||
static void rs_shell_app_lvgl_cmd(int argc, char **argv) {
|
static void rs_shell_app_lvgl_cmd(int argc, char **argv) {
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
// lv_init();
|
// lv_init();
|
||||||
// tim1_init();
|
|
||||||
// lv_tick_set_cb(my_get_millis);
|
// lv_tick_set_cb(my_get_millis);
|
||||||
|
|
||||||
// lv_port_disp_init();
|
// lv_port_disp_init();
|
||||||
@@ -666,7 +663,6 @@ static void rs_shell_app_lvgl_cmd(int argc, char **argv) {
|
|||||||
|
|
||||||
// while(1) {
|
// while(1) {
|
||||||
// lv_timer_handler();
|
// lv_timer_handler();
|
||||||
// delay_ms(5);
|
|
||||||
// printf("hello\n");
|
// printf("hello\n");
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -23,8 +23,10 @@ the root README and subsystem guides.
|
|||||||
and its commercial reference points.
|
and its commercial reference points.
|
||||||
- [rib-interconnect.md](rib-interconnect.md) defines the RIB v1 linear-burst
|
- [rib-interconnect.md](rib-interconnect.md) defines the RIB v1 linear-burst
|
||||||
contract, compatibility boundaries, target status, and verification.
|
contract, compatibility boundaries, target status, and verification.
|
||||||
- [ws2812.md](ws2812.md) defines the WS2812 transmitter register ABI,
|
- [ip/ws2812.md](ip/ws2812.md) defines the WS2812 transmitter register ABI,
|
||||||
timing, FIFO, interrupt, DMA, and integration contracts.
|
timing, FIFO, interrupt, DMA, and integration contracts.
|
||||||
|
- [ip/timer.md](ip/timer.md) defines the dual general timer register ABI,
|
||||||
|
counting modes, interrupt, debug-freeze, HAL, and verification contracts.
|
||||||
- [soc-integration-wiring.md](soc-integration-wiring.md) defines the generated
|
- [soc-integration-wiring.md](soc-integration-wiring.md) defines the generated
|
||||||
pin-map workflow and SoC integration boundary.
|
pin-map workflow and SoC integration boundary.
|
||||||
- [mini-soc-block-diagram.svg](mini-soc-block-diagram.svg) is the Mini SoC
|
- [mini-soc-block-diagram.svg](mini-soc-block-diagram.svg) is the Mini SoC
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# IP Documentation
|
||||||
|
|
||||||
|
This directory owns architecture, register ABI, software contract, and
|
||||||
|
verification documentation for self-owned retroSoC peripheral IP.
|
||||||
|
|
||||||
|
- [timer.md](timer.md) defines the dual RIBP general timer.
|
||||||
|
- [ws2812.md](ws2812.md) defines the WS2812 transmitter.
|
||||||
|
|
||||||
|
The corresponding RTL and HAL implementations remain the executable sources
|
||||||
|
of truth. Update the affected document whenever an IP interface or register ABI
|
||||||
|
changes.
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
# RIBP General Timer
|
||||||
|
|
||||||
|
The Mini SoC contains two identical 32-bit general-purpose timers. Each timer
|
||||||
|
has a 16-bit prescaler, free-running, periodic, and one-shot modes, selectable
|
||||||
|
up/down counting, two compare channels, sticky interrupts, and optional freeze
|
||||||
|
while the management Hazard3 core is halted by its Debug Module.
|
||||||
|
|
||||||
|
## Integration
|
||||||
|
|
||||||
|
| Property | Timer 0 | Timer 1 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| RIBP base address | `0x10002000` | `0x10003000` |
|
||||||
|
| RIBP interrupt group bit | 3 | 4 |
|
||||||
|
| Management-core interrupt | 3 | 4 |
|
||||||
|
| Counter width | 32 bits | 32 bits |
|
||||||
|
| Prescaler width | 16 bits | 16 bits |
|
||||||
|
| Compare channels | 2 | 2 |
|
||||||
|
|
||||||
|
The timer remains accessible while its counter is debug-frozen. The freeze
|
||||||
|
input is the management hart's synchronized halted indication; it does not
|
||||||
|
create or gate a clock. Both the prescaler and the main counter use the normal
|
||||||
|
SoC clock and stop through synchronous enables.
|
||||||
|
|
||||||
|
## Register ABI
|
||||||
|
|
||||||
|
All registers are 32 bits and naturally aligned. Unmapped, unaligned, and
|
||||||
|
direction-invalid accesses complete with `resp_err`. Partial writes are
|
||||||
|
supported for RW registers. Write-one-to-clear and software-interrupt writes
|
||||||
|
only act on a selected low byte.
|
||||||
|
|
||||||
|
| Offset | Name | Access | Description |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `0x000` | `CTRL` | RW | Enable, mode, direction, debug freeze, and compare enables. |
|
||||||
|
| `0x004` | `LOAD` | RW | Active period value; a write also loads the live counter. |
|
||||||
|
| `0x008` | `VALUE` | RO | Current counter value. |
|
||||||
|
| `0x00C` | `BGLOAD` | RW | Replaces `LOAD` without changing the live counter; used at the next periodic reload. |
|
||||||
|
| `0x010` | `PRESCALE` | RW | Divide the source clock by `PRESCALE + 1`; writable only while stopped. |
|
||||||
|
| `0x014` | `COMPARE0` | RW | Compare channel 0 value. |
|
||||||
|
| `0x018` | `COMPARE1` | RW | Compare channel 1 value. |
|
||||||
|
| `0x01C` | `STATUS` | RO | Bit 0 `ACTIVE`, bit 1 `DEBUG_FROZEN`. |
|
||||||
|
| `0x020` | `INTR_STATE` | RW1C | Sticky timeout, compare 0, and compare 1 state. |
|
||||||
|
| `0x024` | `INTR_ENABLE` | RW | Interrupt enable mask. |
|
||||||
|
| `0x028` | `INTR_STATUS` | RO | `INTR_STATE & INTR_ENABLE`. |
|
||||||
|
| `0x02C` | `INTR_TEST` | WO | Write-one software interrupt test. |
|
||||||
|
| `0x0F8` | `IP_VERSION` | RO | ABI version, currently `0x00020000` (2.0). |
|
||||||
|
| `0x0FC` | `CAPABILITY` | RO | Implemented counter, prescaler, mode, compare, direction, and debug-freeze capabilities. |
|
||||||
|
|
||||||
|
`CTRL.MODE` is `0` for free-running, `1` for periodic, and `2` for one-shot;
|
||||||
|
`3` is reserved and rejected. Bit 3 selects down-counting. Bits 4 through 6
|
||||||
|
enable debug freeze, compare 0, and compare 1 respectively. Mode and direction
|
||||||
|
cannot change while `CTRL.ENABLE` is set. Software must stop the timer before
|
||||||
|
changing either field or the prescaler.
|
||||||
|
|
||||||
|
The three interrupt bits are timeout at bit 0, compare 0 at bit 1, and compare
|
||||||
|
1 at bit 2. Events win over a simultaneous software clear, preventing hardware
|
||||||
|
events from being lost. The external interrupt is the reduction OR of
|
||||||
|
`INTR_STATE & INTR_ENABLE`.
|
||||||
|
|
||||||
|
The RTL ABI constants are maintained directly in
|
||||||
|
`rtl/ip/ribp/peripheral/timer_define.svh`. The matching HAL offsets and masks
|
||||||
|
are maintained directly in `crt/src/hal/timer.c`. Changes to either definition
|
||||||
|
must update the other definition, this document, and the RTL/software tests in
|
||||||
|
the same change.
|
||||||
|
|
||||||
|
## Counting Semantics
|
||||||
|
|
||||||
|
One counter update occurs every `PRESCALE + 1` SoC clocks. For up-counting
|
||||||
|
periodic and one-shot modes, a terminal event occurs at `VALUE >= LOAD`. For
|
||||||
|
down-counting modes, it occurs at `VALUE == 0`. A periodic timer reloads zero
|
||||||
|
when counting up and `LOAD` when counting down. A one-shot timer holds its
|
||||||
|
terminal value and clears `CTRL.ENABLE`.
|
||||||
|
|
||||||
|
Free-running mode wraps at the natural 32-bit boundary. Periodic and one-shot
|
||||||
|
periods contain `LOAD + 1` timer ticks. Compare events sample the current value
|
||||||
|
on a timer tick and become sticky when the corresponding compare channel is
|
||||||
|
enabled.
|
||||||
|
|
||||||
|
The HAL exposes structured configuration, bounded millisecond delays, value
|
||||||
|
and status snapshots, compare programming, and interrupt control. Delay
|
||||||
|
conversion uses the active clock reported by SYSCTRL and selects the smallest
|
||||||
|
16-bit prescaler that fits the requested interval in the 32-bit counter.
|
||||||
|
|
||||||
|
## Verification and Current Scope
|
||||||
|
|
||||||
|
The self-checking RTL test covers both count directions, all operating modes,
|
||||||
|
prescaling, background reload, both compare channels, debug freeze/resume,
|
||||||
|
sticky interrupt clear/test behavior, byte strobes, and RIBP access errors.
|
||||||
|
The SBY target proves response, hold, one-shot stop, sticky-event, and interrupt
|
||||||
|
invariants and covers normal and error paths. Host C tests cover period
|
||||||
|
conversion boundaries, and the `ci_smoke` firmware exercises both timer
|
||||||
|
instances through the public HAL.
|
||||||
|
|
||||||
|
The current ABI does not include capture inputs, PWM outputs, cascaded 64-bit
|
||||||
|
operation, DMA requests, or multiple clock sources. Those features require new
|
||||||
|
SoC pins or routing and a versioned ABI extension; they must not reinterpret
|
||||||
|
the existing register fields.
|
||||||
File renamed without changes.
@@ -124,7 +124,11 @@ digraph mini_soc_block_diagram {
|
|||||||
];
|
];
|
||||||
ribp_targets [
|
ribp_targets [
|
||||||
fillcolor="#F9E1E7",
|
fillcolor="#F9E1E7",
|
||||||
label="RIBP target wrapper\nXPI/Flash, SDRAM, PSRAM, SPI-SD and DVP\nGPIO, UART0, timers, I2C and I2S"
|
label="RIBP target wrapper\nXPI/Flash, SDRAM, PSRAM, SPI-SD and DVP\nGPIO, UART0, I2C and I2S"
|
||||||
|
];
|
||||||
|
timers [
|
||||||
|
fillcolor="#F9E1E7",
|
||||||
|
label="General timers 0/1\n32-bit counter, 16-bit prescaler\nperiodic / one-shot, compare, debug freeze"
|
||||||
];
|
];
|
||||||
ws2812 [
|
ws2812 [
|
||||||
fillcolor="#F9E1E7",
|
fillcolor="#F9E1E7",
|
||||||
@@ -149,7 +153,7 @@ digraph mini_soc_block_diagram {
|
|||||||
{ rank=same; user_core; dma; }
|
{ rank=same; user_core; dma; }
|
||||||
{ rank=same; fault; fabric; sram; }
|
{ rank=same; fault; fabric; sram; }
|
||||||
{ rank=same; ribp_adapter; apb_adapter; }
|
{ rank=same; ribp_adapter; apb_adapter; }
|
||||||
{ rank=same; sysctrl; ribp_targets; ws2812; apb_targets; }
|
{ rank=same; sysctrl; ribp_targets; timers; ws2812; apb_targets; }
|
||||||
{ rank=same; gpio_bridge; irq; }
|
{ rank=same; gpio_bridge; irq; }
|
||||||
|
|
||||||
ext_clock -> rcu [label="clock / reset"];
|
ext_clock -> rcu [label="clock / reset"];
|
||||||
@@ -159,6 +163,7 @@ digraph mini_soc_block_diagram {
|
|||||||
jtag_dtm -> debug_module [label="DMI, asynchronous CDC"];
|
jtag_dtm -> debug_module [label="DMI, asynchronous CDC"];
|
||||||
debug_module -> mgmt_core [label="halt, resume, abstract commands"];
|
debug_module -> mgmt_core [label="halt, resume, abstract commands"];
|
||||||
debug_module -> mgmt_adapter [label="reset after bridge idle", style=dashed];
|
debug_module -> mgmt_adapter [label="reset after bridge idle", style=dashed];
|
||||||
|
debug_module -> timers [label="halted", style=dashed];
|
||||||
|
|
||||||
mgmt_core -> mgmt_adapter [label="RIBP"];
|
mgmt_core -> mgmt_adapter [label="RIBP"];
|
||||||
mgmt_adapter -> fabric [label="RIB"];
|
mgmt_adapter -> fabric [label="RIB"];
|
||||||
@@ -171,10 +176,12 @@ digraph mini_soc_block_diagram {
|
|||||||
fabric -> apb_adapter [label="RIB"];
|
fabric -> apb_adapter [label="RIB"];
|
||||||
ribp_adapter -> sysctrl [label="RIBP"];
|
ribp_adapter -> sysctrl [label="RIBP"];
|
||||||
ribp_adapter -> ribp_targets [label="RIBP"];
|
ribp_adapter -> ribp_targets [label="RIBP"];
|
||||||
|
ribp_adapter -> timers [label="RIBP"];
|
||||||
ribp_adapter -> ws2812 [label="RIBP"];
|
ribp_adapter -> ws2812 [label="RIBP"];
|
||||||
apb_adapter -> apb_targets [label="APB"];
|
apb_adapter -> apb_targets [label="APB"];
|
||||||
|
|
||||||
ribp_targets -> gpio_bridge [label="GPIO alternate functions"];
|
ribp_targets -> gpio_bridge [label="GPIO alternate functions"];
|
||||||
|
timers -> irq [label="IRQ3 / IRQ4"];
|
||||||
ws2812 -> gpio_bridge [label="GPIO2 ALT1"];
|
ws2812 -> gpio_bridge [label="GPIO2 ALT1"];
|
||||||
dma -> ws2812 [label="TXDATA writes", style=dashed];
|
dma -> ws2812 [label="TXDATA writes", style=dashed];
|
||||||
ws2812 -> irq [label="IRQ17"];
|
ws2812 -> irq [label="IRQ17"];
|
||||||
|
|||||||
+198
-169
@@ -4,19 +4,19 @@
|
|||||||
<!-- Generated by graphviz version 2.43.0 (0)
|
<!-- Generated by graphviz version 2.43.0 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: mini_soc_block_diagram Pages: 1 -->
|
<!-- Title: mini_soc_block_diagram Pages: 1 -->
|
||||||
<svg width="1315pt" height="887pt"
|
<svg width="1546pt" height="887pt"
|
||||||
viewBox="0.00 0.00 1315.00 887.48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 1546.00 887.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 883.48)">
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 883.48)">
|
||||||
<title>mini_soc_block_diagram</title>
|
<title>mini_soc_block_diagram</title>
|
||||||
<text text-anchor="middle" x="132" y="-861.08" font-family="Arial" font-size="18.00">retroSoC Mini SoC Architecture</text>
|
<text text-anchor="middle" x="132" y="-861.08" font-family="Arial" font-size="18.00">retroSoC Mini SoC Architecture</text>
|
||||||
<g id="clust1" class="cluster">
|
<g id="clust1" class="cluster">
|
||||||
<title>cluster_asic</title>
|
<title>cluster_asic</title>
|
||||||
<path fill="transparent" stroke="#111827" d="M160,-85C160,-85 1287,-85 1287,-85 1293,-85 1299,-91 1299,-97 1299,-97 1299,-763.48 1299,-763.48 1299,-769.48 1293,-775.48 1287,-775.48 1287,-775.48 160,-775.48 160,-775.48 154,-775.48 148,-769.48 148,-763.48 148,-763.48 148,-97 148,-97 148,-91 154,-85 160,-85"/>
|
<path fill="transparent" stroke="#111827" d="M160,-85C160,-85 1518,-85 1518,-85 1524,-85 1530,-91 1530,-97 1530,-97 1530,-763.48 1530,-763.48 1530,-769.48 1524,-775.48 1518,-775.48 1518,-775.48 160,-775.48 160,-775.48 154,-775.48 148,-769.48 148,-763.48 148,-763.48 148,-97 148,-97 148,-91 154,-85 160,-85"/>
|
||||||
<text text-anchor="middle" x="196.5" y="-760.28" font-family="Arial" font-size="14.00" fill="#111827">retrosoc_asic</text>
|
<text text-anchor="middle" x="196.5" y="-760.28" font-family="Arial" font-size="14.00" fill="#111827">retrosoc_asic</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="clust2" class="cluster">
|
<g id="clust2" class="cluster">
|
||||||
<title>cluster_soc</title>
|
<title>cluster_soc</title>
|
||||||
<path fill="transparent" stroke="#94a3b8" stroke-dasharray="5,2" d="M390,-103C390,-103 1269,-103 1269,-103 1275,-103 1281,-109 1281,-115 1281,-115 1281,-720.48 1281,-720.48 1281,-726.48 1275,-732.48 1269,-732.48 1269,-732.48 390,-732.48 390,-732.48 384,-732.48 378,-726.48 378,-720.48 378,-720.48 378,-115 378,-115 378,-109 384,-103 390,-103"/>
|
<path fill="transparent" stroke="#94a3b8" stroke-dasharray="5,2" d="M390,-103C390,-103 1500,-103 1500,-103 1506,-103 1512,-109 1512,-115 1512,-115 1512,-720.48 1512,-720.48 1512,-726.48 1506,-732.48 1500,-732.48 1500,-732.48 390,-732.48 390,-732.48 384,-732.48 378,-726.48 378,-720.48 378,-720.48 378,-115 378,-115 378,-109 384,-103 390,-103"/>
|
||||||
<text text-anchor="middle" x="407.5" y="-718.88" font-family="Arial" font-size="12.00" fill="#334155">retrosoc</text>
|
<text text-anchor="middle" x="407.5" y="-718.88" font-family="Arial" font-size="12.00" fill="#334155">retrosoc</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ext_clock -->
|
<!-- ext_clock -->
|
||||||
@@ -44,313 +44,342 @@
|
|||||||
<!-- ext_io -->
|
<!-- ext_io -->
|
||||||
<g id="node2" class="node">
|
<g id="node2" class="node">
|
||||||
<title>ext_io</title>
|
<title>ext_io</title>
|
||||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M903,-45C903,-45 711,-45 711,-45 705,-45 699,-39 699,-33 699,-33 699,-12 699,-12 699,-6 705,0 711,0 711,0 903,0 903,0 909,0 915,-6 915,-12 915,-12 915,-33 915,-33 915,-39 909,-45 903,-45"/>
|
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M1257,-45C1257,-45 1065,-45 1065,-45 1059,-45 1053,-39 1053,-33 1053,-33 1053,-12 1053,-12 1053,-6 1059,0 1065,0 1065,0 1257,0 1257,0 1263,0 1269,-6 1269,-12 1269,-12 1269,-33 1269,-33 1269,-39 1263,-45 1257,-45"/>
|
||||||
<text text-anchor="middle" x="807" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
|
<text text-anchor="middle" x="1161" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
|
||||||
<text text-anchor="middle" x="807" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, XPI Flash, SDRAM, PSRAM</text>
|
<text text-anchor="middle" x="1161" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, XPI Flash, SDRAM, PSRAM</text>
|
||||||
<text text-anchor="middle" x="807" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP and WS2812</text>
|
<text text-anchor="middle" x="1161" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP and WS2812</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ext_jtag -->
|
<!-- ext_jtag -->
|
||||||
<g id="node3" class="node">
|
<g id="node3" class="node">
|
||||||
<title>ext_jtag</title>
|
<title>ext_jtag</title>
|
||||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M569.5,-851.48C569.5,-851.48 438.5,-851.48 438.5,-851.48 432.5,-851.48 426.5,-845.48 426.5,-839.48 426.5,-839.48 426.5,-827.48 426.5,-827.48 426.5,-821.48 432.5,-815.48 438.5,-815.48 438.5,-815.48 569.5,-815.48 569.5,-815.48 575.5,-815.48 581.5,-821.48 581.5,-827.48 581.5,-827.48 581.5,-839.48 581.5,-839.48 581.5,-845.48 575.5,-851.48 569.5,-851.48"/>
|
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M749.5,-851.48C749.5,-851.48 618.5,-851.48 618.5,-851.48 612.5,-851.48 606.5,-845.48 606.5,-839.48 606.5,-839.48 606.5,-827.48 606.5,-827.48 606.5,-821.48 612.5,-815.48 618.5,-815.48 618.5,-815.48 749.5,-815.48 749.5,-815.48 755.5,-815.48 761.5,-821.48 761.5,-827.48 761.5,-827.48 761.5,-839.48 761.5,-839.48 761.5,-845.48 755.5,-851.48 749.5,-851.48"/>
|
||||||
<text text-anchor="middle" x="504" y="-836.48" font-family="Arial" font-size="10.00" fill="#111827">Management JTAG</text>
|
<text text-anchor="middle" x="684" y="-836.48" font-family="Arial" font-size="10.00" fill="#111827">Management JTAG</text>
|
||||||
<text text-anchor="middle" x="504" y="-825.48" font-family="Arial" font-size="10.00" fill="#111827">TCK, TMS, TDI, TRST_n, TDO</text>
|
<text text-anchor="middle" x="684" y="-825.48" font-family="Arial" font-size="10.00" fill="#111827">TCK, TMS, TDI, TRST_n, TDO</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- jtag_dtm -->
|
<!-- jtag_dtm -->
|
||||||
<g id="node6" class="node">
|
<g id="node6" class="node">
|
||||||
<title>jtag_dtm</title>
|
<title>jtag_dtm</title>
|
||||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M579,-669.98C579,-669.98 429,-669.98 429,-669.98 423,-669.98 417,-663.98 417,-657.98 417,-657.98 417,-645.98 417,-645.98 417,-639.98 423,-633.98 429,-633.98 429,-633.98 579,-633.98 579,-633.98 585,-633.98 591,-639.98 591,-645.98 591,-645.98 591,-657.98 591,-657.98 591,-663.98 585,-669.98 579,-669.98"/>
|
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M759,-669.98C759,-669.98 609,-669.98 609,-669.98 603,-669.98 597,-663.98 597,-657.98 597,-657.98 597,-645.98 597,-645.98 597,-639.98 603,-633.98 609,-633.98 609,-633.98 759,-633.98 759,-633.98 765,-633.98 771,-639.98 771,-645.98 771,-645.98 771,-657.98 771,-657.98 771,-663.98 765,-669.98 759,-669.98"/>
|
||||||
<text text-anchor="middle" x="504" y="-654.98" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 JTAG DTM</text>
|
<text text-anchor="middle" x="684" y="-654.98" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 JTAG DTM</text>
|
||||||
<text text-anchor="middle" x="504" y="-643.98" font-family="Arial" font-size="10.00" fill="#111827">10 MHz asynchronous TCK domain</text>
|
<text text-anchor="middle" x="684" y="-643.98" font-family="Arial" font-size="10.00" fill="#111827">10 MHz asynchronous TCK domain</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ext_jtag->jtag_dtm -->
|
<!-- ext_jtag->jtag_dtm -->
|
||||||
<g id="edge2" class="edge">
|
<g id="edge2" class="edge">
|
||||||
<title>ext_jtag->jtag_dtm</title>
|
<title>ext_jtag->jtag_dtm</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M504,-815.27C504,-783.24 504,-714.39 504,-677.51"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M684,-815.27C684,-783.24 684,-714.39 684,-677.51"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="506.45,-677.14 504,-670.14 501.55,-677.14 506.45,-677.14"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="686.45,-677.14 684,-670.14 681.55,-677.14 686.45,-677.14"/>
|
||||||
<text text-anchor="middle" x="524" y="-786.08" font-family="Arial" font-size="8.00" fill="#374151">JTAG pads</text>
|
<text text-anchor="middle" x="704" y="-786.08" font-family="Arial" font-size="8.00" fill="#374151">JTAG pads</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fabric -->
|
<!-- fabric -->
|
||||||
<g id="node11" class="node">
|
<g id="node11" class="node">
|
||||||
<title>fabric</title>
|
<title>fabric</title>
|
||||||
<path fill="#dcecf8" stroke="#4b5563" stroke-width="1.1" d="M853.66,-442.31C853.66,-442.31 785.98,-470.16 785.98,-470.16 780.43,-472.45 768.88,-474.73 762.88,-474.73 762.88,-474.73 607.12,-474.73 607.12,-474.73 601.12,-474.73 589.57,-472.45 584.02,-470.16 584.02,-470.16 516.34,-442.31 516.34,-442.31 510.79,-440.03 510.79,-435.46 516.34,-433.18 516.34,-433.18 584.02,-405.32 584.02,-405.32 589.57,-403.04 601.12,-400.76 607.12,-400.76 607.12,-400.76 762.88,-400.76 762.88,-400.76 768.88,-400.76 780.43,-403.04 785.98,-405.32 785.98,-405.32 853.66,-433.18 853.66,-433.18 859.21,-435.46 859.21,-440.03 853.66,-442.31"/>
|
<path fill="#dcecf8" stroke="#4b5563" stroke-width="1.1" d="M810.66,-442.31C810.66,-442.31 742.98,-470.16 742.98,-470.16 737.43,-472.45 725.88,-474.73 719.88,-474.73 719.88,-474.73 564.12,-474.73 564.12,-474.73 558.12,-474.73 546.57,-472.45 541.02,-470.16 541.02,-470.16 473.34,-442.31 473.34,-442.31 467.79,-440.03 467.79,-435.46 473.34,-433.18 473.34,-433.18 541.02,-405.32 541.02,-405.32 546.57,-403.04 558.12,-400.76 564.12,-400.76 564.12,-400.76 719.88,-400.76 719.88,-400.76 725.88,-400.76 737.43,-403.04 742.98,-405.32 742.98,-405.32 810.66,-433.18 810.66,-433.18 816.21,-435.46 816.21,-440.03 810.66,-442.31"/>
|
||||||
<text text-anchor="middle" x="685" y="-446.24" font-family="Arial" font-size="10.00" fill="#111827">RIB fabric</text>
|
<text text-anchor="middle" x="642" y="-446.24" font-family="Arial" font-size="10.00" fill="#111827">RIB fabric</text>
|
||||||
<text text-anchor="middle" x="685" y="-435.24" font-family="Arial" font-size="10.00" fill="#111827">3-master round-robin arbitration</text>
|
<text text-anchor="middle" x="642" y="-435.24" font-family="Arial" font-size="10.00" fill="#111827">3-master round-robin arbitration</text>
|
||||||
<text text-anchor="middle" x="685" y="-424.24" font-family="Arial" font-size="10.00" fill="#111827">INCR1 / INCR4, access policy, fault reporting</text>
|
<text text-anchor="middle" x="642" y="-424.24" font-family="Arial" font-size="10.00" fill="#111827">INCR1 / INCR4, access policy, fault reporting</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- rcu->fabric -->
|
<!-- rcu->fabric -->
|
||||||
<g id="edge3" class="edge">
|
<g id="edge3" class="edge">
|
||||||
<title>rcu->fabric</title>
|
<title>rcu->fabric</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M344.67,-529.48C408.63,-512.43 498.81,-488.38 570.28,-469.33"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M336.43,-529.48C391.76,-513.05 468.96,-490.13 531.91,-471.43"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="571,-471.67 577.13,-467.5 569.74,-466.94 571,-471.67"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="532.72,-473.75 538.74,-469.41 531.33,-469.05 532.72,-473.75"/>
|
||||||
<text text-anchor="middle" x="496" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">system clock / reset</text>
|
<text text-anchor="middle" x="476" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">system clock / reset</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- mgmt_core -->
|
<!-- mgmt_core -->
|
||||||
<g id="node5" class="node">
|
<g id="node5" class="node">
|
||||||
<title>mgmt_core</title>
|
<title>mgmt_core</title>
|
||||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M1164,-674.48C1164,-674.48 1010,-674.48 1010,-674.48 1004,-674.48 998,-668.48 998,-662.48 998,-662.48 998,-641.48 998,-641.48 998,-635.48 1004,-629.48 1010,-629.48 1010,-629.48 1164,-629.48 1164,-629.48 1170,-629.48 1176,-635.48 1176,-641.48 1176,-641.48 1176,-662.48 1176,-662.48 1176,-668.48 1170,-674.48 1164,-674.48"/>
|
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M964,-674.48C964,-674.48 810,-674.48 810,-674.48 804,-674.48 798,-668.48 798,-662.48 798,-662.48 798,-641.48 798,-641.48 798,-635.48 804,-629.48 810,-629.48 810,-629.48 964,-629.48 964,-629.48 970,-629.48 976,-635.48 976,-641.48 976,-641.48 976,-662.48 976,-662.48 976,-668.48 970,-674.48 964,-674.48"/>
|
||||||
<text text-anchor="middle" x="1087" y="-660.48" font-family="Arial" font-size="10.00" fill="#111827">Management core</text>
|
<text text-anchor="middle" x="887" y="-660.48" font-family="Arial" font-size="10.00" fill="#111827">Management core</text>
|
||||||
<text text-anchor="middle" x="1087" y="-649.48" font-family="Arial" font-size="10.00" fill="#111827">Fixed Hazard3, branch predictor</text>
|
<text text-anchor="middle" x="887" y="-649.48" font-family="Arial" font-size="10.00" fill="#111827">Fixed Hazard3, branch predictor</text>
|
||||||
<text text-anchor="middle" x="1087" y="-638.48" font-family="Arial" font-size="10.00" fill="#111827">JTAG Debug Module always present</text>
|
<text text-anchor="middle" x="887" y="-638.48" font-family="Arial" font-size="10.00" fill="#111827">JTAG Debug Module always present</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- mgmt_adapter -->
|
<!-- mgmt_adapter -->
|
||||||
<g id="node8" class="node">
|
<g id="node8" class="node">
|
||||||
<title>mgmt_adapter</title>
|
<title>mgmt_adapter</title>
|
||||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M809.5,-569.98C809.5,-569.98 768.5,-569.98 768.5,-569.98 762.5,-569.98 756.5,-563.98 756.5,-557.98 756.5,-557.98 756.5,-545.98 756.5,-545.98 756.5,-539.98 762.5,-533.98 768.5,-533.98 768.5,-533.98 809.5,-533.98 809.5,-533.98 815.5,-533.98 821.5,-539.98 821.5,-545.98 821.5,-545.98 821.5,-557.98 821.5,-557.98 821.5,-563.98 815.5,-569.98 809.5,-569.98"/>
|
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M907.5,-569.98C907.5,-569.98 866.5,-569.98 866.5,-569.98 860.5,-569.98 854.5,-563.98 854.5,-557.98 854.5,-557.98 854.5,-545.98 854.5,-545.98 854.5,-539.98 860.5,-533.98 866.5,-533.98 866.5,-533.98 907.5,-533.98 907.5,-533.98 913.5,-533.98 919.5,-539.98 919.5,-545.98 919.5,-545.98 919.5,-557.98 919.5,-557.98 919.5,-563.98 913.5,-569.98 907.5,-569.98"/>
|
||||||
<text text-anchor="middle" x="789" y="-549.48" font-family="Arial" font-size="10.00" fill="#111827">RIBP2RIB</text>
|
<text text-anchor="middle" x="887" y="-549.48" font-family="Arial" font-size="10.00" fill="#111827">RIBP2RIB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- mgmt_core->mgmt_adapter -->
|
<!-- mgmt_core->mgmt_adapter -->
|
||||||
<g id="edge7" class="edge">
|
<g id="edge8" class="edge">
|
||||||
<title>mgmt_core->mgmt_adapter</title>
|
<title>mgmt_core->mgmt_adapter</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1021.6,-629.48C962.53,-610.05 877.54,-582.1 828.32,-565.92"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M887,-629.24C887,-613.92 887,-593.4 887,-577.51"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="829.04,-563.57 821.62,-563.71 827.51,-568.23 829.04,-563.57"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="889.45,-577.12 887,-570.12 884.55,-577.12 889.45,-577.12"/>
|
||||||
<text text-anchor="middle" x="955.5" y="-600.08" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
<text text-anchor="middle" x="896.5" y="-600.08" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- debug_module -->
|
<!-- debug_module -->
|
||||||
<g id="node7" class="node">
|
<g id="node7" class="node">
|
||||||
<title>debug_module</title>
|
<title>debug_module</title>
|
||||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M840.5,-674.48C840.5,-674.48 719.5,-674.48 719.5,-674.48 713.5,-674.48 707.5,-668.48 707.5,-662.48 707.5,-662.48 707.5,-641.48 707.5,-641.48 707.5,-635.48 713.5,-629.48 719.5,-629.48 719.5,-629.48 840.5,-629.48 840.5,-629.48 846.5,-629.48 852.5,-635.48 852.5,-641.48 852.5,-641.48 852.5,-662.48 852.5,-662.48 852.5,-668.48 846.5,-674.48 840.5,-674.48"/>
|
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M1254.5,-674.48C1254.5,-674.48 1133.5,-674.48 1133.5,-674.48 1127.5,-674.48 1121.5,-668.48 1121.5,-662.48 1121.5,-662.48 1121.5,-641.48 1121.5,-641.48 1121.5,-635.48 1127.5,-629.48 1133.5,-629.48 1133.5,-629.48 1254.5,-629.48 1254.5,-629.48 1260.5,-629.48 1266.5,-635.48 1266.5,-641.48 1266.5,-641.48 1266.5,-662.48 1266.5,-662.48 1266.5,-668.48 1260.5,-674.48 1254.5,-674.48"/>
|
||||||
<text text-anchor="middle" x="780" y="-660.48" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 Debug Module</text>
|
<text text-anchor="middle" x="1194" y="-660.48" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 Debug Module</text>
|
||||||
<text text-anchor="middle" x="780" y="-649.48" font-family="Arial" font-size="10.00" fill="#111827">abstract commands, no SBA</text>
|
<text text-anchor="middle" x="1194" y="-649.48" font-family="Arial" font-size="10.00" fill="#111827">abstract commands, no SBA</text>
|
||||||
<text text-anchor="middle" x="780" y="-638.48" font-family="Arial" font-size="10.00" fill="#111827">management-hart-only reset</text>
|
<text text-anchor="middle" x="1194" y="-638.48" font-family="Arial" font-size="10.00" fill="#111827">management-hart-only reset</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- jtag_dtm->debug_module -->
|
<!-- jtag_dtm->debug_module -->
|
||||||
<g id="edge4" class="edge">
|
<g id="edge4" class="edge">
|
||||||
<title>jtag_dtm->debug_module</title>
|
<title>jtag_dtm->debug_module</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M591.33,-651.98C626.12,-651.98 665.91,-651.98 699.95,-651.98"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M702.06,-670.13C731.11,-699.33 785,-753.48 785,-753.48 785,-753.48 990,-753.48 990,-753.48 990,-753.48 1081.81,-707.8 1142.25,-677.73"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="700.12,-654.43 707.12,-651.98 700.12,-649.53 700.12,-654.43"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1143.55,-679.82 1148.73,-674.51 1141.37,-675.44 1143.55,-679.82"/>
|
||||||
<text text-anchor="middle" x="649.25" y="-657.58" font-family="Arial" font-size="8.00" fill="#374151">DMI, asynchronous CDC</text>
|
<text text-anchor="middle" x="946" y="-786.08" font-family="Arial" font-size="8.00" fill="#374151">DMI, asynchronous CDC</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- debug_module->mgmt_core -->
|
<!-- debug_module->mgmt_core -->
|
||||||
<g id="edge5" class="edge">
|
<g id="edge5" class="edge">
|
||||||
<title>debug_module->mgmt_core</title>
|
<title>debug_module->mgmt_core</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M852.75,-651.98C893.99,-651.98 946.09,-651.98 990.69,-651.98"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1121.11,-651.98C1079.89,-651.98 1027.84,-651.98 983.29,-651.98"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="990.77,-654.43 997.77,-651.98 990.77,-649.53 990.77,-654.43"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="983.21,-649.53 976.21,-651.98 983.21,-654.43 983.21,-649.53"/>
|
||||||
<text text-anchor="middle" x="925.25" y="-657.58" font-family="Arial" font-size="8.00" fill="#374151">halt, resume, abstract commands</text>
|
<text text-anchor="middle" x="1048.75" y="-657.58" font-family="Arial" font-size="8.00" fill="#374151">halt, resume, abstract commands</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- debug_module->mgmt_adapter -->
|
<!-- debug_module->mgmt_adapter -->
|
||||||
<g id="edge6" class="edge">
|
<g id="edge6" class="edge">
|
||||||
<title>debug_module->mgmt_adapter</title>
|
<title>debug_module->mgmt_adapter</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M782,-629.24C783.4,-613.92 785.29,-593.4 786.75,-577.51"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M1126.63,-629.48C1065.43,-609.94 977.24,-581.79 926.67,-565.65"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="789.23,-577.31 787.43,-570.12 784.35,-576.86 789.23,-577.31"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="927.21,-563.25 919.79,-563.45 925.72,-567.92 927.21,-563.25"/>
|
||||||
<text text-anchor="middle" x="822" y="-600.08" font-family="Arial" font-size="8.00" fill="#374151">reset after bridge idle</text>
|
<text text-anchor="middle" x="1087" y="-600.08" font-family="Arial" font-size="8.00" fill="#374151">reset after bridge idle</text>
|
||||||
|
</g>
|
||||||
|
<!-- timers -->
|
||||||
|
<g id="node18" class="node">
|
||||||
|
<title>timers</title>
|
||||||
|
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1484.5,-255C1484.5,-255 1303.5,-255 1303.5,-255 1297.5,-255 1291.5,-249 1291.5,-243 1291.5,-243 1291.5,-222 1291.5,-222 1291.5,-216 1297.5,-210 1303.5,-210 1303.5,-210 1484.5,-210 1484.5,-210 1490.5,-210 1496.5,-216 1496.5,-222 1496.5,-222 1496.5,-243 1496.5,-243 1496.5,-249 1490.5,-255 1484.5,-255"/>
|
||||||
|
<text text-anchor="middle" x="1394" y="-241" font-family="Arial" font-size="10.00" fill="#111827">General timers 0/1</text>
|
||||||
|
<text text-anchor="middle" x="1394" y="-230" font-family="Arial" font-size="10.00" fill="#111827">32-bit counter, 16-bit prescaler</text>
|
||||||
|
<text text-anchor="middle" x="1394" 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="M1211.98,-629.24C1235.84,-600.36 1275,-552.98 1275,-552.98 1275,-552.98 1275,-552.98 1275,-327 1275,-327 1325.68,-287.18 1360.89,-259.51"/>
|
||||||
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1362.41,-261.44 1366.4,-255.19 1359.38,-257.58 1362.41,-261.44"/>
|
||||||
|
<text text-anchor="middle" x="1286" y="-435.84" font-family="Arial" font-size="8.00" fill="#374151">halted</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- mgmt_adapter->fabric -->
|
<!-- mgmt_adapter->fabric -->
|
||||||
<g id="edge8" class="edge">
|
<g id="edge9" class="edge">
|
||||||
<title>mgmt_adapter->fabric</title>
|
<title>mgmt_adapter->fabric</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M773.2,-533.94C759.91,-519.59 740.34,-498.47 723.01,-479.77"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M854.47,-536.08C821.96,-521.19 770.62,-497.67 726.55,-477.48"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="724.75,-478.03 718.19,-474.57 721.15,-481.37 724.75,-478.03"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="727.49,-475.21 720.11,-474.53 725.45,-479.67 727.49,-475.21"/>
|
||||||
<text text-anchor="middle" x="753" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
<text text-anchor="middle" x="793" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- user_core -->
|
<!-- user_core -->
|
||||||
<g id="node9" class="node">
|
<g id="node9" class="node">
|
||||||
<title>user_core</title>
|
<title>user_core</title>
|
||||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M717,-574.48C717,-574.48 641,-574.48 641,-574.48 635,-574.48 629,-568.48 629,-562.48 629,-562.48 629,-541.48 629,-541.48 629,-535.48 635,-529.48 641,-529.48 641,-529.48 717,-529.48 717,-529.48 723,-529.48 729,-535.48 729,-541.48 729,-541.48 729,-562.48 729,-562.48 729,-568.48 723,-574.48 717,-574.48"/>
|
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M680,-574.48C680,-574.48 604,-574.48 604,-574.48 598,-574.48 592,-568.48 592,-562.48 592,-562.48 592,-541.48 592,-541.48 592,-535.48 598,-529.48 604,-529.48 604,-529.48 680,-529.48 680,-529.48 686,-529.48 692,-535.48 692,-541.48 692,-541.48 692,-562.48 692,-562.48 692,-568.48 686,-574.48 680,-574.48"/>
|
||||||
<text text-anchor="middle" x="679" y="-560.48" font-family="Arial" font-size="10.00" fill="#111827">Selected user core</text>
|
<text text-anchor="middle" x="642" y="-560.48" font-family="Arial" font-size="10.00" fill="#111827">Selected user core</text>
|
||||||
<text text-anchor="middle" x="679" y="-549.48" font-family="Arial" font-size="10.00" fill="#111827">C0-C5, one active</text>
|
<text text-anchor="middle" x="642" y="-549.48" font-family="Arial" font-size="10.00" fill="#111827">C0-C5, one active</text>
|
||||||
<text text-anchor="middle" x="679" y="-538.48" font-family="Arial" font-size="10.00" fill="#111827">PicoRV32 at C5</text>
|
<text text-anchor="middle" x="642" y="-538.48" font-family="Arial" font-size="10.00" fill="#111827">PicoRV32 at C5</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- user_core->fabric -->
|
<!-- user_core->fabric -->
|
||||||
<g id="edge9" class="edge">
|
<g id="edge10" class="edge">
|
||||||
<title>user_core->fabric</title>
|
<title>user_core->fabric</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M680.16,-529.34C680.87,-515.97 681.81,-498.34 682.68,-482.19"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M642,-529.34C642,-515.97 642,-498.34 642,-482.19"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="685.14,-482.01 683.07,-474.89 680.25,-481.75 685.14,-482.01"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="644.45,-481.89 642,-474.89 639.55,-481.89 644.45,-481.89"/>
|
||||||
<text text-anchor="middle" x="688" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
<text text-anchor="middle" x="649" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- dma -->
|
<!-- dma -->
|
||||||
<g id="node10" class="node">
|
<g id="node10" class="node">
|
||||||
<title>dma</title>
|
<title>dma</title>
|
||||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M570,-569.98C570,-569.98 452,-569.98 452,-569.98 446,-569.98 440,-563.98 440,-557.98 440,-557.98 440,-545.98 440,-545.98 440,-539.98 446,-533.98 452,-533.98 452,-533.98 570,-533.98 570,-533.98 576,-533.98 582,-539.98 582,-545.98 582,-545.98 582,-557.98 582,-557.98 582,-563.98 576,-569.98 570,-569.98"/>
|
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M1197,-569.98C1197,-569.98 1079,-569.98 1079,-569.98 1073,-569.98 1067,-563.98 1067,-557.98 1067,-557.98 1067,-545.98 1067,-545.98 1067,-539.98 1073,-533.98 1079,-533.98 1079,-533.98 1197,-533.98 1197,-533.98 1203,-533.98 1209,-539.98 1209,-545.98 1209,-545.98 1209,-557.98 1209,-557.98 1209,-563.98 1203,-569.98 1197,-569.98"/>
|
||||||
<text text-anchor="middle" x="511" y="-554.98" font-family="Arial" font-size="10.00" fill="#111827">DMA</text>
|
<text text-anchor="middle" x="1138" y="-554.98" font-family="Arial" font-size="10.00" fill="#111827">DMA</text>
|
||||||
<text text-anchor="middle" x="511" y="-543.98" font-family="Arial" font-size="10.00" fill="#111827">RIB master and RIBP target</text>
|
<text text-anchor="middle" x="1138" y="-543.98" font-family="Arial" font-size="10.00" fill="#111827">RIB master and RIBP target</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- dma->fabric -->
|
<!-- dma->fabric -->
|
||||||
<g id="edge10" class="edge">
|
<g id="edge11" class="edge">
|
||||||
<title>dma->fabric</title>
|
<title>dma->fabric</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M537.43,-533.94C560.15,-519.28 593.81,-497.56 623.25,-478.57"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1080.16,-533.98C1026.87,-518.32 956,-497.48 956,-497.48 956,-497.48 857.85,-479.12 771.3,-462.93"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="624.91,-480.42 629.47,-474.57 622.26,-476.3 624.91,-480.42"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="771.63,-460.5 764.3,-461.62 770.73,-465.32 771.63,-460.5"/>
|
||||||
<text text-anchor="middle" x="599" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
<text text-anchor="middle" x="993" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ws2812 -->
|
<!-- ws2812 -->
|
||||||
<g id="node18" class="node">
|
<g id="node19" class="node">
|
||||||
<title>ws2812</title>
|
<title>ws2812</title>
|
||||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M540,-255C540,-255 406,-255 406,-255 400,-255 394,-249 394,-243 394,-243 394,-222 394,-222 394,-216 400,-210 406,-210 406,-210 540,-210 540,-210 546,-210 552,-216 552,-222 552,-222 552,-243 552,-243 552,-249 546,-255 540,-255"/>
|
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1253,-255C1253,-255 1119,-255 1119,-255 1113,-255 1107,-249 1107,-243 1107,-243 1107,-222 1107,-222 1107,-216 1113,-210 1119,-210 1119,-210 1253,-210 1253,-210 1259,-210 1265,-216 1265,-222 1265,-222 1265,-243 1265,-243 1265,-249 1259,-255 1253,-255"/>
|
||||||
<text text-anchor="middle" x="473" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WS2812 TX</text>
|
<text text-anchor="middle" x="1186" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WS2812 TX</text>
|
||||||
<text text-anchor="middle" x="473" y="-230" font-family="Arial" font-size="10.00" fill="#111827">24-bit MSB-first serializer</text>
|
<text text-anchor="middle" x="1186" y="-230" font-family="Arial" font-size="10.00" fill="#111827">24-bit MSB-first serializer</text>
|
||||||
<text text-anchor="middle" x="473" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16-word FIFO, IRQ17, DMA-fed</text>
|
<text text-anchor="middle" x="1186" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16-word FIFO, IRQ17, DMA-fed</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- dma->ws2812 -->
|
<!-- dma->ws2812 -->
|
||||||
<g id="edge21" class="edge">
|
<g id="edge24" class="edge">
|
||||||
<title>dma->ws2812</title>
|
<title>dma->ws2812</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M506.69,-533.63C501.08,-511.05 492,-474.48 492,-474.48 492,-474.48 480.31,-326.28 475.27,-262.32"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M1145.49,-533.63C1155.22,-511.05 1171,-474.48 1171,-474.48 1171,-474.48 1180.23,-326.28 1184.21,-262.32"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="477.71,-262.1 474.72,-255.31 472.83,-262.48 477.71,-262.1"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1186.65,-262.45 1184.64,-255.31 1181.76,-262.15 1186.65,-262.45"/>
|
||||||
<text text-anchor="middle" x="511.5" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">TXDATA writes</text>
|
<text text-anchor="middle" x="1204.5" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">TXDATA writes</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fault -->
|
<!-- fault -->
|
||||||
<g id="node12" class="node">
|
<g id="node12" class="node">
|
||||||
<title>fault</title>
|
<title>fault</title>
|
||||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M1065.5,-455.74C1065.5,-455.74 956.5,-455.74 956.5,-455.74 950.5,-455.74 944.5,-449.74 944.5,-443.74 944.5,-443.74 944.5,-431.74 944.5,-431.74 944.5,-425.74 950.5,-419.74 956.5,-419.74 956.5,-419.74 1065.5,-419.74 1065.5,-419.74 1071.5,-419.74 1077.5,-425.74 1077.5,-431.74 1077.5,-431.74 1077.5,-443.74 1077.5,-443.74 1077.5,-449.74 1071.5,-455.74 1065.5,-455.74"/>
|
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M1145.5,-455.74C1145.5,-455.74 1036.5,-455.74 1036.5,-455.74 1030.5,-455.74 1024.5,-449.74 1024.5,-443.74 1024.5,-443.74 1024.5,-431.74 1024.5,-431.74 1024.5,-425.74 1030.5,-419.74 1036.5,-419.74 1036.5,-419.74 1145.5,-419.74 1145.5,-419.74 1151.5,-419.74 1157.5,-425.74 1157.5,-431.74 1157.5,-431.74 1157.5,-443.74 1157.5,-443.74 1157.5,-449.74 1151.5,-455.74 1145.5,-455.74"/>
|
||||||
<text text-anchor="middle" x="1011" y="-440.74" font-family="Arial" font-size="10.00" fill="#111827">Error slave</text>
|
<text text-anchor="middle" x="1091" y="-440.74" font-family="Arial" font-size="10.00" fill="#111827">Error slave</text>
|
||||||
<text text-anchor="middle" x="1011" y="-429.74" font-family="Arial" font-size="10.00" fill="#111827">access and protocol faults</text>
|
<text text-anchor="middle" x="1091" y="-429.74" font-family="Arial" font-size="10.00" fill="#111827">access and protocol faults</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fabric->fault -->
|
<!-- fabric->fault -->
|
||||||
<g id="edge11" class="edge">
|
<g id="edge12" class="edge">
|
||||||
<title>fabric->fault</title>
|
<title>fabric->fault</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M871.98,-437.74C894.93,-437.74 917.24,-437.74 937.02,-437.74"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M764.45,-466.01C829.63,-481.05 896.5,-496.48 896.5,-496.48 896.5,-496.48 949.5,-496.48 949.5,-496.48 949.5,-496.48 1011,-474.48 1011,-474.48 1011,-474.48 1027.11,-467.08 1044.88,-458.93"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="871.69,-435.29 864.69,-437.74 871.69,-440.19 871.69,-435.29"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="764.71,-463.55 757.34,-464.36 763.61,-468.33 764.71,-463.55"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="937.19,-440.19 944.19,-437.74 937.19,-435.29 937.19,-440.19"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1046.13,-461.05 1051.47,-455.9 1044.08,-456.59 1046.13,-461.05"/>
|
||||||
<text text-anchor="middle" x="904.56" y="-443.34" font-family="Arial" font-size="8.00" fill="#374151">invalid / denied</text>
|
<text text-anchor="middle" x="923" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">invalid / denied</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- sram -->
|
<!-- sram -->
|
||||||
<g id="node13" class="node">
|
<g id="node13" class="node">
|
||||||
<title>sram</title>
|
<title>sram</title>
|
||||||
<path fill="#fff3c9" stroke="#4b5563" stroke-width="1.1" d="M1215,-455.74C1215,-455.74 1117,-455.74 1117,-455.74 1111,-455.74 1105,-449.74 1105,-443.74 1105,-443.74 1105,-431.74 1105,-431.74 1105,-425.74 1111,-419.74 1117,-419.74 1117,-419.74 1215,-419.74 1215,-419.74 1221,-419.74 1227,-425.74 1227,-431.74 1227,-431.74 1227,-443.74 1227,-443.74 1227,-449.74 1221,-455.74 1215,-455.74"/>
|
<path fill="#fff3c9" stroke="#4b5563" stroke-width="1.1" d="M985,-455.74C985,-455.74 887,-455.74 887,-455.74 881,-455.74 875,-449.74 875,-443.74 875,-443.74 875,-431.74 875,-431.74 875,-425.74 881,-419.74 887,-419.74 887,-419.74 985,-419.74 985,-419.74 991,-419.74 997,-425.74 997,-431.74 997,-431.74 997,-443.74 997,-443.74 997,-449.74 991,-455.74 985,-455.74"/>
|
||||||
<text text-anchor="middle" x="1166" y="-440.74" font-family="Arial" font-size="10.00" fill="#111827">On-chip SRAM</text>
|
<text text-anchor="middle" x="936" y="-440.74" font-family="Arial" font-size="10.00" fill="#111827">On-chip SRAM</text>
|
||||||
<text text-anchor="middle" x="1166" y="-429.74" font-family="Arial" font-size="10.00" fill="#111827">optional RIB2RAM path</text>
|
<text text-anchor="middle" x="936" y="-429.74" font-family="Arial" font-size="10.00" fill="#111827">optional RIB2RAM path</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fabric->sram -->
|
<!-- fabric->sram -->
|
||||||
<g id="edge12" class="edge">
|
<g id="edge13" class="edge">
|
||||||
<title>fabric->sram</title>
|
<title>fabric->sram</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M805.88,-462.06C886.21,-478.22 977,-496.48 977,-496.48 977,-496.48 991,-496.48 991,-496.48 991,-496.48 1091,-474.48 1091,-474.48 1091,-474.48 1105.84,-467.21 1122.32,-459.14"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M821.91,-437.74C837.95,-437.74 853.44,-437.74 867.56,-437.74"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1123.73,-461.18 1128.94,-455.9 1121.58,-456.78 1123.73,-461.18"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="867.81,-440.19 874.81,-437.74 867.81,-435.29 867.81,-440.19"/>
|
||||||
<text text-anchor="middle" x="984" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
<text text-anchor="middle" x="848.31" y="-443.34" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_adapter -->
|
<!-- ribp_adapter -->
|
||||||
<g id="node14" class="node">
|
<g id="node14" class="node">
|
||||||
<title>ribp_adapter</title>
|
<title>ribp_adapter</title>
|
||||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M708.5,-346C708.5,-346 667.5,-346 667.5,-346 661.5,-346 655.5,-340 655.5,-334 655.5,-334 655.5,-322 655.5,-322 655.5,-316 661.5,-310 667.5,-310 667.5,-310 708.5,-310 708.5,-310 714.5,-310 720.5,-316 720.5,-322 720.5,-322 720.5,-334 720.5,-334 720.5,-340 714.5,-346 708.5,-346"/>
|
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M985.5,-346C985.5,-346 944.5,-346 944.5,-346 938.5,-346 932.5,-340 932.5,-334 932.5,-334 932.5,-322 932.5,-322 932.5,-316 938.5,-310 944.5,-310 944.5,-310 985.5,-310 985.5,-310 991.5,-310 997.5,-316 997.5,-322 997.5,-322 997.5,-334 997.5,-334 997.5,-340 991.5,-346 985.5,-346"/>
|
||||||
<text text-anchor="middle" x="688" y="-325.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
<text text-anchor="middle" x="965" y="-325.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fabric->ribp_adapter -->
|
<!-- fabric->ribp_adapter -->
|
||||||
<g id="edge13" class="edge">
|
<g id="edge14" class="edge">
|
||||||
<title>fabric->ribp_adapter</title>
|
<title>fabric->ribp_adapter</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M686,-400.87C686.43,-385.27 686.93,-367.39 687.32,-353.38"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M740.23,-403.98C802.54,-383.19 879.79,-357.42 925.59,-342.15"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="689.78,-353.09 687.53,-346.02 684.88,-352.95 689.78,-353.09"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="926.52,-344.42 932.39,-339.88 924.97,-339.77 926.52,-344.42"/>
|
||||||
<text text-anchor="middle" x="693" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
<text text-anchor="middle" x="848" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- apb_adapter -->
|
<!-- apb_adapter -->
|
||||||
<g id="node15" class="node">
|
<g id="node15" class="node">
|
||||||
<title>apb_adapter</title>
|
<title>apb_adapter</title>
|
||||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M875,-346C875,-346 805,-346 805,-346 799,-346 793,-340 793,-334 793,-334 793,-322 793,-322 793,-316 799,-310 805,-310 805,-310 875,-310 875,-310 881,-310 887,-316 887,-322 887,-322 887,-334 887,-334 887,-340 881,-346 875,-346"/>
|
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M618,-346C618,-346 548,-346 548,-346 542,-346 536,-340 536,-334 536,-334 536,-322 536,-322 536,-316 542,-310 548,-310 548,-310 618,-310 618,-310 624,-310 630,-316 630,-322 630,-322 630,-334 630,-334 630,-340 624,-346 618,-346"/>
|
||||||
<text text-anchor="middle" x="840" y="-331" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
|
<text text-anchor="middle" x="583" y="-331" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
|
||||||
<text text-anchor="middle" x="840" y="-320" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
|
<text text-anchor="middle" x="583" y="-320" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fabric->apb_adapter -->
|
<!-- fabric->apb_adapter -->
|
||||||
<g id="edge14" class="edge">
|
<g id="edge15" class="edge">
|
||||||
<title>fabric->apb_adapter</title>
|
<title>fabric->apb_adapter</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M736.61,-400.87C760.82,-384.04 788.83,-364.57 809.59,-350.14"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M622.35,-400.87C613.57,-384.83 603.48,-366.4 595.71,-352.22"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="811.16,-352.03 815.51,-346.02 808.37,-348.01 811.16,-352.03"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="597.83,-350.98 592.32,-346.02 593.53,-353.34 597.83,-350.98"/>
|
||||||
<text text-anchor="middle" x="787" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
<text text-anchor="middle" x="615" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- sysctrl -->
|
<!-- sysctrl -->
|
||||||
<g id="node16" class="node">
|
<g id="node16" class="node">
|
||||||
<title>sysctrl</title>
|
<title>sysctrl</title>
|
||||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1010.5,-255C1010.5,-255 847.5,-255 847.5,-255 841.5,-255 835.5,-249 835.5,-243 835.5,-243 835.5,-222 835.5,-222 835.5,-216 841.5,-210 847.5,-210 847.5,-210 1010.5,-210 1010.5,-210 1016.5,-210 1022.5,-216 1022.5,-222 1022.5,-222 1022.5,-243 1022.5,-243 1022.5,-249 1016.5,-255 1010.5,-255"/>
|
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M811.5,-255C811.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 811.5,-210 811.5,-210 817.5,-210 823.5,-216 823.5,-222 823.5,-222 823.5,-243 823.5,-243 823.5,-249 817.5,-255 811.5,-255"/>
|
||||||
<text text-anchor="middle" x="929" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL and CLINT</text>
|
<text text-anchor="middle" x="730" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL and CLINT</text>
|
||||||
<text text-anchor="middle" x="929" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user-core select/reset/bus enable</text>
|
<text text-anchor="middle" x="730" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user-core select/reset/bus enable</text>
|
||||||
<text text-anchor="middle" x="929" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
|
<text text-anchor="middle" x="730" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_adapter->sysctrl -->
|
<!-- ribp_adapter->sysctrl -->
|
||||||
<g id="edge15" class="edge">
|
<g id="edge16" class="edge">
|
||||||
<title>ribp_adapter->sysctrl</title>
|
<title>ribp_adapter->sysctrl</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M720.5,-314.39C757.85,-299.9 820,-275.79 866.75,-257.65"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M932.32,-314C895.78,-299.46 835.8,-275.6 790.62,-257.62"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="867.89,-259.84 873.53,-255.02 866.12,-255.27 867.89,-259.84"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="791.47,-255.32 784.06,-255.01 789.66,-259.87 791.47,-255.32"/>
|
||||||
<text text-anchor="middle" x="817.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
<text text-anchor="middle" x="870.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_targets -->
|
<!-- ribp_targets -->
|
||||||
<g id="node17" class="node">
|
<g id="node17" class="node">
|
||||||
<title>ribp_targets</title>
|
<title>ribp_targets</title>
|
||||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M796.5,-255C796.5,-255 591.5,-255 591.5,-255 585.5,-255 579.5,-249 579.5,-243 579.5,-243 579.5,-222 579.5,-222 579.5,-216 585.5,-210 591.5,-210 591.5,-210 796.5,-210 796.5,-210 802.5,-210 808.5,-216 808.5,-222 808.5,-222 808.5,-243 808.5,-243 808.5,-249 802.5,-255 796.5,-255"/>
|
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1067.5,-255C1067.5,-255 862.5,-255 862.5,-255 856.5,-255 850.5,-249 850.5,-243 850.5,-243 850.5,-222 850.5,-222 850.5,-216 856.5,-210 862.5,-210 862.5,-210 1067.5,-210 1067.5,-210 1073.5,-210 1079.5,-216 1079.5,-222 1079.5,-222 1079.5,-243 1079.5,-243 1079.5,-249 1073.5,-255 1067.5,-255"/>
|
||||||
<text text-anchor="middle" x="694" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
|
<text text-anchor="middle" x="965" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
|
||||||
<text text-anchor="middle" x="694" 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="965" 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="694" y="-219" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, timers, I2C and I2S</text>
|
<text text-anchor="middle" x="965" y="-219" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, I2C and I2S</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_adapter->ribp_targets -->
|
<!-- ribp_adapter->ribp_targets -->
|
||||||
<g id="edge16" class="edge">
|
<g id="edge17" class="edge">
|
||||||
<title>ribp_adapter->ribp_targets</title>
|
<title>ribp_adapter->ribp_targets</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M689.1,-309.85C689.95,-296.62 691.14,-278.02 692.14,-262.49"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M965,-309.85C965,-296.62 965,-278.02 965,-262.49"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="694.61,-262.29 692.61,-255.15 689.72,-261.98 694.61,-262.29"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="967.45,-262.15 965,-255.15 962.55,-262.15 967.45,-262.15"/>
|
||||||
<text text-anchor="middle" x="700.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
<text text-anchor="middle" x="974.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||||
|
</g>
|
||||||
|
<!-- ribp_adapter->timers -->
|
||||||
|
<g id="edge18" class="edge">
|
||||||
|
<title>ribp_adapter->timers</title>
|
||||||
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M997.6,-319.9C1058.64,-306.59 1192.62,-277.39 1287.89,-256.63"/>
|
||||||
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1288.65,-258.97 1294.97,-255.08 1287.61,-254.18 1288.65,-258.97"/>
|
||||||
|
<text text-anchor="middle" x="1188.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_adapter->ws2812 -->
|
<!-- ribp_adapter->ws2812 -->
|
||||||
<g id="edge17" class="edge">
|
<g id="edge19" class="edge">
|
||||||
<title>ribp_adapter->ws2812</title>
|
<title>ribp_adapter->ws2812</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M655.35,-312.8C622.03,-298.31 569.68,-275.54 529.6,-258.11"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M997.61,-313.2C1031.91,-298.69 1086.6,-275.55 1128.23,-257.94"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="530.17,-255.69 522.77,-255.15 528.21,-260.18 530.17,-255.69"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1129.31,-260.15 1134.8,-255.16 1127.4,-255.63 1129.31,-260.15"/>
|
||||||
<text text-anchor="middle" x="602.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
<text text-anchor="middle" x="1084.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- apb_targets -->
|
<!-- apb_targets -->
|
||||||
<g id="node19" class="node">
|
<g id="node20" class="node">
|
||||||
<title>apb_targets</title>
|
<title>apb_targets</title>
|
||||||
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1252.5,-255C1252.5,-255 1061.5,-255 1061.5,-255 1055.5,-255 1049.5,-249 1049.5,-243 1049.5,-243 1049.5,-222 1049.5,-222 1049.5,-216 1055.5,-210 1061.5,-210 1061.5,-210 1252.5,-210 1252.5,-210 1258.5,-210 1264.5,-216 1264.5,-222 1264.5,-222 1264.5,-243 1264.5,-243 1264.5,-249 1258.5,-255 1252.5,-255"/>
|
<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="1157" y="-241" font-family="Arial" font-size="10.00" fill="#111827">APB target wrapper</text>
|
<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="1157" 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="-230" font-family="Arial" font-size="10.00" fill="#111827">Archinfo, RNG, UART1, PWM, PS/2, RTC</text>
|
||||||
<text text-anchor="middle" x="1157" y="-219" font-family="Arial" font-size="10.00" fill="#111827">watchdog, CRC, advanced timer and user IP</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>
|
</g>
|
||||||
<!-- apb_adapter->apb_targets -->
|
<!-- apb_adapter->apb_targets -->
|
||||||
<g id="edge18" class="edge">
|
<g id="edge20" class="edge">
|
||||||
<title>apb_adapter->apb_targets</title>
|
<title>apb_adapter->apb_targets</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M887.12,-313.1C937.19,-298.33 1017.25,-274.72 1077.19,-257.04"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M568.14,-309.85C556.27,-296.14 539.39,-276.66 525.66,-260.81"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1078,-259.35 1084.02,-255.02 1076.62,-254.65 1078,-259.35"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="527.19,-258.84 520.75,-255.15 523.49,-262.04 527.19,-258.84"/>
|
||||||
<text text-anchor="middle" x="1006" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
|
<text text-anchor="middle" x="555" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_targets->ext_io -->
|
<!-- ribp_targets->ext_io -->
|
||||||
<g id="edge24" class="edge">
|
<g id="edge27" class="edge">
|
||||||
<title>ribp_targets->ext_io</title>
|
<title>ribp_targets->ext_io</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M780.98,-208.04C820.68,-197.33 859,-187 859,-187 859,-187 859,-178 859,-178 859,-178 837,-85 837,-85 837,-85 828.54,-67.66 820.6,-51.39"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1086.9,-211.18C1091.39,-210.44 1094,-210 1094,-210 1094,-210 1342,-187 1342,-187 1342,-187 1342,-178 1342,-178 1342,-178 1320,-85 1320,-85 1320,-85 1267.94,-64.86 1223.4,-47.64"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="780.2,-205.71 774.08,-209.9 781.48,-210.44 780.2,-205.71"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1086.2,-208.82 1079.7,-212.38 1087.01,-213.65 1086.2,-208.82"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="822.76,-50.23 817.49,-45.01 818.36,-52.38 822.76,-50.23"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1224.02,-45.25 1216.61,-45.01 1222.26,-49.82 1224.02,-45.25"/>
|
||||||
<text text-anchor="middle" x="883" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
|
<text text-anchor="middle" x="1366" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- gpio_bridge -->
|
<!-- gpio_bridge -->
|
||||||
<g id="node20" class="node">
|
<g id="node21" class="node">
|
||||||
<title>gpio_bridge</title>
|
<title>gpio_bridge</title>
|
||||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M811,-155C811,-155 663,-155 663,-155 657,-155 651,-149 651,-143 651,-143 651,-131 651,-131 651,-125 657,-119 663,-119 663,-119 811,-119 811,-119 817,-119 823,-125 823,-131 823,-131 823,-143 823,-143 823,-149 817,-155 811,-155"/>
|
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M1037,-155C1037,-155 889,-155 889,-155 883,-155 877,-149 877,-143 877,-143 877,-131 877,-131 877,-125 883,-119 889,-119 889,-119 1037,-119 1037,-119 1043,-119 1049,-125 1049,-131 1049,-131 1049,-143 1049,-143 1049,-149 1043,-155 1037,-155"/>
|
||||||
<text text-anchor="middle" x="737" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
|
<text text-anchor="middle" x="963" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
|
||||||
<text text-anchor="middle" x="737" y="-129" font-family="Arial" font-size="10.00" fill="#111827">software, alternate and user modes</text>
|
<text text-anchor="middle" x="963" y="-129" font-family="Arial" font-size="10.00" fill="#111827">software, alternate and user modes</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_targets->gpio_bridge -->
|
<!-- ribp_targets->gpio_bridge -->
|
||||||
<g id="edge19" class="edge">
|
<g id="edge21" class="edge">
|
||||||
<title>ribp_targets->gpio_bridge</title>
|
<title>ribp_targets->gpio_bridge</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M695.22,-209.74C696.05,-194.93 697,-178 697,-178 697,-178 705.52,-169.48 714.69,-160.31"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M964.54,-209.81C964.23,-195.66 963.84,-177.17 963.52,-162.49"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="716.59,-161.88 719.8,-155.2 713.12,-158.41 716.59,-161.88"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="965.97,-162.15 963.37,-155.2 961.07,-162.25 965.97,-162.15"/>
|
||||||
<text text-anchor="middle" x="741" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO alternate functions</text>
|
<text text-anchor="middle" x="1008" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO alternate functions</text>
|
||||||
</g>
|
|
||||||
<!-- ws2812->gpio_bridge -->
|
|
||||||
<g id="edge20" class="edge">
|
|
||||||
<title>ws2812->gpio_bridge</title>
|
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M533.9,-209.93C578.56,-194.11 638.71,-172.81 681.94,-157.5"/>
|
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="682.94,-159.74 688.73,-155.1 681.31,-155.12 682.94,-159.74"/>
|
|
||||||
<text text-anchor="middle" x="642.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO2 ALT1</text>
|
|
||||||
</g>
|
</g>
|
||||||
<!-- irq -->
|
<!-- irq -->
|
||||||
<g id="node21" class="node">
|
<g id="node22" class="node">
|
||||||
<title>irq</title>
|
<title>irq</title>
|
||||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M612,-155C612,-155 406,-155 406,-155 400,-155 394,-149 394,-143 394,-143 394,-131 394,-131 394,-125 400,-119 406,-119 406,-119 612,-119 612,-119 618,-119 624,-125 624,-131 624,-131 624,-143 624,-143 624,-149 618,-155 612,-155"/>
|
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M1294,-155C1294,-155 1088,-155 1088,-155 1082,-155 1076,-149 1076,-143 1076,-143 1076,-131 1076,-131 1076,-125 1082,-119 1088,-119 1088,-119 1294,-119 1294,-119 1300,-119 1306,-125 1306,-131 1306,-131 1306,-143 1306,-143 1306,-149 1300,-155 1294,-155"/>
|
||||||
<text text-anchor="middle" x="509" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
|
<text text-anchor="middle" x="1191" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
|
||||||
<text text-anchor="middle" x="509" y="-129" font-family="Arial" font-size="10.00" fill="#111827">RIBP and APB target IRQs to management core</text>
|
<text text-anchor="middle" x="1191" y="-129" font-family="Arial" font-size="10.00" fill="#111827">RIBP and APB target IRQs to management core</text>
|
||||||
|
</g>
|
||||||
|
<!-- timers->irq -->
|
||||||
|
<g id="edge22" class="edge">
|
||||||
|
<title>timers->irq</title>
|
||||||
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1347.17,-209.93C1313.25,-194.31 1267.72,-173.34 1234.58,-158.07"/>
|
||||||
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1235.5,-155.8 1228.12,-155.1 1233.45,-160.25 1235.5,-155.8"/>
|
||||||
|
<text text-anchor="middle" x="1314.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ3 / IRQ4</text>
|
||||||
|
</g>
|
||||||
|
<!-- ws2812->gpio_bridge -->
|
||||||
|
<g id="edge23" class="edge">
|
||||||
|
<title>ws2812->gpio_bridge</title>
|
||||||
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1134.56,-209.93C1097.14,-194.24 1046.86,-173.16 1010.42,-157.88"/>
|
||||||
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1011.18,-155.54 1003.78,-155.1 1009.29,-160.06 1011.18,-155.54"/>
|
||||||
|
<text text-anchor="middle" x="1096.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO2 ALT1</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ws2812->irq -->
|
<!-- ws2812->irq -->
|
||||||
<g id="edge22" class="edge">
|
<g id="edge25" class="edge">
|
||||||
<title>ws2812->irq</title>
|
<title>ws2812->irq</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M481.35,-209.81C486.85,-195.54 494.05,-176.83 499.73,-162.09"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1187.16,-209.81C1187.92,-195.66 1188.91,-177.17 1189.69,-162.49"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="502.15,-162.62 502.38,-155.2 497.57,-160.86 502.15,-162.62"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1192.15,-162.32 1190.08,-155.2 1187.26,-162.06 1192.15,-162.32"/>
|
||||||
<text text-anchor="middle" x="505" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ17</text>
|
<text text-anchor="middle" x="1200" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ17</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- apb_targets->gpio_bridge -->
|
<!-- apb_targets->gpio_bridge -->
|
||||||
<g id="edge23" class="edge">
|
<g id="edge26" class="edge">
|
||||||
<title>apb_targets->gpio_bridge</title>
|
<title>apb_targets->gpio_bridge</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1060.38,-209.99C987.9,-193.86 889.69,-171.99 820.58,-156.61"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M608.05,-209.99C687.77,-193.82 795.84,-171.9 871.72,-156.51"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="820.93,-154.17 813.56,-155.04 819.86,-158.96 820.93,-154.17"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="872.59,-158.84 878.97,-155.04 871.62,-154.03 872.59,-158.84"/>
|
||||||
<text text-anchor="middle" x="965" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
|
<text text-anchor="middle" x="778" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- gpio_bridge->ext_io -->
|
<!-- gpio_bridge->ext_io -->
|
||||||
<g id="edge25" class="edge">
|
<g id="edge28" class="edge">
|
||||||
<title>gpio_bridge->ext_io</title>
|
<title>gpio_bridge->ext_io</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M751.43,-112.81C762.49,-95.04 777.79,-70.44 789.54,-51.56"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M999.4,-115.32C1032.38,-96.58 1081.08,-68.91 1116.39,-48.84"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="749.25,-111.68 747.63,-118.91 753.41,-114.26 749.25,-111.68"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="997.95,-113.33 993.07,-118.91 1000.37,-117.59 997.95,-113.33"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="791.76,-52.63 793.38,-45.39 787.6,-50.04 791.76,-52.63"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1117.95,-50.78 1122.83,-45.19 1115.53,-46.52 1117.95,-50.78"/>
|
||||||
<text text-anchor="middle" x="798" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
|
<text text-anchor="middle" x="1099" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 32 KiB |
@@ -37,7 +37,7 @@ reset/latch time, after abort, and after underflow.
|
|||||||
The RIBP TX FIFO is also a fixed-address target for the generic DMA engine.
|
The RIBP TX FIFO is also a fixed-address target for the generic DMA engine.
|
||||||
DMA remains a normal RIB master and receives RIBP backpressure when the FIFO
|
DMA remains a normal RIB master and receives RIBP backpressure when the FIFO
|
||||||
is full; the transmitter does not own a private DMA request channel. See
|
is full; the transmitter does not own a private DMA request channel. See
|
||||||
[ws2812.md](ws2812.md) for the register and transfer contract.
|
[ws2812.md](ip/ws2812.md) for the register and transfer contract.
|
||||||
|
|
||||||
## Management JTAG
|
## Management JTAG
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,35 @@ RTL changes require an affected firmware build and simulation. Use
|
|||||||
`make regress-pr` or `make regress-nightly` for supported regression coverage;
|
`make regress-pr` or `make regress-nightly` for supported regression coverage;
|
||||||
see [Engineering Workflow](../docs/engineering.md) for results and artifacts.
|
see [Engineering Workflow](../docs/engineering.md) for results and artifacts.
|
||||||
|
|
||||||
|
## Self-Owned RTL Naming
|
||||||
|
|
||||||
|
Self-owned SystemVerilog follows these signal and register naming rules. New
|
||||||
|
RTL and local changes to existing RTL must preserve them:
|
||||||
|
|
||||||
|
- Declare synthesizable data, state, and interconnect signals as `logic`.
|
||||||
|
Reserve explicit net types for signals that require net resolution semantics.
|
||||||
|
- Use `_i` and `_o` for module ports, `s_` for internal signals, and `u_` for
|
||||||
|
module instances.
|
||||||
|
- Name state owned by the current module `s_<name>_d` for next state and
|
||||||
|
`s_<name>_q` for registered current state. Keep the pair adjacent in the
|
||||||
|
declaration and connect it through a reusable register component from
|
||||||
|
ClusterIP Common.
|
||||||
|
- Name a register write enable `s_<name>_en`. Do not add `_d` or `_q` to an
|
||||||
|
ordinary combinational signal or to a parent-module connection simply
|
||||||
|
because its source is registered inside a child module.
|
||||||
|
- Use `s_req`, `s_write`, `s_req_accept`, and `s_access_error` for a RIBP slave
|
||||||
|
transaction. Name its registered response signals `s_ribp_ready_d/q`,
|
||||||
|
`s_ribp_rdata_d/q`, and `s_ribp_resp_err_d/q`.
|
||||||
|
- Name register offsets `RIBP_<IP>_<REGISTER>` and field bit positions
|
||||||
|
`<IP>_<REGISTER>_<FIELD>`. Do not add redundant `_OFFSET`, `_LSB`, `_MASK`,
|
||||||
|
or `_VALUE` suffixes; keep implementation-only masks and constant values as
|
||||||
|
typed `localparam` declarations in the owning module.
|
||||||
|
|
||||||
|
Run `verible-verilog-format --flagfile=.verible-format` on changed RTL. Where
|
||||||
|
the formatter cannot preserve required macro or port-column alignment, use a
|
||||||
|
narrow `// verilog_format: off/on` region and align the enclosed declarations
|
||||||
|
manually.
|
||||||
|
|
||||||
The Verilator harness uses a zero-delay SDRAM protocol model because Verilator
|
The Verilator harness uses a zero-delay SDRAM protocol model because Verilator
|
||||||
does not elaborate the tri-state delays in the Micron model. The Icarus
|
does not elaborate the tri-state delays in the Micron model. The Icarus
|
||||||
testbench retains that Micron timing model, so it is the reference for SDRAM
|
testbench retains that Micron timing model, so it is the reference for SDRAM
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
|
||||||
|
module ribp_timer (
|
||||||
|
// verilog_format: off
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_n_i,
|
||||||
|
input logic debug_halted_i,
|
||||||
|
ribp_if.slave ribp,
|
||||||
|
output logic irq_o
|
||||||
|
// verilog_format: on
|
||||||
|
);
|
||||||
|
|
||||||
|
logic s_enable;
|
||||||
|
logic [ 1:0] s_mode;
|
||||||
|
logic s_direction;
|
||||||
|
logic s_debug_freeze_enable;
|
||||||
|
logic s_compare0_enable;
|
||||||
|
logic s_compare1_enable;
|
||||||
|
logic [15:0] s_prescale;
|
||||||
|
logic [31:0] s_load;
|
||||||
|
logic [31:0] s_compare0;
|
||||||
|
logic [31:0] s_compare1;
|
||||||
|
logic s_start;
|
||||||
|
logic s_stop;
|
||||||
|
logic s_load_now;
|
||||||
|
logic [31:0] s_value;
|
||||||
|
logic s_debug_frozen;
|
||||||
|
logic s_timeout_event;
|
||||||
|
logic s_compare0_event;
|
||||||
|
logic s_compare1_event;
|
||||||
|
logic s_one_shot_done;
|
||||||
|
|
||||||
|
timer_reg u_timer_reg (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
.ribp (ribp),
|
||||||
|
.value_i (s_value),
|
||||||
|
.debug_frozen_i (s_debug_frozen),
|
||||||
|
.timeout_event_i (s_timeout_event),
|
||||||
|
.compare0_event_i (s_compare0_event),
|
||||||
|
.compare1_event_i (s_compare1_event),
|
||||||
|
.one_shot_done_i (s_one_shot_done),
|
||||||
|
.enable_o (s_enable),
|
||||||
|
.mode_o (s_mode),
|
||||||
|
.direction_o (s_direction),
|
||||||
|
.debug_freeze_enable_o(s_debug_freeze_enable),
|
||||||
|
.compare0_enable_o (s_compare0_enable),
|
||||||
|
.compare1_enable_o (s_compare1_enable),
|
||||||
|
.prescale_o (s_prescale),
|
||||||
|
.load_o (s_load),
|
||||||
|
.compare0_o (s_compare0),
|
||||||
|
.compare1_o (s_compare1),
|
||||||
|
.start_o (s_start),
|
||||||
|
.stop_o (s_stop),
|
||||||
|
.load_now_o (s_load_now),
|
||||||
|
.irq_o (irq_o)
|
||||||
|
);
|
||||||
|
|
||||||
|
timer_core u_timer_core (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
.enable_i (s_enable),
|
||||||
|
.mode_i (s_mode),
|
||||||
|
.direction_i (s_direction),
|
||||||
|
.debug_freeze_enable_i(s_debug_freeze_enable),
|
||||||
|
.debug_halted_i (debug_halted_i),
|
||||||
|
.compare0_enable_i (s_compare0_enable),
|
||||||
|
.compare1_enable_i (s_compare1_enable),
|
||||||
|
.prescale_i (s_prescale),
|
||||||
|
.load_i (s_load),
|
||||||
|
.compare0_i (s_compare0),
|
||||||
|
.compare1_i (s_compare1),
|
||||||
|
.start_i (s_start),
|
||||||
|
.stop_i (s_stop),
|
||||||
|
.load_now_i (s_load_now),
|
||||||
|
.value_o (s_value),
|
||||||
|
.debug_frozen_o (s_debug_frozen),
|
||||||
|
.timeout_event_o (s_timeout_event),
|
||||||
|
.compare0_event_o (s_compare0_event),
|
||||||
|
.compare1_event_o (s_compare1_event),
|
||||||
|
.one_shot_done_o (s_one_shot_done)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -1,183 +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.
|
|
||||||
*
|
|
||||||
* Simple 32-bit counter-timer for ravenna. */
|
|
||||||
|
|
||||||
// -- 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_TIMER_DEF_SV
|
|
||||||
`define RIBP_TIMER_DEF_SV
|
|
||||||
|
|
||||||
// verilog_format: off
|
|
||||||
`define RIBP_TIMER_CFG 8'h00
|
|
||||||
`define RIBP_TIMER_RLD 8'h04
|
|
||||||
`define RIBP_TIMER_VAL 8'h08
|
|
||||||
// verilog_format: on
|
|
||||||
|
|
||||||
`endif
|
|
||||||
|
|
||||||
module ribp_timer (
|
|
||||||
// verilog_format: off
|
|
||||||
input logic clk_i,
|
|
||||||
input logic rst_n_i,
|
|
||||||
ribp_if.slave ribp,
|
|
||||||
output logic irq_o
|
|
||||||
// verilog_format: on
|
|
||||||
);
|
|
||||||
|
|
||||||
// ribp
|
|
||||||
logic s_irq_d, s_irq_q;
|
|
||||||
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;
|
|
||||||
// register
|
|
||||||
logic s_tim_cfg_en;
|
|
||||||
logic [3:0] s_tim_cfg_d, s_tim_cfg_q;
|
|
||||||
logic s_tim_rld_en;
|
|
||||||
logic [31:0] s_tim_rld_d, s_tim_rld_q;
|
|
||||||
logic [31:0] s_tim_val_d, s_tim_val_q;
|
|
||||||
// enable (start) the counter/timer
|
|
||||||
// set s_bit_oneshot (1) mode or continuous (0) mode
|
|
||||||
// count up (1) or down (0)
|
|
||||||
// enable interrupt on timeout
|
|
||||||
logic s_bit_en, s_bit_oneshot;
|
|
||||||
logic s_bit_updown, s_bit_irq_en;
|
|
||||||
// irq
|
|
||||||
assign irq_o = s_irq_q;
|
|
||||||
|
|
||||||
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 s_bit_en = s_tim_cfg_q[0];
|
|
||||||
assign s_bit_oneshot = s_tim_cfg_q[1];
|
|
||||||
assign s_bit_updown = s_tim_cfg_q[2];
|
|
||||||
assign s_bit_irq_en = s_tim_cfg_q[3];
|
|
||||||
|
|
||||||
// register
|
|
||||||
assign s_tim_cfg_en = s_ribp_wr_hdshk && ribp.addr[7:0] == `RIBP_TIMER_CFG;
|
|
||||||
assign s_tim_cfg_d = ribp.wdata[3:0];
|
|
||||||
dffer #(4) u_tim_cfg_dffer (
|
|
||||||
clk_i,
|
|
||||||
rst_n_i,
|
|
||||||
s_tim_cfg_en && ribp.wstrb[0],
|
|
||||||
s_tim_cfg_d,
|
|
||||||
s_tim_cfg_q
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
assign s_tim_rld_en = s_ribp_wr_hdshk && ribp.addr[7:0] == `RIBP_TIMER_RLD;
|
|
||||||
always_comb begin
|
|
||||||
s_tim_rld_d = s_tim_rld_q;
|
|
||||||
if (ribp.wstrb[0]) s_tim_rld_d[7:0] = ribp.wdata[7:0];
|
|
||||||
if (ribp.wstrb[1]) s_tim_rld_d[15:8] = ribp.wdata[15:8];
|
|
||||||
if (ribp.wstrb[2]) s_tim_rld_d[23:16] = ribp.wdata[23:16];
|
|
||||||
if (ribp.wstrb[3]) s_tim_rld_d[31:24] = ribp.wdata[31:24];
|
|
||||||
end
|
|
||||||
dffer #(32) u_tim_rld_dffer (
|
|
||||||
clk_i,
|
|
||||||
rst_n_i,
|
|
||||||
s_tim_rld_en,
|
|
||||||
s_tim_rld_d,
|
|
||||||
s_tim_rld_q
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
always_comb begin
|
|
||||||
s_tim_val_d = s_tim_val_q;
|
|
||||||
s_irq_d = s_irq_q;
|
|
||||||
if (s_ribp_wr_hdshk && ribp.addr[7:0] == `RIBP_TIMER_VAL) begin
|
|
||||||
if (ribp.wstrb[0]) s_tim_val_d[7:0] = ribp.wdata[7:0];
|
|
||||||
if (ribp.wstrb[1]) s_tim_val_d[15:8] = ribp.wdata[15:8];
|
|
||||||
if (ribp.wstrb[2]) s_tim_val_d[23:16] = ribp.wdata[23:16];
|
|
||||||
if (ribp.wstrb[3]) s_tim_val_d[31:24] = ribp.wdata[31:24];
|
|
||||||
end else if (s_bit_en) begin
|
|
||||||
if (s_bit_updown) begin
|
|
||||||
if (s_tim_val_q == s_tim_rld_q) begin
|
|
||||||
if (~s_bit_oneshot) s_tim_val_d = '0;
|
|
||||||
s_irq_d = s_bit_irq_en;
|
|
||||||
end else begin
|
|
||||||
s_tim_val_d = s_tim_val_q + 1'b1;
|
|
||||||
s_irq_d = '0;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
if (s_tim_val_q == '0) begin
|
|
||||||
if (~s_bit_oneshot) s_tim_val_d = s_tim_rld_q;
|
|
||||||
s_irq_d = s_bit_irq_en;
|
|
||||||
end else begin
|
|
||||||
s_tim_val_d = s_tim_val_q - 1'b1;
|
|
||||||
s_irq_d = '0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
dffr #(32) u_tim_val_dffr (
|
|
||||||
clk_i,
|
|
||||||
rst_n_i,
|
|
||||||
s_tim_val_d,
|
|
||||||
s_tim_val_q
|
|
||||||
);
|
|
||||||
|
|
||||||
dffr #(1) u_irq_dffr (
|
|
||||||
clk_i,
|
|
||||||
rst_n_i,
|
|
||||||
s_irq_d,
|
|
||||||
s_irq_q
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
assign s_ribp_ready_d = ribp.valid && (~s_ribp_ready_q);
|
|
||||||
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_TIMER_CFG: s_ribp_rdata_d = {28'd0, s_tim_cfg_q};
|
|
||||||
`RIBP_TIMER_RLD: s_ribp_rdata_d = s_tim_rld_q;
|
|
||||||
`RIBP_TIMER_VAL: s_ribp_rdata_d = s_tim_val_q;
|
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
|
||||||
|
module timer_core #(
|
||||||
|
parameter int COUNTER_WIDTH = 32,
|
||||||
|
parameter int PRESCALE_WIDTH = 16
|
||||||
|
) (
|
||||||
|
// verilog_format: off
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_n_i,
|
||||||
|
input logic enable_i,
|
||||||
|
input logic [1:0] mode_i,
|
||||||
|
input logic direction_i,
|
||||||
|
input logic debug_freeze_enable_i,
|
||||||
|
input logic debug_halted_i,
|
||||||
|
input logic compare0_enable_i,
|
||||||
|
input logic compare1_enable_i,
|
||||||
|
input logic [PRESCALE_WIDTH-1:0] prescale_i,
|
||||||
|
input logic [COUNTER_WIDTH-1:0] load_i,
|
||||||
|
input logic [COUNTER_WIDTH-1:0] compare0_i,
|
||||||
|
input logic [COUNTER_WIDTH-1:0] compare1_i,
|
||||||
|
input logic start_i,
|
||||||
|
input logic stop_i,
|
||||||
|
input logic load_now_i,
|
||||||
|
output logic [COUNTER_WIDTH-1:0] value_o,
|
||||||
|
output logic debug_frozen_o,
|
||||||
|
output logic timeout_event_o,
|
||||||
|
output logic compare0_event_o,
|
||||||
|
output logic compare1_event_o,
|
||||||
|
output logic one_shot_done_o
|
||||||
|
// verilog_format: on
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam logic [1:0] MODE_FREE_RUNNING = 2'b00;
|
||||||
|
localparam logic [1:0] MODE_PERIODIC = 2'b01;
|
||||||
|
localparam logic [1:0] MODE_ONE_SHOT = 2'b10;
|
||||||
|
|
||||||
|
logic [PRESCALE_WIDTH-1:0] s_prescale_count;
|
||||||
|
logic s_prescale_load;
|
||||||
|
logic s_prescale_enable;
|
||||||
|
logic s_tick;
|
||||||
|
logic s_terminal;
|
||||||
|
logic s_prescale_overflow;
|
||||||
|
logic [COUNTER_WIDTH-1:0] s_value_d, s_value_q;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if (COUNTER_WIDTH < 1 || PRESCALE_WIDTH < 1) begin
|
||||||
|
$fatal(1, "timer_core: parameter widths must be positive");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign debug_frozen_o = enable_i && debug_freeze_enable_i && debug_halted_i;
|
||||||
|
assign value_o = s_value_q;
|
||||||
|
assign s_tick = enable_i && !debug_frozen_o && !start_i && !stop_i && !load_now_i &&
|
||||||
|
(s_prescale_count == '0) && !s_prescale_overflow;
|
||||||
|
assign s_prescale_load = start_i || (enable_i && load_now_i) || s_tick;
|
||||||
|
assign s_prescale_enable = enable_i && !debug_frozen_o && !start_i && !stop_i && !load_now_i &&
|
||||||
|
!s_tick;
|
||||||
|
|
||||||
|
rs_counter #(
|
||||||
|
.DATA_WIDTH(PRESCALE_WIDTH)
|
||||||
|
) u_prescale_counter (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.clr_i (1'b0),
|
||||||
|
.en_i (s_prescale_enable),
|
||||||
|
.load_i (s_prescale_load),
|
||||||
|
.down_i (1'b1),
|
||||||
|
.dat_i (prescale_i),
|
||||||
|
.dat_o (s_prescale_count),
|
||||||
|
.ovf_o (s_prescale_overflow)
|
||||||
|
);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
unique case (mode_i)
|
||||||
|
MODE_FREE_RUNNING: s_terminal = direction_i ? s_value_q == '0 : s_value_q == '1;
|
||||||
|
MODE_PERIODIC, MODE_ONE_SHOT: begin
|
||||||
|
s_terminal = direction_i ? s_value_q == '0 : s_value_q >= load_i;
|
||||||
|
end
|
||||||
|
default: s_terminal = 1'b0;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
timeout_event_o = 1'b0;
|
||||||
|
compare0_event_o = 1'b0;
|
||||||
|
compare1_event_o = 1'b0;
|
||||||
|
one_shot_done_o = 1'b0;
|
||||||
|
|
||||||
|
if (s_tick) begin
|
||||||
|
compare0_event_o = compare0_enable_i && (s_value_q == compare0_i);
|
||||||
|
compare1_event_o = compare1_enable_i && (s_value_q == compare1_i);
|
||||||
|
timeout_event_o = s_terminal;
|
||||||
|
one_shot_done_o = s_terminal && (mode_i == MODE_ONE_SHOT);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_value_d = s_value_q;
|
||||||
|
if (load_now_i) begin
|
||||||
|
s_value_d = direction_i ? load_i : '0;
|
||||||
|
end else if (s_tick) begin
|
||||||
|
unique case (mode_i)
|
||||||
|
MODE_FREE_RUNNING: s_value_d = direction_i ? s_value_q - 1'b1 : s_value_q + 1'b1;
|
||||||
|
MODE_PERIODIC: begin
|
||||||
|
if (s_terminal) s_value_d = direction_i ? load_i : '0;
|
||||||
|
else s_value_d = direction_i ? s_value_q - 1'b1 : s_value_q + 1'b1;
|
||||||
|
end
|
||||||
|
MODE_ONE_SHOT: begin
|
||||||
|
if (!s_terminal) s_value_d = direction_i ? s_value_q - 1'b1 : s_value_q + 1'b1;
|
||||||
|
end
|
||||||
|
default: s_value_d = s_value_q;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
dffr #(COUNTER_WIDTH) u_value_dffr (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.dat_i (s_value_d),
|
||||||
|
.dat_o (s_value_q)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
|
||||||
|
`ifndef RIBP_TIMER_DEFINE_SVH
|
||||||
|
`define RIBP_TIMER_DEFINE_SVH
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define RIBP_TIMER_CTRL 12'h000
|
||||||
|
`define RIBP_TIMER_LOAD 12'h004
|
||||||
|
`define RIBP_TIMER_VALUE 12'h008
|
||||||
|
`define RIBP_TIMER_BGLOAD 12'h00C
|
||||||
|
`define RIBP_TIMER_PRESCALE 12'h010
|
||||||
|
`define RIBP_TIMER_COMPARE0 12'h014
|
||||||
|
`define RIBP_TIMER_COMPARE1 12'h018
|
||||||
|
`define RIBP_TIMER_STATUS 12'h01C
|
||||||
|
`define RIBP_TIMER_INTR_STATE 12'h020
|
||||||
|
`define RIBP_TIMER_INTR_ENABLE 12'h024
|
||||||
|
`define RIBP_TIMER_INTR_STATUS 12'h028
|
||||||
|
`define RIBP_TIMER_INTR_TEST 12'h02C
|
||||||
|
`define RIBP_TIMER_IP_VERSION 12'h0F8
|
||||||
|
`define RIBP_TIMER_CAPABILITY 12'h0FC
|
||||||
|
|
||||||
|
`define TIMER_CTRL_ENABLE 0
|
||||||
|
`define TIMER_CTRL_MODE 1
|
||||||
|
`define TIMER_CTRL_DIRECTION 3
|
||||||
|
`define TIMER_CTRL_DEBUG_FREEZE 4
|
||||||
|
`define TIMER_CTRL_COMPARE0_ENABLE 5
|
||||||
|
`define TIMER_CTRL_COMPARE1_ENABLE 6
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
`endif
|
||||||
@@ -0,0 +1,305 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
|
||||||
|
`include "timer_define.svh"
|
||||||
|
|
||||||
|
module timer_reg (
|
||||||
|
// verilog_format: off
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_n_i,
|
||||||
|
ribp_if.slave ribp,
|
||||||
|
input logic [31:0] value_i,
|
||||||
|
input logic debug_frozen_i,
|
||||||
|
input logic timeout_event_i,
|
||||||
|
input logic compare0_event_i,
|
||||||
|
input logic compare1_event_i,
|
||||||
|
input logic one_shot_done_i,
|
||||||
|
output logic enable_o,
|
||||||
|
output logic [1:0] mode_o,
|
||||||
|
output logic direction_o,
|
||||||
|
output logic debug_freeze_enable_o,
|
||||||
|
output logic compare0_enable_o,
|
||||||
|
output logic compare1_enable_o,
|
||||||
|
output logic [15:0] prescale_o,
|
||||||
|
output logic [31:0] load_o,
|
||||||
|
output logic [31:0] compare0_o,
|
||||||
|
output logic [31:0] compare1_o,
|
||||||
|
output logic start_o,
|
||||||
|
output logic stop_o,
|
||||||
|
output logic load_now_o,
|
||||||
|
output logic irq_o
|
||||||
|
// verilog_format: on
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam logic [1:0] MODE_RESERVED = 2'b11;
|
||||||
|
localparam logic [31:0] IP_VERSION = 32'h0002_0000;
|
||||||
|
localparam logic [31:0] CAPABILITY = 32'h00F2_1020;
|
||||||
|
localparam logic [31:0] CTRL_ENABLE_MASK = 32'b1 << `TIMER_CTRL_ENABLE;
|
||||||
|
localparam logic [31:0] CTRL_MODE_MASK = 32'b11 << `TIMER_CTRL_MODE;
|
||||||
|
localparam logic [31:0] CTRL_DIRECTION_MASK = 32'b1 << `TIMER_CTRL_DIRECTION;
|
||||||
|
localparam logic [31:0] CTRL_DEBUG_FREEZE_MASK = 32'b1 << `TIMER_CTRL_DEBUG_FREEZE;
|
||||||
|
localparam logic [31:0] CTRL_COMPARE0_ENABLE_MASK = 32'b1 << `TIMER_CTRL_COMPARE0_ENABLE;
|
||||||
|
localparam logic [31:0] CTRL_COMPARE1_ENABLE_MASK = 32'b1 << `TIMER_CTRL_COMPARE1_ENABLE;
|
||||||
|
localparam logic [31:0] CTRL_WRITABLE_MASK =
|
||||||
|
CTRL_ENABLE_MASK | CTRL_MODE_MASK | CTRL_DIRECTION_MASK | CTRL_DEBUG_FREEZE_MASK |
|
||||||
|
CTRL_COMPARE0_ENABLE_MASK | CTRL_COMPARE1_ENABLE_MASK;
|
||||||
|
localparam logic [31:0] CTRL_ACTIVE_IMMUTABLE_MASK = CTRL_MODE_MASK | CTRL_DIRECTION_MASK;
|
||||||
|
logic s_req;
|
||||||
|
logic s_write;
|
||||||
|
logic s_req_accept;
|
||||||
|
logic [11:0] s_offset;
|
||||||
|
logic s_aligned;
|
||||||
|
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 [31:0] s_ctrl_write_value;
|
||||||
|
logic [31:0] s_load_write_value;
|
||||||
|
logic [31:0] s_bgload_write_value;
|
||||||
|
logic [15:0] s_prescale_write_value;
|
||||||
|
logic [31:0] s_compare0_write_value;
|
||||||
|
logic [31:0] s_compare1_write_value;
|
||||||
|
logic [ 2:0] s_intr_enable_write_value;
|
||||||
|
logic [ 2:0] s_intr_clear;
|
||||||
|
logic [ 2:0] s_intr_set;
|
||||||
|
logic [ 2:0] s_intr_state_d;
|
||||||
|
logic [ 2:0] s_intr_state_q;
|
||||||
|
logic [ 2:0] s_intr_enable_d;
|
||||||
|
logic [ 2:0] s_intr_enable_q;
|
||||||
|
logic [31:0] s_ctrl_d, s_ctrl_q;
|
||||||
|
logic [31:0] s_load_d, s_load_q;
|
||||||
|
logic [15:0] s_prescale_d, s_prescale_q;
|
||||||
|
logic [31:0] s_compare0_d, s_compare0_q;
|
||||||
|
logic [31:0] s_compare1_d, s_compare1_q;
|
||||||
|
|
||||||
|
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;
|
||||||
|
begin
|
||||||
|
merged = current;
|
||||||
|
for (int byte_index = 0; byte_index < 4; byte_index++) begin
|
||||||
|
if (strobe[byte_index]) begin
|
||||||
|
merged[byte_index*8+:8] = value[byte_index*8+:8];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return merged;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
assign s_req = ribp.valid && !s_ribp_ready_q;
|
||||||
|
assign s_write = |ribp.wstrb;
|
||||||
|
assign s_req_accept = s_req;
|
||||||
|
assign s_offset = ribp.addr[11:0];
|
||||||
|
assign s_aligned = ribp.addr[1:0] == 2'b00;
|
||||||
|
|
||||||
|
assign ribp.ready = s_ribp_ready_q;
|
||||||
|
assign ribp.rdata = s_ribp_rdata_q;
|
||||||
|
assign ribp.resp_err = s_ribp_resp_err_q;
|
||||||
|
|
||||||
|
assign s_ctrl_write_value = merge_wstrb(s_ctrl_q, ribp.wdata, ribp.wstrb) & CTRL_WRITABLE_MASK;
|
||||||
|
assign s_load_write_value = merge_wstrb(s_load_q, ribp.wdata, ribp.wstrb);
|
||||||
|
assign s_bgload_write_value = merge_wstrb(s_load_q, ribp.wdata, ribp.wstrb);
|
||||||
|
assign s_prescale_write_value = 16'(merge_wstrb({16'd0, s_prescale_q}, ribp.wdata, ribp.wstrb));
|
||||||
|
assign s_compare0_write_value = merge_wstrb(s_compare0_q, ribp.wdata, ribp.wstrb);
|
||||||
|
assign s_compare1_write_value = merge_wstrb(s_compare1_q, ribp.wdata, ribp.wstrb);
|
||||||
|
assign s_intr_enable_write_value = 3'(merge_wstrb(
|
||||||
|
{29'd0, s_intr_enable_q}, ribp.wdata, ribp.wstrb
|
||||||
|
));
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_access_error = !s_aligned;
|
||||||
|
s_ribp_rdata_d = '0;
|
||||||
|
if (s_aligned) begin
|
||||||
|
unique case (s_offset)
|
||||||
|
`RIBP_TIMER_CTRL: begin
|
||||||
|
s_ribp_rdata_d = s_ctrl_q;
|
||||||
|
if (s_write) begin
|
||||||
|
s_access_error =
|
||||||
|
(s_ctrl_write_value[2:1] == MODE_RESERVED) ||
|
||||||
|
(enable_o && (|((s_ctrl_write_value ^ s_ctrl_q) & CTRL_ACTIVE_IMMUTABLE_MASK)));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`RIBP_TIMER_LOAD: s_ribp_rdata_d = s_load_q;
|
||||||
|
`RIBP_TIMER_VALUE: begin
|
||||||
|
s_ribp_rdata_d = value_i;
|
||||||
|
s_access_error = s_write;
|
||||||
|
end
|
||||||
|
`RIBP_TIMER_BGLOAD: s_ribp_rdata_d = s_load_q;
|
||||||
|
`RIBP_TIMER_PRESCALE: begin
|
||||||
|
s_ribp_rdata_d = {16'd0, s_prescale_q};
|
||||||
|
s_access_error = s_write && enable_o;
|
||||||
|
end
|
||||||
|
`RIBP_TIMER_COMPARE0: s_ribp_rdata_d = s_compare0_q;
|
||||||
|
`RIBP_TIMER_COMPARE1: s_ribp_rdata_d = s_compare1_q;
|
||||||
|
`RIBP_TIMER_STATUS: begin
|
||||||
|
s_ribp_rdata_d = {30'd0, debug_frozen_i, enable_o};
|
||||||
|
s_access_error = s_write;
|
||||||
|
end
|
||||||
|
`RIBP_TIMER_INTR_STATE: s_ribp_rdata_d = {29'd0, s_intr_state_q};
|
||||||
|
`RIBP_TIMER_INTR_ENABLE: s_ribp_rdata_d = {29'd0, s_intr_enable_q};
|
||||||
|
`RIBP_TIMER_INTR_STATUS: begin
|
||||||
|
s_ribp_rdata_d = {29'd0, s_intr_state_q & s_intr_enable_q};
|
||||||
|
s_access_error = s_write;
|
||||||
|
end
|
||||||
|
`RIBP_TIMER_INTR_TEST: s_access_error = !s_write;
|
||||||
|
`RIBP_TIMER_IP_VERSION: begin
|
||||||
|
s_ribp_rdata_d = IP_VERSION;
|
||||||
|
s_access_error = s_write;
|
||||||
|
end
|
||||||
|
`RIBP_TIMER_CAPABILITY: begin
|
||||||
|
s_ribp_rdata_d = CAPABILITY;
|
||||||
|
s_access_error = s_write;
|
||||||
|
end
|
||||||
|
default: s_access_error = 1'b1;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign start_o = s_req_accept && s_write && !s_access_error &&
|
||||||
|
(s_offset == `RIBP_TIMER_CTRL) && !enable_o &&
|
||||||
|
s_ctrl_write_value[`TIMER_CTRL_ENABLE];
|
||||||
|
assign stop_o = s_req_accept && s_write && !s_access_error &&
|
||||||
|
(s_offset == `RIBP_TIMER_CTRL) && enable_o &&
|
||||||
|
!s_ctrl_write_value[`TIMER_CTRL_ENABLE];
|
||||||
|
assign load_now_o = s_req_accept && s_write && !s_access_error && (s_offset == `RIBP_TIMER_LOAD);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_ctrl_d = s_ctrl_q;
|
||||||
|
if (s_req_accept && s_write && !s_access_error && (s_offset == `RIBP_TIMER_CTRL)) begin
|
||||||
|
s_ctrl_d = s_ctrl_write_value;
|
||||||
|
end
|
||||||
|
if (one_shot_done_i) begin
|
||||||
|
s_ctrl_d[`TIMER_CTRL_ENABLE] = 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dffr #(32) u_ctrl_dffr (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.dat_i (s_ctrl_d),
|
||||||
|
.dat_o (s_ctrl_q)
|
||||||
|
);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_load_d = s_load_q;
|
||||||
|
if (s_req_accept && s_write && !s_access_error) begin
|
||||||
|
if (s_offset == `RIBP_TIMER_LOAD) s_load_d = s_load_write_value;
|
||||||
|
else if (s_offset == `RIBP_TIMER_BGLOAD) s_load_d = s_bgload_write_value;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dffr #(32) u_load_dffr (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.dat_i (s_load_d),
|
||||||
|
.dat_o (s_load_q)
|
||||||
|
);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_prescale_d = s_prescale_q;
|
||||||
|
if (s_req_accept && s_write && !s_access_error && (s_offset == `RIBP_TIMER_PRESCALE)) begin
|
||||||
|
s_prescale_d = s_prescale_write_value;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dffr #(16) u_prescale_dffr (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.dat_i (s_prescale_d),
|
||||||
|
.dat_o (s_prescale_q)
|
||||||
|
);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_compare0_d = s_compare0_q;
|
||||||
|
s_compare1_d = s_compare1_q;
|
||||||
|
if (s_req_accept && s_write && !s_access_error) begin
|
||||||
|
if (s_offset == `RIBP_TIMER_COMPARE0) s_compare0_d = s_compare0_write_value;
|
||||||
|
if (s_offset == `RIBP_TIMER_COMPARE1) s_compare1_d = s_compare1_write_value;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dffr #(32) u_compare0_dffr (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.dat_i (s_compare0_d),
|
||||||
|
.dat_o (s_compare0_q)
|
||||||
|
);
|
||||||
|
dffr #(32) u_compare1_dffr (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.dat_i (s_compare1_d),
|
||||||
|
.dat_o (s_compare1_q)
|
||||||
|
);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_intr_enable_d = s_intr_enable_q;
|
||||||
|
if (s_req_accept && s_write && !s_access_error && (s_offset == `RIBP_TIMER_INTR_ENABLE)) begin
|
||||||
|
s_intr_enable_d = s_intr_enable_write_value;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dffr #(3) u_intr_enable_dffr (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.dat_i (s_intr_enable_d),
|
||||||
|
.dat_o (s_intr_enable_q)
|
||||||
|
);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_intr_clear = '0;
|
||||||
|
s_intr_set = {compare1_event_i, compare0_event_i, timeout_event_i};
|
||||||
|
if (s_req_accept && s_write && !s_access_error) begin
|
||||||
|
if ((s_offset == `RIBP_TIMER_INTR_STATE) && ribp.wstrb[0]) begin
|
||||||
|
s_intr_clear = ribp.wdata[2:0];
|
||||||
|
end
|
||||||
|
if ((s_offset == `RIBP_TIMER_INTR_TEST) && ribp.wstrb[0]) begin
|
||||||
|
s_intr_set = s_intr_set | ribp.wdata[2:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
s_intr_state_d = (s_intr_state_q & ~s_intr_clear) | s_intr_set;
|
||||||
|
end
|
||||||
|
dffr #(3) 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)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign enable_o = s_ctrl_q[`TIMER_CTRL_ENABLE];
|
||||||
|
assign mode_o = s_ctrl_q[2:1];
|
||||||
|
assign direction_o = s_ctrl_q[`TIMER_CTRL_DIRECTION];
|
||||||
|
assign debug_freeze_enable_o = s_ctrl_q[`TIMER_CTRL_DEBUG_FREEZE];
|
||||||
|
assign compare0_enable_o = s_ctrl_q[`TIMER_CTRL_COMPARE0_ENABLE];
|
||||||
|
assign compare1_enable_o = s_ctrl_q[`TIMER_CTRL_COMPARE1_ENABLE];
|
||||||
|
assign prescale_o = s_prescale_q;
|
||||||
|
assign load_o = (s_req_accept && s_write && !s_access_error &&
|
||||||
|
((s_offset == `RIBP_TIMER_LOAD) ||
|
||||||
|
(s_offset == `RIBP_TIMER_BGLOAD))) ?
|
||||||
|
(s_offset == `RIBP_TIMER_LOAD ?
|
||||||
|
s_load_write_value : s_bgload_write_value) :
|
||||||
|
s_load_q;
|
||||||
|
assign compare0_o = s_compare0_q;
|
||||||
|
assign compare1_o = s_compare1_q;
|
||||||
|
assign irq_o = |(s_intr_state_q & s_intr_enable_q);
|
||||||
|
|
||||||
|
assign s_ribp_ready_d = s_req_accept;
|
||||||
|
assign s_ribp_resp_err_d = s_access_error;
|
||||||
|
|
||||||
|
dffr #(1) u_ribp_ready_dffr (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_ribp_ready_d,
|
||||||
|
s_ribp_ready_q
|
||||||
|
);
|
||||||
|
dffer #(1) u_ribp_resp_err_dffer (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_req_accept,
|
||||||
|
s_ribp_resp_err_d,
|
||||||
|
s_ribp_resp_err_q
|
||||||
|
);
|
||||||
|
dffer #(32) u_ribp_rdata_dffer (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_req_accept,
|
||||||
|
s_ribp_rdata_d,
|
||||||
|
s_ribp_rdata_q
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -39,7 +39,9 @@
|
|||||||
/ip/ribp/memory/sdram.sv
|
/ip/ribp/memory/sdram.sv
|
||||||
/ip/ribp/multimedia/dvp_core.sv
|
/ip/ribp/multimedia/dvp_core.sv
|
||||||
/ip/ribp/multimedia/dvp.sv
|
/ip/ribp/multimedia/dvp.sv
|
||||||
/ip/ribp/peripheral/timer.sv
|
/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/serial/uart.sv
|
||||||
/ip/ribp/peripheral/gpio.sv
|
/ip/ribp/peripheral/gpio.sv
|
||||||
/top/ahbl2ribp.sv
|
/top/ahbl2ribp.sv
|
||||||
|
|||||||
@@ -99,6 +99,16 @@ def source_files(target: str) -> list[Path]:
|
|||||||
SERIAL / "ribp_ws2812.sv",
|
SERIAL / "ribp_ws2812.sv",
|
||||||
SCRIPT_DIR / "ws2812_formal.sv",
|
SCRIPT_DIR / "ws2812_formal.sv",
|
||||||
]
|
]
|
||||||
|
if target == "timer":
|
||||||
|
return [
|
||||||
|
COMMON_RTL / "interface/ribp_if.sv",
|
||||||
|
COMMON_RTL / "utils/register.sv",
|
||||||
|
COMMON_RTL / "clkrst/counter.sv",
|
||||||
|
PERIPHERAL / "timer_core.sv",
|
||||||
|
PERIPHERAL / "timer_reg.sv",
|
||||||
|
PERIPHERAL / "ribp_timer.sv",
|
||||||
|
SCRIPT_DIR / "timer_formal.sv",
|
||||||
|
]
|
||||||
raise ValueError(f"unsupported formal target: {target}")
|
raise ValueError(f"unsupported formal target: {target}")
|
||||||
|
|
||||||
|
|
||||||
@@ -140,6 +150,7 @@ def parse_args() -> argparse.Namespace:
|
|||||||
"pll_rcu",
|
"pll_rcu",
|
||||||
"gpio_user",
|
"gpio_user",
|
||||||
"ws2812",
|
"ws2812",
|
||||||
|
"timer",
|
||||||
),
|
),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
|
||||||
|
module timer_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 debug_halted,
|
||||||
|
output logic active,
|
||||||
|
output logic debug_frozen,
|
||||||
|
output logic [31:0] value,
|
||||||
|
output logic start,
|
||||||
|
output logic stop,
|
||||||
|
output logic load_now,
|
||||||
|
output logic timeout_event,
|
||||||
|
output logic compare0_event,
|
||||||
|
output logic compare1_event,
|
||||||
|
output logic one_shot_done,
|
||||||
|
output logic [ 2:0] intr_state,
|
||||||
|
output logic [ 2:0] intr_enable,
|
||||||
|
output logic irq
|
||||||
|
// verilog_format: on
|
||||||
|
);
|
||||||
|
|
||||||
|
ribp_if rib ();
|
||||||
|
|
||||||
|
(* 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_debug_halted;
|
||||||
|
|
||||||
|
assign rib.valid = f_rib_valid;
|
||||||
|
assign rib.addr = f_rib_addr;
|
||||||
|
assign rib.wdata = f_rib_wdata;
|
||||||
|
assign rib.wstrb = f_rib_wstrb;
|
||||||
|
|
||||||
|
assign rib_valid = rib.valid;
|
||||||
|
assign rib_addr = rib.addr;
|
||||||
|
assign rib_wdata = rib.wdata;
|
||||||
|
assign rib_wstrb = rib.wstrb;
|
||||||
|
assign rib_ready = rib.ready;
|
||||||
|
assign rib_resp_err = rib.resp_err;
|
||||||
|
assign debug_halted = f_debug_halted;
|
||||||
|
assign active = u_dut.s_enable;
|
||||||
|
assign debug_frozen = u_dut.s_debug_frozen;
|
||||||
|
assign value = u_dut.s_value;
|
||||||
|
assign start = u_dut.s_start;
|
||||||
|
assign stop = u_dut.s_stop;
|
||||||
|
assign load_now = u_dut.s_load_now;
|
||||||
|
assign timeout_event = u_dut.s_timeout_event;
|
||||||
|
assign compare0_event = u_dut.s_compare0_event;
|
||||||
|
assign compare1_event = u_dut.s_compare1_event;
|
||||||
|
assign one_shot_done = u_dut.s_one_shot_done;
|
||||||
|
assign intr_state = u_dut.u_timer_reg.s_intr_state_q;
|
||||||
|
assign intr_enable = u_dut.u_timer_reg.s_intr_enable_q;
|
||||||
|
|
||||||
|
ribp_timer u_dut (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
.debug_halted_i(f_debug_halted),
|
||||||
|
.ribp (rib),
|
||||||
|
.irq_o (irq)
|
||||||
|
);
|
||||||
|
|
||||||
|
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,73 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
|
||||||
|
module timer_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 debug_halted;
|
||||||
|
wire active;
|
||||||
|
wire debug_frozen;
|
||||||
|
wire [31:0] value;
|
||||||
|
wire start;
|
||||||
|
wire stop;
|
||||||
|
wire load_now;
|
||||||
|
wire timeout_event;
|
||||||
|
wire compare0_event;
|
||||||
|
wire compare1_event;
|
||||||
|
wire one_shot_done;
|
||||||
|
wire [ 2:0] intr_state;
|
||||||
|
wire [ 2:0] intr_enable;
|
||||||
|
wire irq;
|
||||||
|
|
||||||
|
timer_formal_design u_design (.*);
|
||||||
|
|
||||||
|
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 (irq == |(intr_state & intr_enable));
|
||||||
|
if (f_past_valid && $past(rst_n_i && rib_valid && !rib_ready)) begin
|
||||||
|
assert (rib_ready);
|
||||||
|
end
|
||||||
|
if (f_past_valid && $past(rst_n_i && !active && !load_now)) begin
|
||||||
|
assert (value == $past(value));
|
||||||
|
end
|
||||||
|
if (f_past_valid && $past(rst_n_i && debug_frozen && !load_now && !stop)) begin
|
||||||
|
assert (value == $past(value));
|
||||||
|
end
|
||||||
|
if (f_past_valid && $past(rst_n_i && timeout_event)) begin
|
||||||
|
assert (intr_state[0]);
|
||||||
|
end
|
||||||
|
if (f_past_valid && $past(rst_n_i && compare0_event)) begin
|
||||||
|
assert (intr_state[1]);
|
||||||
|
end
|
||||||
|
if (f_past_valid && $past(rst_n_i && compare1_event)) begin
|
||||||
|
assert (intr_state[2]);
|
||||||
|
end
|
||||||
|
if (f_past_valid && $past(rst_n_i && one_shot_done)) begin
|
||||||
|
assert (!active);
|
||||||
|
end
|
||||||
|
|
||||||
|
cover (start);
|
||||||
|
cover (debug_frozen && debug_halted);
|
||||||
|
cover (timeout_event);
|
||||||
|
cover (compare0_event && compare1_event);
|
||||||
|
cover (irq);
|
||||||
|
cover (rib_ready && rib_resp_err);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
+11
-2
@@ -8,7 +8,7 @@ FORMAL_DEPTH ?= 20
|
|||||||
FORMAL_WS2812_DEPTH ?= 120
|
FORMAL_WS2812_DEPTH ?= 120
|
||||||
FORMAL_TIMEOUT ?= 60
|
FORMAL_TIMEOUT ?= 60
|
||||||
FORMAL_WS2812_TIMEOUT ?= 120
|
FORMAL_WS2812_TIMEOUT ?= 120
|
||||||
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio_user ws2812
|
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio_user ws2812 timer
|
||||||
FORMAL_FILELIST_GENERATOR := $(RTL_PATH)/formal/generate_formal_filelist.py
|
FORMAL_FILELIST_GENERATOR := $(RTL_PATH)/formal/generate_formal_filelist.py
|
||||||
FORMAL_SBY_GENERATOR := $(RTL_PATH)/formal/generate_sby_config.py
|
FORMAL_SBY_GENERATOR := $(RTL_PATH)/formal/generate_sby_config.py
|
||||||
FORMAL_RESULT_GENERATOR := $(RTL_PATH)/formal/formal_results.py
|
FORMAL_RESULT_GENERATOR := $(RTL_PATH)/formal/formal_results.py
|
||||||
@@ -26,6 +26,8 @@ FORMAL_SOURCE_FILES := $(RTL_PATH)/formal/bus_formal.sv \
|
|||||||
$(RTL_PATH)/formal/gpio_user_formal_props.sv \
|
$(RTL_PATH)/formal/gpio_user_formal_props.sv \
|
||||||
$(RTL_PATH)/formal/ws2812_formal.sv \
|
$(RTL_PATH)/formal/ws2812_formal.sv \
|
||||||
$(RTL_PATH)/formal/ws2812_formal_props.sv \
|
$(RTL_PATH)/formal/ws2812_formal_props.sv \
|
||||||
|
$(RTL_PATH)/formal/timer_formal.sv \
|
||||||
|
$(RTL_PATH)/formal/timer_formal_props.sv \
|
||||||
$(RTL_PATH)/top/bus.sv \
|
$(RTL_PATH)/top/bus.sv \
|
||||||
$(RTL_PATH)/top/rib_error_slave.sv \
|
$(RTL_PATH)/top/rib_error_slave.sv \
|
||||||
$(RTL_PATH)/top/rib_if.sv \
|
$(RTL_PATH)/top/rib_if.sv \
|
||||||
@@ -41,6 +43,11 @@ 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_reg.sv \
|
||||||
$(ROOT_PATH)/rtl/ip/ribp/serial/ws2812_core.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/ribp_ws2812.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 \
|
||||||
|
$(ROOT_PATH)/rtl/ip/ribp/peripheral/ribp_timer.sv \
|
||||||
|
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/clkrst/counter.sv \
|
||||||
$(RTL_PATH)/top/rcu.sv \
|
$(RTL_PATH)/top/rcu.sv \
|
||||||
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/interface/ribp_if.sv \
|
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/interface/ribp_if.sv \
|
||||||
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/interface/apb4_pure_if.sv \
|
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/interface/apb4_pure_if.sv \
|
||||||
@@ -135,10 +142,12 @@ formal-gpio-user: $(FORMAL_DIR)/gpio_user/.stamp | manifest
|
|||||||
|
|
||||||
formal-ws2812: $(FORMAL_DIR)/ws2812/.stamp | manifest
|
formal-ws2812: $(FORMAL_DIR)/ws2812/.stamp | manifest
|
||||||
|
|
||||||
|
formal-timer: $(FORMAL_DIR)/timer/.stamp | manifest
|
||||||
|
|
||||||
formal-doctor:
|
formal-doctor:
|
||||||
$(MAKE) FORMAL=YES SIMU=IVERILOG SYNTH=YOSYS STA=NONE doctor
|
$(MAKE) FORMAL=YES SIMU=IVERILOG SYNTH=YOSYS STA=NONE doctor
|
||||||
|
|
||||||
formal-clean:
|
formal-clean:
|
||||||
python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(FORMAL_DIR)
|
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-user formal-ws2812 formal-doctor formal-clean
|
.PHONY: formal formal-bus formal-rib-adapter formal-rib2apb formal-sysctrl formal-pll-rcu formal-gpio-user formal-ws2812 formal-timer formal-doctor formal-clean
|
||||||
@@ -67,6 +67,7 @@ CRT_SRCS := $(ROOT_PATH)/crt/arch/riscv/startup.S \
|
|||||||
$(ROOT_PATH)/crt/src/hal/clock.c \
|
$(ROOT_PATH)/crt/src/hal/clock.c \
|
||||||
$(ROOT_PATH)/crt/src/hal/uart.c \
|
$(ROOT_PATH)/crt/src/hal/uart.c \
|
||||||
$(ROOT_PATH)/crt/src/hal/gpio.c \
|
$(ROOT_PATH)/crt/src/hal/gpio.c \
|
||||||
|
$(ROOT_PATH)/crt/src/hal/timer_math.c \
|
||||||
$(ROOT_PATH)/crt/src/hal/timer.c \
|
$(ROOT_PATH)/crt/src/hal/timer.c \
|
||||||
$(ROOT_PATH)/crt/src/hal/pwm.c \
|
$(ROOT_PATH)/crt/src/hal/pwm.c \
|
||||||
$(ROOT_PATH)/crt/src/hal/rtc.c \
|
$(ROOT_PATH)/crt/src/hal/rtc.c \
|
||||||
|
|||||||
@@ -18,20 +18,22 @@ module core_wrapper (
|
|||||||
input logic jtag_tdi_i,
|
input logic jtag_tdi_i,
|
||||||
input logic jtag_trst_n_i,
|
input logic jtag_trst_n_i,
|
||||||
output logic jtag_tdo_o,
|
output logic jtag_tdo_o,
|
||||||
|
output logic debug_halted_o,
|
||||||
ribp_if.master ribp
|
ribp_if.master ribp
|
||||||
// verilog_format: on
|
// verilog_format: on
|
||||||
);
|
);
|
||||||
|
|
||||||
mgmt_core_wrapper u_mgmt_core_wrapper (
|
mgmt_core_wrapper u_mgmt_core_wrapper (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_n_i (rst_n_i),
|
.rst_n_i (rst_n_i),
|
||||||
.irq_i (irq_i),
|
.irq_i (irq_i),
|
||||||
.jtag_tck_i (jtag_tck_i),
|
.jtag_tck_i (jtag_tck_i),
|
||||||
.jtag_tms_i (jtag_tms_i),
|
.jtag_tms_i (jtag_tms_i),
|
||||||
.jtag_tdi_i (jtag_tdi_i),
|
.jtag_tdi_i (jtag_tdi_i),
|
||||||
.jtag_trst_n_i(jtag_trst_n_i),
|
.jtag_trst_n_i (jtag_trst_n_i),
|
||||||
.jtag_tdo_o (jtag_tdo_o),
|
.jtag_tdo_o (jtag_tdo_o),
|
||||||
.ribp (ribp)
|
.debug_halted_o(debug_halted_o),
|
||||||
|
.ribp (ribp)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
@@ -18,6 +18,7 @@ module ip_ribp_wrapper (
|
|||||||
input logic rst_n_i,
|
input logic rst_n_i,
|
||||||
input logic clk_aud_i,
|
input logic clk_aud_i,
|
||||||
input logic rst_aud_n_i,
|
input logic rst_aud_n_i,
|
||||||
|
input logic debug_halted_i,
|
||||||
rib_if.slave rib,
|
rib_if.slave rib,
|
||||||
gpio_if.dut gpio,
|
gpio_if.dut gpio,
|
||||||
user_gpio_if.padctrl user_gpio,
|
user_gpio_if.padctrl user_gpio,
|
||||||
@@ -98,17 +99,19 @@ module ip_ribp_wrapper (
|
|||||||
);
|
);
|
||||||
|
|
||||||
ribp_timer u_rib_timer0 (
|
ribp_timer u_rib_timer0 (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_n_i(rst_n_i),
|
.rst_n_i (rst_n_i),
|
||||||
.ribp (u_tim0_ribp_if),
|
.debug_halted_i(debug_halted_i),
|
||||||
.irq_o (s_tim0_irq)
|
.ribp (u_tim0_ribp_if),
|
||||||
|
.irq_o (s_tim0_irq)
|
||||||
);
|
);
|
||||||
|
|
||||||
ribp_timer u_rib_timer1 (
|
ribp_timer u_rib_timer1 (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_n_i(rst_n_i),
|
.rst_n_i (rst_n_i),
|
||||||
.ribp (u_tim1_ribp_if),
|
.debug_halted_i(debug_halted_i),
|
||||||
.irq_o (s_tim1_irq)
|
.ribp (u_tim1_ribp_if),
|
||||||
|
.irq_o (s_tim1_irq)
|
||||||
);
|
);
|
||||||
|
|
||||||
ribp_psram u_rib_psram (
|
ribp_psram u_rib_psram (
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ module mgmt_core_wrapper (
|
|||||||
input logic jtag_tdi_i,
|
input logic jtag_tdi_i,
|
||||||
input logic jtag_trst_n_i,
|
input logic jtag_trst_n_i,
|
||||||
output logic jtag_tdo_o,
|
output logic jtag_tdo_o,
|
||||||
ribp_if.master ribp
|
output logic debug_halted_o,
|
||||||
|
ribp_if.master ribp
|
||||||
// verilog_format: on
|
// verilog_format: on
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -48,6 +49,8 @@ module mgmt_core_wrapper (
|
|||||||
logic s_dbg_sbus_err;
|
logic s_dbg_sbus_err;
|
||||||
logic [31:0] s_dbg_sbus_wdata;
|
logic [31:0] s_dbg_sbus_wdata;
|
||||||
logic [31:0] s_dbg_sbus_rdata;
|
logic [31:0] s_dbg_sbus_rdata;
|
||||||
|
|
||||||
|
assign debug_halted_o = s_dbg_halted;
|
||||||
// verilog_format: off
|
// verilog_format: off
|
||||||
ahbl_if u_ahbl_if (clk_i, s_core_rst_n);
|
ahbl_if u_ahbl_if (clk_i, s_core_rst_n);
|
||||||
ahbl2ribp u_ahbl2ribp (u_ahbl_if, ribp, s_ahbl_idle);
|
ahbl2ribp u_ahbl2ribp (u_ahbl_if, ribp, s_ahbl_idle);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ module retrosoc (
|
|||||||
// verilog_format: on
|
// verilog_format: on
|
||||||
|
|
||||||
logic s_tmr_capch;
|
logic s_tmr_capch;
|
||||||
|
logic s_mgmt_debug_halted;
|
||||||
logic [`SOC_IRQ_VECTOR_WIDTH-1:0] s_irq;
|
logic [`SOC_IRQ_VECTOR_WIDTH-1:0] s_irq;
|
||||||
logic [ `SOC_IRQ_RIBP_WIDTH-1:0] s_ribp_irq;
|
logic [ `SOC_IRQ_RIBP_WIDTH-1:0] s_ribp_irq;
|
||||||
logic [ `SOC_IRQ_APB_WIDTH-1:0] s_apb_irq;
|
logic [ `SOC_IRQ_APB_WIDTH-1:0] s_apb_irq;
|
||||||
@@ -111,15 +112,16 @@ module retrosoc (
|
|||||||
`include "soc_gpio_alt_bindings.svh"
|
`include "soc_gpio_alt_bindings.svh"
|
||||||
|
|
||||||
core_wrapper u_core_wrapper (
|
core_wrapper u_core_wrapper (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_n_i (rst_n_i),
|
.rst_n_i (rst_n_i),
|
||||||
`include "soc_mgmt_core_wrapper_fabric.svh"
|
`include "soc_mgmt_core_wrapper_fabric.svh"
|
||||||
.irq_i (s_irq),
|
.irq_i (s_irq),
|
||||||
.jtag_tck_i (jtag_tck_i),
|
.jtag_tck_i (jtag_tck_i),
|
||||||
.jtag_tms_i (jtag_tms_i),
|
.jtag_tms_i (jtag_tms_i),
|
||||||
.jtag_tdi_i (jtag_tdi_i),
|
.jtag_tdi_i (jtag_tdi_i),
|
||||||
.jtag_trst_n_i(jtag_trst_n_i),
|
.jtag_trst_n_i (jtag_trst_n_i),
|
||||||
.jtag_tdo_o (jtag_tdo_o)
|
.jtag_tdo_o (jtag_tdo_o),
|
||||||
|
.debug_halted_o(s_mgmt_debug_halted)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign s_user_irq = u_sysctrl_if.user_bus_enable_o ? s_irq : '0;
|
assign s_user_irq = u_sysctrl_if.user_bus_enable_o ? s_irq : '0;
|
||||||
@@ -165,6 +167,7 @@ core_wrapper u_core_wrapper (
|
|||||||
.rst_n_i (rst_n_i),
|
.rst_n_i (rst_n_i),
|
||||||
.clk_aud_i (clk_aud_i),
|
.clk_aud_i (clk_aud_i),
|
||||||
.rst_aud_n_i (rst_aud_n_i),
|
.rst_aud_n_i (rst_aud_n_i),
|
||||||
|
.debug_halted_i (s_mgmt_debug_halted),
|
||||||
`include "ip_ribp_wrapper_fabric.svh"
|
`include "ip_ribp_wrapper_fabric.svh"
|
||||||
.gpio (u_gpio_if),
|
.gpio (u_gpio_if),
|
||||||
.user_gpio (u_user_gpio_if),
|
.user_gpio (u_user_gpio_if),
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ TEST_SOURCES = (
|
|||||||
"crt/src/lib/stdlib.c",
|
"crt/src/lib/stdlib.c",
|
||||||
"crt/src/lib/string.c",
|
"crt/src/lib/string.c",
|
||||||
"crt/src/hal/ws2812_math.c",
|
"crt/src/hal/ws2812_math.c",
|
||||||
|
"crt/src/hal/timer_math.c",
|
||||||
"app/media/src/video_player.c",
|
"app/media/src/video_player.c",
|
||||||
"app/media/src/wav_audio.c",
|
"app/media/src/wav_audio.c",
|
||||||
"tests/c/test_runtime.c",
|
"tests/c/test_runtime.c",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <retrosoc/core/wait.h>
|
#include <retrosoc/core/wait.h>
|
||||||
#include <retrosoc/hal/lcd.h>
|
#include <retrosoc/hal/lcd.h>
|
||||||
#include <retrosoc/hal/spisd.h>
|
#include <retrosoc/hal/spisd.h>
|
||||||
|
#include <retrosoc/hal/timer.h>
|
||||||
#include <retrosoc/hal/ws2812.h>
|
#include <retrosoc/hal/ws2812.h>
|
||||||
#include <retrosoc/lib/printf.h>
|
#include <retrosoc/lib/printf.h>
|
||||||
#include <retrosoc/lib/stdlib.h>
|
#include <retrosoc/lib/stdlib.h>
|
||||||
@@ -186,6 +187,27 @@ static int test_ws2812_helpers(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_timer_helpers(void)
|
||||||
|
{
|
||||||
|
rs_timer_period_t period;
|
||||||
|
|
||||||
|
if ((rs_timer_period_from_ms(72000000U, 1U, &period) != RS_OK) ||
|
||||||
|
(period.prescale != 0U) || (period.load != 71999U)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((rs_timer_period_from_ms(72000000U, 1000U, &period) != RS_OK) ||
|
||||||
|
(period.prescale != 0U) || (period.load != 71999999U)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if ((rs_timer_period_from_ms(0U, 1U, &period) != RS_EINVAL) ||
|
||||||
|
(rs_timer_period_from_ms(72000000U, 0U, &period) != RS_EINVAL) ||
|
||||||
|
(rs_timer_period_from_ms(72000000U, 1U, NULL) != RS_EINVAL) ||
|
||||||
|
(rs_timer_period_from_ms(UINT32_MAX, UINT32_MAX, &period) != RS_EINVAL)) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int test_wav_parser(void)
|
static int test_wav_parser(void)
|
||||||
{
|
{
|
||||||
static const uint8_t wav[] = {
|
static const uint8_t wav[] = {
|
||||||
@@ -235,6 +257,7 @@ int main(void)
|
|||||||
test_compiler_helpers(),
|
test_compiler_helpers(),
|
||||||
test_wait_helper(),
|
test_wait_helper(),
|
||||||
test_ws2812_helpers(),
|
test_ws2812_helpers(),
|
||||||
|
test_timer_helpers(),
|
||||||
test_wav_parser(),
|
test_wav_parser(),
|
||||||
test_video_parser(),
|
test_video_parser(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
module timer_tb;
|
||||||
|
localparam logic [31:0] CTRL_ENABLE = 32'h0000_0001;
|
||||||
|
localparam logic [31:0] CTRL_PERIODIC = 32'h0000_0002;
|
||||||
|
localparam logic [31:0] CTRL_ONE_SHOT = 32'h0000_0004;
|
||||||
|
localparam logic [31:0] CTRL_DIRECTION_DOWN = 32'h0000_0008;
|
||||||
|
localparam logic [31:0] CTRL_DEBUG_FREEZE = 32'h0000_0010;
|
||||||
|
localparam logic [31:0] CTRL_COMPARE_ENABLE = 32'h0000_0060;
|
||||||
|
|
||||||
|
logic clk_i = 1'b0;
|
||||||
|
logic rst_n_i = 1'b0;
|
||||||
|
logic debug_halted_i = 1'b0;
|
||||||
|
logic irq_o;
|
||||||
|
ribp_if ribp ();
|
||||||
|
|
||||||
|
always #5 clk_i = ~clk_i;
|
||||||
|
|
||||||
|
ribp_timer u_dut (
|
||||||
|
.clk_i,
|
||||||
|
.rst_n_i,
|
||||||
|
.debug_halted_i,
|
||||||
|
.ribp,
|
||||||
|
.irq_o
|
||||||
|
);
|
||||||
|
|
||||||
|
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.valid = 1'b1;
|
||||||
|
ribp.addr = address;
|
||||||
|
ribp.wdata = data;
|
||||||
|
ribp.wstrb = strobe;
|
||||||
|
do @(negedge clk_i); while (!ribp.ready);
|
||||||
|
if (ribp.resp_err !== expected_error) begin
|
||||||
|
$fatal(1, "write %h error=%b expected=%b", address, ribp.resp_err, expected_error);
|
||||||
|
end
|
||||||
|
ribp.valid = 1'b0;
|
||||||
|
ribp.wstrb = '0;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic ribp_read(input logic [31:0] address, output logic [31:0] data,
|
||||||
|
input logic expected_error);
|
||||||
|
begin
|
||||||
|
@(negedge clk_i);
|
||||||
|
ribp.valid = 1'b1;
|
||||||
|
ribp.addr = address;
|
||||||
|
ribp.wdata = '0;
|
||||||
|
ribp.wstrb = '0;
|
||||||
|
do @(negedge clk_i); while (!ribp.ready);
|
||||||
|
data = ribp.rdata;
|
||||||
|
if (ribp.resp_err !== expected_error) begin
|
||||||
|
$fatal(1, "read %h error=%b expected=%b", address, ribp.resp_err, expected_error);
|
||||||
|
end
|
||||||
|
ribp.valid = 1'b0;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic wait_inactive;
|
||||||
|
logic [31:0] status;
|
||||||
|
int cycles;
|
||||||
|
begin
|
||||||
|
status = '1;
|
||||||
|
cycles = 0;
|
||||||
|
while ((status[0] != 1'b0) && (cycles < 64)) begin
|
||||||
|
ribp_read(32'h0000_001C, status, 1'b0);
|
||||||
|
cycles++;
|
||||||
|
end
|
||||||
|
if (status[0] != 1'b0) $fatal(1, "timer did not enter inactive state");
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
logic [31:0] value;
|
||||||
|
logic [31:0] frozen_value;
|
||||||
|
logic [31:0] status;
|
||||||
|
logic [31:0] intr_state;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
ribp.valid = 1'b0;
|
||||||
|
ribp.addr = '0;
|
||||||
|
ribp.wdata = '0;
|
||||||
|
ribp.wstrb = '0;
|
||||||
|
|
||||||
|
repeat (4) @(posedge clk_i);
|
||||||
|
rst_n_i = 1'b1;
|
||||||
|
|
||||||
|
ribp_read(32'h0000_00F8, value, 1'b0);
|
||||||
|
if (value != 32'h0002_0000) $fatal(1, "unexpected timer version %h", value);
|
||||||
|
ribp_read(32'h0000_00FC, value, 1'b0);
|
||||||
|
if (value != 32'h00F2_1020) $fatal(1, "unexpected timer capability %h", value);
|
||||||
|
ribp_read(32'h0000_0100, value, 1'b1);
|
||||||
|
if (value != 32'd0) $fatal(1, "invalid read did not return zero");
|
||||||
|
ribp_read(32'h0000_0002, value, 1'b1);
|
||||||
|
ribp_write(32'h0000_0008, 32'h1234_5678, 4'hF, 1'b1);
|
||||||
|
ribp_read(32'h0000_002C, value, 1'b1);
|
||||||
|
ribp_write(32'h0000_0000, 32'h0000_0006, 4'hF, 1'b1);
|
||||||
|
|
||||||
|
// Free-running mode wraps naturally and stops without changing its value.
|
||||||
|
ribp_write(32'h0000_0000, CTRL_ENABLE, 4'hF, 1'b0);
|
||||||
|
repeat (6) @(posedge clk_i);
|
||||||
|
ribp_read(32'h0000_0008, value, 1'b0);
|
||||||
|
if (value == 32'd0) $fatal(1, "free-running timer did not advance");
|
||||||
|
ribp_write(32'h0000_0000, 32'd0, 4'hF, 1'b0);
|
||||||
|
|
||||||
|
// Up-counting periodic mode with both compare channels.
|
||||||
|
ribp_write(32'h0000_0010, 32'd1, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0014, 32'd1, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0018, 32'd2, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0004, 32'd3, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0024, 32'h0000_0007, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0000, CTRL_ENABLE | CTRL_PERIODIC | CTRL_COMPARE_ENABLE, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0010, 32'd0, 4'hF, 1'b1);
|
||||||
|
repeat (12) @(posedge clk_i);
|
||||||
|
ribp_read(32'h0000_0020, intr_state, 1'b0);
|
||||||
|
if (intr_state[2:0] != 3'b111 || !irq_o) begin
|
||||||
|
$fatal(1, "periodic compare/timeout state invalid: %h irq=%b", intr_state, irq_o);
|
||||||
|
end
|
||||||
|
ribp_write(32'h0000_0020, 32'h0000_0007, 4'h1, 1'b0);
|
||||||
|
ribp_write(32'h0000_0000, CTRL_PERIODIC | CTRL_COMPARE_ENABLE, 4'hF, 1'b0);
|
||||||
|
|
||||||
|
// Down-counting one-shot stops at zero and leaves a sticky timeout.
|
||||||
|
ribp_write(32'h0000_0004, 32'd2, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0020, 32'h0000_0007, 4'h1, 1'b0);
|
||||||
|
ribp_write(32'h0000_0000, CTRL_ENABLE | CTRL_ONE_SHOT | CTRL_DIRECTION_DOWN, 4'hF, 1'b0);
|
||||||
|
wait_inactive();
|
||||||
|
ribp_read(32'h0000_0008, value, 1'b0);
|
||||||
|
ribp_read(32'h0000_0020, intr_state, 1'b0);
|
||||||
|
if (value != 32'd0 || !intr_state[0]) begin
|
||||||
|
$fatal(1, "one-shot completion invalid value=%h state=%h", value, intr_state);
|
||||||
|
end
|
||||||
|
|
||||||
|
// Background load updates the next down-counting period without an immediate reload.
|
||||||
|
ribp_write(32'h0000_0020, 32'h0000_0007, 4'h1, 1'b0);
|
||||||
|
ribp_write(32'h0000_0004, 32'd5, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0010, 32'd3, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0000, CTRL_ENABLE | CTRL_PERIODIC | CTRL_DIRECTION_DOWN, 4'hF, 1'b0);
|
||||||
|
ribp_read(32'h0000_0008, value, 1'b0);
|
||||||
|
ribp_write(32'h0000_000C, 32'd1, 4'hF, 1'b0);
|
||||||
|
ribp_read(32'h0000_0008, frozen_value, 1'b0);
|
||||||
|
if (frozen_value == 32'd1) $fatal(1, "BGLOAD changed the live counter immediately");
|
||||||
|
repeat (32) @(posedge clk_i);
|
||||||
|
ribp_read(32'h0000_0008, value, 1'b0);
|
||||||
|
if (value > 32'd1) $fatal(1, "BGLOAD was not used by the next period: %h", value);
|
||||||
|
ribp_write(32'h0000_0000, CTRL_PERIODIC | CTRL_DIRECTION_DOWN, 4'hF, 1'b0);
|
||||||
|
|
||||||
|
// Debug freeze stops both prescaler and counter while keeping RIBP readable.
|
||||||
|
ribp_write(32'h0000_0004, 32'd20, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0010, 32'd0, 4'hF, 1'b0);
|
||||||
|
ribp_write(32'h0000_0000, CTRL_ENABLE | CTRL_PERIODIC | CTRL_DEBUG_FREEZE, 4'hF, 1'b0);
|
||||||
|
debug_halted_i = 1'b1;
|
||||||
|
repeat (2) @(posedge clk_i);
|
||||||
|
ribp_read(32'h0000_0008, frozen_value, 1'b0);
|
||||||
|
repeat (8) @(posedge clk_i);
|
||||||
|
ribp_read(32'h0000_0008, value, 1'b0);
|
||||||
|
ribp_read(32'h0000_001C, status, 1'b0);
|
||||||
|
if (value != frozen_value || status[1:0] != 2'b11) begin
|
||||||
|
$fatal(1, "debug freeze invalid before=%h after=%h status=%h", frozen_value, value, status);
|
||||||
|
end
|
||||||
|
debug_halted_i = 1'b0;
|
||||||
|
repeat (4) @(posedge clk_i);
|
||||||
|
ribp_read(32'h0000_0008, value, 1'b0);
|
||||||
|
if (value == frozen_value) $fatal(1, "timer did not resume after debug halt");
|
||||||
|
|
||||||
|
// Software interrupt test and W1C clear.
|
||||||
|
ribp_write(32'h0000_002C, 32'h0000_0006, 4'h1, 1'b0);
|
||||||
|
ribp_read(32'h0000_0020, intr_state, 1'b0);
|
||||||
|
if ((intr_state[2:1] != 2'b11) || !irq_o) $fatal(1, "interrupt test failed");
|
||||||
|
ribp_write(32'h0000_0020, 32'h0000_0007, 4'h1, 1'b0);
|
||||||
|
|
||||||
|
$display("RIBP Timer V2 register, mode, interrupt, and error test passed");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
"""RIBP Timer V2 RTL regression tests."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
PERIPHERAL = ROOT / "rtl/ip/ribp/peripheral"
|
||||||
|
def test_timer_modes_interrupts_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"
|
||||||
|
source_list = tmp_path / "timer.fl"
|
||||||
|
source_list.write_text(
|
||||||
|
"\n".join(
|
||||||
|
[
|
||||||
|
"+define+SV_ASSRT_DISABLE",
|
||||||
|
f"+incdir+{common}",
|
||||||
|
f"+incdir+{common / 'interface'}",
|
||||||
|
f"+incdir+{common / 'utils'}",
|
||||||
|
f"+incdir+{common / 'clkrst'}",
|
||||||
|
f"+incdir+{PERIPHERAL}",
|
||||||
|
str(common / "interface/ribp_if.sv"),
|
||||||
|
str(common / "utils/register.sv"),
|
||||||
|
str(common / "clkrst/counter.sv"),
|
||||||
|
str(PERIPHERAL / "timer_core.sv"),
|
||||||
|
str(PERIPHERAL / "timer_reg.sv"),
|
||||||
|
str(PERIPHERAL / "ribp_timer.sv"),
|
||||||
|
str(ROOT / "tests/rtl/timer_tb.sv"),
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
converted = tmp_path / "timer_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 / "timer_tb"
|
||||||
|
subprocess.run(
|
||||||
|
[iverilog, "-g2012", "-s", "timer_tb", "-o", str(simulation), str(converted)],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
result = subprocess.run([vvp, str(simulation)], text=True, capture_output=True, check=True)
|
||||||
|
assert "RIBP Timer V2 register, mode, interrupt, and error test passed" in result.stdout
|
||||||
Reference in new issue
Block a user