diff --git a/.gitignore b/.gitignore index 4319689c..20164cf1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,12 @@ idma hyperbus snitch_cluster .cache -deps/ +# Bender checks its dependencies out into the repo-root deps/ only; anchor so it +# does not also ignore committed paths like sw/deps/chimera-sdk (the SDK submodule). +/deps/ *.OLD *.egg-info/ +*compile.log # EMACS @@ -41,6 +44,7 @@ utils/verible-verilog *wave*.do target/sim/models target/sim/vsim/work +target/sim/vsim/runs target/sim/vsim/transcript target/sim/vsim/*.do target/sim/vsim/trace* @@ -53,3 +57,23 @@ vsim.wlf nonfree/ working_dir/ +build/ + +# GENERATED (SystemRDL / peakrdl) + +.generated/ +docs/addressmap.md + +# TEST / PROFILING ARTIFACTS + +chim-test-report.xml +gmon.out + +# CONTAINERS + +# Auto-pulled toolchain images (see scripts/sdk_container.sh); never commit them. +*.sif +.cache/containers/ + +# Claude +.claude/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..9fb7d927 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "sw/deps/chimera-sdk"] + path = sw/deps/chimera-sdk + url = https://github.com/Xeratec/chimera-sdk.git + branch = dev/multi-binary diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..2c073331 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.11 diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..7f03c460 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,13 @@ +{ + "configurations": [ + { + "name": "chimera-sdk", + "compileCommands": "${workspaceFolder}/sw/deps/chimera-sdk/build/compile_commands.json", + "compilerPath": "/usr/pack/llvm-17.0.6-af/bin/clang", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "linux-clang-x64" + } + ], + "version": 4 +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..f31a06f5 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "ms-vscode.cpptools" + ] +} diff --git a/Bender.local b/Bender.local new file mode 100644 index 00000000..00fd9d2b --- /dev/null +++ b/Bender.local @@ -0,0 +1,3 @@ +overrides: + common_cells: { git: "https://github.com/pulp-platform/common_cells.git", rev: ca9d577f2fbc45ec557ab4e0905bbfc154441540 } # snitch branch from 15.12.25 commit "Add iomsb function used in most other PULP repos" + axi: { git: "https://github.com/colluca/axi", rev: bd1abffc0812f8170902e5fb93142c7785c0b8c1 } # idma: { git: "https://github.com/pulp-platform/iDMA.git", rev: 28a36e5e07705549e59fc33db96ab681bc1ca88e} diff --git a/Bender.lock b/Bender.lock index 7b85b9c4..c88272ef 100644 --- a/Bender.lock +++ b/Bender.lock @@ -17,7 +17,7 @@ packages: - obi_peripherals - register_interface axi: - revision: 8e04779f341eb2c89412aae92223a292beef487e + revision: bd1abffc0812f8170902e5fb93142c7785c0b8c1 version: null source: Git: https://github.com/colluca/axi @@ -37,8 +37,8 @@ packages: - register_interface - tech_cells_generic axi_riscv_atomics: - revision: 0ac3a78fe342c5a5b9b10bff49d58897f773059e - version: 0.8.2 + revision: 97a1dd2ac643c276880420a0cf8eea697f228aa9 + version: 0.8.3 source: Git: https://github.com/pulp-platform/axi_riscv_atomics.git dependencies: @@ -71,7 +71,7 @@ packages: - common_cells - register_interface cheshire: - revision: 1b6ba6294a5925a5dc199b4f98704adb76648ed1 + revision: ad168f88f9d99e973d9ee147453ff911d4c79d6d version: null source: Git: https://github.com/pulp-platform/cheshire.git @@ -87,6 +87,7 @@ packages: - common_cells - common_verification - cva6 + - dram_rtl_sim - idma - irq_router - opentitan_peripherals @@ -95,8 +96,8 @@ packages: - serial_link - unbent clic: - revision: 8ed76ffc779a435d0ed034f3068e4c3334fe2ecf - version: 2.0.0 + revision: 6515a71eb4ae3b143ab912d265e79832b3179a76 + version: 3.0.0 source: Git: https://github.com/pulp-platform/clic.git dependencies: @@ -128,8 +129,8 @@ packages: dependencies: - common_cells common_cells: - revision: 9afda9abb565971649c2aa0985639c096f351171 - version: 1.38.0 + revision: ca9d577f2fbc45ec557ab4e0905bbfc154441540 + version: null source: Git: https://github.com/pulp-platform/common_cells.git dependencies: @@ -142,17 +143,24 @@ packages: Git: https://github.com/pulp-platform/common_verification.git dependencies: [] cva6: - revision: 630bd959c9cc69a35d461a2abc205310d2edacf8 + revision: 4c02b24fe7c04690f626776a92274da24f80d1da version: null source: - Git: https://github.com/Scheremo/cva6.git + Git: https://github.com/pulp-platform/cva6.git dependencies: - axi - common_cells - fpnew - tech_cells_generic + dram_rtl_sim: + revision: a764d5200a19cdd72a5237cbfb16985515a3058d + version: 0.1.2 + source: + Git: https://github.com/pulp-platform/dram_rtl_sim.git + dependencies: + - axi fpnew: - revision: a8e0cba6dd50f357ece73c2c955d96efc3c6c315 + revision: e5aa6a01b5bbe1675c3aa8872e1203413ded83d1 version: null source: Git: https://github.com/pulp-platform/cvfpu.git @@ -167,8 +175,8 @@ packages: dependencies: - common_cells hyperbus: - revision: 841deb9d821b63bf05a1c85d3a4746352a8bcae2 - version: null + revision: 2a14bd8f9a985b488ee23d240764f52f129f7729 + version: 0.0.9 source: Git: https://github.com/pulp-platform/hyperbus.git dependencies: @@ -198,7 +206,7 @@ packages: - common_cells - register_interface memory_island: - revision: 64828cb7a9ccc1f1656ec92d06129072f445c319 + revision: d072ba0945adad5ccd0af2d4604abe57c1058252 version: null source: Git: https://github.com/pulp-platform/memory_island.git @@ -234,8 +242,8 @@ packages: - register_interface - tech_cells_generic register_interface: - revision: 8e8c209ea559d3b54f45cf30fcce95ce70ff5e49 - version: 0.4.6 + revision: d6e1d4cdaab7870f4faf3f88a1c788eaf5ac129d + version: 0.4.7 source: Git: https://github.com/pulp-platform/register_interface.git dependencies: @@ -252,26 +260,27 @@ packages: - common_cells - tech_cells_generic scm: - revision: 472f99affe44ff7b282b519c047a3cfeb35b16c6 - version: 1.2.0 + revision: 1976c7efb4979271eee2abe262fde0f9a20e2557 + version: 1.2.1 source: Git: https://github.com/pulp-platform/scm.git dependencies: - tech_cells_generic serial_link: - revision: c55df03a1da06b00e567cf968b1b1a5f40c9f802 - version: 1.1.2 + revision: d4e513aebd368d77808c5e6629a1e2729c16eba0 + version: 2.0.0 source: Git: https://github.com/pulp-platform/serial_link.git dependencies: + - apb - axi + - axi_stream - common_cells - - register_interface snitch_cluster: - revision: 5b2fccd96c42812774c20ab2f9b811e164809789 + revision: c9cc25849984bf4589698d950e9f79a0631792b9 version: null source: - Git: https://github.com/pulp-platform/snitch_cluster.git + Git: https://github.com/xeratec/snitch_cluster.git dependencies: - apb - axi diff --git a/Bender.yml b/Bender.yml index df8d180d..3fd16fe0 100644 --- a/Bender.yml +++ b/Bender.yml @@ -9,26 +9,22 @@ package: - "Lorenzo Leone " dependencies: - register_interface: { git: "https://github.com/pulp-platform/register_interface.git", version: 0.4.3 } - axi: { git: https://github.com/colluca/axi, rev: multicast } - cheshire: { git: "https://github.com/pulp-platform/cheshire.git", rev: 1b6ba6294a5925a5dc199b4f98704adb76648ed1} - snitch_cluster: { git: "https://github.com/pulp-platform/snitch_cluster.git", rev: 5b2fccd96c42812774c20ab2f9b811e164809789} - common_cells: { git: "https://github.com/pulp-platform/common_cells.git", version: 1.31.1} + register_interface: { git: "https://github.com/pulp-platform/register_interface.git", version: 0.4.7 } + axi: { git: "https://github.com/colluca/axi", rev: bd1abffc0812f8170902e5fb93142c7785c0b8c1 } # + cheshire: { git: "https://github.com/pulp-platform/cheshire.git", rev: wiesep/chimera-main } + snitch_cluster: { git: "https://github.com/xeratec/snitch_cluster.git", rev: wiesep/chimera-main } # main branch from 22.09.25 commit "treewide: Bump AXI after rebase" + common_cells: { git: "https://github.com/pulp-platform/common_cells.git", version: 1.39.0 } idma: { git: "https://github.com/pulp-platform/iDMA.git", version: 0.6.5 } - memory_island: { git: "https://github.com/pulp-platform/memory_island.git", rev: 64828cb7a9ccc1f1656ec92d06129072f445c319 } # main branch - apb: { git: "https://github.com/pulp-platform/apb.git", version: 0.2.4 } - hyperbus: { git: "https://github.com/pulp-platform/hyperbus.git", rev: aottaviano/nonfree } # TMP: to fix hyperbus model issue + memory_island: { git: "https://github.com/pulp-platform/memory_island.git", rev: main } + apb: { git: "https://github.com/pulp-platform/apb.git", version: 0.2.4 } + hyperbus: { git: "https://github.com/pulp-platform/hyperbus.git", version : 0.0.9 } tech_cells_generic: { git: "https://github.com/pulp-platform/tech_cells_generic.git", version: 0.2.12 } export_include_dirs: - hw/include -workspace: - package_links: - cheshire: cheshire - idma: idma - sources: + # Level 0 - hw/chimera_pkg.sv - hw/regs/chimera_reg_pkg.sv diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..006d3d46 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,86 @@ +# CLAUDE.md + +Guidance for Claude Code (claude.ai/code) when working in this repository. + +## What Chimera is + +Chimera is an open-source, configurable heterogeneous SoC template (PULP Platform, ETH Zurich / +University of Bologna). It integrates: + +- a **Cheshire** host SoC (64-bit CVA6, CLINT/PLIC/CLIC, JTAG debug, UART/I²C/SPI/GPIO, AXI LLC), +- up to **5 Snitch clusters** (9 cores each) as compute accelerators, +- a shared multi-banked **memory island** (`0x4800_0000`), +- a **HyperBus** controller for off-chip HyperRAM (`0x8000_0000`). + +This repo is the *integration layer*: almost all leaf IP comes from Bender git dependencies +(cheshire, snitch_cluster, idma, memory_island, hyperbus, axi, common_cells, …). The RTL here +wires those together and adds SoC-control registers, a Snitch bootrom, and the cluster/memory +adapters. + +## Documentation map + +Detailed docs live in `docs/`: + +- `docs/architecture.md` — SoC block diagram, HW module map, full address map. +- `docs/build-system.md` — Bender + Make flow, every target, dependency versions. +- `docs/software.md` — SW build, the cluster-offload model, test inventory, linker layout. +- `docs/verification.md` — current sim/test flow **and** the planned pytest-based framework. +- `docs/sdk-integration.md` — plan to adopt `chimera-sdk` as the SW layer. + +`TODO.md` (repo root) tracks the active cleanup / verification-framework initiative. + +## Environment + +IIS members: `source iis-env.sh` (pins bender-0.31.0, questa-2022.3, RISC-V GCC 32/64, Snitch +LLVM, python3.11; auto-creates `.venv`). Non-IIS: `make python-venv`, install Bender, and a +RISC-V GCC toolchain (`RISCV_GCC_BINROOT`). See `README.md`. + +## Build (current Bender + Make flow) + +```sh +bender checkout +make chim-all # = HW (chs-hw-init sn-hw-all chim-bootrom-init) + SW (chim-sw) + sim (chim-sim) +``` + +Selective: +```sh +make chs-hw-init # patch PLIC, gen iDMA, build libchimera.a, then Cheshire chs-hw-all +make sn-hw-all # generate Snitch cluster RTL (uses cfg/default.json) +make chim-sw # build libchimera.a + all sw/tests/*.c -> *.memisl.elf +make chim-bootrom-init # Cheshire bootrom (⚠ requires chim-sw first) +make snitch_bootrom # regenerate hw/bootrom/snitch/snitch_bootrom.sv (rv32im) +make chim-sim # fetch HyperRAM model + compile RTL in Questa +make chim-run-batch BINARY=sw/tests/.memisl.elf # run a test (batch) +make help # list all targets +``` + +Key gotchas: +- **`chim-sw` must run before `chim-bootrom-init`** (bootrom embeds SW). +- Host builds at `CHS_XLEN=64` (`rv64gc_zifencei`/`lp64d`); the Snitch bootrom is **rv32im**. +- Register offsets come from generated `sw/include/regs/soc_ctrl.h`; regenerate with + `make regenerate_soc_regs` after editing `hw/regs/chimera_regs.hjson`. +- Core counts are hardcoded in `chimera.mk` (`CLINTCORES/PLICCORES/PLIC_NUM_INTRS`) and must + track `ExtClusters`/`NrCores` in `hw/chimera_pkg.sv`. + +## Running / writing tests + +Today a "test" is a host (CVA6) ELF linked into the memory island; it drives SoC-control +registers and offloads functions to clusters via a shared-memory function-pointer + CLINT MSIP +mechanism. Pass/fail = the program's return code. CI runs a fixed matrix via `chim-run-batch` +and greps the transcript with `scripts/vsim_ret_error.sh`. See `docs/software.md` (offload model, +test inventory) and `docs/verification.md` (the planned pytest framework that replaces the +grep-the-transcript approach). + +## Formatting + +```sh +verible-verilog-format --flagfile .verilog_format --inplace hw/*.sv target/sim/src/*.sv +python scripts/run_clang_format.py -ir sw/ # llvm-12; on IIS pass --clang-format-executable=/bin/clang-format +``` + +## Conventions + +- Every source file carries an SPDX header (SHL-0.51 for HW/scripts, Apache-2.0 for SW and + generated register RTL). +- Do not commit build artifacts. Most are gitignored; note `build/` is currently a gap. +- `iis_compile.sh` is an empty placeholder (0 bytes) — safe to ignore/remove. diff --git a/Makefile b/Makefile index cf880d4e..c9bfd351 100644 --- a/Makefile +++ b/Makefile @@ -27,39 +27,41 @@ SN_ROOT ?= . IDMA_ROOT ?= . HYPERB_ROOT ?= . -# Use the default snitch cluster cfg. For the moment chimera -# does not use the snitch_cluster_wrapper feature but we need to generate some files. -SN_CFG = $(SN_ROOT)/cfg/default.json +# Chimera's Snitch-cluster HW config (cfg/chimera.json) reproduces the parameters +# currently hand-coded in hw/clusters/chimera_cluster.sv. It drives generation of +# snitch_cluster_pkg.sv + snitch_cluster_wrapper.sv (`make sn-hw-all`), so the +# cluster config lives in one place instead of being duplicated in RTL. +SN_CFG = $(CHIM_ROOT)/cfg/chimera.json # Bender prerequisites BENDER_YML = $(CHIM_ROOT)/Bender.yml BENDER_LOCK = $(CHIM_ROOT)/Bender.lock -CHS_XLEN ?= 32 +CHS_XLEN ?= 64 CHIM_HW_DIR ?= $(CHIM_ROOT)/hw CHIM_SW_DIR ?= $(CHIM_ROOT)/sw -include $(CHS_ROOT)/cheshire.mk -include $(CHIM_ROOT)/chimera.mk +-include $(CHIM_ROOT)/rdl.mk ######## # MISC # ######## -BASE_PYTHON ?= python -PIP_CACHE_DIR ?= $(CHIM_ROOT)/.cache/pip +UV ?= uv +# Keep the uv cache on the (writable, large) repo scratch, not $HOME (small IIS quota). +export UV_CACHE_DIR ?= $(CHIM_ROOT)/.cache/uv -.PHONY: dvt-flist pythomn-venv python-venv-clean +.PHONY: dvt-flist python-venv python-venv-clean dvt_flist: mkdir -p .dvt $(BENDER) script flist-plus $(COMMON_TARGS) $(SIM_TARGS) > .dvt/default.build -python-venv: .venv ## Create a Python virtual environment +python-venv: .venv ## Create the Python virtual environment (uv) .venv: - $(BASE_PYTHON) -m venv $@ - . $@/bin/activate && \ - python -m pip install --cache-dir $(PIP_CACHE_DIR) . + $(UV) sync python-venv-clean: ## Clean Python virtual environment rm -rf .venv diff --git a/bender.mk b/bender.mk index 2039e684..e48d25f5 100644 --- a/bender.mk +++ b/bender.mk @@ -6,6 +6,6 @@ # Lorenzo Leone COMMON_TARGS ?= -COMMON_TARGS += -t snitch_cluster -t cv32a6_convolve -t cva6 -t rtl +COMMON_TARGS += -t snitch_cluster -t snitch_cluster_wrapper -t cv64a6_imafdchsclic_sv39_wb -t cva6 -t rtl SIM_TARGS = $(COMMON_TARGS) -t test -t sim diff --git a/cfg/chimera.json b/cfg/chimera.json new file mode 100644 index 00000000..848e6c73 --- /dev/null +++ b/cfg/chimera.json @@ -0,0 +1,165 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Chimera Snitch-cluster configuration -- the single source of truth for the +// cluster, consumed by BOTH generators: +// * the HW RTL clustergen (SN_CFG) -> snitch_cluster_wrapper.sv / _pkg.sv +// * the snitch-sdk SW clustergen (SN_CLUSTER_CFG) -> snitch_cluster_{cfg,addrmap}.h +// The overrides below reproduce the parameters previously hand-coded in +// hw/clusters/chimera_cluster.sv, so the generated wrapper is a drop-in +// replacement (no hardware change). +// +// A few fields exist purely so the SW clustergen accepts this file too: +// - top-level `nr_clusters` +// - `icache.sets` (the SW schema's name for what the HW schema calls `ways`) +// Note: the HW clustergen parser does not accept underscore-separated hex, so +// addresses are written without '_'. +{ + nr_clusters: 5, // SW clustergen: total number of clusters + cluster: { + cluster_base_addr: 0x40000000, // chimera: cluster 0 @ 0x4000_0000 + cluster_base_offset: 0x200000, // chimera: 2 MiB stride between clusters + cluster_base_hartid: 1, // chimera: host is hart 0 + boot_addr: 0x30000000, // chimera: external Snitch bootrom (SnitchBootROMRegionStart) + int_bootrom_enable: false, // chimera: use the external bootrom, not the internal one + cluster_base_expose: true, // chimera: drive hart_base_id_i / cluster_base_addr_i per cluster + addr_width: 48, + data_width: 64, + atomic_id_width: 5, // clog2(total number of clusters) + user_width: 53, // addr_width + atomic_id_width + tcdm: { + size: 128, + banks: 16, // chimera: 16 banks x 1024 depth = 128 KiB + }, + cluster_periph_size: 64, // kB // chimera: 64 (default is 60) + zero_mem_size: 64, // kB + alias_region_enable: true, + dma_data_width: 512, + dma_axi_req_fifo_depth: 3, // chimera: DMANumAxInFlight = 3 + dma_req_fifo_depth: 3, // chimera: DMAReqFifoDepth = 3 + narrow_trans: 4, + wide_trans: 32, + dma_user_width: 48, + enable_multicast: true, + // We don't need Snitch debugging in Occamy + enable_debug: false, + // We don't need Snitch (core-internal) virtual memory support + vm_support: false, + // Memory configuration inputs + sram_cfg_expose: true, + sram_cfg_fields: { + ema: 3, + emaw: 2, + emas: 1 + }, + // Timing parameters + timing: { + lat_comp_fp32: 2, + lat_comp_fp64: 3, + lat_comp_fp16: 1, + lat_comp_fp16_alt: 1, + lat_comp_fp8: 1, + lat_comp_fp8_alt: 1, + lat_noncomp: 1, + lat_conv: 2, + lat_sdotp: 3, + fpu_pipe_config: "BEFORE", + narrow_xbar_latency: "CUT_ALL_PORTS", + wide_xbar_latency: "CUT_ALL_PORTS", + // Isolate the core. + register_core_req: true, + register_core_rsp: true, + register_offload_req: true, + register_offload_rsp: true, + register_fpu_req: true, + register_ext_narrow: false, + register_ext_wide: false + }, + hives: [ + // Hive 0 + { + icache: { + size: 1, // total instruction cache size in kByte (chimera: LineCount 16) + ways: 2, // number of ways (HW clustergen) + sets: 2, // SW clustergen alias for `ways` (same value) + cacheline: 256 // word size in bits (chimera: ICacheLineWidth 256) + }, + cores: [ + { $ref: "#/compute_core_template" }, + { $ref: "#/compute_core_template" }, + { $ref: "#/compute_core_template" }, + { $ref: "#/compute_core_template" }, + { $ref: "#/compute_core_template" }, + { $ref: "#/compute_core_template" }, + { $ref: "#/compute_core_template" }, + { $ref: "#/compute_core_template" }, + { $ref: "#/dma_core_template" }, + ] + } + ] + }, + external_addr_regions: [ + { + name: "dram", + address: 0x80000000, + length: 0x80000000, + cacheable: true + }, + { + name: "clint", + address: 0xFFFF0000, + length: 0x1000 + }, + ], + // Templates. + compute_core_template: { + isa: "rv32imafd", + xssr: true, + xfrep: true, + xcopift: true, + xdma: false, + xf16: true, + xf16alt: true, + xf8: true, + xf8alt: true, + xfdotp: true, + xfvec: true, + ssr_nr_credits: 4, + num_int_outstanding_loads: 4, + num_int_outstanding_mem: 4, + num_fp_outstanding_loads: 4, + num_fp_outstanding_mem: 4, + num_sequencer_instructions: 32, + num_sequencer_loops: 2, + num_dtlb_entries: 1, + num_itlb_entries: 1, + // SSSR configuration below + ssr_intersection: true, + ssr_intersection_triple: [0, 1, 2], + ssrs: [ + {indirection: true}, // Master 0 + {indirection: true}, // Master 1 + {}, // Slave + ], + }, + dma_core_template: { + isa: "rv32imafd", + xdma: true, + xssr: false, + xfrep: false, + xcopift: true, // chimera: Xcopift enabled on all cores + xf16: false, + xf16alt: false, + xf8: false, + xf8alt: false, + xfdotp: false, + xfvec: false, + num_int_outstanding_loads: 4, + num_int_outstanding_mem: 4, + num_fp_outstanding_loads: 4, + num_fp_outstanding_mem: 4, + num_dtlb_entries: 1, + num_itlb_entries: 1, + } +} diff --git a/cfg/rdl/chimera_addrmap.rdl b/cfg/rdl/chimera_addrmap.rdl new file mode 100644 index 00000000..3043758f --- /dev/null +++ b/cfg/rdl/chimera_addrmap.rdl @@ -0,0 +1,54 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Chimera global SoC address map, in SystemRDL. Single source of truth for the +// region layout previously duplicated by hand across hw/chimera_pkg.sv and +// sw/include/soc_addr_map.h. Render with peakrdl (see rdl.mk): +// - Markdown address-map table (docs) +// - C / SV headers of region base addresses +// +// The per-cluster window instantiates the snitch_cluster address map shipped by +// the snitch_cluster dependency (hw/generated/snitch_cluster.rdl), so the SoC map +// contains the real cluster internals (TCDM, bootrom, peripheral regs, zeromem) +// rather than an opaque block. peakrdl resolves it via the -I dirs in rdl.mk. + +`include "snitch_cluster.rdl" +`include "chimera_soc_regs.rdl" +`include "cheshire.rdl" + +addrmap chimera_addrmap #( + longint unsigned NrClusters = 5, + longint unsigned ClusterStride = 0x200000, // 2 MiB per cluster window + longint unsigned SlinkNumLanes = 4 +) { + name = "Chimera SoC Address Map"; + desc = "Top-level physical address map of the Chimera SoC (host regs, Snitch + clusters, memory island and HyperBus)."; + + cheshire #(.SlinkNumLanes (SlinkNumLanes)) cheshire @0x0000_0000; + + // --- Peripheral / config region (0x3000_0000 .. 0x3000_6000) --- + external mem { mementries = 0x400; memwidth = 32; + desc = "Snitch cluster bootrom (4 KiB)"; } snitch_bootrom @ 0x30000000; + + external chimera_soc_regs #(.NrClusters(NrClusters)) soc_ctrl @ 0x30001000; + + external mem { mementries = 0xC00; memwidth = 32; + desc = "External config regs (PADs / FLLs / PMU via APB, 12 KiB)"; } ext_cfg_regs @ 0x30002000; + + external mem { mementries = 0x400; memwidth = 32; + desc = "HyperBus configuration registers (4 KiB)"; } hyperbus_cfg @ 0x30005000; + + // --- Snitch clusters: NrClusters windows of ClusterStride each --- + // Real per-cluster map from the snitch_cluster dependency. + snitch_cluster cluster[NrClusters] @ 0x40000000 += ClusterStride; + + // --- Shared memory island (512 KiB) --- + external mem { mementries = 0x20000; memwidth = 32; + desc = "Shared multi-banked memory island (512 KiB)"; } mem_island @ 0x48000000; + + // --- Off-chip HyperRAM (4 GiB window) --- + external mem { mementries = 0x40000000; memwidth = 32; + desc = "Off-chip HyperRAM via HyperBus (4 GiB window)"; } hyperram @ 0x80000000; +}; diff --git a/cfg/rdl/chimera_soc_regs.rdl b/cfg/rdl/chimera_soc_regs.rdl new file mode 100644 index 00000000..aba0ef23 --- /dev/null +++ b/cfg/rdl/chimera_soc_regs.rdl @@ -0,0 +1,55 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Chimera top-level SoC-control register block, in SystemRDL. +// Single source of truth for the register layout previously kept in +// hw/regs/chimera_regs.hjson (lowRISC reggen). peakrdl renders it to the SV +// register block (regblock), the C header and the Markdown map (see rdl.mk). +// Layout (32-bit regs) matches the legacy offsets 0x0-0x6c. + +`ifndef CHIMERA_SOC_REGS_RDL +`define CHIMERA_SOC_REGS_RDL + +addrmap chimera_soc_regs #( + longint unsigned NrClusters = 5 +) { + name = "Chimera SoC Control Registers"; + desc = "Top-level SoC-control registers: Snitch boot/interrupt addresses and + per-cluster reset, clock-gate, return, busy and wide-memory bypass."; + + default regwidth = 32; + default sw = rw; + default hw = r; // hwaccess "hro": hardware reads, software writes + + reg { desc = "Boot address for all Snitch cores"; + field { reset = 0xBADCAB1E; } value[31:0]; } snitch_boot_addr @ 0x0; + + reg { desc = "Configurable boot address executed by each Snitch core"; + field { reset = 0x30000000; } value[31:0]; } snitch_configurable_boot_addr @ 0x4; + + reg { desc = "Interrupt handler address for all Snitch cores"; + field { reset = 0xBADCAB1E; } value[31:0]; } snitch_intr_handler_addr @ 0x8; + + reg snitch_cluster_return_t { desc = "Return value of a Snitch cluster"; + field { reset = 0x0; } value[31:0]; }; + snitch_cluster_return_t snitch_cluster_return[NrClusters] @ 0xc += 0x4; + + reg reset_cluster_t { desc = "Soft reset for a cluster (active high)"; + field { reset = 0x1; } value[0:0]; }; + reset_cluster_t reset_cluster[NrClusters] @ 0x20 += 0x4; + + reg cluster_clk_gate_en_t { desc = "Clock-gate enable for a cluster (disables the clock)"; + field { reset = 0x1; } value[0:0]; }; + cluster_clk_gate_en_t cluster_clk_gate_en[NrClusters] @ 0x34 += 0x4; + + reg wide_mem_cluster_bypass_t { desc = "Bypass the cluster-to-memory wide connection"; + field { reset = 0x0; } value[0:0]; }; + wide_mem_cluster_bypass_t wide_mem_cluster_bypass[NrClusters] @ 0x48 += 0x4; + + reg cluster_busy_t { desc = "Cluster busy status"; + field { reset = 0x1; } value[0:0]; }; + cluster_busy_t cluster_busy[NrClusters] @ 0x5c += 0x4; +}; + +`endif // CHIMERA_SOC_REGS_RDL diff --git a/chimera.mk b/chimera.mk index f5248233..72f5d4c8 100644 --- a/chimera.mk +++ b/chimera.mk @@ -21,9 +21,16 @@ gen_idma_hw: make -C $(IDMA_ROOT) idma_hw_all CHS_SW_LD_DIR = $(CHIM_ROOT)/sw/link +CHS_SW_ADDRS_LDH = $(CHS_SW_LD_DIR)/chimera_addrs.ldh + +$(CHS_SW_LD_DIR)/chimera_addrs.ldh: $(CHIM_ROOT)/cfg/rdl/chimera_addrmap.rdl $(CHS_SLINK_DIR)/.generated + $(PEAKRDL) raw-header $< --format ldh $(PEAKRDL_INCLUDES) $(CHS_PEAKRDL_PARAMS) --no-prefix --license_str $$'Copyright 2025 ETH Zurich and University of Bologna.\nLicensed under the Apache License, Version 2.0, see LICENSE for details.\nSPDX-License-Identifier: Apache-2.0' -o $@ + +$(CHS_ROOT)/hw/bootrom/cheshire_bootrom.elf: $(CHS_SW_LD_DIR)/cheshire_bootrom.ld $(CHS_BROM_SRCS) $(CHS_SW_ADDRS_LDH) + $(CHS_SW_CC) $(CHS_SW_INCLUDES) -T$< $(CHS_BROM_FLAGS) -o $@ $(CHS_BROM_SRCS) .PHONY: chs-hw-init -chs-hw-init: update_plic gen_idma_hw $(CHIM_SW_LIB) ## Generate Cheshire RTL +chs-hw-init: update_plic gen_idma_hw ## Generate Cheshire RTL make -B chs-hw-all CHS_XLEN=$(CHS_XLEN) CHS_SW_LD_DIR=$(CHS_SW_LD_DIR) ################## @@ -41,44 +48,42 @@ chs-hw-init: update_plic gen_idma_hw $(CHIM_SW_LIB) ## Generate Cheshire RTL sn-hw-all: sn-rtl ## Generate Snitch RTL sn-hw-clean: sn-clean-rtl ## Clean Snitch RTL -.PHONY: $(CHIM_SW_DIR)/include/regs/soc_ctrl.h -$(CHIM_SW_DIR)/include/regs/soc_ctrl.h: $(CHIM_ROOT)/hw/regs/chimera_regs.hjson - python $(CHIM_ROOT)/utils/reggen/regtool.py -D $< > $@ - -.PHONY: $(CHIM_SW_DIR)/hw/regs/pcr.md -$(CHIM_HW_DIR)/regs/pcr.md: $(CHIM_ROOT)/hw/regs/chimera_regs.hjson - python $(CHIM_ROOT)/utils/reggen/regtool.py -d $< > $@ +# NOTE: the SoC-control register block now comes from SystemRDL (cfg/rdl) via +# peakrdl (see rdl.mk `regenerate_soc_regs`); the lowRISC reggen flow +# (chimera_regs.hjson + utils/reggen) was retired. The Snitch bootrom sources +# now include the generated headers from .generated directly; the hand-kept +# sw/include/{regs/soc_ctrl.h,soc_addr_map.h,offload.h} were removed. .PHONY: snitch_bootrom -CHIM_BROM_SRCS = $(wildcard $(CHIM_ROOT)/hw/bootrom/snitch/*.S $(CHIM_ROOT)/hw/bootrom/snitch/*.c) $(CHIM_SW_LIBS) -CHIM_BROM_FLAGS = $(CHS_SW_LDFLAGS) -Os -fno-zero-initialized-in-bss -flto -fwhole-program -march=rv32im +CHIM_BROM_SRCS = $(wildcard $(CHIM_ROOT)/hw/bootrom/snitch/*.S $(CHIM_ROOT)/hw/bootrom/snitch/*.c) +CHIM_BROM_FLAGS = $(CHS_SW_LDFLAGS) -Os -fno-zero-initialized-in-bss -flto -fwhole-program -march=rv32im_zicsr -mabi=ilp32 CHIM_BOOTROM_ALL += $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.sv $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.dump snitch_bootrom: $(CHIM_BOOTROM_ALL) ## Generate Snitch bootrom -$(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.elf: $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.ld $(CHIM_BROM_SRCS) - $(CHS_SW_CC) -I$(CHIM_SW_DIR)/include/regs $(CHS_SW_INCLUDES) -T$< $(CHIM_BROM_FLAGS) -o $@ $(CHIM_BROM_SRCS) +# The bootrom sources include the SystemRDL-generated headers directly +# (.generated/{chimera_addrmap_raw,snitch_cluster_addrmap,snitch_cluster_cfg}.h), +# so add -I$(RDL_GEN_DIR) and ensure they are generated first (chim-rdl-raw-header +# + chim-rdl-sw-headers). The old hand-maintained sw/include headers were removed. +$(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.elf: $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.ld $(CHIM_BROM_SRCS) | chim-rdl-raw-header chim-rdl-sw-headers + $(CHS_SW_CC) -I$(RDL_GEN_DIR) $(CHS_SW_INCLUDES) -T$< $(CHIM_BROM_FLAGS) -o $@ $(CHIM_BROM_SRCS) $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.bin: $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.elf $(CHS_SW_OBJCOPY) -O binary $< $@ $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.sv: $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.bin $(CHS_ROOT)/util/gen_bootrom.py - $(CHS_ROOT)/util/gen_bootrom.py --sv-module snitch_bootrom $< > $@ + $(CHS_ROOT)/util/gen_bootrom.py --sv-module chimera_snitch_bootrom $< > $@ .PHONY: regenerate_soc_regs -regenerate_soc_regs: $(CHIM_ROOT)/hw/regs/chimera_reg_pkg.sv $(CHIM_ROOT)/hw/regs/chimera_reg_top.sv $(CHIM_SW_DIR)/include/regs/soc_ctrl.h $(CHIM_HW_DIR)/regs/pcr.md ## Generate SoC configuration registers - -.PHONY: $(CHIM_ROOT)/hw/regs/chimera_reg_pkg.sv hw/regs/chimera_reg_top.sv -$(CHIM_ROOT)/hw/regs/chimera_reg_pkg.sv $(CHIM_ROOT)/hw/regs/chimera_reg_top.sv: $(CHIM_ROOT)/hw/regs/chimera_regs.hjson - python $(CHIM_ROOT)/utils/reggen/regtool.py -r $< --outdir $(dir $@) +regenerate_soc_regs: chim-rdl-regblock ## Regenerate the SoC-control register block from SystemRDL (cfg/rdl) -include $(CHIM_NONFREE_DIR)/nonfree.mk -include $(CHIM_ROOT)/bender.mk -# Necessary to build libchimera.a for bootrom.elf +# Provides the Snitch bootrom compile flags (march/ABI) -include $(CHIM_ROOT)/sw/sw.mk # Include subdir Makefiles @@ -91,10 +96,10 @@ TB_DUT = tb_chimera_soc # Phonies for the entire system # ################################# CHIM_HW_ALL = chs-hw-init sn-hw-all chim-bootrom-init -CHIM_SW_ALL = chim-sw +CHIM_SW_ALL = chim-rdl chim-sw CHIM_SIM_ALL = chim-sim CHIM_ALL += $(CHIM_HW_ALL) $(CHIM_SW_ALL) $(CHIM_SIM_ALL) -CHIM_CLEAN += chim-sw-clean chim-sim-clean sn-hw-clean +CHIM_CLEAN += chim-rdl-clean chim-sw-clean chim-sim-clean sn-hw-clean .PHONY: chim-all chim-all: $(CHIM_ALL) ## Generate full chimera infrastructure diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 00000000..ad0ab130 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,93 @@ +# Chimera SoC Architecture + +Chimera integrates a Cheshire host, N Snitch clusters, a shared memory island, and a HyperBus +off-chip memory controller. This document describes the RTL structure and the address map. All +paths are relative to the repo root. + +## Block overview + +``` + ┌───────────────────────────────────────────────┐ + │ cheshire_soc │ + │ CVA6 (64-bit) · CLINT/PLIC/CLIC · JTAG dbg │ + │ UART/I2C/SPI/GPIO · AXI LLC · crossbar │ + └───┬───────────────┬───────────────┬────────────┘ + ext AXI mst/slv ext reg demux LLC AXI (async) + │ │ │ + ┌────────────────┼───────┐ ┌───┴─────────┐ ┌──┴───────────────┐ + │ chimera_clu_domain │ │ ext cfg regs│ │ hyperbus_wrap │ + │ 5× chimera_cluster │ │ ┌─────────┐ │ │ axi_cdc + pulp │ + │ (Snitch, 9 cores) │ │ │reg->apb │ │ │ hyperbus PHY │ + │ + cluster_adapter │ │ │apb_dump │ │ └──────► HyperRAM │ + └───────┬────────────────┘ │ └─────────┘ │ 0x8000_0000 │ + │ wide (mem) port │ chimera_reg │ + ┌───────┴────────────────┐ │ _top (SoC │ + reg->mem + + │ chimera_memisland_domain│ │ ctrl regs) │ snitch_bootrom + │ atomics+cut+mem_island │ └─────────────┘ + │ 0x4800_0000 (512 KiB) │ + └─────────────────────────┘ +``` + +The host exposes external AXI master/slave ports and external register-demux ports. Chimera +attaches the clusters, memory island, HyperBus, and four external register slaves (Snitch +bootrom, top-level SoC-control regs, external cfg regs → APB, HyperBus cfg regs) to those ports. + +## HW module map (`hw/`) + +| File | Role | +|------|------| +| `chimera_pkg.sv` | Central config package. `ExtClusters=5`, per-cluster `ChimeraClusterCfg` (`NrCores=9`, `ClusterType`, `hasWideMasterPort`, `EnAxiCdc`), `gen_chimera_cfg()` builds the Cheshire config (48-bit addr, 64-bit AXI, LLC 64 KiB 8-way, CLIC). Holds the **address map** localparams and `ChimeraCfg[0]` (default) / `[1]` (isolation). | +| `chimera_top_wrapper.sv` | Top RTL. Instantiates `cheshire_soc`, the reg→apb + `apb_dump_msg` path, `chimera_reg_top`, reg→mem + `snitch_bootrom`, `chimera_clu_domain`, `chimera_memisland_domain`, AXI CDC + `hyperbus_wrap`. Fans reg2hw out to per-cluster clock-gate/reset/wide-bypass; builds the cluster reset AND-tree. | +| `chimera_clu_domain.sv` | Instantiates the 5 clusters in a genloop; optional `axi_isolate` per port when `IsolateClusters==1` (power gating); slices flat interrupt/debug vectors per cluster. | +| `clusters/chimera_cluster.sv` | Single Snitch cluster wrapper: `tc_clk_gating`, optional `narrow_adapter`, `chimera_cluster_adapter`, and `snitch_cluster` (TCDM 128 KiB = 1024×16 banks, 2 I$ ways, boot addr = Snitch bootrom `0x3000_0000`, one `Xdma` DMA core). PMA cached = HyperBus + memory island. | +| `chimera_cluster_adapter.sv` | Per-cluster AXI glue: ID-width conversion, wide-request demux (to memory island, or wide→narrow when outside mem-island range / in bypass mode), optional per-port `axi_cdc`. Includes SVA on bypass routing. | +| `narrow_adapter.sv` | AXI **data-width** converters between cluster narrow (64b) and SoC narrow width. | +| `chimera_memisland_domain.sv` | `axi_riscv_atomics_structs` (AMO) → `axi_cut` → `axi_memory_island_wrap`. NarrowToWide=16, 2 wide banks, 1024 words/bank. | +| `hyperbus_wrap.sv` | `axi_cdc_dst` + pulp `hyperbus` IP → HyperBus PHY pads. `NumPhys=1`, `NumChips=2`. | +| `apb_dump_msg.sv` | Sim-only: snoops APB writes to `0x3000_4ffc` and prints them as a UART-like console (`$write`). Pass-through under `SYNTHESIS`. | +| `regs/` | `chimera_regs.hjson` (source) → `chimera_reg_pkg.sv` + `chimera_reg_top.sv` (reggen). | +| `bootrom/snitch/` | Snitch cluster boot code (rv32im): `snitch_bootrom.S`, `snitch_startup.c`, `.ld` (ORIGIN `0x3000_0000`), generated `snitch_bootrom.sv`. | +| `include/chimera/typedef.svh` | `CHIMERA_TYPEDEF_*` macros deriving wide/narrow AXI struct types (exported via Bender `export_include_dirs`). | +| `rv_plic.cfg.hjson` | PLIC config template patched by `update_plic`. | + +## Address map + +> ⚠ There is currently **no single machine-readable memory map**. Three sources are kept in +> sync by hand — `hw/chimera_pkg.sv` localparams, `sw/include/soc_addr_map.h`, and the reggen +> register offsets. Unifying these via SystemRDL is a tracked TODO (see `../TODO.md`). + +| Region | Base | Size | +|--------|------|------| +| CLINT | `0x0204_0000` | — | +| Cheshire regs | `0x0300_0000` | — | +| Snitch bootrom | `0x3000_0000` | 4 KiB | +| SoC-control (top-level) regs | `0x3000_1000` | 4 KiB | +| External cfg regs (PADs/FLLs/PMU → APB) | `0x3000_2000` | 12 KiB | +| HyperBus cfg regs | `0x3000_5000` | 4 KiB | +| Cluster 0..4 | `0x4000_0000` + n·`0x20_0000` | 2 MiB each | +| Memory island | `0x4800_0000` | 512 KiB | +| HyperRAM | `0x8000_0000` | 4 GiB | + +### SoC-control register block (`0x3000_1000`, 32-bit regs) + +Generated into `sw/include/regs/soc_ctrl.h` from `hw/regs/chimera_regs.hjson`: + +| Offset | Register | +|--------|----------| +| `0x00` | `SNITCH_BOOT_ADDR` (resval `0xBADCAB1E`) | +| `0x04` | `SNITCH_CONFIGURABLE_BOOT_ADDR` (resval `0x3000_0000`) | +| `0x08` | `SNITCH_INTR_HANDLER_ADDR` | +| `0x0c`–`0x1c` | `SNITCH_CLUSTER_{0..4}_RETURN` | +| `0x20`–`0x30` | `RESET_CLUSTER_{0..4}` (resval 1) | +| `0x34`–`0x44` | `CLUSTER_{0..4}_CLK_GATE_EN` (resval 1) | +| `0x48`–`0x58` | `WIDE_MEM_CLUSTER_{0..4}_BYPASS` | +| `0x5c`–`0x6c` | `CLUSTER_{0..4}_BUSY` | + +## Notable structural risks (for verification / refactor) + +- **Config duplication**: `hw/chimera_pkg.sv` (`ChimeraCfg`) vs `target/sim/src/tb_chimera_pkg.sv` + (a separate, Cheshire-flavored config array) can drift. +- **Address-map triplication** (above). +- **Hardcoded core counts** in `chimera.mk` must track the package. +- **Fast-debug preload** force-writes memory-island SRAM via hierarchical paths + (`target/sim/src/tb_chimera_soc.sv`), which is brittle against RTL refactors of the mem island. diff --git a/docs/build-system.md b/docs/build-system.md new file mode 100644 index 00000000..e540256e --- /dev/null +++ b/docs/build-system.md @@ -0,0 +1,94 @@ +# Build System + +Chimera builds with **Bender** (HW dependency + compile-script management) driving a layered +**Make** flow that wraps Cheshire's own build machinery. There is no CMake in the current flow. + +## Entry points + +- `Makefile` (root) — sets `CHIM_ROOT`, defines `BENDER = bender -d $(CHIM_ROOT)`, resolves + dependency roots via `bender path ` (only if `.bender/` exists), then `-include`s + **`cheshire.mk` from the cheshire dependency** and **`chimera.mk`**. Also defines + `python-venv`, `dvt_flist`, and the `help` target. +- `chimera.mk` — the SoC-level targets (below). +- `bender.mk` — Bender target flags: + `COMMON_TARGS = -t snitch_cluster -t cv64a6_imafdchsclic_sv39_wb -t cva6 -t rtl`; + `SIM_TARGS = $(COMMON_TARGS) -t test -t sim`. +- `sw/sw.mk`, `target/sim/sim.mk`, `utils/utils.mk` — sub-makefiles included from `chimera.mk`. +- `iis-env.sh` — IIS environment (bender-0.31.0, questa-2022.3, RISC-V GCC 32/64, Snitch LLVM, + python3.11; auto-creates/sources `.venv`). +- `iis_compile.sh` — **empty (0 bytes)** placeholder. + +## Relationship to Cheshire + +Chimera does not reimplement the SW/bootrom/sim machinery — it **wraps** Cheshire's phonies and +reuses its variables (`CHS_SW_CC`, `CHS_SW_INCLUDES`, `CHS_SW_LIBS`, `CHS_SW_LDFLAGS`, +`CHS_SW_LD_DIR`, `gen_bootrom.py`, `elfloader.cpp`): + +| Chimera target | wraps Cheshire | +|----------------|----------------| +| `chs-hw-init` | `chs-hw-all` (after `update_plic`, `gen_idma_hw`, `libchimera.a`) | +| `chim-bootrom-init` | `chs-bootrom-all` | +| `chim-sim` | `chs-sim-all` | + +Cheshire itself is pinned to `rev wiesep/chimera-main` and locally cloned to +`working_dir/cheshire` (via `Bender.local`), which is where `cheshire.mk` comes from. + +## Targets + +| Target | What it does | +|--------|--------------| +| `chim-all` | `CHIM_HW_ALL` (`chs-hw-init sn-hw-all chim-bootrom-init`) + `chim-sw` + `chim-sim` | +| `chs-hw-init` | `update_plic` (sed-patch `rv_plic.cfg.hjson` counts) + `gen_idma_hw` (`make -C idma idma_hw_all`) + build `libchimera.a`, then `chs-hw-all` | +| `sn-hw-all` | `sn-rtl` — generate Snitch cluster RTL from `SN_CFG` (`cfg/default.json`) | +| `chim-sw` | build `libchimera.a` (`sw/lib/*.c`) + every `sw/tests/*.c` → `*.memisl.elf` + `.dump` | +| `chim-bootrom-init` | build the Cheshire bootrom (**needs `chim-sw` first**) | +| `snitch_bootrom` | compile `hw/bootrom/snitch/*.{S,c}` (rv32im) → elf → bin → `snitch_bootrom.sv` via `gen_bootrom.py` | +| `regenerate_soc_regs` | run vendored `utils/reggen/regtool.py` on `hw/regs/chimera_regs.hjson` → `chimera_reg_{pkg,top}.sv`, `sw/include/regs/soc_ctrl.h`, `hw/regs/pcr.md` | +| `chim-sim` | `chim-hyperram-model` (fetch s27ks0641 VIP) + `chs-sim-all` + `chim-compile` (`bender script vsim` → `compile.tcl`, then `vsim -c`) | +| `chim-run` | GUI sim: `vsim -voptargs=+acc tb_chimera_soc` | +| `chim-run-batch` | batch sim: `vsim -c ... tb_chimera_soc -do "run -all; quit"` | +| `dvt_flist` | `bender script flist-plus` → `.dvt/default.build` for DVT Eclipse | + +Simulation plusargs (`BINARY`, `SELCFG`, `BOOTMODE`, `PRELMODE`, `IMAGE`) are forwarded to vsim +by the `add_vsim_flag` macro in `sim.mk`. + +## Key variables + +- `CHS_XLEN ?= 64` — host is 64-bit. +- `CLINTCORES=46`, `PLICCORES=92`, `PLIC_NUM_INTRS=59` — **hand-computed** from 5 clusters × 9 + cores + host; must track `ExtClusters`/`NrCores` in `hw/chimera_pkg.sv`. +- `SN_CFG = $(SN_ROOT)/cfg/default.json` — Snitch cluster configuration. +- `CHS_SW_LD_DIR = $(CHIM_ROOT)/sw/link` — repoints linker scripts to Chimera's. + +## Dependencies (Bender) + +From `Bender.yml` / `Bender.lock` (see also `Bender.local` overrides): + +| Dep | Pin | +|-----|-----| +| cheshire | `rev wiesep/chimera-main` (local clone `working_dir/cheshire`) | +| snitch_cluster | `5b2fccd…` | +| axi | `colluca/axi` `bd1abff…` | +| idma | `0.6.5` (override `28a36e5…`) | +| memory_island | `main` | +| hyperbus | `0.0.9` | +| common_cells | `1.39.0` (override `ca9d577…`) | +| register_interface | `0.4.7` | +| apb | `0.2.4` | +| tech_cells_generic | `0.2.12` | + +`Bender.yml` also declares `workspace.package_links` (symlinks `deps/cheshire`, +`deps/snitch_cluster`, `deps/cva6`) and a `vendor_package` importing lowRISC **reggen** into +`utils/reggen/`. + +## Current status + +The repo is on branch `dev/64bit` — the switch to 64-bit CVA6 (and LLC/HyperBus rework) is in +progress. See `../TODO.md`. + +## Cleanup opportunities + +- `build/` is not gitignored (other artifacts are). +- Register generation uses **vendored reggen**; `peakrdl` (SystemRDL) is declared in + `pyproject.toml` but unused — see the SystemRDL TODO. +- Python env is a plain `venv` + `pyproject.toml`; consider `uv` + committed lockfile (Gwaihir). diff --git a/docs/memory-map.md b/docs/memory-map.md new file mode 100644 index 00000000..ad32f15a --- /dev/null +++ b/docs/memory-map.md @@ -0,0 +1,43 @@ +# Memory Map & Registers (SystemRDL) + +Chimera's SoC memory map and control registers are described **once** in SystemRDL under +`cfg/rdl/`, and all downstream artifacts are generated with [`peakrdl`](https://peakrdl.readthedocs.io) +(`make chim-rdl`). This replaces the previous hand-maintained duplication across +`hw/chimera_pkg.sv` localparams, `sw/include/soc_addr_map.h`, and the lowRISC-reggen +register block (`hw/regs/chimera_regs.hjson`). + +## Sources (`cfg/rdl/`) + +- `chimera_soc_regs.rdl` — the top-level SoC-control register block (Snitch boot/interrupt + addresses; per-cluster reset, clock-gate, return, busy, wide-memory bypass). Layout matches + the legacy offsets `0x0–0x6c`. +- `chimera_addrmap.rdl` — the **global address map**: the SoC-control block plus every region + (bootrom, external cfg regs, HyperBus cfg, the `NrClusters` cluster windows, the memory + island, and off-chip HyperRAM). + +## Generation (`make chim-rdl`) + +| Target | Output | Tool | +|--------|--------|------| +| `chim-rdl-markdown` | `docs/addressmap.md` (generated, gitignored) | `peakrdl markdown` | +| `chim-rdl-c-header` | `.generated/chimera_soc_regs.h` | `peakrdl c-header` | +| `chim-rdl-raw-header` | `.generated/chimera_addrmap.{svh,h}` (region base addrs/sizes) | `peakrdl raw-header` | +| `rdl` | all of the above | | + +All generated output lands in `.generated/` (gitignored); nothing generated is committed. + +## Migration status & plan + +Done: +- SoC-control registers + the global address map authored in SystemRDL and validated + (`peakrdl` emits correct offsets/resets and a region table matching the RTL). + +Next (incremental, to avoid breaking the RTL/SW at once): +1. Point `sw/include/soc_addr_map.h` (and the SDK targets' `soc_addr_map.h`) at the generated + `chimera_addrmap.svh`/`.h` region bases, instead of hand-editing them. +2. Replace the lowRISC-reggen register block (`chimera_reg_pkg.sv` / `chimera_reg_top.sv`, + `reg_iface`) with `peakrdl regblock`, and retire `hw/regs/chimera_regs.hjson` + `utils/reggen`. +3. Derive `hw/chimera_pkg.sv`'s address-map localparams from the RDL (or assert-check them + against the generated header in CI) so the three maps can never drift again. +4. Fold in the peripheral register blocks (cheshire, hyperbus, clint) as RDL includes so the + whole SoC map is one document (cf. Gwaihir's `cfg/rdl/`). diff --git a/docs/rdl-support.md b/docs/rdl-support.md new file mode 100644 index 00000000..9b1cb0ce --- /dev/null +++ b/docs/rdl-support.md @@ -0,0 +1,70 @@ + + +# SystemRDL support across Chimera and its dependencies + +Chimera's global memory map and SoC-control registers are described in **SystemRDL** +(`cfg/rdl/*.rdl`) and rendered with **peakrdl** (`make chim-rdl` / `make chim-rdl-regblock`, see +`rdl.mk`). The top address map (`cfg/rdl/chimera_addrmap.rdl`) is *hierarchical*: where a +dependency ships its own RDL, we `` `include `` it and instantiate it, so the generated map +(`docs/addressmap.md`, `.generated/chimera_addrmap.*`) contains that block's real internals +instead of an opaque window. + +Dependency RDL is resolved **in place** from each dependency's checkout via `bender path` +(no copying), the same mechanism Gwaihir uses. See `rdl.mk` (`PEAKRDL_INCLUDES`). + +## Support matrix + +Surveyed every Bender dependency (`bender path `) for `*.rdl` / `*.rdl.tpl` and for a +peakrdl flow in its makefiles. + +| Component | Ships RDL? | In the Chimera map? | Notes | +|---|---|---|---| +| **chimera-top** (this repo) | ✅ `cfg/rdl/chimera_{addrmap,soc_regs}.rdl` | — (it *is* the map) | SoC-control regs + top address map. The reg block is generated from RDL via `peakrdl regblock` (replaced lowRISC reggen). | +| **snitch_cluster** | ✅ `hw/generated/snitch_cluster.rdl` (+ `snitch_cluster_peripheral_reg.rdl`) | ✅ **integrated** | Real per-cluster map folded in: TCDM, bootrom, peripheral registers, zeromem. Instantiated as `snitch_cluster cluster[NrClusters]` at `0x4000_0000`. The `.rdl` is generated by clustergen from `snitch_cluster.rdl.tpl`. | +| **cheshire** (host) | ⚠️ **not in our fork** | ❌ not yet | We track `pulp-platform/cheshire@wiesep/chimera-main` (rev `21de1a9`), whose registers are still lowRISC **reggen** (`hw/regs/cheshire_regs.hjson`) with no `*.rdl` and no peakrdl in `cheshire.mk`. Upstream cheshire *does* ship `hw/cheshire.rdl` + `hw/regs/cheshire_soc_regs.rdl` and exports `CHS_PEAKRDL_INCLUDES`. Integrating the host map needs the fork bumped/rebased onto a cheshire with RDL. The host region (`0x0000_0000–0x3000_0000`: CLINT/PLIC/CLIC, LLC, UART/I²C/SPI/GPIO, debug) is currently **absent** from the Chimera map. | +| register_interface | ❌ | ❌ | Bus IP; no memory-mapped register block. | +| axi | ❌ | ❌ | Bus IP; no register block. | +| idma | ❌ (uses reggen `*.hjson`) | via cluster | iDMA config regs are reggen-generated inside the cluster; exposed through the cluster peripheral region, not as standalone RDL. | +| memory_island | ❌ | as `external mem` | Modeled in the top map as the 512 KiB `mem_island` window at `0x4800_0000` (no register block to describe). | +| apb | ❌ | ❌ | Bus IP. | +| hyperbus | ❌ (reggen) | as `external mem` | HyperBus config regs modeled as the `hyperbus_cfg` window at `0x3000_5000`; the off-chip HyperRAM as the `hyperram` window at `0x8000_0000`. Register fields not yet described in RDL. | +| common_cells | ❌ | ❌ | Utility cells; no registers. | +| tech_cells_generic | ❌ | ❌ | Technology cells; no registers. | + +Legend: ✅ has/integrated · ⚠️ partial/conditional · ❌ none. + +## What is integrated today + +- **chimera-top SoC-control registers** — the single source of truth (`cfg/rdl/chimera_soc_regs.rdl`), + rendered to the SV register block (`hw/regs/chimera_reg_{pkg,top}.sv` via `peakrdl regblock`), the + C header and the Markdown map. +- **snitch_cluster** — the real per-cluster address map (`bender path`-resolved include). + +Everything else appears in the top map as an `external mem` region (memory_island, hyperbus/hyperram, +and the config-register windows), which is correct for blocks that expose only a memory window, and a +placeholder for blocks that *do* have registers but ship them via reggen (cheshire, hyperbus, idma). + +## Not yet — and how to add it + +1. **cheshire host map** — the biggest gap. Requires our cheshire (`wiesep/chimera-main`) to gain + RDL (bump/rebase onto an upstream cheshire that ships `cheshire.rdl` + `cheshire_soc_regs.rdl`, or + port those files into the fork). Then, in `cfg/rdl/chimera_addrmap.rdl`: + `` `include "cheshire.rdl" `` and instantiate `cheshire host @0x0;`, and add + `-I $(shell bender path cheshire)/hw` (+ `hw/regs`) to `PEAKRDL_INCLUDES` in `rdl.mk` + (mirroring the `snitch_cluster` includes). Cheshire's own `CHS_PEAKRDL_INCLUDES` can be pulled in + by `include`-ing `cheshire.mk`. +2. **hyperbus registers** — describe the HyperBus controller register block in RDL (or vendor its + reggen output) and replace the `hyperbus_cfg` `external mem` stub with the real block. +3. **idma registers** — could be surfaced from the cluster's RDL once snitch_cluster exposes them. + +### Mechanism recap (to add any dependency's RDL) + +- Add `` `include ".rdl" `` to `cfg/rdl/chimera_addrmap.rdl` and instantiate the addrmap at its + base address. +- Add the dependency's RDL directory to `PEAKRDL_INCLUDES` in `rdl.mk` via + `-I $(shell bender path )/` (and any nested include dir the RDL references). +- `make chim-rdl` regenerates `docs/addressmap.md` + the headers with the new block folded in. diff --git a/docs/sdk-integration.md b/docs/sdk-integration.md new file mode 100644 index 00000000..513a32c7 --- /dev/null +++ b/docs/sdk-integration.md @@ -0,0 +1,90 @@ +# chimera-sdk Integration + +Goal: add **chimera-sdk** as a git submodule and retire the hand-written `sw/` layer +(`sw/lib/offload.c`, `sw/include/*`, `sw/link/*`, and the 8 tests), so chimera-top (and later the +downstream closed project) share one SW SDK. Tracked in `../TODO.md`. + +## What chimera-sdk is + +A newer, **CMake-first** bare-metal SW platform for Chimera-architecture SoCs (LLVM 18.1.4-pulp + +picolibc, *not* GCC/newlib). Its headline feature is a **multi-binary compilation flow**: one ELF +per execution domain (host + each device), so RV64 host and RV32 Snitch code no longer share a +common-denominator ISA. + +Key pieces: + +- `cmake/Chimera.cmake` — the API: `add_device_binary()` (compile a Snitch ELF, emit + absolute-address symbol stubs + a placement `.ldh`) and `add_host_binary()` (compile the host + ELF, link the device symbol stubs, chain placement, optionally merge into one unified ELF). +- `targets//` — per-SoC config: `config.cmake` (ISA/ABI), linker templates, crt0, + register maps, and the `chimera_shared_data_t` `.common` layout. **`chimera-open` already + matches chimera-top** (host `rv64imafdc/lp64d`, cluster `rv32imafd_xdma/ilp32d`, memisl at + `0x4800_0000`). +- `host/` — HAL (`device_api`, `interrupt_api`), drivers (cluster offload, uart_apb, clint32, + hyperbus), runtime (alloc/clint/fll/uart/log), OpenTitan peripherals. +- `devices/snitch_cluster/` — cluster runtime + the `snitch-sdk` (SNRT) submodule. +- `tests/` — per-test dirs (`src_host/` + `src_cluster/` + `CMakeLists.txt`); the canonical + example is `tests/snitchCluster/simpleOffload`. +- Build flavors via `HARDWARE_BACKEND` = `RTL` | `GVSoC` | `ASIC`; run via `ctest` + (`TEST_MODE=simulation`, RTL) or `scripts/run_tests.sh` (GVSoC/ASIC). + +## How the offload model maps + +| chimera-top today | chimera-sdk | +|-------------------|-------------| +| Host + "device" functions in one memisl ELF, offloaded by function pointer | Separate host + device ELFs, chained by placement `.ldh`, sharing a `.common` section | +| `sw/lib/offload.c` HAL | `host/drivers/cluster/offload_snitchCluster.c` | +| `sw/include/soc_addr_map.h`, `regs/soc_ctrl.h` | `targets/chimera-open/shared/inc/*` | +| `sw/link/memisl.ld`, `common.ldh` | `targets/chimera-open/{host,devices}/link.ld.in`, `shared/common.ldh` | +| GCC/newlib, rv64gc | LLVM/picolibc, per-domain ISA/ABI | + +## Integration steps + +1. **Add submodule**: `git submodule add sw/sdk` (or top-level `chimera-sdk/`). + The SDK has **nested** submodules (`snitch-sdk`, `opentitan_peripherals`) → always + `git submodule update --init --recursive`. +2. **Toolchain**: provide `TOOLCHAIN_DIR` (LLVM) + `PICOLIBC_DIR`. Easiest via the SDK container + image (below); alternatively `make llvm` / `make picolibc-multilib` in the SDK. +3. **Ensure `uv` is available** — SDK post-build steps (section-overlap check, unified-ELF merge + via `lief`) shell out to `uv run python`. +4. **Adopt/extend the `chimera-open` target** for chimera-top (verify address map, register + headers, ISA/ABI, `chimera_shared_data_t` match the RTL). Add a new `targets//` only if + chimera-top diverges from `chimera-open`. +5. **Migrate the 8 tests** into SDK test dirs (host `src_host/` + device `src_cluster/`), plus a + **new iDMA test** (current coverage gap): + testReturnZero, testCluster, testClusterOffload, testClusterGating, testCfgBootAddr, + testHyperbusAddr, testMemBypass, testPeripheralsGating. +6. **Wire simulation**: pass chimera-top's compiled RTL model as the SDK's `SOC_MODEL_BINARY` + with `TEST_MODE=simulation`, so `ctest` (and the planned pytest layer) can launch it. +7. **Retire** the old `sw/lib`, `sw/include`, `sw/link`, `sw/tests`, and the `chim-sw` make rules + once parity is reached. + +## Containerized build (Docker / Singularity) + +The SDK builds inside a toolchain container (LLVM + compiler-rt multilib + picolibc). Standard +Docker flow: + +```bash +docker run -it --rm -v $(pwd):/app/chimera zsh +cmake -D TARGET_PLATFORM=chimera-open \ + -D TOOLCHAIN_DIR=/app/install/llvm-18.1.4-pulp \ + -D PICOLIBC_DIR=/app/install/picolibc \ + -D HARDWARE_BACKEND=RTL -D CHIMERA_UNIFIED_ELF=ON -B build +cmake --build build -j +``` + +On IIS workstations (no Docker) use **Singularity/Apptainer**: +`singularity pull docker://` then `singularity shell -e -s /bin/zsh ` (`-e` isolates +the host env so container tool paths win). + +> ⚠ **Image name is inconsistent in the SDK** — README uses `chimera:latest`, usage.rst uses +> `chimera:devel`, CLAUDE.md uses `deeploy:devel`. Standardize on one before documenting the +> chimera-top build. + +## Open questions to resolve during integration + +- Submodule location/name (`sw/sdk` vs top-level `chimera-sdk`). +- Whether chimera-top keeps the Bender/Make HW flow while the SDK owns *only* SW (recommended: + yes — HW stays Bender, SW moves to the SDK's CMake). +- How the SDK's per-domain ELFs are preloaded by the existing `tb_chimera_soc.sv` fast-debug path + (which currently expects a single memisl ELF). diff --git a/docs/software.md b/docs/software.md new file mode 100644 index 00000000..e7c1f5cd --- /dev/null +++ b/docs/software.md @@ -0,0 +1,91 @@ +# Software + +The `sw/` tree is deliberately thin: it reuses Cheshire's entire SW build machinery and adds only +the Chimera-specific offload library, SoC address map, SoC-control register defines, memory-island +linker scripts, and the tests. + +## Layout + +``` +sw/ +├── sw.mk # Chimera SW build fragment +├── include/ +│ ├── offload.h # cluster offload / gating / reset API +│ ├── soc_addr_map.h # SoC memory map + per-cluster core counts +│ └── regs/soc_ctrl.h # generated SoC-control register offsets +├── lib/offload.c # the only Chimera lib source → libchimera.a +├── link/ +│ ├── common.ldh # shared MEMORY regions + peripheral base symbols +│ └── memisl.ld # places binaries in the memory island (0x4800_0000) +└── tests/*.c # 8 host test programs +``` + +## Build flow + +- Toolchain selected by `CHS_XLEN` (default 64) → `riscv64-unknown-elf-*`. `sw/sw.mk` overrides + the arch to `-march=rv64gc_zifencei -mabi=lp64d`. +- `sw/lib/*.c` → `libchimera.a`, appended to Cheshire's `CHS_SW_LIBS`. +- Each `tests/*.c` compiles to `test.o`, then links with `sw/link/memisl.ld` + libs into + `test.memisl.elf` (+ `.dump`). Only the `memisl` link variant is built by default. +- The Snitch cluster **bootrom** (`hw/bootrom/snitch/`) is the one true device binary: compiled + **rv32im** (`-march=rv32im_zicsr -mabi=ilp32`), objcopy'd to binary, converted to + `snitch_bootrom.sv`. + +## The offload model (how "device" code runs) + +There is **no separate device ELF and no objcopy-into-array embedding**. "Device" code is just +ordinary functions in the *same host ELF*, which lives in the memory island (`0x4800_0000`) — +addressable by both CVA6 and the Snitch clusters. Offload works via shared-memory function +pointers + interrupts: + +1. Host writes the target function pointer into `SNITCH_BOOT_ADDR`. +2. Host raises a CLINT software interrupt (MSIP) on the target cluster's hart + (`hartId = 1 + Σ preceding cores`; hart 0 is CVA6). +3. The cluster's rv32 bootrom (`run_from_reg`) reads `SNITCH_BOOT_ADDR` and `jalr`s into it. +4. Host busy-polls `SNITCH_CLUSTER_n_RETURN` for the result (set by `cluster_return(ret)` which + writes `ret|1`). + +The HAL is entirely in `sw/lib/offload.c` (+ `include/offload.h`): +`setupInterruptHandler`, `offloadToCluster`, `waitForCluster`, `waitClusterBusy`, +`setClusterClockGating`/`setAllClusterClockGating`, `setClusterReset`/`setAllClusterReset`. +The cluster side is `hw/bootrom/snitch/snitch_startup.c` (`cluster_startup`, `cluster_return`, +`set_busy`/`clean_busy`). + +> Note: `offload.h` declares the gating/reset setters with `uint8_t*` but `offload.c` defines +> them `volatile uint8_t*` — a signature mismatch to clean up. +> Note: host offloaded functions are rv64gc but the bootrom is rv32 — an existing quirk to be +> aware of during the SDK migration. + +## Test inventory (`sw/tests/`) + +All 8 are host (CVA6) programs; return 0 = pass. These are the tests to migrate into chimera-sdk. + +| Test | Exercises | +|------|-----------| +| `testReturnZero.c` | Smoke: ungate clusters, return 0 (host-only) | +| `testCluster.c` | Narrow-AXI accessibility of each cluster's TCDM; reset/gating | +| `testClusterOffload.c` | Canonical offload round-trip over all 5 clusters (CLINT MSIP, return regs) | +| `testClusterGating.c` | Per-cluster clock gating (waveform-inspected, not self-checking) | +| `testCfgBootAddr.c` | `SNITCH_CONFIGURABLE_BOOT_ADDR` reset value + R/W; triggers cluster boot | +| `testHyperbusAddr.c` | HyperBus cfg + HyperRAM R/W at `0x8000_0000` (needs HyperRAM VIP) | +| `testMemBypass.c` | Memory island via wide vs narrow path; `WIDE_MEM_CLUSTER_n_BYPASS`; offload | +| `testPeripheralsGating.c` | Cheshire peripheral clock-gating driven from Chimera | + +**Coverage gap:** there is **no iDMA test** despite `idma` being a dependency — add one. + +## Linker layout + +- `common.ldh` defines `MEMORY` regions: `bootrom 0x0200_0000`, `spm 0x1000_0000`, + **`memisl 0x4800_0000` (128 KiB in the script)**, `dram 0x8000_0000`, plus peripheral base + symbols. `__stack_start` tops the memory island. +- `memisl.ld` places `.text/.misc/.bss/.bulk` all in `memisl` — so host test binaries execute + out of the memory island, which is what makes offloaded functions reachable by the clusters. +- The only device linker script is the bootrom's `hw/bootrom/snitch/snitch_bootrom.ld` + (ORIGIN `0x3000_0000`, `__chim_regs = 0x3000_1000`). + +## Relationship to Cheshire SW + +Chimera inherits Cheshire's toolchain/flag machinery, `libcheshire.a` (printf, drivers, +OpenTitan DIFs, CRT0), the bootrom flow, and the linker-script structure. Chimera adds only the +offload HAL, SoC map, generated SoC-control regs, the `memisl` linker target, and the 8 tests. +Base-host coverage (helloworld, peripherals, DMA) is left to Cheshire's own `sw/tests/`. diff --git a/docs/verification.md b/docs/verification.md new file mode 100644 index 00000000..e75f6b2a --- /dev/null +++ b/docs/verification.md @@ -0,0 +1,95 @@ +# Verification + +This document describes the **current** simulation/test flow and the **planned** verification +framework. The framework work is tracked in `../TODO.md`. + +## Current flow + +Simulator: **QuestaSim/vsim only** (`iis-env.sh` pins questa-2022.3; compilation is Bender-driven +via `bender script vsim`). + +Testbench (`target/sim/src/`): + +- `tb_chimera_soc.sv` — top TB. Reads plusargs `BOOTMODE`, `PRELMODE`, `BINARY`, `IMAGE`. + Preload modes: JTAG (0), UART (2), **FAST DEBUG (3, default)** which force-writes ELF sections + directly into memory-island SRAM by hierarchical path, then polls end-of-computation. +- `fixture_chimera_soc.sv` — DUT + clocks (`ClkPeriodClu=2ns`, `ClkPeriodSys=5ns`) + VIP. +- `vip_chimera_soc.sv` — JTAG riscv-dbg driver + tasks (`jtag_init/elf_run/halt/resume/ + wait_for_eoc`, EOC from `CHESHIRE_SCRATCH_2`), UART model/printer, I²C EEPROM, SPI flash, and + HyperRAM models with `$sdf_annotate`. +- `tb_chimera_pkg.sv` — a sim-side config array (separate from `chimera_pkg::ChimeraCfg`). + +How a test runs today: + +```sh +make chim-sw +make chim-run-batch BINARY=sw/tests/testClusterOffload.memisl.elf VSIM_FLAGS="-l t.transcript" +./scripts/vsim_ret_error.sh t.transcript # greps "Errors: N", nonzero if N>0 +``` + +CI (`.gitlab-ci.yml`) runs `init-deps → vsim-build → vsim-test`, where `vsim-test` is a fixed +`parallel:matrix` over `{testCluster, testClusterOffload, testMemBypass, testPeripheralsGating, +testHyperbusAddr, testCfgBootAddr}`, each invoked as above. + +### Limitations + +- Pass/fail is *grep the transcript* — no structured result, no per-assertion reporting. +- The test list lives only in CI YAML → **cannot be reproduced locally** with one command. +- No golden-model / data-output verification. +- Single simulator; no GVSoC path. + +## Planned framework + +Design goals: (1) the **exact same test runs locally and in CI**; (2) structured, browsable +reporting; (3) a declarative test registry; (4) built on top of the `chimera-sdk` CMake/ctest +build (see `sdk-integration.md`). + +**Chosen tooling: `pytest` as the single top-level runner.** CI (`.gitlab-ci.yml` / GitHub +Actions) does nothing but call `pytest`; so does the developer. Rationale: + +- `@pytest.mark.parametrize` expresses the test matrix `(binary, backend, prelmode, expected)` in + Python — this replaces the CI-only YAML matrix and is the *locally runnable* equivalent of + Gwaihir's `parallel:matrix` registry. +- fixtures model "build ELFs once (session), launch a sim per test, tear down cleanly". +- `--junitxml` + `pytest-html` give CI-consumable and browsable reports from one run. +- markers (`-m hyperbus`, `-m offload`, `-m "not slow"`) select subsets. +- `pytest-xdist` parallelizes locally, matching CI throughput. + +**Layering:** keep `ctest` (already partially wired in chimera-sdk via `add_test` when +`TEST_MODE=simulation`) as the thin CMake-native registration; pytest is the orchestration + +reporting layer on top (it can shell out to `ctest -R ` or invoke the sim directly). + +**Result contract (adopt from Gwaihir):** the testbench prints a canonical `] SUCCESS` / a +`return code N`, and a single shared checker interprets it (success string / expected nonzero +exit / optional UART match / fail on any `Fatal:`/`Error:`). For data-heavy kernels, dump memory +and run a Python `verify.py` subclassing one shared `Verifier` (`get_expected`/`get_actual`). + +> Runner performance is intentionally not a selection criterion — wall-clock is dominated by the +> RTL/GVSoC simulation, so a faster (e.g. Rust) runner would not move the needle and would leave +> the toolchain (Python/uv/CMake) fragmented. + +### Sketch + +``` +tests/ +├── conftest.py # fixtures: build session, sim launcher, transcript parser +├── registry.py # TEST_MATRIX = [(elf, backend, prelmode, expected), ...] +└── test_soc.py # @parametrize over registry -> launch sim -> assert on result +``` + +```yaml +# .gitlab-ci.yml (and mirrored GitHub workflow) — the entire test stage: +test: + script: + - pytest --junitxml=report.xml + artifacts: + reports: { junit: report.xml } +``` + +## Migration path + +1. Land `chimera-sdk` integration (SW builds via CMake, ELFs land in `build/bin/`). +2. Migrate the 8 tests (+ a new iDMA test) into SDK test dirs. +3. Add the pytest harness + registry; wire the shared result contract into the TB. +4. Replace the CI `vsim-test` matrix and `scripts/vsim_ret_error.sh` with a single `pytest` call. +5. (Optional) add a second simulator and/or a GVSoC backend behind the same `backend` param. diff --git a/hw/apb_dump_msg.sv b/hw/apb_dump_msg.sv index af22ee60..3f1fe54c 100644 --- a/hw/apb_dump_msg.sv +++ b/hw/apb_dump_msg.sv @@ -19,11 +19,11 @@ module apb_dump_msg input logic clk_i, input logic rst_ni, // From Top - output apb_resp_t apb_rsp_o, - input apb_req_t apb_req_i, + output apb_soc_resp_t apb_rsp_o, + input apb_soc_req_t apb_req_i, // To Top - input apb_resp_t apb_rsp_i, - output apb_req_t apb_req_o + input apb_soc_resp_t apb_rsp_i, + output apb_soc_req_t apb_req_o ); `ifdef SYNTHESIS diff --git a/hw/bootrom/snitch/snitch_bootrom.S b/hw/bootrom/snitch/snitch_bootrom.S index 691435c9..a7f39be6 100644 --- a/hw/bootrom/snitch/snitch_bootrom.S +++ b/hw/bootrom/snitch/snitch_bootrom.S @@ -4,7 +4,15 @@ // // Moritz Scherer -#include +// SoC-control register addresses from the SystemRDL single source of truth +// (peakrdl raw-header -> .generated/chimera_addrmap_raw.h, `make rdl`), resolved +// via -I .generated. Register offsets are (absolute addr - SoC-control base). +#include "chimera_addrmap_raw.h" + +#define CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET \ + (CHIMERA_ADDRMAP_SOC_CTRL_SNITCH_BOOT_ADDR_BASE_ADDR - CHIMERA_ADDRMAP_SOC_CTRL_BASE_ADDR) +#define CHIMERA_SNITCH_INTR_HANDLER_ADDR_REG_OFFSET \ + (CHIMERA_ADDRMAP_SOC_CTRL_SNITCH_INTR_HANDLER_ADDR_BASE_ADDR - CHIMERA_ADDRMAP_SOC_CTRL_BASE_ADDR) .global _start _start: diff --git a/hw/bootrom/snitch/snitch_bootrom.bin b/hw/bootrom/snitch/snitch_bootrom.bin index a1166c51..3f70cba5 100755 Binary files a/hw/bootrom/snitch/snitch_bootrom.bin and b/hw/bootrom/snitch/snitch_bootrom.bin differ diff --git a/hw/bootrom/snitch/snitch_bootrom.sv b/hw/bootrom/snitch/snitch_bootrom.sv index 5253b812..0df7325b 100644 --- a/hw/bootrom/snitch/snitch_bootrom.sv +++ b/hw/bootrom/snitch/snitch_bootrom.sv @@ -11,7 +11,7 @@ // // AUTOMATICALLY GENERATED by gen_bootrom.py; edit the script instead. -module snitch_bootrom #( +module chimera_snitch_bootrom #( parameter int unsigned AddrWidth = 32, parameter int unsigned DataWidth = 32 )( @@ -30,7 +30,7 @@ module snitch_bootrom #( data_o = '0; unique case (word) 000: data_o = 32'h30057073 /* 0x0000 */; - 001: data_o = 32'h244000ef /* 0x0004 */; + 001: data_o = 32'h0cc000ef /* 0x0004 */; 002: data_o = 32'h00000297 /* 0x0008 */; 003: data_o = 32'h0a828293 /* 0x000c */; 004: data_o = 32'h30529073 /* 0x0010 */; @@ -61,14 +61,14 @@ module snitch_bootrom #( 029: data_o = 32'h00000e93 /* 0x0074 */; 030: data_o = 32'h00000f13 /* 0x0078 */; 031: data_o = 32'h00000f93 /* 0x007c */; - 032: data_o = 32'h0d4000ef /* 0x0080 */; + 032: data_o = 32'h0d8000ef /* 0x0080 */; 033: data_o = 32'h10500073 /* 0x0084 */; - 034: data_o = 32'h048000ef /* 0x0088 */; + 034: data_o = 32'h148000ef /* 0x0088 */; 035: data_o = 32'h00001297 /* 0x008c */; 036: data_o = 32'hf7428293 /* 0x0090 */; 037: data_o = 32'h0002a283 /* 0x0094 */; 038: data_o = 32'h000280e7 /* 0x0098 */; - 039: data_o = 32'h130000ef /* 0x009c */; + 039: data_o = 32'h040000ef /* 0x009c */; 040: data_o = 32'hf75ff06f /* 0x00a0 */; 041: data_o = 32'h00000013 /* 0x00a4 */; 042: data_o = 32'h00000013 /* 0x00a8 */; @@ -81,102 +81,102 @@ module snitch_bootrom #( 049: data_o = 32'h00000000 /* 0x00c4 */; 050: data_o = 32'h00000000 /* 0x00c8 */; 051: data_o = 32'h00000000 /* 0x00cc */; - 052: data_o = 32'hf14027f3 /* 0x00d0 */; - 053: data_o = 32'h01300713 /* 0x00d4 */; - 054: data_o = 32'h0ff7f793 /* 0x00d8 */; - 055: data_o = 32'h04e78463 /* 0x00dc */; - 056: data_o = 32'h00f76c63 /* 0x00e0 */; - 057: data_o = 32'h00100713 /* 0x00e4 */; - 058: data_o = 32'h02e78263 /* 0x00e8 */; - 059: data_o = 32'h00a00693 /* 0x00ec */; - 060: data_o = 32'h02d78463 /* 0x00f0 */; - 061: data_o = 32'h00008067 /* 0x00f4 */; - 062: data_o = 32'h01c00713 /* 0x00f8 */; - 063: data_o = 32'h02e78c63 /* 0x00fc */; - 064: data_o = 32'h02500713 /* 0x0100 */; - 065: data_o = 32'h04e78063 /* 0x0104 */; - 066: data_o = 32'h00008067 /* 0x0108 */; - 067: data_o = 32'h30001737 /* 0x010c */; - 068: data_o = 32'h04f72e23 /* 0x0110 */; - 069: data_o = 32'h00008067 /* 0x0114 */; - 070: data_o = 32'h300017b7 /* 0x0118 */; - 071: data_o = 32'h06e7a023 /* 0x011c */; - 072: data_o = 32'h00008067 /* 0x0120 */; - 073: data_o = 32'h300017b7 /* 0x0124 */; - 074: data_o = 32'h00100713 /* 0x0128 */; - 075: data_o = 32'h06e7a223 /* 0x012c */; + 052: data_o = 32'h304467f3 /* 0x00d0 */; + 053: data_o = 32'h300467f3 /* 0x00d4 */; + 054: data_o = 32'h00008067 /* 0x00d8 */; + 055: data_o = 32'hf14027f3 /* 0x00dc */; + 056: data_o = 32'h01300713 /* 0x00e0 */; + 057: data_o = 32'h0ff7f793 /* 0x00e4 */; + 058: data_o = 32'h00156513 /* 0x00e8 */; + 059: data_o = 32'h04e78463 /* 0x00ec */; + 060: data_o = 32'h00f76c63 /* 0x00f0 */; + 061: data_o = 32'h00100713 /* 0x00f4 */; + 062: data_o = 32'h02e78263 /* 0x00f8 */; + 063: data_o = 32'h00a00713 /* 0x00fc */; + 064: data_o = 32'h02e78463 /* 0x0100 */; + 065: data_o = 32'h00008067 /* 0x0104 */; + 066: data_o = 32'h01c00713 /* 0x0108 */; + 067: data_o = 32'h02e78a63 /* 0x010c */; + 068: data_o = 32'h02500713 /* 0x0110 */; + 069: data_o = 32'h02e78c63 /* 0x0114 */; + 070: data_o = 32'h00008067 /* 0x0118 */; + 071: data_o = 32'h300017b7 /* 0x011c */; + 072: data_o = 32'h00a7a623 /* 0x0120 */; + 073: data_o = 32'h00008067 /* 0x0124 */; + 074: data_o = 32'h300017b7 /* 0x0128 */; + 075: data_o = 32'h00a7a823 /* 0x012c */; 076: data_o = 32'h00008067 /* 0x0130 */; 077: data_o = 32'h300017b7 /* 0x0134 */; - 078: data_o = 32'h00100713 /* 0x0138 */; - 079: data_o = 32'h06e7a423 /* 0x013c */; - 080: data_o = 32'h00008067 /* 0x0140 */; - 081: data_o = 32'h300017b7 /* 0x0144 */; - 082: data_o = 32'h00100713 /* 0x0148 */; - 083: data_o = 32'h06e7a623 /* 0x014c */; - 084: data_o = 32'h00008067 /* 0x0150 */; - 085: data_o = 32'hf14027f3 /* 0x0154 */; - 086: data_o = 32'h01300713 /* 0x0158 */; - 087: data_o = 32'h0ff7f793 /* 0x015c */; - 088: data_o = 32'h04e78463 /* 0x0160 */; - 089: data_o = 32'h00f76c63 /* 0x0164 */; - 090: data_o = 32'h00100713 /* 0x0168 */; - 091: data_o = 32'h02e78263 /* 0x016c */; - 092: data_o = 32'h00a00713 /* 0x0170 */; - 093: data_o = 32'h02e78463 /* 0x0174 */; - 094: data_o = 32'h00008067 /* 0x0178 */; - 095: data_o = 32'h01c00713 /* 0x017c */; - 096: data_o = 32'h02e78a63 /* 0x0180 */; - 097: data_o = 32'h02500713 /* 0x0184 */; - 098: data_o = 32'h02e78c63 /* 0x0188 */; - 099: data_o = 32'h00008067 /* 0x018c */; - 100: data_o = 32'h300017b7 /* 0x0190 */; - 101: data_o = 32'h0407ae23 /* 0x0194 */; - 102: data_o = 32'h00008067 /* 0x0198 */; - 103: data_o = 32'h300017b7 /* 0x019c */; - 104: data_o = 32'h0607a023 /* 0x01a0 */; - 105: data_o = 32'h00008067 /* 0x01a4 */; - 106: data_o = 32'h300017b7 /* 0x01a8 */; - 107: data_o = 32'h0607a223 /* 0x01ac */; - 108: data_o = 32'h00008067 /* 0x01b0 */; - 109: data_o = 32'h300017b7 /* 0x01b4 */; - 110: data_o = 32'h0607a423 /* 0x01b8 */; - 111: data_o = 32'h00008067 /* 0x01bc */; - 112: data_o = 32'h300017b7 /* 0x01c0 */; - 113: data_o = 32'h0607a623 /* 0x01c4 */; - 114: data_o = 32'h00008067 /* 0x01c8 */; - 115: data_o = 32'hf14027f3 /* 0x01cc */; - 116: data_o = 32'h01300713 /* 0x01d0 */; - 117: data_o = 32'h0ff7f793 /* 0x01d4 */; - 118: data_o = 32'h00156513 /* 0x01d8 */; + 078: data_o = 32'h00a7aa23 /* 0x0138 */; + 079: data_o = 32'h00008067 /* 0x013c */; + 080: data_o = 32'h300017b7 /* 0x0140 */; + 081: data_o = 32'h00a7ac23 /* 0x0144 */; + 082: data_o = 32'h00008067 /* 0x0148 */; + 083: data_o = 32'h300017b7 /* 0x014c */; + 084: data_o = 32'h00a7ae23 /* 0x0150 */; + 085: data_o = 32'h00008067 /* 0x0154 */; + 086: data_o = 32'hf14027f3 /* 0x0158 */; + 087: data_o = 32'h01300713 /* 0x015c */; + 088: data_o = 32'h0ff7f793 /* 0x0160 */; + 089: data_o = 32'h04e78463 /* 0x0164 */; + 090: data_o = 32'h00f76c63 /* 0x0168 */; + 091: data_o = 32'h00100713 /* 0x016c */; + 092: data_o = 32'h02e78263 /* 0x0170 */; + 093: data_o = 32'h00a00713 /* 0x0174 */; + 094: data_o = 32'h02e78463 /* 0x0178 */; + 095: data_o = 32'h00008067 /* 0x017c */; + 096: data_o = 32'h01c00713 /* 0x0180 */; + 097: data_o = 32'h02e78a63 /* 0x0184 */; + 098: data_o = 32'h02500713 /* 0x0188 */; + 099: data_o = 32'h02e78c63 /* 0x018c */; + 100: data_o = 32'h00008067 /* 0x0190 */; + 101: data_o = 32'h300017b7 /* 0x0194 */; + 102: data_o = 32'h0407ae23 /* 0x0198 */; + 103: data_o = 32'h00008067 /* 0x019c */; + 104: data_o = 32'h300017b7 /* 0x01a0 */; + 105: data_o = 32'h0607a023 /* 0x01a4 */; + 106: data_o = 32'h00008067 /* 0x01a8 */; + 107: data_o = 32'h300017b7 /* 0x01ac */; + 108: data_o = 32'h0607a223 /* 0x01b0 */; + 109: data_o = 32'h00008067 /* 0x01b4 */; + 110: data_o = 32'h300017b7 /* 0x01b8 */; + 111: data_o = 32'h0607a423 /* 0x01bc */; + 112: data_o = 32'h00008067 /* 0x01c0 */; + 113: data_o = 32'h300017b7 /* 0x01c4 */; + 114: data_o = 32'h0607a623 /* 0x01c8 */; + 115: data_o = 32'h00008067 /* 0x01cc */; + 116: data_o = 32'hf14027f3 /* 0x01d0 */; + 117: data_o = 32'h01300713 /* 0x01d4 */; + 118: data_o = 32'h0ff7f793 /* 0x01d8 */; 119: data_o = 32'h04e78463 /* 0x01dc */; 120: data_o = 32'h00f76c63 /* 0x01e0 */; 121: data_o = 32'h00100713 /* 0x01e4 */; 122: data_o = 32'h02e78263 /* 0x01e8 */; - 123: data_o = 32'h00a00713 /* 0x01ec */; - 124: data_o = 32'h02e78463 /* 0x01f0 */; + 123: data_o = 32'h00a00693 /* 0x01ec */; + 124: data_o = 32'h02d78463 /* 0x01f0 */; 125: data_o = 32'h00008067 /* 0x01f4 */; 126: data_o = 32'h01c00713 /* 0x01f8 */; - 127: data_o = 32'h02e78a63 /* 0x01fc */; + 127: data_o = 32'h02e78c63 /* 0x01fc */; 128: data_o = 32'h02500713 /* 0x0200 */; - 129: data_o = 32'h02e78c63 /* 0x0204 */; + 129: data_o = 32'h04e78063 /* 0x0204 */; 130: data_o = 32'h00008067 /* 0x0208 */; - 131: data_o = 32'h300017b7 /* 0x020c */; - 132: data_o = 32'h00a7a623 /* 0x0210 */; + 131: data_o = 32'h30001737 /* 0x020c */; + 132: data_o = 32'h04f72e23 /* 0x0210 */; 133: data_o = 32'h00008067 /* 0x0214 */; 134: data_o = 32'h300017b7 /* 0x0218 */; - 135: data_o = 32'h00a7a823 /* 0x021c */; + 135: data_o = 32'h06e7a023 /* 0x021c */; 136: data_o = 32'h00008067 /* 0x0220 */; 137: data_o = 32'h300017b7 /* 0x0224 */; - 138: data_o = 32'h00a7aa23 /* 0x0228 */; - 139: data_o = 32'h00008067 /* 0x022c */; - 140: data_o = 32'h300017b7 /* 0x0230 */; - 141: data_o = 32'h00a7ac23 /* 0x0234 */; - 142: data_o = 32'h00008067 /* 0x0238 */; - 143: data_o = 32'h300017b7 /* 0x023c */; - 144: data_o = 32'h00a7ae23 /* 0x0240 */; - 145: data_o = 32'h00008067 /* 0x0244 */; - 146: data_o = 32'h304467f3 /* 0x0248 */; - 147: data_o = 32'h300467f3 /* 0x024c */; + 138: data_o = 32'h00100713 /* 0x0228 */; + 139: data_o = 32'h06e7a223 /* 0x022c */; + 140: data_o = 32'h00008067 /* 0x0230 */; + 141: data_o = 32'h300017b7 /* 0x0234 */; + 142: data_o = 32'h00100713 /* 0x0238 */; + 143: data_o = 32'h06e7a423 /* 0x023c */; + 144: data_o = 32'h00008067 /* 0x0240 */; + 145: data_o = 32'h300017b7 /* 0x0244 */; + 146: data_o = 32'h00100713 /* 0x0248 */; + 147: data_o = 32'h06e7a623 /* 0x024c */; 148: data_o = 32'h00008067 /* 0x0250 */; 149: data_o = 32'h00000000 /* 0x0254 */; 150: data_o = 32'h00000000 /* 0x0258 */; diff --git a/hw/bootrom/snitch/snitch_startup.c b/hw/bootrom/snitch/snitch_startup.c index a4848227..3768f577 100644 --- a/hw/bootrom/snitch/snitch_startup.c +++ b/hw/bootrom/snitch/snitch_startup.c @@ -6,8 +6,14 @@ // Lorenzo Leone #include -#include -#include + +// SoC-control register absolute addresses come straight from the SystemRDL +// single source of truth (peakrdl raw-header -> .generated/chimera_addrmap_raw.h, +// `make rdl`). The per-cluster core count / cluster count come from the +// generated snitch cluster config. All resolved via -I .generated (see chimera.mk). +#include "chimera_addrmap_raw.h" +#include "snitch_cluster_addrmap.h" +#include "snitch_cluster_cfg.h" #define set_csr(reg, bit) \ ({ \ @@ -24,6 +30,21 @@ #define MSTATUS_MIE 0x00000008 #define MIP_MSIP (1 << IRQ_M_SOFT) +// Snitch harts are numbered 1..(SNRT_CLUSTER_NUM * CFG_CLUSTER_NR_CORES); the +// host is hart 0. Only a cluster's first hart drives that cluster's SoC-control +// registers. Returns 1 and sets *clusterId when hartId is such a first hart. +static inline int chimera_cluster_of_hart(uint8_t hartId, uint32_t *clusterId) { + if (hartId < 1) { + return 0; + } + uint32_t idx = (uint32_t)hartId - 1u; + if (idx % CFG_CLUSTER_NR_CORES != 0) { + return 0; + } + *clusterId = idx / CFG_CLUSTER_NR_CORES; + return (*clusterId < SNRT_CLUSTER_NUM); +} + void cluster_startup() { set_csr(mie, MIP_MSIP); set_csr(mstatus, MSTATUS_MIE); // set M global interrupt enable @@ -31,88 +52,39 @@ void cluster_startup() { } void cluster_return(uint32_t ret) { - uint32_t retVal = ret | 0x000000001; uint8_t hartId; asm("csrr %0, mhartid" : "=r"(hartId)::); - switch (hartId) { - - case 1: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_0_RETURN_REG_OFFSET)) = + uint32_t clusterId; + if (chimera_cluster_of_hart(hartId, &clusterId)) { + *((volatile uint32_t *)CHIMERA_ADDRMAP_SOC_CTRL_SNITCH_CLUSTER_RETURN_BASE_ADDR(clusterId)) = retVal; - break; - case 1 + CLUSTER_0_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_1_RETURN_REG_OFFSET)) = - retVal; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_2_RETURN_REG_OFFSET)) = - retVal; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES + CLUSTER_2_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_3_RETURN_REG_OFFSET)) = - retVal; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES + CLUSTER_2_NUMCORES + CLUSTER_3_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_4_RETURN_REG_OFFSET)) = - retVal; - break; } return; } void clean_busy() { - uint8_t hartId; asm("csrr %0, mhartid" : "=r"(hartId)::); - switch (hartId) { - - case 1: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_0_BUSY_REG_OFFSET)) = 0; - break; - case 1 + CLUSTER_0_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_1_BUSY_REG_OFFSET)) = 0; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_2_BUSY_REG_OFFSET)) = 0; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES + CLUSTER_2_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_3_BUSY_REG_OFFSET)) = 0; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES + CLUSTER_2_NUMCORES + CLUSTER_3_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_4_BUSY_REG_OFFSET)) = 0; - break; + uint32_t clusterId; + if (chimera_cluster_of_hart(hartId, &clusterId)) { + *((volatile uint32_t *)CHIMERA_ADDRMAP_SOC_CTRL_CLUSTER_BUSY_BASE_ADDR(clusterId)) = 0; } return; } void set_busy() { - uint8_t hartId; asm("csrr %0, mhartid" : "=r"(hartId)::); - switch (hartId) { - - case 1: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_0_BUSY_REG_OFFSET)) = 1; - break; - case 1 + CLUSTER_0_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_1_BUSY_REG_OFFSET)) = 1; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_2_BUSY_REG_OFFSET)) = 1; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES + CLUSTER_2_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_3_BUSY_REG_OFFSET)) = 1; - break; - case 1 + CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES + CLUSTER_2_NUMCORES + CLUSTER_3_NUMCORES: - *((volatile uint32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_4_BUSY_REG_OFFSET)) = 1; - break; + uint32_t clusterId; + if (chimera_cluster_of_hart(hartId, &clusterId)) { + *((volatile uint32_t *)CHIMERA_ADDRMAP_SOC_CTRL_CLUSTER_BUSY_BASE_ADDR(clusterId)) = 1; } return; diff --git a/hw/chimera_pkg.sv b/hw/chimera_pkg.sv index 96aaca0b..67d875ab 100644 --- a/hw/chimera_pkg.sv +++ b/hw/chimera_pkg.sv @@ -141,10 +141,8 @@ ExtClusters localparam shrt_bt MemIslWordsPerBank = 1024; // WIESEP: Memory Island size = 16 * 2 * 4096 * 32 bit = 512 KB - // Hyperbus - localparam byte_bt HyperbusIdx = MemIslandIdx + 1; - // WIESEP: Address space 256 MiB - localparam doub_bt HyperbusRegionLength = 64'h1000_0000; + + localparam doub_bt HyperbusRegionLength = 64'h1_0000_0000; localparam doub_bt HyperbusRegionStart = 64'h8000_0000; localparam doub_bt HyperbusRegionEnd = HyperbusRegionStart + HyperbusRegionLength; @@ -166,21 +164,29 @@ ExtClusters chimera_cfg_t chimera_cfg; cheshire_cfg_t cfg = DefaultCfg; - // Global CFG - // Set all Chimera addresses as uncached - cfg.Cva6ExtCieLength = 'h0; - cfg.Cva6ExtCieOnTop = 1; + // Configure Cached, In, Execute Regions + cfg.Cva6ExtCieBase = MemIslRegionStart; + cfg.Cva6ExtCieLength = MemIslRegionLength; + // Global CFG cfg.Vga = 0; cfg.SerialLink = 0; - // SCHEREMO: Fully remove LLC - cfg.LlcNotBypass = 0; - cfg.LlcOutConnect = 0; + cfg.Clic = 1; + cfg.Usb = 0; + // LLC Config + // 64 KiB (8 way-set associative, 128 lines, 64B line size) + cfg.LlcNotBypass = 1; + cfg.LlcOutConnect = 1; + cfg.LlcSetAssoc = 8; + cfg.LlcNumLines = 128; + cfg.LlcNumBlocks = 8; + cfg.LlcOutRegionStart = HyperbusRegionStart; + cfg.LlcOutRegionEnd = HyperbusRegionEnd; // AXI CFG cfg.AxiMstIdWidth = 2; - cfg.AxiDataWidth = 32; + cfg.AxiDataWidth = 64; cfg.AddrWidth = 48; cfg.LlcOutRegionEnd = 'hFFFF_FFFF; @@ -188,12 +194,12 @@ ExtClusters // SCHEREMO: Two ports for each cluster: one to convert stray wides, one for the original narrow cfg.AxiExtNumMst = ExtClusters + $countones(ChimeraClusterCfg.hasWideMasterPort); - cfg.AxiExtNumSlv = ExtClusters + MemoryIsland + Hyperbus; - cfg.AxiExtNumRules = ExtClusters + MemoryIsland + Hyperbus; + cfg.AxiExtNumSlv = ExtClusters + MemoryIsland; + cfg.AxiExtNumRules = ExtClusters + MemoryIsland; - cfg.AxiExtRegionIdx = {HyperbusIdx, MemIslandIdx, ClusterIdx}; - cfg.AxiExtRegionStart = {HyperbusRegionStart, MemIslRegionStart, ClusterRegionStart}; - cfg.AxiExtRegionEnd = {HyperbusRegionEnd, MemIslRegionEnd, ClusterRegionEnd}; + cfg.AxiExtRegionIdx = {MemIslandIdx, ClusterIdx}; + cfg.AxiExtRegionStart = {MemIslRegionStart, ClusterRegionStart}; + cfg.AxiExtRegionEnd = {MemIslRegionEnd, ClusterRegionEnd}; // REG CFG cfg.RegExtNumSlv = ExtRegNum; @@ -252,6 +258,6 @@ ExtClusters localparam type data_t = logic [RegDataWidth-1:0]; localparam type strb_t = logic [RegDataWidth/8-1:0]; - `APB_TYPEDEF_ALL(apb, addr_t, data_t, strb_t) + `APB_TYPEDEF_ALL(apb_soc, addr_t, data_t, strb_t) endpackage diff --git a/hw/chimera_top_wrapper.sv b/hw/chimera_top_wrapper.sv index 467f273d..81e55ee1 100644 --- a/hw/chimera_top_wrapper.sv +++ b/hw/chimera_top_wrapper.sv @@ -67,8 +67,8 @@ module chimera_top_wrapper output logic [ HypNumPhys-1:0] hyper_dq_oe_o, output logic [ HypNumPhys-1:0] hyper_reset_no, // APB interface - input apb_resp_t apb_rsp_i, - output apb_req_t apb_req_o, + input apb_soc_resp_t apb_rsp_i, + output apb_soc_req_t apb_req_o, // PMU Clusters control signals input logic [ExtClusters-1:0] pmu_rst_clusters_ni, input logic [ExtClusters-1:0] pmu_clkgate_en_clusters_i, // TODO: lleone @@ -94,11 +94,13 @@ module chimera_top_wrapper localparam type axi_wide_slv_req_t = mem_isl_wide_axi_slv_req_t; localparam type axi_wide_slv_rsp_t = mem_isl_wide_axi_slv_rsp_t; - chimera_reg2hw_t reg2hw; + chimera_reg_pkg::chimera_soc_regs__out_t chimera_hwif_out; // External AXI crossbar ports axi_mst_req_t [iomsb(ChsCfg.AxiExtNumMst):0] axi_mst_req; axi_mst_rsp_t [iomsb(ChsCfg.AxiExtNumMst):0] axi_mst_rsp; + axi_llc_req_t axi_llc_req; + axi_llc_rsp_t axi_llc_rsp; axi_wide_mst_req_t [iomsb(ChsCfg.AxiExtNumWideMst):0] axi_wide_mst_req; axi_wide_mst_rsp_t [iomsb(ChsCfg.AxiExtNumWideMst):0] axi_wide_mst_rsp; axi_slv_req_t [iomsb(ChsCfg.AxiExtNumSlv):0] axi_slv_req; @@ -123,8 +125,8 @@ module chimera_top_wrapper logic [iomsb(ChsCfg.NumExtDbgHarts):0] dbg_ext_unavail; // Logic signals to APB dump mdoule - apb_req_t apb_to_dump_req; - apb_resp_t apb_from_dump_rsp; + apb_soc_req_t apb_to_dump_req; + apb_soc_resp_t apb_from_dump_rsp; // --------------------------------------- // | Cheshire SoC | @@ -133,8 +135,8 @@ module chimera_top_wrapper cheshire_soc #( .Cfg (ChsCfg), .ExtHartinfo ('0), - .axi_ext_llc_req_t(axi_mst_req_t), - .axi_ext_llc_rsp_t(axi_mst_rsp_t), + .axi_ext_llc_req_t(axi_llc_req_t), + .axi_ext_llc_rsp_t(axi_llc_rsp_t), .axi_ext_mst_req_t(axi_mst_req_t), .axi_ext_mst_rsp_t(axi_mst_rsp_t), .axi_ext_slv_req_t(axi_slv_req_t), @@ -148,8 +150,8 @@ module chimera_top_wrapper .boot_mode_i, .rtc_i, // External AXI LLC (DRAM) port - .axi_llc_mst_req_o(), - .axi_llc_mst_rsp_i('0), + .axi_llc_mst_req_o(axi_llc_req), + .axi_llc_mst_rsp_i(axi_llc_rsp), // External AXI crossbar ports .axi_ext_mst_req_i(axi_mst_req), .axi_ext_mst_rsp_o(axi_mst_rsp), @@ -257,16 +259,37 @@ module chimera_top_wrapper // TOP-LEVEL REG - chimera_reg_top #( + // Convert the register bus to APB4 for the peakrdl-generated register block. + apb_soc_req_t soc_reg_apb_req; + apb_soc_resp_t soc_reg_apb_rsp; + reg_to_apb #( .reg_req_t(reg_req_t), - .reg_rsp_t(reg_rsp_t) - ) i_reg_top ( + .reg_rsp_t(reg_rsp_t), + .apb_req_t(apb_req_t), + .apb_rsp_t(apb_resp_t) + ) i_soc_reg_to_apb ( .clk_i (soc_clk_i), - .rst_ni, + .rst_ni (rst_ni), .reg_req_i(reg_slv_req[TopLevelCfgRegsIdx]), .reg_rsp_o(reg_slv_rsp[TopLevelCfgRegsIdx]), - .reg2hw (reg2hw), - .devmode_i('1) + .apb_req_o(soc_reg_apb_req), + .apb_rsp_i(soc_reg_apb_rsp) + ); + + chimera_reg_top i_reg_top ( + .clk (soc_clk_i), + .arst_n (rst_ni), + .s_apb_psel (soc_reg_apb_req.psel), + .s_apb_penable(soc_reg_apb_req.penable), + .s_apb_pwrite (soc_reg_apb_req.pwrite), + .s_apb_pprot (soc_reg_apb_req.pprot), + .s_apb_paddr (soc_reg_apb_req.paddr[6:0]), + .s_apb_pwdata (soc_reg_apb_req.pwdata), + .s_apb_pstrb (soc_reg_apb_req.pstrb), + .s_apb_pready (soc_reg_apb_rsp.pready), + .s_apb_prdata (soc_reg_apb_rsp.prdata), + .s_apb_pslverr(soc_reg_apb_rsp.pslverr), + .hwif_out (chimera_hwif_out) ); @@ -304,7 +327,7 @@ module chimera_top_wrapper .rerror_i (snitch_bootrom_we_q) ); - snitch_bootrom #( + chimera_snitch_bootrom #( .AddrWidth(32), .DataWidth(32) ) i_snitch_bootrom ( @@ -317,11 +340,11 @@ module chimera_top_wrapper logic [ExtClusters-1:0] wide_mem_bypass_mode; assign wide_mem_bypass_mode = { - reg2hw.wide_mem_cluster_4_bypass.q, - reg2hw.wide_mem_cluster_3_bypass.q, - reg2hw.wide_mem_cluster_2_bypass.q, - reg2hw.wide_mem_cluster_1_bypass.q, - reg2hw.wide_mem_cluster_0_bypass.q + chimera_hwif_out.wide_mem_cluster_bypass[4].value.value, + chimera_hwif_out.wide_mem_cluster_bypass[3].value.value, + chimera_hwif_out.wide_mem_cluster_bypass[2].value.value, + chimera_hwif_out.wide_mem_cluster_bypass[1].value.value, + chimera_hwif_out.wide_mem_cluster_bypass[0].value.value }; logic [ExtClusters-1:0] cluster_clock_gate_en; @@ -331,22 +354,22 @@ module chimera_top_wrapper // It will be used to drive the actual clk eneable signal in each cluster. // For this reason it's inverted when connected to the cluster. assign cluster_clock_gate_en = { - reg2hw.cluster_4_clk_gate_en, - reg2hw.cluster_3_clk_gate_en, - reg2hw.cluster_2_clk_gate_en, - reg2hw.cluster_1_clk_gate_en, - reg2hw.cluster_0_clk_gate_en + chimera_hwif_out.cluster_clk_gate_en[4].value.value, + chimera_hwif_out.cluster_clk_gate_en[3].value.value, + chimera_hwif_out.cluster_clk_gate_en[2].value.value, + chimera_hwif_out.cluster_clk_gate_en[1].value.value, + chimera_hwif_out.cluster_clk_gate_en[0].value.value }; logic [ExtClusters-1:0] cluster_rst_n; logic [ExtClusters-1:0] cluster_soft_rst_n; assign cluster_soft_rst_n = { - ~reg2hw.reset_cluster_4.q, - ~reg2hw.reset_cluster_3.q, - ~reg2hw.reset_cluster_2.q, - ~reg2hw.reset_cluster_1.q, - ~reg2hw.reset_cluster_0.q + ~chimera_hwif_out.reset_cluster[4].value.value, + ~chimera_hwif_out.reset_cluster[3].value.value, + ~chimera_hwif_out.reset_cluster[2].value.value, + ~chimera_hwif_out.reset_cluster[1].value.value, + ~chimera_hwif_out.reset_cluster[0].value.value }; // The Rst used for each cluster is the AND gate among all different source of rst in the system that are: @@ -373,7 +396,7 @@ module chimera_top_wrapper .rst_ni (cluster_rst_n), .clu_clk_en_i (~cluster_clock_gate_en), .widemem_bypass_i (wide_mem_bypass_mode), - .boot_addr_i (reg2hw.snitch_configurable_boot_addr.q), + .boot_addr_i (chimera_hwif_out.snitch_configurable_boot_addr.value.value), .debug_req_i (dbg_ext_req), .xeip_i (xeip_ext), .mtip_i (mtip_ext), @@ -412,9 +435,9 @@ module chimera_top_wrapper .axi_wide_rsp_o (axi_wide_mst_rsp) ); - localparam int unsigned AxiSlvIdWidth = ChsCfg.AxiMstIdWidth + $clog2(AxiIn.num_in); // Slave CDC parameters + localparam int unsigned AxiSlvIdWidth = ChsCfg.AxiMstIdWidth + $clog2(AxiIn.num_in); localparam int unsigned ChimeraAxiSlvAwWidth = (2 ** LogDepth) * axi_pkg::aw_width( ChsCfg.AddrWidth, AxiSlvIdWidth, ChsCfg.AxiUserWidth ); @@ -448,38 +471,61 @@ module chimera_top_wrapper ChsCfg.AxiDataWidth, ChsCfg.AxiMstIdWidth, ChsCfg.AxiUserWidth ); - logic [ChimeraAxiSlvArWidth-1:0] hyper_ar_data; + // LLC CDC parameters + localparam int unsigned ChimeraAxiLlcIdWidth = ChsCfg.AxiMstIdWidth + + $clog2(AxiIn.num_in)+ + ChsCfg.LlcNotBypass ; + localparam int unsigned ChimeraAxiLlcArWidth = (2**LogDepth)* + axi_pkg::ar_width(ChsCfg.AddrWidth , + ChimeraAxiLlcIdWidth , + ChsCfg.AxiUserWidth); + localparam int unsigned ChimeraAxiLlcAwWidth = (2**LogDepth)* + axi_pkg::aw_width(ChsCfg.AddrWidth , + ChimeraAxiLlcIdWidth , + ChsCfg.AxiUserWidth); + localparam int unsigned ChimeraAxiLlcBWidth = (2**LogDepth)* + axi_pkg::b_width(ChimeraAxiLlcIdWidth , + ChsCfg.AxiUserWidth); + localparam int unsigned ChimeraAxiLlcRWidth = (2**LogDepth)* + axi_pkg::r_width(ChsCfg.AxiDataWidth, + ChimeraAxiLlcIdWidth , + ChsCfg.AxiUserWidth); + localparam int unsigned ChimeraAxiLlcWWidth = (2**LogDepth)* + axi_pkg::w_width(ChsCfg.AxiDataWidth, + ChsCfg.AxiUserWidth ); + + logic [ChimeraAxiLlcArWidth-1:0] hyper_ar_data; logic [ LogDepth:0] hyper_ar_wptr; logic [ LogDepth:0] hyper_ar_rptr; - logic [ChimeraAxiSlvAwWidth-1:0] hyper_aw_data; + logic [ChimeraAxiLlcAwWidth-1:0] hyper_aw_data; logic [ LogDepth:0] hyper_aw_wptr; logic [ LogDepth:0] hyper_aw_rptr; - logic [ ChimeraAxiSlvBWidth-1:0] hyper_b_data; + logic [ ChimeraAxiLlcBWidth-1:0] hyper_b_data; logic [ LogDepth:0] hyper_b_wptr; logic [ LogDepth:0] hyper_b_rptr; - logic [ ChimeraAxiSlvRWidth-1:0] hyper_r_data; + logic [ ChimeraAxiLlcRWidth-1:0] hyper_r_data; logic [ LogDepth:0] hyper_r_wptr; logic [ LogDepth:0] hyper_r_rptr; - logic [ ChimeraAxiSlvWWidth-1:0] hyper_w_data; + logic [ ChimeraAxiLlcWWidth-1:0] hyper_w_data; logic [ LogDepth:0] hyper_w_wptr; logic [ LogDepth:0] hyper_w_rptr; axi_cdc_src #( .LogDepth (LogDepth), .SyncStages(SyncStages), - .aw_chan_t (axi_slv_aw_chan_t), - .w_chan_t (axi_slv_w_chan_t), - .b_chan_t (axi_slv_b_chan_t), - .ar_chan_t (axi_slv_ar_chan_t), - .r_chan_t (axi_slv_r_chan_t), - .axi_req_t (axi_slv_req_t), - .axi_resp_t(axi_slv_rsp_t) + .aw_chan_t (axi_llc_aw_chan_t), + .w_chan_t (axi_llc_w_chan_t), + .b_chan_t (axi_llc_b_chan_t), + .ar_chan_t (axi_llc_ar_chan_t), + .r_chan_t (axi_llc_r_chan_t), + .axi_req_t (axi_llc_req_t), + .axi_resp_t(axi_llc_rsp_t) ) hyperbus_slv_cdc_src ( // synchronous slave port .src_clk_i (soc_clk_i), .src_rst_ni (rst_ni), - .src_req_i (axi_slv_req[HyperbusIdx]), - .src_resp_o (axi_slv_rsp[HyperbusIdx]), + .src_req_i (axi_llc_req), + .src_resp_o (axi_llc_rsp), // asynchronous master port .async_data_master_aw_data_o(hyper_aw_data), .async_data_master_aw_wptr_o(hyper_aw_wptr), @@ -504,30 +550,30 @@ module chimera_top_wrapper .IsClockODelayed (1'b0), .AxiAddrWidth (ChsCfg.AddrWidth), .AxiDataWidth (ChsCfg.AxiDataWidth), - .AxiIdWidth (AxiSlvIdWidth), + .AxiIdWidth (ChimeraAxiLlcIdWidth), .AxiUserWidth (ChsCfg.AxiUserWidth), - .axi_req_t (axi_slv_req_t), - .axi_rsp_t (axi_slv_rsp_t), - .axi_w_chan_t (axi_slv_w_chan_t), - .axi_b_chan_t (axi_slv_b_chan_t), - .axi_ar_chan_t (axi_slv_ar_chan_t), - .axi_r_chan_t (axi_slv_r_chan_t), - .axi_aw_chan_t (axi_slv_aw_chan_t), + .axi_req_t (axi_llc_req_t), + .axi_rsp_t (axi_llc_rsp_t), + .axi_w_chan_t (axi_llc_w_chan_t), + .axi_b_chan_t (axi_llc_b_chan_t), + .axi_ar_chan_t (axi_llc_ar_chan_t), + .axi_r_chan_t (axi_llc_r_chan_t), + .axi_aw_chan_t (axi_llc_aw_chan_t), .RegAddrWidth (ChsCfg.AddrWidth), - .RegDataWidth (ChsCfg.AxiDataWidth), + .RegDataWidth (RegDataWidth), .reg_req_t (reg_req_t), .reg_rsp_t (reg_rsp_t), .RxFifoLogDepth (32'd2), .TxFifoLogDepth (32'd2), - .RstChipBase (ChsCfg.LlcOutRegionStart), - .RstChipSpace (HyperbusRegionEnd - HyperbusRegionStart), + .RstChipBase (HyperbusRegionStart), + .RstChipSpace (HypNumPhys * HypNumChips * 'h800_0000), .PhyStartupCycles(300 * 200), .AxiLogDepth (LogDepth), - .AxiSlaveArWidth (ChimeraAxiSlvArWidth), - .AxiSlaveAwWidth (ChimeraAxiSlvAwWidth), - .AxiSlaveBWidth (ChimeraAxiSlvBWidth), - .AxiSlaveRWidth (ChimeraAxiSlvRWidth), - .AxiSlaveWWidth (ChimeraAxiSlvWWidth), + .AxiSlaveArWidth (ChimeraAxiLlcArWidth), + .AxiSlaveAwWidth (ChimeraAxiLlcAwWidth), + .AxiSlaveBWidth (ChimeraAxiLlcBWidth), + .AxiSlaveRWidth (ChimeraAxiLlcRWidth), + .AxiSlaveWWidth (ChimeraAxiLlcWWidth), .AxiMaxTrans (ChsCfg.AxiMaxSlvTrans), .CdcSyncStages (SyncStages) ) i_hyperbus_wrap ( diff --git a/hw/clusters/chimera_cluster.sv b/hw/clusters/chimera_cluster.sv index 702bc4e3..e1f97063 100644 --- a/hw/clusters/chimera_cluster.sv +++ b/hw/clusters/chimera_cluster.sv @@ -8,6 +8,7 @@ module chimera_cluster import chimera_pkg::*; import cheshire_pkg::*; + import snitch_cluster_pkg::*; #( parameter chimera_cfg_t Cfg = '0, @@ -230,10 +231,6 @@ module chimera_cluster sram_cfg_t tcdm; } sram_cfgs_t; - localparam int unsigned NumIntOutstandingLoads[NrCores] = '{NrCores{32'h1}}; - localparam int unsigned NumIntOutstandingMem[NrCores] = '{NrCores{32'h4}}; - - // ---------------- // | TCDM INTF | // ---------------- @@ -258,63 +255,34 @@ module chimera_cluster default: 0 }; - snitch_cluster #( + + snitch_cluster_wrapper #( + // Widths, AXI/SRAM struct types and the PMA config are driven from the + // Chimera/Cheshire integration; everything else (NrCores, TCDM, ICache, FP + // config, sequencer/SSR sizing, register stages, ...) is baked into the + // generated wrapper from cfg/chimera.json (see SN_CFG in the Makefile). .PhysicalAddrWidth(Cfg.ChsCfg.AddrWidth), - .NarrowDataWidth (ClusterDataWidth), // SCHEREMO: Convolve needs this... + .NarrowDataWidth (ClusterDataWidth), .WideDataWidth (WideDataWidth), .NarrowIdWidthIn (ClusterNarrowAxiMstIdWidth), .WideIdWidthIn (WideMasterIdWidth), .NarrowUserWidth (Cfg.ChsCfg.AxiUserWidth), .WideUserWidth (Cfg.ChsCfg.AxiUserWidth), - .AliasRegionEnable(1), - .AliasRegionBase ('h1800_0000), - .SnitchPMACfg (SnitchPMACfg), - .BootAddr (SnitchBootROMRegionStart), - .IntBootromEnable (0), - - .NrHives (1), - .NrCores (NrCores), - .TCDMDepth (1024), - .ZeroMemorySize (64), - .ClusterPeriphSize(64), - .NrBanks (16), - // WIESEP: TCDM size = 16 * 1024 * 64 bit = 128 KiB - - .DMANumAxInFlight(3), - .DMAReqFifoDepth (3), - - .ICacheLineWidth('{256}), - .ICacheLineCount('{16}), - .ICacheWays ('{2}), - - .VMSupport(0), - .Xdma ({1'b1, {(NrCores - 1) {1'b0}}}), - - .NumIntOutstandingLoads(NumIntOutstandingLoads), - .NumIntOutstandingMem (NumIntOutstandingMem), - .RegisterOffloadReq (1), - .RegisterOffloadRsp (1), - .RegisterCoreReq (1), - .RegisterCoreRsp (1), - - .narrow_in_req_t (axi_cluster_in_narrow_req_t), - .narrow_in_resp_t(axi_cluster_in_narrow_resp_t), - .wide_in_req_t (axi_cluster_in_wide_req_t), - .wide_in_resp_t (axi_cluster_in_wide_resp_t), - + .narrow_in_req_t (axi_cluster_in_narrow_req_t), + .narrow_in_resp_t (axi_cluster_in_narrow_resp_t), .narrow_out_req_t (axi_cluster_out_narrow_req_t), .narrow_out_resp_t(axi_cluster_out_narrow_resp_t), .wide_out_req_t (axi_cluster_out_wide_req_t), .wide_out_resp_t (axi_cluster_out_wide_resp_t), + .wide_in_req_t (axi_cluster_in_wide_req_t), + .wide_in_resp_t (axi_cluster_in_wide_resp_t), .tcdm_dma_req_t (tcdm_dma_req_t), .tcdm_dma_rsp_t (tcdm_dma_rsp_t), + .sram_cfg_t (sram_cfg_t), + .sram_cfgs_t (sram_cfgs_t), - .sram_cfg_t (sram_cfg_t), - .sram_cfgs_t(sram_cfgs_t), - - .RegisterExtWide ('0), - .RegisterExtNarrow('0) + .SnitchPMACfg (SnitchPMACfg) ) i_test_cluster ( .clk_i (clu_clk_gated), diff --git a/hw/regs/chimera_reg_pkg.sv b/hw/regs/chimera_reg_pkg.sv index 13c33497..cabbbec9 100644 --- a/hw/regs/chimera_reg_pkg.sv +++ b/hw/regs/chimera_reg_pkg.sv @@ -1,199 +1,89 @@ -// Copyright lowRISC contributors. +// Copyright 2024 ETH Zurich and University of Bologna. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -// -// Register Package auto-generated by `reggen` containing data structure -package chimera_reg_pkg; - - // Address widths within the block - parameter int BlockAw = 7; - - //////////////////////////// - // Typedefs for registers // - //////////////////////////// - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_boot_addr_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_configurable_boot_addr_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_intr_handler_addr_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_0_return_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_1_return_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_2_return_reg_t; +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_3_return_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_4_return_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_0_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_1_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_2_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_3_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_4_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_0_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_1_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_2_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_3_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_4_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_0_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_1_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_2_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_3_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_4_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_0_busy_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_1_busy_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_2_busy_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_3_busy_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_4_busy_reg_t; - - // Register -> HW type - typedef struct packed { - chimera_reg2hw_snitch_boot_addr_reg_t snitch_boot_addr; // [275:244] - chimera_reg2hw_snitch_configurable_boot_addr_reg_t snitch_configurable_boot_addr; // [243:212] - chimera_reg2hw_snitch_intr_handler_addr_reg_t snitch_intr_handler_addr; // [211:180] - chimera_reg2hw_snitch_cluster_0_return_reg_t snitch_cluster_0_return; // [179:148] - chimera_reg2hw_snitch_cluster_1_return_reg_t snitch_cluster_1_return; // [147:116] - chimera_reg2hw_snitch_cluster_2_return_reg_t snitch_cluster_2_return; // [115:84] - chimera_reg2hw_snitch_cluster_3_return_reg_t snitch_cluster_3_return; // [83:52] - chimera_reg2hw_snitch_cluster_4_return_reg_t snitch_cluster_4_return; // [51:20] - chimera_reg2hw_reset_cluster_0_reg_t reset_cluster_0; // [19:19] - chimera_reg2hw_reset_cluster_1_reg_t reset_cluster_1; // [18:18] - chimera_reg2hw_reset_cluster_2_reg_t reset_cluster_2; // [17:17] - chimera_reg2hw_reset_cluster_3_reg_t reset_cluster_3; // [16:16] - chimera_reg2hw_reset_cluster_4_reg_t reset_cluster_4; // [15:15] - chimera_reg2hw_cluster_0_clk_gate_en_reg_t cluster_0_clk_gate_en; // [14:14] - chimera_reg2hw_cluster_1_clk_gate_en_reg_t cluster_1_clk_gate_en; // [13:13] - chimera_reg2hw_cluster_2_clk_gate_en_reg_t cluster_2_clk_gate_en; // [12:12] - chimera_reg2hw_cluster_3_clk_gate_en_reg_t cluster_3_clk_gate_en; // [11:11] - chimera_reg2hw_cluster_4_clk_gate_en_reg_t cluster_4_clk_gate_en; // [10:10] - chimera_reg2hw_wide_mem_cluster_0_bypass_reg_t wide_mem_cluster_0_bypass; // [9:9] - chimera_reg2hw_wide_mem_cluster_1_bypass_reg_t wide_mem_cluster_1_bypass; // [8:8] - chimera_reg2hw_wide_mem_cluster_2_bypass_reg_t wide_mem_cluster_2_bypass; // [7:7] - chimera_reg2hw_wide_mem_cluster_3_bypass_reg_t wide_mem_cluster_3_bypass; // [6:6] - chimera_reg2hw_wide_mem_cluster_4_bypass_reg_t wide_mem_cluster_4_bypass; // [5:5] - chimera_reg2hw_cluster_0_busy_reg_t cluster_0_busy; // [4:4] - chimera_reg2hw_cluster_1_busy_reg_t cluster_1_busy; // [3:3] - chimera_reg2hw_cluster_2_busy_reg_t cluster_2_busy; // [2:2] - chimera_reg2hw_cluster_3_busy_reg_t cluster_3_busy; // [1:1] - chimera_reg2hw_cluster_4_busy_reg_t cluster_4_busy; // [0:0] - } chimera_reg2hw_t; - - // Register offsets - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_BOOT_ADDR_OFFSET = 7'h0; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR_OFFSET = 7'h4; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_INTR_HANDLER_ADDR_OFFSET = 7'h8; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_0_RETURN_OFFSET = 7'hc; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_1_RETURN_OFFSET = 7'h10; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_2_RETURN_OFFSET = 7'h14; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_3_RETURN_OFFSET = 7'h18; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_4_RETURN_OFFSET = 7'h1c; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_0_OFFSET = 7'h20; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_1_OFFSET = 7'h24; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_2_OFFSET = 7'h28; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_3_OFFSET = 7'h2c; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_4_OFFSET = 7'h30; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_0_CLK_GATE_EN_OFFSET = 7'h34; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_1_CLK_GATE_EN_OFFSET = 7'h38; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_2_CLK_GATE_EN_OFFSET = 7'h3c; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_3_CLK_GATE_EN_OFFSET = 7'h40; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_4_CLK_GATE_EN_OFFSET = 7'h44; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_OFFSET = 7'h48; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_OFFSET = 7'h4c; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_OFFSET = 7'h50; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_OFFSET = 7'h54; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_OFFSET = 7'h58; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_0_BUSY_OFFSET = 7'h5c; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_1_BUSY_OFFSET = 7'h60; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_2_BUSY_OFFSET = 7'h64; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_3_BUSY_OFFSET = 7'h68; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_4_BUSY_OFFSET = 7'h6c; - - // Register index - typedef enum int { - CHIMERA_SNITCH_BOOT_ADDR, - CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR, - CHIMERA_SNITCH_INTR_HANDLER_ADDR, - CHIMERA_SNITCH_CLUSTER_0_RETURN, - CHIMERA_SNITCH_CLUSTER_1_RETURN, - CHIMERA_SNITCH_CLUSTER_2_RETURN, - CHIMERA_SNITCH_CLUSTER_3_RETURN, - CHIMERA_SNITCH_CLUSTER_4_RETURN, - CHIMERA_RESET_CLUSTER_0, - CHIMERA_RESET_CLUSTER_1, - CHIMERA_RESET_CLUSTER_2, - CHIMERA_RESET_CLUSTER_3, - CHIMERA_RESET_CLUSTER_4, - CHIMERA_CLUSTER_0_CLK_GATE_EN, - CHIMERA_CLUSTER_1_CLK_GATE_EN, - CHIMERA_CLUSTER_2_CLK_GATE_EN, - CHIMERA_CLUSTER_3_CLK_GATE_EN, - CHIMERA_CLUSTER_4_CLK_GATE_EN, - CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS, - CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS, - CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS, - CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS, - CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS, - CHIMERA_CLUSTER_0_BUSY, - CHIMERA_CLUSTER_1_BUSY, - CHIMERA_CLUSTER_2_BUSY, - CHIMERA_CLUSTER_3_BUSY, - CHIMERA_CLUSTER_4_BUSY - } chimera_id_e; - - // Register width information to check illegal writes - parameter logic [3:0] CHIMERA_PERMIT[28] = '{ - 4'b1111, // index[ 0] CHIMERA_SNITCH_BOOT_ADDR - 4'b1111, // index[ 1] CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR - 4'b1111, // index[ 2] CHIMERA_SNITCH_INTR_HANDLER_ADDR - 4'b1111, // index[ 3] CHIMERA_SNITCH_CLUSTER_0_RETURN - 4'b1111, // index[ 4] CHIMERA_SNITCH_CLUSTER_1_RETURN - 4'b1111, // index[ 5] CHIMERA_SNITCH_CLUSTER_2_RETURN - 4'b1111, // index[ 6] CHIMERA_SNITCH_CLUSTER_3_RETURN - 4'b1111, // index[ 7] CHIMERA_SNITCH_CLUSTER_4_RETURN - 4'b0001, // index[ 8] CHIMERA_RESET_CLUSTER_0 - 4'b0001, // index[ 9] CHIMERA_RESET_CLUSTER_1 - 4'b0001, // index[10] CHIMERA_RESET_CLUSTER_2 - 4'b0001, // index[11] CHIMERA_RESET_CLUSTER_3 - 4'b0001, // index[12] CHIMERA_RESET_CLUSTER_4 - 4'b0001, // index[13] CHIMERA_CLUSTER_0_CLK_GATE_EN - 4'b0001, // index[14] CHIMERA_CLUSTER_1_CLK_GATE_EN - 4'b0001, // index[15] CHIMERA_CLUSTER_2_CLK_GATE_EN - 4'b0001, // index[16] CHIMERA_CLUSTER_3_CLK_GATE_EN - 4'b0001, // index[17] CHIMERA_CLUSTER_4_CLK_GATE_EN - 4'b0001, // index[18] CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS - 4'b0001, // index[19] CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS - 4'b0001, // index[20] CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS - 4'b0001, // index[21] CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS - 4'b0001, // index[22] CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS - 4'b0001, // index[23] CHIMERA_CLUSTER_0_BUSY - 4'b0001, // index[24] CHIMERA_CLUSTER_1_BUSY - 4'b0001, // index[25] CHIMERA_CLUSTER_2_BUSY - 4'b0001, // index[26] CHIMERA_CLUSTER_3_BUSY - 4'b0001 // index[27] CHIMERA_CLUSTER_4_BUSY - }; +package chimera_reg_pkg; + localparam CHIMERA_REG_TOP_DATA_WIDTH = 32; + localparam CHIMERA_REG_TOP_MIN_ADDR_WIDTH = 7; + localparam CHIMERA_REG_TOP_SIZE = 'h70; + localparam NrClusters = 'h5; + + typedef struct { + logic [31:0] value; + } chimera_soc_regs__snitch_boot_addr__value__out_t; + + typedef struct { + chimera_soc_regs__snitch_boot_addr__value__out_t value; + } chimera_soc_regs__snitch_boot_addr__out_t; + + typedef struct { + logic [31:0] value; + } chimera_soc_regs__snitch_configurable_boot_addr__value__out_t; + + typedef struct { + chimera_soc_regs__snitch_configurable_boot_addr__value__out_t value; + } chimera_soc_regs__snitch_configurable_boot_addr__out_t; + + typedef struct { + logic [31:0] value; + } chimera_soc_regs__snitch_intr_handler_addr__value__out_t; + + typedef struct { + chimera_soc_regs__snitch_intr_handler_addr__value__out_t value; + } chimera_soc_regs__snitch_intr_handler_addr__out_t; + + typedef struct { + logic [31:0] value; + } chimera_soc_regs__snitch_cluster_return_t__value__out_t; + + typedef struct { + chimera_soc_regs__snitch_cluster_return_t__value__out_t value; + } chimera_soc_regs__snitch_cluster_return_t__out_t; + + typedef struct { + logic value; + } chimera_soc_regs__reset_cluster_t__value__out_t; + + typedef struct { + chimera_soc_regs__reset_cluster_t__value__out_t value; + } chimera_soc_regs__reset_cluster_t__out_t; + + typedef struct { + logic value; + } chimera_soc_regs__cluster_clk_gate_en_t__value__out_t; + + typedef struct { + chimera_soc_regs__cluster_clk_gate_en_t__value__out_t value; + } chimera_soc_regs__cluster_clk_gate_en_t__out_t; + + typedef struct { + logic value; + } chimera_soc_regs__wide_mem_cluster_bypass_t__value__out_t; + + typedef struct { + chimera_soc_regs__wide_mem_cluster_bypass_t__value__out_t value; + } chimera_soc_regs__wide_mem_cluster_bypass_t__out_t; + + typedef struct { + logic value; + } chimera_soc_regs__cluster_busy_t__value__out_t; + + typedef struct { + chimera_soc_regs__cluster_busy_t__value__out_t value; + } chimera_soc_regs__cluster_busy_t__out_t; + + typedef struct { + chimera_soc_regs__snitch_boot_addr__out_t snitch_boot_addr; + chimera_soc_regs__snitch_configurable_boot_addr__out_t snitch_configurable_boot_addr; + chimera_soc_regs__snitch_intr_handler_addr__out_t snitch_intr_handler_addr; + chimera_soc_regs__snitch_cluster_return_t__out_t snitch_cluster_return[5]; + chimera_soc_regs__reset_cluster_t__out_t reset_cluster[5]; + chimera_soc_regs__cluster_clk_gate_en_t__out_t cluster_clk_gate_en[5]; + chimera_soc_regs__wide_mem_cluster_bypass_t__out_t wide_mem_cluster_bypass[5]; + chimera_soc_regs__cluster_busy_t__out_t cluster_busy[5]; + } chimera_soc_regs__out_t; endpackage - diff --git a/hw/regs/chimera_reg_top.sv b/hw/regs/chimera_reg_top.sv index d6d5033b..d2862aa2 100644 --- a/hw/regs/chimera_reg_top.sv +++ b/hw/regs/chimera_reg_top.sv @@ -1,1249 +1,499 @@ -// Copyright lowRISC contributors. +// Copyright 2024 ETH Zurich and University of Bologna. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -// -// Register Top module auto-generated by `reggen` - - -`include "common_cells/assertions.svh" - -module chimera_reg_top #( - parameter type reg_req_t = logic, - parameter type reg_rsp_t = logic, - parameter int AW = 7 -) ( - input logic clk_i, - input logic rst_ni, - input reg_req_t reg_req_i, - output reg_rsp_t reg_rsp_o, - // To HW - output chimera_reg_pkg::chimera_reg2hw_t reg2hw, // Write - - - // Config - input devmode_i // If 1, explicit error return for unmapped register access -); - - import chimera_reg_pkg::*; - - localparam int DW = 32; - localparam int DBW = DW / 8; // Byte Width - - // register signals - logic reg_we; - logic reg_re; - logic [BlockAw-1:0] reg_addr; - logic [ DW-1:0] reg_wdata; - logic [ DBW-1:0] reg_be; - logic [ DW-1:0] reg_rdata; - logic reg_error; - - logic addrmiss, wr_err; - - logic [DW-1:0] reg_rdata_next; - - // Below register interface can be changed - reg_req_t reg_intf_req; - reg_rsp_t reg_intf_rsp; - - - assign reg_intf_req = reg_req_i; - assign reg_rsp_o = reg_intf_rsp; - - - assign reg_we = reg_intf_req.valid & reg_intf_req.write; - assign reg_re = reg_intf_req.valid & ~reg_intf_req.write; - assign reg_addr = reg_intf_req.addr[BlockAw-1:0]; - assign reg_wdata = reg_intf_req.wdata; - assign reg_be = reg_intf_req.wstrb; - assign reg_intf_rsp.rdata = reg_rdata; - assign reg_intf_rsp.error = reg_error; - assign reg_intf_rsp.ready = 1'b1; - - assign reg_rdata = reg_rdata_next; - assign reg_error = (devmode_i & addrmiss) | wr_err; - - - // Define SW related signals - // Format: __{wd|we|qs} - // or _{wd|we|qs} if field == 1 or 0 - logic [31:0] snitch_boot_addr_qs; - logic [31:0] snitch_boot_addr_wd; - logic snitch_boot_addr_we; - logic [31:0] snitch_configurable_boot_addr_qs; - logic [31:0] snitch_configurable_boot_addr_wd; - logic snitch_configurable_boot_addr_we; - logic [31:0] snitch_intr_handler_addr_qs; - logic [31:0] snitch_intr_handler_addr_wd; - logic snitch_intr_handler_addr_we; - logic [31:0] snitch_cluster_0_return_qs; - logic [31:0] snitch_cluster_0_return_wd; - logic snitch_cluster_0_return_we; - logic [31:0] snitch_cluster_1_return_qs; - logic [31:0] snitch_cluster_1_return_wd; - logic snitch_cluster_1_return_we; - logic [31:0] snitch_cluster_2_return_qs; - logic [31:0] snitch_cluster_2_return_wd; - logic snitch_cluster_2_return_we; - logic [31:0] snitch_cluster_3_return_qs; - logic [31:0] snitch_cluster_3_return_wd; - logic snitch_cluster_3_return_we; - logic [31:0] snitch_cluster_4_return_qs; - logic [31:0] snitch_cluster_4_return_wd; - logic snitch_cluster_4_return_we; - logic reset_cluster_0_qs; - logic reset_cluster_0_wd; - logic reset_cluster_0_we; - logic reset_cluster_1_qs; - logic reset_cluster_1_wd; - logic reset_cluster_1_we; - logic reset_cluster_2_qs; - logic reset_cluster_2_wd; - logic reset_cluster_2_we; - logic reset_cluster_3_qs; - logic reset_cluster_3_wd; - logic reset_cluster_3_we; - logic reset_cluster_4_qs; - logic reset_cluster_4_wd; - logic reset_cluster_4_we; - logic cluster_0_clk_gate_en_qs; - logic cluster_0_clk_gate_en_wd; - logic cluster_0_clk_gate_en_we; - logic cluster_1_clk_gate_en_qs; - logic cluster_1_clk_gate_en_wd; - logic cluster_1_clk_gate_en_we; - logic cluster_2_clk_gate_en_qs; - logic cluster_2_clk_gate_en_wd; - logic cluster_2_clk_gate_en_we; - logic cluster_3_clk_gate_en_qs; - logic cluster_3_clk_gate_en_wd; - logic cluster_3_clk_gate_en_we; - logic cluster_4_clk_gate_en_qs; - logic cluster_4_clk_gate_en_wd; - logic cluster_4_clk_gate_en_we; - logic wide_mem_cluster_0_bypass_qs; - logic wide_mem_cluster_0_bypass_wd; - logic wide_mem_cluster_0_bypass_we; - logic wide_mem_cluster_1_bypass_qs; - logic wide_mem_cluster_1_bypass_wd; - logic wide_mem_cluster_1_bypass_we; - logic wide_mem_cluster_2_bypass_qs; - logic wide_mem_cluster_2_bypass_wd; - logic wide_mem_cluster_2_bypass_we; - logic wide_mem_cluster_3_bypass_qs; - logic wide_mem_cluster_3_bypass_wd; - logic wide_mem_cluster_3_bypass_we; - logic wide_mem_cluster_4_bypass_qs; - logic wide_mem_cluster_4_bypass_wd; - logic wide_mem_cluster_4_bypass_we; - logic cluster_0_busy_qs; - logic cluster_0_busy_wd; - logic cluster_0_busy_we; - logic cluster_1_busy_qs; - logic cluster_1_busy_wd; - logic cluster_1_busy_we; - logic cluster_2_busy_qs; - logic cluster_2_busy_wd; - logic cluster_2_busy_we; - logic cluster_3_busy_qs; - logic cluster_3_busy_wd; - logic cluster_3_busy_we; - logic cluster_4_busy_qs; - logic cluster_4_busy_wd; - logic cluster_4_busy_we; - - // Register instances - // R[snitch_boot_addr]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'hbadcab1e) - ) u_snitch_boot_addr ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_boot_addr_we), - .wd(snitch_boot_addr_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_boot_addr.q), - - // to register interface (read) - .qs(snitch_boot_addr_qs) - ); - - - // R[snitch_configurable_boot_addr]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h30000000) - ) u_snitch_configurable_boot_addr ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_configurable_boot_addr_we), - .wd(snitch_configurable_boot_addr_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_configurable_boot_addr.q), - - // to register interface (read) - .qs(snitch_configurable_boot_addr_qs) - ); - - - // R[snitch_intr_handler_addr]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'hbadcab1e) - ) u_snitch_intr_handler_addr ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_intr_handler_addr_we), - .wd(snitch_intr_handler_addr_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_intr_handler_addr.q), - - // to register interface (read) - .qs(snitch_intr_handler_addr_qs) - ); - - - // R[snitch_cluster_0_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_0_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_0_return_we), - .wd(snitch_cluster_0_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_0_return.q), - - // to register interface (read) - .qs(snitch_cluster_0_return_qs) - ); - - - // R[snitch_cluster_1_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_1_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_1_return_we), - .wd(snitch_cluster_1_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_1_return.q), - - // to register interface (read) - .qs(snitch_cluster_1_return_qs) - ); - - - // R[snitch_cluster_2_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_2_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_2_return_we), - .wd(snitch_cluster_2_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_2_return.q), - - // to register interface (read) - .qs(snitch_cluster_2_return_qs) - ); - - - // R[snitch_cluster_3_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_3_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_3_return_we), - .wd(snitch_cluster_3_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_3_return.q), - - // to register interface (read) - .qs(snitch_cluster_3_return_qs) - ); - - - // R[snitch_cluster_4_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_4_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_4_return_we), - .wd(snitch_cluster_4_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_4_return.q), - - // to register interface (read) - .qs(snitch_cluster_4_return_qs) - ); - - - // R[reset_cluster_0]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_0 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_0_we), - .wd(reset_cluster_0_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_0.q), - - // to register interface (read) - .qs(reset_cluster_0_qs) - ); - - - // R[reset_cluster_1]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_1 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_1_we), - .wd(reset_cluster_1_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_1.q), - - // to register interface (read) - .qs(reset_cluster_1_qs) - ); - - - // R[reset_cluster_2]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_2 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_2_we), - .wd(reset_cluster_2_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_2.q), - - // to register interface (read) - .qs(reset_cluster_2_qs) - ); - - - // R[reset_cluster_3]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_3 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_3_we), - .wd(reset_cluster_3_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_3.q), - - // to register interface (read) - .qs(reset_cluster_3_qs) - ); - - - // R[reset_cluster_4]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_4 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_4_we), - .wd(reset_cluster_4_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_4.q), - - // to register interface (read) - .qs(reset_cluster_4_qs) - ); - - - // R[cluster_0_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_0_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_0_clk_gate_en_we), - .wd(cluster_0_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_0_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_0_clk_gate_en_qs) - ); - - - // R[cluster_1_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_1_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_1_clk_gate_en_we), - .wd(cluster_1_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_1_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_1_clk_gate_en_qs) - ); - - - // R[cluster_2_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_2_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_2_clk_gate_en_we), - .wd(cluster_2_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_2_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_2_clk_gate_en_qs) - ); - - - // R[cluster_3_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_3_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_3_clk_gate_en_we), - .wd(cluster_3_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_3_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_3_clk_gate_en_qs) - ); - - - // R[cluster_4_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_4_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_4_clk_gate_en_we), - .wd(cluster_4_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_4_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_4_clk_gate_en_qs) - ); - - - // R[wide_mem_cluster_0_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_0_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_0_bypass_we), - .wd(wide_mem_cluster_0_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_0_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_0_bypass_qs) - ); - - - // R[wide_mem_cluster_1_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_1_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_1_bypass_we), - .wd(wide_mem_cluster_1_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_1_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_1_bypass_qs) - ); - - - // R[wide_mem_cluster_2_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_2_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_2_bypass_we), - .wd(wide_mem_cluster_2_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_2_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_2_bypass_qs) - ); - - - // R[wide_mem_cluster_3_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_3_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_3_bypass_we), - .wd(wide_mem_cluster_3_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_3_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_3_bypass_qs) - ); - - - // R[wide_mem_cluster_4_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_4_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_4_bypass_we), - .wd(wide_mem_cluster_4_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_4_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_4_bypass_qs) - ); - - - // R[cluster_0_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_0_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_0_busy_we), - .wd(cluster_0_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_0_busy.q), - - // to register interface (read) - .qs(cluster_0_busy_qs) - ); - - - // R[cluster_1_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_1_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_1_busy_we), - .wd(cluster_1_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_1_busy.q), - - // to register interface (read) - .qs(cluster_1_busy_qs) - ); - - - // R[cluster_2_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_2_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_2_busy_we), - .wd(cluster_2_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_2_busy.q), - - // to register interface (read) - .qs(cluster_2_busy_qs) - ); - - - // R[cluster_3_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_3_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_3_busy_we), - .wd(cluster_3_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_3_busy.q), - - // to register interface (read) - .qs(cluster_3_busy_qs) - ); - - - // R[cluster_4_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_4_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_4_busy_we), - .wd(cluster_4_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_4_busy.q), - - // to register interface (read) - .qs(cluster_4_busy_qs) - ); - - - - - logic [27:0] addr_hit; - always_comb begin - addr_hit = '0; - addr_hit[0] = (reg_addr == CHIMERA_SNITCH_BOOT_ADDR_OFFSET); - addr_hit[1] = (reg_addr == CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR_OFFSET); - addr_hit[2] = (reg_addr == CHIMERA_SNITCH_INTR_HANDLER_ADDR_OFFSET); - addr_hit[3] = (reg_addr == CHIMERA_SNITCH_CLUSTER_0_RETURN_OFFSET); - addr_hit[4] = (reg_addr == CHIMERA_SNITCH_CLUSTER_1_RETURN_OFFSET); - addr_hit[5] = (reg_addr == CHIMERA_SNITCH_CLUSTER_2_RETURN_OFFSET); - addr_hit[6] = (reg_addr == CHIMERA_SNITCH_CLUSTER_3_RETURN_OFFSET); - addr_hit[7] = (reg_addr == CHIMERA_SNITCH_CLUSTER_4_RETURN_OFFSET); - addr_hit[8] = (reg_addr == CHIMERA_RESET_CLUSTER_0_OFFSET); - addr_hit[9] = (reg_addr == CHIMERA_RESET_CLUSTER_1_OFFSET); - addr_hit[10] = (reg_addr == CHIMERA_RESET_CLUSTER_2_OFFSET); - addr_hit[11] = (reg_addr == CHIMERA_RESET_CLUSTER_3_OFFSET); - addr_hit[12] = (reg_addr == CHIMERA_RESET_CLUSTER_4_OFFSET); - addr_hit[13] = (reg_addr == CHIMERA_CLUSTER_0_CLK_GATE_EN_OFFSET); - addr_hit[14] = (reg_addr == CHIMERA_CLUSTER_1_CLK_GATE_EN_OFFSET); - addr_hit[15] = (reg_addr == CHIMERA_CLUSTER_2_CLK_GATE_EN_OFFSET); - addr_hit[16] = (reg_addr == CHIMERA_CLUSTER_3_CLK_GATE_EN_OFFSET); - addr_hit[17] = (reg_addr == CHIMERA_CLUSTER_4_CLK_GATE_EN_OFFSET); - addr_hit[18] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_OFFSET); - addr_hit[19] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_OFFSET); - addr_hit[20] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_OFFSET); - addr_hit[21] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_OFFSET); - addr_hit[22] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_OFFSET); - addr_hit[23] = (reg_addr == CHIMERA_CLUSTER_0_BUSY_OFFSET); - addr_hit[24] = (reg_addr == CHIMERA_CLUSTER_1_BUSY_OFFSET); - addr_hit[25] = (reg_addr == CHIMERA_CLUSTER_2_BUSY_OFFSET); - addr_hit[26] = (reg_addr == CHIMERA_CLUSTER_3_BUSY_OFFSET); - addr_hit[27] = (reg_addr == CHIMERA_CLUSTER_4_BUSY_OFFSET); - end - - assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0; - - // Check sub-word write is permitted - always_comb begin - wr_err = (reg_we & - ((addr_hit[ 0] & (|(CHIMERA_PERMIT[ 0] & ~reg_be))) | - (addr_hit[ 1] & (|(CHIMERA_PERMIT[ 1] & ~reg_be))) | - (addr_hit[ 2] & (|(CHIMERA_PERMIT[ 2] & ~reg_be))) | - (addr_hit[ 3] & (|(CHIMERA_PERMIT[ 3] & ~reg_be))) | - (addr_hit[ 4] & (|(CHIMERA_PERMIT[ 4] & ~reg_be))) | - (addr_hit[ 5] & (|(CHIMERA_PERMIT[ 5] & ~reg_be))) | - (addr_hit[ 6] & (|(CHIMERA_PERMIT[ 6] & ~reg_be))) | - (addr_hit[ 7] & (|(CHIMERA_PERMIT[ 7] & ~reg_be))) | - (addr_hit[ 8] & (|(CHIMERA_PERMIT[ 8] & ~reg_be))) | - (addr_hit[ 9] & (|(CHIMERA_PERMIT[ 9] & ~reg_be))) | - (addr_hit[10] & (|(CHIMERA_PERMIT[10] & ~reg_be))) | - (addr_hit[11] & (|(CHIMERA_PERMIT[11] & ~reg_be))) | - (addr_hit[12] & (|(CHIMERA_PERMIT[12] & ~reg_be))) | - (addr_hit[13] & (|(CHIMERA_PERMIT[13] & ~reg_be))) | - (addr_hit[14] & (|(CHIMERA_PERMIT[14] & ~reg_be))) | - (addr_hit[15] & (|(CHIMERA_PERMIT[15] & ~reg_be))) | - (addr_hit[16] & (|(CHIMERA_PERMIT[16] & ~reg_be))) | - (addr_hit[17] & (|(CHIMERA_PERMIT[17] & ~reg_be))) | - (addr_hit[18] & (|(CHIMERA_PERMIT[18] & ~reg_be))) | - (addr_hit[19] & (|(CHIMERA_PERMIT[19] & ~reg_be))) | - (addr_hit[20] & (|(CHIMERA_PERMIT[20] & ~reg_be))) | - (addr_hit[21] & (|(CHIMERA_PERMIT[21] & ~reg_be))) | - (addr_hit[22] & (|(CHIMERA_PERMIT[22] & ~reg_be))) | - (addr_hit[23] & (|(CHIMERA_PERMIT[23] & ~reg_be))) | - (addr_hit[24] & (|(CHIMERA_PERMIT[24] & ~reg_be))) | - (addr_hit[25] & (|(CHIMERA_PERMIT[25] & ~reg_be))) | - (addr_hit[26] & (|(CHIMERA_PERMIT[26] & ~reg_be))) | - (addr_hit[27] & (|(CHIMERA_PERMIT[27] & ~reg_be))))); - end - - assign snitch_boot_addr_we = addr_hit[0] & reg_we & !reg_error; - assign snitch_boot_addr_wd = reg_wdata[31:0]; - - assign snitch_configurable_boot_addr_we = addr_hit[1] & reg_we & !reg_error; - assign snitch_configurable_boot_addr_wd = reg_wdata[31:0]; - - assign snitch_intr_handler_addr_we = addr_hit[2] & reg_we & !reg_error; - assign snitch_intr_handler_addr_wd = reg_wdata[31:0]; - - assign snitch_cluster_0_return_we = addr_hit[3] & reg_we & !reg_error; - assign snitch_cluster_0_return_wd = reg_wdata[31:0]; - - assign snitch_cluster_1_return_we = addr_hit[4] & reg_we & !reg_error; - assign snitch_cluster_1_return_wd = reg_wdata[31:0]; - - assign snitch_cluster_2_return_we = addr_hit[5] & reg_we & !reg_error; - assign snitch_cluster_2_return_wd = reg_wdata[31:0]; - - assign snitch_cluster_3_return_we = addr_hit[6] & reg_we & !reg_error; - assign snitch_cluster_3_return_wd = reg_wdata[31:0]; - - assign snitch_cluster_4_return_we = addr_hit[7] & reg_we & !reg_error; - assign snitch_cluster_4_return_wd = reg_wdata[31:0]; - - assign reset_cluster_0_we = addr_hit[8] & reg_we & !reg_error; - assign reset_cluster_0_wd = reg_wdata[0]; - - assign reset_cluster_1_we = addr_hit[9] & reg_we & !reg_error; - assign reset_cluster_1_wd = reg_wdata[0]; - - assign reset_cluster_2_we = addr_hit[10] & reg_we & !reg_error; - assign reset_cluster_2_wd = reg_wdata[0]; - - assign reset_cluster_3_we = addr_hit[11] & reg_we & !reg_error; - assign reset_cluster_3_wd = reg_wdata[0]; - - assign reset_cluster_4_we = addr_hit[12] & reg_we & !reg_error; - assign reset_cluster_4_wd = reg_wdata[0]; - - assign cluster_0_clk_gate_en_we = addr_hit[13] & reg_we & !reg_error; - assign cluster_0_clk_gate_en_wd = reg_wdata[0]; - - assign cluster_1_clk_gate_en_we = addr_hit[14] & reg_we & !reg_error; - assign cluster_1_clk_gate_en_wd = reg_wdata[0]; - - assign cluster_2_clk_gate_en_we = addr_hit[15] & reg_we & !reg_error; - assign cluster_2_clk_gate_en_wd = reg_wdata[0]; - - assign cluster_3_clk_gate_en_we = addr_hit[16] & reg_we & !reg_error; - assign cluster_3_clk_gate_en_wd = reg_wdata[0]; - - assign cluster_4_clk_gate_en_we = addr_hit[17] & reg_we & !reg_error; - assign cluster_4_clk_gate_en_wd = reg_wdata[0]; - - assign wide_mem_cluster_0_bypass_we = addr_hit[18] & reg_we & !reg_error; - assign wide_mem_cluster_0_bypass_wd = reg_wdata[0]; - - assign wide_mem_cluster_1_bypass_we = addr_hit[19] & reg_we & !reg_error; - assign wide_mem_cluster_1_bypass_wd = reg_wdata[0]; - - assign wide_mem_cluster_2_bypass_we = addr_hit[20] & reg_we & !reg_error; - assign wide_mem_cluster_2_bypass_wd = reg_wdata[0]; - - assign wide_mem_cluster_3_bypass_we = addr_hit[21] & reg_we & !reg_error; - assign wide_mem_cluster_3_bypass_wd = reg_wdata[0]; - - assign wide_mem_cluster_4_bypass_we = addr_hit[22] & reg_we & !reg_error; - assign wide_mem_cluster_4_bypass_wd = reg_wdata[0]; - - assign cluster_0_busy_we = addr_hit[23] & reg_we & !reg_error; - assign cluster_0_busy_wd = reg_wdata[0]; - - assign cluster_1_busy_we = addr_hit[24] & reg_we & !reg_error; - assign cluster_1_busy_wd = reg_wdata[0]; - - assign cluster_2_busy_we = addr_hit[25] & reg_we & !reg_error; - assign cluster_2_busy_wd = reg_wdata[0]; - - assign cluster_3_busy_we = addr_hit[26] & reg_we & !reg_error; - assign cluster_3_busy_wd = reg_wdata[0]; - - assign cluster_4_busy_we = addr_hit[27] & reg_we & !reg_error; - assign cluster_4_busy_wd = reg_wdata[0]; - - // Read data return - always_comb begin - reg_rdata_next = '0; - unique case (1'b1) - addr_hit[0]: begin - reg_rdata_next[31:0] = snitch_boot_addr_qs; - end - - addr_hit[1]: begin - reg_rdata_next[31:0] = snitch_configurable_boot_addr_qs; - end - - addr_hit[2]: begin - reg_rdata_next[31:0] = snitch_intr_handler_addr_qs; - end - - addr_hit[3]: begin - reg_rdata_next[31:0] = snitch_cluster_0_return_qs; - end - - addr_hit[4]: begin - reg_rdata_next[31:0] = snitch_cluster_1_return_qs; - end - - addr_hit[5]: begin - reg_rdata_next[31:0] = snitch_cluster_2_return_qs; - end - - addr_hit[6]: begin - reg_rdata_next[31:0] = snitch_cluster_3_return_qs; - end - - addr_hit[7]: begin - reg_rdata_next[31:0] = snitch_cluster_4_return_qs; - end - - addr_hit[8]: begin - reg_rdata_next[0] = reset_cluster_0_qs; - end - - addr_hit[9]: begin - reg_rdata_next[0] = reset_cluster_1_qs; - end - - addr_hit[10]: begin - reg_rdata_next[0] = reset_cluster_2_qs; - end - - addr_hit[11]: begin - reg_rdata_next[0] = reset_cluster_3_qs; - end - - addr_hit[12]: begin - reg_rdata_next[0] = reset_cluster_4_qs; - end - - addr_hit[13]: begin - reg_rdata_next[0] = cluster_0_clk_gate_en_qs; - end - - addr_hit[14]: begin - reg_rdata_next[0] = cluster_1_clk_gate_en_qs; - end - - addr_hit[15]: begin - reg_rdata_next[0] = cluster_2_clk_gate_en_qs; - end - - addr_hit[16]: begin - reg_rdata_next[0] = cluster_3_clk_gate_en_qs; - end - - addr_hit[17]: begin - reg_rdata_next[0] = cluster_4_clk_gate_en_qs; - end - - addr_hit[18]: begin - reg_rdata_next[0] = wide_mem_cluster_0_bypass_qs; - end - - addr_hit[19]: begin - reg_rdata_next[0] = wide_mem_cluster_1_bypass_qs; - end - - addr_hit[20]: begin - reg_rdata_next[0] = wide_mem_cluster_2_bypass_qs; - end - - addr_hit[21]: begin - reg_rdata_next[0] = wide_mem_cluster_3_bypass_qs; - end - - addr_hit[22]: begin - reg_rdata_next[0] = wide_mem_cluster_4_bypass_qs; - end - - addr_hit[23]: begin - reg_rdata_next[0] = cluster_0_busy_qs; - end - - addr_hit[24]: begin - reg_rdata_next[0] = cluster_1_busy_qs; - end - - addr_hit[25]: begin - reg_rdata_next[0] = cluster_2_busy_qs; - end - - addr_hit[26]: begin - reg_rdata_next[0] = cluster_3_busy_qs; - end - - addr_hit[27]: begin - reg_rdata_next[0] = cluster_4_busy_qs; - end - - default: begin - reg_rdata_next = '1; - end - endcase - end - - // Unused signal tieoff - - // wdata / byte enable are not always fully used - // add a blanket unused statement to handle lint waivers - logic unused_wdata; - logic unused_be; - assign unused_wdata = ^reg_wdata; - assign unused_be = ^reg_be; - - // Assertions for Register Interface - `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit)) - -endmodule - -module chimera_reg_top_intf #( - parameter int AW = 7, - localparam int DW = 32 -) ( - input logic clk_i, - input logic rst_ni, - REG_BUS.in regbus_slave, - // To HW - output chimera_reg_pkg::chimera_reg2hw_t reg2hw, // Write - // Config - input devmode_i // If 1, explicit error return for unmapped register access -); - localparam int unsigned STRB_WIDTH = DW / 8; - - `include "register_interface/typedef.svh" - `include "register_interface/assign.svh" - - // Define structs for reg_bus - typedef logic [AW-1:0] addr_t; - typedef logic [DW-1:0] data_t; - typedef logic [STRB_WIDTH-1:0] strb_t; - `REG_BUS_TYPEDEF_ALL(reg_bus, addr_t, data_t, strb_t) - - reg_bus_req_t s_reg_req; - reg_bus_rsp_t s_reg_rsp; - - // Assign SV interface to structs - `REG_BUS_ASSIGN_TO_REQ(s_reg_req, regbus_slave) - `REG_BUS_ASSIGN_FROM_RSP(regbus_slave, s_reg_rsp) - - - - chimera_reg_top #( - .reg_req_t(reg_bus_req_t), - .reg_rsp_t(reg_bus_rsp_t), - .AW (AW) - ) i_regs ( - .clk_i, - .rst_ni, - .reg_req_i(s_reg_req), - .reg_rsp_o(s_reg_rsp), - .reg2hw, // Write - .devmode_i - ); +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module chimera_reg_top ( + input wire clk, + input wire arst_n, + + input wire s_apb_psel, + input wire s_apb_penable, + input wire s_apb_pwrite, + input wire [2:0] s_apb_pprot, + input wire [6:0] s_apb_paddr, + input wire [31:0] s_apb_pwdata, + input wire [3:0] s_apb_pstrb, + output logic s_apb_pready, + output logic [31:0] s_apb_prdata, + output logic s_apb_pslverr, + + output chimera_reg_pkg::chimera_soc_regs__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [6:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + // Request + logic is_active; + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + is_active <= '0; + cpuif_req <= '0; + cpuif_req_is_wr <= '0; + cpuif_addr <= '0; + cpuif_wr_data <= '0; + cpuif_wr_biten <= '0; + end else begin + if(~is_active) begin + if(s_apb_psel) begin + is_active <= '1; + cpuif_req <= '1; + cpuif_req_is_wr <= s_apb_pwrite; + cpuif_addr <= {s_apb_paddr[6:2], 2'b0}; + cpuif_wr_data <= s_apb_pwdata; + for(int i=0; i<4; i++) begin + cpuif_wr_biten[i*8 +: 8] <= {8{s_apb_pstrb[i]}}; + end + end + end else begin + cpuif_req <= '0; + if(cpuif_rd_ack || cpuif_wr_ack) begin + is_active <= '0; + end + end + end + end + + // Response + assign s_apb_pready = cpuif_rd_ack | cpuif_wr_ack; + assign s_apb_prdata = cpuif_rd_data; + assign s_apb_pslverr = cpuif_rd_err | cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct { + logic snitch_boot_addr; + logic snitch_configurable_boot_addr; + logic snitch_intr_handler_addr; + logic snitch_cluster_return[5]; + logic reset_cluster[5]; + logic cluster_clk_gate_en[5]; + logic wide_mem_cluster_bypass[5]; + logic cluster_busy[5]; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_err; + logic [6:0] decoded_addr; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + automatic logic is_valid_addr; + automatic logic is_valid_rw; + is_valid_addr = '1; // No valid address check + is_valid_rw = '1; // No valid RW check + decoded_reg_strb.snitch_boot_addr = cpuif_req_masked & (cpuif_addr == 7'h0); + decoded_reg_strb.snitch_configurable_boot_addr = cpuif_req_masked & (cpuif_addr == 7'h4); + decoded_reg_strb.snitch_intr_handler_addr = cpuif_req_masked & (cpuif_addr == 7'h8); + for(int i0=0; i0<5; i0++) begin + decoded_reg_strb.snitch_cluster_return[i0] = cpuif_req_masked & (cpuif_addr == 7'hc + (7)'(i0) * 7'h4); + end + for(int i0=0; i0<5; i0++) begin + decoded_reg_strb.reset_cluster[i0] = cpuif_req_masked & (cpuif_addr == 7'h20 + (7)'(i0) * 7'h4); + end + for(int i0=0; i0<5; i0++) begin + decoded_reg_strb.cluster_clk_gate_en[i0] = cpuif_req_masked & (cpuif_addr == 7'h34 + (7)'(i0) * 7'h4); + end + for(int i0=0; i0<5; i0++) begin + decoded_reg_strb.wide_mem_cluster_bypass[i0] = cpuif_req_masked & (cpuif_addr == 7'h48 + (7)'(i0) * 7'h4); + end + for(int i0=0; i0<5; i0++) begin + decoded_reg_strb.cluster_busy[i0] = cpuif_req_masked & (cpuif_addr == 7'h5c + (7)'(i0) * 7'h4); + end + decoded_err = '0; + end + + // Pass down signals to next stage + assign decoded_addr = cpuif_addr; + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct { + struct { + struct { + logic [31:0] next; + logic load_next; + } value; + } snitch_boot_addr; + struct { + struct { + logic [31:0] next; + logic load_next; + } value; + } snitch_configurable_boot_addr; + struct { + struct { + logic [31:0] next; + logic load_next; + } value; + } snitch_intr_handler_addr; + struct { + struct { + logic [31:0] next; + logic load_next; + } value; + } snitch_cluster_return[5]; + struct { + struct { + logic next; + logic load_next; + } value; + } reset_cluster[5]; + struct { + struct { + logic next; + logic load_next; + } value; + } cluster_clk_gate_en[5]; + struct { + struct { + logic next; + logic load_next; + } value; + } wide_mem_cluster_bypass[5]; + struct { + struct { + logic next; + logic load_next; + } value; + } cluster_busy[5]; + } field_combo_t; + field_combo_t field_combo; + + typedef struct { + struct { + struct { + logic [31:0] value; + } value; + } snitch_boot_addr; + struct { + struct { + logic [31:0] value; + } value; + } snitch_configurable_boot_addr; + struct { + struct { + logic [31:0] value; + } value; + } snitch_intr_handler_addr; + struct { + struct { + logic [31:0] value; + } value; + } snitch_cluster_return[5]; + struct { + struct { + logic value; + } value; + } reset_cluster[5]; + struct { + struct { + logic value; + } value; + } cluster_clk_gate_en[5]; + struct { + struct { + logic value; + } value; + } wide_mem_cluster_bypass[5]; + struct { + struct { + logic value; + } value; + } cluster_busy[5]; + } field_storage_t; + field_storage_t field_storage; + + // Field: chimera_soc_regs.snitch_boot_addr.value + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.snitch_boot_addr.value.value; + load_next_c = '0; + if(decoded_reg_strb.snitch_boot_addr && decoded_req_is_wr) begin // SW write + next_c = (field_storage.snitch_boot_addr.value.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.snitch_boot_addr.value.next = next_c; + field_combo.snitch_boot_addr.value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + field_storage.snitch_boot_addr.value.value <= 32'hbadcab1e; + end else begin + if(field_combo.snitch_boot_addr.value.load_next) begin + field_storage.snitch_boot_addr.value.value <= field_combo.snitch_boot_addr.value.next; + end + end + end + assign hwif_out.snitch_boot_addr.value.value = field_storage.snitch_boot_addr.value.value; + // Field: chimera_soc_regs.snitch_configurable_boot_addr.value + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.snitch_configurable_boot_addr.value.value; + load_next_c = '0; + if(decoded_reg_strb.snitch_configurable_boot_addr && decoded_req_is_wr) begin // SW write + next_c = (field_storage.snitch_configurable_boot_addr.value.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.snitch_configurable_boot_addr.value.next = next_c; + field_combo.snitch_configurable_boot_addr.value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + field_storage.snitch_configurable_boot_addr.value.value <= 32'h30000000; + end else begin + if(field_combo.snitch_configurable_boot_addr.value.load_next) begin + field_storage.snitch_configurable_boot_addr.value.value <= field_combo.snitch_configurable_boot_addr.value.next; + end + end + end + assign hwif_out.snitch_configurable_boot_addr.value.value = field_storage.snitch_configurable_boot_addr.value.value; + // Field: chimera_soc_regs.snitch_intr_handler_addr.value + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.snitch_intr_handler_addr.value.value; + load_next_c = '0; + if(decoded_reg_strb.snitch_intr_handler_addr && decoded_req_is_wr) begin // SW write + next_c = (field_storage.snitch_intr_handler_addr.value.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.snitch_intr_handler_addr.value.next = next_c; + field_combo.snitch_intr_handler_addr.value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + field_storage.snitch_intr_handler_addr.value.value <= 32'hbadcab1e; + end else begin + if(field_combo.snitch_intr_handler_addr.value.load_next) begin + field_storage.snitch_intr_handler_addr.value.value <= field_combo.snitch_intr_handler_addr.value.next; + end + end + end + assign hwif_out.snitch_intr_handler_addr.value.value = field_storage.snitch_intr_handler_addr.value.value; + for(genvar i0=0; i0<5; i0++) begin + // Field: chimera_soc_regs.snitch_cluster_return[].value + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.snitch_cluster_return[i0].value.value; + load_next_c = '0; + if(decoded_reg_strb.snitch_cluster_return[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.snitch_cluster_return[i0].value.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.snitch_cluster_return[i0].value.next = next_c; + field_combo.snitch_cluster_return[i0].value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + field_storage.snitch_cluster_return[i0].value.value <= 32'h0; + end else begin + if(field_combo.snitch_cluster_return[i0].value.load_next) begin + field_storage.snitch_cluster_return[i0].value.value <= field_combo.snitch_cluster_return[i0].value.next; + end + end + end + assign hwif_out.snitch_cluster_return[i0].value.value = field_storage.snitch_cluster_return[i0].value.value; + end + for(genvar i0=0; i0<5; i0++) begin + // Field: chimera_soc_regs.reset_cluster[].value + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.reset_cluster[i0].value.value; + load_next_c = '0; + if(decoded_reg_strb.reset_cluster[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.reset_cluster[i0].value.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.reset_cluster[i0].value.next = next_c; + field_combo.reset_cluster[i0].value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + field_storage.reset_cluster[i0].value.value <= 1'h1; + end else begin + if(field_combo.reset_cluster[i0].value.load_next) begin + field_storage.reset_cluster[i0].value.value <= field_combo.reset_cluster[i0].value.next; + end + end + end + assign hwif_out.reset_cluster[i0].value.value = field_storage.reset_cluster[i0].value.value; + end + for(genvar i0=0; i0<5; i0++) begin + // Field: chimera_soc_regs.cluster_clk_gate_en[].value + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.cluster_clk_gate_en[i0].value.value; + load_next_c = '0; + if(decoded_reg_strb.cluster_clk_gate_en[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.cluster_clk_gate_en[i0].value.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.cluster_clk_gate_en[i0].value.next = next_c; + field_combo.cluster_clk_gate_en[i0].value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + field_storage.cluster_clk_gate_en[i0].value.value <= 1'h1; + end else begin + if(field_combo.cluster_clk_gate_en[i0].value.load_next) begin + field_storage.cluster_clk_gate_en[i0].value.value <= field_combo.cluster_clk_gate_en[i0].value.next; + end + end + end + assign hwif_out.cluster_clk_gate_en[i0].value.value = field_storage.cluster_clk_gate_en[i0].value.value; + end + for(genvar i0=0; i0<5; i0++) begin + // Field: chimera_soc_regs.wide_mem_cluster_bypass[].value + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.wide_mem_cluster_bypass[i0].value.value; + load_next_c = '0; + if(decoded_reg_strb.wide_mem_cluster_bypass[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.wide_mem_cluster_bypass[i0].value.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.wide_mem_cluster_bypass[i0].value.next = next_c; + field_combo.wide_mem_cluster_bypass[i0].value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + field_storage.wide_mem_cluster_bypass[i0].value.value <= 1'h0; + end else begin + if(field_combo.wide_mem_cluster_bypass[i0].value.load_next) begin + field_storage.wide_mem_cluster_bypass[i0].value.value <= field_combo.wide_mem_cluster_bypass[i0].value.next; + end + end + end + assign hwif_out.wide_mem_cluster_bypass[i0].value.value = field_storage.wide_mem_cluster_bypass[i0].value.value; + end + for(genvar i0=0; i0<5; i0++) begin + // Field: chimera_soc_regs.cluster_busy[].value + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.cluster_busy[i0].value.value; + load_next_c = '0; + if(decoded_reg_strb.cluster_busy[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.cluster_busy[i0].value.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.cluster_busy[i0].value.next = next_c; + field_combo.cluster_busy[i0].value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if(~arst_n) begin + field_storage.cluster_busy[i0].value.value <= 1'h1; + end else begin + if(field_combo.cluster_busy[i0].value.load_next) begin + field_storage.cluster_busy[i0].value.value <= field_combo.cluster_busy[i0].value.next; + end + end + end + assign hwif_out.cluster_busy[i0].value.value = field_storage.cluster_busy[i0].value.value; + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic [6:0] rd_mux_addr; + assign rd_mux_addr = decoded_addr; + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + always_comb begin + automatic logic [31:0] readback_data_var; + readback_data_var = '0; + if(rd_mux_addr == 7'h0) begin + readback_data_var[31:0] = field_storage.snitch_boot_addr.value.value; + end + if(rd_mux_addr == 7'h4) begin + readback_data_var[31:0] = field_storage.snitch_configurable_boot_addr.value.value; + end + if(rd_mux_addr == 7'h8) begin + readback_data_var[31:0] = field_storage.snitch_intr_handler_addr.value.value; + end + for(int i0=0; i0<5; i0++) begin + if(rd_mux_addr == 7'hc + (7)'(i0) * 7'h4) begin + readback_data_var[31:0] = field_storage.snitch_cluster_return[i0].value.value; + end + end + for(int i0=0; i0<5; i0++) begin + if(rd_mux_addr == 7'h20 + (7)'(i0) * 7'h4) begin + readback_data_var[0] = field_storage.reset_cluster[i0].value.value; + end + end + for(int i0=0; i0<5; i0++) begin + if(rd_mux_addr == 7'h34 + (7)'(i0) * 7'h4) begin + readback_data_var[0] = field_storage.cluster_clk_gate_en[i0].value.value; + end + end + for(int i0=0; i0<5; i0++) begin + if(rd_mux_addr == 7'h48 + (7)'(i0) * 7'h4) begin + readback_data_var[0] = field_storage.wide_mem_cluster_bypass[i0].value.value; + end + end + for(int i0=0; i0<5; i0++) begin + if(rd_mux_addr == 7'h5c + (7)'(i0) * 7'h4) begin + readback_data_var[0] = field_storage.cluster_busy[i0].value.value; + end + end + readback_data = readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; endmodule - - diff --git a/hw/regs/chimera_regs.hjson b/hw/regs/chimera_regs.hjson deleted file mode 100644 index 2bdc93c1..00000000 --- a/hw/regs/chimera_regs.hjson +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// Moritz Scherer - -{ - name: "chimera", - clock_primary: "clk_i", - bus_interfaces: [ - { protocol: "reg_iface", direction: "device" } - ], - regwidth: "32", - registers :[ - { - name: "SNITCH_BOOT_ADDR", - desc: "Set boot address for all snitch cores", - swaccess: "rw", - hwaccess: "hro", - resval: "0xBADCAB1E", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - { - name: "SNITCH_CONFIGURABLE_BOOT_ADDR", - desc: "Define the address of the Boot executed by each Snitch core", - swaccess: "rw", - hwaccess: "hro", - resval: "0x30000000", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - { - name: "SNITCH_INTR_HANDLER_ADDR", - desc: "Set interrupt handler address for all snitch cores", - swaccess: "rw", - hwaccess: "hro", - resval: "0xBADCAB1E", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - { - name: "SNITCH_CLUSTER_0_RETURN", - desc: "Register to store return value of Snitch cluster 0", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "SNITCH_CLUSTER_1_RETURN", - desc: "Register to store return value of Snitch cluster 1", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "SNITCH_CLUSTER_2_RETURN", - desc: "Register to store return value of Snitch cluster 2", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "SNITCH_CLUSTER_3_RETURN", - desc: "Register to store return value of Snitch cluster 3", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "SNITCH_CLUSTER_4_RETURN", - desc: "Register to store return value of Snitch cluster 4", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "RESET_CLUSTER_0", - desc: "Soft reset for cluster 0. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "RESET_CLUSTER_1", - desc: "Soft reset for cluster 1. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "RESET_CLUSTER_2", - desc: "Soft reset for cluster 2. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "RESET_CLUSTER_3", - desc: "Soft reset for cluster 3. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "RESET_CLUSTER_4", - desc: "Soft reset for cluster 4. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_0_CLK_GATE_EN", - desc: "Enable clock gate for cluster 0 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_1_CLK_GATE_EN", - desc: "Enable clock gate for cluster 1 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_2_CLK_GATE_EN", - desc: "Enable clock gate for cluster 2 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_3_CLK_GATE_EN", - desc: "Enable clock gate for cluster 3 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_4_CLK_GATE_EN", - desc: "Enable clock gate for cluster 4 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "WIDE_MEM_CLUSTER_0_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 0", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - - - { - name: "WIDE_MEM_CLUSTER_1_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 1", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - { - name: "WIDE_MEM_CLUSTER_2_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 2", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - { - name: "WIDE_MEM_CLUSTER_3_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 3", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - { - name: "WIDE_MEM_CLUSTER_4_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 4", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_0_BUSY", - desc: "Register to identify when cluster 0 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_1_BUSY", - desc: "Register to identify when cluster 1 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - { - name: "CLUSTER_2_BUSY", - desc: "Register to identify when cluster 2 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - { - name: "CLUSTER_3_BUSY", - desc: "Register to identify when cluster 3 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - { - name: "CLUSTER_4_BUSY", - desc: "Register to identify when cluster 4 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - - ] -} diff --git a/iis-env.sh b/iis-env.sh index beb92989..5ea6bc12 100755 --- a/iis-env.sh +++ b/iis-env.sh @@ -9,16 +9,21 @@ export VOPT="questa-2022.3 vopt" export VLIB="questa-2022.3 vlib" export BASE_PYTHON=/usr/local/anaconda3/bin/python3.11 export CHS_SW_32_GCC_BINROOT=/usr/pack/riscv-1.0-kgf/pulp-gcc-2.5.0/bin -export RISCV_GCC_BINROOT=/usr/pack/riscv-1.0-kgf/pulp-gcc-2.5.0/bin +export CHS_SW_64_GCC_BINROOT=/usr/pack/riscv-1.0-kgf/riscv64-gcc-12.2.0/bin +export CHS_SW_GCC_BINROOT=/usr/pack/riscv-1.0-kgf/riscv64-gcc-12.2.0/bin export CC=/usr/pack/gcc-11.2.0-af/linux-x64/bin/gcc export CXX=/usr/pack/gcc-11.2.0-af/linux-x64/bin/g++ export CMAKE=cmake-3.28.3 export SN_LLVM_BINROOT=/usr/scratch2/vulcano/colluca/tools/riscv32-snitch-llvm-almalinux8-15.0.0-snitch-0.2.0/bin -# Create the python venv -if [ ! -d ".venv" ]; then - make python-venv -fi +# One-command bootstrap: fetch HW dependencies (fast no-op if already checked +# out) so a fresh clone is buildable after a single `source iis-env.sh`. +$BENDER checkout + +# Python environment via uv. Keep the uv cache on the (writable, large) repo +# scratch rather than $HOME (small IIS quota). +export UV_CACHE_DIR="${UV_CACHE_DIR:-$(pwd)/.cache/uv}" +uv sync --locked # Activate the python venv only if not already active if [ -z "$VIRTUAL_ENV" ] || [ "$VIRTUAL_ENV" != "$(realpath .venv)" ]; then diff --git a/pyproject.toml b/pyproject.toml index bdbf0fba..f3863170 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,23 @@ dependencies = [ "peakrdl", "peakrdl-rawheader", "peakrdl-markdown", + # Provides pkg_resources, needed by the lowRISC reggen regtool.py used for + # iDMA/Cheshire RTL generation. A pip venv bundled it implicitly; uv does not. + # Pin <81: setuptools >=81 removed pkg_resources. + "setuptools<81", +] + +[dependency-groups] +# SoC test framework (pytest front-end wrapping ctest) + tooling. Installed by +# default with `uv sync` (the `dev` group). +dev = ["pytest", "pytest-html", "pytest-xdist"] + +[tool.pytest.ini_options] +testpaths = ["test"] +addopts = "-ra" +markers = [ + "host: host-only tests (no cluster offload)", + "cluster: tests that offload to a Snitch cluster", ] [tool.setuptools] diff --git a/rdl.mk b/rdl.mk new file mode 100644 index 00000000..bd092687 --- /dev/null +++ b/rdl.mk @@ -0,0 +1,86 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Solderpad Hardware License, Version 0.51, see LICENSE for details. +# SPDX-License-Identifier: SHL-0.51 + +##@ SystemRDL (global memory map / registers) + +# Single source of truth for the SoC memory map and control registers lives in +# cfg/rdl/*.rdl and is rendered with peakrdl (declared in pyproject.toml). This +# replaces the hand-maintained duplication across hw/chimera_pkg.sv, +# sw/include/soc_addr_map.h and the lowRISC-reggen register block. +# See docs/memory-map.md for the migration plan. + +# --- Tools ------------------------------------------------------------------- +# peakrdl and the Python interpreter both live in the project venv. Resolve the +# interpreter independently of $(PEAKRDL): the latter may be overridden to a bare +# name on $PATH (e.g. under iis-env), which would break a $(dir ...)-derived path. +PEAKRDL ?= $(CHIM_ROOT)/.venv/bin/peakrdl +RDL_PYTHON ?= $(CHIM_ROOT)/.venv/bin/python + +# --- Paths ------------------------------------------------------------------- +RDL_DIR ?= $(CHIM_ROOT)/cfg/rdl +RDL_GEN_DIR ?= $(CHIM_ROOT)/.generated +RDL_TOP ?= $(RDL_DIR)/chimera_addrmap.rdl +RDL_REGS ?= $(RDL_DIR)/chimera_soc_regs.rdl +RDL_REG_OUT ?= $(CHIM_ROOT)/hw/regs +DOCS_ADDRMAP ?= $(CHIM_ROOT)/docs/addressmap.md +NUMCLUSTERS ?= 5 + +# --- Snitch cluster SW headers (RTL clustergen) ------------------------------ +# The Snitch bootrom needs the cluster config (CFG_CLUSTER_NR_CORES / +# SNRT_CLUSTER_NUM) and the cluster-local address map. These come from the SAME +# single source of truth as the RTL wrapper (cfg/chimera.json, i.e. SN_CFG) AND +# the SAME generator: the RTL snitch_cluster clustergen ($(SN_ROOT)/util/ +# clustergen), not the snitch-sdk's separate copy -- so the SW headers can never +# drift from the wrapper. Only the header .tpl files still come from the +# snitch-sdk. PYTHONPATH lets the script `import cluster` from its own directory. +SN_SDK_DIR ?= $(CHIM_SDK_DIR)/devices/snitch_cluster/third_party/snitch-sdk +SN_SDK_DEV ?= $(SN_SDK_DIR)/devices/snitch_cluster +SN_CLUSTER_CFG?= $(CHIM_ROOT)/cfg/chimera.json +SN_CLUSTERGEN ?= $(SN_ROOT)/util/clustergen/clustergen.py +SN_CLUSTERGEN_CMD ?= PYTHONPATH=$(dir $(SN_CLUSTERGEN)) $(RDL_PYTHON) $(SN_CLUSTERGEN) -c $(SN_CLUSTER_CFG) + +# The top address map includes the real per-cluster map shipped by the +# snitch_cluster dependency (hw/generated/snitch_cluster.rdl, which itself +# includes snitch_cluster_peripheral_reg.rdl). Resolve those include dirs from +# the dependency checkout via `bender path` (Gwaihir-style), so peakrdl finds +# them in place without copying anything. +PEAKRDL_INCLUDES = -I $(RDL_DIR) +ifneq ($(SN_ROOT),) +PEAKRDL_INCLUDES += -I $(SN_ROOT)/hw/generated +PEAKRDL_INCLUDES += -I $(SN_ROOT)/hw/snitch_cluster/src/snitch_cluster_peripheral +endif +ifneq ($(CHS_ROOT),) +PEAKRDL_INCLUDES += $(CHS_PEAKRDL_INCLUDES) +endif + +.PHONY: chim-rdl chim-rdl-markdown chim-rdl-c-header chim-rdl-raw-header \ + chim-rdl-sw-headers chim-rdl-regblock chim-rdl-clean + +$(RDL_GEN_DIR): + mkdir -p $@ + +chim-rdl-markdown: | $(RDL_GEN_DIR) ## Generate the global address-map Markdown (docs/addressmap.md) + $(PEAKRDL) markdown $(RDL_TOP) $(PEAKRDL_INCLUDES) -o $(DOCS_ADDRMAP) + +chim-rdl-c-header: | $(RDL_GEN_DIR) ## Generate the SoC address-map register C header + $(PEAKRDL) c-header $(RDL_TOP) $(PEAKRDL_INCLUDES) -o $(RDL_GEN_DIR)/chimera_addrmap.h + +chim-rdl-raw-header: | $(RDL_GEN_DIR) ## Generate SV + C address-map base-address headers + $(PEAKRDL) raw-header $(RDL_TOP) $(PEAKRDL_INCLUDES) --format svh -o $(RDL_GEN_DIR)/chimera_addrmap.svh + $(PEAKRDL) raw-header $(RDL_TOP) $(PEAKRDL_INCLUDES) --format c -o $(RDL_GEN_DIR)/chimera_addrmap_raw.h + +chim-rdl-regblock: ## Generate the SoC-control SV register block into hw/regs (replaces reggen) + $(PEAKRDL) regblock $(RDL_REGS) -o $(RDL_REG_OUT) --cpuif apb4-flat --default-reset arst_n \ + --module-name chimera_reg_top --package-name chimera_reg_pkg -P NrClusters=$(NUMCLUSTERS) + @for f in $(RDL_REG_OUT)/chimera_reg_pkg.sv $(RDL_REG_OUT)/chimera_reg_top.sv; do \ + sed -i '1i// Copyright 2024 ETH Zurich and University of Bologna.\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-License-Identifier: Apache-2.0\n' $$f; done + +chim-rdl-sw-headers: | $(RDL_GEN_DIR) ## Generate the Snitch cluster SW headers (cfg + addrmap) + $(SN_CLUSTERGEN_CMD) --template $(SN_SDK_DEV)/templates/snitch_cluster_cfg.h.tpl -o $(RDL_GEN_DIR)/snitch_cluster_cfg.h + $(SN_CLUSTERGEN_CMD) --template $(SN_SDK_DEV)/templates/snitch_cluster_addrmap.h.tpl -o $(RDL_GEN_DIR)/snitch_cluster_addrmap.h + +chim-rdl: chim-rdl-markdown chim-rdl-c-header chim-rdl-raw-header chim-rdl-sw-headers ## Generate the memory-map artifacts + +chim-rdl-clean: ## Remove generated SystemRDL artifacts + rm -rf $(RDL_GEN_DIR) $(DOCS_ADDRMAP) diff --git a/scripts/sdk_container.sh b/scripts/sdk_container.sh new file mode 100755 index 00000000..0b4e46fd --- /dev/null +++ b/scripts/sdk_container.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# Copyright 2024 ETH Zurich and University of Bologna. +# Solderpad Hardware License, Version 0.51, see LICENSE for details. +# SPDX-License-Identifier: SHL-0.51 +# +# Run a command inside the chimera-sdk toolchain container (LLVM 18.1.4-pulp + +# picolibc + Python deps). Supports both Singularity/Apptainer and Docker so the +# exact same SDK build works on IIS workstations (Singularity) and elsewhere +# (Docker), per chimera-sdk/docs/src_sphinx/usage/usage.rst. +# +# Usage: +# scripts/sdk_container.sh +# scripts/sdk_container.sh # no args -> interactive shell +# +# Environment overrides: +# CONTAINER_RUNTIME auto|singularity|docker (default: auto) +# CHIM_SDK_SIF path to the .sif image (default: /.cache/containers/chimera_latest.sif) +# Auto-pulled from CHIM_SDK_IMAGE if missing; kept gitignored. +# CHIM_SDK_IMAGE docker image ref (default: ghcr.io/xeratec/chimera) +# TODO: switch to ghcr.io/pulp-platform/chimera:devel once +# https://github.com/pulp-platform/chimera-sdk/pull/43 is merged. +# CHIM_SDK_WORKDIR dir to cd into inside (default: /sw/deps/chimera-sdk) +# CHIM_SDK_CACHE_DIR writable uv/ccache root (default: /.cache) +# Kept on the bind-mounted scratch (large quota), NOT in $HOME +# (small quota on IIS) and NOT /scratch (read-only in-container). +# Point it at a shared scratch dir to reuse caches across repos. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CHIM_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +CONTAINER_RUNTIME="${CONTAINER_RUNTIME:-auto}" +CHIM_SDK_IMAGE="${CHIM_SDK_IMAGE:-ghcr.io/xeratec/chimera}" +CHIM_SDK_WORKDIR="${CHIM_SDK_WORKDIR:-$CHIM_ROOT/sw/deps/chimera-sdk}" +CHIM_SDK_CACHE_DIR="${CHIM_SDK_CACHE_DIR:-$CHIM_ROOT/.cache}" +# Managed, gitignored image location (auto-pulled on first use). Not a hardcoded +# external path — override CHIM_SDK_SIF to reuse an image elsewhere (e.g. a shared dir). +CHIM_SDK_SIF="${CHIM_SDK_SIF:-$CHIM_SDK_CACHE_DIR/containers/chimera_latest.sif}" + +# Auto-select a runtime: prefer Singularity/Apptainer when available (the .sif is +# pulled on demand), else Docker. +if [ "$CONTAINER_RUNTIME" = "auto" ]; then + if command -v singularity >/dev/null 2>&1 || command -v apptainer >/dev/null 2>&1; then + CONTAINER_RUNTIME=singularity + elif command -v docker >/dev/null 2>&1; then + CONTAINER_RUNTIME=docker + else + echo "sdk_container.sh: no container runtime found (need singularity/apptainer or docker)." >&2 + exit 1 + fi +fi + +# Fetch the image if it is not present yet. +ensure_image() { + case "$CONTAINER_RUNTIME" in + singularity|apptainer) + local rt; rt="$(command -v singularity || command -v apptainer)" + if [ ! -f "$CHIM_SDK_SIF" ]; then + echo ">> image missing -> pulling docker://$CHIM_SDK_IMAGE into $CHIM_SDK_SIF" >&2 + mkdir -p "$(dirname "$CHIM_SDK_SIF")" + # Keep the (large) layer cache on scratch too, not in $HOME. + SINGULARITY_CACHEDIR="$CHIM_SDK_CACHE_DIR/singularity" \ + APPTAINER_CACHEDIR="$CHIM_SDK_CACHE_DIR/singularity" \ + "$rt" pull "$CHIM_SDK_SIF" "docker://$CHIM_SDK_IMAGE" + fi + ;; + docker) + if ! docker image inspect "$CHIM_SDK_IMAGE" >/dev/null 2>&1; then + echo ">> image missing -> docker pull $CHIM_SDK_IMAGE" >&2 + docker pull "$CHIM_SDK_IMAGE" + fi + ;; + esac +} +ensure_image + +# The command to run inside the container (default: interactive shell). +if [ "$#" -eq 0 ]; then + CMD="exec zsh" +else + CMD="$*" +fi + +# Cache/venv setup. Unlike ~/.zsh-container (which parks caches in $HOME to dodge the +# read-only in-container /scratch), we keep them on the bind-mounted, high-quota scratch +# via CHIM_SDK_CACHE_DIR — IIS $HOME quota is too small for uv/ccache. We also keep a +# container-specific uv venv (.venv-container) separate from the host's .venv. For +# Singularity, `bash -l` sources ~/.profile which may reset UV_CACHE_DIR, so these +# exports run *after* login setup. +mkdir -p "$CHIM_SDK_CACHE_DIR/uv" "$CHIM_SDK_CACHE_DIR/ccache" +ENV_SETUP="export UV_CACHE_DIR='$CHIM_SDK_CACHE_DIR/uv' CCACHE_DIR='$CHIM_SDK_CACHE_DIR/ccache' UV_PROJECT_ENVIRONMENT=.venv-container;" + +# Bind the repo, and the cache dir too if it lives outside the repo. +BINDS=("$CHIM_ROOT") +case "$CHIM_SDK_CACHE_DIR" in "$CHIM_ROOT"/*) ;; *) BINDS+=("$CHIM_SDK_CACHE_DIR") ;; esac +BIND_ARG="$(IFS=,; echo "${BINDS[*]}")" + +case "$CONTAINER_RUNTIME" in + singularity|apptainer) + RT="$(command -v singularity || command -v apptainer)" + echo ">> [singularity] $CHIM_SDK_SIF :: $CMD" >&2 + exec "$RT" exec -e --bind "$BIND_ARG" "$CHIM_SDK_SIF" \ + bash -lc "$ENV_SETUP cd '$CHIM_SDK_WORKDIR' && $CMD" + ;; + docker) + echo ">> [docker] $CHIM_SDK_IMAGE :: $CMD" >&2 + # Mount the repo (and external cache dir) at the same path so build artifacts and + # their baked-in absolute paths are identical on host and in the container. + DOCKER_MOUNTS=(-v "$CHIM_ROOT":"$CHIM_ROOT") + case "$CHIM_SDK_CACHE_DIR" in "$CHIM_ROOT"/*) ;; *) DOCKER_MOUNTS+=(-v "$CHIM_SDK_CACHE_DIR":"$CHIM_SDK_CACHE_DIR") ;; esac + exec docker run --rm -it \ + "${DOCKER_MOUNTS[@]}" -w "$CHIM_SDK_WORKDIR" \ + -e UV_CACHE_DIR="$CHIM_SDK_CACHE_DIR/uv" \ + -e CCACHE_DIR="$CHIM_SDK_CACHE_DIR/ccache" \ + -e UV_PROJECT_ENVIRONMENT=.venv-container \ + "$CHIM_SDK_IMAGE" bash -lc "cd '$CHIM_SDK_WORKDIR' && $CMD" + ;; + *) + echo "sdk_container.sh: unknown CONTAINER_RUNTIME='$CONTAINER_RUNTIME'" >&2 + exit 1 + ;; +esac diff --git a/scripts/sim_runner.sh b/scripts/sim_runner.sh new file mode 100755 index 00000000..ef7d1c07 --- /dev/null +++ b/scripts/sim_runner.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +# Copyright 2024 ETH Zurich and University of Bologna. +# Solderpad Hardware License, Version 0.51, see LICENSE for details. +# SPDX-License-Identifier: SHL-0.51 +# +# One-test RTL simulation primitive. Used as the chimera-sdk `SOC_MODEL_BINARY` +# so `ctest` (and the pytest front-end wrapping it) can run each unified ELF in +# the chimera-top Questa testbench via the existing `chim-run-batch` flow. +# +# Invoked the way chimera-sdk's add_test() calls the sim model: +# sim_runner.sh +BINARY= [+PRELMODE=] +# +# Exit 0 = pass (testbench printed SUCCESS, no Fatal, "Errors: 0"). +# NOTE: no `set -u` — sourcing iis-env.sh references unset vars and would abort. +set -o pipefail + +CHIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +BINARY="" +PRELMODE=3 +for arg in "$@"; do + case "$arg" in + +BINARY=*) BINARY="${arg#+BINARY=}" ;; + +PRELMODE=*) PRELMODE="${arg#+PRELMODE=}" ;; + esac +done + +if [ -z "$BINARY" ]; then + echo "sim_runner.sh: missing +BINARY=" >&2 + exit 2 +fi +if [ ! -f "$BINARY" ]; then + echo "sim_runner.sh: binary not found: $BINARY" >&2 + exit 2 +fi + +name="$(basename "$BINARY" .elf)" + +# Per-test run directory. The RTL tracers write trace_hart_*/dma_trace_*/transcript +# to the cwd, so give each test its own dir → isolated, parallel-safe traces. +rundir="$CHIM_ROOT/target/sim/vsim/runs/${name}" +mkdir -p "$rundir/target/sim" +# The HyperRAM SDF is referenced by a compile-time-baked relative path +# (./target/sim/models/...); expose just that subtree so it resolves from rundir. +ln -sfn "$CHIM_ROOT/target/sim/models" "$rundir/target/sim/models" +transcript="$rundir/transcript" + +# Bring in the IIS sim environment (VSIM/questa) if not already set. +if ! command -v vsim >/dev/null 2>&1 || [ -z "${VSIM:-}" ]; then + # shellcheck disable=SC1091 + source "$CHIM_ROOT/iis-env.sh" >/dev/null 2>&1 || true +fi + +# Wall-clock watchdog: the testbench has no internal cycle-limit, so a run that +# never reaches end-of-computation would hang forever. Kill it after SIM_TIMEOUT +# seconds (SIGTERM, then SIGKILL 10s later) and clean up any orphaned vsim. +SIM_TIMEOUT="${SIM_TIMEOUT:-600}" + +# Reap this run's vsim (matched by its unique unified-ELF name on the command +# line). Killing `timeout`/`make` alone orphans vsim, so target it explicitly. +reap_vsim() { pkill -u "$(id -un)" -f "vsim.*${name}" 2>/dev/null || true; } + +# On Ctrl+C / SIGTERM (e.g. interrupting `make chim-test`), kill the sim child +# and reap vsim so nothing is left running. +on_interrupt() { + echo ">> [sim] interrupted: $name" >&2 + [ -n "${sim_pid:-}" ] && kill "$sim_pid" 2>/dev/null || true + reap_vsim + exit 130 +} +trap on_interrupt INT TERM + +echo ">> [sim] $name (PRELMODE=$PRELMODE, timeout=${SIM_TIMEOUT}s)" +# Run in the background + wait so the trap can fire promptly while the sim runs. +timeout -k 10 "$SIM_TIMEOUT" \ + make -C "$CHIM_ROOT" chim-run-batch \ + RUN_DIR="$rundir" \ + BINARY="$BINARY" PRELMODE="$PRELMODE" \ + VSIM_FLAGS="-c -l $transcript" >/dev/null 2>&1 & +sim_pid=$! +wait "$sim_pid" +rc=$? +trap - INT TERM + +if [ "$rc" -eq 124 ]; then + # timeout fired; make was killed but vsim may be orphaned — reap it. + reap_vsim + echo ">> [sim] TIMEOUT after ${SIM_TIMEOUT}s: $name" >&2 + exit 1 +fi + +# Pass iff the testbench signalled SUCCESS, hit no Fatal, and reported 0 errors. +if grep -q "] SUCCESS" "$transcript" 2>/dev/null \ + && ! grep -qE "Fatal:" "$transcript" \ + && grep -qE "Errors: 0(,|$)" "$transcript"; then + echo ">> [sim] PASS: $name" + exit 0 +fi + +echo ">> [sim] FAIL: $name (transcript: $transcript)" >&2 +grep -iE "FAILED|Fatal:|Errors: [1-9]" "$transcript" 2>/dev/null | tail -5 >&2 +exit 1 diff --git a/sw/deps/chimera-sdk b/sw/deps/chimera-sdk new file mode 160000 index 00000000..c8b820e5 --- /dev/null +++ b/sw/deps/chimera-sdk @@ -0,0 +1 @@ +Subproject commit c8b820e52f91d37f11ec6220daeb9218a8991d74 diff --git a/sw/include/offload.h b/sw/include/offload.h deleted file mode 100644 index 7d034394..00000000 --- a/sw/include/offload.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer -// Viviane Potocnik -// Lorenzo Leone - -#ifndef _OFFLOAD_INCLUDE_GUARD_ -#define _OFFLOAD_INCLUDE_GUARD_ - -#include -#include - -void setupInterruptHandler(void *handler); -void setClusterClockGating(uint8_t *regPtr, uint8_t clusterId, bool enable); -void setAllClusterClockGating(uint8_t *regPtr, bool enable); -void setClusterReset(uint8_t *regPtr, uint8_t clusterId, bool enable); -void setAllClusterReset(uint8_t *regPtr, bool enable); -void offloadToCluster(void *function, uint8_t hartId); -void waitClusterBusy(uint8_t clusterId); -uint32_t waitForCluster(uint8_t clusterId); - -#endif diff --git a/sw/include/regs/soc_ctrl.h b/sw/include/regs/soc_ctrl.h deleted file mode 100644 index a63244b3..00000000 --- a/sw/include/regs/soc_ctrl.h +++ /dev/null @@ -1,127 +0,0 @@ -// Generated register defines for chimera - -// Copyright information found in source file: -// Copyright 2024 ETH Zurich and University of Bologna. - -// Licensing information found in source file: -// -// SPDX-License-Identifier: SHL-0.51 - -#ifndef _CHIMERA_REG_DEFS_ -#define _CHIMERA_REG_DEFS_ - -#ifdef __cplusplus -extern "C" { -#endif -// Register width -#define CHIMERA_PARAM_REG_WIDTH 32 - -// Set boot address for all snitch cores -#define CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET 0x0 - -// Define the address of the Boot executed by each Snitch core -#define CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR_REG_OFFSET 0x4 - -// Set interrupt handler address for all snitch cores -#define CHIMERA_SNITCH_INTR_HANDLER_ADDR_REG_OFFSET 0x8 - -// Register to store return value of Snitch cluster 0 -#define CHIMERA_SNITCH_CLUSTER_0_RETURN_REG_OFFSET 0xc - -// Register to store return value of Snitch cluster 1 -#define CHIMERA_SNITCH_CLUSTER_1_RETURN_REG_OFFSET 0x10 - -// Register to store return value of Snitch cluster 2 -#define CHIMERA_SNITCH_CLUSTER_2_RETURN_REG_OFFSET 0x14 - -// Register to store return value of Snitch cluster 3 -#define CHIMERA_SNITCH_CLUSTER_3_RETURN_REG_OFFSET 0x18 - -// Register to store return value of Snitch cluster 4 -#define CHIMERA_SNITCH_CLUSTER_4_RETURN_REG_OFFSET 0x1c - -// Soft reset for cluster 0. Active High -#define CHIMERA_RESET_CLUSTER_0_REG_OFFSET 0x20 -#define CHIMERA_RESET_CLUSTER_0_RESET_CLUSTER_0_BIT 0 - -// Soft reset for cluster 1. Active High -#define CHIMERA_RESET_CLUSTER_1_REG_OFFSET 0x24 -#define CHIMERA_RESET_CLUSTER_1_RESET_CLUSTER_1_BIT 0 - -// Soft reset for cluster 2. Active High -#define CHIMERA_RESET_CLUSTER_2_REG_OFFSET 0x28 -#define CHIMERA_RESET_CLUSTER_2_RESET_CLUSTER_2_BIT 0 - -// Soft reset for cluster 3. Active High -#define CHIMERA_RESET_CLUSTER_3_REG_OFFSET 0x2c -#define CHIMERA_RESET_CLUSTER_3_RESET_CLUSTER_3_BIT 0 - -// Soft reset for cluster 4. Active High -#define CHIMERA_RESET_CLUSTER_4_REG_OFFSET 0x30 -#define CHIMERA_RESET_CLUSTER_4_RESET_CLUSTER_4_BIT 0 - -// Enable clock gate for cluster 0 (disable clock) -#define CHIMERA_CLUSTER_0_CLK_GATE_EN_REG_OFFSET 0x34 -#define CHIMERA_CLUSTER_0_CLK_GATE_EN_CLUSTER_0_CLK_GATE_EN_BIT 0 - -// Enable clock gate for cluster 1 (disable clock) -#define CHIMERA_CLUSTER_1_CLK_GATE_EN_REG_OFFSET 0x38 -#define CHIMERA_CLUSTER_1_CLK_GATE_EN_CLUSTER_1_CLK_GATE_EN_BIT 0 - -// Enable clock gate for cluster 2 (disable clock) -#define CHIMERA_CLUSTER_2_CLK_GATE_EN_REG_OFFSET 0x3c -#define CHIMERA_CLUSTER_2_CLK_GATE_EN_CLUSTER_2_CLK_GATE_EN_BIT 0 - -// Enable clock gate for cluster 3 (disable clock) -#define CHIMERA_CLUSTER_3_CLK_GATE_EN_REG_OFFSET 0x40 -#define CHIMERA_CLUSTER_3_CLK_GATE_EN_CLUSTER_3_CLK_GATE_EN_BIT 0 - -// Enable clock gate for cluster 4 (disable clock) -#define CHIMERA_CLUSTER_4_CLK_GATE_EN_REG_OFFSET 0x44 -#define CHIMERA_CLUSTER_4_CLK_GATE_EN_CLUSTER_4_CLK_GATE_EN_BIT 0 - -// Bypass cluster to mem wide connection for cluster 0 -#define CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_REG_OFFSET 0x48 -#define CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_WIDE_MEM_CLUSTER_0_BYPASS_BIT 0 - -// Bypass cluster to mem wide connection for cluster 1 -#define CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_REG_OFFSET 0x4c -#define CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_WIDE_MEM_CLUSTER_1_BYPASS_BIT 0 - -// Bypass cluster to mem wide connection for cluster 2 -#define CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_REG_OFFSET 0x50 -#define CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_WIDE_MEM_CLUSTER_2_BYPASS_BIT 0 - -// Bypass cluster to mem wide connection for cluster 3 -#define CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_REG_OFFSET 0x54 -#define CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_WIDE_MEM_CLUSTER_3_BYPASS_BIT 0 - -// Bypass cluster to mem wide connection for cluster 4 -#define CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_REG_OFFSET 0x58 -#define CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_WIDE_MEM_CLUSTER_4_BYPASS_BIT 0 - -// Register to identify when cluster 0 is busy -#define CHIMERA_CLUSTER_0_BUSY_REG_OFFSET 0x5c -#define CHIMERA_CLUSTER_0_BUSY_CLUSTER_0_BUSY_BIT 0 - -// Register to identify when cluster 1 is busy -#define CHIMERA_CLUSTER_1_BUSY_REG_OFFSET 0x60 -#define CHIMERA_CLUSTER_1_BUSY_CLUSTER_1_BUSY_BIT 0 - -// Register to identify when cluster 2 is busy -#define CHIMERA_CLUSTER_2_BUSY_REG_OFFSET 0x64 -#define CHIMERA_CLUSTER_2_BUSY_CLUSTER_2_BUSY_BIT 0 - -// Register to identify when cluster 3 is busy -#define CHIMERA_CLUSTER_3_BUSY_REG_OFFSET 0x68 -#define CHIMERA_CLUSTER_3_BUSY_CLUSTER_3_BUSY_BIT 0 - -// Register to identify when cluster 4 is busy -#define CHIMERA_CLUSTER_4_BUSY_REG_OFFSET 0x6c -#define CHIMERA_CLUSTER_4_BUSY_CLUSTER_4_BUSY_BIT 0 - -#ifdef __cplusplus -} // extern "C" -#endif -#endif // _CHIMERA_REG_DEFS_ - // End generated register defines for chimera \ No newline at end of file diff --git a/sw/include/soc_addr_map.h b/sw/include/soc_addr_map.h deleted file mode 100644 index 780ab0cd..00000000 --- a/sw/include/soc_addr_map.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer -// Sergio Mazzola - -#ifndef _SOC_ADDR_MAP_INCLUDE_GUARD_ -#define _SOC_ADDR_MAP_INCLUDE_GUARD_ - -#include - -#define CLINT_CTRL_BASE 0x02040000 - -#define SOC_CTRL_BASE 0x30001000 - -#define CLUSTER_0_BASE 0x40000000 -#define CLUSTER_1_BASE 0x40200000 -#define CLUSTER_2_BASE 0x40400000 -#define CLUSTER_3_BASE 0x40600000 -#define CLUSTER_4_BASE 0x40800000 - -#define CLUSTER_0_NUMCORES 9 -#define CLUSTER_1_NUMCORES 9 -#define CLUSTER_2_NUMCORES 9 -#define CLUSTER_3_NUMCORES 9 -#define CLUSTER_4_NUMCORES 9 - -static uint8_t _chimera_numCores[] = {CLUSTER_0_NUMCORES, CLUSTER_1_NUMCORES, CLUSTER_2_NUMCORES, - CLUSTER_3_NUMCORES, CLUSTER_4_NUMCORES}; -#define _chimera_numClusters 5 - -#define CHIMERA_PADFRAME_BASE_ADDRESS 0x30002000 -#define FLL_BASE_ADDR 0x30003000 - -#define HYPERBUS_CFG_BASE 0x30005000 -#define HYPERRAM_BASE 0x80000000 - -#endif diff --git a/sw/lib/offload.c b/sw/lib/offload.c deleted file mode 100644 index d31d0ff8..00000000 --- a/sw/lib/offload.c +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer -// Viviane Potocnik -// Lorenzo Leone - -#include "regs/soc_ctrl.h" -#include "soc_addr_map.h" -#include -#include -#include - -void setupInterruptHandler(void *handler) { - volatile void **snitchTrapHandlerAddr = - (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_INTR_HANDLER_ADDR_REG_OFFSET); - - *snitchTrapHandlerAddr = handler; -} - -void waitClusterBusy(uint8_t clusterId) { - volatile int32_t *busy_ptr; - - if (clusterId == 0) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_0_BUSY_REG_OFFSET); - } else if (clusterId == 1) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_1_BUSY_REG_OFFSET); - } else if (clusterId == 2) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_2_BUSY_REG_OFFSET); - } else if (clusterId == 3) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_3_BUSY_REG_OFFSET); - } else if (clusterId == 4) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_4_BUSY_REG_OFFSET); - } - - while (*busy_ptr == 1) { - } - // TODO: temporary race condition fix - for (int i = 0; i < 1000; i++) { - // NOP - asm volatile("addi x0, x0, 0\n" :::); - } - - return; -} - -/* Set Clock Gating on specified cluster */ -void setClusterClockGating(volatile uint8_t *regPtr, uint8_t clusterId, bool enable) { - - if (regPtr == NULL) return; - - if (clusterId == 0) { - *(regPtr + CHIMERA_CLUSTER_0_CLK_GATE_EN_REG_OFFSET) = enable; - } else if (clusterId == 1) { - *(regPtr + CHIMERA_CLUSTER_1_CLK_GATE_EN_REG_OFFSET) = enable; - } else if (clusterId == 2) { - *(regPtr + CHIMERA_CLUSTER_2_CLK_GATE_EN_REG_OFFSET) = enable; - } else if (clusterId == 3) { - *(regPtr + CHIMERA_CLUSTER_3_CLK_GATE_EN_REG_OFFSET) = enable; - } else if (clusterId == 4) { - *(regPtr + CHIMERA_CLUSTER_4_CLK_GATE_EN_REG_OFFSET) = enable; - } -} - -/* Set Clock Gating on all clusters */ -void setAllClusterClockGating(volatile uint8_t *regPtr, bool enable) { - - if (regPtr == NULL) return; - - *(regPtr + CHIMERA_CLUSTER_0_CLK_GATE_EN_REG_OFFSET) = enable; - *(regPtr + CHIMERA_CLUSTER_1_CLK_GATE_EN_REG_OFFSET) = enable; - *(regPtr + CHIMERA_CLUSTER_2_CLK_GATE_EN_REG_OFFSET) = enable; - *(regPtr + CHIMERA_CLUSTER_3_CLK_GATE_EN_REG_OFFSET) = enable; - *(regPtr + CHIMERA_CLUSTER_4_CLK_GATE_EN_REG_OFFSET) = enable; -} - -/* Set Soft Reset on specified cluster */ -void setClusterReset(volatile uint8_t *regPtr, uint8_t clusterId, bool enable) { - - if (regPtr == NULL) return; - - if (clusterId == 0) { - *(regPtr + CHIMERA_RESET_CLUSTER_0_REG_OFFSET) = enable; - } else if (clusterId == 1) { - *(regPtr + CHIMERA_RESET_CLUSTER_1_REG_OFFSET) = enable; - } else if (clusterId == 2) { - *(regPtr + CHIMERA_RESET_CLUSTER_2_REG_OFFSET) = enable; - } else if (clusterId == 3) { - *(regPtr + CHIMERA_RESET_CLUSTER_3_REG_OFFSET) = enable; - } else if (clusterId == 4) { - *(regPtr + CHIMERA_RESET_CLUSTER_4_REG_OFFSET) = enable; - } -} - -/* Set Soft Reset on all clusters */ -void setAllClusterReset(volatile uint8_t *regPtr, bool enable) { - - if (regPtr == NULL) return; - - *(regPtr + CHIMERA_RESET_CLUSTER_0_REG_OFFSET) = enable; - *(regPtr + CHIMERA_RESET_CLUSTER_1_REG_OFFSET) = enable; - *(regPtr + CHIMERA_RESET_CLUSTER_2_REG_OFFSET) = enable; - *(regPtr + CHIMERA_RESET_CLUSTER_3_REG_OFFSET) = enable; - *(regPtr + CHIMERA_RESET_CLUSTER_4_REG_OFFSET) = enable; -} - -/* Offloads a void function pointer to the specified cluster's core 0 */ -void offloadToCluster(void *function, uint8_t clusterId) { - - volatile void **snitchBootAddr = - (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET); - - *snitchBootAddr = function; - - uint32_t hartId = 1; - for (uint32_t i = 0; i < clusterId; i++) { - hartId += _chimera_numCores[i]; - } - - volatile uint32_t *interruptTarget = ((uint32_t *)CLINT_CTRL_BASE) + hartId; - waitClusterBusy(clusterId); - *interruptTarget = 1; -} - -/* Busy waits for the return of a cluster, clears the return register, and - * returns the return value */ -uint32_t waitForCluster(uint8_t clusterId) { - volatile int32_t *snitchReturnAddr; - if (clusterId == 0) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_0_RETURN_REG_OFFSET); - } else if (clusterId == 1) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_1_RETURN_REG_OFFSET); - } else if (clusterId == 2) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_2_RETURN_REG_OFFSET); - } else if (clusterId == 3) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_3_RETURN_REG_OFFSET); - } else if (clusterId == 4) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_4_RETURN_REG_OFFSET); - } - - while (*snitchReturnAddr == 0) { - } - - uint32_t retVal = *snitchReturnAddr; - *snitchReturnAddr = 0; - - return retVal; -} diff --git a/sw/link/cheshire_addrs.ldh b/sw/link/cheshire_addrs.ldh new file mode 100644 index 00000000..cc2babb1 --- /dev/null +++ b/sw/link/cheshire_addrs.ldh @@ -0,0 +1,226 @@ +/* Copyright 2025 ETH Zurich and University of Bologna. */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Generated by PeakRDL raw-header */ + +/* Memories */ +MEMORY +{ + extrom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + bootrom (rx) : ORIGIN = 0x02000000, LENGTH = 0x00040000 + spm (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000 + spm_unc (rwx) : ORIGIN = 0x14000000, LENGTH = 0x04000000 + dram (rwx) : ORIGIN = 0x80000000, LENGTH = 0x00800000 +} + +/* Blocks */ +PROVIDE(__base_addr__ = 0x00000000); +PROVIDE(__size__ = 0x80800000); + +PROVIDE(__extrom_base_addr__ = 0x00000000); +PROVIDE(__extrom_size__ = 0x00040000); + +PROVIDE(__dma_base_addr__ = 0x01000000); +PROVIDE(__dma_size__ = 0x00001000); + +PROVIDE(__bootrom_base_addr__ = 0x02000000); +PROVIDE(__bootrom_size__ = 0x00040000); + +PROVIDE(__clint_base_addr__ = 0x02040000); +PROVIDE(__clint_size__ = 0x00040000); + +PROVIDE(__irq_router_base_addr__ = 0x02080000); +PROVIDE(__irq_router_size__ = 0x00040000); + +PROVIDE(__axirt_base_addr__ = 0x020C0000); +PROVIDE(__axirt_size__ = 0x00040000); + +PROVIDE(__regs_base_addr__ = 0x03000000); +PROVIDE(__regs_size__ = 0x0000005C); + +PROVIDE(__llc_base_addr__ = 0x03001000); +PROVIDE(__llc_size__ = 0x00001000); + +PROVIDE(__uart_base_addr__ = 0x03002000); +PROVIDE(__uart_size__ = 0x00001000); + +PROVIDE(__i2c_base_addr__ = 0x03003000); +PROVIDE(__i2c_size__ = 0x00001000); + +PROVIDE(__spih_base_addr__ = 0x03004000); +PROVIDE(__spih_size__ = 0x00001000); + +PROVIDE(__gpio_base_addr__ = 0x03005000); +PROVIDE(__gpio_size__ = 0x00001000); + +PROVIDE(__slink_base_addr__ = 0x03006000); +PROVIDE(__slink_size__ = 0x00000804); + +PROVIDE(__vga_base_addr__ = 0x03007000); +PROVIDE(__vga_size__ = 0x00001000); + +PROVIDE(__usb_base_addr__ = 0x03008000); +PROVIDE(__usb_size__ = 0x00001000); + +PROVIDE(__bus_err_base_addr__ = 0x03009000); +PROVIDE(__bus_err_size__ = 0x00000040); + +PROVIDE(__plic_base_addr__ = 0x04000000); +PROVIDE(__plic_size__ = 0x04000000); + +PROVIDE(__clic_base_addr__ = 0x08000000); +PROVIDE(__clic_size__ = 0x00040000); + +PROVIDE(__spm_base_addr__ = 0x10000000); +PROVIDE(__spm_size__ = 0x00010000); + +PROVIDE(__spm_unc_base_addr__ = 0x14000000); +PROVIDE(__spm_unc_size__ = 0x04000000); + +PROVIDE(__dram_base_addr__ = 0x80000000); +PROVIDE(__dram_size__ = 0x00800000); + +/* Registers */ +PROVIDE(__dma_status_base_addr__ = 0x01000000); + +PROVIDE(__dma__end_base_addr__ = 0x01000FFC); + +PROVIDE(__clint_status_base_addr__ = 0x02040000); + +PROVIDE(__clint__end_base_addr__ = 0x0207FFFC); + +PROVIDE(__irq_router_status_base_addr__ = 0x02080000); + +PROVIDE(__irq_router__end_base_addr__ = 0x020BFFFC); + +PROVIDE(__axirt_status_base_addr__ = 0x020C0000); + +PROVIDE(__axirt__end_base_addr__ = 0x020FFFFC); + +PROVIDE(__regs_scratch_0_base_addr__ = 0x03000000); +PROVIDE(__regs_scratch_1_base_addr__ = 0x03000004); +PROVIDE(__regs_scratch_2_base_addr__ = 0x03000008); +PROVIDE(__regs_scratch_3_base_addr__ = 0x0300000C); +PROVIDE(__regs_scratch_4_base_addr__ = 0x03000010); +PROVIDE(__regs_scratch_5_base_addr__ = 0x03000014); +PROVIDE(__regs_scratch_6_base_addr__ = 0x03000018); +PROVIDE(__regs_scratch_7_base_addr__ = 0x0300001C); +PROVIDE(__regs_scratch_8_base_addr__ = 0x03000020); +PROVIDE(__regs_scratch_9_base_addr__ = 0x03000024); +PROVIDE(__regs_scratch_10_base_addr__ = 0x03000028); +PROVIDE(__regs_scratch_11_base_addr__ = 0x0300002C); +PROVIDE(__regs_scratch_12_base_addr__ = 0x03000030); +PROVIDE(__regs_scratch_13_base_addr__ = 0x03000034); +PROVIDE(__regs_scratch_14_base_addr__ = 0x03000038); +PROVIDE(__regs_scratch_15_base_addr__ = 0x0300003C); +PROVIDE(__regs_scratch_num__ = 0x00000010); +PROVIDE(__regs_scratch_stride__ = 0x00000004); + +PROVIDE(__regs_boot_mode_base_addr__ = 0x03000040); + +PROVIDE(__regs_rtc_freq_base_addr__ = 0x03000044); + +PROVIDE(__regs_platform_rom_base_addr__ = 0x03000048); + +PROVIDE(__regs_num_int_harts_base_addr__ = 0x0300004C); + +PROVIDE(__regs_hw_features_base_addr__ = 0x03000050); + +PROVIDE(__regs_llc_size_base_addr__ = 0x03000054); + +PROVIDE(__regs_vga_params_base_addr__ = 0x03000058); + +PROVIDE(__llc_status_base_addr__ = 0x03001000); + +PROVIDE(__llc__end_base_addr__ = 0x03001FFC); + +PROVIDE(__uart_status_base_addr__ = 0x03002000); + +PROVIDE(__uart__end_base_addr__ = 0x03002FFC); + +PROVIDE(__i2c_status_base_addr__ = 0x03003000); + +PROVIDE(__i2c__end_base_addr__ = 0x03003FFC); + +PROVIDE(__spih_status_base_addr__ = 0x03004000); + +PROVIDE(__spih__end_base_addr__ = 0x03004FFC); + +PROVIDE(__gpio_status_base_addr__ = 0x03005000); + +PROVIDE(__gpio__end_base_addr__ = 0x03005FFC); + +PROVIDE(__slink_ctrl_base_addr__ = 0x03006000); + +PROVIDE(__slink_isolated_base_addr__ = 0x03006004); + +PROVIDE(__slink_raw_mode_en_base_addr__ = 0x03006008); + +PROVIDE(__slink_raw_mode_in_data_base_addr__ = 0x0300600C); + +PROVIDE(__slink_raw_mode_in_ch_sel_base_addr__ = 0x03006010); + +PROVIDE(__slink_raw_mode_out_data_fifo_base_addr__ = 0x03006014); + +PROVIDE(__slink_raw_mode_out_data_fifo_ctrl_base_addr__ = 0x03006018); + +PROVIDE(__slink_raw_mode_out_en_base_addr__ = 0x0300601C); + +PROVIDE(__slink_flow_control_fifo_clear_base_addr__ = 0x03006020); + +PROVIDE(__slink_raw_mode_in_data_valid_0_base_addr__ = 0x03006100); +PROVIDE(__slink_raw_mode_in_data_valid_num__ = 0x00000001); +PROVIDE(__slink_raw_mode_in_data_valid_stride__ = 0x00000004); + +PROVIDE(__slink_raw_mode_out_ch_mask_0_base_addr__ = 0x03006200); +PROVIDE(__slink_raw_mode_out_ch_mask_num__ = 0x00000001); +PROVIDE(__slink_raw_mode_out_ch_mask_stride__ = 0x00000004); + +PROVIDE(__slink_tx_phy_clk_div_0_base_addr__ = 0x03006300); +PROVIDE(__slink_tx_phy_clk_div_num__ = 0x00000001); +PROVIDE(__slink_tx_phy_clk_div_stride__ = 0x00000004); + +PROVIDE(__slink_tx_phy_clk_start_0_base_addr__ = 0x03006400); +PROVIDE(__slink_tx_phy_clk_start_num__ = 0x00000001); +PROVIDE(__slink_tx_phy_clk_start_stride__ = 0x00000004); + +PROVIDE(__slink_tx_phy_clk_end_0_base_addr__ = 0x03006500); +PROVIDE(__slink_tx_phy_clk_end_num__ = 0x00000001); +PROVIDE(__slink_tx_phy_clk_end_stride__ = 0x00000004); + +PROVIDE(__slink_channel_alloc_tx_cfg_base_addr__ = 0x03006600); + +PROVIDE(__slink_channel_alloc_tx_ctrl_base_addr__ = 0x03006604); + +PROVIDE(__slink_channel_alloc_rx_cfg_base_addr__ = 0x03006608); + +PROVIDE(__slink_channel_alloc_rx_ctrl_base_addr__ = 0x0300660C); + +PROVIDE(__slink_channel_alloc_tx_ch_en_0_base_addr__ = 0x03006700); +PROVIDE(__slink_channel_alloc_tx_ch_en_num__ = 0x00000001); +PROVIDE(__slink_channel_alloc_tx_ch_en_stride__ = 0x00000004); + +PROVIDE(__slink_channel_alloc_rx_ch_en_0_base_addr__ = 0x03006800); +PROVIDE(__slink_channel_alloc_rx_ch_en_num__ = 0x00000001); +PROVIDE(__slink_channel_alloc_rx_ch_en_stride__ = 0x00000004); + +PROVIDE(__vga_status_base_addr__ = 0x03007000); + +PROVIDE(__vga__end_base_addr__ = 0x03007FFC); + +PROVIDE(__usb_status_base_addr__ = 0x03008000); + +PROVIDE(__usb__end_base_addr__ = 0x03008FFC); + +PROVIDE(__bus_err_status_base_addr__ = 0x03009000); + +PROVIDE(__bus_err__end_base_addr__ = 0x0300903C); + +PROVIDE(__plic_status_base_addr__ = 0x04000000); + +PROVIDE(__plic__end_base_addr__ = 0x07FFFFFC); + +PROVIDE(__clic_status_base_addr__ = 0x08000000); + +PROVIDE(__clic__end_base_addr__ = 0x0803FFFC); + diff --git a/sw/link/memisl.ld b/sw/link/cheshire_bootrom.ld similarity index 85% rename from sw/link/memisl.ld rename to sw/link/cheshire_bootrom.ld index 6dcf16cd..669def14 100644 --- a/sw/link/memisl.ld +++ b/sw/link/cheshire_bootrom.ld @@ -5,17 +5,17 @@ /* Nicole Narr */ /* Christopher Reinwardt */ /* Paul Scheffler */ -/* Lorenzo Leone */ - -INCLUDE common.ldh +INCLUDE cheshire_common.ldh SECTIONS { + __stack_pointer$ = __stack_start - 8; + .text : { *(.text._start) *(.text) *(.text.*) - } > memisl + } > bootrom .misc : ALIGN(16) { *(.rodata) @@ -26,7 +26,7 @@ SECTIONS { *(.srodata.*) *(.sdata) *(.sdata.*) - } > memisl + } > bootrom . = ALIGN(32); __bss_start = .; @@ -35,12 +35,12 @@ SECTIONS { *(.bss.*) *(.sbss) *(.sbss.*) - } > memisl + } > bootrom . = ALIGN(32); __bss_end = .; .bulk : ALIGN(16) { *(.bulk) *(.bulk.*) - } > memisl + } > bootrom } diff --git a/sw/link/common.ldh b/sw/link/cheshire_common.ldh similarity index 70% rename from sw/link/common.ldh rename to sw/link/cheshire_common.ldh index 9133302b..83e79d22 100644 --- a/sw/link/common.ldh +++ b/sw/link/cheshire_common.ldh @@ -5,21 +5,14 @@ /* Nicole Narr */ /* Christopher Reinwardt */ /* Paul Scheffler */ +/* Philip Wiese */ /* This header defines symbols and rules universal to bare-metal execution */ ENTRY(_start) -MEMORY { - bootrom (rx) : ORIGIN = 0x02000000, LENGTH = 16K - /* We assume at least 64 KiB SPM, same minus stack for ROMs. */ - /* If more SPM is available, CRT0 repoints the stack. */ - extrom (rx) : ORIGIN = 0x00000000, LENGTH = 48K - spm (rwx) : ORIGIN = 0x10000000, LENGTH = 64K - memisl (rwx) : ORIGIN = 0x48000000, LENGTH = 128K - /* We assume at least 8 MiB of DRAM (minimum for Linux). */ - dram (rwx) : ORIGIN = 0x80000000, LENGTH = 8M -} +/* Memory regions and peripheral base addresses are auto-generated from cheshire.rdl */ +INCLUDE cheshire_addrs.ldh SECTIONS { /* Keep binaries lean */ @@ -30,6 +23,9 @@ SECTIONS { __global_pointer$ = ADDR(.misc) + SIZEOF(.misc) / 2; __stack_pointer$ = 0; + /* AXI-RT guard register (specific offset within AXI-RT region, not a named block) */ + __axirtgrd_base_addr__ = 0x020C1ffc; + /* Further addresses */ __base_dma = 0x01000000; __base_bootrom = 0x02000000; @@ -50,6 +46,5 @@ SECTIONS { __base_clic = 0x08000000; __base_spm = ORIGIN(spm); __base_dram = ORIGIN(dram); - __base_memisl = ORIGIN(memisl); - __stack_start = ORIGIN(memisl) + LENGTH(memisl); + __stack_start = ORIGIN(dram) + LENGTH(dram); } diff --git a/sw/link/chimera_addrs.ldh b/sw/link/chimera_addrs.ldh new file mode 100644 index 00000000..fd0782f5 --- /dev/null +++ b/sw/link/chimera_addrs.ldh @@ -0,0 +1,438 @@ +/* Copyright 2025 ETH Zurich and University of Bologna. */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Generated by PeakRDL raw-header */ + +/* Memories */ +MEMORY +{ + cheshire_extrom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + cheshire_bootrom (rx) : ORIGIN = 0x02000000, LENGTH = 0x00040000 + cheshire_spm (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000 + cheshire_spm_unc (rwx) : ORIGIN = 0x14000000, LENGTH = 0x04000000 + snitch_bootrom (rw) : ORIGIN = 0x30000000, LENGTH = 0x00001000 + ext_cfg_regs (rw) : ORIGIN = 0x30002000, LENGTH = 0x00003000 + hyperbus_cfg (rw) : ORIGIN = 0x30005000, LENGTH = 0x00001000 + cluster_tcdm_0 (rw) : ORIGIN = 0x40000000, LENGTH = 0x00020000 + cluster_tcdm_1 (rw) : ORIGIN = 0x40200000, LENGTH = 0x00020000 + cluster_tcdm_2 (rw) : ORIGIN = 0x40400000, LENGTH = 0x00020000 + cluster_tcdm_3 (rw) : ORIGIN = 0x40600000, LENGTH = 0x00020000 + cluster_tcdm_4 (rw) : ORIGIN = 0x40800000, LENGTH = 0x00020000 + cluster_zeromem_0 (rw) : ORIGIN = 0x40030000, LENGTH = 0x00010000 + cluster_zeromem_1 (rw) : ORIGIN = 0x40230000, LENGTH = 0x00010000 + cluster_zeromem_2 (rw) : ORIGIN = 0x40430000, LENGTH = 0x00010000 + cluster_zeromem_3 (rw) : ORIGIN = 0x40630000, LENGTH = 0x00010000 + cluster_zeromem_4 (rw) : ORIGIN = 0x40830000, LENGTH = 0x00010000 + mem_island (rw) : ORIGIN = 0x48000000, LENGTH = 0x00080000 + hyperram (rw) : ORIGIN = 0x80000000, LENGTH = 0x100000000 +} + +/* Blocks */ +PROVIDE(__base_addr__ = 0x00000000); +PROVIDE(__size__ = 0x180000000); + +PROVIDE(__cheshire_base_addr__ = 0x00000000); +PROVIDE(__cheshire_size__ = 0x18000000); + +PROVIDE(__cheshire_extrom_base_addr__ = 0x00000000); +PROVIDE(__cheshire_extrom_size__ = 0x00040000); + +PROVIDE(__cheshire_dma_base_addr__ = 0x01000000); +PROVIDE(__cheshire_dma_size__ = 0x00001000); + +PROVIDE(__cheshire_bootrom_base_addr__ = 0x02000000); +PROVIDE(__cheshire_bootrom_size__ = 0x00040000); + +PROVIDE(__cheshire_clint_base_addr__ = 0x02040000); +PROVIDE(__cheshire_clint_size__ = 0x00040000); + +PROVIDE(__cheshire_irq_router_base_addr__ = 0x02080000); +PROVIDE(__cheshire_irq_router_size__ = 0x00040000); + +PROVIDE(__cheshire_axirt_base_addr__ = 0x020C0000); +PROVIDE(__cheshire_axirt_size__ = 0x00040000); + +PROVIDE(__cheshire_regs_base_addr__ = 0x03000000); +PROVIDE(__cheshire_regs_size__ = 0x0000005C); + +PROVIDE(__cheshire_llc_base_addr__ = 0x03001000); +PROVIDE(__cheshire_llc_size__ = 0x00001000); + +PROVIDE(__cheshire_uart_base_addr__ = 0x03002000); +PROVIDE(__cheshire_uart_size__ = 0x00001000); + +PROVIDE(__cheshire_i2c_base_addr__ = 0x03003000); +PROVIDE(__cheshire_i2c_size__ = 0x00001000); + +PROVIDE(__cheshire_spih_base_addr__ = 0x03004000); +PROVIDE(__cheshire_spih_size__ = 0x00001000); + +PROVIDE(__cheshire_gpio_base_addr__ = 0x03005000); +PROVIDE(__cheshire_gpio_size__ = 0x00001000); + +PROVIDE(__cheshire_slink_base_addr__ = 0x03006000); +PROVIDE(__cheshire_slink_size__ = 0x00000804); + +PROVIDE(__cheshire_vga_base_addr__ = 0x03007000); +PROVIDE(__cheshire_vga_size__ = 0x00001000); + +PROVIDE(__cheshire_usb_base_addr__ = 0x03008000); +PROVIDE(__cheshire_usb_size__ = 0x00001000); + +PROVIDE(__cheshire_bus_err_base_addr__ = 0x03009000); +PROVIDE(__cheshire_bus_err_size__ = 0x00000040); + +PROVIDE(__cheshire_plic_base_addr__ = 0x04000000); +PROVIDE(__cheshire_plic_size__ = 0x04000000); + +PROVIDE(__cheshire_clic_base_addr__ = 0x08000000); +PROVIDE(__cheshire_clic_size__ = 0x00040000); + +PROVIDE(__cheshire_spm_base_addr__ = 0x10000000); +PROVIDE(__cheshire_spm_size__ = 0x00010000); + +PROVIDE(__cheshire_spm_unc_base_addr__ = 0x14000000); +PROVIDE(__cheshire_spm_unc_size__ = 0x04000000); + +PROVIDE(__snitch_bootrom_base_addr__ = 0x30000000); +PROVIDE(__snitch_bootrom_size__ = 0x00001000); + +PROVIDE(__soc_ctrl_base_addr__ = 0x30001000); +PROVIDE(__soc_ctrl_size__ = 0x00000070); + +PROVIDE(__ext_cfg_regs_base_addr__ = 0x30002000); +PROVIDE(__ext_cfg_regs_size__ = 0x00003000); + +PROVIDE(__hyperbus_cfg_base_addr__ = 0x30005000); +PROVIDE(__hyperbus_cfg_size__ = 0x00001000); + +PROVIDE(__cluster_0_base_addr__ = 0x40000000); +PROVIDE(__cluster_1_base_addr__ = 0x40200000); +PROVIDE(__cluster_2_base_addr__ = 0x40400000); +PROVIDE(__cluster_3_base_addr__ = 0x40600000); +PROVIDE(__cluster_4_base_addr__ = 0x40800000); +PROVIDE(__cluster_size__ = 0x00040000); +PROVIDE(__cluster_num__ = 0x00000005); +PROVIDE(__cluster_stride__ = 0x00200000); +PROVIDE(__cluster_total_size__ = 0x00A00000); + +PROVIDE(__cluster_tcdm_0_base_addr__ = 0x40000000); +PROVIDE(__cluster_tcdm_1_base_addr__ = 0x40200000); +PROVIDE(__cluster_tcdm_2_base_addr__ = 0x40400000); +PROVIDE(__cluster_tcdm_3_base_addr__ = 0x40600000); +PROVIDE(__cluster_tcdm_4_base_addr__ = 0x40800000); +PROVIDE(__cluster_tcdm_size__ = 0x00020000); + +PROVIDE(__cluster_peripheral_reg_0_base_addr__ = 0x40020000); +PROVIDE(__cluster_peripheral_reg_1_base_addr__ = 0x40220000); +PROVIDE(__cluster_peripheral_reg_2_base_addr__ = 0x40420000); +PROVIDE(__cluster_peripheral_reg_3_base_addr__ = 0x40620000); +PROVIDE(__cluster_peripheral_reg_4_base_addr__ = 0x40820000); +PROVIDE(__cluster_peripheral_reg_size__ = 0x000001C0); + +PROVIDE(__cluster_peripheral_reg_perf_regs_0_base_addr__ = 0x40020000); +PROVIDE(__cluster_peripheral_reg_perf_regs_1_base_addr__ = 0x40220000); +PROVIDE(__cluster_peripheral_reg_perf_regs_2_base_addr__ = 0x40420000); +PROVIDE(__cluster_peripheral_reg_perf_regs_3_base_addr__ = 0x40620000); +PROVIDE(__cluster_peripheral_reg_perf_regs_4_base_addr__ = 0x40820000); +PROVIDE(__cluster_peripheral_reg_perf_regs_size__ = 0x00000180); + +PROVIDE(__cluster_zeromem_0_base_addr__ = 0x40030000); +PROVIDE(__cluster_zeromem_1_base_addr__ = 0x40230000); +PROVIDE(__cluster_zeromem_2_base_addr__ = 0x40430000); +PROVIDE(__cluster_zeromem_3_base_addr__ = 0x40630000); +PROVIDE(__cluster_zeromem_4_base_addr__ = 0x40830000); +PROVIDE(__cluster_zeromem_size__ = 0x00010000); + +PROVIDE(__mem_island_base_addr__ = 0x48000000); +PROVIDE(__mem_island_size__ = 0x00080000); + +PROVIDE(__hyperram_base_addr__ = 0x80000000); +PROVIDE(__hyperram_size__ = 0x100000000); + +/* Registers */ +PROVIDE(__cheshire_dma_status_base_addr__ = 0x01000000); + +PROVIDE(__cheshire_dma__end_base_addr__ = 0x01000FFC); + +PROVIDE(__cheshire_clint_status_base_addr__ = 0x02040000); + +PROVIDE(__cheshire_clint__end_base_addr__ = 0x0207FFFC); + +PROVIDE(__cheshire_irq_router_status_base_addr__ = 0x02080000); + +PROVIDE(__cheshire_irq_router__end_base_addr__ = 0x020BFFFC); + +PROVIDE(__cheshire_axirt_status_base_addr__ = 0x020C0000); + +PROVIDE(__cheshire_axirt__end_base_addr__ = 0x020FFFFC); + +PROVIDE(__cheshire_regs_scratch_0_base_addr__ = 0x03000000); +PROVIDE(__cheshire_regs_scratch_1_base_addr__ = 0x03000004); +PROVIDE(__cheshire_regs_scratch_2_base_addr__ = 0x03000008); +PROVIDE(__cheshire_regs_scratch_3_base_addr__ = 0x0300000C); +PROVIDE(__cheshire_regs_scratch_4_base_addr__ = 0x03000010); +PROVIDE(__cheshire_regs_scratch_5_base_addr__ = 0x03000014); +PROVIDE(__cheshire_regs_scratch_6_base_addr__ = 0x03000018); +PROVIDE(__cheshire_regs_scratch_7_base_addr__ = 0x0300001C); +PROVIDE(__cheshire_regs_scratch_8_base_addr__ = 0x03000020); +PROVIDE(__cheshire_regs_scratch_9_base_addr__ = 0x03000024); +PROVIDE(__cheshire_regs_scratch_10_base_addr__ = 0x03000028); +PROVIDE(__cheshire_regs_scratch_11_base_addr__ = 0x0300002C); +PROVIDE(__cheshire_regs_scratch_12_base_addr__ = 0x03000030); +PROVIDE(__cheshire_regs_scratch_13_base_addr__ = 0x03000034); +PROVIDE(__cheshire_regs_scratch_14_base_addr__ = 0x03000038); +PROVIDE(__cheshire_regs_scratch_15_base_addr__ = 0x0300003C); +PROVIDE(__cheshire_regs_scratch_num__ = 0x00000010); +PROVIDE(__cheshire_regs_scratch_stride__ = 0x00000004); + +PROVIDE(__cheshire_regs_boot_mode_base_addr__ = 0x03000040); + +PROVIDE(__cheshire_regs_rtc_freq_base_addr__ = 0x03000044); + +PROVIDE(__cheshire_regs_platform_rom_base_addr__ = 0x03000048); + +PROVIDE(__cheshire_regs_num_int_harts_base_addr__ = 0x0300004C); + +PROVIDE(__cheshire_regs_hw_features_base_addr__ = 0x03000050); + +PROVIDE(__cheshire_regs_llc_size_base_addr__ = 0x03000054); + +PROVIDE(__cheshire_regs_vga_params_base_addr__ = 0x03000058); + +PROVIDE(__cheshire_llc_status_base_addr__ = 0x03001000); + +PROVIDE(__cheshire_llc__end_base_addr__ = 0x03001FFC); + +PROVIDE(__cheshire_uart_status_base_addr__ = 0x03002000); + +PROVIDE(__cheshire_uart__end_base_addr__ = 0x03002FFC); + +PROVIDE(__cheshire_i2c_status_base_addr__ = 0x03003000); + +PROVIDE(__cheshire_i2c__end_base_addr__ = 0x03003FFC); + +PROVIDE(__cheshire_spih_status_base_addr__ = 0x03004000); + +PROVIDE(__cheshire_spih__end_base_addr__ = 0x03004FFC); + +PROVIDE(__cheshire_gpio_status_base_addr__ = 0x03005000); + +PROVIDE(__cheshire_gpio__end_base_addr__ = 0x03005FFC); + +PROVIDE(__cheshire_slink_ctrl_base_addr__ = 0x03006000); + +PROVIDE(__cheshire_slink_isolated_base_addr__ = 0x03006004); + +PROVIDE(__cheshire_slink_raw_mode_en_base_addr__ = 0x03006008); + +PROVIDE(__cheshire_slink_raw_mode_in_data_base_addr__ = 0x0300600C); + +PROVIDE(__cheshire_slink_raw_mode_in_ch_sel_base_addr__ = 0x03006010); + +PROVIDE(__cheshire_slink_raw_mode_out_data_fifo_base_addr__ = 0x03006014); + +PROVIDE(__cheshire_slink_raw_mode_out_data_fifo_ctrl_base_addr__ = 0x03006018); + +PROVIDE(__cheshire_slink_raw_mode_out_en_base_addr__ = 0x0300601C); + +PROVIDE(__cheshire_slink_flow_control_fifo_clear_base_addr__ = 0x03006020); + +PROVIDE(__cheshire_slink_raw_mode_in_data_valid_0_base_addr__ = 0x03006100); +PROVIDE(__cheshire_slink_raw_mode_in_data_valid_num__ = 0x00000001); +PROVIDE(__cheshire_slink_raw_mode_in_data_valid_stride__ = 0x00000004); + +PROVIDE(__cheshire_slink_raw_mode_out_ch_mask_0_base_addr__ = 0x03006200); +PROVIDE(__cheshire_slink_raw_mode_out_ch_mask_num__ = 0x00000001); +PROVIDE(__cheshire_slink_raw_mode_out_ch_mask_stride__ = 0x00000004); + +PROVIDE(__cheshire_slink_tx_phy_clk_div_0_base_addr__ = 0x03006300); +PROVIDE(__cheshire_slink_tx_phy_clk_div_num__ = 0x00000001); +PROVIDE(__cheshire_slink_tx_phy_clk_div_stride__ = 0x00000004); + +PROVIDE(__cheshire_slink_tx_phy_clk_start_0_base_addr__ = 0x03006400); +PROVIDE(__cheshire_slink_tx_phy_clk_start_num__ = 0x00000001); +PROVIDE(__cheshire_slink_tx_phy_clk_start_stride__ = 0x00000004); + +PROVIDE(__cheshire_slink_tx_phy_clk_end_0_base_addr__ = 0x03006500); +PROVIDE(__cheshire_slink_tx_phy_clk_end_num__ = 0x00000001); +PROVIDE(__cheshire_slink_tx_phy_clk_end_stride__ = 0x00000004); + +PROVIDE(__cheshire_slink_channel_alloc_tx_cfg_base_addr__ = 0x03006600); + +PROVIDE(__cheshire_slink_channel_alloc_tx_ctrl_base_addr__ = 0x03006604); + +PROVIDE(__cheshire_slink_channel_alloc_rx_cfg_base_addr__ = 0x03006608); + +PROVIDE(__cheshire_slink_channel_alloc_rx_ctrl_base_addr__ = 0x0300660C); + +PROVIDE(__cheshire_slink_channel_alloc_tx_ch_en_0_base_addr__ = 0x03006700); +PROVIDE(__cheshire_slink_channel_alloc_tx_ch_en_num__ = 0x00000001); +PROVIDE(__cheshire_slink_channel_alloc_tx_ch_en_stride__ = 0x00000004); + +PROVIDE(__cheshire_slink_channel_alloc_rx_ch_en_0_base_addr__ = 0x03006800); +PROVIDE(__cheshire_slink_channel_alloc_rx_ch_en_num__ = 0x00000001); +PROVIDE(__cheshire_slink_channel_alloc_rx_ch_en_stride__ = 0x00000004); + +PROVIDE(__cheshire_vga_status_base_addr__ = 0x03007000); + +PROVIDE(__cheshire_vga__end_base_addr__ = 0x03007FFC); + +PROVIDE(__cheshire_usb_status_base_addr__ = 0x03008000); + +PROVIDE(__cheshire_usb__end_base_addr__ = 0x03008FFC); + +PROVIDE(__cheshire_bus_err_status_base_addr__ = 0x03009000); + +PROVIDE(__cheshire_bus_err__end_base_addr__ = 0x0300903C); + +PROVIDE(__cheshire_plic_status_base_addr__ = 0x04000000); + +PROVIDE(__cheshire_plic__end_base_addr__ = 0x07FFFFFC); + +PROVIDE(__cheshire_clic_status_base_addr__ = 0x08000000); + +PROVIDE(__cheshire_clic__end_base_addr__ = 0x0803FFFC); + +PROVIDE(__soc_ctrl_snitch_boot_addr_base_addr__ = 0x30001000); + +PROVIDE(__soc_ctrl_snitch_configurable_boot_addr_base_addr__ = 0x30001004); + +PROVIDE(__soc_ctrl_snitch_intr_handler_addr_base_addr__ = 0x30001008); + +PROVIDE(__soc_ctrl_snitch_cluster_return_0_base_addr__ = 0x3000100C); +PROVIDE(__soc_ctrl_snitch_cluster_return_1_base_addr__ = 0x30001010); +PROVIDE(__soc_ctrl_snitch_cluster_return_2_base_addr__ = 0x30001014); +PROVIDE(__soc_ctrl_snitch_cluster_return_3_base_addr__ = 0x30001018); +PROVIDE(__soc_ctrl_snitch_cluster_return_4_base_addr__ = 0x3000101C); +PROVIDE(__soc_ctrl_snitch_cluster_return_num__ = 0x00000005); +PROVIDE(__soc_ctrl_snitch_cluster_return_stride__ = 0x00000004); + +PROVIDE(__soc_ctrl_reset_cluster_0_base_addr__ = 0x30001020); +PROVIDE(__soc_ctrl_reset_cluster_1_base_addr__ = 0x30001024); +PROVIDE(__soc_ctrl_reset_cluster_2_base_addr__ = 0x30001028); +PROVIDE(__soc_ctrl_reset_cluster_3_base_addr__ = 0x3000102C); +PROVIDE(__soc_ctrl_reset_cluster_4_base_addr__ = 0x30001030); +PROVIDE(__soc_ctrl_reset_cluster_num__ = 0x00000005); +PROVIDE(__soc_ctrl_reset_cluster_stride__ = 0x00000004); + +PROVIDE(__soc_ctrl_cluster_clk_gate_en_0_base_addr__ = 0x30001034); +PROVIDE(__soc_ctrl_cluster_clk_gate_en_1_base_addr__ = 0x30001038); +PROVIDE(__soc_ctrl_cluster_clk_gate_en_2_base_addr__ = 0x3000103C); +PROVIDE(__soc_ctrl_cluster_clk_gate_en_3_base_addr__ = 0x30001040); +PROVIDE(__soc_ctrl_cluster_clk_gate_en_4_base_addr__ = 0x30001044); +PROVIDE(__soc_ctrl_cluster_clk_gate_en_num__ = 0x00000005); +PROVIDE(__soc_ctrl_cluster_clk_gate_en_stride__ = 0x00000004); + +PROVIDE(__soc_ctrl_wide_mem_cluster_bypass_0_base_addr__ = 0x30001048); +PROVIDE(__soc_ctrl_wide_mem_cluster_bypass_1_base_addr__ = 0x3000104C); +PROVIDE(__soc_ctrl_wide_mem_cluster_bypass_2_base_addr__ = 0x30001050); +PROVIDE(__soc_ctrl_wide_mem_cluster_bypass_3_base_addr__ = 0x30001054); +PROVIDE(__soc_ctrl_wide_mem_cluster_bypass_4_base_addr__ = 0x30001058); +PROVIDE(__soc_ctrl_wide_mem_cluster_bypass_num__ = 0x00000005); +PROVIDE(__soc_ctrl_wide_mem_cluster_bypass_stride__ = 0x00000004); + +PROVIDE(__soc_ctrl_cluster_busy_0_base_addr__ = 0x3000105C); +PROVIDE(__soc_ctrl_cluster_busy_1_base_addr__ = 0x30001060); +PROVIDE(__soc_ctrl_cluster_busy_2_base_addr__ = 0x30001064); +PROVIDE(__soc_ctrl_cluster_busy_3_base_addr__ = 0x30001068); +PROVIDE(__soc_ctrl_cluster_busy_4_base_addr__ = 0x3000106C); +PROVIDE(__soc_ctrl_cluster_busy_num__ = 0x00000005); +PROVIDE(__soc_ctrl_cluster_busy_stride__ = 0x00000004); + +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_0_base_addr__ = 0x40020000); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_1_base_addr__ = 0x40020008); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_2_base_addr__ = 0x40020010); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_3_base_addr__ = 0x40020018); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_4_base_addr__ = 0x40020020); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_5_base_addr__ = 0x40020028); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_6_base_addr__ = 0x40020030); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_7_base_addr__ = 0x40020038); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_8_base_addr__ = 0x40020040); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_9_base_addr__ = 0x40020048); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_10_base_addr__ = 0x40020050); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_11_base_addr__ = 0x40020058); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_12_base_addr__ = 0x40020060); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_13_base_addr__ = 0x40020068); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_14_base_addr__ = 0x40020070); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_15_base_addr__ = 0x40020078); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_num__ = 0x00000010); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_en_stride__ = 0x00000008); + +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_0_base_addr__ = 0x40020080); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_1_base_addr__ = 0x40020088); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_2_base_addr__ = 0x40020090); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_3_base_addr__ = 0x40020098); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_4_base_addr__ = 0x400200A0); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_5_base_addr__ = 0x400200A8); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_6_base_addr__ = 0x400200B0); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_7_base_addr__ = 0x400200B8); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_8_base_addr__ = 0x400200C0); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_9_base_addr__ = 0x400200C8); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_10_base_addr__ = 0x400200D0); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_11_base_addr__ = 0x400200D8); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_12_base_addr__ = 0x400200E0); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_13_base_addr__ = 0x400200E8); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_14_base_addr__ = 0x400200F0); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_15_base_addr__ = 0x400200F8); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_num__ = 0x00000010); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_sel_stride__ = 0x00000008); + +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_0_base_addr__ = 0x40020100); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_1_base_addr__ = 0x40020108); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_2_base_addr__ = 0x40020110); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_3_base_addr__ = 0x40020118); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_4_base_addr__ = 0x40020120); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_5_base_addr__ = 0x40020128); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_6_base_addr__ = 0x40020130); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_7_base_addr__ = 0x40020138); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_8_base_addr__ = 0x40020140); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_9_base_addr__ = 0x40020148); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_10_base_addr__ = 0x40020150); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_11_base_addr__ = 0x40020158); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_12_base_addr__ = 0x40020160); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_13_base_addr__ = 0x40020168); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_14_base_addr__ = 0x40020170); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_15_base_addr__ = 0x40020178); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_num__ = 0x00000010); +PROVIDE(__cluster_peripheral_reg_perf_regs_perf_cnt_stride__ = 0x00000008); + +PROVIDE(__cluster_peripheral_reg_scratch_0_base_addr__ = 0x40020180); +PROVIDE(__cluster_peripheral_reg_scratch_1_base_addr__ = 0x40020188); +PROVIDE(__cluster_peripheral_reg_scratch_2_base_addr__ = 0x40020190); +PROVIDE(__cluster_peripheral_reg_scratch_3_base_addr__ = 0x40020198); +PROVIDE(__cluster_peripheral_reg_scratch_num__ = 0x00000004); +PROVIDE(__cluster_peripheral_reg_scratch_stride__ = 0x00000008); + +PROVIDE(__cluster_peripheral_reg_cl_clint_set_0_base_addr__ = 0x400201A0); +PROVIDE(__cluster_peripheral_reg_cl_clint_set_1_base_addr__ = 0x402201A0); +PROVIDE(__cluster_peripheral_reg_cl_clint_set_2_base_addr__ = 0x404201A0); +PROVIDE(__cluster_peripheral_reg_cl_clint_set_3_base_addr__ = 0x406201A0); +PROVIDE(__cluster_peripheral_reg_cl_clint_set_4_base_addr__ = 0x408201A0); +PROVIDE(__cluster_peripheral_reg_cl_clint_set_num__ = 0x00000005); +PROVIDE(__cluster_peripheral_reg_cl_clint_set_stride__ = 0x00200000); + +PROVIDE(__cluster_peripheral_reg_cl_clint_clear_0_base_addr__ = 0x400201A8); +PROVIDE(__cluster_peripheral_reg_cl_clint_clear_1_base_addr__ = 0x402201A8); +PROVIDE(__cluster_peripheral_reg_cl_clint_clear_2_base_addr__ = 0x404201A8); +PROVIDE(__cluster_peripheral_reg_cl_clint_clear_3_base_addr__ = 0x406201A8); +PROVIDE(__cluster_peripheral_reg_cl_clint_clear_4_base_addr__ = 0x408201A8); +PROVIDE(__cluster_peripheral_reg_cl_clint_clear_num__ = 0x00000005); +PROVIDE(__cluster_peripheral_reg_cl_clint_clear_stride__ = 0x00200000); + +PROVIDE(__cluster_peripheral_reg_icache_prefetch_enable_0_base_addr__ = 0x400201B0); +PROVIDE(__cluster_peripheral_reg_icache_prefetch_enable_1_base_addr__ = 0x402201B0); +PROVIDE(__cluster_peripheral_reg_icache_prefetch_enable_2_base_addr__ = 0x404201B0); +PROVIDE(__cluster_peripheral_reg_icache_prefetch_enable_3_base_addr__ = 0x406201B0); +PROVIDE(__cluster_peripheral_reg_icache_prefetch_enable_4_base_addr__ = 0x408201B0); +PROVIDE(__cluster_peripheral_reg_icache_prefetch_enable_num__ = 0x00000005); +PROVIDE(__cluster_peripheral_reg_icache_prefetch_enable_stride__ = 0x00200000); + +PROVIDE(__cluster_peripheral_reg_unused_0_base_addr__ = 0x400201B8); +PROVIDE(__cluster_peripheral_reg_unused_1_base_addr__ = 0x402201B8); +PROVIDE(__cluster_peripheral_reg_unused_2_base_addr__ = 0x404201B8); +PROVIDE(__cluster_peripheral_reg_unused_3_base_addr__ = 0x406201B8); +PROVIDE(__cluster_peripheral_reg_unused_4_base_addr__ = 0x408201B8); +PROVIDE(__cluster_peripheral_reg_unused_num__ = 0x00000005); +PROVIDE(__cluster_peripheral_reg_unused_stride__ = 0x00200000); + diff --git a/sw/sw.mk b/sw/sw.mk index e297f777..e12b8c25 100644 --- a/sw/sw.mk +++ b/sw/sw.mk @@ -9,61 +9,110 @@ ifndef chim_sw_mk chim_sw_mk=1 -CHS_SW_INCLUDES += -I$(CHIM_SW_DIR)/include - - -# SCHEREMO: use im for platform-level SW, as the smallest common denominator between CVA6 and the Snitch cluster. -# CVA6's bootrom however needs imc, so override that for this specific case. -CHS_SW_FLAGS += -falign-functions=64 -march=rv32im -CHS_BROM_FLAGS += -march=rv32imc - -CHS_SW_LDFLAGS += -L$(CHIM_SW_DIR)/lib - -CHIM_SW_LIB_SRCS_C = $(wildcard $(CHIM_SW_DIR)/lib/*.c $(CHIM_SW_DIR)/lib/**/*.c) -CHIM_SW_LIB_SRCS_O = $(CHIM_SW_DEPS_SRCS:.c=.o) $(CHIM_SW_LIB_SRCS_S:.S=.o) $(CHIM_SW_LIB_SRCS_C:.c=.o) - -CHIM_SW_LIB = $(CHIM_SW_DIR)/lib/libchimera.a -CHS_SW_LIBS += $(CHIM_SW_LIB) - -$(CHIM_SW_DIR)/lib/libchimera.a: $(CHIM_SW_LIB_SRCS_O) - rm -f $@ - $(CHS_SW_AR) $(CHS_SW_ARFLAGS) -rcsv $@ $^ - - -CHIM_SW_TEST_SRCS_S = $(wildcard $(CHIM_SW_DIR)/tests/*.S) -CHIM_SW_TEST_SRCS_C = $(wildcard $(CHIM_SW_DIR)/tests/*.c) - -CHIM_SW_TEST_MEMISL_DUMP = $(CHIM_SW_TEST_SRCS_S:.S=.memisl.dump) $(CHIM_SW_TEST_SRCS_C:.c=.memisl.dump) - -CHIM_SW_TESTS += $(CHIM_SW_TEST_MEMISL_DUMP) - -# All objects require up-to-date patches and headers -%.o: %.c - $(CHS_SW_CC) $(CHS_SW_INCLUDES) $(CHS_SW_CCFLAGS) -c $< -o $@ - -%.o: %.S - $(CHS_SW_CC) $(CHS_SW_INCLUDES) $(CHS_SW_CCFLAGS) -c $< -o $@ - -define chim_sw_ld_elf_rule -.PRECIOUS: %.$(1).elf - -%.$(1).elf: $$(CHS_SW_LD_DIR)/$(1).ld %.o $$(CHS_SW_LIBS) - $$(CHS_SW_CC) $$(CHS_SW_INCLUDES) -T$$< $$(CHS_SW_LDFLAGS) -o $$@ $$*.o $$(CHS_SW_LIBS) -endef - -$(foreach link,$(patsubst $(CHS_SW_LD_DIR)/%.ld,%,$(wildcard $(CHS_SW_LD_DIR)/*.ld)),$(eval $(call chim_sw_ld_elf_rule,$(link)))) - -chim-sw: $(CHIM_SW_LIB) $(CHIM_SW_TESTS) ## Compile all software tests - +##@ SoC Software (chimera-sdk) + +# The SoC software is built by the chimera-sdk submodule with its own CMake flow +# inside the toolchain container (LLVM 18.1.4-pulp + picolibc). The remaining +# bootrom bits below only serve the Snitch bootrom (hw/bootrom/snitch), which now +# includes the SystemRDL-generated headers from .generated directly (the +# hand-maintained sw/include/{regs/soc_ctrl.h,soc_addr_map.h} were removed; the +# -I.generated is added in chimera.mk). + +# --- Snitch bootrom flags --- +# SCHEREMO: use im as the smallest common denominator between CVA6 and the Snitch +# cluster; CVA6's bootrom needs imc, so override for that case. +CHS_SW_FLAGS += -falign-functions=64 -march=rv64gc_zifencei -mabi=lp64d +CHS_BROM_FLAGS += -march=rv64gc_zifencei -mabi=lp64d + +# --- chimera-sdk build configuration --- +CHIM_SDK_DIR ?= $(CHIM_SW_DIR)/deps/chimera-sdk +CHIM_SDK_BUILD_DIR ?= $(CHIM_SDK_DIR)/build +CHIM_SDK_TARGET_PLATFORM ?= chimera-open +CHIM_SDK_HW_BACKEND ?= RTL +CHIM_SDK_UNIFIED_ELF ?= ON +# Container-internal toolchain paths (provided by the image). +CHIM_SDK_TOOLCHAIN_DIR ?= /app/install/llvm-18.1.4-pulp +CHIM_SDK_PICOLIBC_DIR ?= /app/install/picolibc +# Container runner (honours CONTAINER_RUNTIME / CHIM_SDK_SIF / CHIM_SDK_IMAGE / +# CHIM_SDK_CACHE_DIR — see scripts/sdk_container.sh). +SDK_CONTAINER ?= $(CHIM_ROOT)/scripts/sdk_container.sh + +CHIM_SDK_CMAKE_ARGS = \ + -D TARGET_PLATFORM=$(CHIM_SDK_TARGET_PLATFORM) \ + -D TOOLCHAIN_DIR=$(CHIM_SDK_TOOLCHAIN_DIR) \ + -D PICOLIBC_DIR=$(CHIM_SDK_PICOLIBC_DIR) \ + -D HARDWARE_BACKEND=$(CHIM_SDK_HW_BACKEND) \ + -D CHIMERA_UNIFIED_ELF=$(CHIM_SDK_UNIFIED_ELF) + +.PHONY: chim-sw chim-sw-init chim-sw-configure chim-sw-build chim-sw-shell chim-sw-clean + +chim-sw-init: ## Init/update the chimera-sdk submodule (recursive) + git -C $(CHIM_ROOT) submodule update --init --recursive $(CHIM_SDK_DIR) + +chim-sw-configure: ## Configure the SoC software (chimera-sdk, CMake) in the container + $(SDK_CONTAINER) "cmake $(CHIM_SDK_CMAKE_ARGS) -B build" + +chim-sw-build: ## Build the SoC software (chimera-sdk) in the container + $(SDK_CONTAINER) "cmake --build build -j" + +chim-sw: chim-sw-configure chim-sw-build ## Configure + build the SoC software (chimera-sdk) + +chim-sw-shell: ## Open an interactive shell in the toolchain container + $(SDK_CONTAINER) + +chim-sw-clean: ## Remove the chimera-sdk build directory + rm -rf $(CHIM_SDK_BUILD_DIR) + +##@ Testing (ctest + pytest) + +# The SDK is configured with TEST_MODE=simulation and the chimera-top RTL sim as +# the SoC model (scripts/sim_runner.sh bridges to `make chim-run-batch`). ctest +# registers one case per test; pytest (test/) discovers and runs them with +# JUnit/HTML reporting. The SAME `make chim-test` runs locally and in CI. + +CHIM_SDK_SIM_RUNNER ?= $(CHIM_ROOT)/scripts/sim_runner.sh +CHIM_SDK_PRELOAD_MODE ?= 3 +PYTEST ?= $(CHIM_ROOT)/.venv/bin/python -m pytest + +# Per-test wall-clock timeout (seconds), enforced in sim_runner.sh. Exported so it +# reaches the runner through the pytest -> ctest layers. Override: make chim-test SIM_TIMEOUT=300 +SIM_TIMEOUT ?= 60 +export SIM_TIMEOUT + +CHIM_SDK_SIM_CMAKE_ARGS = $(CHIM_SDK_CMAKE_ARGS) \ + -D TEST_MODE=simulation \ + -D SOC_MODEL_BINARY=$(CHIM_SDK_SIM_RUNNER) \ + -D PRELOAD_MODE=$(CHIM_SDK_PRELOAD_MODE) + +# VERBOSE=1 -> per-test status (-v), no capture (-s), live vsim streaming. +# JOBS= -> run that many sims in parallel via pytest-xdist. +CHIM_TEST_FLAGS := $(PYTEST_EXTRA) +ifeq ($(VERBOSE),1) +CHIM_TEST_FLAGS += -v -s --sim-verbose +endif +ifdef JOBS +CHIM_TEST_FLAGS += -n $(JOBS) +endif + +.PHONY: chim-test-configure chim-test chim-test-ctest + +chim-test-configure: ## Configure chimera-sdk for RTL-sim testing (registers ctest cases) + $(SDK_CONTAINER) "cmake $(CHIM_SDK_SIM_CMAKE_ARGS) -B build" + +# Re-configure (sim mode) and rebuild before running, so the suite always +# exercises freshly-compiled ELFs (correct per-target ISA/ABI from the SDK). +chim-test: chim-test-configure chim-sw-build ## Build + run the SoC test suite (pytest); VERBOSE=1 for live output + $(PYTEST) $(CHIM_ROOT)/test \ + --build-dir $(CHIM_SDK_BUILD_DIR) $(CHIM_TEST_FLAGS) + +chim-test-ctest: ## Run the SoC test suite directly via ctest (no pytest) + ctest --test-dir $(CHIM_SDK_BUILD_DIR) --output-on-failure $(CTEST_EXTRA) + +##@ Bootrom + +# The bootrom no longer depends on the SoC software (libchimera.a was removed). .PHONY: chim-bootrom-init -chim-bootrom-init: chs-hw-init chim-sw ## Generate SoC bootrom +chim-bootrom-init: chs-hw-init ## Generate SoC bootrom make -B chs-bootrom-all CHS_XLEN=$(CHS_XLEN) CHS_SW_LD_DIR=$(CHS_SW_LD_DIR) - -chim-sw-clean: - @find sw/tests | grep ".*\.elf" | xargs -I ! rm ! - @find sw/tests | grep ".*\.dump" | xargs -I ! rm ! - @find sw/tests | grep ".*\.memh" | xargs -I ! rm ! - @find sw/lib | grep ".*\.a" | xargs -I ! rm ! - endif # chim_sw_mk diff --git a/sw/tests/testCfgBootAddr.c b/sw/tests/testCfgBootAddr.c deleted file mode 100644 index 8f6ff52e..00000000 --- a/sw/tests/testCfgBootAddr.c +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Lorenzo Leone - -#include -#include "regs/soc_ctrl.h" -#include -#include - -#define TESTVAL 0x00E0D0C0 -#define RSTVAL 0x30000000 - -int main() { - volatile uint32_t *regPtr = (volatile uint32_t *)SOC_CTRL_BASE; - uint32_t regVal = 0; - uint32_t regOffset = CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR_REG_OFFSET / 4; - - // Check if configurable boot address reset value is the expected one: 0x30000000 - regVal = *(regPtr + regOffset); - if (regVal != RSTVAL) { - return 1; - } - - // Write a TESTVAL and check the write was succesfull - *(regPtr + regOffset) = TESTVAL; - regVal = *(regPtr + regOffset); - if (regVal != TESTVAL) { - return 2; - } - - // Write the original value again and disable cluster clock gating to check correct boot - // wait 100 cycles to see boot access from, the waveforms. - *(regPtr + regOffset) = RSTVAL; - setAllClusterReset(regPtr, 0); - setAllClusterClockGating(regPtr, 0); - - for (int i = 0; i < 100; i++) { - // NOP - asm volatile("addi x0, x0, 0\n" :::); - } - - return 0; -} diff --git a/sw/tests/testCluster.c b/sw/tests/testCluster.c deleted file mode 100644 index 761e62b7..00000000 --- a/sw/tests/testCluster.c +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer -// Viviane Potocnik - -#include -#include - -#define CLUSTERMEMORYSTART CLUSTER_0_BASE -#define CLUSTERDISTANCE (CLUSTER_1_BASE - CLUSTER_0_BASE) -#define NUMCLUSTERS 5 - -#define TESTVAL 0x00E0D0C0 - -int main() { - volatile uint8_t *regPtr = (volatile uint8_t *)SOC_CTRL_BASE; - - setAllClusterReset(regPtr, 0); - setAllClusterClockGating(regPtr, 0); - - volatile int32_t *clusterMemPtr = (volatile int32_t *)CLUSTERMEMORYSTART; - volatile int32_t result; - - uint8_t ret = 0; - for (int i = 0; i < NUMCLUSTERS; i++) { - *(clusterMemPtr) = TESTVAL; - clusterMemPtr += CLUSTERDISTANCE / 4; - } - - clusterMemPtr = (volatile int32_t *)CLUSTERMEMORYSTART; - for (int i = 0; i < NUMCLUSTERS; i++) { - result = *(clusterMemPtr); - if (result == TESTVAL) { - ret += 1; - } else { - ret += 1 << (NUMCLUSTERS + i); - } - clusterMemPtr += CLUSTERDISTANCE / 4; - } - - if ((ret & ((1 << NUMCLUSTERS) - 1)) == NUMCLUSTERS) { - return 0; - } - - return ret; -} diff --git a/sw/tests/testClusterGating.c b/sw/tests/testClusterGating.c deleted file mode 100644 index bea0820e..00000000 --- a/sw/tests/testClusterGating.c +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer -// Viviane Potocnik - -#include "regs/soc_ctrl.h" -#include "soc_addr_map.h" -#include "offload.h" -#include - -int main() { - volatile uint8_t *regPtr = (volatile uint8_t *)SOC_CTRL_BASE; - - setAllClusterReset(regPtr, 0); - setClusterClockGating(regPtr, 0, 1); - setClusterClockGating(regPtr, 3, 1); - setClusterClockGating(regPtr, 4, 1); - - while (1) { - } - - return 0; -} diff --git a/sw/tests/testClusterOffload.c b/sw/tests/testClusterOffload.c deleted file mode 100644 index df444bb9..00000000 --- a/sw/tests/testClusterOffload.c +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer -// Viviane Potocnik - -// Simple offload test. Set the trap handler first, offload a function, retrieve -// return value from cluster. Does not currently take care of stack -// initialization and bss initialization on cluster. - -#include "offload.h" -#include "soc_addr_map.h" -#include -#include - -#define TESTVAL 0x050CCE55 - -static uint32_t *clintPointer = (uint32_t *)CLINT_CTRL_BASE; - -void clusterTrapHandler() { - uint8_t hartId; - asm("csrr %0, mhartid" : "=r"(hartId)::); - - volatile uint32_t *interruptTarget = clintPointer + hartId; - *interruptTarget = 0; - return; -} - -int32_t testReturn() { - return TESTVAL; -} - -int main() { - volatile uint8_t *regPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setupInterruptHandler(clusterTrapHandler); - - uint32_t retVal = 0; - for (int i = 0; i < _chimera_numClusters; i++) { - setClusterReset(regPtr, i, 0); - setClusterClockGating(regPtr, i, 0); - offloadToCluster(testReturn, i); - retVal |= waitForCluster(i); - setClusterClockGating(regPtr, i, 1); - setClusterReset(regPtr, i, 0); - } - - return (retVal != (TESTVAL | 0x000000001)); -} diff --git a/sw/tests/testHyperbusAddr.c b/sw/tests/testHyperbusAddr.c deleted file mode 100644 index d1bef52b..00000000 --- a/sw/tests/testHyperbusAddr.c +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Sergio Mazzola -// Viviane Potocnik - -// Test HyperRAM addressability through the Hyperbus peripheral - -#include -#include - -#define HYPER_BASE HYPERRAM_BASE -#define TESTVAL (uint32_t)0x1234ABCD - -int main() { - volatile uint8_t *regPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterReset(regPtr, 0); - setAllClusterClockGating(regPtr, 0); - volatile uint32_t *hyperMemPtr = (volatile uint32_t *)HYPER_BASE; - volatile uint32_t result; - - // write - *(hyperMemPtr) = TESTVAL; - // read - result = *(hyperMemPtr); - - // verify - if (result == TESTVAL) { - return 0; - } else { - return 1; - } -} diff --git a/sw/tests/testMemBypass.c b/sw/tests/testMemBypass.c deleted file mode 100644 index f6907392..00000000 --- a/sw/tests/testMemBypass.c +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Lorenzo Leone -// Viviane Potocnik - -// Test to check if clusters can access the memory island both using -// the wide interconnect and the narrow AXI. -// The following tests are executed: -// - Write and Read configuration registers for all clusters -// - Access the memory island both settin/disabling the bypass mode - -#include -#include "regs/soc_ctrl.h" -#include "offload.h" -#include "soc_addr_map.h" - -// #define TOPLEVELREGION 0x30001000 -#define NUMCLUSTERS 5 -#define TESTNARROW 0x050CCE55 -#define TESTWIDE 0x060CCE55 - -static uint32_t *clintPointer = (uint32_t *)CLINT_CTRL_BASE; - -void clusterTrapHandler() { - uint8_t hartId; - asm("csrr %0, mhartid" : "=r"(hartId)::); - - volatile uint32_t *interruptTarget = clintPointer + hartId; - *interruptTarget = 0; - return; -} - -int32_t returnPtr(uint32_t ClstIdx) { - int32_t regPtr; - - if (ClstIdx == 0) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_REG_OFFSET); - } else if (ClstIdx == 1) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_REG_OFFSET); - } else if (ClstIdx == 2) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_REG_OFFSET); - } else if (ClstIdx == 3) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_REG_OFFSET); - } else if (ClstIdx == 4) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_REG_OFFSET); - } - return regPtr; -} - -// Align function to make sure consecutive calls need to be fetched -int32_t __attribute__((aligned(32))) testMemNarrow() { - return TESTNARROW; -} - -int32_t __attribute__((aligned(32))) testMemWide() { - return TESTWIDE; -} - -int main() { - volatile uint8_t *clockGatingRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - volatile uint8_t *resetRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterReset(resetRegPtr, 0); - setAllClusterClockGating(clockGatingRegPtr, 0); - - volatile int32_t *regPtr = 0; - - uint32_t retVal = 0; - - // Tes for each cluster - for (int ClstIdx = 0; ClstIdx < NUMCLUSTERS; ClstIdx++) { - - regPtr = (volatile int32_t *)returnPtr(ClstIdx); - - /* TEST RESET VALUE */ - if (*regPtr != 0) { - return 1; - } - - /* TEST WRITABILITY */ - *regPtr = 1; - if (*regPtr != 1) { - return 2; - } - } - - /* Offload Cluster 1 and Test NARROW PATH */ - regPtr = (volatile int32_t *)returnPtr(1); - *regPtr = 1; - setupInterruptHandler(clusterTrapHandler); - offloadToCluster(testMemNarrow, 0); - retVal = waitForCluster(0); - - if (retVal != TESTNARROW) { - return 3; - } - - /* Offload Cluster 2 and Test WIDE PATH */ - regPtr = (volatile int32_t *)returnPtr(2); - *regPtr = 0; - setupInterruptHandler(clusterTrapHandler); - offloadToCluster(testMemWide, 1); - retVal = waitForCluster(1); - - if (retVal != TESTWIDE) { - return 4; - } - - return 0; -} diff --git a/sw/tests/testPeripheralsGating.c b/sw/tests/testPeripheralsGating.c deleted file mode 100644 index 49858a4d..00000000 --- a/sw/tests/testPeripheralsGating.c +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Lorenzo Leone -// Viviane Potocnik - -// This test aims to check if the clock gating registers -// inside Cheshire can be correctly driven from Chimera. -// The test is not automated; each peripheral's clock -// signal must be manually checked by looking at the waveforms. - -#include -#include "offload.h" -#include "regs/cheshire.h" -#include "soc_addr_map.h" - -#define CHESHIRE_REGS_BASE 0x03000000 - -int main() { - volatile uint8_t *clockGatingRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - volatile uint8_t *resetRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterReset(resetRegPtr, 0); - setAllClusterClockGating(clockGatingRegPtr, 0); - - volatile uint32_t *regPtr = 0; - uint8_t expVal; - - regPtr = - (volatile uint32_t *)(CHESHIRE_REGS_BASE + CHESHIRE_CLK_GATE_EN_PERIPHERALS_REG_OFFSET); - - // |------------------------------| - // | READ RST VALUE | - // |------------------------------| - if (*regPtr != 0) return 1; - - // |------------------------------| - // | ENABLE CLK GATE | - // |------------------------------| - expVal = 0x00007F; - *regPtr |= expVal; - if (*regPtr ^ expVal) return 2; - - // |------------------------------| - // | DISABLE CLK GATE | - // |------------------------------| - expVal = 0x0000; - *regPtr &= expVal; - if (*regPtr ^ expVal) return 3; - - return 0; -} diff --git a/sw/tests/testReturnZero.c b/sw/tests/testReturnZero.c deleted file mode 100644 index e95677e4..00000000 --- a/sw/tests/testReturnZero.c +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Viviane Potocnik - -#include -#include - -int main() { - volatile uint8_t *clockGatingRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterClockGating(clockGatingRegPtr, 0); - - return 0; -} \ No newline at end of file diff --git a/target/sim/sim.mk b/target/sim/sim.mk index efd3e739..e5e2d52d 100644 --- a/target/sim/sim.mk +++ b/target/sim/sim.mk @@ -13,6 +13,10 @@ CHIM_SIM_DIR ?= $(CHIM_ROOT)/target/sim VSIM_DIR ?= $(CHIM_ROOT)/target/sim/vsim VSIM ?= vsim VSIM_WORK ?= $(VSIM_DIR)/work +# Directory the simulation runs in; all per-run artifacts (trace_hart_*, dma_trace_*, +# transcript, modelsim.ini) are written to the cwd, so isolate them here. Defaults to +# the repo root (unchanged behaviour); sim_runner.sh overrides it per test. +RUN_DIR ?= $(CHIM_ROOT) CHIM_HYPERBUS_SDF_PATH ?= ./target/sim/models/s27ks0641/s27ks0641.sdf CHIM_VLOG_ARGS += -work $(VSIM_WORK) @@ -28,7 +32,15 @@ CHIM_VLOG_ARGS += +define+PATH_TO_HYP_SDF=\"$(CHIM_HYPERBUS_SDF_PATH)\" VSIM_FLAGS_GUI = -voptargs=+acc -override VSIM_FLAGS += -work $(VSIM_WORK) +# Pre-optimized design for PARALLEL-safe batch runs. `vsim ` re-optimizes on +# every invocation and takes an *exclusive* lock on the work library, so parallel +# runs serialize on work/_lock (and time out). Optimizing once into a snapshot lets +# many `vsim ` open it read-only concurrently. +VOPT ?= vopt +CHIM_OPT_TOP ?= $(TB_DUT)_opt +VOPT_ARGS += -work $(VSIM_WORK) -modelsimini $(CHIM_ROOT)/modelsim.ini + +override VSIM_FLAGS += -work $(VSIM_WORK) -suppress 8386 # Set testbech parameters define add_vsim_flag @@ -44,11 +56,11 @@ $(eval $(call add_vsim_flag,PRELMODE)) $(eval $(call add_vsim_flag,IMAGE)) # Init vsim compilation -.PHONY: chim-sim chim-compile chim-run chim-run-batch -chim-sim: chim-hyperram-model chs-sim-all chim-compile ## Compile Chimera SoC +.PHONY: chim-sim chim-compile chim-opt chim-run chim-run-batch +chim-sim: chim-hyperram-model chs-sim-all chim-compile chim-opt ## Compile Chimera SoC -.PHONY: chim-hyperram-model ## Get HypperRAM VIP for simulation -chim-hyperram-model: $(CHIM_SIM_DIR)/models/s27ks0641/s27ks0641.sv +.PHONY: chim-hyperram-model +chim-hyperram-model: $(CHIM_SIM_DIR)/models/s27ks0641/s27ks0641.sv ## Get HypperRAM VIP for simulation $(CHIM_SIM_DIR)/models/s27ks0641/s27ks0641.sv: make -C $(HYPERB_ROOT) models/s27ks0641 mkdir -p $(dir $@) @@ -68,13 +80,19 @@ $(CHIM_SIM_DIR)/vsim/compile.tcl: $(BENDER_YML) $(BENDER_LOCK) chim-compile: $(CHIM_SIM_DIR)/vsim/compile.tcl $(CHIM_HW_ALL) $(VSIM) -c $(VSIM_FLAGS) -do "source $<; quit" +# Optimize once into a read-only snapshot so batch runs can execute in parallel. +chim-opt: ## Optimize the compiled design into a parallel-safe snapshot ($(CHIM_OPT_TOP)) + $(VOPT) $(VOPT_ARGS) $(TB_DUT) -o $(CHIM_OPT_TOP) + # Run simulation with GUI chim-run: ## Run simulation with GUI - $(VSIM) $(VSIM_FLAGS) $(VSIM_FLAGS_GUI) $(TB_DUT) -do "log -r /*" + mkdir -p $(RUN_DIR) + cd $(RUN_DIR) && $(VSIM) $(VSIM_FLAGS) $(VSIM_FLAGS_GUI) -modelsimini $(CHIM_ROOT)/modelsim.ini $(TB_DUT) -do "log -r /*" # Run simulation in batch mode -chim-run-batch: ## Run simulation in command line mode - $(VSIM) -c $(VSIM_FLAGS) $(TB_DUT) -do "run -all; quit" +chim-run-batch: ## Run simulation in command line mode (read-only opt snapshot; parallel-safe) + mkdir -p $(RUN_DIR) + cd $(RUN_DIR) && $(VSIM) -c $(VSIM_FLAGS) -modelsimini $(CHIM_ROOT)/modelsim.ini $(CHIM_OPT_TOP) -do "run -all; quit" # Clean diff --git a/target/sim/src/tb_chimera_soc.sv b/target/sim/src/tb_chimera_soc.sv index 3ca6d760..64cb3363 100644 --- a/target/sim/src/tb_chimera_soc.sv +++ b/target/sim/src/tb_chimera_soc.sv @@ -41,7 +41,7 @@ module tb_chimera_soc force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_req_i[1] = 1'b1; force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_we_i[1] = 1'b1; force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_wdata_i[1] = write_data; - force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_strb_i[1] = 4'hf; + force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_strb_i[1] = 8'hff; force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_gnt_o[1] = 1'b0; force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_rvalid_o[1] = 1'b0; endtask @@ -58,18 +58,19 @@ module tb_chimera_soc $display("[FAST PRELOAD] Preloading section at 0x%h (%0d bytes)", sec_addr, sec_len); if (read_section(sec_addr, bf, sec_len)) $fatal(1, "[FAST PRELOAD] Failed to read ELF section!"); - @(posedge fix.vip.soc_clk); // + @(posedge fix.vip.soc_clk); // for (longint i = 0; i <= sec_len; i += riscv::XLEN / 8) begin bit checkpoint = (i != 0 && i % 512 == 0); - if (checkpoint) + //if (checkpoint) $display( - "[FAST PRELOAD] - %0d/%0d bytes (%0d%%)", + "%0t ns [FAST PRELOAD] - %0d/%0d bytes (%0d%%)", + $time, i, sec_len, i * 100 / (sec_len > 1 ? sec_len - 1 : 1) ); @(posedge fix.vip.soc_clk); - force_write((sec_addr + i), {bf[i+3], bf[i+2], bf[i+1], bf[i]}); + force_write((sec_addr + i), {bf[i+7], bf[i+6], bf[i+5], bf[i+4], bf[i+3], bf[i+2], bf[i+1], bf[i]}); end end @(posedge fix.vip.soc_clk); @@ -112,7 +113,7 @@ module tb_chimera_soc fix.vip.uart_debug_elf_run_and_wait(preload_elf, exit_code); end 3: begin // FAST DEBUG - // Initialize JTAG + // Initialize JTAG fix.vip.jtag_init(); // Halt the core fix.vip.jtag_halt_hart(); diff --git a/target/sim/src/vip_chimera_soc.sv b/target/sim/src/vip_chimera_soc.sv index 2d64ae76..daac019d 100644 --- a/target/sim/src/vip_chimera_soc.sv +++ b/target/sim/src/vip_chimera_soc.sv @@ -368,7 +368,7 @@ module vip_chimera_soc // Wait for termination signal and get return code task automatic jtag_wait_for_eoc(output word_bt exit_code); - jtag_poll_bit0(AmRegs + cheshire_reg_pkg::CHESHIRE_SCRATCH_2_OFFSET, exit_code, 4000); + jtag_poll_bit0(cheshire_addrmap_pkg::REGS_SCRATCH_BASE_ADDR(2), exit_code, 4000); exit_code >>= 1; if (exit_code) $error("[JTAG] FAILED: return code %0d", exit_code); else $display("[JTAG] SUCCESS"); diff --git a/target/sim/vsim/run.tcl b/target/sim/vsim/run.tcl deleted file mode 100644 index 7402f67e..00000000 --- a/target/sim/vsim/run.tcl +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2026 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# Philip wiese - -source setup.chimera_soc.tcl -source compile.tcl -source start.chimera_soc.tcl -do wave/waves.tcl -run -a \ No newline at end of file diff --git a/target/sim/vsim/setup.chimera_soc.tcl b/target/sim/vsim/setup.chimera_soc.tcl deleted file mode 100644 index 08765876..00000000 --- a/target/sim/vsim/setup.chimera_soc.tcl +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2024 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# Moritz Scherer - -set BINARY ../../../sw/tests/testCluster.memisl.elf -set SELCFG 0 diff --git a/target/sim/vsim/start.chimera_soc.tcl b/target/sim/vsim/start.chimera_soc.tcl deleted file mode 100644 index 39e5dc34..00000000 --- a/target/sim/vsim/start.chimera_soc.tcl +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2022 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# Nicole Narr -# Christopher Reinwardt -# Alessandro Ottaviano -# Paul Scheffler - -set TESTBENCH tb_chimera_soc - -# Set voptargs only if not already set to make overridable. -# Default on fast simulation flags. -if {![info exists VOPTARGS]} { - set VOPTARGS "+acc" -} - -if {![info exists DEBUG] || ($DEBUG == 0)} { - set debug "" -} else { - set debug "-do \"log -r /*;\"" -} - - -set flags "-permissive -suppress 3009 -suppress 8386 -error 7 " -if {[info exists SELCFG]} { append flags "-gSelectedCfg=${SELCFG} " } - -set pargs "" -if {[info exists BOOTMODE]} { append pargs "+BOOTMODE=${BOOTMODE} " } -if {[info exists PRELMODE]} { append pargs "+PRELMODE=${PRELMODE} " } -if {[info exists BINARY]} { append pargs "+BINARY=${BINARY} " } -if {[info exists IMAGE]} { append pargs "+IMAGE=${IMAGE} " } - -if {[catch { - eval "vsim -c ${TESTBENCH} -t 1ps -vopt -voptargs=\"${VOPTARGS}\"" ${pargs} ${flags} ${debug} -}]} {return 1} - -set StdArithNoWarnings 1 -set NumericStdNoWarnings 1 diff --git a/target/sim/vsim/wave/waves.tcl b/target/sim/vsim/wave/waves.tcl index 26c13ef5..d8a00088 100644 --- a/target/sim/vsim/wave/waves.tcl +++ b/target/sim/vsim/wave/waves.tcl @@ -49,6 +49,10 @@ add wave -noupdate -expand -group {Global} {/tb_chimera_soc/fix/dut/uart_rx_i} add wave -noupdate -expand -group {CVA6} {/tb_chimera_soc/fix/dut/i_cheshire/gen_cva6_cores[0]/i_core_cva6/hart_id_i} add wave -noupdate -expand -group {CVA6} {/tb_chimera_soc/fix/dut/i_cheshire/gen_cva6_cores[0]/i_core_cva6/pc_commit} +add wave -noupdate -expand -group {CVA6} {/tb_chimera_soc/fix/dut/i_cheshire/intr_routed} +add wave -noupdate -expand -group {CVA6} {/tb_chimera_soc/fix/dut/i_cheshire/intr} +add wave -noupdate -expand -group {CVA6} {/tb_chimera_soc/fix/dut/i_cheshire/msip} +add wave -noupdate -expand -group {CVA6} {/tb_chimera_soc/fix/dut/i_cheshire/mtip} add wave -noupdate -expand -group {Cluster Register} {tb_chimera_soc/fix/dut/i_reg_top/reg2hw} diff --git a/test/conftest.py b/test/conftest.py new file mode 100644 index 00000000..864df45f --- /dev/null +++ b/test/conftest.py @@ -0,0 +1,103 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +"""pytest front-end for the Chimera SoC test suite. + +The chimera-sdk build (``TEST_MODE=simulation``) registers one ctest case per +enabled test, each of which runs the unified ELF in the chimera-top RTL +testbench via ``scripts/sim_runner.sh`` (the SoC model binary). This front-end +discovers those ctest cases and runs each as a pytest case, so the *same* +command runs locally and in CI, with JUnit/HTML reporting on top. + +Discovery is done with ``ctest --show-only=json-v1`` so pytest and ctest never +drift out of sync. +""" + +import json +import shutil +import subprocess +from pathlib import Path + +import pytest + +CHIM_ROOT = Path(__file__).resolve().parent.parent +DEFAULT_BUILD_DIR = CHIM_ROOT / "sw" / "deps" / "chimera-sdk" / "build" + +# Per-test sim-timeout overrides (seconds). Tests not listed use --sim-timeout. +# Some cluster tests are legitimately slow in RTL simulation (a single global +# timeout can't fit both a ~30s host test and a multi-minute cluster test). +SIM_TIMEOUT_OVERRIDES = { + "test_host_uartSimple": 1800, + "test_snitchCluster_snrt": 3600, # host-forwarded syscall printf: slowest test in RTL + "test_snitchCluster_matmul": 1800, # compute kernel + "test_snitchCluster_offloadAll": 1800, # offloading all clusters +} + + +def pytest_addoption(parser): + parser.addoption( + "--build-dir", + action="store", + default=str(DEFAULT_BUILD_DIR), + help="chimera-sdk CMake build directory configured with TEST_MODE=simulation", + ) + parser.addoption( + "--sim-verbose", + action="store_true", + default=False, + help="Stream ctest/vsim output live instead of capturing it (use with -s).", + ) + parser.addoption( + "--sim-timeout", + action="store", + type=int, + default=300, + help="Default per-test sim timeout (s); per-test overrides in SIM_TIMEOUT_OVERRIDES.", + ) + + +@pytest.fixture +def sim_timeout(request): + """Resolved per-test sim timeout in seconds (override map, else --sim-timeout).""" + name = request.getfixturevalue("soc_test") + return SIM_TIMEOUT_OVERRIDES.get(name, request.config.getoption("--sim-timeout")) + + +def _discover_ctest_tests(build_dir: str): + """Return the list of ctest test names registered in build_dir (or []).""" + if shutil.which("ctest") is None or not Path(build_dir).is_dir(): + return [] + try: + out = subprocess.run( + ["ctest", "--test-dir", build_dir, "--show-only=json-v1"], + capture_output=True, text=True, check=True, + ) + data = json.loads(out.stdout) + return [t["name"] for t in data.get("tests", [])] + except (subprocess.CalledProcessError, json.JSONDecodeError): + return [] + + +def _test_markers(name): + """host/cluster marks so `pytest -m host` / `pytest -m cluster` select subsets.""" + if "snitchCluster" in name: + return [pytest.mark.cluster] + if "host" in name: + return [pytest.mark.host] + return [] + + +def pytest_generate_tests(metafunc): + """Parametrize `soc_test` over the ctest cases discovered in the build dir.""" + if "soc_test" not in metafunc.fixturenames: + return + build_dir = metafunc.config.getoption("--build-dir") + tests = _discover_ctest_tests(build_dir) + if not tests: + pytest.skip( + f"No ctest cases in {build_dir}. Build the SDK with TEST_MODE=simulation " + f"first (make chim-sdk-test-configure)." + ) + params = [pytest.param(t, marks=_test_markers(t)) for t in tests] + metafunc.parametrize("soc_test", params, ids=tests) diff --git a/test/test_soc.py b/test/test_soc.py new file mode 100644 index 00000000..1855ac8e --- /dev/null +++ b/test/test_soc.py @@ -0,0 +1,36 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +"""Run every chimera-sdk simulation test through ctest and report pass/fail. + +Each `soc_test` is a ctest case name (see conftest.py). We invoke ctest for that +single case; ctest runs the SoC model (scripts/sim_runner.sh) on the test's +unified ELF, which drives the RTL testbench and returns 0 only if the testbench +printed SUCCESS with no errors. +""" + +import os +import subprocess + + +def test_soc_simulation(soc_test, sim_timeout, request): + build_dir = request.config.getoption("--build-dir") + cmd = ["ctest", "--test-dir", build_dir, "-R", f"^{soc_test}$", + "--output-on-failure", "-V"] + + # Per-test wall-clock timeout, enforced by sim_runner.sh via $SIM_TIMEOUT. + env = os.environ.copy() + env["SIM_TIMEOUT"] = str(sim_timeout) + + if request.config.getoption("--sim-verbose"): + # Inherit stdout/stderr so ctest/vsim output streams live (needs `-s`). + result = subprocess.run(cmd, env=env) + else: + result = subprocess.run(cmd, env=env, capture_output=True, text=True) + # Surface the sim/transcript output in the pytest report (on failure). + print(result.stdout) + if result.stderr: + print(result.stderr) + + assert result.returncode == 0, f"{soc_test} failed in RTL simulation" diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..7553d1af --- /dev/null +++ b/uv.lock @@ -0,0 +1,794 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" + +[[package]] +name = "antlr4-python3-runtime" +version = "4.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/5f/2cdf6f7aca3b20d3f316e9f505292e1f256a32089bd702034c29ebde6242/antlr4_python3_runtime-4.13.2.tar.gz", hash = "sha256:909b647e1d2fc2b70180ac586df3933e38919c85f98ccc656a96cd3f25ef3916", size = 117467, upload-time = "2024-08-03T19:00:12.757Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/03/a851e84fcbb85214dc637b6378121ef9a0dd61b4c65264675d8a5c9b1ae7/antlr4_python3_runtime-4.13.2-py3-none-any.whl", hash = "sha256:fe3835eb8d33daece0e799090eda89719dbccee7aa39ef94eed3818cafa5a7e8", size = 144462, upload-time = "2024-08-03T19:00:11.134Z" }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "chimera" +version = "1.0.0" +source = { editable = "." } +dependencies = [ + { name = "flatdict" }, + { name = "hjson" }, + { name = "json5" }, + { name = "jsonref" }, + { name = "jsonschema" }, + { name = "mako" }, + { name = "peakrdl" }, + { name = "peakrdl-markdown" }, + { name = "peakrdl-rawheader" }, + { name = "pyyaml" }, + { name = "setuptools" }, + { name = "tabulate" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, + { name = "pytest-html" }, + { name = "pytest-xdist" }, +] + +[package.metadata] +requires-dist = [ + { name = "flatdict" }, + { name = "hjson" }, + { name = "json5" }, + { name = "jsonref" }, + { name = "jsonschema" }, + { name = "mako" }, + { name = "peakrdl" }, + { name = "peakrdl-markdown" }, + { name = "peakrdl-rawheader" }, + { name = "pyyaml" }, + { name = "setuptools", specifier = "<81" }, + { name = "tabulate" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "pytest" }, + { name = "pytest-html" }, + { name = "pytest-xdist" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "execnet" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, +] + +[[package]] +name = "flatdict" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/ba/e0461697020839f60741e493fc42b20a4cd3f91594ed3228f65ae9a50aee/flatdict-4.1.0.tar.gz", hash = "sha256:63bcd906a0859d91d0aace44b327178706c7fcf85a88c7ccf0825628376ad66b", size = 33930, upload-time = "2026-02-15T19:00:27.175Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b5/6b6c496304047982b67d984ed2f77c183f73d69f7dbbc0cd2928252cc6b4/flatdict-4.1.0-py3-none-any.whl", hash = "sha256:24c3ff816733e472f91071031bd286c3826ecf2d646d5020af49fe10b20a5677", size = 7248, upload-time = "2026-02-15T19:00:26.131Z" }, +] + +[[package]] +name = "git-me-the-url" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitpython" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/36/e58975894d84387432ca9c5f221d4f05f1f07296c5488c1115a964bdef62/git_me_the_url-2.2.0.tar.gz", hash = "sha256:fc000b2c67171f45da263760a75dbce21a08aeb428ee5021cd8ab29330297dc3", size = 423769, upload-time = "2025-11-21T03:15:50.167Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/a8/16ff25e716248b4433a81c429a51996eb2c263199c1777ea1d5424b5c673/git_me_the_url-2.2.0-py3-none-any.whl", hash = "sha256:bd759ddde7d21ebe1d85558f00d6822b74b7e5907adcaeb9fc4d72203a34264b", size = 12945, upload-time = "2025-11-21T03:15:48.831Z" }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, +] + +[[package]] +name = "gitpython" +version = "3.1.50" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/f6/354ae6491228b5eb40e10d89c4d13c651fe1cf7556e35ebdded50cff57ce/gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc", size = 219798, upload-time = "2026-05-06T04:01:26.571Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9", size = 212507, upload-time = "2026-05-06T04:01:23.799Z" }, +] + +[[package]] +name = "hjson" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/e5/0b56d723a76ca67abadbf7fb71609fb0ea7e6926e94fcca6c65a85b36a0e/hjson-3.1.0.tar.gz", hash = "sha256:55af475a27cf83a7969c808399d7bccdec8fb836a07ddbd574587593b9cdcf75", size = 40541, upload-time = "2022-08-13T02:53:01.919Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/7f/13cd798d180af4bf4c0ceddeefba2b864a63c71645abc0308b768d67bb81/hjson-3.1.0-py3-none-any.whl", hash = "sha256:65713cdcf13214fb554eb8b4ef803419733f4f5e551047c9b711098ab7186b89", size = 54018, upload-time = "2022-08-13T02:52:59.899Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "json5" +version = "0.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/7d/05c46a96a78147ae3bf99c2f4169ce144a70220b8d6fcd56f6ec368b8ce9/json5-0.15.0.tar.gz", hash = "sha256:7424d1f1eb1d56da6e3d70643f53619862b4ce81440bdb8ecfd6f875e5ba4a71", size = 53278, upload-time = "2026-06-19T20:08:27.716Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/be/59527c99478aade6bb33a68d72e6e18dd4e6ff6eacfc7d01bdb15bc76912/json5-0.15.0-py3-none-any.whl", hash = "sha256:56636a30c0e8a4665fe2179c0212f32eae3796dea89ea6f649b9436ecdb39618", size = 36570, upload-time = "2026-06-19T20:08:26.748Z" }, +] + +[[package]] +name = "jsonref" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/0d/c1f3277e90ccdb50d33ed5ba1ec5b3f0a242ed8c1b1a85d3afeb68464dca/jsonref-1.1.0.tar.gz", hash = "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552", size = 8814, upload-time = "2023-01-16T16:10:04.455Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/ec/e1db9922bceb168197a558a2b8c03a7963f1afe93517ddd3cf99f202f996/jsonref-1.1.0-py3-none-any.whl", hash = "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9", size = 9425, upload-time = "2023-01-16T16:10:02.255Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "mako" +version = "1.3.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/62/791b31e69ae182791ec67f04850f2f062716bbd205483d63a215f3e062d3/mako-1.3.12.tar.gz", hash = "sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a", size = 400219, upload-time = "2026-04-28T19:01:08.512Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/b1/a0ec7a5a9db730a08daef1fdfb8090435b82465abbf758a596f0ea88727e/mako-1.3.12-py3-none-any.whl", hash = "sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9", size = 78521, upload-time = "2026-04-28T19:01:10.393Z" }, +] + +[[package]] +name = "markdown" +version = "3.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2b/f4/69fa6ed85ae003c2378ffa8f6d2e3234662abd02c10d216c0ba96081a238/markdown-3.10.2.tar.gz", hash = "sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950", size = 368805, upload-time = "2026-02-09T14:57:26.942Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl", hash = "sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36", size = 108180, upload-time = "2026-02-09T14:57:25.787Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "peakrdl" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "peakrdl-cheader" }, + { name = "peakrdl-cli" }, + { name = "peakrdl-html" }, + { name = "peakrdl-ipxact" }, + { name = "peakrdl-regblock" }, + { name = "peakrdl-systemrdl" }, + { name = "peakrdl-uvm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/dd/c329e3f50e0129180d2b6dffcf13e3140277ab2e929ab774d91ea84ae85c/peakrdl-1.5.0.tar.gz", hash = "sha256:7aa5abce889fd75083f860727bbf69aacb969ec3d204250e808576237ced0dec", size = 5052, upload-time = "2025-10-03T04:17:09.521Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/2a/1d7c2cf934e779caeddb72b7f22f74a86ad815a1cb48bdfa46c7b3af6110/peakrdl-1.5.0-py3-none-any.whl", hash = "sha256:819ae8fb445969d125329c9b6fc1c164a1e9bef02f0594698db5bce2aa0a0277", size = 5186, upload-time = "2025-10-03T04:17:08.255Z" }, +] + +[[package]] +name = "peakrdl-cheader" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/eb/0029f029510523277d2aea7c6a7b86f4c6a14da092c06700434d191483be/peakrdl_cheader-1.1.0.tar.gz", hash = "sha256:2e1593d68ca96608eb0b29ae3efbd5abca961050984d4ee1e4a65998237cd58b", size = 30518, upload-time = "2026-03-28T02:57:52.734Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/a4/112cc4f9c80c7c1373e38e33172d8219bf4db360b915dd856e2fb31a0cec/peakrdl_cheader-1.1.0-py3-none-any.whl", hash = "sha256:72bc5af33a0a353eacc88fd35e271a9f008176b758fdb0c7cfbff1f5144c42af", size = 19765, upload-time = "2026-03-28T02:57:51.268Z" }, +] + +[[package]] +name = "peakrdl-cli" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/c8/85baad7853c8995407ce04e98aaff713bc0d82de1f38721679f033c53d0b/peakrdl_cli-1.5.0.tar.gz", hash = "sha256:fb11961bc4d5636239e02b3392072025e7310afaceba34d834adbb279c770f65", size = 17559, upload-time = "2025-10-03T04:17:04.251Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/0d/8b3023ad5fe1b8fdaeb15a8a1f54dc9de384e398ebd374e234f783b4c100/peakrdl_cli-1.5.0-py3-none-any.whl", hash = "sha256:e6d86a41f8e8cdf09021e0abfdad604f6213f8d3aaf7ea6579ccbb6f047c81ca", size = 22772, upload-time = "2025-10-03T04:17:02.821Z" }, +] + +[[package]] +name = "peakrdl-html" +version = "2.12.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "git-me-the-url" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "python-markdown-math" }, + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/0a/069fd914b588ef1d9dbc89031d962293fa2b9255c3b1104f9de9f0891320/peakrdl_html-2.12.2.tar.gz", hash = "sha256:7be4b92dead8d296d714da5d25e71249ebf488bccdd255ed7581f32dd3a99546", size = 11255605, upload-time = "2026-03-06T04:57:29.273Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/32/8bb83251ca56366af0fcea102331b337e87b2baeca81ade16942357e172f/peakrdl_html-2.12.2-py3-none-any.whl", hash = "sha256:1b74a43579900b48fb6ebf0468b91c50d2256828d1f9751da8bfeb2f0883710c", size = 5582847, upload-time = "2026-03-06T04:57:26.857Z" }, +] + +[[package]] +name = "peakrdl-ipxact" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/f6/af8f79d853081ce9258c60863606291ad5aab9e12eccd050f2e3e8a3a051/peakrdl_ipxact-3.5.0.tar.gz", hash = "sha256:183b9e5412cad7734c25c710ca3722f75f8776b8c20ed38c1d4b83ac409d92d8", size = 71628, upload-time = "2024-10-15T04:45:01.901Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/81/778784087d63d004d8db431212153e635d89bd43fd05f61391090211d6f5/peakrdl_ipxact-3.5.0-py3-none-any.whl", hash = "sha256:930460f2b95cf5be52d7fadad416f040b68defbc17c372a58c581ee7195be364", size = 40804, upload-time = "2024-10-15T04:45:00.346Z" }, +] + +[[package]] +name = "peakrdl-markdown" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "peakrdl-cli" }, + { name = "py-markdown-table" }, + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/9f/c49e2872706ba4de2178b4965d8dc2c26ca9258b37ff1fee94ce35e17879/peakrdl_markdown-1.0.3.tar.gz", hash = "sha256:1647f42fcb6fc87da1ee6242c76a0eb0b7d0088839c21ebfdf72214f34ab6347", size = 17445, upload-time = "2025-11-13T17:15:57.118Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/f4/20ca21c0cd8f772c0ee71b35a2992962b6520980822841550bff681c036e/peakrdl_markdown-1.0.3-py3-none-any.whl", hash = "sha256:a528829b36f121b85081f0442bf4a9bb9567a9fdce263a11081ba7bd502a342e", size = 18856, upload-time = "2025-11-13T17:15:56.225Z" }, +] + +[[package]] +name = "peakrdl-rawheader" +version = "0.2.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mako" }, + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/83/26dbb3d17400f03d1dea16144070bae4774edb5d32c7b8e0d94261676f2c/peakrdl_rawheader-0.2.6.tar.gz", hash = "sha256:404a0b8c34f1b383c505ac12c35609b8ff72dc4c4e3c807b470d14a85f80a270", size = 10921, upload-time = "2026-07-06T10:11:06.068Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/5c/d18fa5c51957a5de47e13e780b2af5ce79fb34b189508280bcac9d71fa42/peakrdl_rawheader-0.2.6-py3-none-any.whl", hash = "sha256:4c01d841e86fc1d90926134b58c13d223afd3807298dc548e90f98ee7c3026ab", size = 14085, upload-time = "2026-07-06T10:11:05.014Z" }, +] + +[[package]] +name = "peakrdl-regblock" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/d1/f6488f1d3ac8b3cfa7120ed9e8c586193c8372f2336ee8e94d8559261da0/peakrdl_regblock-1.3.1.tar.gz", hash = "sha256:d72803e62ff0c0feb2c17a51263e39cdee14ec6bf5dc8a7100e8a93f63306a07", size = 555526, upload-time = "2026-03-28T03:05:09.748Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/69/c35c9a4d2d461a839e9041c763fcfe6294f5399e13dc554c60ecbea67e34/peakrdl_regblock-1.3.1-py3-none-any.whl", hash = "sha256:d769306d834dea3dbd02cdd976f694d2009ef33dbb72bcfadc344b7de6cfb492", size = 83185, upload-time = "2026-03-28T03:05:08.144Z" }, +] + +[[package]] +name = "peakrdl-systemrdl" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/3e/bc15ce1445c7b80717d4babc6d1de92f857e1ff00cd8eefeb9505c9c19f2/peakrdl_systemrdl-1.0.1.tar.gz", hash = "sha256:77fe097d01d252b365f9d603e2712a85b3cf65f32c7ad52aadd1a8dea9635a5e", size = 16359, upload-time = "2025-11-07T03:30:55.24Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/b0/1ac2934d117e3e8cb59afc7f658b1dc5b2a34ede0718952ab6993990b5ca/peakrdl_systemrdl-1.0.1-py3-none-any.whl", hash = "sha256:17d72641ade637e5650a20589977a3452316ecb630f500907f4c579c0a8f7ebd", size = 10208, upload-time = "2025-11-07T03:30:53.546Z" }, +] + +[[package]] +name = "peakrdl-uvm" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/d4/de4c1e44ba589aaae7fa230266516ba67608e7dca425ccf3a7b21bb062ab/peakrdl_uvm-2.4.0.tar.gz", hash = "sha256:bebbec7ea84c76137e3e61442565d1de9a225eaf01774c65de3d10dd7096ad78", size = 15293, upload-time = "2025-11-25T01:59:54.771Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/f0/cc6f81291ce62422ca6b73efe2e032d86689dadd91a04356e199f0b915e1/peakrdl_uvm-2.4.0-py3-none-any.whl", hash = "sha256:2ec87aaac25f6597a0a0b173edae8cd81d1dd05957591013f1e6b93957de0d87", size = 16945, upload-time = "2025-11-25T01:59:53.029Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "py-markdown-table" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dd/f6/9ab65a746a4ab6618e4c9da6875cacee269c496694dcbeab8ead9ebb29dc/py_markdown_table-1.3.0.tar.gz", hash = "sha256:be63f6bcbe32e10a9a68575eb48a648949df067b54b48ad6d993b0e5748f57d6", size = 15714, upload-time = "2025-02-06T16:56:21.116Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/5e/c4afc80e5a76aa7d0801378cb720a2f894097c25497221ad139b5b73d24d/py_markdown_table-1.3.0-py3-none-any.whl", hash = "sha256:b8740b57e466f343dbb1e9c7ca4e2d1b4281d96fb922bf1ed60b6c496c8725c4", size = 13426, upload-time = "2025-02-06T16:56:19.303Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-html" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "pytest" }, + { name = "pytest-metadata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c4/08/2076aa09507e51c1119d16a84c6307354d16270558f1a44fc9a2c99fdf1d/pytest_html-4.2.0.tar.gz", hash = "sha256:b6a88cba507500d8709959201e2e757d3941e859fd17cfd4ed87b16fc0c67912", size = 108634, upload-time = "2026-01-19T11:25:26.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/47/07046e0acedc12fe2bae79cf6c73ad67f51ae9d67df64d06b0f3eac73d36/pytest_html-4.2.0-py3-none-any.whl", hash = "sha256:ff5caf3e17a974008e5816edda61168e6c3da442b078a44f8744865862a85636", size = 23801, upload-time = "2026-01-19T11:25:25.008Z" }, +] + +[[package]] +name = "pytest-metadata" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a6/85/8c969f8bec4e559f8f2b958a15229a35495f5b4ce499f6b865eac54b878d/pytest_metadata-3.1.1.tar.gz", hash = "sha256:d2a29b0355fbc03f168aa96d41ff88b1a3b44a3b02acbe491801c98a048017c8", size = 9952, upload-time = "2024-02-12T19:38:44.887Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/43/7e7b2ec865caa92f67b8f0e9231a798d102724ca4c0e1f414316be1c1ef2/pytest_metadata-3.1.1-py3-none-any.whl", hash = "sha256:c8e0844db684ee1c798cfa38908d20d67d0463ecb6137c72e91f418558dd5f4b", size = 11428, upload-time = "2024-02-12T19:38:42.531Z" }, +] + +[[package]] +name = "pytest-xdist" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, +] + +[[package]] +name = "python-markdown-math" +version = "0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/68/fbea05ec6fb318bdcf56ea47596605614554f51d77bfd14f6fb481139ad8/python_markdown_math-0.9.tar.gz", hash = "sha256:567395553dc4941e79b3789a1096dcabb3fda9539d150d558ef3507948b264a3", size = 8680, upload-time = "2025-04-10T10:10:31.84Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/68/ecf3535c40845de2efd8ac2d092dd5fca0868219fa3684d9e58ef7abeece/python_markdown_math-0.9-py3-none-any.whl", hash = "sha256:ac9932df517a5c0f6d01c56e7a44d065eca4a420893ac45f7a6937c67cb41e86", size = 6046, upload-time = "2025-04-10T10:10:30.318Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/1f/a2dca5ffdbf1d475ffc4e80e4d5d720ff3a00f691795910116960ee12511/rpds_py-2026.6.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7b689145a1485c335569bd056464f3243a29af7ed3871c7be31ad624ba239bc7", size = 342174, upload-time = "2026-06-30T07:14:54.821Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dc/323d08583c0832911768663d1944f0107fcd4088704858d84b5e06d105a0/rpds_py-2026.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db08f45aecde626498fb3df07bcf6d2ec040af42e859a4f5040d79c200342911", size = 345513, upload-time = "2026-06-30T07:14:56.515Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2a/e31989834d18d2f26ec1d2774c5b1eb3331df4ea8ada525175294c94b48a/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc992ab27b15f852c76755eb2ab7dce86585ddadba6fa5946e58556088845b4", size = 373783, upload-time = "2026-06-30T07:14:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/87/fe/e80107ee3639585c9941c17d6a42cd65325022f656c023191fce78c324c8/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f88d653e7b3b779d71ae7454e20dcc9b6bae903f33c269db9f2be41bda3f261", size = 378316, upload-time = "2026-06-30T07:14:59.077Z" }, + { url = "https://files.pythonhosted.org/packages/22/6f/81e3adf81acfb6fa694de2a6e4e7d8863121e3e0799e0a7725e6cf5679c4/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e52655eaf81e32593abedaa4bfe33170c8cfedf3365ed9be6e11e07f148f0278", size = 499423, upload-time = "2026-06-30T07:15:00.488Z" }, + { url = "https://files.pythonhosted.org/packages/2d/9a/41263969df0ce3d9af2a96d5005a288200af1989aed3354bfceb5fc0b21f/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dfcc8b909769d19db55c7cc9541eb64b9b774b1057ffffb4f1048070475bb9f9", size = 386077, upload-time = "2026-06-30T07:15:01.911Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/7e98f468bd50346faff5b10e5297374b443bfdddacc8e9fbc65984539597/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c1255b302953c86a486b81d330d5ee1d5bd937691ce271b6be0ef0e299eaab7", size = 371315, upload-time = "2026-06-30T07:15:03.317Z" }, + { url = "https://files.pythonhosted.org/packages/99/3c/2b973b4d371906a134b03decfea7f5d9835a2c6d263454392e15b64b5b18/rpds_py-2026.6.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:8d2294a31386bfa251d8c8a39472beee17db67d4f1a6eabea665d35c9a4461c3", size = 383502, upload-time = "2026-06-30T07:15:04.627Z" }, + { url = "https://files.pythonhosted.org/packages/98/2a/12e2799500af0a307bca76b63361c51f9fe479223561489c29eea1f2ee41/rpds_py-2026.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8f23ead891a3b762f35ab3b04623da7056545b48aa60d59957e6789914545da", size = 402673, upload-time = "2026-06-30T07:15:05.856Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e3/21e5872d165fe08be4f229e3d5ee9d90019c0bf0e5538de60dbd54009450/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:421aba32367055614287a4292b6a17f1939c9452299f7a0209c117e990b646d4", size = 549964, upload-time = "2026-06-30T07:15:07.159Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d0/5ee0fe36844297de8123bee27bc12078c1a7416ad9f1b8a8ca18d6b0c0ac/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1e5822dfc2f0d4ab7e745eaa6d85945069329beeccef965af3f3bb26058fcab6", size = 615446, upload-time = "2026-06-30T07:15:08.531Z" }, + { url = "https://files.pythonhosted.org/packages/b1/80/1ea5873cb683f2fbe5f21b23ea1f6d179ead19f3c5b249b7eb5dca568ef2/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83e35b57523816c8613fd0776b40cd8bb9f596b37ddd2692eb4a6bb5ab2f8c93", size = 576975, upload-time = "2026-06-30T07:15:09.97Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e1/90ef639217a5ddb15b7f4f61b1c33911fd044ad03c311bafdd2bcab85582/rpds_py-2026.6.3-cp311-cp311-win32.whl", hash = "sha256:de3eceba0b683bcbb1ab93da016d0270df1f9ae7be716b40214c5dafac6ea45a", size = 204453, upload-time = "2026-06-30T07:15:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b7/b7a1695d7af36f521fb11e80d6d3adbd744f73b921859bd3c2a2c0dc706f/rpds_py-2026.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:2c54a076ca4d370980ab57bc0e31df57bbe8d41340436a90ef8b1219a3cbb127", size = 223219, upload-time = "2026-06-30T07:15:12.476Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a2/145afacf796e4506062825941176ad9445c2dcf2b3b6a1f13d3030a15e19/rpds_py-2026.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:168c733a7112e071bb7a66460e667edfcff06c017a3c523f7a8a8e08d0140804", size = 219137, upload-time = "2026-06-30T07:15:13.631Z" }, + { url = "https://files.pythonhosted.org/packages/5c/be/2e8974163072e7bab7df1a5acd54c4498e75e35d6d18b864d3a9d5dadc92/rpds_py-2026.6.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0811d33247c3d6128a3001d763f2aa056bb3425204335400ac54f89eec3a0d0", size = 343691, upload-time = "2026-06-30T07:15:14.96Z" }, + { url = "https://files.pythonhosted.org/packages/a4/73/319dfa745dd668efe89309141ded489126461fcecd2b8f3a3cda185129b6/rpds_py-2026.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:538949e262e46caa31ac01bdb3c1e8f642622922cacbabbae6a8445d9dc33eaf", size = 338542, upload-time = "2026-06-30T07:15:16.267Z" }, + { url = "https://files.pythonhosted.org/packages/21/63/4239893be1c4d09b709b1a8f6be4188f0870084ff547f46606b8a75f1b03/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24", size = 368180, upload-time = "2026-06-30T07:15:17.62Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ca/9c5de382225234ceb37b1844ebdb140db12b2a278bb9efe2fcd19f6c82ce/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e", size = 375067, upload-time = "2026-06-30T07:15:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/87/dc/863f69d1bf04ade34b7fe0d59b9fdf6f0135fe2d7cbca74f1d665589559d/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975", size = 490509, upload-time = "2026-06-30T07:15:20.434Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ef/eac16a12048b45ec7c7fa94f2be3438a5f26bf9cc8580b18a1cfd609b7f6/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680", size = 382754, upload-time = "2026-06-30T07:15:21.831Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/d2f3f532616be4d06c316ef119683e832bd3d41e112bf3a88f4151c95b17/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6", size = 366189, upload-time = "2026-06-30T07:15:23.371Z" }, + { url = "https://files.pythonhosted.org/packages/e3/29/41a7b0e98a4b44cd676ab7598419623373eb43b20be68c084935c1a8cf88/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a", size = 377750, upload-time = "2026-06-30T07:15:24.659Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/ecda0bec46f9a1565090bcdc941d023f6a25aff85fda28f89f8d19878152/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4", size = 395576, upload-time = "2026-06-30T07:15:25.987Z" }, + { url = "https://files.pythonhosted.org/packages/68/a8/6ed52f03ee6cb854ce78785cc9a9a672eb880e83fd7224d471f667d151f1/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa", size = 543807, upload-time = "2026-06-30T07:15:27.356Z" }, + { url = "https://files.pythonhosted.org/packages/8f/d6/156c0d3eea27ba09b92562ba2364ba124c0a061b199e17eac637cd25a5e2/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc", size = 611187, upload-time = "2026-06-30T07:15:28.931Z" }, + { url = "https://files.pythonhosted.org/packages/f1/31/774212ed989c62f7f310220089f9b0a3fb8f40f5443d1727abd5d9f52bc9/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822", size = 573030, upload-time = "2026-06-30T07:15:30.553Z" }, + { url = "https://files.pythonhosted.org/packages/c9/50/22f73127a41f1ce4f87fe39aadfb9a126345801c274aa93ae88456249327/rpds_py-2026.6.3-cp312-cp312-win32.whl", hash = "sha256:501f9f04a588d6a09179368c57071301445191767c64e4b52a6aa9871f1ef5ed", size = 202185, upload-time = "2026-06-30T07:15:32.027Z" }, + { url = "https://files.pythonhosted.org/packages/04/3a/f0ee4d4dde9d3b69dedf1b5f74e7a40017046d55052d173e418c6a94f960/rpds_py-2026.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2c958bf94822e9290a40aaf2a822d4bc5c88099093e3948ad6c571eca9272e5f", size = 220394, upload-time = "2026-06-30T07:15:33.359Z" }, + { url = "https://files.pythonhosted.org/packages/f3/83/3382fe37f809b59f02aac04dbc4e765b480b46ee0227ed516e3bdc4d3dfc/rpds_py-2026.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:22bffe6042b9bcb0822bcd1955ec00e245daf17b4344e4ed8e9551b976b63e96", size = 215753, upload-time = "2026-06-30T07:15:34.778Z" }, + { url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" }, + { url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" }, + { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" }, + { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" }, + { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" }, + { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" }, + { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" }, + { url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" }, + { url = "https://files.pythonhosted.org/packages/b6/36/7fbe9dcdaf857fb3f63c2a2284b62492d95f5e8334e947e5fb6e7f68c9be/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e", size = 344510, upload-time = "2026-06-30T07:15:57.921Z" }, + { url = "https://files.pythonhosted.org/packages/ba/54/f785cc3d3f60839ca57a5af4927a9f347b07b2799c373fc20f7949f87c7e/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd", size = 339495, upload-time = "2026-06-30T07:15:59.238Z" }, + { url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" }, + { url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" }, + { url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" }, + { url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" }, + { url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" }, + { url = "https://files.pythonhosted.org/packages/87/03/2a69ab618a789cf6cf85c86bb844c62d090e700ab1a2aa676b3741b6c516/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8", size = 202504, upload-time = "2026-06-30T07:16:16.893Z" }, + { url = "https://files.pythonhosted.org/packages/85/62/a3892ba945f4e24c78f352e5de3c7620d8479f73f211406a97263d13c7d2/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5", size = 220380, upload-time = "2026-06-30T07:16:18.108Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e7/c2bd44dc831931815ad11ebb5f430b5a0a4d3caa9de837107876c30c3432/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703", size = 215976, upload-time = "2026-06-30T07:16:19.654Z" }, + { url = "https://files.pythonhosted.org/packages/79/9c/fff7b74bce9a091ec9a012a03f9ff5f69364eaf9451060dfc4486da2ffdd/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90", size = 346840, upload-time = "2026-06-30T07:16:21.268Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/77bcb1168b33704908295533d27f10eb811e9e3e193e8993dc99572211d3/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4", size = 340282, upload-time = "2026-06-30T07:16:22.875Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" }, + { url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" }, + { url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" }, + { url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" }, + { url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" }, + { url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f6/21101359743cd136ada781e8210a85769578422ba460672eea0e29739200/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e", size = 201068, upload-time = "2026-06-30T07:16:41.316Z" }, + { url = "https://files.pythonhosted.org/packages/a6/b2/9574d4d44f7760c2aa32d92a0a4f41698e33f5b204a0bf5c9758f52c79d5/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2", size = 220600, upload-time = "2026-06-30T07:16:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/08/ae/f23a2697e6ee6340a578b0f136be6483657bef0c6f9497b752bb5c0964bb/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13", size = 344726, upload-time = "2026-06-30T07:16:44.5Z" }, + { url = "https://files.pythonhosted.org/packages/c3/63/e7b3a1a5358dd32c930a1062d8e15b67fd6e8922e81df9e91706d66ee5c8/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05", size = 339587, upload-time = "2026-06-30T07:16:46.255Z" }, + { url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" }, + { url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" }, + { url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" }, + { url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" }, + { url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" }, + { url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" }, + { url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" }, + { url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" }, + { url = "https://files.pythonhosted.org/packages/29/71/4d8fcf700931815594bce892255bbd973b94efaf0fc1932b0590df18d886/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369", size = 202864, upload-time = "2026-06-30T07:17:05.746Z" }, + { url = "https://files.pythonhosted.org/packages/eb/62/b577562de0edbb55b2be85ce5fd09c33e386b9b13eee09833af4240fd5c4/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146", size = 220430, upload-time = "2026-06-30T07:17:07.471Z" }, + { url = "https://files.pythonhosted.org/packages/c8/95/d6d0b2509825141eef60669a5739eec88dbc6a48053d6c92993a5704defe/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e", size = 215877, upload-time = "2026-06-30T07:17:09.008Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bf/f3ea278f0afd615c1d0f19cb69043a41526e2bb600c2b536eb192218eb27/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b", size = 346933, upload-time = "2026-06-30T07:17:10.762Z" }, + { url = "https://files.pythonhosted.org/packages/9d/29/9907bdf1c5346763cf10b7f6852aad86652168c259def904cbe0082c5864/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690", size = 340274, upload-time = "2026-06-30T07:17:12.266Z" }, + { url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" }, + { url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" }, + { url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" }, + { url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" }, + { url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" }, + { url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" }, + { url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" }, + { url = "https://files.pythonhosted.org/packages/ba/76/65002b08596c389105720a8c0d22298b8dc25a4baf89b2ce431343c8b1de/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577", size = 201204, upload-time = "2026-06-30T07:17:30.193Z" }, + { url = "https://files.pythonhosted.org/packages/8c/97/d855d6b3c322d1f27e26f5241c42016b56cf01377ea8ed348285f54652f0/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324", size = 220719, upload-time = "2026-06-30T07:17:31.788Z" }, + { url = "https://files.pythonhosted.org/packages/b4/9c/f0d19ac587fd0e4ab6b72cda355e9c5a6166b01ef7e064e437aef8eb9fef/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4cf2d36a2357e4d07bb5a4f98801265327b48256867816cfd2ceb001e9754a8f", size = 349791, upload-time = "2026-06-30T07:17:33.315Z" }, + { url = "https://files.pythonhosted.org/packages/38/c7/1d49d204c9fd2ee6c537601dc4c1ba921e03363ca576bfab94a00254ac9a/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:30c6dc199b24a5e3e81d50da0f00858c5bbdb2617a750395687f4339c5818171", size = 352842, upload-time = "2026-06-30T07:17:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e5/c0b5dc93cd0d4c06ce1f438907649514e2ea077bcd911e3154a51e96c38e/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9891e594296ab9dada6551c8e7b387b2721f27a67eecd528412e8906247a7b90", size = 382094, upload-time = "2026-06-30T07:17:36.514Z" }, + { url = "https://files.pythonhosted.org/packages/0d/54/ec0e907b4ca8d541112db352409bd15f871c9b243e0c92c9b5a46ae96f01/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5c2dc92304aa48a4a60443b548bb12f12e119d4b72f314015e67b9e1be97fca", size = 388662, upload-time = "2026-06-30T07:17:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f4/921c22a4fd0f1c1ac13a3996ffbf0aa67951e2c8ad0d1d9574938a2932e8/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:127e08c0642d880cf32ca47ec2a4a77b901f7e2dd1ad9762adb13955d72ffcc9", size = 504896, upload-time = "2026-06-30T07:17:39.689Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1b/a114b972cefa1ab1cdb3c7bb177cd3844a12826c507c722d3a73516dbbaf/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bb68f03f395eb793220b45c097bd4d8c32944393da0fad8b999efac0868fc8c", size = 391545, upload-time = "2026-06-30T07:17:41.336Z" }, + { url = "https://files.pythonhosted.org/packages/4e/98/af9b3db77d47fcbe6c8c1f36e2c2147ec70292819e99c325f871584a1c11/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3450b693fde92133e9f51060568a4c31fcca76d5e53bbd611e689ca446517e9", size = 380059, upload-time = "2026-06-30T07:17:42.857Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ba/0efd8668b97c1d26a61566386c636a7a7a09829e474fdf807caa15a2c844/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:5e8d07bddee435a2ff6f1920e18feff28d0bc4533e42f4bf6927fbd073312c41", size = 393235, upload-time = "2026-06-30T07:17:44.637Z" }, + { url = "https://files.pythonhosted.org/packages/62/90/8c139ee9690f73b0829f32647de6f40d826f8f443af6fa72644f96351aac/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a83ae6c67b7676b9878378547ca8e93ed77a580037bcbcd1d32f739e1e6089c", size = 413008, upload-time = "2026-06-30T07:17:46.225Z" }, + { url = "https://files.pythonhosted.org/packages/9c/97/0043896fdd7828ce09a1d9a8b06433714d0960fc4ff3fc4aa72b666b764e/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2bfd04c19ddbd6640de0b51894d764bd2758854d5b75bd102d2ef10cb9c293a9", size = 558118, upload-time = "2026-06-30T07:17:47.759Z" }, + { url = "https://files.pythonhosted.org/packages/f6/40/02355f0e134f783a8f9814c4680a1bd311d37671577a5964ea838573ff37/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:ca6546b66be9dc4738b1b043d5ebd5488c66c578c5ff0fd0e8065313fe3afb76", size = 623138, upload-time = "2026-06-30T07:17:49.355Z" }, + { url = "https://files.pythonhosted.org/packages/10/85/48f0abdcef5cce4e034c7a5b0ceeceba0b01bf0d942824f4bb720afe2dec/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8e65860d238379ed982fd9ba690579b5e95af2f4840f99c772816dbe573cb826", size = 586486, upload-time = "2026-06-30T07:17:51.141Z" }, +] + +[[package]] +name = "setuptools" +version = "80.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70", size = 1200343, upload-time = "2026-01-25T22:38:17.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173", size = 1064234, upload-time = "2026-01-25T22:38:15.216Z" }, +] + +[[package]] +name = "smmap" +version = "5.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/ea/49c993d6dfdd7338c9b1000a0f36817ed7ec84577ae2e52f890d1a4ff909/smmap-5.0.3.tar.gz", hash = "sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c", size = 22506, upload-time = "2026-03-09T03:43:26.1Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl", hash = "sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f", size = 24390, upload-time = "2026-03-09T03:43:24.361Z" }, +] + +[[package]] +name = "systemrdl-compiler" +version = "1.32.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "antlr4-python3-runtime" }, + { name = "colorama" }, + { name = "markdown" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/03/ac/2088114d65e191e2a057313036254fb3df6ec64aaa744929a50b1e5202cb/systemrdl_compiler-1.32.2.tar.gz", hash = "sha256:3308f5ba2db23f035c25391022c70dbaba8980fdbfdf652bd2ad79fd33aba1f2", size = 484930, upload-time = "2026-02-27T05:54:23.244Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/18/d76dc65c7a2cffb5524c018c9edd69397d94f4cd708b52fad2c8cc3f8c99/systemrdl_compiler-1.32.2-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:4870074e9d1f720f577966e107f7096e0c464772456ecd9e772fd2055216d6a4", size = 1145125, upload-time = "2026-02-27T05:54:04.031Z" }, + { url = "https://files.pythonhosted.org/packages/d8/c7/ca0aa3d315e606c584841f1929b0b9bd7d9a6f1b1c76f09164cfd3f0ee2f/systemrdl_compiler-1.32.2-cp37-abi3-macosx_11_0_x86_64.whl", hash = "sha256:69e8ce07e5435cd61dc126113734b0f5e26271f193e08c9f31326a429d857fd9", size = 1172296, upload-time = "2026-02-27T05:54:05.948Z" }, + { url = "https://files.pythonhosted.org/packages/06/18/7abeafa5b642cc9e89ed534a7a73416b77540e7234bea08cc3138e790844/systemrdl_compiler-1.32.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2777441b26f8ac880ba402c300bb2fd92d6b155aa50261715d9519a3a6e780a", size = 10973073, upload-time = "2026-02-27T05:54:07.25Z" }, + { url = "https://files.pythonhosted.org/packages/f2/97/04dc3272980a212674c9737f3c2928e49d862879843135c86da90b0c23fc/systemrdl_compiler-1.32.2-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be36bb56fdcb218e266ec7c1ae950492c6c0d9327c0c4d85912583ac6e26347b", size = 10845166, upload-time = "2026-02-27T05:54:09.59Z" }, + { url = "https://files.pythonhosted.org/packages/55/43/2ffd2c7753789e02bac7d902e847738af81f9a32098233464067a85ba92a/systemrdl_compiler-1.32.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9707da961e8b8b28c43ebf542b2863e2dc581d194f5c4ceb0315a45ad8883e0", size = 11020140, upload-time = "2026-02-27T05:54:11.992Z" }, + { url = "https://files.pythonhosted.org/packages/94/7b/f94162860a1a5e2ccaa707c9c4c4c5031d98f3f00251b03a75ee9147b4da/systemrdl_compiler-1.32.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:56f37930d5948da9ca77b70702d11b5b19bb9755e5fab97444aa65ce9be8d37e", size = 11049533, upload-time = "2026-02-27T05:54:14.107Z" }, + { url = "https://files.pythonhosted.org/packages/dc/3e/3596309bc436ca1ca6a8e20aee3af8b4924038fbeb422514f9b0756fbaa5/systemrdl_compiler-1.32.2-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:8477c6d9fab1458c6dbd95f3d38bdb5c2a40998601a467e8e6c230cc82880b46", size = 11261692, upload-time = "2026-02-27T05:54:16.125Z" }, + { url = "https://files.pythonhosted.org/packages/28/84/4a0369f39c5a6a960382a2a9db0b8d7f511e1941c6ef21a9fb5401ce76c4/systemrdl_compiler-1.32.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a05dd1bcd8e7c29d2fe67fb46149f503f39173e462b4bf63fbd375fc0efd3cd1", size = 11301976, upload-time = "2026-02-27T05:54:18.141Z" }, + { url = "https://files.pythonhosted.org/packages/74/a2/91435c5c8b13dc065dd28dd6e7ca4122de566157f0282126add9025e74e5/systemrdl_compiler-1.32.2-cp37-abi3-win32.whl", hash = "sha256:402620a125e11086da3e1b609a3c8bd82d207c71691f6547242a3df237eb3b30", size = 923159, upload-time = "2026-02-27T05:54:20.104Z" }, + { url = "https://files.pythonhosted.org/packages/69/43/6794d66c9aa5394376ca1ef18343ebf146f25c75ba0d4240707e6198e47c/systemrdl_compiler-1.32.2-cp37-abi3-win_amd64.whl", hash = "sha256:06d6221257251adc0ee422da2dae9748a88239d72dd6e9b6ee21788396d6c2d0", size = 955604, upload-time = "2026-02-27T05:54:21.419Z" }, +] + +[[package]] +name = "tabulate" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/46/58/8c37dea7bbf769b20d58e7ace7e5edfe65b849442b00ffcdd56be88697c6/tabulate-0.10.0.tar.gz", hash = "sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d", size = 91754, upload-time = "2026-03-04T18:55:34.402Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3", size = 39814, upload-time = "2026-03-04T18:55:31.284Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +]