Skip to content
Draft
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ tags
# Python
**.idea
venv
__pycache__/
# Visual Studio Code
.vscode
*.code-workspace
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Add support for DRAMsys5.0 co-simulation
- Add support for atomics in L2
- Add Dynamic Address Scrambling (DAS) support with configurable partitioning, hardware address scrambler, and software runtime for dynamic heap allocation
- Add Back2Local rerouting mechanism and interconnect extensions to use underutilized tile ports and increase TCDM bandwidth for local accesses

### Changes
- Add physical feasible TeraPool configuration with SubGroup hierarchy.
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,10 @@ app=hello_world make simc
make trace
# Generate a visualization of the traces
app=hello_world make tracevis
# Automatically run the benchmark (headless), extract the traces, and log the results
app=hello_world make benchmark
# Benchmark and plot an app bracketed by mempool_start_benchmark() and
# mempool_stop_benchmark(); see hardware/scripts/trace_analysis/README.md.
app=matmul_i32 make benchmark
app=matmul_i32 make plots
```

You can set up the configuration of the system in the file `config/config.mk`, controlling the total number of cores, the number of cores per tile and whether the Xpulpimg extension is enabled or not in the Snitch core; the `xpulpimg` parameter also control the default core architecture considered when compiling applications for MemPool.
Expand Down
19 changes: 19 additions & 0 deletions config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ you can use the following command to make git pick up tracking the file again:
git update-index --no-assume-unchanged config/config.mk
```

## Back2Local

Back2Local reuses upper-level tile ports for TCDM requests that remain in the
source group or subgroup. It changes the route to memory, not the address
mapping, and can be used with or without DAS.

| Variable | Default | Description |
|-------------------------|---------|--------------------------------------------|
| `back2local` | `0` | Enable Back2Local for the selected setup |
| `back2local_tera_group` | `0` | Also use TeraPool's group-level tile ports |

For TeraPool, `back2local=1` uses the subgroup-level ports by default. Setting
`back2local_tera_group=1` also makes the group-level ports available and may
contend with inter-group traffic.

The current port selection uses the core index modulo the available ports. It
is a simple baseline policy that can be adapted in
`hardware/src/mempool_tile.sv`.

## Dynamic Address Scrambling (DAS)

Dynamic Address Scrambling (DAS) is a runtime-configurable address mapping
Expand Down
5 changes: 5 additions & 0 deletions config/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ num_das_partitions ?= 4
# Size of DAS-heap per core
das_mem_size ?= 2048

# Enable Back2Local rerouting for the selected topology.
# The core-index modulo port selection in mempool_tile.sv is a placeholder,
# not an optimized routing policy. Adapt it to the target traffic pattern.
back2local ?= 0

# This parameter is only used for TeraPool configurations
num_sub_groups_per_group ?= 1
remote_group_latency_cycles ?= 7
Expand Down
5 changes: 5 additions & 0 deletions config/terapool.mk
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ num_divsqrt_per_tile ?= 2
# L1 scratchpad banking factor
banking_factor ?= 4

# Also use group-level ports for same-subgroup Back2Local requests.
# Requires back2local=1 and more than one subgroup per group. This may
# contend with inter-group traffic.
back2local_tera_group ?= 0

# Access latency between remote groups
# Options: "7", "9" or "11":
remote_group_latency_cycles ?= 7
Expand Down
55 changes: 50 additions & 5 deletions hardware/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ python ?= python3
buildpath ?= build
# Result path
resultpath ?= results
# Two-stage benchmark/plotting workflow; see scripts/trace_analysis/README.md.
include $(ROOT_DIR)/scripts/trace_analysis/benchmark.mk
result_dir := $(if $(strip $(result_dir)),$(result_dir),$(resultpath)/$(shell date +"%Y%m%d_%H%M%S_$(app)_$$(git rev-parse --short HEAD)"))
# Traces
snitch_trace ?= 1
Expand All @@ -67,6 +69,7 @@ questa_args += -sv_lib $(dramsys_lib_path)/libsystemc -sv_lib $(dramsys_lib_path
app_path ?= $(abspath $(ROOT_DIR)/../software/bin)
ifdef app
preload := "$(app_path)/$(app)"
ifeq ($(skip_app_validation),)
ifeq ("$(shell test -f $(preload))","")
# The file doesn't exist, let's search for the app in the bin folder
# since we might just be missing the hierarchy
Expand All @@ -81,6 +84,7 @@ ifdef app
$(error "Multiple apps ($(app)) found in bin dir $(app_path): $(search_app)")
endif
endif
endif
endif

# QuestaSim args
Expand Down Expand Up @@ -120,12 +124,26 @@ vlog_defs += -DL1_BANK_SIZE=$(l1_bank_size)
vlog_defs += -DBOOT_ADDR=32\'d$(boot_addr)
vlog_defs += -DDAS=$(das)
vlog_defs += -DNUM_DAS_PARTITIONS=$(num_das_partitions)
ifeq ($(das),1)
vlog_defs += -DDAS_MEM_SIZE=$(das_mem_size)
endif
ifeq ($(back2local),1)
vlog_defs += -DBACK2LOCAL
ifeq ($(config),terapool)
ifeq ($(back2local_tera_group),1)
vlog_defs += -DBACK2LOCAL_TERA_GROUP
endif
endif
endif
# Snitch ISA
vlog_defs += -DXPULPIMG=$(xpulpimg)
vlog_defs += -DZFINX=$(zfinx)
vlog_defs += -DZQUARTERINX=$(zquarterinx)
vlog_defs += -DXDIVSQRT=$(xDivSqrt)
vlog_defs += -DSNITCH_TRACE=$(snitch_trace)
ifeq ($(tcdm_addr_trace),1)
vlog_defs += -DTCDM_ADDR_TRACE
endif
# AXI & DMA
vlog_defs += -DAXI_DATA_WIDTH=$(axi_data_width)
vlog_defs += -DRO_LINE_WIDTH=$(ro_line_width)
Expand Down Expand Up @@ -255,7 +273,7 @@ simvcs: compile_vcs_simv
cd $(buildpath) && \
./mempool_simv $(vcs_args) -ucli -do ../scripts/vcs/run.tcl -gui

simcvcs: compile_vcs_simvopt
simcvcs: clean-dasm compile_vcs_simvopt
cd $(buildpath) && \
./mempool_simvopt $(vcs_args)

Expand Down Expand Up @@ -359,24 +377,51 @@ spyglass/tmp/files: $(bender)

# Give configuration in env
trace_env += NUM_CORES=$(num_cores)
trace_env += NUM_CORES_PER_TILE=$(num_cores_per_tile)
trace_env += SEQ_MEM_SIZE=$(seq_mem_size)
trace_env += BANKING_FACTOR=$(banking_factor)
trace_env += L1_BANK_SIZE=$(l1_bank_size)

# Per-hart CSV parts, merged by post_trace; `make benchmark` skips the
# .trace copies into result_dir (copy_traces=0).
tracepartspath ?= $(tracepath)/results_parts
copy_traces ?= 1

trace: pre_trace $(trace) post_trace

# Order pre_trace -> per-hart traces -> post_trace under `make -j`.
$(trace): | pre_trace
post_trace: $(trace)

pre_trace:
rm -rf $(tracepath)
rm -f $(buildpath)/trace_hart_*.trace

post_trace:
mkdir -p "$(result_dir)"
cp $(buildpath)/transcript "$(result_dir)/" | true
$(python) $(ROOT_DIR)/scripts/merge_trace_csvs.py \
--folder "$(tracepartspath)" \
--expected-count "$(words $(trace))" \
--csv "$(traceresult)"
cp $(traceresult) "$(result_dir)"
ifeq ($(copy_traces),1)
cp $(trace) "$(result_dir)"
endif
$(python) $(ROOT_DIR)/scripts/gen_avg.py --folder "$(result_dir)" | tee $(result_dir)/avg.txt

$(buildpath)/%.trace: $(buildpath)/%.dasm
mkdir -p $(tracepath)
mkdir -p $(tracepath) $(tracepartspath)
ifeq ($(tcdm_addr_trace),1)
$(INSTALL_DIR)/riscv-isa-sim/bin/spike-dasm < $< > $(tracepath)/$*.raw
$(python) $(ROOT_DIR)/scripts/merge_tcdm_trace.py \
$(tracepath)/$*.raw $(buildpath)/tcdm_addr_hart_$(patsubst trace_hart_%,%,$*).csv \
> $(tracepath)/$*
rm -f $(tracepath)/$*.raw
else
$(INSTALL_DIR)/riscv-isa-sim/bin/spike-dasm < $< > $(tracepath)/$*
$(trace_env) $(python) $(ROOT_DIR)/scripts/gen_trace.py -p --csv $(traceresult) $(tracepath)/$* > $@
endif
$(trace_env) $(python) $(ROOT_DIR)/scripts/gen_trace.py -p --csv $(tracepartspath)/$*.csv $(tracepath)/$* > $@

tracevis:
$(MEMPOOL_DIR)/scripts/tracevis.py $(preload) $(buildpath)/*.trace -o $(buildpath)/tracevis.json
Expand Down Expand Up @@ -435,7 +480,7 @@ clean:
@rm -rf $(verilator_build)

clean-dasm:
rm -rf $(buildpath)/*.dasm
rm -rf $(buildpath)/*.dasm $(buildpath)/tcdm_addr_hart_*.csv

clean-trace:
rm -rf $(buildpath)/*.trace
rm -rf $(buildpath)/*.trace
15 changes: 8 additions & 7 deletions hardware/deps/idma/src/midends/idma_address_scrambler.sv
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module idma_address_scrambler #(
parameter int unsigned NumTiles = 128,
parameter int unsigned NumBanksPerTile = 32,
parameter int unsigned TCDMSizePerBank = 1024,
parameter int unsigned RowsInterleavingWidth = $clog2(TCDMSizePerBank) - ByteOffset,
parameter int unsigned NumDASPartitions = 4,
parameter int unsigned DASStartAddr = 1024,
parameter int unsigned MemSizePerTile = NumBanksPerTile*TCDMSizePerBank,
Expand All @@ -25,10 +26,10 @@ module idma_address_scrambler #(
input logic [AddrWidth-1:0] address_i,
input logic [31:0] num_bytes_i,
input logic [NumDASPartitions-1:0][$clog2(NumTiles):0] tiles_das_i,
input logic [NumDASPartitions-1:0][$clog2(NumTiles):0] rows_das_i,
input logic [NumDASPartitions-1:0][RowsInterleavingWidth-1:0] rows_das_i,
input logic [NumDASPartitions-1:0][DataWidth-1:0] start_das_i,
output logic [$clog2(NumTiles):0] tiles_das_o,
output logic [$clog2(NumTiles):0] rows_das_o,
output logic [RowsInterleavingWidth:0] rows_das_o,
output logic [AddrWidth-1:0] address_o
);
// Basic Settings
Expand All @@ -45,7 +46,7 @@ module idma_address_scrambler #(
// `tile_index` : how many bits to shift for TileID bits in each partition
// `row_index`: how many bits need to swap within Row Index
logic [NumDASPartitions-1:0][$clog2($clog2(NumTiles)+1)-1:0] tile_index;
logic [NumDASPartitions-1:0][$clog2($clog2(NumTiles)+1)-1:0] row_index;
logic [NumDASPartitions-1:0][$clog2(RowsInterleavingWidth)-1:0] row_index;

for (genvar i = 0; i < NumDASPartitions; i++) begin : gen_shift_index
lzc #(
Expand All @@ -57,12 +58,12 @@ module idma_address_scrambler #(
.empty_o (/* Unused */ )
);
lzc #(
.WIDTH ($clog2(NumTiles)+1),
.WIDTH (RowsInterleavingWidth),
.MODE (1'b0 )
) i_log_row_index (
.in_i (rows_das_i[i][$clog2(NumTiles):0]),
.cnt_o (row_index[i] ),
.empty_o (/* Unused */ )
.in_i (rows_das_i[i]),
.cnt_o (row_index[i] ),
.empty_o (/* Unused */ )
);
end

Expand Down
4 changes: 2 additions & 2 deletions hardware/deps/idma/src/midends/idma_distributed_midend.sv
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ module idma_distributed_midend #(
/// Number of generic 1D requests that can be buffered
parameter int unsigned TransFifoDepth = 1,
`ifdef DAS
parameter int unsigned NumTiles = 64,
parameter int unsigned NumDASPartitions = 4,
parameter int unsigned RowsWidth,
`endif
/// Arbitrary 1D burst request definition
parameter type burst_req_t = logic,
Expand All @@ -32,7 +32,7 @@ module idma_distributed_midend #(
input logic rst_ni,
`ifdef DAS
// DAS signals
input logic [$clog2(NumTiles):0] rows_das_i,
input logic [RowsWidth-1:0] rows_das_i,
`endif
// Slave
input burst_req_t burst_req_i,
Expand Down
15 changes: 10 additions & 5 deletions hardware/deps/idma/src/midends/idma_split_midend.sv
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module idma_split_midend #(
parameter int unsigned NumTiles = 64,
parameter int unsigned NumBanksPerTile = 32,
parameter int unsigned TCDMSizePerBank = 1024,
parameter int unsigned RowsInterleavingWidth = $clog2(TCDMSizePerBank) - 2,
parameter int unsigned NumDASPartitions = 4,
parameter int unsigned DASStartAddr = 1024,
parameter int unsigned NumTilesPerDma = 16,
Expand All @@ -30,8 +31,8 @@ module idma_split_midend #(
// DAS signals
input logic [NumDASPartitions-1:0][$clog2(NumTiles):0] tiles_das_i,
input logic [NumDASPartitions-1:0][AddrWidth-1:0] start_das_i,
input logic [NumDASPartitions-1:0][$clog2(NumTiles):0] rows_das_i,
output logic [$clog2(NumTiles):0] rows_das_o,
input logic [NumDASPartitions-1:0][RowsInterleavingWidth-1:0] rows_das_i,
output logic [RowsInterleavingWidth:0] rows_das_o,
`endif
// Slave
input burst_req_t burst_req_i,
Expand Down Expand Up @@ -80,7 +81,7 @@ module idma_split_midend #(
logic [AddrWidth-1:0] post_scramble_src;
logic [AddrWidth-1:0] post_scramble_dst;
logic [$clog2(NumTiles):0] tiles_das_src, tiles_das_dst, tiles_das_sel;
logic [$clog2(NumTiles):0] rows_das_src, rows_das_dst, rows_das_sel;
logic [RowsInterleavingWidth:0] rows_das_src, rows_das_dst, rows_das_sel;

assign tiles_das_sel = tiles_das_src | tiles_das_dst;
assign rows_das_sel = rows_das_src | rows_das_dst;
Expand All @@ -90,8 +91,10 @@ module idma_split_midend #(
.AddrWidth (AddrWidth ),
.NumTiles (NumTiles ),
.NumBanksPerTile (NumBanksPerTile ),
.RowsInterleavingWidth (RowsInterleavingWidth),
.Bypass (0 ),
.NumDASPartitions (NumDASPartitions),
.DASStartAddr (DASStartAddr ),
.TCDMSizePerBank (TCDMSizePerBank )
) i_idma_address_scrambler_src (
.address_i (burst_req_i.src),
Expand All @@ -108,8 +111,10 @@ module idma_split_midend #(
.AddrWidth (AddrWidth ),
.NumTiles (NumTiles ),
.NumBanksPerTile (NumBanksPerTile ),
.RowsInterleavingWidth (RowsInterleavingWidth),
.Bypass (0 ),
.NumDASPartitions (NumDASPartitions),
.DASStartAddr (DASStartAddr ),
.TCDMSizePerBank (TCDMSizePerBank )
) i_idma_address_scrambler_dst (
.address_i (burst_req_i.dst),
Expand Down Expand Up @@ -173,7 +178,7 @@ module idma_split_midend #(
`FFARN(beat_cnt_q, beat_cnt_d, '0, clk_i, rst_ni)

// log2(rows_das_sel): number of row-index bits in the active partition
logic [$clog2(NumTiles):0] log2_rows;
logic [$clog2(RowsInterleavingWidth+1)-1:0] log2_rows;
// Bitmask to extract row index from the beat counter (lower log2_rows bits)
logic [$clog2(NumTiles):0] row_idx_mask;
// Current row index within the partition (0 .. rows_das-1)
Expand All @@ -182,7 +187,7 @@ module idma_split_midend #(
logic [$clog2(NumTiles):0] col_idx;

lzc #(
.WIDTH ($clog2(NumTiles)+1),
.WIDTH (RowsInterleavingWidth+1),
.MODE (1'b0 )
) i_log2_rows (
.in_i (rows_das_sel),
Expand Down
Loading