mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
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:
17 files changed
+747
-392
No files matched your search
@@ -28,7 +28,9 @@ under the [Mulan Permissive Software License, Version 2](LICENSE).
|
||||
- Configurable GF180, SKY130, IHP130, and ICS55 implementation targets with
|
||||
open-source CI coverage.
|
||||
- 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),
|
||||
WS2812, SPI/QSPI, SDIO, PSRAM/OPI-PSRAM, SDRAM, DMA, LCD, RTC, an
|
||||
independent-clock window watchdog, CRC, and a
|
||||
|
||||
@@ -59,7 +59,7 @@ int main(void) {
|
||||
(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("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("wdg", "wdg test", true, ip_wdg_test);
|
||||
(void)rs_shell_register("rng", "rng test", true, rs_rng_shell_test);
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"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_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_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"},
|
||||
|
||||
@@ -192,16 +192,6 @@
|
||||
#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_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
|
||||
#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))
|
||||
|
||||
@@ -1,5 +1,77 @@
|
||||
#ifndef 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
|
||||
+203
-33
@@ -1,41 +1,211 @@
|
||||
#include <retrosoc/core/soc.h>
|
||||
#include <retrosoc/lib/printf.h>
|
||||
#include <retrosoc/hal/timer.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)argv;
|
||||
|
||||
printf("[APB IP] pwm test\n");
|
||||
|
||||
reg_pwm_ctrl = (uint32_t)0;
|
||||
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");
|
||||
status = rs_pwm_probe();
|
||||
if (status == RS_OK) {
|
||||
status = rs_pwm_disable();
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
printf("[APB IP] PWM V2 status=%x outputs=%x\n", snapshot.status, snapshot.output_status);
|
||||
}
|
||||
@@ -121,7 +121,8 @@ void rs_app_info(void) {
|
||||
printf(" 1 x RNG @%p\n",
|
||||
(void *)(uintptr_t)RS_SOC_APB_RNG_BASE);
|
||||
printf(" 1 x UART1(ADV) @%p\n", (void *)®_uart1_lcr);
|
||||
printf(" 1 x PWM(4CHNL) @%p\n", (void *)®_pwm_ctrl);
|
||||
printf(" 1 x PWM V2(4CH) @%p\n",
|
||||
(void *)(uintptr_t)RS_SOC_APB_PWM_BASE);
|
||||
printf(" 1 x PS2 @%p\n",
|
||||
(void *)(uintptr_t)RS_SOC_APB_PS2_BASE);
|
||||
printf(" 1 x RTC @%p\n",
|
||||
|
||||
@@ -38,6 +38,9 @@ the root README and subsystem guides.
|
||||
defines Epoch time, alarms, periodic wake, calibration, CDC, and software.
|
||||
- The managed [CRC V2 datasheet](../rtl/managed/clusterip/crc/doc/datasheet.md)
|
||||
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
|
||||
pin-map workflow and SoC integration boundary.
|
||||
- [mini-soc-block-diagram.svg](mini-soc-block-diagram.svg) is the Mini SoC
|
||||
|
||||
@@ -43,7 +43,7 @@ digraph mini_soc_block_diagram {
|
||||
];
|
||||
ext_io [
|
||||
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 [
|
||||
fillcolor="#F3F4F6",
|
||||
@@ -152,7 +152,11 @@ digraph mini_soc_block_diagram {
|
||||
];
|
||||
apb_targets [
|
||||
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 [
|
||||
fillcolor="#FDE68A",
|
||||
@@ -193,7 +197,7 @@ digraph mini_soc_block_diagram {
|
||||
{ rank=same; user_core; dma; }
|
||||
{ rank=same; fault; fabric; sram; }
|
||||
{ rank=same; ribp_adapter; apb_adapter; }
|
||||
{ rank=same; sysctrl; clint; ribp_targets; 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; }
|
||||
|
||||
ext_clock -> rcu [label="clock / reset"];
|
||||
@@ -229,6 +233,7 @@ digraph mini_soc_block_diagram {
|
||||
apb_adapter -> rtc [label="APB"];
|
||||
apb_adapter -> wdg [label="APB"];
|
||||
apb_adapter -> crc [label="APB"];
|
||||
apb_adapter -> pwm [label="APB"];
|
||||
apb_adapter -> apb_targets [label="APB"];
|
||||
|
||||
ribp_targets -> gpio_controller [label="alternate functions"];
|
||||
@@ -247,6 +252,8 @@ digraph mini_soc_block_diagram {
|
||||
rng -> irq [label="IRQ16"];
|
||||
ps2 -> gpio_controller [label="GPIO0/1 ALT1\nopen drain"];
|
||||
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];
|
||||
rtc -> irq [label="IRQ13"];
|
||||
rtc -> sysctrl [label="wake live / sticky", style=dashed];
|
||||
|
||||
+363
-331
File diff suppressed because it is too large.
Load diff
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 60 KiB |
@@ -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
|
||||
[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
|
||||
|
||||
The single-channel WS2812 transmitter occupies RIBP address `0x10008000` and
|
||||
|
||||
@@ -9,6 +9,15 @@
|
||||
/clusterip/uart/rtl/uart_rx.sv
|
||||
/clusterip/uart/rtl/uart_irq.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/apb4_pwm.sv
|
||||
/clusterip/ps2/rtl/ps2_filter.sv
|
||||
|
||||
@@ -73,14 +73,14 @@
|
||||
"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": 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": 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": 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": 5, "alt0": {"inputs": [], "do": "u_pwm_if.do_o[2]", "oe": "1'b1"}, "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": 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.pwm_o[0]", "oe": "u_pwm_if.oe_o[0]"}, "alt1": {"inputs": ["u_i2c1_if.scl_i"], "do": "u_i2c1_if.scl_o", "oe": "u_i2c1_if.scl_oe_o"}},
|
||||
{"pin": 4, "alt0": {"inputs": [], "do": "u_pwm_if.pwm_o[1]", "oe": "u_pwm_if.oe_o[1]"}, "alt1": {"inputs": ["u_i2c1_if.sda_i"], "do": "u_i2c1_if.sda_o", "oe": "u_i2c1_if.sda_oe_o"}},
|
||||
{"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.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": 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": 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"}},
|
||||
@@ -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": 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": 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": 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": 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": ["u_pwm_if.capture_i[1]"], "do": "1'b0", "oe": "1'b0"}}
|
||||
]
|
||||
}
|
||||
@@ -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/rtc/sw/src/rtc.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_keyboard.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/rtc/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)/crt/include \
|
||||
$(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)
|
||||
SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/include \
|
||||
-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 \
|
||||
-type f -name '*.h' 2>/dev/null)
|
||||
|
||||
|
||||
@@ -156,8 +156,11 @@ module ip_apb_wrapper (
|
||||
.uart(uart)
|
||||
);
|
||||
|
||||
apb4_pwm u_apb4_pwm (
|
||||
.apb4(u_pwm_apb_if),
|
||||
apb4_pwm #(
|
||||
.PCLK_HZ(`SOC_EXT_CLK_HZ)
|
||||
) u_apb4_pwm (
|
||||
.debug_halted_i(debug_halted_i),
|
||||
.apb4 (u_pwm_apb_if),
|
||||
.pwm (pwm)
|
||||
);
|
||||
|
||||
|
||||
@@ -12,6 +12,45 @@
|
||||
`include "soc_clock_config.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 (
|
||||
`include "retrosoc_asic_ports.svh"
|
||||
);
|
||||
|
||||
@@ -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_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_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 apb_interfaces.count("apb4_if u_") == 10
|
||||
assert "apb4_pure_if u_archinfo_apb_pure_if ();" in apb_interfaces
|
||||
|
||||
Reference in new issue
Block a user