mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: add CLINT peripheral support and related enhancements
- Updated the formal file list generator to include CLINT source files. - Added CLINT timebase to the clock and reset domains configuration. - Enhanced the SOC topology generation to include CLINT interrupts and their mappings. - Introduced a new CLINT testbench to validate multi-hart and timebase functionality. - Modified the software build configuration to define CLINT timebase frequency. - Updated the RCU module to integrate CLINT timebase generation. - Adjusted the IRQ configuration to reflect changes in CLINT interrupt signals. - Added user-visible flags for interrupts in the topology configuration. - Enhanced the clock reset domain checks to include CLINT timebase. - Updated the memory map tests to validate CLINT peripheral integration.
This commit is contained in:
55 files changed
+1706
-956
No files matched your search
@@ -41,6 +41,8 @@ HAVE_SRAM_MACRO ?= NO
|
||||
PDK_BEHAV ?= NO
|
||||
HAVE_SVA ?= NO
|
||||
JTAG_IDCODE ?= DEADBEEF
|
||||
EXT_CLK_HZ ?= 72000000
|
||||
CLINT_TIMEBASE_HZ ?= 1000000
|
||||
WAVE ?= NO
|
||||
FORMAL ?= NO
|
||||
VCS_USE_LSF ?= YES
|
||||
@@ -80,7 +82,8 @@ JOBS ?= $(shell count=$$(nproc 2>/dev/null || printf '1'); \
|
||||
if [ "$$count" -gt "$(MAX_JOBS)" ]; then printf '%s' '$(MAX_JOBS)'; \
|
||||
else printf '%s' "$$count"; fi)
|
||||
CONFIG_KEY_VARS := SOC PDK HAVE_PLL HAVE_SRAM_IF HAVE_SRAM_MACRO PDK_BEHAV HAVE_SVA \
|
||||
JTAG_IDCODE ISA HAVE_CSR APP LINK_TYPE COREMARK_MODE RTL_TOP FIRMWARE_NAME
|
||||
JTAG_IDCODE EXT_CLK_HZ CLINT_TIMEBASE_HZ ISA HAVE_CSR APP LINK_TYPE \
|
||||
COREMARK_MODE RTL_TOP FIRMWARE_NAME
|
||||
VARIANT_ID := $(strip $(shell $(VCS_SHELL_PYTHON) $(ROOT_PATH)/scripts/config_key.py \
|
||||
--lock $(LOCK_FILE) --profile $(PROFILE_NAME) --timestamp $(BUILD_TIMESTAMP) \
|
||||
$(foreach var,$(CONFIG_KEY_VARS),--value $(var)=$($(var))) | tail -n 1))
|
||||
@@ -145,6 +148,20 @@ endif
|
||||
JTAG_IDCODE_DEC := $(shell value=$$(printf '%u' 0x$(JTAG_IDCODE)); \
|
||||
if [ $$value -gt 2147483647 ]; then echo $$((value - 4294967296)); else echo $$value; fi)
|
||||
|
||||
EXT_CLK_HZ_VALID := $(shell printf '%s' '$(EXT_CLK_HZ)' | grep -E '^[1-9][[:digit:]]*$$')
|
||||
ifneq ($(EXT_CLK_HZ_VALID),$(EXT_CLK_HZ))
|
||||
$(error EXT_CLK_HZ='$(EXT_CLK_HZ)' must be a positive integer)
|
||||
endif
|
||||
CLINT_TIMEBASE_HZ_VALID := $(shell printf '%s' '$(CLINT_TIMEBASE_HZ)' | grep -E '^[1-9][[:digit:]]*$$')
|
||||
ifneq ($(CLINT_TIMEBASE_HZ_VALID),$(CLINT_TIMEBASE_HZ))
|
||||
$(error CLINT_TIMEBASE_HZ='$(CLINT_TIMEBASE_HZ)' must be a positive integer)
|
||||
endif
|
||||
CLINT_TIMEBASE_RATIO_VALID := $(shell if [ '$(EXT_CLK_HZ)' -ge '$(CLINT_TIMEBASE_HZ)' ] && \
|
||||
[ $$(( $(EXT_CLK_HZ) % $(CLINT_TIMEBASE_HZ) )) -eq 0 ]; then printf YES; fi)
|
||||
ifneq ($(CLINT_TIMEBASE_RATIO_VALID),YES)
|
||||
$(error EXT_CLK_HZ must be an integer multiple of CLINT_TIMEBASE_HZ)
|
||||
endif
|
||||
|
||||
ifneq ($(filter benchmark-report,$(MAKECMDGOALS)),)
|
||||
ifneq ($(APP),benchmark)
|
||||
$(error benchmark-report requires APP=benchmark)
|
||||
@@ -178,6 +195,8 @@ endif
|
||||
DEF_LIST ?= +define+PDK_$(PDK)
|
||||
DEF_LIST += +define+SIMU_$(SIMU)
|
||||
DEF_LIST += +define+SOC_JTAG_IDCODE=$(JTAG_IDCODE_DEC)
|
||||
DEF_LIST += +define+SOC_EXT_CLK_HZ=$(EXT_CLK_HZ)
|
||||
DEF_LIST += +define+SOC_CLINT_TIMEBASE_HZ=$(CLINT_TIMEBASE_HZ)
|
||||
|
||||
ifeq ($(HAVE_PLL), YES)
|
||||
ifneq ($(filter $(PDK),GF180 SKY130),)
|
||||
@@ -261,7 +280,7 @@ help:
|
||||
' check-clock-reset-domains validate the root clock/reset and CDC inventory' \
|
||||
' rtl-lint | check-rtl-lint run/check strict Verilator RTL lint warnings' \
|
||||
' formal | formal-bus | formal-rib-adapter | formal-rib2apb run SBY protocol proofs' \
|
||||
' formal-sysctrl | formal-pll-rcu | formal-gpio-user | formal-ws2812 | formal-timer run peripheral proofs' \
|
||||
' formal-sysctrl | formal-pll-rcu | formal-gpio-user | formal-ws2812 | formal-timer | formal-clint run peripheral proofs' \
|
||||
' formal-doctor check the SBY, Yosys, sv2v, and Bitwuzla formal toolchain' \
|
||||
' benchmark-report run the memory/DMA profile and write meta/performance.json' \
|
||||
' coremark-report run the quick CoreMark profile and write meta/coremark.json' \
|
||||
@@ -294,7 +313,8 @@ config:
|
||||
VCS_USE_LSF '$(VCS_USE_LSF)' PDK '$(PDK)' \
|
||||
HAVE_PLL '$(HAVE_PLL)' HAVE_SRAM_IF '$(HAVE_SRAM_IF)' \
|
||||
HAVE_SRAM_MACRO '$(HAVE_SRAM_MACRO)' PDK_BEHAV '$(PDK_BEHAV)' HAVE_SVA '$(HAVE_SVA)' \
|
||||
JTAG_IDCODE '$(JTAG_IDCODE)' \
|
||||
JTAG_IDCODE '$(JTAG_IDCODE)' EXT_CLK_HZ '$(EXT_CLK_HZ)' \
|
||||
CLINT_TIMEBASE_HZ '$(CLINT_TIMEBASE_HZ)' \
|
||||
ISA '$(ISA)' HAVE_CSR '$(HAVE_CSR)' APP '$(APP)' \
|
||||
LINK_TYPE '$(LINK_TYPE)' COREMARK_MODE '$(COREMARK_MODE)'
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <retrosoc/core/soc.h>
|
||||
#include <retrosoc/hal/clint.h>
|
||||
#include <retrosoc/hal/timer.h>
|
||||
#include <retrosoc/hal/uart.h>
|
||||
#include <retrosoc/lib/printf.h>
|
||||
@@ -13,6 +14,34 @@ static bool rs_ci_smoke_archinfo_matches_reset_values(void) {
|
||||
(archinfo_idh == UINT32_C(0x00FFFFFF));
|
||||
}
|
||||
|
||||
static bool rs_ci_smoke_clint_standard_map(void) {
|
||||
uint64_t first;
|
||||
uint64_t current;
|
||||
uint64_t compare;
|
||||
bool pending;
|
||||
|
||||
if (rs_clint_get_time(&first) != RS_OK) {
|
||||
return false;
|
||||
}
|
||||
current = first;
|
||||
for (rs_timeout_t timeout = 512U; (timeout != 0U) && (current == first); --timeout) {
|
||||
if (rs_clint_get_time(¤t) != RS_OK) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((current <= first) || (rs_clint_set_compare(0U, current + UINT64_C(1000)) != RS_OK) ||
|
||||
(rs_clint_get_compare(0U, &compare) != RS_OK) || (compare != (current + UINT64_C(1000)))) {
|
||||
return false;
|
||||
}
|
||||
if ((rs_clint_set_software_interrupt(0U, true) != RS_OK) ||
|
||||
(rs_clint_get_software_interrupt(0U, &pending) != RS_OK) || !pending ||
|
||||
(rs_clint_set_software_interrupt(0U, false) != RS_OK) ||
|
||||
(rs_clint_get_software_interrupt(0U, &pending) != RS_OK) || pending) {
|
||||
return false;
|
||||
}
|
||||
return rs_clint_set_compare(0U, UINT64_MAX) == RS_OK;
|
||||
}
|
||||
|
||||
static bool rs_ci_smoke_timer_one_shot(void) {
|
||||
const rs_timer_config_t config = {
|
||||
.mode = RS_TIMER_MODE_ONE_SHOT,
|
||||
@@ -88,14 +117,17 @@ int main(void) {
|
||||
if (!rs_ci_smoke_archinfo_matches_reset_values()) {
|
||||
rs_test_finish(RS_TEST_FAILED, 1U);
|
||||
}
|
||||
if (!rs_ci_smoke_timer_one_shot()) {
|
||||
if (!rs_ci_smoke_clint_standard_map()) {
|
||||
rs_test_finish(RS_TEST_FAILED, 2U);
|
||||
}
|
||||
if (!rs_ci_smoke_timer_periodic()) {
|
||||
if (!rs_ci_smoke_timer_one_shot()) {
|
||||
rs_test_finish(RS_TEST_FAILED, 3U);
|
||||
}
|
||||
if (!rs_ci_smoke_timer_periodic()) {
|
||||
rs_test_finish(RS_TEST_FAILED, 4U);
|
||||
}
|
||||
|
||||
printf("ci_smoke: archinfo and timer tests passed\n");
|
||||
printf("ci_smoke: archinfo, CLINT, and timer tests passed\n");
|
||||
rs_test_finish(RS_TEST_PASSED, 0U);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
PDK_BEHAV := YES
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := YES
|
||||
APP := coremark
|
||||
COREMARK_MODE := standard
|
||||
LINK_TYPE := ld2_all_sram
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
PDK_BEHAV := YES
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := YES
|
||||
APP := coremark
|
||||
COREMARK_MODE := standard
|
||||
LINK_TYPE := ld2_all_sram
|
||||
@@ -1,12 +1,14 @@
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
PDK_BEHAV := YES
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := YES
|
||||
APP := coremark
|
||||
COREMARK_MODE := quick
|
||||
LINK_TYPE := ld2_all_sram
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
PDK_BEHAV := YES
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := YES
|
||||
APP := coremark
|
||||
COREMARK_MODE := quick
|
||||
LINK_TYPE := ld2_all_sram
|
||||
@@ -1,11 +1,13 @@
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
PDK_BEHAV := YES
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := benchmark
|
||||
LINK_TYPE := ld2_sram
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
PDK_BEHAV := YES
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := benchmark
|
||||
LINK_TYPE := ld2_sram
|
||||
+12
-10
@@ -1,10 +1,12 @@
|
||||
SOC := MINI
|
||||
PDK := GF180
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
SOC := MINI
|
||||
PDK := GF180
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
+12
-10
@@ -1,10 +1,12 @@
|
||||
SOC := MINI
|
||||
PDK := ICS55
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
SOC := MINI
|
||||
PDK := ICS55
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
+14
-12
@@ -1,12 +1,14 @@
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
PDK_BEHAV := YES
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := debug
|
||||
FIRMWARE_NAME := retrosoc_debug
|
||||
LINK_TYPE := ld2_sram
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
PDK_BEHAV := YES
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := debug
|
||||
FIRMWARE_NAME := retrosoc_debug
|
||||
LINK_TYPE := ld2_sram
|
||||
+12
-10
@@ -1,10 +1,12 @@
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := YES
|
||||
APP := shell
|
||||
LINK_TYPE := ld2_psram
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := YES
|
||||
APP := shell
|
||||
LINK_TYPE := ld2_psram
|
||||
+12
-10
@@ -1,10 +1,12 @@
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
SOC := MINI
|
||||
PDK := IHP130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
+12
-10
@@ -1,10 +1,12 @@
|
||||
SOC := MINI
|
||||
PDK := SKY130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
SOC := MINI
|
||||
PDK := SKY130
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
+12
-10
@@ -1,10 +1,12 @@
|
||||
SOC := MINI
|
||||
PDK := ICS55
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
SOC := MINI
|
||||
PDK := ICS55
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := NO
|
||||
HAVE_SRAM_MACRO := NO
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 72000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := NO
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_psram
|
||||
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// -- 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 __SYSTEM_TIMER_H__
|
||||
#define __SYSTEM_TIMER_H__
|
||||
|
||||
#include <retrosoc/arch/riscv/system_gcc.h>
|
||||
#include <retrosoc/arch/riscv/system_base.h>
|
||||
|
||||
typedef struct {
|
||||
__IOM uint64_t mtime;
|
||||
__IOM uint64_t mtimecmp;
|
||||
__IOM uint32_t msip;
|
||||
__IOM uint32_t clkdiv;
|
||||
} SysTimer_Type;
|
||||
|
||||
/* Timer Control / Status Register Definitions */
|
||||
#define SysTimer_MSIP_MSIP_POS 0U /*!< SysTick Timer msip: msip bit Position */
|
||||
#define SysTimer_MSIP_MSIP_MASK \
|
||||
(1UL << SysTimer_MSIP_MSIP_POS) /*!< SysTick Timer msip: msip Mask */
|
||||
|
||||
#define SysTimer_MTIMER_MASK (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMER value Mask */
|
||||
#define SysTimer_MTIMERCMP_MASK (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMERCMP value Mask */
|
||||
#define SysTimer_MSIP_MASK (0xFFFFFFFFUL) /*!< SysTick Timer msip value Mask */
|
||||
|
||||
#define __SYSTIMER_BASEADDR 0x1000C000
|
||||
#ifndef __SYSTIMER_BASEADDR
|
||||
/* Base address of SYSTIMER(__SYSTIMER_BASEADDR) should be defined in <Device.h> */
|
||||
#error "__SYSTIMER_BASEADDR is not defined, please check!"
|
||||
#endif
|
||||
/* System Timer Memory mapping of Device */
|
||||
#define SysTimer_BASE __SYSTIMER_BASEADDR /*!< SysTick Base Address */
|
||||
#define SysTimer ((SysTimer_Type *)SysTimer_BASE) /*!< SysTick configuration struct */
|
||||
|
||||
/**
|
||||
* \defgroup NMSIS_Core_SysTimer SysTimer Functions
|
||||
* \brief Functions that configure the Core System Timer.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief Set system timer load value
|
||||
* \details
|
||||
* This function set the system timer load value in MTIMER register.
|
||||
* \param [in] value value to set system timer MTIMER register.
|
||||
* \remarks
|
||||
* - Load value is 64bits wide.
|
||||
* - \ref SysTimer_GetLoadValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetMtimeValue(uint64_t value) {
|
||||
SysTimer->mtime = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get system timer load value
|
||||
* \details
|
||||
* This function get the system timer current value in MTIMER register.
|
||||
* \return current value(64bit) of system timer MTIMER register.
|
||||
* \remarks
|
||||
* - Load value is 64bits wide.
|
||||
* - \ref SysTimer_SetLoadValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint64_t SysTimer_GetMtimeValue(void) {
|
||||
return SysTimer->mtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set system timer compare value
|
||||
* \details
|
||||
* This function set the system Timer compare value in MTIMERCMP register.
|
||||
* \param [in] value compare value to set system timer MTIMERCMP register.
|
||||
* \remarks
|
||||
* - Compare value is 64bits wide.
|
||||
* - If compare value is larger than current value timer interrupt generate.
|
||||
* - Modify the load value or compare value less to clear the interrupt.
|
||||
* - \ref SysTimer_GetCompareValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetMtimecmpValue(uint64_t value) {
|
||||
SysTimer->mtimecmp = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get system timer compare value
|
||||
* \details
|
||||
* This function get the system timer compare value in MTIMERCMP register.
|
||||
* \return compare value of system timer MTIMERCMP register.
|
||||
* \remarks
|
||||
* - Compare value is 64bits wide.
|
||||
* - \ref SysTimer_SetCompareValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint64_t SysTimer_GetMtimecmpValue(void) {
|
||||
return SysTimer->mtimecmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Trigger or set software interrupt via system timer
|
||||
* \details
|
||||
* This function set the system timer MSIP bit in MSIP register.
|
||||
* \remarks
|
||||
* - Set system timer MSIP bit and generate a SW interrupt.
|
||||
* - \ref SysTimer_ClearSWIRQ
|
||||
* - \ref SysTimer_GetMsipValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetSoftwareIRQ(void) {
|
||||
SysTimer->msip |= SysTimer_MSIP_MSIP_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear system timer software interrupt pending request
|
||||
* \details
|
||||
* This function clear the system timer MSIP bit in MSIP register.
|
||||
* \remarks
|
||||
* - Clear system timer MSIP bit in MSIP register to clear the software interrupt pending.
|
||||
* - \ref SysTimer_SetSWIRQ
|
||||
* - \ref SysTimer_GetMsipValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_ClearSoftwareIRQ(void) {
|
||||
SysTimer->msip &= ~SysTimer_MSIP_MSIP_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get system timer MSIP register value
|
||||
* \details
|
||||
* This function get the system timer MSIP register value.
|
||||
* \return Value of Timer MSIP register.
|
||||
* \remarks
|
||||
* - Bit0 is SW interrupt flag.
|
||||
* Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear.
|
||||
* - \ref SysTimer_SetSWIRQ
|
||||
* - \ref SysTimer_ClearSWIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t SysTimer_GetMsipValue(void) {
|
||||
return (uint32_t)(SysTimer->msip & SysTimer_MSIP_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set system timer MSIP register value
|
||||
* \details
|
||||
* This function set the system timer MSIP register value.
|
||||
* \param [in] msip value to set MSIP register
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetMsipValue(uint32_t msip) {
|
||||
SysTimer->msip = (msip & SysTimer_MSIP_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief System Tick Configuration
|
||||
* \details Initializes the System Timer and its non-vector interrupt, and starts the System Tick
|
||||
* Timer.
|
||||
*
|
||||
* In our default implementation, the timer counter will be set to zero, and it will start a timer
|
||||
* compare non-vector interrupt when it matchs the ticks user set, during the timer interrupt user
|
||||
* should reload the system tick using \ref SysTick_Reload function or similar function written by
|
||||
* user, so it can produce period timer interrupt. \param [in] ticks Number of ticks between two
|
||||
* interrupts. \return 0 Function succeeded. \return 1 Function failed. \sa
|
||||
* - \ref SysTimer_SetCompareValue; SysTimer_SetLoadValue
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks) {
|
||||
SysTimer_SetMtimeValue(0);
|
||||
SysTimer_SetMtimecmpValue(ticks);
|
||||
__enable_timer_irq();
|
||||
return (0UL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief System Tick Reload
|
||||
* \details Reload the System Timer Tick when the MTIMECMP reached TIME value
|
||||
*
|
||||
* \param [in] ticks Number of ticks between two interrupts.
|
||||
* \return 0 Function succeeded.
|
||||
* \return 1 Function failed.
|
||||
* \sa
|
||||
* - \ref SysTimer_SetCompareValue
|
||||
* - \ref SysTimer_SetLoadValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t SysTick_Reload(uint64_t ticks) {
|
||||
uint64_t cur_ticks = SysTimer->mtime;
|
||||
uint64_t reload_ticks = ticks + cur_ticks;
|
||||
|
||||
if (__USUALLY(reload_ticks > cur_ticks)) {
|
||||
SysTimer->mtimecmp = reload_ticks;
|
||||
} else {
|
||||
/* When added the ticks value, then the MTIMERCMP < TIMER,
|
||||
* which means the MTIMERCMP is overflowed,
|
||||
* so we need to reset the counter to zero */
|
||||
SysTimer->mtime = 0;
|
||||
SysTimer->mtimecmp = ticks;
|
||||
}
|
||||
|
||||
return (0UL);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -204,13 +204,6 @@
|
||||
#define RS_SOC_PERF_CTRL_ENABLE UINT32_C(0x00000001)
|
||||
#define RS_SOC_PERF_CTRL_CLEAR UINT32_C(0x00000002)
|
||||
#define RS_SOC_PERF_CTRL_SNAPSHOT UINT32_C(0x00000004)
|
||||
// clint
|
||||
#define reg_clint_mtimel RS_SOC_REG32(RS_SOC_RIBP_CLINT_BASE, UINT32_C(0x00))
|
||||
#define reg_clint_mtimeh RS_SOC_REG32(RS_SOC_RIBP_CLINT_BASE, UINT32_C(0x04))
|
||||
#define reg_clint_mtimecmpl RS_SOC_REG32(RS_SOC_RIBP_CLINT_BASE, UINT32_C(0x08))
|
||||
#define reg_clint_mtimecmph RS_SOC_REG32(RS_SOC_RIBP_CLINT_BASE, UINT32_C(0x0C))
|
||||
#define reg_clint_msip RS_SOC_REG32(RS_SOC_RIBP_CLINT_BASE, UINT32_C(0x10))
|
||||
#define reg_clint_clkdiv RS_SOC_REG32(RS_SOC_RIBP_CLINT_BASE, UINT32_C(0x14))
|
||||
// sdram
|
||||
#define reg_sdram_clkdiv RS_SOC_REG32(RS_SOC_RIBP_SDRAM_BASE, UINT32_C(0x00))
|
||||
#define reg_sdram_cfg RS_SOC_REG32(RS_SOC_RIBP_SDRAM_BASE, UINT32_C(0x04))
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef RETROSOC_HAL_CLINT_H
|
||||
#define RETROSOC_HAL_CLINT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <retrosoc/core/status.h>
|
||||
|
||||
#define RS_CLINT_HART_COUNT UINT32_C(1)
|
||||
|
||||
#ifndef RS_CLINT_TIMEBASE_HZ
|
||||
#define RS_CLINT_TIMEBASE_HZ UINT32_C(1000000)
|
||||
#endif
|
||||
|
||||
rs_status_t rs_clint_get_time(uint64_t *time);
|
||||
rs_status_t rs_clint_set_time(uint64_t time);
|
||||
rs_status_t rs_clint_get_compare(uint32_t hart, uint64_t *compare);
|
||||
rs_status_t rs_clint_set_compare(uint32_t hart, uint64_t compare);
|
||||
rs_status_t rs_clint_get_software_interrupt(uint32_t hart, bool *pending);
|
||||
rs_status_t rs_clint_set_software_interrupt(uint32_t hart, bool pending);
|
||||
|
||||
#endif
|
||||
+16
-8
@@ -1,11 +1,11 @@
|
||||
#include <retrosoc/arch/riscv/system_base.h>
|
||||
#include <retrosoc/arch/riscv/system_csr.h>
|
||||
#include <retrosoc/arch/riscv/system_timer.h>
|
||||
#include <retrosoc/core/irq.h>
|
||||
#include <retrosoc/hal/clint.h>
|
||||
#include <retrosoc/hal/timer.h>
|
||||
#include <retrosoc/lib/printf.h>
|
||||
|
||||
#define RS_TIMER_DELTA_VALUE 360000UL
|
||||
#define RS_TIMER_DELTA_VALUE (RS_CLINT_TIMEBASE_HZ / UINT32_C(200))
|
||||
#define RS_IRQ_TEST_TIMEOUT_MS 6000U
|
||||
|
||||
static volatile uint32_t timer_irq_count;
|
||||
@@ -18,14 +18,15 @@ static void rs_timer_irq_handler(uintptr_t mcause, uintptr_t stack_pointer) {
|
||||
(void)mcause;
|
||||
(void)stack_pointer;
|
||||
++timer_irq_count;
|
||||
now = SysTimer_GetMtimeValue();
|
||||
SysTimer_SetMtimecmpValue(now + RS_TIMER_DELTA_VALUE);
|
||||
if (rs_clint_get_time(&now) == RS_OK) {
|
||||
(void)rs_clint_set_compare(0U, now + RS_TIMER_DELTA_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void rs_software_irq_handler(uintptr_t mcause, uintptr_t stack_pointer) {
|
||||
(void)mcause;
|
||||
(void)stack_pointer;
|
||||
SysTimer_ClearSoftwareIRQ();
|
||||
(void)rs_clint_set_software_interrupt(0U, false);
|
||||
++software_irq_count;
|
||||
software_irq_ready = 1U;
|
||||
}
|
||||
@@ -56,8 +57,12 @@ void irq_test(int argc, char **argv) {
|
||||
return;
|
||||
}
|
||||
__enable_irq();
|
||||
now = SysTimer_GetMtimeValue();
|
||||
SysTimer_SetMtimecmpValue(now + RS_TIMER_DELTA_VALUE);
|
||||
if ((rs_clint_get_time(&now) != RS_OK) ||
|
||||
(rs_clint_set_compare(0U, now + RS_TIMER_DELTA_VALUE) != RS_OK)) {
|
||||
printf("unable to configure machine timer\n");
|
||||
__disable_core_irq(IRQ_M_TIMER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rs_irq_wait_for_count(&timer_irq_count, 6U) != RS_OK) {
|
||||
printf("timer irq timed out\n");
|
||||
@@ -76,7 +81,10 @@ void irq_test(int argc, char **argv) {
|
||||
return;
|
||||
}
|
||||
software_irq_ready = 0U;
|
||||
SysTimer_SetSoftwareIRQ();
|
||||
if (rs_clint_set_software_interrupt(0U, true) != RS_OK) {
|
||||
printf("unable to trigger software irq\n");
|
||||
return;
|
||||
}
|
||||
if (rs_irq_wait_for_count(&software_irq_count, attempt + 1U) != RS_OK) {
|
||||
printf("software irq timed out\n");
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include <retrosoc/core/soc.h>
|
||||
#include <retrosoc/hal/clint.h>
|
||||
|
||||
#define RS_CLINT_MSIP_OFFSET UINT32_C(0x0000)
|
||||
#define RS_CLINT_MTIMECMP_OFFSET UINT32_C(0x4000)
|
||||
#define RS_CLINT_MTIME_OFFSET UINT32_C(0xBFF8)
|
||||
#define RS_CLINT_MSIP_STRIDE UINT32_C(4)
|
||||
#define RS_CLINT_MTIMECMP_STRIDE UINT32_C(8)
|
||||
#define RS_CLINT_HIGH_WORD_OFFSET UINT32_C(4)
|
||||
#define RS_CLINT_SNAPSHOT_ATTEMPTS UINT32_C(4)
|
||||
#define RS_CLINT_SOFTWARE_IRQ_PENDING UINT32_C(1)
|
||||
|
||||
static volatile uint32_t *rs_clint_register(uint32_t offset) {
|
||||
return (volatile uint32_t *)(uintptr_t)(RS_SOC_RIBP_CLINT_BASE + offset);
|
||||
}
|
||||
|
||||
static bool rs_clint_hart_valid(uint32_t hart) {
|
||||
return hart < RS_CLINT_HART_COUNT;
|
||||
}
|
||||
|
||||
static rs_status_t rs_clint_read64(uint32_t offset, uint64_t *value) {
|
||||
uint32_t high_before;
|
||||
uint32_t low;
|
||||
uint32_t high_after;
|
||||
|
||||
if (value == NULL) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
for (uint32_t attempt = 0U; attempt < RS_CLINT_SNAPSHOT_ATTEMPTS; ++attempt) {
|
||||
high_before = *rs_clint_register(offset + RS_CLINT_HIGH_WORD_OFFSET);
|
||||
low = *rs_clint_register(offset);
|
||||
high_after = *rs_clint_register(offset + RS_CLINT_HIGH_WORD_OFFSET);
|
||||
if (high_before == high_after) {
|
||||
*value = ((uint64_t)high_after << 32U) | (uint64_t)low;
|
||||
return RS_OK;
|
||||
}
|
||||
}
|
||||
return RS_ETIMEOUT;
|
||||
}
|
||||
|
||||
rs_status_t rs_clint_get_time(uint64_t *time) {
|
||||
return rs_clint_read64(RS_CLINT_MTIME_OFFSET, time);
|
||||
}
|
||||
|
||||
rs_status_t rs_clint_set_time(uint64_t time) {
|
||||
*rs_clint_register(RS_CLINT_MTIME_OFFSET + RS_CLINT_HIGH_WORD_OFFSET) = (uint32_t)(time >> 32U);
|
||||
*rs_clint_register(RS_CLINT_MTIME_OFFSET) = (uint32_t)time;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_clint_get_compare(uint32_t hart, uint64_t *compare) {
|
||||
if (!rs_clint_hart_valid(hart)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
return rs_clint_read64(RS_CLINT_MTIMECMP_OFFSET + (hart * RS_CLINT_MTIMECMP_STRIDE), compare);
|
||||
}
|
||||
|
||||
rs_status_t rs_clint_set_compare(uint32_t hart, uint64_t compare) {
|
||||
uint32_t offset;
|
||||
|
||||
if (!rs_clint_hart_valid(hart)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
offset = RS_CLINT_MTIMECMP_OFFSET + (hart * RS_CLINT_MTIMECMP_STRIDE);
|
||||
*rs_clint_register(offset) = UINT32_MAX;
|
||||
*rs_clint_register(offset + RS_CLINT_HIGH_WORD_OFFSET) = (uint32_t)(compare >> 32U);
|
||||
*rs_clint_register(offset) = (uint32_t)compare;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_clint_get_software_interrupt(uint32_t hart, bool *pending) {
|
||||
uint32_t offset;
|
||||
|
||||
if (!rs_clint_hart_valid(hart) || (pending == NULL)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
offset = RS_CLINT_MSIP_OFFSET + (hart * RS_CLINT_MSIP_STRIDE);
|
||||
*pending = (*rs_clint_register(offset) & RS_CLINT_SOFTWARE_IRQ_PENDING) != 0U;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_clint_set_software_interrupt(uint32_t hart, bool pending) {
|
||||
uint32_t offset;
|
||||
|
||||
if (!rs_clint_hart_valid(hart)) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
offset = RS_CLINT_MSIP_OFFSET + (hart * RS_CLINT_MSIP_STRIDE);
|
||||
*rs_clint_register(offset) = pending ? RS_CLINT_SOFTWARE_IRQ_PENDING : 0U;
|
||||
return RS_OK;
|
||||
}
|
||||
@@ -107,7 +107,8 @@ void rs_app_info(void) {
|
||||
printf(" 1 x XPI @%p\n", (void *)®_xpi_cfgidx);
|
||||
printf(" 1 x DMA @%p\n", (void *)®_dma_mode);
|
||||
printf(" 1 x SYSCTRL @%p\n", (void *)®_sysctrl_coresel);
|
||||
printf(" 1 x CLINT @%p\n", (void *)®_clint_mtimel);
|
||||
printf(" 1 x CLINT @%p\n",
|
||||
(void *)(uintptr_t)RS_SOC_RIBP_CLINT_BASE);
|
||||
printf(" 1 x SDRAM @%p\n", (void *)®_sdram_clkdiv);
|
||||
printf(" 1 x DVP @%p\n", (void *)®_dvp_recven);
|
||||
printf(" 1 x I2C1 @%p\n", (void *)®_i2c1_clkdiv);
|
||||
|
||||
+4
-5
@@ -16,17 +16,16 @@ the root README and subsystem guides.
|
||||
- [coremark.md](coremark.md) defines the SRAM-resident Hazard3 CoreMark quick
|
||||
measurement, optional standard hardware run, and structured result format.
|
||||
- [soc-family-positioning.md](soc-family-positioning.md) defines the planned
|
||||
Tiny, Mini, Std, and Pro product ladder, target capabilities, claim gates,
|
||||
and commercial reference points.
|
||||
- [mini-product-positioning.md](mini-product-positioning.md) separates the
|
||||
implemented Mini baseline from the planned VexiiRiscv Linux product target
|
||||
and its commercial reference points.
|
||||
Tiny, Mini, Std, and Pro product ladder, the implemented Mini baseline,
|
||||
planned product targets, claim gates, and commercial reference points.
|
||||
- [rib-interconnect.md](rib-interconnect.md) defines the RIB v1 linear-burst
|
||||
contract, compatibility boundaries, target status, and verification.
|
||||
- [ip/ws2812.md](ip/ws2812.md) defines the WS2812 transmitter register ABI,
|
||||
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.
|
||||
- [ip/clint.md](ip/clint.md) defines the standard CLINT register map, fixed
|
||||
timebase, RV32 access rules, interrupt behavior, and verification contract.
|
||||
- [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
|
||||
|
||||
@@ -5,6 +5,7 @@ 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.
|
||||
- [clint.md](clint.md) defines the management-hart software and timer interrupt block.
|
||||
|
||||
The corresponding RTL and HAL implementations remain the executable sources
|
||||
of truth. Update the affected document whenever an IP interface or register ABI
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# Core-Local Interruptor
|
||||
|
||||
The Mini SoC CLINT provides machine software and machine timer interrupts for
|
||||
the management hart. Its register layout follows the conventional SiFive
|
||||
CLINT and RISC-V ACLINT-compatible offsets, while its bus-facing logic uses the
|
||||
retroSoC RIBP target protocol.
|
||||
|
||||
## Integration
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| RIBP base address | `0x10020000` |
|
||||
| RIBP aperture | 64 KiB |
|
||||
| Implemented Mini SoC harts | 1 management hart |
|
||||
| RTL hart parameter range | 1 through 4095 |
|
||||
| Timebase frequency | 1 MHz |
|
||||
| Management-core interrupts | software IRQ 0, timer IRQ 1 |
|
||||
| User-core access | denied by the RIB access policy |
|
||||
| User-core interrupt visibility | masked |
|
||||
|
||||
The timebase divider runs from the buffered external reference clock, not the
|
||||
PLL-selected system clock. A toggle crosses into the system domain through the
|
||||
Common `edge_det` synchronizer and produces one system-clock pulse per
|
||||
microsecond. Consequently, changing the PLL frequency does not change the
|
||||
meaning of an `mtime` tick. `EXT_CLK_HZ` must be an integer multiple of
|
||||
`CLINT_TIMEBASE_HZ`; committed profiles use 72 MHz and 1 MHz respectively.
|
||||
|
||||
## Register ABI
|
||||
|
||||
All implemented registers are 32-bit aligned RIBP accesses. Unmapped,
|
||||
unimplemented-hart, and unaligned accesses complete with `resp_err` and read as
|
||||
zero. Partial writes use byte strobes. The Mini SoC implements hart 0; the RTL
|
||||
array dimensions and address decoder are parameterized for additional harts.
|
||||
|
||||
| Offset | Name | Access | Reset | Description |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `0x0000 + 4 * hart` | `MSIP` | RW | 0 | Bit 0 controls the hart machine software interrupt. |
|
||||
| `0x4000 + 8 * hart` | `MTIMECMP_LO` | RW | all ones | Low half of the 64-bit timer comparison value. |
|
||||
| `0x4004 + 8 * hart` | `MTIMECMP_HI` | RW | all ones | High half of the 64-bit timer comparison value. |
|
||||
| `0xBFF8` | `MTIME_LO` | RW | 0 | Low half of the shared 64-bit time counter. |
|
||||
| `0xBFFC` | `MTIME_HI` | RW | 0 | High half of the shared 64-bit time counter. |
|
||||
|
||||
The timer interrupt for hart `n` is asserted when `mtime >= mtimecmp[n]` and is
|
||||
deasserted after software moves the comparison into the future. The registered
|
||||
interrupt output adds one system-clock cycle of latency. Resetting
|
||||
`mtimecmp` to all ones prevents an unintended interrupt at reset.
|
||||
|
||||
## RV32 Software Contract
|
||||
|
||||
The public `<retrosoc/hal/clint.h>` API avoids C 64-bit volatile accesses,
|
||||
which are not atomic on RV32. Time and comparison reads use a bounded
|
||||
high-low-high sequence and retry if the high word rolls over. Comparison
|
||||
writes use the recommended low-all-ones, high, low sequence so an intermediate
|
||||
value cannot spuriously assert the timer interrupt.
|
||||
|
||||
Writing `mtime` itself is inherently non-atomic on a 32-bit bus. Software that
|
||||
changes it must first prevent concurrent timer handling and account for the
|
||||
global discontinuity. Normal scheduling code should leave `mtime` running and
|
||||
only update `mtimecmp`.
|
||||
|
||||
## Verification and Current Scope
|
||||
|
||||
The self-checking RTL test instantiates two harts and covers reset values,
|
||||
standard offsets, independent software interrupts, timer comparison, `mtime`
|
||||
writes, byte strobes, invalid accesses, and synchronized reference-clock
|
||||
ticks. The SBY target proves bounded RIBP response, `mtime` load/tick/hold
|
||||
priority, registered timer interrupt behavior, and reaches software interrupt,
|
||||
timer interrupt, write-time, and error paths. The `ci_smoke` firmware checks
|
||||
the standard map through the public HAL before completing the normal SoC boot
|
||||
test.
|
||||
|
||||
The current Mini integration does not implement supervisor timer comparison,
|
||||
multiple privilege domains, or per-hart access filtering inside CLINT. Adding
|
||||
those features should use the RISC-V ACLINT MTIMER and MSWI split-device model
|
||||
and a versioned SoC integration update.
|
||||
|
||||
The register layout and machine interrupt behavior follow the RISC-V
|
||||
[machine timer requirements](https://docs.riscv.org/reference/isa/priv/machine.html),
|
||||
the conventional [SiFive E31 CLINT map](https://starfivetech.com/uploads/e31_core_complex_manual_21G1.pdf),
|
||||
and the [RISC-V ACLINT specification](https://github.com/riscvarchive/riscv-aclint/blob/main/riscv-aclint.adoc).
|
||||
@@ -1,126 +0,0 @@
|
||||
# retroSoC Mini Product Positioning
|
||||
|
||||
## Status
|
||||
|
||||
retroSoC Mini is currently an open-source RISC-V microcontroller-class SoC
|
||||
with a fixed Hazard3 management core and one software-selected user core. This
|
||||
document also defines a planned Linux-capable configuration built around a
|
||||
32-bit VexiiRiscv user core. The VexiiRiscv integration and Linux boot flow are
|
||||
product targets, not supported repository configurations yet.
|
||||
|
||||
Mini is the price, complexity, and Linux-capability anchor for the planned
|
||||
[retroSoC product family](soc-family-positioning.md). Tiny removes the Linux
|
||||
and external-DRAM requirements for low-power MCU use, while Std adds RV32
|
||||
performance and efficiency cores, full AXI4 memory transport, and graphical
|
||||
and AI acceleration. Pro is the only planned RV64 tier.
|
||||
|
||||
The target product position is a low-cost, heterogeneous, 32-bit RISC-V Linux
|
||||
control SoC for embedded control, compact human-machine interfaces, gateways,
|
||||
and retro multimedia systems. It is not intended to compete with general-purpose
|
||||
Linux application processors that require RV64, cache-coherent multiprocessing,
|
||||
or high-bandwidth DDR interfaces.
|
||||
|
||||
## Current Mini Baseline
|
||||
|
||||
The current executable RTL and generated integration inputs define these
|
||||
capabilities:
|
||||
|
||||
- A fixed Hazard3 management core owns system control and has a permanent JTAG
|
||||
Debug Module.
|
||||
- The C0-C5 extension fabric permits one selected user core to run at a time.
|
||||
- SYSCTRL controls user-core selection, reset, interrupt admission, and bus
|
||||
admission. A stop request blocks new user transactions, drains an accepted
|
||||
transaction, and then asserts reset.
|
||||
- The canonical address map exposes 128 KiB of on-chip SRAM, a 32 MiB SDRAM
|
||||
window, and an 8 MiB PSRAM window. Address-window capacity does not guarantee
|
||||
that every implementation includes the corresponding physical memory.
|
||||
- RIB v1 is a 32-bit interconnect with `INCR1` and aligned four-word `INCR4`
|
||||
transfers and one outstanding transaction per master.
|
||||
- Current external-memory targets serialize an accepted RIB burst into ordered
|
||||
scalar RIBP accesses. They do not yet combine an `INCR4` request into a native
|
||||
SDRAM, PSRAM, or flash streaming transaction.
|
||||
|
||||
The generated address map, user-extension map, and
|
||||
[RIB protocol contract](rib-interconnect.md) remain the executable sources of
|
||||
truth for the implemented baseline.
|
||||
|
||||
## Planned Linux Configuration
|
||||
|
||||
The Linux configuration keeps Hazard3 as the always-available trusted
|
||||
management core and adds VexiiRiscv as the application processor. Hazard3 is
|
||||
responsible for clock and memory initialization, image selection, VexiiRiscv
|
||||
boot release, fault recovery, and final power-state control. Linux must not be
|
||||
able to reconfigure the management-core lifecycle controls.
|
||||
|
||||
The initial VexiiRiscv configuration should provide:
|
||||
|
||||
- RV32IMAC with machine, supervisor, and user modes.
|
||||
- Sv32 virtual memory, hardware page-table walking, and the privileged CSRs
|
||||
required by the supported Linux kernel.
|
||||
- LR/SC atomics, separate 16 KiB instruction and data caches, and uncached MMIO
|
||||
regions.
|
||||
- A PLIC-compatible external interrupt controller, CLINT-compatible timer and
|
||||
software interrupts, and a deterministic reset vector.
|
||||
- A documented DMA cache-maintenance contract unless the memory system supplies
|
||||
hardware coherency.
|
||||
|
||||
The management firmware initializes external memory, verifies and places the
|
||||
OpenSBI firmware, device tree, kernel, and initial filesystem, programs the
|
||||
VexiiRiscv entry point, and then enables its bus access and releases reset. A
|
||||
normal stop first requests Linux shutdown through a mailbox. After Linux
|
||||
acknowledges and flushes persistent data, the management core disables new bus
|
||||
transactions, drains the final accepted transaction, and asserts reset. A
|
||||
bounded timeout permits fault recovery through forced isolation and reset.
|
||||
|
||||
## Product Targets
|
||||
|
||||
The following values define a useful commercial target rather than an
|
||||
implemented or cross-PDK guarantee:
|
||||
|
||||
| Area | Minimum target | Preferred target |
|
||||
| --- | --- | --- |
|
||||
| VexiiRiscv frequency | 150 MHz | PDK-qualified maximum above 150 MHz |
|
||||
| Main memory | 64 MiB SDRAM | 128 MiB SDRAM |
|
||||
| L1 caches | 16 KiB I-cache and 16 KiB D-cache | Same, with measured refill and DMA behavior |
|
||||
| Memory transport | Native cache-line burst | Native burst with two to four outstanding transactions per master |
|
||||
| Boot storage | SPI NAND or qualified SDIO path | SDIO/eMMC plus recovery image |
|
||||
| Linux platform devices | UART, timer, interrupt controller, storage | Ethernet or USB selected by the product profile |
|
||||
|
||||
Meeting these targets requires enlarging the current 32 MiB SDRAM address
|
||||
window and replacing the scalar external-memory bottleneck. A dedicated memory
|
||||
fabric may evolve independently while RIBP and APB remain the stable peripheral
|
||||
register interfaces. Frequency claims must be qualified separately for each
|
||||
PDK and physical implementation.
|
||||
|
||||
## Commercial Reference Points
|
||||
|
||||
The products below are reference points along different axes. None is a
|
||||
pin-compatible or performance-equivalent substitute for retroSoC Mini.
|
||||
|
||||
| Commercial SoC | Relevant architecture | Comparison with the planned Mini |
|
||||
| --- | --- | --- |
|
||||
| [Bouffalo Lab BL808](https://github.com/bouffalolab/bl808_linux) | RISC-V Linux application core with separate MCU and low-power cores | Closest RISC-V heterogeneous architecture; substantially stronger wireless, multimedia, memory, and application-core capability |
|
||||
| [NXP i.MX 7ULP](https://www.nxp.com/products/i.MX7ULP) | Cortex-A7 Linux core and Cortex-M4 system master with boot and power-control responsibilities | Closest commercial lifecycle-control model; a much larger application-processor platform |
|
||||
| [ST STM32MP151](https://www.st.com/en/microcontrollers-microprocessors/stm32mp151a.html) | Single Cortex-A7 Linux core and Cortex-M4 real-time core | Useful industrial heterogeneous-MPU reference; DDR, cache, interconnect, and peripheral capabilities are substantially higher |
|
||||
| [CV1800B and SG2002](https://milkv.io/docs/duo/overview) | Two RISC-V application-class cores supporting Linux and real-time workloads, with 64 or 256 MiB SiP memory | Closest low-cost dual-system RISC-V market reference; 64-bit cores and multimedia acceleration place it above Mini |
|
||||
| [Allwinner F133](https://www.allwinnertech.com/index.php?c=product&id=101) | RV64 C906 Linux processor with 64 MiB SiP DDR and display/video functions | Direct low-cost RISC-V Linux market reference without the same independent management-core model |
|
||||
| [Allwinner F1C200s](https://www.allwinnertech.com/uploads/pdf/201812181725033b.pdf) | 32-bit ARM9 Linux processor with 64 MiB SiP DDR in a compact package | Closest cost, memory, and lightweight-Linux application reference, but without a separate management core |
|
||||
| [Ingenic X1000/X1000E](https://www.ingenic.com.cn/products-detail/id-50.html) | 32-bit MIPS Linux processor with 32 or 64 MiB LPDDR and fast-boot positioning | Comparable low-power Linux product segment with much higher CPU frequency and a mature multimedia subsystem |
|
||||
| [Espressif ESP32-P4](https://docs.espressif.com/projects/esp-techpedia/en/latest/esp-friends/get-started/board-selection.html) | Dual 32-bit RISC-V high-performance cores and a low-power core | Relevant core-topology and power-control reference, but not a direct general-purpose MMU Linux competitor |
|
||||
|
||||
Commercial information and links in this table were checked on 2026-08-06.
|
||||
Specifications can change and must be revalidated before being used in product,
|
||||
cost, or performance claims.
|
||||
|
||||
## Positioning Summary
|
||||
|
||||
The closest architectural reference points are BL808 and i.MX 7ULP. The
|
||||
closest cost and lightweight-Linux reference is F1C200s, while F133 and
|
||||
CV1800B represent the nearest commercial RISC-V Linux market. ESP32-P4 is a
|
||||
control-topology reference rather than a Linux performance reference.
|
||||
|
||||
After the Linux configuration meets the memory and interconnect targets above,
|
||||
retroSoC Mini should be positioned between F1C200s and BL808: less capable than
|
||||
modern 64-bit multimedia SoCs, but differentiated by open RTL and explicit
|
||||
management-core control over Linux-core boot, bus admission, shutdown, and
|
||||
fault recovery.
|
||||
@@ -61,7 +61,7 @@ digraph mini_soc_block_diagram {
|
||||
|
||||
rcu [
|
||||
fillcolor="#EDE9FE",
|
||||
label="RCU\nclock buffering and reset synchronization\nPLL request/acknowledgment CDC"
|
||||
label="RCU\nclock buffering and reset synchronization\nPLL CDC and fixed 1 MHz timebase"
|
||||
];
|
||||
|
||||
subgraph cluster_soc {
|
||||
@@ -120,7 +120,11 @@ digraph mini_soc_block_diagram {
|
||||
];
|
||||
sysctrl [
|
||||
fillcolor="#F9E1E7",
|
||||
label="SYSCTRL and CLINT\nPLL, user-core select/reset/bus enable\nfault and performance control"
|
||||
label="SYSCTRL\nPLL, user-core select/reset/bus enable\nfault and performance control"
|
||||
];
|
||||
clint [
|
||||
fillcolor="#F9E1E7",
|
||||
label="CLINT\nstandard 64 KiB register map\nmtime, mtimecmp and MSIP"
|
||||
];
|
||||
ribp_targets [
|
||||
fillcolor="#F9E1E7",
|
||||
@@ -153,7 +157,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; ribp_targets; timers; ws2812; apb_targets; }
|
||||
{ rank=same; sysctrl; clint; ribp_targets; timers; ws2812; apb_targets; }
|
||||
{ rank=same; gpio_bridge; irq; }
|
||||
|
||||
ext_clock -> rcu [label="clock / reset"];
|
||||
@@ -164,6 +168,7 @@ digraph mini_soc_block_diagram {
|
||||
debug_module -> mgmt_core [label="halt, resume, abstract commands"];
|
||||
debug_module -> mgmt_adapter [label="reset after bridge idle", style=dashed];
|
||||
debug_module -> timers [label="halted", style=dashed];
|
||||
rcu -> clint [label="1 MHz tick", style=dashed];
|
||||
|
||||
mgmt_core -> mgmt_adapter [label="RIBP"];
|
||||
mgmt_adapter -> fabric [label="RIB"];
|
||||
@@ -175,6 +180,7 @@ digraph mini_soc_block_diagram {
|
||||
fabric -> ribp_adapter [label="RIB"];
|
||||
fabric -> apb_adapter [label="RIB"];
|
||||
ribp_adapter -> sysctrl [label="RIBP"];
|
||||
ribp_adapter -> clint [label="RIBP"];
|
||||
ribp_adapter -> ribp_targets [label="RIBP"];
|
||||
ribp_adapter -> timers [label="RIBP"];
|
||||
ribp_adapter -> ws2812 [label="RIBP"];
|
||||
@@ -182,6 +188,7 @@ digraph mini_soc_block_diagram {
|
||||
|
||||
ribp_targets -> gpio_bridge [label="GPIO alternate functions"];
|
||||
timers -> irq [label="IRQ3 / IRQ4"];
|
||||
clint -> irq [label="machine IRQ0 / IRQ1"];
|
||||
ws2812 -> gpio_bridge [label="GPIO2 ALT1"];
|
||||
dma -> ws2812 [label="TXDATA writes", style=dashed];
|
||||
ws2812 -> irq [label="IRQ17"];
|
||||
|
||||
+222
-193
@@ -4,19 +4,19 @@
|
||||
<!-- Generated by graphviz version 2.43.0 (0)
|
||||
-->
|
||||
<!-- Title: mini_soc_block_diagram Pages: 1 -->
|
||||
<svg width="1546pt" height="887pt"
|
||||
viewBox="0.00 0.00 1546.00 887.48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg width="1719pt" height="887pt"
|
||||
viewBox="0.00 0.00 1719.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)">
|
||||
<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>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_asic</title>
|
||||
<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"/>
|
||||
<path fill="transparent" stroke="#111827" d="M160,-85C160,-85 1691,-85 1691,-85 1697,-85 1703,-91 1703,-97 1703,-97 1703,-763.48 1703,-763.48 1703,-769.48 1697,-775.48 1691,-775.48 1691,-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>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_soc</title>
|
||||
<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"/>
|
||||
<path fill="transparent" stroke="#94a3b8" stroke-dasharray="5,2" d="M390,-103C390,-103 1673,-103 1673,-103 1679,-103 1685,-109 1685,-115 1685,-115 1685,-720.48 1685,-720.48 1685,-726.48 1679,-732.48 1673,-732.48 1673,-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>
|
||||
</g>
|
||||
<!-- ext_clock -->
|
||||
@@ -32,7 +32,7 @@
|
||||
<path fill="#ede9fe" stroke="#4b5563" stroke-width="1.1" d="M350,-574.48C350,-574.48 178,-574.48 178,-574.48 172,-574.48 166,-568.48 166,-562.48 166,-562.48 166,-541.48 166,-541.48 166,-535.48 172,-529.48 178,-529.48 178,-529.48 350,-529.48 350,-529.48 356,-529.48 362,-535.48 362,-541.48 362,-541.48 362,-562.48 362,-562.48 362,-568.48 356,-574.48 350,-574.48"/>
|
||||
<text text-anchor="middle" x="264" y="-560.48" font-family="Arial" font-size="10.00" fill="#111827">RCU</text>
|
||||
<text text-anchor="middle" x="264" y="-549.48" font-family="Arial" font-size="10.00" fill="#111827">clock buffering and reset synchronization</text>
|
||||
<text text-anchor="middle" x="264" y="-538.48" font-family="Arial" font-size="10.00" fill="#111827">PLL request/acknowledgment CDC</text>
|
||||
<text text-anchor="middle" x="264" y="-538.48" font-family="Arial" font-size="10.00" fill="#111827">PLL CDC and fixed 1 MHz timebase</text>
|
||||
</g>
|
||||
<!-- ext_clock->rcu -->
|
||||
<g id="edge1" class="edge">
|
||||
@@ -44,342 +44,371 @@
|
||||
<!-- ext_io -->
|
||||
<g id="node2" class="node">
|
||||
<title>ext_io</title>
|
||||
<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="1161" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</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="1161" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP and WS2812</text>
|
||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M1557,-45C1557,-45 1365,-45 1365,-45 1359,-45 1353,-39 1353,-33 1353,-33 1353,-12 1353,-12 1353,-6 1359,0 1365,0 1365,0 1557,0 1557,0 1563,0 1569,-6 1569,-12 1569,-12 1569,-33 1569,-33 1569,-39 1563,-45 1557,-45"/>
|
||||
<text text-anchor="middle" x="1461" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
|
||||
<text text-anchor="middle" x="1461" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, XPI Flash, SDRAM, PSRAM</text>
|
||||
<text text-anchor="middle" x="1461" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP and WS2812</text>
|
||||
</g>
|
||||
<!-- ext_jtag -->
|
||||
<g id="node3" class="node">
|
||||
<title>ext_jtag</title>
|
||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="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="684" y="-836.48" font-family="Arial" font-size="10.00" fill="#111827">Management JTAG</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>
|
||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M678.5,-851.48C678.5,-851.48 547.5,-851.48 547.5,-851.48 541.5,-851.48 535.5,-845.48 535.5,-839.48 535.5,-839.48 535.5,-827.48 535.5,-827.48 535.5,-821.48 541.5,-815.48 547.5,-815.48 547.5,-815.48 678.5,-815.48 678.5,-815.48 684.5,-815.48 690.5,-821.48 690.5,-827.48 690.5,-827.48 690.5,-839.48 690.5,-839.48 690.5,-845.48 684.5,-851.48 678.5,-851.48"/>
|
||||
<text text-anchor="middle" x="613" y="-836.48" font-family="Arial" font-size="10.00" fill="#111827">Management JTAG</text>
|
||||
<text text-anchor="middle" x="613" y="-825.48" font-family="Arial" font-size="10.00" fill="#111827">TCK, TMS, TDI, TRST_n, TDO</text>
|
||||
</g>
|
||||
<!-- jtag_dtm -->
|
||||
<g id="node6" class="node">
|
||||
<title>jtag_dtm</title>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="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="684" y="-654.98" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 JTAG DTM</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>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M688,-669.98C688,-669.98 538,-669.98 538,-669.98 532,-669.98 526,-663.98 526,-657.98 526,-657.98 526,-645.98 526,-645.98 526,-639.98 532,-633.98 538,-633.98 538,-633.98 688,-633.98 688,-633.98 694,-633.98 700,-639.98 700,-645.98 700,-645.98 700,-657.98 700,-657.98 700,-663.98 694,-669.98 688,-669.98"/>
|
||||
<text text-anchor="middle" x="613" y="-654.98" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 JTAG DTM</text>
|
||||
<text text-anchor="middle" x="613" y="-643.98" font-family="Arial" font-size="10.00" fill="#111827">10 MHz asynchronous TCK domain</text>
|
||||
</g>
|
||||
<!-- ext_jtag->jtag_dtm -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>ext_jtag->jtag_dtm</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M684,-815.27C684,-783.24 684,-714.39 684,-677.51"/>
|
||||
<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="704" y="-786.08" font-family="Arial" font-size="8.00" fill="#374151">JTAG pads</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M613,-815.27C613,-783.24 613,-714.39 613,-677.51"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="615.45,-677.14 613,-670.14 610.55,-677.14 615.45,-677.14"/>
|
||||
<text text-anchor="middle" x="633" y="-786.08" font-family="Arial" font-size="8.00" fill="#374151">JTAG pads</text>
|
||||
</g>
|
||||
<!-- fabric -->
|
||||
<g id="node11" class="node">
|
||||
<title>fabric</title>
|
||||
<path fill="#dcecf8" stroke="#4b5563" stroke-width="1.1" d="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="642" y="-446.24" font-family="Arial" font-size="10.00" fill="#111827">RIB fabric</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="642" y="-424.24" font-family="Arial" font-size="10.00" fill="#111827">INCR1 / INCR4, access policy, fault reporting</text>
|
||||
<path fill="#dcecf8" stroke="#4b5563" stroke-width="1.1" d="M1066.66,-442.31C1066.66,-442.31 998.98,-470.16 998.98,-470.16 993.43,-472.45 981.88,-474.73 975.88,-474.73 975.88,-474.73 820.12,-474.73 820.12,-474.73 814.12,-474.73 802.57,-472.45 797.02,-470.16 797.02,-470.16 729.34,-442.31 729.34,-442.31 723.79,-440.03 723.79,-435.46 729.34,-433.18 729.34,-433.18 797.02,-405.32 797.02,-405.32 802.57,-403.04 814.12,-400.76 820.12,-400.76 820.12,-400.76 975.88,-400.76 975.88,-400.76 981.88,-400.76 993.43,-403.04 998.98,-405.32 998.98,-405.32 1066.66,-433.18 1066.66,-433.18 1072.21,-435.46 1072.21,-440.03 1066.66,-442.31"/>
|
||||
<text text-anchor="middle" x="898" y="-446.24" font-family="Arial" font-size="10.00" fill="#111827">RIB fabric</text>
|
||||
<text text-anchor="middle" x="898" y="-435.24" font-family="Arial" font-size="10.00" fill="#111827">3-master round-robin arbitration</text>
|
||||
<text text-anchor="middle" x="898" y="-424.24" font-family="Arial" font-size="10.00" fill="#111827">INCR1 / INCR4, access policy, fault reporting</text>
|
||||
</g>
|
||||
<!-- rcu->fabric -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>rcu->fabric</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="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="532.72,-473.75 538.74,-469.41 531.33,-469.05 532.72,-473.75"/>
|
||||
<text text-anchor="middle" x="476" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">system clock / reset</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M362.03,-531.47C368.2,-530.24 372,-529.48 372,-529.48 372,-529.48 697,-474.48 697,-474.48 697,-474.48 728.7,-468.85 766.93,-462.05"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="767.67,-464.41 774.14,-460.77 766.82,-459.58 767.67,-464.41"/>
|
||||
<text text-anchor="middle" x="588" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">system clock / reset</text>
|
||||
</g>
|
||||
<!-- clint -->
|
||||
<g id="node17" class="node">
|
||||
<title>clint</title>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M527.5,-255C527.5,-255 406.5,-255 406.5,-255 400.5,-255 394.5,-249 394.5,-243 394.5,-243 394.5,-222 394.5,-222 394.5,-216 400.5,-210 406.5,-210 406.5,-210 527.5,-210 527.5,-210 533.5,-210 539.5,-216 539.5,-222 539.5,-222 539.5,-243 539.5,-243 539.5,-249 533.5,-255 527.5,-255"/>
|
||||
<text text-anchor="middle" x="467" y="-241" font-family="Arial" font-size="10.00" fill="#111827">CLINT</text>
|
||||
<text text-anchor="middle" x="467" y="-230" font-family="Arial" font-size="10.00" fill="#111827">standard 64 KiB register map</text>
|
||||
<text text-anchor="middle" x="467" y="-219" font-family="Arial" font-size="10.00" fill="#111827">mtime, mtimecmp and MSIP</text>
|
||||
</g>
|
||||
<!-- rcu->clint -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>rcu->clint</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M277.95,-529.16C313.89,-472.95 409.6,-323.28 449.33,-261.14"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="451.51,-262.27 453.22,-255.05 447.38,-259.63 451.51,-262.27"/>
|
||||
<text text-anchor="middle" x="397.5" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">1 MHz tick</text>
|
||||
</g>
|
||||
<!-- mgmt_core -->
|
||||
<g id="node5" class="node">
|
||||
<title>mgmt_core</title>
|
||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="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="887" y="-660.48" font-family="Arial" font-size="10.00" fill="#111827">Management core</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="887" y="-638.48" font-family="Arial" font-size="10.00" fill="#111827">JTAG Debug Module always present</text>
|
||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M1273,-674.48C1273,-674.48 1119,-674.48 1119,-674.48 1113,-674.48 1107,-668.48 1107,-662.48 1107,-662.48 1107,-641.48 1107,-641.48 1107,-635.48 1113,-629.48 1119,-629.48 1119,-629.48 1273,-629.48 1273,-629.48 1279,-629.48 1285,-635.48 1285,-641.48 1285,-641.48 1285,-662.48 1285,-662.48 1285,-668.48 1279,-674.48 1273,-674.48"/>
|
||||
<text text-anchor="middle" x="1196" y="-660.48" font-family="Arial" font-size="10.00" fill="#111827">Management core</text>
|
||||
<text text-anchor="middle" x="1196" y="-649.48" font-family="Arial" font-size="10.00" fill="#111827">Fixed Hazard3, branch predictor</text>
|
||||
<text text-anchor="middle" x="1196" y="-638.48" font-family="Arial" font-size="10.00" fill="#111827">JTAG Debug Module always present</text>
|
||||
</g>
|
||||
<!-- mgmt_adapter -->
|
||||
<g id="node8" class="node">
|
||||
<title>mgmt_adapter</title>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="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="887" y="-549.48" font-family="Arial" font-size="10.00" fill="#111827">RIBP2RIB</text>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M1216.5,-569.98C1216.5,-569.98 1175.5,-569.98 1175.5,-569.98 1169.5,-569.98 1163.5,-563.98 1163.5,-557.98 1163.5,-557.98 1163.5,-545.98 1163.5,-545.98 1163.5,-539.98 1169.5,-533.98 1175.5,-533.98 1175.5,-533.98 1216.5,-533.98 1216.5,-533.98 1222.5,-533.98 1228.5,-539.98 1228.5,-545.98 1228.5,-545.98 1228.5,-557.98 1228.5,-557.98 1228.5,-563.98 1222.5,-569.98 1216.5,-569.98"/>
|
||||
<text text-anchor="middle" x="1196" y="-549.48" font-family="Arial" font-size="10.00" fill="#111827">RIBP2RIB</text>
|
||||
</g>
|
||||
<!-- mgmt_core->mgmt_adapter -->
|
||||
<g id="edge8" class="edge">
|
||||
<g id="edge9" class="edge">
|
||||
<title>mgmt_core->mgmt_adapter</title>
|
||||
<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="889.45,-577.12 887,-570.12 884.55,-577.12 889.45,-577.12"/>
|
||||
<text text-anchor="middle" x="896.5" y="-600.08" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1196,-629.24C1196,-613.92 1196,-593.4 1196,-577.51"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1198.45,-577.12 1196,-570.12 1193.55,-577.12 1198.45,-577.12"/>
|
||||
<text text-anchor="middle" x="1205.5" y="-600.08" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- debug_module -->
|
||||
<g id="node7" class="node">
|
||||
<title>debug_module</title>
|
||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="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="1194" y="-660.48" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 Debug Module</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="1194" y="-638.48" font-family="Arial" font-size="10.00" fill="#111827">management-hart-only reset</text>
|
||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M949.5,-674.48C949.5,-674.48 828.5,-674.48 828.5,-674.48 822.5,-674.48 816.5,-668.48 816.5,-662.48 816.5,-662.48 816.5,-641.48 816.5,-641.48 816.5,-635.48 822.5,-629.48 828.5,-629.48 828.5,-629.48 949.5,-629.48 949.5,-629.48 955.5,-629.48 961.5,-635.48 961.5,-641.48 961.5,-641.48 961.5,-662.48 961.5,-662.48 961.5,-668.48 955.5,-674.48 949.5,-674.48"/>
|
||||
<text text-anchor="middle" x="889" y="-660.48" font-family="Arial" font-size="10.00" fill="#111827">Hazard3 Debug Module</text>
|
||||
<text text-anchor="middle" x="889" y="-649.48" font-family="Arial" font-size="10.00" fill="#111827">abstract commands, no SBA</text>
|
||||
<text text-anchor="middle" x="889" y="-638.48" font-family="Arial" font-size="10.00" fill="#111827">management-hart-only reset</text>
|
||||
</g>
|
||||
<!-- jtag_dtm->debug_module -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>jtag_dtm->debug_module</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="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="1143.55,-679.82 1148.73,-674.51 1141.37,-675.44 1143.55,-679.82"/>
|
||||
<text text-anchor="middle" x="946" y="-786.08" font-family="Arial" font-size="8.00" fill="#374151">DMI, asynchronous CDC</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M700.33,-651.98C735.12,-651.98 774.91,-651.98 808.95,-651.98"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="809.12,-654.43 816.12,-651.98 809.12,-649.53 809.12,-654.43"/>
|
||||
<text text-anchor="middle" x="758.25" y="-657.58" font-family="Arial" font-size="8.00" fill="#374151">DMI, asynchronous CDC</text>
|
||||
</g>
|
||||
<!-- debug_module->mgmt_core -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>debug_module->mgmt_core</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="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="983.21,-649.53 976.21,-651.98 983.21,-654.43 983.21,-649.53"/>
|
||||
<text text-anchor="middle" x="1048.75" y="-657.58" font-family="Arial" font-size="8.00" fill="#374151">halt, resume, abstract commands</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M961.75,-651.98C1002.99,-651.98 1055.09,-651.98 1099.69,-651.98"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1099.77,-654.43 1106.77,-651.98 1099.77,-649.53 1099.77,-654.43"/>
|
||||
<text text-anchor="middle" x="1034.25" y="-657.58" font-family="Arial" font-size="8.00" fill="#374151">halt, resume, abstract commands</text>
|
||||
</g>
|
||||
<!-- debug_module->mgmt_adapter -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>debug_module->mgmt_adapter</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="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="927.21,-563.25 919.79,-563.45 925.72,-567.92 927.21,-563.25"/>
|
||||
<text text-anchor="middle" x="1087" y="-600.08" font-family="Arial" font-size="8.00" fill="#374151">reset after bridge idle</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M961.7,-629.68C1038.93,-607.04 1150,-574.48 1150,-574.48 1150,-574.48 1152.57,-573.29 1156.49,-571.45"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1157.75,-573.56 1163.06,-568.38 1155.68,-569.13 1157.75,-573.56"/>
|
||||
<text text-anchor="middle" x="1103" y="-600.08" font-family="Arial" font-size="8.00" fill="#374151">reset after bridge idle</text>
|
||||
</g>
|
||||
<!-- timers -->
|
||||
<g id="node18" class="node">
|
||||
<g id="node19" 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>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M759.5,-255C759.5,-255 578.5,-255 578.5,-255 572.5,-255 566.5,-249 566.5,-243 566.5,-243 566.5,-222 566.5,-222 566.5,-216 572.5,-210 578.5,-210 578.5,-210 759.5,-210 759.5,-210 765.5,-210 771.5,-216 771.5,-222 771.5,-222 771.5,-243 771.5,-243 771.5,-249 765.5,-255 759.5,-255"/>
|
||||
<text text-anchor="middle" x="669" y="-241" font-family="Arial" font-size="10.00" fill="#111827">General timers 0/1</text>
|
||||
<text text-anchor="middle" x="669" y="-230" font-family="Arial" font-size="10.00" fill="#111827">32-bit counter, 16-bit prescaler</text>
|
||||
<text text-anchor="middle" x="669" 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>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M840.72,-629.48C775.96,-600.63 669,-552.98 669,-552.98 669,-552.98 669,-552.98 669,-327 669,-327 669,-289.76 669,-262.28"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="671.45,-262.19 669,-255.19 666.55,-262.19 671.45,-262.19"/>
|
||||
<text text-anchor="middle" x="680" y="-435.84" font-family="Arial" font-size="8.00" fill="#374151">halted</text>
|
||||
</g>
|
||||
<!-- mgmt_adapter->fabric -->
|
||||
<g id="edge9" class="edge">
|
||||
<g id="edge10" class="edge">
|
||||
<title>mgmt_adapter->fabric</title>
|
||||
<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="727.49,-475.21 720.11,-474.53 725.45,-479.67 727.49,-475.21"/>
|
||||
<text text-anchor="middle" x="793" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1177.65,-533.76C1160.99,-518.12 1139,-497.48 1139,-497.48 1139,-497.48 1077.55,-482.51 1016.71,-467.68"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1017.06,-465.24 1009.68,-465.96 1015.9,-470 1017.06,-465.24"/>
|
||||
<text text-anchor="middle" x="1155" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
</g>
|
||||
<!-- user_core -->
|
||||
<g id="node9" class="node">
|
||||
<title>user_core</title>
|
||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="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="642" y="-560.48" font-family="Arial" font-size="10.00" fill="#111827">Selected user core</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="642" y="-538.48" font-family="Arial" font-size="10.00" fill="#111827">PicoRV32 at C5</text>
|
||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M1124,-574.48C1124,-574.48 1048,-574.48 1048,-574.48 1042,-574.48 1036,-568.48 1036,-562.48 1036,-562.48 1036,-541.48 1036,-541.48 1036,-535.48 1042,-529.48 1048,-529.48 1048,-529.48 1124,-529.48 1124,-529.48 1130,-529.48 1136,-535.48 1136,-541.48 1136,-541.48 1136,-562.48 1136,-562.48 1136,-568.48 1130,-574.48 1124,-574.48"/>
|
||||
<text text-anchor="middle" x="1086" y="-560.48" font-family="Arial" font-size="10.00" fill="#111827">Selected user core</text>
|
||||
<text text-anchor="middle" x="1086" y="-549.48" font-family="Arial" font-size="10.00" fill="#111827">C0-C5, one active</text>
|
||||
<text text-anchor="middle" x="1086" y="-538.48" font-family="Arial" font-size="10.00" fill="#111827">PicoRV32 at C5</text>
|
||||
</g>
|
||||
<!-- user_core->fabric -->
|
||||
<g id="edge10" class="edge">
|
||||
<g id="edge11" class="edge">
|
||||
<title>user_core->fabric</title>
|
||||
<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="644.45,-481.89 642,-474.89 639.55,-481.89 644.45,-481.89"/>
|
||||
<text text-anchor="middle" x="649" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1102.11,-529.26C1110.49,-517.96 1119,-506.48 1119,-506.48 1119,-506.48 1119,-497.48 1119,-497.48 1119,-497.48 1066.59,-483.55 1012.81,-469.26"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1013.3,-466.86 1005.91,-467.43 1012.05,-471.59 1013.3,-466.86"/>
|
||||
<text text-anchor="middle" x="1126" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
</g>
|
||||
<!-- dma -->
|
||||
<g id="node10" class="node">
|
||||
<title>dma</title>
|
||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="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="1138" y="-554.98" font-family="Arial" font-size="10.00" fill="#111827">DMA</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>
|
||||
<path fill="#ddf2e3" stroke="#4b5563" stroke-width="1.1" d="M1487,-569.98C1487,-569.98 1369,-569.98 1369,-569.98 1363,-569.98 1357,-563.98 1357,-557.98 1357,-557.98 1357,-545.98 1357,-545.98 1357,-539.98 1363,-533.98 1369,-533.98 1369,-533.98 1487,-533.98 1487,-533.98 1493,-533.98 1499,-539.98 1499,-545.98 1499,-545.98 1499,-557.98 1499,-557.98 1499,-563.98 1493,-569.98 1487,-569.98"/>
|
||||
<text text-anchor="middle" x="1428" y="-554.98" font-family="Arial" font-size="10.00" fill="#111827">DMA</text>
|
||||
<text text-anchor="middle" x="1428" y="-543.98" font-family="Arial" font-size="10.00" fill="#111827">RIB master and RIBP target</text>
|
||||
</g>
|
||||
<!-- dma->fabric -->
|
||||
<g id="edge11" class="edge">
|
||||
<g id="edge12" class="edge">
|
||||
<title>dma->fabric</title>
|
||||
<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="771.63,-460.5 764.3,-461.62 770.73,-465.32 771.63,-460.5"/>
|
||||
<text text-anchor="middle" x="993" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1356.8,-535.91C1271.31,-517.8 1126.48,-487.13 1022.39,-465.08"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1022.63,-462.63 1015.28,-463.58 1021.62,-467.43 1022.63,-462.63"/>
|
||||
<text text-anchor="middle" x="1217" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
</g>
|
||||
<!-- ws2812 -->
|
||||
<g id="node19" class="node">
|
||||
<g id="node20" class="node">
|
||||
<title>ws2812</title>
|
||||
<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="1186" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WS2812 TX</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="1186" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16-word FIFO, IRQ17, DMA-fed</text>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1400,-255C1400,-255 1266,-255 1266,-255 1260,-255 1254,-249 1254,-243 1254,-243 1254,-222 1254,-222 1254,-216 1260,-210 1266,-210 1266,-210 1400,-210 1400,-210 1406,-210 1412,-216 1412,-222 1412,-222 1412,-243 1412,-243 1412,-249 1406,-255 1400,-255"/>
|
||||
<text text-anchor="middle" x="1333" y="-241" font-family="Arial" font-size="10.00" fill="#111827">WS2812 TX</text>
|
||||
<text text-anchor="middle" x="1333" y="-230" font-family="Arial" font-size="10.00" fill="#111827">24-bit MSB-first serializer</text>
|
||||
<text text-anchor="middle" x="1333" y="-219" font-family="Arial" font-size="10.00" fill="#111827">16-word FIFO, IRQ17, DMA-fed</text>
|
||||
</g>
|
||||
<!-- dma->ws2812 -->
|
||||
<g id="edge24" class="edge">
|
||||
<g id="edge27" class="edge">
|
||||
<title>dma->ws2812</title>
|
||||
<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="1186.65,-262.45 1184.64,-255.31 1181.76,-262.15 1186.65,-262.45"/>
|
||||
<text text-anchor="middle" x="1204.5" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">TXDATA writes</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M1433.9,-533.63C1441.57,-511.05 1454,-474.48 1454,-474.48 1454,-474.48 1454,-401 1454,-401 1454,-401 1387.1,-308.39 1352.79,-260.89"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1354.66,-259.29 1348.57,-255.05 1350.68,-262.16 1354.66,-259.29"/>
|
||||
<text text-anchor="middle" x="1463.5" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">TXDATA writes</text>
|
||||
</g>
|
||||
<!-- fault -->
|
||||
<g id="node12" class="node">
|
||||
<title>fault</title>
|
||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="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="1091" y="-440.74" font-family="Arial" font-size="10.00" fill="#111827">Error slave</text>
|
||||
<text text-anchor="middle" x="1091" y="-429.74" font-family="Arial" font-size="10.00" fill="#111827">access and protocol faults</text>
|
||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M1278.5,-455.74C1278.5,-455.74 1169.5,-455.74 1169.5,-455.74 1163.5,-455.74 1157.5,-449.74 1157.5,-443.74 1157.5,-443.74 1157.5,-431.74 1157.5,-431.74 1157.5,-425.74 1163.5,-419.74 1169.5,-419.74 1169.5,-419.74 1278.5,-419.74 1278.5,-419.74 1284.5,-419.74 1290.5,-425.74 1290.5,-431.74 1290.5,-431.74 1290.5,-443.74 1290.5,-443.74 1290.5,-449.74 1284.5,-455.74 1278.5,-455.74"/>
|
||||
<text text-anchor="middle" x="1224" y="-440.74" font-family="Arial" font-size="10.00" fill="#111827">Error slave</text>
|
||||
<text text-anchor="middle" x="1224" y="-429.74" font-family="Arial" font-size="10.00" fill="#111827">access and protocol faults</text>
|
||||
</g>
|
||||
<!-- fabric->fault -->
|
||||
<g id="edge12" class="edge">
|
||||
<g id="edge13" class="edge">
|
||||
<title>fabric->fault</title>
|
||||
<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="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="1046.13,-461.05 1051.47,-455.9 1044.08,-456.59 1046.13,-461.05"/>
|
||||
<text text-anchor="middle" x="923" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">invalid / denied</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1084.98,-437.74C1107.93,-437.74 1130.24,-437.74 1150.02,-437.74"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1084.69,-435.29 1077.69,-437.74 1084.69,-440.19 1084.69,-435.29"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1150.19,-440.19 1157.19,-437.74 1150.19,-435.29 1150.19,-440.19"/>
|
||||
<text text-anchor="middle" x="1117.56" y="-443.34" font-family="Arial" font-size="8.00" fill="#374151">invalid / denied</text>
|
||||
</g>
|
||||
<!-- sram -->
|
||||
<g id="node13" class="node">
|
||||
<title>sram</title>
|
||||
<path fill="#fff3c9" stroke="#4b5563" stroke-width="1.1" d="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="936" y="-440.74" font-family="Arial" font-size="10.00" fill="#111827">On-chip SRAM</text>
|
||||
<text text-anchor="middle" x="936" y="-429.74" font-family="Arial" font-size="10.00" fill="#111827">optional RIB2RAM path</text>
|
||||
<path fill="#fff3c9" stroke="#4b5563" stroke-width="1.1" d="M1428,-455.74C1428,-455.74 1330,-455.74 1330,-455.74 1324,-455.74 1318,-449.74 1318,-443.74 1318,-443.74 1318,-431.74 1318,-431.74 1318,-425.74 1324,-419.74 1330,-419.74 1330,-419.74 1428,-419.74 1428,-419.74 1434,-419.74 1440,-425.74 1440,-431.74 1440,-431.74 1440,-443.74 1440,-443.74 1440,-449.74 1434,-455.74 1428,-455.74"/>
|
||||
<text text-anchor="middle" x="1379" y="-440.74" font-family="Arial" font-size="10.00" fill="#111827">On-chip SRAM</text>
|
||||
<text text-anchor="middle" x="1379" y="-429.74" font-family="Arial" font-size="10.00" fill="#111827">optional RIB2RAM path</text>
|
||||
</g>
|
||||
<!-- fabric->sram -->
|
||||
<g id="edge13" class="edge">
|
||||
<g id="edge14" class="edge">
|
||||
<title>fabric->sram</title>
|
||||
<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="867.81,-440.19 874.81,-437.74 867.81,-435.29 867.81,-440.19"/>
|
||||
<text text-anchor="middle" x="848.31" y="-443.34" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1004.32,-468.06C1054.69,-482.42 1104,-496.48 1104,-496.48 1104,-496.48 1118,-496.48 1118,-496.48 1118,-496.48 1304,-474.48 1304,-474.48 1304,-474.48 1318.84,-467.21 1335.32,-459.14"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1336.73,-461.18 1341.94,-455.9 1334.58,-456.78 1336.73,-461.18"/>
|
||||
<text text-anchor="middle" x="1111" y="-500.08" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
</g>
|
||||
<!-- ribp_adapter -->
|
||||
<g id="node14" class="node">
|
||||
<title>ribp_adapter</title>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="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="965" y="-325.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M1060.5,-346C1060.5,-346 1019.5,-346 1019.5,-346 1013.5,-346 1007.5,-340 1007.5,-334 1007.5,-334 1007.5,-322 1007.5,-322 1007.5,-316 1013.5,-310 1019.5,-310 1019.5,-310 1060.5,-310 1060.5,-310 1066.5,-310 1072.5,-316 1072.5,-322 1072.5,-322 1072.5,-334 1072.5,-334 1072.5,-340 1066.5,-346 1060.5,-346"/>
|
||||
<text text-anchor="middle" x="1040" y="-325.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
||||
</g>
|
||||
<!-- fabric->ribp_adapter -->
|
||||
<g id="edge14" class="edge">
|
||||
<g id="edge15" class="edge">
|
||||
<title>fabric->ribp_adapter</title>
|
||||
<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="926.52,-344.42 932.39,-339.88 924.97,-339.77 926.52,-344.42"/>
|
||||
<text text-anchor="middle" x="848" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M945.28,-400.87C967.36,-384.11 992.9,-364.73 1011.89,-350.33"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1013.47,-352.2 1017.57,-346.02 1010.51,-348.3 1013.47,-352.2"/>
|
||||
<text text-anchor="middle" x="992" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
</g>
|
||||
<!-- apb_adapter -->
|
||||
<g id="node15" class="node">
|
||||
<title>apb_adapter</title>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="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="583" y="-331" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
|
||||
<text text-anchor="middle" x="583" y="-320" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M938,-346C938,-346 868,-346 868,-346 862,-346 856,-340 856,-334 856,-334 856,-322 856,-322 856,-316 862,-310 868,-310 868,-310 938,-310 938,-310 944,-310 950,-316 950,-322 950,-322 950,-334 950,-334 950,-340 944,-346 938,-346"/>
|
||||
<text text-anchor="middle" x="903" y="-331" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
|
||||
<text text-anchor="middle" x="903" y="-320" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
|
||||
</g>
|
||||
<!-- fabric->apb_adapter -->
|
||||
<g id="edge15" class="edge">
|
||||
<g id="edge16" class="edge">
|
||||
<title>fabric->apb_adapter</title>
|
||||
<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="597.83,-350.98 592.32,-346.02 593.53,-353.34 597.83,-350.98"/>
|
||||
<text text-anchor="middle" x="615" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M899.66,-400.87C900.39,-385.27 901.22,-367.39 901.87,-353.38"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="904.33,-353.13 902.21,-346.02 899.44,-352.9 904.33,-353.13"/>
|
||||
<text text-anchor="middle" x="908" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||
</g>
|
||||
<!-- sysctrl -->
|
||||
<g id="node16" class="node">
|
||||
<title>sysctrl</title>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="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="730" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL and CLINT</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="730" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1215.5,-255C1215.5,-255 1052.5,-255 1052.5,-255 1046.5,-255 1040.5,-249 1040.5,-243 1040.5,-243 1040.5,-222 1040.5,-222 1040.5,-216 1046.5,-210 1052.5,-210 1052.5,-210 1215.5,-210 1215.5,-210 1221.5,-210 1227.5,-216 1227.5,-222 1227.5,-222 1227.5,-243 1227.5,-243 1227.5,-249 1221.5,-255 1215.5,-255"/>
|
||||
<text text-anchor="middle" x="1134" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL</text>
|
||||
<text text-anchor="middle" x="1134" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user-core select/reset/bus enable</text>
|
||||
<text text-anchor="middle" x="1134" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->sysctrl -->
|
||||
<g id="edge16" class="edge">
|
||||
<g id="edge17" class="edge">
|
||||
<title>ribp_adapter->sysctrl</title>
|
||||
<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="791.47,-255.32 784.06,-255.01 789.66,-259.87 791.47,-255.32"/>
|
||||
<text text-anchor="middle" x="870.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1057.24,-309.85C1071.15,-296.02 1090.95,-276.32 1106.96,-260.39"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1109,-261.82 1112.24,-255.15 1105.54,-258.35 1109,-261.82"/>
|
||||
<text text-anchor="middle" x="1096.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->clint -->
|
||||
<g id="edge18" class="edge">
|
||||
<title>ribp_adapter->clint</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1007.33,-319.69C986.73,-315.08 964,-310 964,-310 964,-310 553,-255 553,-255 553,-255 550.57,-254.39 546.54,-253.38"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="546.95,-250.96 539.56,-251.64 545.76,-255.72 546.95,-250.96"/>
|
||||
<text text-anchor="middle" x="792.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- ribp_targets -->
|
||||
<g id="node17" class="node">
|
||||
<g id="node18" class="node">
|
||||
<title>ribp_targets</title>
|
||||
<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="965" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</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="965" y="-219" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, I2C and I2S</text>
|
||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1656.5,-255C1656.5,-255 1451.5,-255 1451.5,-255 1445.5,-255 1439.5,-249 1439.5,-243 1439.5,-243 1439.5,-222 1439.5,-222 1439.5,-216 1445.5,-210 1451.5,-210 1451.5,-210 1656.5,-210 1656.5,-210 1662.5,-210 1668.5,-216 1668.5,-222 1668.5,-222 1668.5,-243 1668.5,-243 1668.5,-249 1662.5,-255 1656.5,-255"/>
|
||||
<text text-anchor="middle" x="1554" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
|
||||
<text text-anchor="middle" x="1554" 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="1554" y="-219" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, I2C and I2S</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->ribp_targets -->
|
||||
<g id="edge17" class="edge">
|
||||
<g id="edge19" class="edge">
|
||||
<title>ribp_adapter->ribp_targets</title>
|
||||
<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="967.45,-262.15 965,-255.15 962.55,-262.15 967.45,-262.15"/>
|
||||
<text text-anchor="middle" x="974.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1072.54,-321.08C1143.35,-308.2 1314.49,-277.07 1432.4,-255.62"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1432.94,-258.01 1439.39,-254.35 1432.06,-253.19 1432.94,-258.01"/>
|
||||
<text text-anchor="middle" x="1306.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->timers -->
|
||||
<g id="edge18" class="edge">
|
||||
<g id="edge20" 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>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1007.42,-318.91C960.37,-307.22 879,-287 879,-287 879,-287 817,-271.21 760.38,-256.78"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="760.9,-254.38 753.51,-255.03 759.69,-259.13 760.9,-254.38"/>
|
||||
<text text-anchor="middle" x="888.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- ribp_adapter->ws2812 -->
|
||||
<g id="edge19" class="edge">
|
||||
<g id="edge21" class="edge">
|
||||
<title>ribp_adapter->ws2812</title>
|
||||
<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="1129.31,-260.15 1134.8,-255.16 1127.4,-255.63 1129.31,-260.15"/>
|
||||
<text text-anchor="middle" x="1084.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1072.76,-316.55C1117.4,-302.3 1198.65,-276.37 1258.52,-257.27"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1259.42,-259.55 1265.35,-255.09 1257.93,-254.88 1259.42,-259.55"/>
|
||||
<text text-anchor="middle" x="1195.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||
</g>
|
||||
<!-- apb_targets -->
|
||||
<g id="node20" class="node">
|
||||
<g id="node21" class="node">
|
||||
<title>apb_targets</title>
|
||||
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M597.5,-255C597.5,-255 406.5,-255 406.5,-255 400.5,-255 394.5,-249 394.5,-243 394.5,-243 394.5,-222 394.5,-222 394.5,-216 400.5,-210 406.5,-210 406.5,-210 597.5,-210 597.5,-210 603.5,-210 609.5,-216 609.5,-222 609.5,-222 609.5,-243 609.5,-243 609.5,-249 603.5,-255 597.5,-255"/>
|
||||
<text text-anchor="middle" x="502" y="-241" font-family="Arial" font-size="10.00" fill="#111827">APB target wrapper</text>
|
||||
<text text-anchor="middle" x="502" y="-230" font-family="Arial" font-size="10.00" fill="#111827">Archinfo, RNG, UART1, PWM, PS/2, RTC</text>
|
||||
<text text-anchor="middle" x="502" y="-219" font-family="Arial" font-size="10.00" fill="#111827">watchdog, CRC, advanced timer and user IP</text>
|
||||
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M1001.5,-255C1001.5,-255 810.5,-255 810.5,-255 804.5,-255 798.5,-249 798.5,-243 798.5,-243 798.5,-222 798.5,-222 798.5,-216 804.5,-210 810.5,-210 810.5,-210 1001.5,-210 1001.5,-210 1007.5,-210 1013.5,-216 1013.5,-222 1013.5,-222 1013.5,-243 1013.5,-243 1013.5,-249 1007.5,-255 1001.5,-255"/>
|
||||
<text text-anchor="middle" x="906" y="-241" font-family="Arial" font-size="10.00" fill="#111827">APB target wrapper</text>
|
||||
<text text-anchor="middle" x="906" y="-230" font-family="Arial" font-size="10.00" fill="#111827">Archinfo, RNG, UART1, PWM, PS/2, RTC</text>
|
||||
<text text-anchor="middle" x="906" y="-219" font-family="Arial" font-size="10.00" fill="#111827">watchdog, CRC, advanced timer and user IP</text>
|
||||
</g>
|
||||
<!-- apb_adapter->apb_targets -->
|
||||
<g id="edge20" class="edge">
|
||||
<g id="edge22" class="edge">
|
||||
<title>apb_adapter->apb_targets</title>
|
||||
<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="527.19,-258.84 520.75,-255.15 523.49,-262.04 527.19,-258.84"/>
|
||||
<text text-anchor="middle" x="555" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
|
||||
</g>
|
||||
<!-- ribp_targets->ext_io -->
|
||||
<g id="edge27" class="edge">
|
||||
<title>ribp_targets->ext_io</title>
|
||||
<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="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="1224.02,-45.25 1216.61,-45.01 1222.26,-49.82 1224.02,-45.25"/>
|
||||
<text text-anchor="middle" x="1366" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
|
||||
</g>
|
||||
<!-- gpio_bridge -->
|
||||
<g id="node21" class="node">
|
||||
<title>gpio_bridge</title>
|
||||
<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="963" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</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>
|
||||
<!-- ribp_targets->gpio_bridge -->
|
||||
<g id="edge21" class="edge">
|
||||
<title>ribp_targets->gpio_bridge</title>
|
||||
<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="965.97,-162.15 963.37,-155.2 961.07,-162.25 965.97,-162.15"/>
|
||||
<text text-anchor="middle" x="1008" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO alternate functions</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M903.55,-309.85C903.97,-296.62 904.57,-278.02 905.07,-262.49"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="907.53,-262.22 905.31,-255.15 902.63,-262.07 907.53,-262.22"/>
|
||||
<text text-anchor="middle" x="912" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
|
||||
</g>
|
||||
<!-- irq -->
|
||||
<g id="node22" class="node">
|
||||
<g id="node23" class="node">
|
||||
<title>irq</title>
|
||||
<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="1191" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</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>
|
||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M772,-155C772,-155 566,-155 566,-155 560,-155 554,-149 554,-143 554,-143 554,-131 554,-131 554,-125 560,-119 566,-119 566,-119 772,-119 772,-119 778,-119 784,-125 784,-131 784,-131 784,-143 784,-143 784,-149 778,-155 772,-155"/>
|
||||
<text text-anchor="middle" x="669" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
|
||||
<text text-anchor="middle" x="669" y="-129" font-family="Arial" font-size="10.00" fill="#111827">RIBP and APB target IRQs to management core</text>
|
||||
</g>
|
||||
<!-- clint->irq -->
|
||||
<g id="edge25" class="edge">
|
||||
<title>clint->irq</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M513.6,-209.93C547.35,-194.31 592.66,-173.34 625.64,-158.07"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="626.74,-160.26 632.06,-155.1 624.68,-155.81 626.74,-160.26"/>
|
||||
<text text-anchor="middle" x="618.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">machine IRQ0 / IRQ1</text>
|
||||
</g>
|
||||
<!-- ribp_targets->ext_io -->
|
||||
<g id="edge30" class="edge">
|
||||
<title>ribp_targets->ext_io</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1541.78,-203.07C1536.28,-190.28 1531,-178 1531,-178 1531,-178 1494.07,-96.48 1473.85,-51.87"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1539.63,-204.28 1544.65,-209.74 1544.13,-202.34 1539.63,-204.28"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1476,-50.67 1470.88,-45.31 1471.54,-52.7 1476,-50.67"/>
|
||||
<text text-anchor="middle" x="1550" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
|
||||
</g>
|
||||
<!-- gpio_bridge -->
|
||||
<g id="node22" class="node">
|
||||
<title>gpio_bridge</title>
|
||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M1448,-155C1448,-155 1300,-155 1300,-155 1294,-155 1288,-149 1288,-143 1288,-143 1288,-131 1288,-131 1288,-125 1294,-119 1300,-119 1300,-119 1448,-119 1448,-119 1454,-119 1460,-125 1460,-131 1460,-131 1460,-143 1460,-143 1460,-149 1454,-155 1448,-155"/>
|
||||
<text text-anchor="middle" x="1374" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
|
||||
<text text-anchor="middle" x="1374" y="-129" font-family="Arial" font-size="10.00" fill="#111827">software, alternate and user modes</text>
|
||||
</g>
|
||||
<!-- ribp_targets->gpio_bridge -->
|
||||
<g id="edge23" class="edge">
|
||||
<title>ribp_targets->gpio_bridge</title>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1499.16,-209.9C1470.36,-198.56 1441,-187 1441,-187 1441,-187 1421.43,-172.69 1403.44,-159.53"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1404.53,-157.29 1397.43,-155.14 1401.64,-161.25 1404.53,-157.29"/>
|
||||
<text text-anchor="middle" x="1485" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO alternate functions</text>
|
||||
</g>
|
||||
<!-- timers->irq -->
|
||||
<g id="edge22" class="edge">
|
||||
<g id="edge24" 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>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M669,-209.81C669,-195.66 669,-177.17 669,-162.49"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="671.45,-162.2 669,-155.2 666.55,-162.2 671.45,-162.2"/>
|
||||
<text text-anchor="middle" x="691.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">
|
||||
<g id="edge26" 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>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1341.95,-209.74C1348.04,-194.93 1355,-178 1355,-178 1355,-178 1358.68,-170.25 1362.8,-161.58"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1365.04,-162.57 1365.83,-155.2 1360.62,-160.47 1365.04,-162.57"/>
|
||||
<text text-anchor="middle" x="1377.5" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO2 ALT1</text>
|
||||
</g>
|
||||
<!-- ws2812->irq -->
|
||||
<g id="edge25" class="edge">
|
||||
<g id="edge28" class="edge">
|
||||
<title>ws2812->irq</title>
|
||||
<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="1192.15,-162.32 1190.08,-155.2 1187.26,-162.06 1192.15,-162.32"/>
|
||||
<text text-anchor="middle" x="1200" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ17</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1253.79,-212.99C1246.05,-211.18 1241,-210 1241,-210 1241,-210 959.53,-174.57 791.48,-153.42"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="791.32,-150.93 784.06,-152.48 790.7,-155.79 791.32,-150.93"/>
|
||||
<text text-anchor="middle" x="1067" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">IRQ17</text>
|
||||
</g>
|
||||
<!-- apb_targets->gpio_bridge -->
|
||||
<g id="edge26" class="edge">
|
||||
<g id="edge29" class="edge">
|
||||
<title>apb_targets->gpio_bridge</title>
|
||||
<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="872.59,-158.84 878.97,-155.04 871.62,-154.03 872.59,-158.84"/>
|
||||
<text text-anchor="middle" x="778" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1013.66,-209.99C1094.75,-193.79 1204.75,-171.81 1281.8,-156.42"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1282.3,-158.82 1288.69,-155.04 1281.34,-154.01 1282.3,-158.82"/>
|
||||
<text text-anchor="middle" x="1186" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
|
||||
</g>
|
||||
<!-- gpio_bridge->ext_io -->
|
||||
<g id="edge28" class="edge">
|
||||
<g id="edge31" class="edge">
|
||||
<title>gpio_bridge->ext_io</title>
|
||||
<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="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="1117.95,-50.78 1122.83,-45.19 1115.53,-46.52 1117.95,-50.78"/>
|
||||
<text text-anchor="middle" x="1099" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
|
||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1391.54,-113.32C1405.42,-95.37 1424.86,-70.24 1439.64,-51.12"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1389.56,-111.88 1387.21,-118.91 1393.43,-114.88 1389.56,-111.88"/>
|
||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1441.73,-52.43 1444.07,-45.39 1437.85,-49.43 1441.73,-52.43"/>
|
||||
<text text-anchor="middle" x="1445" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 35 KiB |
+125
-34
@@ -38,40 +38,6 @@ Tiny is not a Mini with features disabled, and Std is not a Mini that merely
|
||||
adds a GPU. Their memory systems, power targets, software contracts, and
|
||||
verification requirements differ materially.
|
||||
|
||||
## Mini: Family Anchor
|
||||
|
||||
### Position
|
||||
|
||||
Mini is the low-cost, heterogeneous, 32-bit Linux control SoC in the family. It
|
||||
targets industrial control, protocol gateways, compact human-machine
|
||||
interfaces, and retro multimedia systems that need Linux but do not need a
|
||||
desktop-class graphics pipeline. Hazard3 remains the trusted management core,
|
||||
and one RV32 VexiiRiscv application core runs Linux.
|
||||
|
||||
The product target starts at 64 MiB of external SDRAM, with 128 MiB preferred.
|
||||
A simple display controller or framebuffer is compatible with the Mini
|
||||
position, but a 3D GPU, NPU, coherent multiprocessing, and a full graphical
|
||||
desktop are deliberately outside the defining Mini requirements. This keeps
|
||||
Mini below Std in memory bandwidth, software complexity, die area, and power.
|
||||
|
||||
The detailed current baseline, planned Linux boot flow, lifecycle controls, and
|
||||
memory-transport gaps are defined in
|
||||
[Mini Product Positioning](mini-product-positioning.md).
|
||||
|
||||
### Commercial Reference Points
|
||||
|
||||
| Commercial SoC | Relevant axis | Position relative to Mini |
|
||||
| --- | --- | --- |
|
||||
| [Allwinner F1C200s](https://www.allwinnertech.com/uploads/pdf/201812181725033b.pdf) | Compact, low-cost Linux device with 64 MiB SiP DDR | Closest cost and lightweight-Linux reference, without an independent management core |
|
||||
| [Bouffalo Lab BL808](https://github.com/bouffalolab/bl808_linux) | RISC-V application, MCU, and low-power core domains | Closest heterogeneous RISC-V topology, but with much stronger wireless and multimedia integration |
|
||||
| [NXP i.MX 7ULP](https://www.nxp.com/products/i.MX7ULP) | Linux application core plus an independently useful MCU domain | Strong lifecycle and power-domain reference, but a larger application-processor platform |
|
||||
| [Allwinner F133](https://www.allwinnertech.com/index.php?c=product&id=101) | Low-cost RISC-V Linux with SiP memory and display functions | Direct RISC-V Linux market reference with more multimedia integration and no equivalent trusted management model |
|
||||
|
||||
Mini should be positioned between F1C200s and BL808 after it boots Linux from a
|
||||
qualified external-memory path. It differentiates itself through open RTL and
|
||||
explicit management-core authority, not through headline CPU or multimedia
|
||||
performance.
|
||||
|
||||
## Tiny: Low-Power MCU and Edge Connectivity
|
||||
|
||||
### Position
|
||||
@@ -128,6 +94,131 @@ Tiny-MCU should be compared primarily with RP2350 and lower-memory STM32U5
|
||||
devices. Tiny-Connect should be compared with ESP32-H2; ESP32-C6 is the upper
|
||||
feature reference when Wi-Fi is included.
|
||||
|
||||
## Mini: Family Anchor
|
||||
|
||||
### Status and Position
|
||||
|
||||
retroSoC Mini is currently an open-source RISC-V microcontroller-class SoC
|
||||
with a fixed Hazard3 management core and one software-selected user core. The
|
||||
planned Linux-capable configuration adds a 32-bit VexiiRiscv user core. The
|
||||
VexiiRiscv integration and Linux boot flow are product targets, not supported
|
||||
repository configurations yet.
|
||||
|
||||
Mini is the price, complexity, and Linux-capability anchor for the family. It
|
||||
targets industrial control, protocol gateways, compact human-machine
|
||||
interfaces, and retro multimedia systems that need Linux but do not need a
|
||||
desktop-class graphics pipeline. Hazard3 remains the trusted management core,
|
||||
and one RV32 VexiiRiscv application core runs Linux in the planned
|
||||
configuration.
|
||||
|
||||
The product target starts at 64 MiB of external SDRAM, with 128 MiB preferred.
|
||||
A simple display controller or framebuffer is compatible with the Mini
|
||||
position, but a 3D GPU, NPU, coherent multiprocessing, and a full graphical
|
||||
desktop are deliberately outside the defining Mini requirements. This keeps
|
||||
Mini below Std in memory bandwidth, software complexity, die area, and power.
|
||||
Mini is not intended to compete with general-purpose Linux application
|
||||
processors that require RV64, cache-coherent multiprocessing, or
|
||||
high-bandwidth DDR interfaces.
|
||||
|
||||
### Current Mini Baseline
|
||||
|
||||
The current executable RTL and generated integration inputs define these
|
||||
capabilities:
|
||||
|
||||
- A fixed Hazard3 management core owns system control and has a permanent JTAG
|
||||
Debug Module.
|
||||
- The C0-C5 extension fabric permits one selected user core to run at a time.
|
||||
- SYSCTRL controls user-core selection, reset, interrupt admission, and bus
|
||||
admission. A stop request blocks new user transactions, drains an accepted
|
||||
transaction, and then asserts reset.
|
||||
- The canonical address map exposes 128 KiB of on-chip SRAM, a 32 MiB SDRAM
|
||||
window, and an 8 MiB PSRAM window. Address-window capacity does not guarantee
|
||||
that every implementation includes the corresponding physical memory.
|
||||
- RIB v1 is a 32-bit interconnect with `INCR1` and aligned four-word `INCR4`
|
||||
transfers and one outstanding transaction per master.
|
||||
- Current external-memory targets serialize an accepted RIB burst into ordered
|
||||
scalar RIBP accesses. They do not yet combine an `INCR4` request into a native
|
||||
SDRAM, PSRAM, or flash streaming transaction.
|
||||
|
||||
The generated address map, user-extension map, and
|
||||
[RIB protocol contract](rib-interconnect.md) remain the executable sources of
|
||||
truth for the implemented baseline.
|
||||
|
||||
### Planned Linux Configuration
|
||||
|
||||
The Linux configuration keeps Hazard3 as the always-available trusted
|
||||
management core and adds VexiiRiscv as the application processor. Hazard3 is
|
||||
responsible for clock and memory initialization, image selection, VexiiRiscv
|
||||
boot release, fault recovery, and final power-state control. Linux must not be
|
||||
able to reconfigure the management-core lifecycle controls.
|
||||
|
||||
The initial VexiiRiscv configuration should provide:
|
||||
|
||||
- RV32IMAC with machine, supervisor, and user modes.
|
||||
- Sv32 virtual memory, hardware page-table walking, and the privileged CSRs
|
||||
required by the supported Linux kernel.
|
||||
- LR/SC atomics, separate 16 KiB instruction and data caches, and uncached MMIO
|
||||
regions.
|
||||
- A PLIC-compatible external interrupt controller, CLINT-compatible timer and
|
||||
software interrupts, and a deterministic reset vector.
|
||||
- A documented DMA cache-maintenance contract unless the memory system supplies
|
||||
hardware coherency.
|
||||
|
||||
The management firmware initializes external memory, verifies and places the
|
||||
OpenSBI firmware, device tree, kernel, and initial filesystem, programs the
|
||||
VexiiRiscv entry point, and then enables its bus access and releases reset. A
|
||||
normal stop first requests Linux shutdown through a mailbox. After Linux
|
||||
acknowledges and flushes persistent data, the management core disables new bus
|
||||
transactions, drains the final accepted transaction, and asserts reset. A
|
||||
bounded timeout permits fault recovery through forced isolation and reset.
|
||||
|
||||
### Product Targets
|
||||
|
||||
The following values define a useful commercial target rather than an
|
||||
implemented or cross-PDK guarantee:
|
||||
|
||||
| Area | Minimum target | Preferred target |
|
||||
| --- | --- | --- |
|
||||
| VexiiRiscv frequency | 150 MHz | PDK-qualified maximum above 150 MHz |
|
||||
| Main memory | 64 MiB SDRAM | 128 MiB SDRAM |
|
||||
| L1 caches | 16 KiB I-cache and 16 KiB D-cache | Same, with measured refill and DMA behavior |
|
||||
| Memory transport | Native cache-line burst | Native burst with two to four outstanding transactions per master |
|
||||
| Boot storage | SPI NAND or qualified SDIO path | SDIO/eMMC plus recovery image |
|
||||
| Linux platform devices | UART, timer, interrupt controller, storage | Ethernet or USB selected by the product profile |
|
||||
|
||||
Meeting these targets requires enlarging the current 32 MiB SDRAM address
|
||||
window and replacing the scalar external-memory bottleneck. A dedicated memory
|
||||
fabric may evolve independently while RIBP and APB remain the stable peripheral
|
||||
register interfaces. Frequency claims must be qualified separately for each
|
||||
PDK and physical implementation.
|
||||
|
||||
### Commercial Reference Points
|
||||
|
||||
The products below are reference points along different axes. None is a
|
||||
pin-compatible or performance-equivalent substitute for retroSoC Mini.
|
||||
|
||||
| Commercial SoC | Relevant architecture | Comparison with the planned Mini |
|
||||
| --- | --- | --- |
|
||||
| [Bouffalo Lab BL808](https://github.com/bouffalolab/bl808_linux) | RISC-V Linux application core with separate MCU and low-power cores | Closest RISC-V heterogeneous architecture; substantially stronger wireless, multimedia, memory, and application-core capability |
|
||||
| [NXP i.MX 7ULP](https://www.nxp.com/products/i.MX7ULP) | Cortex-A7 Linux core and Cortex-M4 system master with boot and power-control responsibilities | Closest commercial lifecycle-control model; a much larger application-processor platform |
|
||||
| [ST STM32MP151](https://www.st.com/en/microcontrollers-microprocessors/stm32mp151a.html) | Single Cortex-A7 Linux core and Cortex-M4 real-time core | Useful industrial heterogeneous-MPU reference; DDR, cache, interconnect, and peripheral capabilities are substantially higher |
|
||||
| [CV1800B and SG2002](https://milkv.io/docs/duo/overview) | Two RISC-V application-class cores supporting Linux and real-time workloads, with 64 or 256 MiB SiP memory | Closest low-cost dual-system RISC-V market reference; 64-bit cores and multimedia acceleration place it above Mini |
|
||||
| [Allwinner F133](https://www.allwinnertech.com/index.php?c=product&id=101) | RV64 C906 Linux processor with 64 MiB SiP DDR and display/video functions | Direct low-cost RISC-V Linux market reference without the same independent management-core model |
|
||||
| [Allwinner F1C200s](https://www.allwinnertech.com/uploads/pdf/201812181725033b.pdf) | 32-bit ARM9 Linux processor with 64 MiB SiP DDR in a compact package | Closest cost, memory, and lightweight-Linux application reference, but without a separate management core |
|
||||
| [Ingenic X1000/X1000E](https://www.ingenic.com.cn/products-detail/id-50.html) | 32-bit MIPS Linux processor with 32 or 64 MiB LPDDR and fast-boot positioning | Comparable low-power Linux product segment with much higher CPU frequency and a mature multimedia subsystem |
|
||||
| [Espressif ESP32-P4](https://docs.espressif.com/projects/esp-techpedia/en/latest/esp-friends/get-started/board-selection.html) | Dual 32-bit RISC-V high-performance cores and a low-power core | Relevant core-topology and power-control reference, but not a direct general-purpose MMU Linux competitor |
|
||||
|
||||
The closest architectural reference points are BL808 and i.MX 7ULP. The
|
||||
closest cost and lightweight-Linux reference is F1C200s, while F133 and
|
||||
CV1800B represent the nearest commercial RISC-V Linux market. ESP32-P4 is a
|
||||
control-topology reference rather than a Linux performance reference.
|
||||
|
||||
After the Linux configuration meets the memory and interconnect targets above,
|
||||
retroSoC Mini should be positioned between F1C200s and BL808: less capable than
|
||||
modern 64-bit multimedia SoCs, but differentiated by open RTL and explicit
|
||||
management-core control over Linux-core boot, bus admission, shutdown, and
|
||||
fault recovery.
|
||||
|
||||
## Std: RV32 Heterogeneous Graphical Linux
|
||||
|
||||
### Position
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
// 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 CLINT_DEF_SV
|
||||
`define CLINT_DEF_SV
|
||||
|
||||
// verilog_format: off
|
||||
`define RIBP_CLINT_MTIMEL 8'h00
|
||||
`define RIBP_CLINT_MTIMEH 8'h04
|
||||
`define RIBP_CLINT_MTIMECMPL 8'h08
|
||||
`define RIBP_CLINT_MTIMECMPH 8'h0C
|
||||
`define RIBP_CLINT_MSIP 8'h10
|
||||
`define RIBP_CLINT_CLKDIV 8'h14
|
||||
// verilog_format: on
|
||||
|
||||
`endif
|
||||
|
||||
interface simp_clint_if ();
|
||||
logic tmr_irq_o;
|
||||
logic sfr_irq_o;
|
||||
|
||||
modport dut(output tmr_irq_o, output sfr_irq_o);
|
||||
endinterface
|
||||
|
||||
module ribp_clint (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
ribp_if.slave ribp,
|
||||
simp_clint_if.dut clint
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
logic s_ribp_wr_hdshk, s_ribp_rd_hdshk;
|
||||
logic s_ribp_ready_d, s_ribp_ready_q;
|
||||
logic s_ribp_rdata_en;
|
||||
logic [31:0] s_ribp_rdata_d, s_ribp_rdata_q;
|
||||
|
||||
logic s_clint_clkdiv_en;
|
||||
logic [7:0] s_clint_clkdiv_d, s_clint_clkdiv_q;
|
||||
logic s_clint_mtime_en;
|
||||
logic [63:0] s_clint_mtime_d, s_clint_mtime_q;
|
||||
logic s_clint_mtimecmp_en;
|
||||
logic [63:0] s_clint_mtimecmp_d, s_clint_mtimecmp_q;
|
||||
logic s_clint_msip_en;
|
||||
logic s_clint_msip_d, s_clint_msip_q;
|
||||
// utils
|
||||
logic [7:0] s_clk_cnt_d, s_clk_cnt_q;
|
||||
// pipelined 64-bit compare: split into hi32 and lo32 stages
|
||||
logic s_tmr_hi_gt, s_tmr_hi_eq, s_tmr_lo_ge;
|
||||
logic s_tmr_irq_d, s_tmr_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;
|
||||
|
||||
// pipelined 64-bit magnitude compare (registered output)
|
||||
assign s_tmr_hi_gt = s_clint_mtime_q[63:32] > s_clint_mtimecmp_q[63:32];
|
||||
assign s_tmr_hi_eq = s_clint_mtime_q[63:32] == s_clint_mtimecmp_q[63:32];
|
||||
assign s_tmr_lo_ge = s_clint_mtime_q[31:0] >= s_clint_mtimecmp_q[31:0];
|
||||
assign s_tmr_irq_d = s_tmr_hi_gt || (s_tmr_hi_eq && s_tmr_lo_ge);
|
||||
dffr #(1) u_tmr_irq_dffr (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_tmr_irq_d,
|
||||
s_tmr_irq_q
|
||||
);
|
||||
assign clint.tmr_irq_o = s_tmr_irq_q;
|
||||
assign clint.sfr_irq_o = s_clint_msip_q;
|
||||
|
||||
|
||||
assign s_clint_clkdiv_en = s_ribp_wr_hdshk && ribp.addr[7:0] == `RIBP_CLINT_CLKDIV;
|
||||
assign s_clint_clkdiv_d = ribp.wdata[7:0];
|
||||
dffer #(8) u_clint_clkdiv_dffer (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_clint_clkdiv_en,
|
||||
s_clint_clkdiv_d,
|
||||
s_clint_clkdiv_q
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
s_clk_cnt_d = s_clk_cnt_q;
|
||||
if (s_clk_cnt_q == s_clint_clkdiv_q) begin
|
||||
s_clk_cnt_d = '0;
|
||||
end else begin
|
||||
s_clk_cnt_d = s_clk_cnt_q + 1'b1;
|
||||
end
|
||||
end
|
||||
dffr #(8) u_clk_cnt_dffr (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_clk_cnt_d,
|
||||
s_clk_cnt_q
|
||||
);
|
||||
|
||||
|
||||
assign s_clint_mtime_en = s_clk_cnt_q == s_clint_clkdiv_q;
|
||||
assign s_clint_mtime_d = s_clint_mtime_q + 1'b1;
|
||||
dffer #(64) u_clint_mtime_dffer (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_clint_mtime_en,
|
||||
s_clint_mtime_d,
|
||||
s_clint_mtime_q
|
||||
);
|
||||
|
||||
|
||||
assign s_clint_mtimecmp_en = s_ribp_wr_hdshk && (ribp.addr[7:0] == `RIBP_CLINT_MTIMECMPL || ribp.addr[7:0] == `RIBP_CLINT_MTIMECMPH);
|
||||
always_comb begin
|
||||
s_clint_mtimecmp_d = s_clint_mtimecmp_q;
|
||||
if (ribp.addr[7:0] == `RIBP_CLINT_MTIMECMPL) begin
|
||||
if (ribp.wstrb[0]) s_clint_mtimecmp_d[7:0] = ribp.wdata[7:0];
|
||||
if (ribp.wstrb[1]) s_clint_mtimecmp_d[15:8] = ribp.wdata[15:8];
|
||||
if (ribp.wstrb[2]) s_clint_mtimecmp_d[23:16] = ribp.wdata[23:16];
|
||||
if (ribp.wstrb[3]) s_clint_mtimecmp_d[31:24] = ribp.wdata[31:24];
|
||||
end else if (ribp.addr[7:0] == `RIBP_CLINT_MTIMECMPH) begin
|
||||
if (ribp.wstrb[0]) s_clint_mtimecmp_d[39:32] = ribp.wdata[7:0];
|
||||
if (ribp.wstrb[1]) s_clint_mtimecmp_d[47:40] = ribp.wdata[15:8];
|
||||
if (ribp.wstrb[2]) s_clint_mtimecmp_d[55:48] = ribp.wdata[23:16];
|
||||
if (ribp.wstrb[3]) s_clint_mtimecmp_d[63:56] = ribp.wdata[31:24];
|
||||
end
|
||||
end
|
||||
dfferh #(64) u_clint_mtimecmp_dfferh (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_clint_mtimecmp_en,
|
||||
s_clint_mtimecmp_d,
|
||||
s_clint_mtimecmp_q
|
||||
);
|
||||
|
||||
|
||||
assign s_clint_msip_en = s_ribp_wr_hdshk && ribp.addr[7:0] == `RIBP_CLINT_MSIP;
|
||||
assign s_clint_msip_d = ribp.wdata[0];
|
||||
dffer #(1) u_clint_msip_dffer (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
s_clint_msip_en,
|
||||
s_clint_msip_d,
|
||||
s_clint_msip_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_CLINT_CLKDIV: s_ribp_rdata_d = {24'd0, s_clint_clkdiv_q};
|
||||
`RIBP_CLINT_MTIMEL: s_ribp_rdata_d = s_clint_mtime_q[31:0];
|
||||
`RIBP_CLINT_MTIMEH: s_ribp_rdata_d = s_clint_mtime_q[63:32];
|
||||
`RIBP_CLINT_MTIMECMPL: s_ribp_rdata_d = s_clint_mtimecmp_q[31:0];
|
||||
`RIBP_CLINT_MTIMECMPH: s_ribp_rdata_d = s_clint_mtimecmp_q[63:32];
|
||||
`RIBP_CLINT_MSIP: s_ribp_rdata_d = {31'd0, s_clint_msip_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,58 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module clint_core #(
|
||||
parameter int HART_NUM = 1
|
||||
) (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
input logic tick_i,
|
||||
input logic mtime_load_i,
|
||||
input logic [63:0] mtime_load_value_i,
|
||||
input logic [63:0] mtimecmp_i [0:HART_NUM-1],
|
||||
output logic [63:0] mtime_o,
|
||||
output logic [HART_NUM-1:0] timer_irq_o
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
logic [HART_NUM-1:0] s_timer_irq_d, s_timer_irq_q;
|
||||
|
||||
initial begin
|
||||
if ((HART_NUM < 1) || (HART_NUM > 4095)) begin
|
||||
$fatal(1, "clint_core: HART_NUM must be between 1 and 4095");
|
||||
end
|
||||
end
|
||||
|
||||
// MTIME wraps modulo 2^64, so the Common carry output is intentionally unused.
|
||||
/* verilator lint_off PINCONNECTEMPTY */
|
||||
rs_counter #(
|
||||
.DATA_WIDTH(64)
|
||||
) u_mtime_counter (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.clr_i (1'b0),
|
||||
.en_i (tick_i),
|
||||
.load_i (mtime_load_i),
|
||||
.down_i (1'b0),
|
||||
.dat_i (mtime_load_value_i),
|
||||
.dat_o (mtime_o),
|
||||
.ovf_o ()
|
||||
);
|
||||
/* verilator lint_on PINCONNECTEMPTY */
|
||||
|
||||
always_comb begin
|
||||
for (int hart = 0; hart < HART_NUM; hart++) begin
|
||||
s_timer_irq_d[hart] = mtime_o >= mtimecmp_i[hart];
|
||||
end
|
||||
end
|
||||
dffr #(HART_NUM) u_timer_irq_dffr (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_timer_irq_d),
|
||||
.dat_o (s_timer_irq_q)
|
||||
);
|
||||
|
||||
assign timer_irq_o = s_timer_irq_q;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2023-2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
`ifndef CLINT_DEFINE_SVH
|
||||
`define CLINT_DEFINE_SVH
|
||||
|
||||
// verilog_format: off
|
||||
`define RIBP_CLINT_MSIP 16'h0000
|
||||
`define RIBP_CLINT_MTIMECMP 16'h4000
|
||||
`define RIBP_CLINT_MTIME 16'hBFF8
|
||||
`define RIBP_CLINT_MTIMEH 16'hBFFC
|
||||
|
||||
`define CLINT_MSIP_STRIDE 16'h0004
|
||||
`define CLINT_MTIMECMP_STRIDE 16'h0008
|
||||
// verilog_format: on
|
||||
|
||||
`endif
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright (c) 2023-2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
interface clint_if #(
|
||||
parameter int HART_NUM = 1
|
||||
) ();
|
||||
logic [HART_NUM-1:0] timer_irq_o;
|
||||
logic [HART_NUM-1:0] software_irq_o;
|
||||
|
||||
modport dut(output timer_irq_o, output software_irq_o);
|
||||
endinterface
|
||||
@@ -0,0 +1,191 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
`include "clint_define.svh"
|
||||
|
||||
module clint_reg #(
|
||||
parameter int HART_NUM = 1
|
||||
) (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
ribp_if.slave ribp,
|
||||
input logic [63:0] mtime_i,
|
||||
output logic mtime_load_o,
|
||||
output logic [63:0] mtime_load_value_o,
|
||||
output logic [HART_NUM-1:0] msip_o,
|
||||
output logic [63:0] mtimecmp_o [0:HART_NUM-1]
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
localparam int HART_INDEX_WIDTH = HART_NUM > 1 ? $clog2(HART_NUM) : 1;
|
||||
localparam logic [11:0] HART_COUNT = 12'(HART_NUM);
|
||||
|
||||
logic s_req;
|
||||
logic s_write;
|
||||
logic s_req_accept;
|
||||
logic [15:0] s_offset;
|
||||
logic s_aligned;
|
||||
logic s_access_error;
|
||||
logic s_msip_select;
|
||||
logic s_mtimecmp_select;
|
||||
logic s_mtimecmp_high;
|
||||
logic s_mtime_select;
|
||||
logic s_mtime_high;
|
||||
logic [11:0] s_msip_hart;
|
||||
logic [11:0] s_mtimecmp_hart;
|
||||
|
||||
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 [HART_NUM-1:0] s_msip_en;
|
||||
logic [HART_NUM-1:0] s_msip_d, s_msip_q;
|
||||
logic [HART_NUM-1:0] s_mtimecmp_en;
|
||||
logic [ 63:0] s_mtimecmp_d [0:HART_NUM-1];
|
||||
logic [ 63:0] s_mtimecmp_q [0:HART_NUM-1];
|
||||
|
||||
function automatic logic [31:0] merge_wstrb(input logic [31:0] current, input logic [31:0] value,
|
||||
input logic [3:0] strobe);
|
||||
logic [31:0] merged;
|
||||
integer byte_index;
|
||||
begin
|
||||
merged = current;
|
||||
for (byte_index = 0; byte_index < 4; byte_index = byte_index + 1) begin
|
||||
if (strobe[byte_index]) begin
|
||||
merged[byte_index*8+:8] = value[byte_index*8+:8];
|
||||
end
|
||||
end
|
||||
return merged;
|
||||
end
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
if ((HART_NUM < 1) || (HART_NUM > 4095)) begin
|
||||
$fatal(1, "clint_reg: HART_NUM must be between 1 and 4095");
|
||||
end
|
||||
end
|
||||
|
||||
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[15:0];
|
||||
assign s_aligned = ribp.addr[1:0] == 2'b00;
|
||||
|
||||
assign s_msip_hart = s_offset[13:2];
|
||||
assign s_mtimecmp_hart = s_offset[14:3] - 12'h800;
|
||||
assign s_msip_select = (s_offset < `RIBP_CLINT_MTIMECMP) && (s_msip_hart < HART_COUNT);
|
||||
assign s_mtimecmp_select = (s_offset >= `RIBP_CLINT_MTIMECMP) &&
|
||||
(s_offset < `RIBP_CLINT_MTIME) &&
|
||||
(s_mtimecmp_hart < HART_COUNT);
|
||||
assign s_mtimecmp_high = s_offset[2];
|
||||
assign s_mtime_select = (s_offset == `RIBP_CLINT_MTIME) || (s_offset == `RIBP_CLINT_MTIMEH);
|
||||
assign s_mtime_high = s_offset == `RIBP_CLINT_MTIMEH;
|
||||
|
||||
assign ribp.ready = s_ribp_ready_q;
|
||||
assign ribp.rdata = s_ribp_rdata_q;
|
||||
assign ribp.resp_err = s_ribp_resp_err_q;
|
||||
|
||||
always_comb begin
|
||||
s_access_error = !s_aligned || !(s_msip_select || s_mtimecmp_select || s_mtime_select);
|
||||
s_ribp_rdata_d = '0;
|
||||
if (s_aligned) begin
|
||||
if (s_msip_select) begin
|
||||
s_ribp_rdata_d = {31'd0, s_msip_q[s_msip_hart[HART_INDEX_WIDTH-1:0]]};
|
||||
end else if (s_mtimecmp_select) begin
|
||||
if (s_mtimecmp_high) begin
|
||||
s_ribp_rdata_d = s_mtimecmp_q[s_mtimecmp_hart[HART_INDEX_WIDTH-1:0]][63:32];
|
||||
end else begin
|
||||
s_ribp_rdata_d = s_mtimecmp_q[s_mtimecmp_hart[HART_INDEX_WIDTH-1:0]][31:0];
|
||||
end
|
||||
end else if (s_mtime_select) begin
|
||||
s_ribp_rdata_d = s_mtime_high ? mtime_i[63:32] : mtime_i[31:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
s_msip_en = '0;
|
||||
s_msip_d = s_msip_q;
|
||||
if (s_req_accept && s_write && !s_access_error && s_msip_select && ribp.wstrb[0]) begin
|
||||
s_msip_en[s_msip_hart[HART_INDEX_WIDTH-1:0]] = 1'b1;
|
||||
s_msip_d[s_msip_hart[HART_INDEX_WIDTH-1:0]] = ribp.wdata[0];
|
||||
end
|
||||
end
|
||||
for (genvar hart = 0; hart < HART_NUM; hart++) begin : gen_msip
|
||||
dffer #(1) u_msip_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_msip_en[hart]),
|
||||
.dat_i (s_msip_d[hart]),
|
||||
.dat_o (s_msip_q[hart])
|
||||
);
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
s_mtimecmp_en = '0;
|
||||
for (int hart = 0; hart < HART_NUM; hart++) begin
|
||||
s_mtimecmp_d[hart] = s_mtimecmp_q[hart];
|
||||
end
|
||||
if (s_req_accept && s_write && !s_access_error && s_mtimecmp_select) begin
|
||||
s_mtimecmp_en[s_mtimecmp_hart[HART_INDEX_WIDTH-1:0]] = 1'b1;
|
||||
if (s_mtimecmp_high) begin
|
||||
s_mtimecmp_d[s_mtimecmp_hart[HART_INDEX_WIDTH-1:0]][63:32] = merge_wstrb(
|
||||
s_mtimecmp_q[s_mtimecmp_hart[HART_INDEX_WIDTH-1:0]][63:32], ribp.wdata, ribp.wstrb);
|
||||
end else begin
|
||||
s_mtimecmp_d[s_mtimecmp_hart[HART_INDEX_WIDTH-1:0]][31:0] = merge_wstrb(
|
||||
s_mtimecmp_q[s_mtimecmp_hart[HART_INDEX_WIDTH-1:0]][31:0], ribp.wdata, ribp.wstrb);
|
||||
end
|
||||
end
|
||||
end
|
||||
for (genvar hart = 0; hart < HART_NUM; hart++) begin : gen_mtimecmp
|
||||
dfferh #(64) u_mtimecmp_dfferh (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_mtimecmp_en[hart]),
|
||||
.dat_i (s_mtimecmp_d[hart]),
|
||||
.dat_o (s_mtimecmp_q[hart])
|
||||
);
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
mtime_load_o = 1'b0;
|
||||
mtime_load_value_o = mtime_i;
|
||||
if (s_req_accept && s_write && !s_access_error && s_mtime_select) begin
|
||||
mtime_load_o = 1'b1;
|
||||
if (s_mtime_high) begin
|
||||
mtime_load_value_o[63:32] = merge_wstrb(mtime_i[63:32], ribp.wdata, ribp.wstrb);
|
||||
end else begin
|
||||
mtime_load_value_o[31:0] = merge_wstrb(mtime_i[31:0], ribp.wdata, ribp.wstrb);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign msip_o = s_msip_q;
|
||||
assign mtimecmp_o = s_mtimecmp_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 (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (s_ribp_ready_d),
|
||||
.dat_o (s_ribp_ready_q)
|
||||
);
|
||||
dffer #(1) u_ribp_resp_err_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_req_accept),
|
||||
.dat_i (s_ribp_resp_err_d),
|
||||
.dat_o (s_ribp_resp_err_q)
|
||||
);
|
||||
dffer #(32) u_ribp_rdata_dffer (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.en_i (s_req_accept),
|
||||
.dat_i (s_ribp_rdata_d),
|
||||
.dat_o (s_ribp_rdata_q)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module clint_timebase #(
|
||||
parameter int REF_CLK_HZ = 72_000_000,
|
||||
parameter int TIMEBASE_HZ = 1_000_000,
|
||||
parameter int CDC_STAGE = 2
|
||||
) (
|
||||
// verilog_format: off
|
||||
input logic ref_clk_i,
|
||||
input logic ref_rst_n_i,
|
||||
input logic sys_clk_i,
|
||||
input logic sys_rst_n_i,
|
||||
output logic tick_o
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
localparam int DIVISOR = REF_CLK_HZ / TIMEBASE_HZ;
|
||||
localparam int DIV_WIDTH = DIVISOR > 1 ? $clog2(DIVISOR) : 1;
|
||||
|
||||
logic [DIV_WIDTH-1:0] s_div_count;
|
||||
logic s_div_terminal;
|
||||
logic s_tick_toggle_d, s_tick_toggle_q;
|
||||
logic s_tick_toggle_sync;
|
||||
logic s_tick_re, s_tick_fe;
|
||||
|
||||
initial begin
|
||||
if ((REF_CLK_HZ <= 0) || (TIMEBASE_HZ <= 0) || (REF_CLK_HZ < TIMEBASE_HZ) ||
|
||||
((REF_CLK_HZ % TIMEBASE_HZ) != 0)) begin
|
||||
$fatal(1, "clint_timebase: REF_CLK_HZ must be a positive multiple of TIMEBASE_HZ");
|
||||
end
|
||||
end
|
||||
|
||||
assign s_div_terminal = s_div_count == DIV_WIDTH'(DIVISOR - 1);
|
||||
|
||||
// The divider clears before its natural carry; the Common carry output is intentionally unused.
|
||||
/* verilator lint_off PINCONNECTEMPTY */
|
||||
rs_counter #(
|
||||
.DATA_WIDTH(DIV_WIDTH)
|
||||
) u_div_counter (
|
||||
.clk_i (ref_clk_i),
|
||||
.rst_n_i(ref_rst_n_i),
|
||||
.clr_i (s_div_terminal),
|
||||
.en_i (1'b1),
|
||||
.load_i (1'b0),
|
||||
.down_i (1'b0),
|
||||
.dat_i ('0),
|
||||
.dat_o (s_div_count),
|
||||
.ovf_o ()
|
||||
);
|
||||
/* verilator lint_on PINCONNECTEMPTY */
|
||||
|
||||
assign s_tick_toggle_d = s_div_terminal ? ~s_tick_toggle_q : s_tick_toggle_q;
|
||||
dffr #(1) u_tick_toggle_dffr (
|
||||
.clk_i (ref_clk_i),
|
||||
.rst_n_i(ref_rst_n_i),
|
||||
.dat_i (s_tick_toggle_d),
|
||||
.dat_o (s_tick_toggle_q)
|
||||
);
|
||||
|
||||
edge_det #(
|
||||
.STAGE(CDC_STAGE)
|
||||
) u_tick_edge_det (
|
||||
.clk_i (sys_clk_i),
|
||||
.rst_n_i(sys_rst_n_i),
|
||||
.dat_i (s_tick_toggle_q),
|
||||
.dat_o (s_tick_toggle_sync),
|
||||
.re_o (s_tick_re),
|
||||
.fe_o (s_tick_fe)
|
||||
);
|
||||
|
||||
assign tick_o = (s_tick_re && !s_tick_toggle_sync) || (s_tick_fe && s_tick_toggle_sync);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2023-2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module ribp_clint #(
|
||||
parameter int HART_NUM = 1
|
||||
) (
|
||||
// verilog_format: off
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
input logic timebase_tick_i,
|
||||
ribp_if.slave ribp,
|
||||
clint_if.dut clint
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
logic s_mtime_load;
|
||||
logic [ 63:0] s_mtime_load_value;
|
||||
logic [ 63:0] s_mtime;
|
||||
logic [HART_NUM-1:0] s_msip;
|
||||
logic [ 63:0] s_mtimecmp [0:HART_NUM-1];
|
||||
logic [HART_NUM-1:0] s_timer_irq;
|
||||
|
||||
clint_reg #(
|
||||
.HART_NUM(HART_NUM)
|
||||
) u_clint_reg (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.ribp (ribp),
|
||||
.mtime_i (s_mtime),
|
||||
.mtime_load_o (s_mtime_load),
|
||||
.mtime_load_value_o(s_mtime_load_value),
|
||||
.msip_o (s_msip),
|
||||
.mtimecmp_o (s_mtimecmp)
|
||||
);
|
||||
|
||||
clint_core #(
|
||||
.HART_NUM(HART_NUM)
|
||||
) u_clint_core (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.tick_i (timebase_tick_i),
|
||||
.mtime_load_i (s_mtime_load),
|
||||
.mtime_load_value_i(s_mtime_load_value),
|
||||
.mtimecmp_i (s_mtimecmp),
|
||||
.mtime_o (s_mtime),
|
||||
.timer_irq_o (s_timer_irq)
|
||||
);
|
||||
|
||||
assign clint.software_irq_o = s_msip;
|
||||
assign clint.timer_irq_o = s_timer_irq;
|
||||
|
||||
endmodule
|
||||
@@ -47,7 +47,7 @@
|
||||
{"symbol": "RIBP_XPI", "base": "0x10009000", "size": "0x00001000", "route": "ribp", "kind": "active", "public": true, "user_access": "none"},
|
||||
{"symbol": "RIBP_DMA", "base": "0x1000A000", "size": "0x00001000", "route": "ribp", "kind": "active", "public": true, "user_access": "none"},
|
||||
{"symbol": "RIBP_SYSCTRL", "base": "0x1000B000", "size": "0x00001000", "route": "ribp", "kind": "active", "public": true, "user_access": "none"},
|
||||
{"symbol": "RIBP_CLINT", "base": "0x1000C000", "size": "0x00001000", "route": "ribp", "kind": "active", "public": true, "user_access": "none"},
|
||||
{"symbol": "RIBP_CLINT", "base": "0x10020000", "size": "0x00010000", "route": "ribp", "kind": "active", "public": true, "user_access": "none"},
|
||||
{"symbol": "RIBP_SDRAM", "base": "0x1000D000", "size": "0x00001000", "route": "ribp", "kind": "active", "public": true, "user_access": "none"},
|
||||
{"symbol": "RIBP_DVP", "base": "0x1000E000", "size": "0x00001000", "route": "ribp", "kind": "active", "public": true, "user_access": "rw"},
|
||||
{"symbol": "RIBP_SDIO", "base": "0x1000F000", "size": "0x00001000", "route": "reserved", "kind": "reserved", "public": false, "user_access": "none"},
|
||||
|
||||
@@ -32,7 +32,11 @@
|
||||
/ip/ribp/peripheral/dma.sv
|
||||
/ip/ribp/peripheral/pll_ctrl_if.sv
|
||||
/ip/ribp/peripheral/sysctrl.sv
|
||||
/ip/ribp/peripheral/clint.sv
|
||||
/ip/ribp/peripheral/clint_if.sv
|
||||
/ip/ribp/peripheral/clint_timebase.sv
|
||||
/ip/ribp/peripheral/clint_reg.sv
|
||||
/ip/ribp/peripheral/clint_core.sv
|
||||
/ip/ribp/peripheral/ribp_clint.sv
|
||||
/ip/ribp/memory/sdram_clkgen.sv
|
||||
/ip/ribp/memory/sdram_reg.sv
|
||||
/ip/ribp/memory/sdram_core.sv
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module clint_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 tick,
|
||||
output logic [63:0] mtime,
|
||||
output logic mtime_load,
|
||||
output logic [63:0] mtime_load_value,
|
||||
output logic [ 1:0] msip,
|
||||
output logic [ 1:0] timer_irq_next,
|
||||
output logic [ 1:0] timer_irq
|
||||
// verilog_format: on
|
||||
);
|
||||
|
||||
ribp_if ribp ();
|
||||
(* 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_tick;
|
||||
logic s_mtime_load;
|
||||
logic [63:0] s_mtime_load_value;
|
||||
logic [63:0] s_mtime;
|
||||
logic [ 1:0] s_msip;
|
||||
logic [63:0] s_mtimecmp [0:1];
|
||||
logic [ 1:0] s_timer_irq;
|
||||
|
||||
assign ribp.valid = f_rib_valid;
|
||||
assign ribp.addr = f_rib_addr;
|
||||
assign ribp.wdata = f_rib_wdata;
|
||||
assign ribp.wstrb = f_rib_wstrb;
|
||||
|
||||
assign rib_valid = ribp.valid;
|
||||
assign rib_addr = ribp.addr;
|
||||
assign rib_wdata = ribp.wdata;
|
||||
assign rib_wstrb = ribp.wstrb;
|
||||
assign rib_ready = ribp.ready;
|
||||
assign rib_resp_err = ribp.resp_err;
|
||||
assign tick = f_tick;
|
||||
assign mtime = s_mtime;
|
||||
assign mtime_load = s_mtime_load;
|
||||
assign mtime_load_value = s_mtime_load_value;
|
||||
assign msip = s_msip;
|
||||
assign timer_irq_next[0] = s_mtime >= s_mtimecmp[0];
|
||||
assign timer_irq_next[1] = s_mtime >= s_mtimecmp[1];
|
||||
assign timer_irq = s_timer_irq;
|
||||
|
||||
clint_reg #(
|
||||
.HART_NUM(2)
|
||||
) u_clint_reg (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.ribp (ribp),
|
||||
.mtime_i (s_mtime),
|
||||
.mtime_load_o (s_mtime_load),
|
||||
.mtime_load_value_o(s_mtime_load_value),
|
||||
.msip_o (s_msip),
|
||||
.mtimecmp_o (s_mtimecmp)
|
||||
);
|
||||
|
||||
clint_core #(
|
||||
.HART_NUM(2)
|
||||
) u_clint_core (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.tick_i (f_tick),
|
||||
.mtime_load_i (s_mtime_load),
|
||||
.mtime_load_value_i(s_mtime_load_value),
|
||||
.mtimecmp_i (s_mtimecmp),
|
||||
.mtime_o (s_mtime),
|
||||
.timer_irq_o (s_timer_irq)
|
||||
);
|
||||
|
||||
initial begin
|
||||
rst_n_i = 1'b1;
|
||||
f_past_valid = 1'b0;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
rst_n_i <= f_past_valid;
|
||||
f_past_valid <= 1'b1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
module clint_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 tick;
|
||||
wire [63:0] mtime;
|
||||
wire mtime_load;
|
||||
wire [63:0] mtime_load_value;
|
||||
wire [ 1:0] msip;
|
||||
wire [ 1:0] timer_irq_next;
|
||||
wire [ 1:0] timer_irq;
|
||||
|
||||
clint_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 (f_past_valid && !$past(rst_n_i)) begin
|
||||
assert (mtime == 64'd0);
|
||||
assert (msip == 2'b00);
|
||||
assert (timer_irq == 2'b00);
|
||||
end
|
||||
|
||||
if (rst_n_i) begin
|
||||
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)) begin
|
||||
assert (timer_irq == $past(timer_irq_next));
|
||||
if ($past(mtime_load)) begin
|
||||
assert (mtime == $past(mtime_load_value));
|
||||
end else if ($past(tick)) begin
|
||||
assert (mtime == $past(mtime) + 64'd1);
|
||||
end else begin
|
||||
assert (mtime == $past(mtime));
|
||||
end
|
||||
end
|
||||
|
||||
cover (msip[0]);
|
||||
cover (timer_irq[0]);
|
||||
cover (rib_ready && rib_resp_err);
|
||||
cover (mtime_load);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -75,7 +75,10 @@ def source_files(target: str) -> list[Path]:
|
||||
COMMON_RTL / "cdc/cdc_rst_ctrlr.sv",
|
||||
COMMON_RTL / "cdc/cdc_2phase.sv",
|
||||
COMMON_RTL / "clkrst/rst_sync.sv",
|
||||
COMMON_RTL / "clkrst/counter.sv",
|
||||
COMMON_RTL / "utils/edge_det.sv",
|
||||
PERIPHERAL / "pll_ctrl_if.sv",
|
||||
PERIPHERAL / "clint_timebase.sv",
|
||||
TOP / "rcu.sv",
|
||||
SCRIPT_DIR / "pll_rcu_formal.sv",
|
||||
]
|
||||
@@ -109,6 +112,17 @@ def source_files(target: str) -> list[Path]:
|
||||
PERIPHERAL / "ribp_timer.sv",
|
||||
SCRIPT_DIR / "timer_formal.sv",
|
||||
]
|
||||
if target == "clint":
|
||||
return [
|
||||
COMMON_RTL / "interface/ribp_if.sv",
|
||||
COMMON_RTL / "utils/register.sv",
|
||||
COMMON_RTL / "clkrst/counter.sv",
|
||||
PERIPHERAL / "clint_if.sv",
|
||||
PERIPHERAL / "clint_reg.sv",
|
||||
PERIPHERAL / "clint_core.sv",
|
||||
PERIPHERAL / "ribp_clint.sv",
|
||||
SCRIPT_DIR / "clint_formal.sv",
|
||||
]
|
||||
raise ValueError(f"unsupported formal target: {target}")
|
||||
|
||||
|
||||
@@ -151,6 +165,7 @@ def parse_args() -> argparse.Namespace:
|
||||
"gpio_user",
|
||||
"ws2812",
|
||||
"timer",
|
||||
"clint",
|
||||
),
|
||||
required=True,
|
||||
)
|
||||
|
||||
@@ -95,6 +95,14 @@
|
||||
"path": "rtl/mini/top/rcu.sv",
|
||||
"instance": "u_pll_response_cdc"
|
||||
},
|
||||
{
|
||||
"name": "clint_timebase",
|
||||
"source": "external",
|
||||
"destination": "system",
|
||||
"primitive": "edge_det",
|
||||
"path": "rtl/ip/ribp/peripheral/clint_timebase.sv",
|
||||
"instance": "u_tick_edge_det"
|
||||
},
|
||||
{
|
||||
"name": "dvp_enable",
|
||||
"source": "system",
|
||||
|
||||
@@ -27,8 +27,8 @@ FABRIC_PROTOCOLS = {
|
||||
IRQ_GROUP_NAMES = ("ribp", "apb")
|
||||
IRQ_VECTOR_WIDTH = 32
|
||||
COMPATIBILITY_IRQ_BINDINGS = (
|
||||
("clint_software", "ribp", 0, 0, "u_clint_if.sfr_irq_o"),
|
||||
("clint_timer", "ribp", 1, 1, "u_clint_if.tmr_irq_o"),
|
||||
("clint_software", "ribp", 0, 0, "u_clint_if.software_irq_o[0]"),
|
||||
("clint_timer", "ribp", 1, 1, "u_clint_if.timer_irq_o[0]"),
|
||||
("uart0", "ribp", 2, 2, "uart.irq_o"),
|
||||
("timer0", "ribp", 3, 3, "s_tim0_irq"),
|
||||
("timer1", "ribp", 4, 4, "s_tim1_irq"),
|
||||
@@ -102,6 +102,7 @@ class Interrupt:
|
||||
group_bit: int
|
||||
core_bit: int
|
||||
signal: str
|
||||
user_visible: bool
|
||||
|
||||
|
||||
def atomic_write(path: Path, content: str) -> None:
|
||||
@@ -442,6 +443,9 @@ def parse_interrupts(value: Any, groups: list[IrqGroup], vector_width: int) -> l
|
||||
group_bit = interrupt.get("group_bit")
|
||||
core_bit = interrupt.get("core_bit")
|
||||
signal = require_value(interrupt.get("signal"), f"interrupts[{index}].signal")
|
||||
user_visible = interrupt.get("user_visible", True)
|
||||
if not isinstance(user_visible, bool):
|
||||
raise ValueError(f"interrupts[{index}].user_visible must be boolean")
|
||||
if group not in group_widths:
|
||||
raise ValueError(f"interrupts[{index}].group is not a supported interrupt group")
|
||||
if not isinstance(group_bit, int) or not 0 <= group_bit < group_widths[group]:
|
||||
@@ -457,7 +461,9 @@ def parse_interrupts(value: Any, groups: list[IrqGroup], vector_width: int) -> l
|
||||
names.add(name)
|
||||
group_bits[group].add(group_bit)
|
||||
core_bits.add(core_bit)
|
||||
interrupts.append(Interrupt(name, description, group, group_bit, core_bit, signal))
|
||||
interrupts.append(
|
||||
Interrupt(name, description, group, group_bit, core_bit, signal, user_visible)
|
||||
)
|
||||
|
||||
for group in groups:
|
||||
expected = set(range(group.width))
|
||||
@@ -768,13 +774,19 @@ def irq_width_macro(group: IrqGroup) -> str:
|
||||
return f"SOC_IRQ_{group.name.upper()}_WIDTH"
|
||||
|
||||
|
||||
def render_irq_config(vector_width: int, groups: list[IrqGroup]) -> str:
|
||||
def render_irq_config(
|
||||
vector_width: int, groups: list[IrqGroup], interrupts: list[Interrupt]
|
||||
) -> str:
|
||||
user_irq_mask = sum(
|
||||
1 << interrupt.core_bit for interrupt in interrupts if interrupt.user_visible
|
||||
)
|
||||
lines = [
|
||||
"// Generated by rtl/mini/integration/generate_soc_topology.py; do not edit.",
|
||||
"`ifndef RETROSOC_SOC_IRQ_CONFIG_SVH",
|
||||
"`define RETROSOC_SOC_IRQ_CONFIG_SVH",
|
||||
"",
|
||||
f"`define SOC_IRQ_VECTOR_WIDTH {vector_width}",
|
||||
f"`define SOC_USER_IRQ_MASK {vector_width}'h{user_irq_mask:0{vector_width // 4}X}",
|
||||
]
|
||||
lines.extend(f"`define {irq_width_macro(group)} {group.width}" for group in groups)
|
||||
lines.extend(["", "`endif"])
|
||||
@@ -909,7 +921,10 @@ def generate(topology_path: Path, memory_map_path: Path, output_dir: Path) -> No
|
||||
render_fabric_connection(fabric_links, "apb", "rib"),
|
||||
)
|
||||
atomic_write(rtl_dir / "soc_gpio_alt_bindings.svh", render_gpio_bindings(gpio_functions))
|
||||
atomic_write(rtl_dir / "soc_irq_config.svh", render_irq_config(irq_vector_width, irq_groups))
|
||||
atomic_write(
|
||||
rtl_dir / "soc_irq_config.svh",
|
||||
render_irq_config(irq_vector_width, irq_groups, interrupts),
|
||||
)
|
||||
for group in irq_groups:
|
||||
filename = f"{group.name}_irq_bindings.svh"
|
||||
if group.name != "ribp":
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
{"name": "apb", "width": 7, "top_signal": "s_apb_irq"}
|
||||
],
|
||||
"interrupts": [
|
||||
{"name": "clint_software", "description": "CLINT machine software interrupt", "group": "ribp", "group_bit": 0, "core_bit": 0, "signal": "u_clint_if.sfr_irq_o"},
|
||||
{"name": "clint_timer", "description": "CLINT machine timer interrupt", "group": "ribp", "group_bit": 1, "core_bit": 1, "signal": "u_clint_if.tmr_irq_o"},
|
||||
{"name": "clint_software", "description": "CLINT machine software interrupt", "group": "ribp", "group_bit": 0, "core_bit": 0, "signal": "u_clint_if.software_irq_o[0]", "user_visible": false},
|
||||
{"name": "clint_timer", "description": "CLINT machine timer interrupt", "group": "ribp", "group_bit": 1, "core_bit": 1, "signal": "u_clint_if.timer_irq_o[0]", "user_visible": false},
|
||||
{"name": "uart0", "description": "RIBP UART0 interrupt", "group": "ribp", "group_bit": 2, "core_bit": 2, "signal": "uart.irq_o"},
|
||||
{"name": "timer0", "description": "RIBP timer0 interrupt", "group": "ribp", "group_bit": 3, "core_bit": 3, "signal": "s_tim0_irq"},
|
||||
{"name": "timer1", "description": "RIBP timer1 interrupt", "group": "ribp", "group_bit": 4, "core_bit": 4, "signal": "s_tim1_irq"},
|
||||
|
||||
+14
-4
@@ -6,9 +6,10 @@ FORMAL_SOLVER_DIR := $(FORMAL_DIR)/bin
|
||||
FORMAL_SOLVER_WRAPPER := $(FORMAL_SOLVER_DIR)/bitwuzla
|
||||
FORMAL_DEPTH ?= 20
|
||||
FORMAL_WS2812_DEPTH ?= 120
|
||||
FORMAL_CLINT_DEPTH ?= 32
|
||||
FORMAL_TIMEOUT ?= 60
|
||||
FORMAL_WS2812_TIMEOUT ?= 120
|
||||
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio_user ws2812 timer
|
||||
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio_user ws2812 timer clint
|
||||
FORMAL_FILELIST_GENERATOR := $(RTL_PATH)/formal/generate_formal_filelist.py
|
||||
FORMAL_SBY_GENERATOR := $(RTL_PATH)/formal/generate_sby_config.py
|
||||
FORMAL_RESULT_GENERATOR := $(RTL_PATH)/formal/formal_results.py
|
||||
@@ -28,6 +29,8 @@ FORMAL_SOURCE_FILES := $(RTL_PATH)/formal/bus_formal.sv \
|
||||
$(RTL_PATH)/formal/ws2812_formal_props.sv \
|
||||
$(RTL_PATH)/formal/timer_formal.sv \
|
||||
$(RTL_PATH)/formal/timer_formal_props.sv \
|
||||
$(RTL_PATH)/formal/clint_formal.sv \
|
||||
$(RTL_PATH)/formal/clint_formal_props.sv \
|
||||
$(RTL_PATH)/top/bus.sv \
|
||||
$(RTL_PATH)/top/rib_error_slave.sv \
|
||||
$(RTL_PATH)/top/rib_if.sv \
|
||||
@@ -47,6 +50,11 @@ FORMAL_SOURCE_FILES := $(RTL_PATH)/formal/bus_formal.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/ip/ribp/peripheral/clint_define.svh \
|
||||
$(ROOT_PATH)/rtl/ip/ribp/peripheral/clint_if.sv \
|
||||
$(ROOT_PATH)/rtl/ip/ribp/peripheral/clint_reg.sv \
|
||||
$(ROOT_PATH)/rtl/ip/ribp/peripheral/clint_core.sv \
|
||||
$(ROOT_PATH)/rtl/ip/ribp/peripheral/ribp_clint.sv \
|
||||
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/clkrst/counter.sv \
|
||||
$(RTL_PATH)/top/rcu.sv \
|
||||
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/interface/ribp_if.sv \
|
||||
@@ -86,13 +94,13 @@ $(FORMAL_DIR)/%/prove.sby: $(FORMAL_DIR)/%/design.v $(RTL_PATH)/formal/%_formal_
|
||||
$(FORMAL_SBY_GENERATOR)
|
||||
python3 $(FORMAL_SBY_GENERATOR) --top $*_formal --input $< \
|
||||
--properties $(RTL_PATH)/formal/$*_formal_props.sv --solver $(FORMAL_SOLVER) \
|
||||
--mode prove --depth $(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(FORMAL_DEPTH)) --output $@
|
||||
--mode prove --depth $(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(if $(filter clint,$*),$(FORMAL_CLINT_DEPTH),$(FORMAL_DEPTH))) --output $@
|
||||
|
||||
$(FORMAL_DIR)/%/cover.sby: $(FORMAL_DIR)/%/design.v $(RTL_PATH)/formal/%_formal_props.sv \
|
||||
$(FORMAL_SBY_GENERATOR)
|
||||
python3 $(FORMAL_SBY_GENERATOR) --top $*_formal --input $< \
|
||||
--properties $(RTL_PATH)/formal/$*_formal_props.sv --solver $(FORMAL_SOLVER) \
|
||||
--mode cover --depth $(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(FORMAL_DEPTH)) --output $@
|
||||
--mode cover --depth $(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(if $(filter clint,$*),$(FORMAL_CLINT_DEPTH),$(FORMAL_DEPTH))) --output $@
|
||||
|
||||
$(FORMAL_SOLVER_WRAPPER): $(ROOT_PATH)/scripts/bitwuzla_smt2.py
|
||||
@mkdir -p $(@D)
|
||||
@@ -144,10 +152,12 @@ formal-ws2812: $(FORMAL_DIR)/ws2812/.stamp | manifest
|
||||
|
||||
formal-timer: $(FORMAL_DIR)/timer/.stamp | manifest
|
||||
|
||||
formal-clint: $(FORMAL_DIR)/clint/.stamp | manifest
|
||||
|
||||
formal-doctor:
|
||||
$(MAKE) FORMAL=YES SIMU=IVERILOG SYNTH=YOSYS STA=NONE doctor
|
||||
|
||||
formal-clean:
|
||||
python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(FORMAL_DIR)
|
||||
|
||||
.PHONY: formal formal-bus formal-rib-adapter formal-rib2apb formal-sysctrl formal-pll-rcu formal-gpio-user formal-ws2812 formal-timer 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-clint formal-doctor formal-clean
|
||||
@@ -44,6 +44,7 @@ DEF_VAL += -DAPP_$(APP)
|
||||
DEF_VAL += -DCOMPILER_NAME='"$(CC)"'
|
||||
DEF_VAL += -DCOMPILER_CFLAGS='"$(GCC_FLAGS) $(SW_WARN_FLAGS)"'
|
||||
DEF_VAL += -DCOMPILER_ISA='"$(ISA_FLAGS)"'
|
||||
DEF_VAL += -DRS_CLINT_TIMEBASE_HZ=$(CLINT_TIMEBASE_HZ)U
|
||||
ifeq ($(HAVE_CSR),YES)
|
||||
DEF_VAL += -DCSR_ENABLE
|
||||
endif
|
||||
@@ -64,6 +65,7 @@ CRT_SRCS := $(ROOT_PATH)/crt/arch/riscv/startup.S \
|
||||
$(ROOT_PATH)/crt/src/service/bench.c \
|
||||
$(ROOT_PATH)/crt/src/service/booter.c \
|
||||
$(ROOT_PATH)/crt/src/service/test.c \
|
||||
$(ROOT_PATH)/crt/src/hal/clint.c \
|
||||
$(ROOT_PATH)/crt/src/hal/clock.c \
|
||||
$(ROOT_PATH)/crt/src/hal/uart.c \
|
||||
$(ROOT_PATH)/crt/src/hal/gpio.c \
|
||||
|
||||
@@ -19,6 +19,7 @@ module ip_ribp_wrapper (
|
||||
input logic clk_aud_i,
|
||||
input logic rst_aud_n_i,
|
||||
input logic debug_halted_i,
|
||||
input logic timebase_tick_i,
|
||||
rib_if.slave rib,
|
||||
gpio_if.dut gpio,
|
||||
user_gpio_if.padctrl user_gpio,
|
||||
@@ -52,7 +53,7 @@ module ip_ribp_wrapper (
|
||||
ribp_if ribp ();
|
||||
// verilog_format: on
|
||||
|
||||
simp_clint_if u_clint_if ();
|
||||
clint_if u_clint_if ();
|
||||
dma_hw_trg_if u_dma_hw_trg_if ();
|
||||
|
||||
logic s_dma_i2s_tx_stall, s_dma_i2s_rx_stall;
|
||||
@@ -185,10 +186,11 @@ module ip_ribp_wrapper (
|
||||
);
|
||||
|
||||
ribp_clint u_rib_clint (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.ribp (u_clint_ribp_if),
|
||||
.clint (u_clint_if)
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.timebase_tick_i(timebase_tick_i),
|
||||
.ribp (u_clint_ribp_if),
|
||||
.clint (u_clint_if)
|
||||
);
|
||||
|
||||
ribp_sdram u_rib_sdram (
|
||||
|
||||
+18
-3
@@ -8,7 +8,10 @@
|
||||
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the Mulan PSL v2 for more details.
|
||||
|
||||
module rcu (
|
||||
module rcu #(
|
||||
parameter int EXT_CLK_HZ = 72_000_000,
|
||||
parameter int CLINT_TIMEBASE_HZ = 1_000_000
|
||||
) (
|
||||
input logic ext_clk_i,
|
||||
input logic aud_clk_i,
|
||||
input logic ext_rst_n_i,
|
||||
@@ -19,7 +22,8 @@ module rcu (
|
||||
output logic sys_clk_o,
|
||||
output logic sys_rst_n_o,
|
||||
output logic aud_rst_n_o,
|
||||
output logic sys_clkdiv4_o
|
||||
output logic sys_clkdiv4_o,
|
||||
output logic timebase_tick_o
|
||||
);
|
||||
logic s_ext_clk_buf;
|
||||
logic s_aud_clk_buf;
|
||||
@@ -183,7 +187,18 @@ module rcu (
|
||||
assign aud_rst_n_o = s_aud_rst_n_sync;
|
||||
assign sys_clkdiv4_o = s_sys_clkdiv4_q;
|
||||
|
||||
assign s_div_cnt_d = (s_div_cnt_q == 4'd1) ? '0 : s_div_cnt_q + 1'b1;
|
||||
clint_timebase #(
|
||||
.REF_CLK_HZ (EXT_CLK_HZ),
|
||||
.TIMEBASE_HZ(CLINT_TIMEBASE_HZ)
|
||||
) u_clint_timebase (
|
||||
.ref_clk_i (s_ext_clk_buf),
|
||||
.ref_rst_n_i(s_ext_rst_n_sync),
|
||||
.sys_clk_i (sys_clk_o),
|
||||
.sys_rst_n_i(sys_rst_n_o),
|
||||
.tick_o (timebase_tick_o)
|
||||
);
|
||||
|
||||
assign s_div_cnt_d = (s_div_cnt_q == 4'd1) ? '0 : s_div_cnt_q + 1'b1;
|
||||
dffr #(4) u_div_cnt_dffr (
|
||||
sys_clk_o,
|
||||
sys_rst_n_o,
|
||||
|
||||
@@ -19,6 +19,7 @@ module retrosoc (
|
||||
input logic clk_aud_i,
|
||||
input logic rst_aud_n_i,
|
||||
input logic clkdiv4_i,
|
||||
input logic timebase_tick_i,
|
||||
pll_ctrl_if.sysctrl pll_ctrl,
|
||||
`ifdef HAVE_SRAM_IF
|
||||
ram_if.master ram,
|
||||
@@ -124,7 +125,7 @@ core_wrapper u_core_wrapper (
|
||||
.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 & `SOC_USER_IRQ_MASK) : '0;
|
||||
user_core_top u_user_core_top (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
@@ -168,6 +169,7 @@ core_wrapper u_core_wrapper (
|
||||
.clk_aud_i (clk_aud_i),
|
||||
.rst_aud_n_i (rst_aud_n_i),
|
||||
.debug_halted_i (s_mgmt_debug_halted),
|
||||
.timebase_tick_i (timebase_tick_i),
|
||||
`include "ip_ribp_wrapper_fabric.svh"
|
||||
.gpio (u_gpio_if),
|
||||
.user_gpio (u_user_gpio_if),
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
// See the Mulan PSL v2 for more details.
|
||||
|
||||
`include "gpio_define.svh"
|
||||
`include "soc_clock_config.svh"
|
||||
`include "user_extensions.svh"
|
||||
|
||||
module retrosoc_asic (
|
||||
@@ -17,6 +18,7 @@ module retrosoc_asic (
|
||||
logic s_ext_clk;
|
||||
logic s_aud_clk;
|
||||
logic s_sys_clkdiv4;
|
||||
logic s_timebase_tick;
|
||||
`ifdef HAVE_PLL
|
||||
logic s_xtal_io;
|
||||
`endif
|
||||
@@ -45,18 +47,22 @@ module retrosoc_asic (
|
||||
|
||||
`include "retrosoc_asic_pad_bindings.svh"
|
||||
|
||||
rcu u_rcu (
|
||||
.ext_clk_i (s_ext_clk),
|
||||
.aud_clk_i (s_aud_clk),
|
||||
.ext_rst_n_i (s_ext_rst_n),
|
||||
rcu #(
|
||||
.EXT_CLK_HZ (`SOC_EXT_CLK_HZ),
|
||||
.CLINT_TIMEBASE_HZ(`SOC_CLINT_TIMEBASE_HZ)
|
||||
) u_rcu (
|
||||
.ext_clk_i (s_ext_clk),
|
||||
.aud_clk_i (s_aud_clk),
|
||||
.ext_rst_n_i (s_ext_rst_n),
|
||||
`ifdef HAVE_PLL
|
||||
.xtal_clk_i (s_xtal_io),
|
||||
.xtal_clk_i (s_xtal_io),
|
||||
`endif
|
||||
.pll_ctrl (u_pll_ctrl_if),
|
||||
.sys_clk_o (s_sys_clk),
|
||||
.sys_rst_n_o (s_sys_rst_n),
|
||||
.aud_rst_n_o (s_aud_rst_n),
|
||||
.sys_clkdiv4_o(s_sys_clkdiv4)
|
||||
.pll_ctrl (u_pll_ctrl_if),
|
||||
.sys_clk_o (s_sys_clk),
|
||||
.sys_rst_n_o (s_sys_rst_n),
|
||||
.aud_rst_n_o (s_aud_rst_n),
|
||||
.sys_clkdiv4_o (s_sys_clkdiv4),
|
||||
.timebase_tick_o(s_timebase_tick)
|
||||
);
|
||||
|
||||
`ifdef HAVE_SRAM_IF
|
||||
@@ -67,27 +73,28 @@ rcu u_rcu (
|
||||
`endif
|
||||
|
||||
retrosoc u_retrosoc (
|
||||
.clk_i (s_sys_clk),
|
||||
.rst_n_i (s_sys_rst_n),
|
||||
.clk_aud_i (s_aud_clk),
|
||||
.rst_aud_n_i (s_aud_rst_n),
|
||||
.clkdiv4_i (s_sys_clkdiv4),
|
||||
.pll_ctrl (u_pll_ctrl_if),
|
||||
.clk_i (s_sys_clk),
|
||||
.rst_n_i (s_sys_rst_n),
|
||||
.clk_aud_i (s_aud_clk),
|
||||
.rst_aud_n_i (s_aud_rst_n),
|
||||
.clkdiv4_i (s_sys_clkdiv4),
|
||||
.timebase_tick_i(s_timebase_tick),
|
||||
.pll_ctrl (u_pll_ctrl_if),
|
||||
`ifdef HAVE_SRAM_IF
|
||||
.ram (u_ram_if),
|
||||
.ram (u_ram_if),
|
||||
`endif
|
||||
.gpio (u_gpio_if),
|
||||
.uart0 (u_uart0_if),
|
||||
.xpi (u_xpi_if),
|
||||
.sdram (u_sdram_if),
|
||||
.jtag_tck_i (s_jtag_tck),
|
||||
.jtag_tms_i (s_jtag_tms),
|
||||
.jtag_tdi_i (s_jtag_tdi),
|
||||
.jtag_trst_n_i(s_jtag_trst_n),
|
||||
.jtag_tdo_o (s_jtag_tdo),
|
||||
.test_done_o (s_test_done),
|
||||
.test_pass_o (s_test_pass),
|
||||
.test_code_o (s_test_code)
|
||||
.gpio (u_gpio_if),
|
||||
.uart0 (u_uart0_if),
|
||||
.xpi (u_xpi_if),
|
||||
.sdram (u_sdram_if),
|
||||
.jtag_tck_i (s_jtag_tck),
|
||||
.jtag_tms_i (s_jtag_tms),
|
||||
.jtag_tdi_i (s_jtag_tdi),
|
||||
.jtag_trst_n_i (s_jtag_trst_n),
|
||||
.jtag_tdo_o (s_jtag_tdo),
|
||||
.test_done_o (s_test_done),
|
||||
.test_pass_o (s_test_pass),
|
||||
.test_code_o (s_test_code)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||
// retroSoC is licensed under Mulan PSL v2.
|
||||
|
||||
`ifndef RETROSOC_SOC_CLOCK_CONFIG_SVH
|
||||
`define RETROSOC_SOC_CLOCK_CONFIG_SVH
|
||||
|
||||
`ifndef SOC_EXT_CLK_HZ
|
||||
`define SOC_EXT_CLK_HZ 72000000
|
||||
`endif
|
||||
|
||||
`ifndef SOC_CLINT_TIMEBASE_HZ
|
||||
`define SOC_CLINT_TIMEBASE_HZ 1000000
|
||||
`endif
|
||||
|
||||
`endif
|
||||
@@ -11,7 +11,13 @@ from typing import Any
|
||||
|
||||
|
||||
RESET_PRIMITIVES = {"rst_sync"}
|
||||
CDC_PRIMITIVES = {"async_fifo", "cdc_2phase", "cdc_sync", "hazard3_apb_async_bridge"}
|
||||
CDC_PRIMITIVES = {
|
||||
"async_fifo",
|
||||
"cdc_2phase",
|
||||
"cdc_sync",
|
||||
"edge_det",
|
||||
"hazard3_apb_async_bridge",
|
||||
}
|
||||
IDENTIFIER_RE = re.compile(r"[A-Za-z_][A-Za-z0-9_]*$")
|
||||
HIERARCHICAL_PIN_RE = re.compile(
|
||||
r"[A-Za-z_][A-Za-z0-9_.]*(?:/[A-Za-z_][A-Za-z0-9_.]*)+$"
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module clint_tb;
|
||||
logic clk_i = 1'b0;
|
||||
logic ref_clk_i = 1'b0;
|
||||
logic rst_n_i = 1'b0;
|
||||
logic tick_i = 1'b0;
|
||||
logic timebase_tick;
|
||||
logic [31:0] value;
|
||||
integer timebase_tick_count = 0;
|
||||
ribp_if ribp ();
|
||||
clint_if #(.HART_NUM(2)) clint ();
|
||||
|
||||
always #5 clk_i = ~clk_i;
|
||||
always #2 ref_clk_i = ~ref_clk_i;
|
||||
|
||||
always @(posedge clk_i) begin
|
||||
if (timebase_tick) timebase_tick_count <= timebase_tick_count + 1;
|
||||
end
|
||||
|
||||
clint_timebase #(
|
||||
.REF_CLK_HZ (4),
|
||||
.TIMEBASE_HZ(1)
|
||||
) u_timebase (
|
||||
.ref_clk_i (ref_clk_i),
|
||||
.ref_rst_n_i(rst_n_i),
|
||||
.sys_clk_i (clk_i),
|
||||
.sys_rst_n_i(rst_n_i),
|
||||
.tick_o (timebase_tick)
|
||||
);
|
||||
|
||||
ribp_clint #(
|
||||
.HART_NUM(2)
|
||||
) u_dut (
|
||||
.clk_i,
|
||||
.rst_n_i,
|
||||
.timebase_tick_i(tick_i),
|
||||
.ribp,
|
||||
.clint
|
||||
);
|
||||
|
||||
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 pulse_tick;
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
tick_i = 1'b1;
|
||||
@(negedge clk_i);
|
||||
tick_i = 1'b0;
|
||||
end
|
||||
endtask
|
||||
|
||||
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_0000, value, 1'b0);
|
||||
if (value != 32'd0 || clint.software_irq_o != 2'b00) begin
|
||||
$fatal(1, "MSIP reset state is invalid");
|
||||
end
|
||||
ribp_read(32'h0000_4000, value, 1'b0);
|
||||
if (value != 32'hFFFF_FFFF) $fatal(1, "MTIMECMP low reset state is invalid");
|
||||
ribp_read(32'h0000_4004, value, 1'b0);
|
||||
if (value != 32'hFFFF_FFFF || clint.timer_irq_o != 2'b00) begin
|
||||
$fatal(1, "MTIMECMP high reset state is invalid");
|
||||
end
|
||||
|
||||
ribp_write(32'h0000_0004, 32'h0000_0001, 4'h1, 1'b0);
|
||||
if (clint.software_irq_o != 2'b10) $fatal(1, "hart 1 MSIP did not assert");
|
||||
ribp_write(32'h0000_0004, 32'h0000_0000, 4'h1, 1'b0);
|
||||
if (clint.software_irq_o != 2'b00) $fatal(1, "hart 1 MSIP did not clear");
|
||||
|
||||
ribp_write(32'h0000_BFFC, 32'd0, 4'hF, 1'b0);
|
||||
ribp_write(32'h0000_BFF8, 32'd10, 4'hF, 1'b0);
|
||||
ribp_read(32'h0000_BFF8, value, 1'b0);
|
||||
if (value != 32'd10) $fatal(1, "MTIME write/read failed: %h", value);
|
||||
|
||||
ribp_write(32'h0000_4004, 32'd0, 4'hF, 1'b0);
|
||||
ribp_write(32'h0000_4000, 32'd12, 4'hF, 1'b0);
|
||||
pulse_tick();
|
||||
pulse_tick();
|
||||
repeat (2) @(posedge clk_i);
|
||||
if (clint.timer_irq_o[0] != 1'b1) $fatal(1, "hart 0 timer IRQ did not assert");
|
||||
if (clint.timer_irq_o[1] != 1'b0) $fatal(1, "hart 1 timer IRQ asserted unexpectedly");
|
||||
|
||||
ribp_write(32'h0000_4001, 32'd0, 4'hF, 1'b1);
|
||||
ribp_read(32'h0000_0010, value, 1'b1);
|
||||
if (value != 32'd0) $fatal(1, "invalid read did not return zero");
|
||||
|
||||
repeat (20) @(posedge clk_i);
|
||||
if (timebase_tick_count < 2) begin
|
||||
$fatal(1, "reference-clock timebase did not produce synchronized ticks");
|
||||
end
|
||||
|
||||
$display("CLINT standard map, multi-hart, IRQ, error, and timebase test passed");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -25,17 +25,18 @@ module pll_ctrl_tb;
|
||||
always #27 aud_clk_i = ~aud_clk_i;
|
||||
|
||||
rcu u_rcu (
|
||||
.ext_clk_i (ext_clk_i),
|
||||
.aud_clk_i (aud_clk_i),
|
||||
.ext_rst_n_i (rst_n_i),
|
||||
.ext_clk_i (ext_clk_i),
|
||||
.aud_clk_i (aud_clk_i),
|
||||
.ext_rst_n_i (rst_n_i),
|
||||
`ifdef HAVE_PLL
|
||||
.xtal_clk_i (xtal_clk_i),
|
||||
.xtal_clk_i (xtal_clk_i),
|
||||
`endif
|
||||
.pll_ctrl (pll_ctrl),
|
||||
.sys_clk_o (sys_clk_o),
|
||||
.sys_rst_n_o (sys_rst_n_o),
|
||||
.aud_rst_n_o (aud_rst_n_o),
|
||||
.sys_clkdiv4_o(sys_clkdiv4_o)
|
||||
.pll_ctrl (pll_ctrl),
|
||||
.sys_clk_o (sys_clk_o),
|
||||
.sys_rst_n_o (sys_rst_n_o),
|
||||
.aud_rst_n_o (aud_rst_n_o),
|
||||
.sys_clkdiv4_o (sys_clkdiv4_o),
|
||||
.timebase_tick_o()
|
||||
);
|
||||
|
||||
ribp_sysctrl u_sysctrl (
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
"""CLINT 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_clint_standard_map_multi_hart_and_timebase(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 / "clint.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 / "utils/edge_det.sv"),
|
||||
str(common / "cdc/cdc_sync.sv"),
|
||||
str(common / "clkrst/counter.sv"),
|
||||
str(PERIPHERAL / "clint_if.sv"),
|
||||
str(PERIPHERAL / "clint_timebase.sv"),
|
||||
str(PERIPHERAL / "clint_reg.sv"),
|
||||
str(PERIPHERAL / "clint_core.sv"),
|
||||
str(PERIPHERAL / "ribp_clint.sv"),
|
||||
str(ROOT / "tests/rtl/clint_tb.sv"),
|
||||
"",
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
converted = tmp_path / "clint_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 / "clint_tb"
|
||||
subprocess.run(
|
||||
[iverilog, "-g2012", "-s", "clint_tb", "-o", str(simulation), str(converted)],
|
||||
check=True,
|
||||
)
|
||||
result = subprocess.run([vvp, str(simulation)], text=True, capture_output=True, check=True)
|
||||
assert "CLINT standard map, multi-hart, IRQ, error, and timebase test passed" in result.stdout
|
||||
@@ -42,7 +42,14 @@ def test_clock_reset_domain_inventory_matches_the_rcu() -> None:
|
||||
assert {
|
||||
(crossing["name"], crossing["source"], crossing["destination"])
|
||||
for crossing in document["crossings"]
|
||||
} >= {("jtag_dmi", "jtag", "system")}
|
||||
} >= {
|
||||
("clint_timebase", "external", "system"),
|
||||
("jtag_dmi", "jtag", "system"),
|
||||
}
|
||||
clint = next(
|
||||
crossing for crossing in document["crossings"] if crossing["name"] == "clint_timebase"
|
||||
)
|
||||
assert clint["primitive"] == "edge_det"
|
||||
|
||||
|
||||
def test_clock_reset_domain_inventory_rejects_unknown_domain_and_instance(tmp_path: Path) -> None:
|
||||
|
||||
@@ -227,7 +227,10 @@ def test_pll_controller_reconfigures_and_falls_back_to_the_safe_clock(tmp_path:
|
||||
str(ROOT / "rtl/managed/clusterip/common/rtl/cdc/cdc_rst_ctrlr.sv"),
|
||||
str(ROOT / "rtl/managed/clusterip/common/rtl/cdc/cdc_2phase.sv"),
|
||||
str(ROOT / "rtl/managed/clusterip/common/rtl/clkrst/rst_sync.sv"),
|
||||
str(ROOT / "rtl/managed/clusterip/common/rtl/clkrst/counter.sv"),
|
||||
str(ROOT / "rtl/managed/clusterip/common/rtl/utils/edge_det.sv"),
|
||||
str(ROOT / "rtl/ip/ribp/peripheral/pll_ctrl_if.sv"),
|
||||
str(ROOT / "rtl/ip/ribp/peripheral/clint_timebase.sv"),
|
||||
str(ROOT / "rtl/ip/ribp/peripheral/sysctrl.sv"),
|
||||
str(ROOT / "rtl/tech/tc_clk.sv"),
|
||||
str(ROOT / "rtl/tech/tc_pll.sv"),
|
||||
|
||||
@@ -205,6 +205,7 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
|
||||
pll_rcu_filelist = tmp_path / "pll_rcu.fl"
|
||||
gpio_user_filelist = tmp_path / "gpio_user.fl"
|
||||
ws2812_filelist = tmp_path / "ws2812.fl"
|
||||
clint_filelist = tmp_path / "clint.fl"
|
||||
assert generate_formal_filelist("bus", bus_filelist, memory_map, topology, user_extensions)
|
||||
assert generate_formal_filelist(
|
||||
"rib_adapter", rib_adapter_filelist, memory_map, topology, user_extensions
|
||||
@@ -224,6 +225,9 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
|
||||
assert generate_formal_filelist(
|
||||
"ws2812", ws2812_filelist, memory_map, topology, user_extensions
|
||||
)
|
||||
assert generate_formal_filelist(
|
||||
"clint", clint_filelist, memory_map, topology, user_extensions
|
||||
)
|
||||
|
||||
bus = parse_filelists([bus_filelist], require_files=False)
|
||||
rib_adapter = parse_filelists([rib_adapter_filelist], require_files=False)
|
||||
@@ -232,6 +236,7 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
|
||||
pll_rcu = parse_filelists([pll_rcu_filelist], require_files=False)
|
||||
gpio_user = parse_filelists([gpio_user_filelist], require_files=False)
|
||||
ws2812 = parse_filelists([ws2812_filelist], require_files=False)
|
||||
clint = parse_filelists([clint_filelist], require_files=False)
|
||||
assert "+define+SV_ASSRT_DISABLE" in bus.defines
|
||||
assert ROOT / "rtl/mini/top/bus.sv" in bus.files
|
||||
assert ROOT / "rtl/mini/top/rib_if.sv" in bus.files
|
||||
@@ -254,6 +259,8 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
|
||||
assert ROOT / "rtl/ip/ribp/serial/ribp_ws2812.sv" in ws2812.files
|
||||
assert ROOT / "rtl/managed/clusterip/common/rtl/utils/fifo.sv" in ws2812.files
|
||||
assert ROOT / "rtl/mini/formal/ws2812_formal.sv" in ws2812.files
|
||||
assert ROOT / "rtl/ip/ribp/peripheral/ribp_clint.sv" in clint.files
|
||||
assert ROOT / "rtl/mini/formal/clint_formal.sv" in clint.files
|
||||
|
||||
|
||||
def test_sysctrl_formal_properties_use_exported_user_core_shape() -> None:
|
||||
@@ -751,8 +758,8 @@ def test_benchmark_profile_uses_functional_sram_and_reserved_data() -> None:
|
||||
assert re.search(r"^PDK_BEHAV\s+\?= NO$", makefile, re.MULTILINE)
|
||||
assert "PDK_BEHAV HAVE_SVA" in makefile
|
||||
assert "PDK_BEHAV=YES is for functional simulation" in makefile
|
||||
assert "HAVE_SRAM_MACRO := YES" in profile
|
||||
assert "PDK_BEHAV := YES" in profile
|
||||
assert re.search(r"^HAVE_SRAM_MACRO\s*:= YES$", profile, re.MULTILINE)
|
||||
assert re.search(r"^PDK_BEHAV\s*:= YES$", profile, re.MULTILINE)
|
||||
assert "RS_BENCHMARK_SRAM_OFFSET UINT32_C(0x10000)" in benchmark
|
||||
|
||||
|
||||
|
||||
@@ -97,9 +97,10 @@ def test_topology_generates_complete_rib_apb_and_gpio_bindings(tmp_path: Path) -
|
||||
assert ".apb_rib(u_apb_rib_if)" in bus_fabric
|
||||
assert ".rib(u_rib_if)" in bus_fabric
|
||||
assert "`define SOC_IRQ_VECTOR_WIDTH 32" in irq_config
|
||||
assert "`define SOC_USER_IRQ_MASK 32'h0003FFFC" in irq_config
|
||||
assert "`define SOC_IRQ_RIBP_WIDTH 11" in irq_config
|
||||
assert "`define SOC_IRQ_APB_WIDTH 7" in irq_config
|
||||
assert "assign irq_o[0] = u_clint_if.sfr_irq_o;" in rib_irq
|
||||
assert "assign irq_o[0] = u_clint_if.software_irq_o[0];" in rib_irq
|
||||
assert "assign irq_o[10] = ws2812.irq_o;" in rib_irq
|
||||
assert "assign irq_o[5] = u_tmr_if.irq_o;" in apb_irq
|
||||
assert "s_irq[16] = s_apb_irq[6];" in irq_wiring
|
||||
@@ -122,8 +123,8 @@ def test_topology_preserves_default_irq_compatibility_mapping() -> None:
|
||||
for interrupt in document["interrupts"]
|
||||
]
|
||||
assert mappings[:18] == [
|
||||
("clint_software", "ribp", 0, 0, "u_clint_if.sfr_irq_o"),
|
||||
("clint_timer", "ribp", 1, 1, "u_clint_if.tmr_irq_o"),
|
||||
("clint_software", "ribp", 0, 0, "u_clint_if.software_irq_o[0]"),
|
||||
("clint_timer", "ribp", 1, 1, "u_clint_if.timer_irq_o[0]"),
|
||||
("uart0", "ribp", 2, 2, "uart.irq_o"),
|
||||
("timer0", "ribp", 3, 3, "s_tim0_irq"),
|
||||
("timer1", "ribp", 4, 4, "s_tim1_irq"),
|
||||
|
||||
Reference in new issue
Block a user