feat: add PWM V2 support and update GPIO configurations

- Introduced PWM V2 alternate functions in the documentation, detailing the GPIO mappings and fault handling.
- Updated the filelist to include new PWM RTL files for the PWM V2 implementation.
- Modified the SOC topology JSON to reflect new GPIO alternate functions for PWM, including synchronization and capture inputs.
- Updated software makefile to include PWM source and header files.
- Enhanced the APB wrapper to integrate the PWM module with proper parameters.
- Updated the ASIC top-level module to include new GPIO mappings for PWM functionality.
- Added tests to validate the new GPIO and PWM connections in the topology.
This commit is contained in:
maksyuki committed 2026-08-11 07:35:06 +08:00
1 parent da061e0070
commit 068c05bf66
17 files changed
+749 -394

No files matched your search

+3 -1
View File
@@ -28,7 +28,9 @@ under the [Mulan Permissive Software License, Version 2](LICENSE).
- 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, - A memory-mapped peripheral subsystem with GPIO, UART,
[dual general timers](docs/ip/timer.md), PWM, [dual I2C controllers](docs/ip/i2c.md), I2S, [dual general timers](docs/ip/timer.md),
[PWM V2](rtl/managed/clusterip/pwm/doc/datasheet.md),
[dual I2C controllers](docs/ip/i2c.md), I2S,
[bidirectional PS/2 V2](docs/ip/ps2.md), [bidirectional PS/2 V2](docs/ip/ps2.md),
WS2812, SPI/QSPI, SDIO, PSRAM/OPI-PSRAM, SDRAM, DMA, LCD, RTC, an WS2812, SPI/QSPI, SDIO, PSRAM/OPI-PSRAM, SDRAM, DMA, LCD, RTC, an
independent-clock window watchdog, CRC, and a independent-clock window watchdog, CRC, and a
+1 -1
View File
@@ -59,7 +59,7 @@ int main(void) {
(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, rs_timer_shell_test); (void)rs_shell_register("tim", "timer test", true, rs_timer_shell_test);
(void)rs_shell_register("gpio", "gpio test", true, rs_gpio_shell_test); (void)rs_shell_register("gpio", "gpio test", true, rs_gpio_shell_test);
(void)rs_shell_register("pwm", "pwm test", true, ip_pwm_test); (void)rs_shell_register("pwm", "pwm test", true, rs_pwm_shell_test);
(void)rs_shell_register("rtc", "rtc test", true, rs_rtc_shell_test); (void)rs_shell_register("rtc", "rtc test", true, rs_rtc_shell_test);
(void)rs_shell_register("wdg", "wdg test", true, ip_wdg_test); (void)rs_shell_register("wdg", "wdg test", true, ip_wdg_test);
(void)rs_shell_register("rng", "rng test", true, rs_rng_shell_test); (void)rs_shell_register("rng", "rng test", true, rs_rng_shell_test);
+1 -1
View File
@@ -68,7 +68,7 @@
"cluster_i2s": {"url": "https://github.com/retroSoC/i2s.git", "revision": "bd0978e8b45e4cf4c1335a1fa7311385d2a4e805", "destination": "rtl/managed/clusterip/i2s", "license": "NOASSERTION"}, "cluster_i2s": {"url": "https://github.com/retroSoC/i2s.git", "revision": "bd0978e8b45e4cf4c1335a1fa7311385d2a4e805", "destination": "rtl/managed/clusterip/i2s", "license": "NOASSERTION"},
"cluster_plic": {"url": "https://github.com/retroSoC/plic.git", "revision": "c851d93829d2e75b224003a058e718925855c0cc", "destination": "rtl/managed/clusterip/plic", "license": "NOASSERTION"}, "cluster_plic": {"url": "https://github.com/retroSoC/plic.git", "revision": "c851d93829d2e75b224003a058e718925855c0cc", "destination": "rtl/managed/clusterip/plic", "license": "NOASSERTION"},
"cluster_ps2": {"url": "https://github.com/retroSoC/ps2.git", "revision": "2097a0d41b07573ff0453d65ba9a1670b3df7b9c", "destination": "rtl/managed/clusterip/ps2", "license": "MulanPSL-2.0"}, "cluster_ps2": {"url": "https://github.com/retroSoC/ps2.git", "revision": "2097a0d41b07573ff0453d65ba9a1670b3df7b9c", "destination": "rtl/managed/clusterip/ps2", "license": "MulanPSL-2.0"},
"cluster_pwm": {"url": "https://github.com/retroSoC/pwm.git", "revision": "c631ede87506d34f714167313ba69b196c0bea72", "destination": "rtl/managed/clusterip/pwm", "license": "NOASSERTION"}, "cluster_pwm": {"url": "https://github.com/retroSoC/pwm.git", "revision": "79ae32f725e848a1e7f6134847b3fb032ed64006", "destination": "rtl/managed/clusterip/pwm", "license": "MulanPSL-2.0"},
"cluster_rng": {"url": "https://github.com/retroSoC/rng.git", "revision": "36f3e0774d8f3c4b597d3db8a96ca3992532b61e", "destination": "rtl/managed/clusterip/rng", "license": "MulanPSL-2.0"}, "cluster_rng": {"url": "https://github.com/retroSoC/rng.git", "revision": "36f3e0774d8f3c4b597d3db8a96ca3992532b61e", "destination": "rtl/managed/clusterip/rng", "license": "MulanPSL-2.0"},
"cluster_rtc": {"url": "https://github.com/retroSoC/rtc.git", "revision": "32548c5cbcdf39e09d0880fb611f9dd47940ea88", "destination": "rtl/managed/clusterip/rtc", "license": "NOASSERTION"}, "cluster_rtc": {"url": "https://github.com/retroSoC/rtc.git", "revision": "32548c5cbcdf39e09d0880fb611f9dd47940ea88", "destination": "rtl/managed/clusterip/rtc", "license": "NOASSERTION"},
"cluster_spi": {"url": "https://github.com/retroSoC/spi.git", "revision": "515cb408806584525605b4747db5e890dbdf1928", "destination": "rtl/managed/clusterip/spi", "license": "NOASSERTION"}, "cluster_spi": {"url": "https://github.com/retroSoC/spi.git", "revision": "515cb408806584525605b4747db5e890dbdf1928", "destination": "rtl/managed/clusterip/spi", "license": "NOASSERTION"},
-10
View File
@@ -192,16 +192,6 @@
#define reg_uart1_trx RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x08)) #define reg_uart1_trx RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x08))
#define reg_uart1_fcr RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x0C)) #define reg_uart1_fcr RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x0C))
#define reg_uart1_lsr RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x10)) #define reg_uart1_lsr RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x10))
// pwm
#define reg_pwm_ctrl RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x00))
#define reg_pwm_pscr RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x04))
#define reg_pwm_cnt RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x08))
#define reg_pwm_cmp RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x0C))
#define reg_pwm_cr0 RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x10))
#define reg_pwm_cr1 RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x14))
#define reg_pwm_cr2 RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x18))
#define reg_pwm_cr3 RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x1C))
#define reg_pwm_stat RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x20))
// tim3 // tim3
#define reg_tim3_ctrl RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x00)) #define reg_tim3_ctrl RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x00))
#define reg_tim3_pscr RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x04)) #define reg_tim3_pscr RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x04))
+73 -1
View File
@@ -1,5 +1,77 @@
#ifndef RETROSOC_PWM_H #ifndef RETROSOC_PWM_H
#define RETROSOC_PWM_H #define RETROSOC_PWM_H
void ip_pwm_test(int argc, char **argv); #include <pwm.h>
#include <pwm_regs.h>
#include <retrosoc/core/status.h>
typedef pwm_timer_config_t rs_pwm_timer_config_t;
typedef pwm_channel_config_t rs_pwm_channel_config_t;
typedef pwm_operator_config_t rs_pwm_operator_config_t;
typedef pwm_fade_segment_t rs_pwm_fade_segment_t;
typedef pwm_fault_config_t rs_pwm_fault_config_t;
typedef pwm_capture_config_t rs_pwm_capture_config_t;
typedef pwm_snapshot_t rs_pwm_snapshot_t;
typedef pwm_count_mode_t rs_pwm_count_mode_t;
typedef pwm_load_mode_t rs_pwm_load_mode_t;
typedef pwm_safe_state_t rs_pwm_safe_state_t;
#define RS_PWM_COUNT_MODE_UP PWM_COUNT_MODE_UP
#define RS_PWM_COUNT_MODE_DOWN PWM_COUNT_MODE_DOWN
#define RS_PWM_COUNT_MODE_UP_DOWN PWM_COUNT_MODE_UP_DOWN
#define RS_PWM_LOAD_ON_ZERO PWM_LOAD_ON_ZERO
#define RS_PWM_LOAD_ON_PERIOD PWM_LOAD_ON_PERIOD
#define RS_PWM_LOAD_ON_ZERO_OR_SYNC PWM_LOAD_ON_ZERO_OR_SYNC
#define RS_PWM_LOAD_ON_SYNC PWM_LOAD_ON_SYNC
#define RS_PWM_SAFE_LOW PWM_SAFE_LOW
#define RS_PWM_SAFE_HIGH PWM_SAFE_HIGH
#define RS_PWM_SAFE_HIGH_Z PWM_SAFE_HIGH_Z
#define RS_PWM_ACTION_HOLD PWM_ACTION_HOLD
#define RS_PWM_ACTION_LOW PWM_ACTION_LOW
#define RS_PWM_ACTION_HIGH PWM_ACTION_HIGH
#define RS_PWM_ACTION_TOGGLE PWM_ACTION_TOGGLE
#define RS_PWM_EVENT_TIMER0_ZERO PWM_INTR_TIMER0_ZERO_MASK
#define RS_PWM_EVENT_TIMER1_ZERO PWM_INTR_TIMER1_ZERO_MASK
#define RS_PWM_EVENT_TIMER0_PERIOD PWM_INTR_TIMER0_PERIOD_MASK
#define RS_PWM_EVENT_TIMER1_PERIOD PWM_INTR_TIMER1_PERIOD_MASK
#define RS_PWM_EVENT_FADE0_DONE PWM_INTR_FADE0_DONE_MASK
#define RS_PWM_EVENT_FADE1_DONE PWM_INTR_FADE1_DONE_MASK
#define RS_PWM_EVENT_FADE2_DONE PWM_INTR_FADE2_DONE_MASK
#define RS_PWM_EVENT_FADE3_DONE PWM_INTR_FADE3_DONE_MASK
#define RS_PWM_EVENT_FAULT PWM_INTR_FAULT_MASK
#define RS_PWM_EVENT_CAPTURE0 PWM_INTR_CAPTURE0_MASK
#define RS_PWM_EVENT_CAPTURE1 PWM_INTR_CAPTURE1_MASK
#define RS_PWM_EVENT_CAPTURE0_OVERFLOW PWM_INTR_CAPTURE0_OVERFLOW_MASK
#define RS_PWM_EVENT_CAPTURE1_OVERFLOW PWM_INTR_CAPTURE1_OVERFLOW_MASK
#define RS_PWM_EVENT_ALL PWM_INTR_ALL_MASK
rs_status_t rs_pwm_probe(void);
rs_status_t rs_pwm_timer_configure(uint8_t timer, const rs_pwm_timer_config_t *config);
rs_status_t rs_pwm_channel_configure(uint8_t channel, const rs_pwm_channel_config_t *config);
rs_status_t rs_pwm_operator_configure(uint8_t operator_id, const rs_pwm_operator_config_t *config);
rs_status_t rs_pwm_fault_configure(const rs_pwm_fault_config_t *config);
rs_status_t rs_pwm_capture_configure(const rs_pwm_capture_config_t *config);
rs_status_t rs_pwm_enable(bool debug_freeze);
rs_status_t rs_pwm_disable(void);
rs_status_t rs_pwm_apply_update(rs_timeout_t timeout);
rs_status_t rs_pwm_software_sync(void);
rs_status_t rs_pwm_set_duty(uint8_t channel, uint32_t duty, rs_timeout_t timeout);
rs_status_t rs_pwm_fade_configure(uint8_t channel, const rs_pwm_fade_segment_t *segment);
rs_status_t rs_pwm_fade_start(uint8_t channel);
rs_status_t rs_pwm_fade_pause(uint8_t channel);
rs_status_t rs_pwm_fade_resume(uint8_t channel);
rs_status_t rs_pwm_fade_stop(uint8_t channel);
rs_status_t rs_pwm_gamma_program(uint8_t channel, const rs_pwm_fade_segment_t *segments,
uint8_t count);
rs_status_t rs_pwm_gamma_start(uint8_t channel, uint8_t count);
rs_status_t rs_pwm_fault_clear(void);
rs_status_t rs_pwm_fault_test(void);
rs_status_t rs_pwm_capture_read(uint8_t channel, uint32_t *timestamp, rs_timeout_t timeout);
rs_status_t rs_pwm_interrupt_enable(uint32_t mask);
rs_status_t rs_pwm_interrupt_clear(uint32_t mask);
rs_status_t rs_pwm_interrupt_test(uint32_t mask);
rs_status_t rs_pwm_get_status(rs_pwm_snapshot_t *snapshot);
void rs_pwm_shell_test(int argc, char **argv);
#endif #endif
+204 -34
View File
@@ -1,41 +1,211 @@
#include <retrosoc/core/soc.h>
#include <retrosoc/lib/printf.h>
#include <retrosoc/hal/timer.h>
#include <retrosoc/hal/pwm.h> #include <retrosoc/hal/pwm.h>
void ip_pwm_test(int argc, char **argv) { #include <retrosoc/core/soc.h>
#include <retrosoc/lib/printf.h>
static rs_status_t rs_pwm_status(pwm_status_t status) {
rs_status_t result;
switch (status) {
case PWM_STATUS_OK:
result = RS_OK;
break;
case PWM_STATUS_INVALID_ARGUMENT:
result = RS_EINVAL;
break;
case PWM_STATUS_TIMEOUT:
result = RS_ETIMEOUT;
break;
case PWM_STATUS_EMPTY:
result = RS_ENOSPC;
break;
case PWM_STATUS_LOCKED:
result = RS_ENOTSUP;
break;
case PWM_STATUS_INCOMPATIBLE:
result = RS_EFORMAT;
break;
case PWM_STATUS_BUSY:
default:
result = RS_EIO;
break;
}
return result;
}
rs_status_t rs_pwm_probe(void) {
return rs_pwm_status(pwm_probe((uintptr_t)RS_SOC_APB_PWM_BASE));
}
rs_status_t rs_pwm_timer_configure(uint8_t timer, const rs_pwm_timer_config_t *config) {
return rs_pwm_status(pwm_timer_configure((uintptr_t)RS_SOC_APB_PWM_BASE, timer, config));
}
rs_status_t rs_pwm_channel_configure(uint8_t channel, const rs_pwm_channel_config_t *config) {
return rs_pwm_status(pwm_channel_configure((uintptr_t)RS_SOC_APB_PWM_BASE, channel, config));
}
rs_status_t rs_pwm_operator_configure(uint8_t operator_id, const rs_pwm_operator_config_t *config) {
return rs_pwm_status(
pwm_operator_configure((uintptr_t)RS_SOC_APB_PWM_BASE, operator_id, config));
}
rs_status_t rs_pwm_fault_configure(const rs_pwm_fault_config_t *config) {
return rs_pwm_status(pwm_fault_configure((uintptr_t)RS_SOC_APB_PWM_BASE, config));
}
rs_status_t rs_pwm_capture_configure(const rs_pwm_capture_config_t *config) {
return rs_pwm_status(pwm_capture_configure((uintptr_t)RS_SOC_APB_PWM_BASE, config));
}
rs_status_t rs_pwm_enable(bool debug_freeze) {
return rs_pwm_status(pwm_enable((uintptr_t)RS_SOC_APB_PWM_BASE, debug_freeze));
}
rs_status_t rs_pwm_disable(void) {
return rs_pwm_status(pwm_disable((uintptr_t)RS_SOC_APB_PWM_BASE));
}
rs_status_t rs_pwm_apply_update(rs_timeout_t timeout) {
return rs_pwm_status(pwm_apply_update((uintptr_t)RS_SOC_APB_PWM_BASE, timeout));
}
rs_status_t rs_pwm_software_sync(void) {
return rs_pwm_status(pwm_software_sync((uintptr_t)RS_SOC_APB_PWM_BASE));
}
rs_status_t rs_pwm_set_duty(uint8_t channel, uint32_t duty, rs_timeout_t timeout) {
return rs_pwm_status(pwm_set_duty((uintptr_t)RS_SOC_APB_PWM_BASE, channel, duty, timeout));
}
rs_status_t rs_pwm_fade_configure(uint8_t channel, const rs_pwm_fade_segment_t *segment) {
return rs_pwm_status(pwm_fade_configure((uintptr_t)RS_SOC_APB_PWM_BASE, channel, segment));
}
rs_status_t rs_pwm_fade_start(uint8_t channel) {
return rs_pwm_status(pwm_fade_start((uintptr_t)RS_SOC_APB_PWM_BASE, channel));
}
rs_status_t rs_pwm_fade_pause(uint8_t channel) {
return rs_pwm_status(pwm_fade_pause((uintptr_t)RS_SOC_APB_PWM_BASE, channel));
}
rs_status_t rs_pwm_fade_resume(uint8_t channel) {
return rs_pwm_status(pwm_fade_resume((uintptr_t)RS_SOC_APB_PWM_BASE, channel));
}
rs_status_t rs_pwm_fade_stop(uint8_t channel) {
return rs_pwm_status(pwm_fade_stop((uintptr_t)RS_SOC_APB_PWM_BASE, channel));
}
rs_status_t rs_pwm_gamma_program(uint8_t channel, const rs_pwm_fade_segment_t *segments,
uint8_t count) {
return rs_pwm_status(
pwm_gamma_program((uintptr_t)RS_SOC_APB_PWM_BASE, channel, segments, count));
}
rs_status_t rs_pwm_gamma_start(uint8_t channel, uint8_t count) {
return rs_pwm_status(pwm_gamma_start((uintptr_t)RS_SOC_APB_PWM_BASE, channel, count));
}
rs_status_t rs_pwm_fault_clear(void) {
return rs_pwm_status(pwm_fault_clear((uintptr_t)RS_SOC_APB_PWM_BASE));
}
rs_status_t rs_pwm_fault_test(void) {
return rs_pwm_status(pwm_fault_test((uintptr_t)RS_SOC_APB_PWM_BASE));
}
rs_status_t rs_pwm_capture_read(uint8_t channel, uint32_t *timestamp, rs_timeout_t timeout) {
return rs_pwm_status(
pwm_capture_read((uintptr_t)RS_SOC_APB_PWM_BASE, channel, timestamp, timeout));
}
rs_status_t rs_pwm_interrupt_enable(uint32_t mask) {
return rs_pwm_status(pwm_interrupt_enable((uintptr_t)RS_SOC_APB_PWM_BASE, mask));
}
rs_status_t rs_pwm_interrupt_clear(uint32_t mask) {
return rs_pwm_status(pwm_interrupt_clear((uintptr_t)RS_SOC_APB_PWM_BASE, mask));
}
rs_status_t rs_pwm_interrupt_test(uint32_t mask) {
return rs_pwm_status(pwm_interrupt_test((uintptr_t)RS_SOC_APB_PWM_BASE, mask));
}
rs_status_t rs_pwm_get_status(rs_pwm_snapshot_t *snapshot) {
return rs_pwm_status(pwm_get_status((uintptr_t)RS_SOC_APB_PWM_BASE, snapshot));
}
void rs_pwm_shell_test(int argc, char **argv) {
static const rs_pwm_timer_config_t timer = {
.divider_q16_8 = UINT32_C(0x00000100),
.period = UINT32_C(72000),
.phase = 0U,
.count_mode = RS_PWM_COUNT_MODE_UP,
.load_mode = RS_PWM_LOAD_ON_ZERO,
.sync_enable = true,
.enable = true,
};
static const rs_pwm_channel_config_t channel = {
.phase = 0U,
.duty = UINT32_C(36000),
.action = UINT16_C(0x0042),
.timer = 0U,
.invert = false,
.enable = true,
};
static const rs_pwm_operator_config_t operator_config = {
.rising_deadtime = 0U,
.falling_deadtime = 0U,
.carrier_period = 0U,
.carrier_duty = 0U,
.carrier_invert = false,
.complementary = false,
.carrier_enable = false,
};
static const rs_pwm_fault_config_t fault = {
.filter_cycles = 2U,
.safe_state = {RS_PWM_SAFE_LOW, RS_PWM_SAFE_LOW, RS_PWM_SAFE_LOW, RS_PWM_SAFE_LOW},
.active_high = true,
.one_shot = false,
.enable = true,
.lock = false,
};
rs_pwm_snapshot_t snapshot;
rs_status_t status;
(void)argc; (void)argc;
(void)argv; (void)argv;
printf("[APB IP] pwm test\n"); status = rs_pwm_probe();
if (status == RS_OK) {
reg_pwm_ctrl = (uint32_t)0; status = rs_pwm_disable();
reg_pwm_pscr = (uint32_t)(CPU_FREQ - 1); // 'CPU_FREQ' MHz for 1MHz
reg_pwm_cmp = (uint32_t)(1000 - 1); // 1KHz
printf("reg_pwm_ctrl: %d reg_pwm_pscr: %d reg_pwm_cmp: %d\n", reg_pwm_ctrl, reg_pwm_pscr,
reg_pwm_cmp);
for (int i = 0; i < 6; i++) {
for (int j = 10; j <= 990; ++j) {
reg_pwm_ctrl = (uint32_t)4;
reg_pwm_cr0 = j;
reg_pwm_ctrl = (uint32_t)3;
reg_pwm_pscr = 49;
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) {
reg_pwm_ctrl = (uint32_t)4;
reg_pwm_cr0 = j;
reg_pwm_ctrl = (uint32_t)3;
reg_pwm_pscr = 49;
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);
} }
if (status == RS_OK) {
status = rs_pwm_fault_configure(&fault);
}
if (status == RS_OK) {
status = rs_pwm_operator_configure(0U, &operator_config);
}
if (status == RS_OK) {
status = rs_pwm_timer_configure(0U, &timer);
}
if (status == RS_OK) {
status = rs_pwm_channel_configure(0U, &channel);
}
if (status == RS_OK) {
status = rs_pwm_apply_update(RS_TIMEOUT_DEFAULT);
}
if (status == RS_OK) {
status = rs_pwm_enable(true);
}
if (status == RS_OK) {
status = rs_pwm_get_status(&snapshot);
}
if (status != RS_OK) {
printf("[PWM] V2 test failed: %d\n", status);
return;
}
printf("[APB IP] PWM V2 status=%x outputs=%x\n", snapshot.status, snapshot.output_status);
} }
+2 -1
View File
@@ -121,7 +121,8 @@ void rs_app_info(void) {
printf(" 1 x RNG @%p\n", printf(" 1 x RNG @%p\n",
(void *)(uintptr_t)RS_SOC_APB_RNG_BASE); (void *)(uintptr_t)RS_SOC_APB_RNG_BASE);
printf(" 1 x UART1(ADV) @%p\n", (void *)&reg_uart1_lcr); printf(" 1 x UART1(ADV) @%p\n", (void *)&reg_uart1_lcr);
printf(" 1 x PWM(4CHNL) @%p\n", (void *)&reg_pwm_ctrl); printf(" 1 x PWM V2(4CH) @%p\n",
(void *)(uintptr_t)RS_SOC_APB_PWM_BASE);
printf(" 1 x PS2 @%p\n", printf(" 1 x PS2 @%p\n",
(void *)(uintptr_t)RS_SOC_APB_PS2_BASE); (void *)(uintptr_t)RS_SOC_APB_PS2_BASE);
printf(" 1 x RTC @%p\n", printf(" 1 x RTC @%p\n",
+3
View File
@@ -38,6 +38,9 @@ the root README and subsystem guides.
defines Epoch time, alarms, periodic wake, calibration, CDC, and software. defines Epoch time, alarms, periodic wake, calibration, CDC, and software.
- The managed [CRC V2 datasheet](../rtl/managed/clusterip/crc/doc/datasheet.md) - The managed [CRC V2 datasheet](../rtl/managed/clusterip/crc/doc/datasheet.md)
defines the programmable streaming CRC engine, APB ABI, errors, and software. defines the programmable streaming CRC engine, APB ABI, errors, and software.
- The managed [PWM V2 datasheet](../rtl/managed/clusterip/pwm/doc/datasheet.md)
defines the dual-timer/four-channel LED and motor PWM controller, fault,
synchronization, dead-time, carrier, fade, and capture 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
+10 -3
View File
@@ -43,7 +43,7 @@ digraph mini_soc_block_diagram {
]; ];
ext_io [ ext_io [
fillcolor="#F3F4F6", fillcolor="#F3F4F6",
label="External I/O and memory\nGPIO, UART0, PS/2, XPI Flash, SDRAM, PSRAM\nSD card, I2C, I2S, DVP and WS2812" label="External I/O and memory\nGPIO, UART0, PS/2, XPI Flash, SDRAM, PSRAM\nSD card, I2C, I2S, DVP, WS2812 and PWM V2"
]; ];
ext_jtag [ ext_jtag [
fillcolor="#F3F4F6", fillcolor="#F3F4F6",
@@ -152,7 +152,11 @@ digraph mini_soc_block_diagram {
]; ];
apb_targets [ apb_targets [
fillcolor="#E6F4EA", fillcolor="#E6F4EA",
label="APB target wrapper\nUART1, PWM, advanced timer\nand user IP" label="APB target wrapper\nUART1, advanced timer\nand user IP"
];
pwm [
fillcolor="#E6F4EA",
label="PWM V2\n2 timers, 4 action channels, 2 operators\nfades, dead time, carrier, fault and capture, IRQ11"
]; ];
wdg [ wdg [
fillcolor="#FDE68A", fillcolor="#FDE68A",
@@ -193,7 +197,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; clint; ribp_targets; uart0; i2c_controllers; gpio_controller; timers; ws2812; archinfo; rng; ps2; rtc; wdg; crc; apb_targets; } { rank=same; sysctrl; clint; ribp_targets; uart0; i2c_controllers; gpio_controller; timers; ws2812; archinfo; rng; ps2; rtc; wdg; crc; pwm; apb_targets; }
{ rank=same; gpio_bridge; irq; } { rank=same; gpio_bridge; irq; }
ext_clock -> rcu [label="clock / reset"]; ext_clock -> rcu [label="clock / reset"];
@@ -229,6 +233,7 @@ digraph mini_soc_block_diagram {
apb_adapter -> rtc [label="APB"]; apb_adapter -> rtc [label="APB"];
apb_adapter -> wdg [label="APB"]; apb_adapter -> wdg [label="APB"];
apb_adapter -> crc [label="APB"]; apb_adapter -> crc [label="APB"];
apb_adapter -> pwm [label="APB"];
apb_adapter -> apb_targets [label="APB"]; apb_adapter -> apb_targets [label="APB"];
ribp_targets -> gpio_controller [label="alternate functions"]; ribp_targets -> gpio_controller [label="alternate functions"];
@@ -247,6 +252,8 @@ digraph mini_soc_block_diagram {
rng -> irq [label="IRQ16"]; rng -> irq [label="IRQ16"];
ps2 -> gpio_controller [label="GPIO0/1 ALT1\nopen drain"]; ps2 -> gpio_controller [label="GPIO0/1 ALT1\nopen drain"];
ps2 -> irq [label="IRQ12"]; ps2 -> irq [label="IRQ12"];
pwm -> gpio_controller [dir=both, label="GPIO3-6 output\nGPIO2 sync, GPIO9 fault\nGPIO30/31 capture"];
pwm -> irq [label="IRQ11"];
rcu -> rtc [label="18.432 MHz audio clock", style=dashed]; rcu -> rtc [label="18.432 MHz audio clock", style=dashed];
rtc -> irq [label="IRQ13"]; rtc -> irq [label="IRQ13"];
rtc -> sysctrl [label="wake live / sticky", style=dashed]; rtc -> sysctrl [label="wake live / sticky", style=dashed];
File diff suppressed because it is too large. Load diff

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 60 KiB

+17
View File
@@ -36,6 +36,23 @@ Board-level pull-ups are therefore required. I2C0 uses management-core IRQ7
and generic-DMA modes 7/8; I2C1 uses IRQ19 and DMA modes 9/10. See and generic-DMA modes 7/8; I2C1 uses IRQ19 and DMA modes 9/10. See
[i2c.md](ip/i2c.md) for the register and transfer contract. [i2c.md](ip/i2c.md) for the register and transfer contract.
## PWM V2 alternate functions
The APB PWM V2 controller drives GPIO3 through GPIO6 on ALT0. Both output data
and output enable come from the PWM interface, so a fault-configured high-Z
state reaches the GPIO pad bridge instead of being overridden by a constant
enable. PWM uses management-core IRQ11.
GPIO2 ALT0 feeds the external synchronization input while retaining its
existing advanced-timer capture binding. GPIO9 ALT0 feeds the asynchronous
fault input. GPIO30 and GPIO31 ALT1 feed capture channels 0 and 1. Software must
select the corresponding alternate function and input mode before relying on
these paths. GPIO9 fault shutdown includes an immediate asynchronous safe-state
path plus synchronized filtering/status inside the IP; technology sign-off must
verify external pulse width and pad-disable latency. The complete programming,
safety, and verification contract is in the managed
[PWM V2 datasheet](../rtl/managed/clusterip/pwm/doc/datasheet.md).
## WS2812 output ## WS2812 output
The single-channel WS2812 transmitter occupies RIBP address `0x10008000` and The single-channel WS2812 transmitter occupies RIBP address `0x10008000` and
+9
View File
@@ -9,6 +9,15 @@
/clusterip/uart/rtl/uart_rx.sv /clusterip/uart/rtl/uart_rx.sv
/clusterip/uart/rtl/uart_irq.sv /clusterip/uart/rtl/uart_irq.sv
/clusterip/uart/rtl/apb4_uart.sv /clusterip/uart/rtl/apb4_uart.sv
/clusterip/pwm/rtl/pwm_pkg.sv
/clusterip/pwm/rtl/pwm_tickgen.sv
/clusterip/pwm/rtl/pwm_timer.sv
/clusterip/pwm/rtl/pwm_channel.sv
/clusterip/pwm/rtl/pwm_deadtime.sv
/clusterip/pwm/rtl/pwm_carrier.sv
/clusterip/pwm/rtl/pwm_capture.sv
/clusterip/pwm/rtl/pwm_core.sv
/clusterip/pwm/rtl/pwm_reg.sv
/clusterip/pwm/rtl/pwm_if.sv /clusterip/pwm/rtl/pwm_if.sv
/clusterip/pwm/rtl/apb4_pwm.sv /clusterip/pwm/rtl/apb4_pwm.sv
/clusterip/ps2/rtl/ps2_filter.sv /clusterip/ps2/rtl/ps2_filter.sv
+8 -8
View File
@@ -73,14 +73,14 @@
"gpio_alt_functions": [ "gpio_alt_functions": [
{"pin": 0, "alt0": {"inputs": ["u_uart1_if.rx_i"], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": ["u_ps2_if.ps2_clk_i"], "do": "u_ps2_if.ps2_clk_o", "oe": "u_ps2_if.ps2_clk_oe_o"}}, {"pin": 0, "alt0": {"inputs": ["u_uart1_if.rx_i"], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": ["u_ps2_if.ps2_clk_i"], "do": "u_ps2_if.ps2_clk_o", "oe": "u_ps2_if.ps2_clk_oe_o"}},
{"pin": 1, "alt0": {"inputs": [], "do": "u_uart1_if.tx_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_ps2_if.ps2_dat_i"], "do": "u_ps2_if.ps2_dat_o", "oe": "u_ps2_if.ps2_dat_oe_o"}}, {"pin": 1, "alt0": {"inputs": [], "do": "u_uart1_if.tx_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_ps2_if.ps2_dat_i"], "do": "u_ps2_if.ps2_dat_o", "oe": "u_ps2_if.ps2_dat_oe_o"}},
{"pin": 2, "alt0": {"inputs": ["s_tmr_capch"], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": [], "do": "u_ws2812_if.dat_o", "oe": "1'b1"}}, {"pin": 2, "alt0": {"inputs": ["s_tmr_capch", "u_pwm_if.sync_i"], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": [], "do": "u_ws2812_if.dat_o", "oe": "1'b1"}},
{"pin": 3, "alt0": {"inputs": [], "do": "u_pwm_if.do_o[0]", "oe": "1'b1"}, "alt1": {"inputs": ["u_i2c1_if.scl_i"], "do": "u_i2c1_if.scl_o", "oe": "u_i2c1_if.scl_oe_o"}}, {"pin": 3, "alt0": {"inputs": [], "do": "u_pwm_if.pwm_o[0]", "oe": "u_pwm_if.oe_o[0]"}, "alt1": {"inputs": ["u_i2c1_if.scl_i"], "do": "u_i2c1_if.scl_o", "oe": "u_i2c1_if.scl_oe_o"}},
{"pin": 4, "alt0": {"inputs": [], "do": "u_pwm_if.do_o[1]", "oe": "1'b1"}, "alt1": {"inputs": ["u_i2c1_if.sda_i"], "do": "u_i2c1_if.sda_o", "oe": "u_i2c1_if.sda_oe_o"}}, {"pin": 4, "alt0": {"inputs": [], "do": "u_pwm_if.pwm_o[1]", "oe": "u_pwm_if.oe_o[1]"}, "alt1": {"inputs": ["u_i2c1_if.sda_i"], "do": "u_i2c1_if.sda_o", "oe": "u_i2c1_if.sda_oe_o"}},
{"pin": 5, "alt0": {"inputs": [], "do": "u_pwm_if.do_o[2]", "oe": "1'b1"}, "alt1": {"inputs": [], "do": "clkdiv4_i", "oe": "1'b1"}}, {"pin": 5, "alt0": {"inputs": [], "do": "u_pwm_if.pwm_o[2]", "oe": "u_pwm_if.oe_o[2]"}, "alt1": {"inputs": [], "do": "clkdiv4_i", "oe": "1'b1"}},
{"pin": 6, "alt0": {"inputs": [], "do": "u_pwm_if.do_o[3]", "oe": "1'b1"}, "alt1": {"inputs": [], "do": "u_spisd_if.sck_o", "oe": "1'b1"}}, {"pin": 6, "alt0": {"inputs": [], "do": "u_pwm_if.pwm_o[3]", "oe": "u_pwm_if.oe_o[3]"}, "alt1": {"inputs": [], "do": "u_spisd_if.sck_o", "oe": "1'b1"}},
{"pin": 7, "alt0": {"inputs": ["u_i2c0_if.scl_i"], "do": "u_i2c0_if.scl_o", "oe": "u_i2c0_if.scl_oe_o"}, "alt1": {"inputs": [], "do": "u_spisd_if.nss_o", "oe": "1'b1"}}, {"pin": 7, "alt0": {"inputs": ["u_i2c0_if.scl_i"], "do": "u_i2c0_if.scl_o", "oe": "u_i2c0_if.scl_oe_o"}, "alt1": {"inputs": [], "do": "u_spisd_if.nss_o", "oe": "1'b1"}},
{"pin": 8, "alt0": {"inputs": ["u_i2c0_if.sda_i"], "do": "u_i2c0_if.sda_o", "oe": "u_i2c0_if.sda_oe_o"}, "alt1": {"inputs": [], "do": "u_spisd_if.mosi_o", "oe": "1'b1"}}, {"pin": 8, "alt0": {"inputs": ["u_i2c0_if.sda_i"], "do": "u_i2c0_if.sda_o", "oe": "u_i2c0_if.sda_oe_o"}, "alt1": {"inputs": [], "do": "u_spisd_if.mosi_o", "oe": "1'b1"}},
{"pin": 9, "alt0": {"inputs": [], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": ["u_spisd_if.miso_i"], "do": "1'b0", "oe": "1'b0"}}, {"pin": 9, "alt0": {"inputs": ["u_pwm_if.fault_i"], "do": "1'b0", "oe": "1'b0"}, "alt1": {"inputs": ["u_spisd_if.miso_i"], "do": "1'b0", "oe": "1'b0"}},
{"pin": 10, "alt0": {"inputs": [], "do": "u_i2s_if.mclk_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_dvp_if.pclk_i"], "do": "1'b0", "oe": "1'b0"}}, {"pin": 10, "alt0": {"inputs": [], "do": "u_i2s_if.mclk_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_dvp_if.pclk_i"], "do": "1'b0", "oe": "1'b0"}},
{"pin": 11, "alt0": {"inputs": [], "do": "u_i2s_if.sclk_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_dvp_if.href_i"], "do": "1'b0", "oe": "1'b0"}}, {"pin": 11, "alt0": {"inputs": [], "do": "u_i2s_if.sclk_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_dvp_if.href_i"], "do": "1'b0", "oe": "1'b0"}},
{"pin": 12, "alt0": {"inputs": [], "do": "u_i2s_if.lrck_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_dvp_if.vsync_i"], "do": "1'b0", "oe": "1'b0"}}, {"pin": 12, "alt0": {"inputs": [], "do": "u_i2s_if.lrck_o", "oe": "1'b1"}, "alt1": {"inputs": ["u_dvp_if.vsync_i"], "do": "1'b0", "oe": "1'b0"}},
@@ -101,7 +101,7 @@
{"pin": 27, "alt0": {"inputs": ["u_opipsram_if.io_di_i[4]"], "do": "u_opipsram_if.io_do_o[4]", "oe": "u_opipsram_if.io_oe_o[4]"}, "alt1": {"inputs": [], "do": "u_psram_if.nss_o[1]", "oe": "1'b1"}}, {"pin": 27, "alt0": {"inputs": ["u_opipsram_if.io_di_i[4]"], "do": "u_opipsram_if.io_do_o[4]", "oe": "u_opipsram_if.io_oe_o[4]"}, "alt1": {"inputs": [], "do": "u_psram_if.nss_o[1]", "oe": "1'b1"}},
{"pin": 28, "alt0": {"inputs": ["u_opipsram_if.io_di_i[5]"], "do": "u_opipsram_if.io_do_o[5]", "oe": "u_opipsram_if.io_oe_o[5]"}, "alt1": {"inputs": [], "do": "u_psram_if.nss_o[2]", "oe": "1'b1"}}, {"pin": 28, "alt0": {"inputs": ["u_opipsram_if.io_di_i[5]"], "do": "u_opipsram_if.io_do_o[5]", "oe": "u_opipsram_if.io_oe_o[5]"}, "alt1": {"inputs": [], "do": "u_psram_if.nss_o[2]", "oe": "1'b1"}},
{"pin": 29, "alt0": {"inputs": ["u_opipsram_if.io_di_i[6]"], "do": "u_opipsram_if.io_do_o[6]", "oe": "u_opipsram_if.io_oe_o[6]"}, "alt1": {"inputs": [], "do": "u_psram_if.nss_o[3]", "oe": "1'b1"}}, {"pin": 29, "alt0": {"inputs": ["u_opipsram_if.io_di_i[6]"], "do": "u_opipsram_if.io_do_o[6]", "oe": "u_opipsram_if.io_oe_o[6]"}, "alt1": {"inputs": [], "do": "u_psram_if.nss_o[3]", "oe": "1'b1"}},
{"pin": 30, "alt0": {"inputs": ["u_opipsram_if.io_di_i[7]"], "do": "u_opipsram_if.io_do_o[7]", "oe": "u_opipsram_if.io_oe_o[7]"}, "alt1": {"inputs": [], "do": "1'b0", "oe": "1'b0"}}, {"pin": 30, "alt0": {"inputs": ["u_opipsram_if.io_di_i[7]"], "do": "u_opipsram_if.io_do_o[7]", "oe": "u_opipsram_if.io_oe_o[7]"}, "alt1": {"inputs": ["u_pwm_if.capture_i[0]"], "do": "1'b0", "oe": "1'b0"}},
{"pin": 31, "alt0": {"inputs": ["u_opipsram_if.dqs_di_i"], "do": "u_opipsram_if.dqs_do_o", "oe": "u_opipsram_if.dqs_oe_o"}, "alt1": {"inputs": [], "do": "1'b0", "oe": "1'b0"}} {"pin": 31, "alt0": {"inputs": ["u_opipsram_if.dqs_di_i"], "do": "u_opipsram_if.dqs_do_o", "oe": "u_opipsram_if.dqs_oe_o"}, "alt1": {"inputs": ["u_pwm_if.capture_i[1]"], "do": "1'b0", "oe": "1'b0"}}
] ]
} }
+4
View File
@@ -67,6 +67,7 @@ CRT_SRCS := $(ROOT_PATH)/crt/arch/riscv/startup.S \
$(ROOT_PATH)/rtl/managed/clusterip/rng/sw/src/rng.c \ $(ROOT_PATH)/rtl/managed/clusterip/rng/sw/src/rng.c \
$(ROOT_PATH)/rtl/managed/clusterip/rtc/sw/src/rtc.c \ $(ROOT_PATH)/rtl/managed/clusterip/rtc/sw/src/rtc.c \
$(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/src/wdg.c \ $(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/src/wdg.c \
$(ROOT_PATH)/rtl/managed/clusterip/pwm/sw/src/pwm.c \
$(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/src/ps2.c \ $(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/src/ps2.c \
$(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/src/ps2_keyboard.c \ $(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/src/ps2_keyboard.c \
$(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/src/ps2_mouse.c \ $(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/src/ps2_mouse.c \
@@ -141,6 +142,7 @@ INC_PATH := -I$(SW_BUILD_DIR)/include \
-I$(ROOT_PATH)/rtl/managed/clusterip/rng/sw/include \ -I$(ROOT_PATH)/rtl/managed/clusterip/rng/sw/include \
-I$(ROOT_PATH)/rtl/managed/clusterip/rtc/sw/include \ -I$(ROOT_PATH)/rtl/managed/clusterip/rtc/sw/include \
-I$(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/include \ -I$(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/include \
-I$(ROOT_PATH)/rtl/managed/clusterip/pwm/sw/include \
-I$(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/include \ -I$(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/include \
-I$(ROOT_PATH)/crt/include \ -I$(ROOT_PATH)/crt/include \
$(addprefix -I,$(APP_INC_DIRS)) $(addprefix -I,$(APP_INC_DIRS))
@@ -162,6 +164,8 @@ SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/rtc/sw/incl
-type f -name '*.h' 2>/dev/null) -type f -name '*.h' 2>/dev/null)
SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/include \ SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/include \
-type f -name '*.h' 2>/dev/null) -type f -name '*.h' 2>/dev/null)
SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/pwm/sw/include \
-type f -name '*.h' 2>/dev/null)
SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/include \ SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/include \
-type f -name '*.h' 2>/dev/null) -type f -name '*.h' 2>/dev/null)
+6 -3
View File
@@ -156,9 +156,12 @@ module ip_apb_wrapper (
.uart(uart) .uart(uart)
); );
apb4_pwm u_apb4_pwm ( apb4_pwm #(
.apb4(u_pwm_apb_if), .PCLK_HZ(`SOC_EXT_CLK_HZ)
.pwm (pwm) ) u_apb4_pwm (
.debug_halted_i(debug_halted_i),
.apb4 (u_pwm_apb_if),
.pwm (pwm)
); );
apb4_ps2 #( apb4_ps2 #(
+39
View File
@@ -12,6 +12,45 @@
`include "soc_clock_config.svh" `include "soc_clock_config.svh"
`include "user_extensions.svh" `include "user_extensions.svh"
// GPIO mux reference. The executable source of truth is
// rtl/mini/integration/soc_topology.json. ALT_ENABLE selects the alternate
// path, ALT_SELECT chooses ALT0/ALT1, and USER_SELECT gives the pin to User IP.
//
// GPIO ALT0 DIR ALT1 DIR
// ------ --------------------------- ------ ---------------------- ------
// GPIO00 UART1_RX IN PS2_CLK BIDI
// GPIO01 UART1_TX OUT PS2_DATA BIDI
// GPIO02 TMR_CAPTURE + PWM_SYNC IN WS2812_DATA OUT
// GPIO03 PWM0 OUT I2C1_SCL BIDI
// GPIO04 PWM1 OUT I2C1_SDA BIDI
// GPIO05 PWM2 OUT CLKDIV4 OUT
// GPIO06 PWM3 OUT SPISD_SCK OUT
// GPIO07 I2C0_SCL BIDI SPISD_NSS OUT
// GPIO08 I2C0_SDA BIDI SPISD_MOSI OUT
// GPIO09 PWM_FAULT IN SPISD_MISO IN
// GPIO10 I2S_MCLK OUT DVP_PCLK IN
// GPIO11 I2S_SCLK OUT DVP_HREF IN
// GPIO12 I2S_LRCK OUT DVP_VSYNC IN
// GPIO13 I2S_DAC_DATA OUT DVP_DATA0 IN
// GPIO14 I2S_ADC_DATA IN DVP_DATA1 IN
// GPIO15 SDIO_SCK OUT DVP_DATA2 IN
// GPIO16 SDIO_CMD BIDI DVP_DATA3 IN
// GPIO17 SDIO_DATA0 BIDI DVP_DATA4 IN
// GPIO18 SDIO_DATA1 BIDI DVP_DATA5 IN
// GPIO19 SDIO_DATA2 BIDI DVP_DATA6 IN
// GPIO20 SDIO_DATA3 BIDI DVP_DATA7 IN
// GPIO21 OPI_PSRAM_SCK OUT QSPI_PSRAM_SCK OUT
// GPIO22 OPI_PSRAM_CE OUT QSPI_PSRAM_NSS0 OUT
// GPIO23 OPI_PSRAM_IO0 BIDI QSPI_PSRAM_IO0 BIDI
// GPIO24 OPI_PSRAM_IO1 BIDI QSPI_PSRAM_IO1 BIDI
// GPIO25 OPI_PSRAM_IO2 BIDI QSPI_PSRAM_IO2 BIDI
// GPIO26 OPI_PSRAM_IO3 BIDI QSPI_PSRAM_IO3 BIDI
// GPIO27 OPI_PSRAM_IO4 BIDI QSPI_PSRAM_NSS1 OUT
// GPIO28 OPI_PSRAM_IO5 BIDI QSPI_PSRAM_NSS2 OUT
// GPIO29 OPI_PSRAM_IO6 BIDI QSPI_PSRAM_NSS3 OUT
// GPIO30 OPI_PSRAM_IO7 BIDI PWM_CAPTURE0 IN
// GPIO31 OPI_PSRAM_DQS BIDI PWM_CAPTURE1 IN
module retrosoc_asic ( module retrosoc_asic (
`include "retrosoc_asic_ports.svh" `include "retrosoc_asic_ports.svh"
); );
+6
View File
@@ -88,6 +88,12 @@ def test_topology_generates_complete_rib_apb_and_gpio_bindings(tmp_path: Path) -
assert "assign u_gpio_if.alt1_do_i[1] = u_ps2_if.ps2_dat_o;" in gpio assert "assign u_gpio_if.alt1_do_i[1] = u_ps2_if.ps2_dat_o;" in gpio
assert "assign u_gpio_if.alt1_oe_i[1] = u_ps2_if.ps2_dat_oe_o;" in gpio assert "assign u_gpio_if.alt1_oe_i[1] = u_ps2_if.ps2_dat_oe_o;" in gpio
assert "assign u_gpio_if.alt1_do_i[2] = u_ws2812_if.dat_o;" in gpio assert "assign u_gpio_if.alt1_do_i[2] = u_ws2812_if.dat_o;" in gpio
assert "assign u_pwm_if.sync_i = u_gpio_if.di_i[2];" in gpio
assert "assign u_gpio_if.alt0_do_i[3] = u_pwm_if.pwm_o[0];" in gpio
assert "assign u_gpio_if.alt0_oe_i[3] = u_pwm_if.oe_o[0];" in gpio
assert "assign u_pwm_if.fault_i = u_gpio_if.di_i[9];" in gpio
assert "assign u_pwm_if.capture_i[0] = u_gpio_if.di_i[30];" in gpio
assert "assign u_pwm_if.capture_i[1] = u_gpio_if.di_i[31];" in gpio
assert "assign u_gpio_if.alt1_do_i[22] = u_psram_if.nss_o[0];" in gpio assert "assign u_gpio_if.alt1_do_i[22] = u_psram_if.nss_o[0];" in gpio
assert apb_interfaces.count("apb4_if u_") == 10 assert apb_interfaces.count("apb4_if u_") == 10
assert "apb4_pure_if u_archinfo_apb_pure_if ();" in apb_interfaces assert "apb4_pure_if u_archinfo_apb_pure_if ();" in apb_interfaces