Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ variables:
CI_CONFIG_DUAL: 'cachepool_dual_fpu_4g'
CI_CONFIG_16G: 'cachepool_fpu_16g'
CI_CONFIG_DUAL_16G: 'cachepool_dual_fpu_16g'
# Binary prefix of the tests whose KERNEL has no group prefix (rlc-, ctrl-)
SW_PREFIX: 'test-'

default:
Expand Down Expand Up @@ -169,16 +170,16 @@ test:
- fmatmul-32b_M64_N64_K64
- fft-32b_M1024_N16
- byte-enable
- multi_producer_single_consumer_double_linked_list_M1_N1350_K10
- multi_producer_single_consumer_double_linked_list_M1_N1350_K4_P2_C2_am_G1024_tbchk
- multi_producer_single_consumer_double_linked_list_P1_C3_ul_ci
- rlc-multi_producer_single_consumer_double_linked_list_M1_N1350_K10
- rlc-multi_producer_single_consumer_double_linked_list_M1_N1350_K4_P2_C2_am_G1024_tbchk
- rlc-multi_producer_single_consumer_double_linked_list_P1_C3_ul_ci
script:
# The vsim script writes a .rtlbinary marker here; monitor logs need the
# core/noc/others subfolders. Build artifacts exclude sim/bin/logs/, so
# these must be recreated in the test job too.
- mkdir -p sim/bin/logs sim/bin/logs/core sim/bin/logs/noc sim/bin/logs/others
- chmod +x sim/bin/cachepool_cluster.vsim
- BIN="${SW_PREFIX}${KERNEL}"
- case "$KERNEL" in rlc-*|ctrl-*) BIN="$KERNEL" ;; *) BIN="${SW_PREFIX}${KERNEL}" ;; esac
- sim/bin/cachepool_cluster.vsim software/build/CachePoolTests/$BIN 2>&1 | tee test_${KERNEL}.log
- python3 util/auto-benchmark/check-ci.py test_${KERNEL}.log
artifacts:
Expand Down Expand Up @@ -209,7 +210,7 @@ test-dual:
script:
- mkdir -p sim/bin/logs sim/bin/logs/core sim/bin/logs/noc sim/bin/logs/others
- chmod +x sim/bin/cachepool_cluster.vsim
- BIN="${SW_PREFIX}${KERNEL}"
- case "$KERNEL" in rlc-*|ctrl-*) BIN="$KERNEL" ;; *) BIN="${SW_PREFIX}${KERNEL}" ;; esac
- sim/bin/cachepool_cluster.vsim software/build/CachePoolTests/$BIN 2>&1 | tee test_dual_${KERNEL}.log
- python3 util/auto-benchmark/check-ci.py test_dual_${KERNEL}.log
artifacts:
Expand All @@ -235,11 +236,11 @@ test-16g:
- fmatmul-32b_M128_N128_K128
- fft-32b_M1024_N16
- byte-enable
- multi_producer_single_consumer_double_linked_list_M1_N1350_K10
- rlc-multi_producer_single_consumer_double_linked_list_M1_N1350_K10
script:
- mkdir -p sim/bin/logs sim/bin/logs/core sim/bin/logs/noc sim/bin/logs/others
- chmod +x sim/bin/cachepool_cluster.vsim
- BIN="${SW_PREFIX}${KERNEL}"
- case "$KERNEL" in rlc-*|ctrl-*) BIN="$KERNEL" ;; *) BIN="${SW_PREFIX}${KERNEL}" ;; esac
- sim/bin/cachepool_cluster.vsim software/build/CachePoolTests/$BIN 2>&1 | tee test_16g_${KERNEL}.log
- python3 util/auto-benchmark/check-ci.py test_16g_${KERNEL}.log
artifacts:
Expand Down Expand Up @@ -268,7 +269,7 @@ test-dual-16g:
script:
- mkdir -p sim/bin/logs sim/bin/logs/core sim/bin/logs/noc sim/bin/logs/others
- chmod +x sim/bin/cachepool_cluster.vsim
- BIN="${SW_PREFIX}${KERNEL}"
- case "$KERNEL" in rlc-*|ctrl-*) BIN="$KERNEL" ;; *) BIN="${SW_PREFIX}${KERNEL}" ;; esac
- sim/bin/cachepool_cluster.vsim software/build/CachePoolTests/$BIN 2>&1 | tee test_dual_16g_${KERNEL}.log
- python3 util/auto-benchmark/check-ci.py test_dual_16g_${KERNEL}.log
artifacts:
Expand Down
4 changes: 2 additions & 2 deletions Bender.lock
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ packages:
dependencies:
- axi
floo_noc:
revision: 8413d9b044a51f958a7d4ef261e2b01e73db4544
revision: 7e5104cd0875c3ded16d53366caaef2dc465c49d
version: null
source:
Git: https://github.com/pulp-platform/FlooNoC.git
Expand Down Expand Up @@ -150,7 +150,7 @@ packages:
dependencies:
- tech_cells_generic
spatz:
revision: 6acbd2e0cb9131f870209d03ffb85c46fbd2ea9c
revision: f574402d29ed54f2dbede81099419889575c4584
version: null
source:
Git: https://github.com/pulp-platform/spatz.git
Expand Down
6 changes: 4 additions & 2 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,22 @@ export_include_dirs:
sources:
# Level 0
- hardware/src/reqrsp_to_reg.sv
- hardware/src/reqrsp_w2n_converter.sv
- hardware/src/reqrsp_xbar.sv
- hardware/src/tcdm_cache_interco.sv
- hardware/src/tcdm_id_remapper.sv
- hardware/src/spatz_cache_amo.sv
# Memory-mapped register
- hardware/cachepool_peripheral/cachepool_peripheral_reg_pkg.sv
- hardware/cachepool_peripheral/cachepool_peripheral_reg_top.sv
- hardware/cachepool_peripheral/cachepool_peripheral.sv
# Bootrom
- hardware/bootrom/bootrom.sv
# Level 1
- hardware/generated/floo_cachepool_noc_pkg.sv
- hardware/src/cachepool_pkg.sv
- hardware/cachepool_peripheral/cachepool_peripheral.sv
# Group configuration registers (cluster sender + group-level register)
- hardware/src/cachepool_group_cfg_sender.sv
- hardware/src/cachepool_group_cfg.sv
- hardware/src/cachepool_acc_cut.sv
- hardware/src/cachepool_cc.sv
- hardware/src/cachepool_spatz_lock.sv
Expand Down
17 changes: 15 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,15 @@ CACHEPOOL_DEFS += -DDATA_WIDTH=$(data_width)
CACHEPOOL_DEFS += -DADDR_WIDTH=$(addr_width)
CACHEPOOL_DEFS += -DNUM_BARRIER_SLOTS=$(num_barrier_slots)

# Group-level configuration registers and the reset values shared with the cluster peripheral
CACHEPOOL_DEFS += -DGROUP_CFG_BASE=$(group_cfg_base)
CACHEPOOL_DEFS += -DGROUP_CFG_STRIDE=$(group_cfg_stride)
CACHEPOOL_DEFS += -DL1D_XBAR_OFFSET_RST=$(l1d_xbar_offset_rst)
CACHEPOOL_DEFS += -DL1D_PRIVATE_RST=$(l1d_private_rst)
CACHEPOOL_DEFS += -DL1D_PRIVATE_ADDR_RST=$(l1d_private_addr_rst)
CACHEPOOL_DEFS += -DICACHE_PREFETCH_RST=$(icache_prefetch_rst)
CACHEPOOL_DEFS += -DBOOTROM_DATA_WIDTH=$(bootrom_data_width)

# Tile configuration
CACHEPOOL_DEFS += -DREFILL_DATA_WIDTH=$(refill_data_width)

Expand Down Expand Up @@ -395,7 +404,7 @@ include sim/sim.mk
TESTS_DIR := $(SOFTWARE_DIR)/tests

# Test-group roots (relative to SOFTWARE_DIR) scanned for data-generated tests.
TEST_ROOTS := cache sync kernels/fp kernels/int rlc tests
TEST_ROOTS := cache sync kernels/fp kernels/int rlc control tests

# Auto-discover every test that has a script/gen_data.py.
# Convention: script/data_<params>.json → data/data_<params>.h
Expand Down Expand Up @@ -468,7 +477,11 @@ SW_CMAKE_FLAGS = \
-DGCC_PATH=${GCC_INSTALL_DIR} \
-DPYTHON=${PYTHON} \
-DBUILD_TESTS=ON \
-DNUM_SCALAR_PER_CORE=$(num_scalar_per_core)
-DNUM_SCALAR_PER_CORE=$(num_scalar_per_core) \
-DL2_CHANNEL=$(l2_channel) \
-DL2_INTERLEAVE=$(l2_interleave) \
-DL2_BANK_WIDTH=$(l2_bank_width) \
-DL1D_CACHELINE_WIDTH=$(l1d_cacheline_width)

.PHONY: sw
sw: generate bootrom gen-data
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ The default boundary is `0xA000_0000`. This means data in `.pdcp_src` (at `0xA00

Flush instructions are issued through the cluster peripheral and dispatched to cache controllers via a two-level controller:

- **Cluster level** (`cachepool_peripheral`): holds the instruction and a per-tile one-hot tile-select mask. Issues the instruction to all tiles simultaneously and tracks completion at tile granularity.
- **Cluster level** (`cachepool_peripheral`): holds the instruction and a per-tile one-hot tile-select mask. On `L1D_INSN_COMMIT` it sends the instruction, with each group's slice of the mask, to the group-level configuration register of every group over the L2 mesh (`cachepool_group_cfg_sender`), and stays busy until every group has answered.
- **Group level** (`cachepool_group_cfg`): starts the instruction in its selected tiles and answers only once all of them have finished.
- **Tile level** (`cachepool_tile`): receives the instruction, determines which of its local cache controllers to activate based on the partition field, and returns a single ready pulse to the cluster controller when all targeted controllers finish.

### Flush instruction encoding
Expand Down Expand Up @@ -342,7 +343,7 @@ l1d_xbar_config(uint32_t offset);

Lower-level, single-shot primitives (`l1d_flush()`, `l1d_private_flush()`, `l1d_shared_flush()`, `l1d_commit()`, `l1d_wait()`) exist for building custom sequences but issue only the register write — the caller is responsible for cluster-wide fence/barrier synchronization around them.

`l1d_addr()` has no hardware completion status bit (unlike flush, which polls `L1D_FLUSH_STATUS` via `l1d_wait()`); its peripheral register write is posted over the interconnect, so it bridges the gap with a fixed-cycle delay on core 0 before the final barrier.
Only flush/invalidate instructions are committed. The configuration registers (`L1D_PRIVATE`, `L1D_ADDR`, `XBAR_OFFSET`, `ICACHE_PREFETCH_ENABLE`) need no commit: when a value changes, the peripheral sends it to every group on its own. `L1D_FLUSH_STATUS` stays busy until every group has applied it, so `l1d_part()`, `l1d_addr()` and `l1d_xbar_config()` end with `l1d_wait()`. Writing the value a register already holds sends nothing.

> Changing the partition mode, boundary address, or crossbar offset while the cache contains valid data requires a flush first — `l1d_xbar_config()` and `l1d_part()` flush internally; `l1d_addr()` does not (call a cluster flush before it if needed).

Expand Down
1 change: 1 addition & 0 deletions config/cachepool.hjson.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
cluster: {
mempool: 0,
boot_addr: ${boot_addr}, // e.g., 4096 (0x1000)
bootrom_data_width: ${bootrom_data_width},
cluster_base_addr: ${stack_addr}, // 0xBFFF_F800 typically
cluster_base_offset: 0,
cluster_base_hartid: 0,
Expand Down
23 changes: 21 additions & 2 deletions config/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ data_width ?= 32
# Core addrwidth
addr_width ?= 32

# Bootrom datawidth
bootrom_data_width ?= 32
# Bootrom datawidth: must equal the L2 refill width, the bootrom is only read by full-line
# iCache refills on the wide L2 path
bootrom_data_width ?= $(refill_data_width)


######################
Expand Down Expand Up @@ -227,3 +228,21 @@ boot_addr ?= 4096

# UART address (32'hC001_0000)
uart_addr ?= 3221291008

# Group-level configuration registers, written by the cluster peripheral over the
# L2 mesh. Group g owns one word at group_cfg_base + g * group_cfg_stride.
# Base (32'hD000_0000)
group_cfg_base ?= 3489660928
# Stride per group (32'h100)
group_cfg_stride ?= 256

# Reset values of the L1D/xbar configuration, shared by the cluster peripheral
# registers and the group-level copies so both always come out of reset equal.
# Cache xbar offset (bit position selecting the cache bank)
l1d_xbar_offset_rst ?= 14
# Private partition size and fold (L1D_PRIVATE)
l1d_private_rst ?= 0
# Start address of the private L1D partition (32'hA000_0000)
l1d_private_addr_rst ?= 2684354560
# Instruction cache prefetching enable
icache_prefetch_rst ?= 1
7 changes: 5 additions & 2 deletions hardware/bootrom/bootrom.S
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
.global BOOTDATA

_start:
la t1, exception
// lla, not la: la loads the address from the GOT, a 32-bit data read of the bootrom.
// The bootrom is only served on the wide L2 path (instruction refills), so it must
// never see data loads.
lla t1, exception
csrw mtvec, t1
csrr a0, mhartid
la a1, BOOTDATA
lla a1, BOOTDATA

// Enable MSI interrupt
csrw mie, 0xF
Expand Down
Loading
Loading