From ca167e79c6d80c50a1ce0a927aac82d49f23f455 Mon Sep 17 00:00:00 2001 From: SikongJueluo Date: Sat, 16 May 2026 19:23:49 +0800 Subject: [PATCH] refactor(hw/sim): extract common cocotb make infrastructure into shared mk/ directory - Split monolithic hw/sim/Makefile into modular include files (mk/cocotb-common.mk, mk/rtl-sources.mk) - Add per-module test Makefiles (cam_core_banked, cam_read_noise, cam_write_noise, match_engine_pipeline, perf, top) - Add missing simulation tools (yosys, graphviz, xdot) to devenv.nix - Fix path handling in sweep_noise.py and test modules to be HASH_BITS-aware --- devenv.nix | 24 ++-- hw/sim/Makefile | 111 +++++------------- hw/sim/mk/cocotb-common.mk | 82 +++++++++++++ hw/sim/mk/rtl-sources.mk | 23 ++++ hw/sim/{ => scripts}/sweep_noise.py | 6 + hw/sim/tests/__init__.py | 0 hw/sim/tests/model/__init__.py | 0 .../tests/{ => model}/test_ref_model_noise.py | 0 hw/sim/tests/modules/__init__.py | 0 hw/sim/tests/modules/cam_core_banked/Makefile | 9 ++ .../tests/modules/cam_core_banked/__init__.py | 0 .../cam_core_banked}/test_cam_core_banked.py | 5 +- hw/sim/tests/modules/cam_read_noise/Makefile | 15 +++ .../tests/modules/cam_read_noise/__init__.py | 0 .../cam_read_noise}/test_cam_read_noise.py | 7 +- hw/sim/tests/modules/cam_write_noise/Makefile | 15 +++ .../tests/modules/cam_write_noise/__init__.py | 0 .../cam_write_noise}/test_cam_write_noise.py | 4 +- .../modules/match_engine_pipeline/Makefile | 9 ++ .../modules/match_engine_pipeline/__init__.py | 0 .../test_match_engine_pipeline.py | 4 +- hw/sim/tests/perf/Makefile | 15 +++ hw/sim/tests/perf/__init__.py | 0 hw/sim/tests/{ => perf}/test_cam_perf.py | 0 hw/sim/tests/top/Makefile | 9 ++ hw/sim/tests/top/__init__.py | 0 hw/sim/tests/{ => top}/test_cam_basic.py | 0 27 files changed, 241 insertions(+), 97 deletions(-) create mode 100644 hw/sim/mk/cocotb-common.mk create mode 100644 hw/sim/mk/rtl-sources.mk rename hw/sim/{ => scripts}/sweep_noise.py (95%) create mode 100644 hw/sim/tests/__init__.py create mode 100644 hw/sim/tests/model/__init__.py rename hw/sim/tests/{ => model}/test_ref_model_noise.py (100%) create mode 100644 hw/sim/tests/modules/__init__.py create mode 100644 hw/sim/tests/modules/cam_core_banked/Makefile create mode 100644 hw/sim/tests/modules/cam_core_banked/__init__.py rename hw/sim/tests/{ => modules/cam_core_banked}/test_cam_core_banked.py (87%) create mode 100644 hw/sim/tests/modules/cam_read_noise/Makefile create mode 100644 hw/sim/tests/modules/cam_read_noise/__init__.py rename hw/sim/tests/{ => modules/cam_read_noise}/test_cam_read_noise.py (87%) create mode 100644 hw/sim/tests/modules/cam_write_noise/Makefile create mode 100644 hw/sim/tests/modules/cam_write_noise/__init__.py rename hw/sim/tests/{ => modules/cam_write_noise}/test_cam_write_noise.py (86%) create mode 100644 hw/sim/tests/modules/match_engine_pipeline/Makefile create mode 100644 hw/sim/tests/modules/match_engine_pipeline/__init__.py rename hw/sim/tests/{ => modules/match_engine_pipeline}/test_match_engine_pipeline.py (95%) create mode 100644 hw/sim/tests/perf/Makefile create mode 100644 hw/sim/tests/perf/__init__.py rename hw/sim/tests/{ => perf}/test_cam_perf.py (100%) create mode 100644 hw/sim/tests/top/Makefile create mode 100644 hw/sim/tests/top/__init__.py rename hw/sim/tests/{ => top}/test_cam_basic.py (100%) diff --git a/devenv.nix b/devenv.nix index 21671b2..4af7147 100644 --- a/devenv.nix +++ b/devenv.nix @@ -4,20 +4,26 @@ config, inputs, ... -}: let +}: +let pkgs-nixgl = (import inputs.nixpkgs { system = pkgs.stdenv.hostPlatform.system; config.allowUnfree = true; - overlays = [inputs.nixgl.overlay]; - }).nixgl.override { - nvidiaVersionFile = "/proc/driver/nvidia/version"; - nvidiaVersion = "580.126.09"; - }; -in { + overlays = [ inputs.nixgl.overlay ]; + }).nixgl.override + { + nvidiaVersionFile = "/proc/driver/nvidia/version"; + nvidiaVersion = "580.126.09"; + }; +in +{ packages = with pkgs; [ - nil - verilator + nil + verilator + yosys + graphviz + xdot ]; enterShell = '' diff --git a/hw/sim/Makefile b/hw/sim/Makefile index 0156073..7117b5b 100644 --- a/hw/sim/Makefile +++ b/hw/sim/Makefile @@ -1,90 +1,41 @@ -SIM ?= verilator -TOPLEVEL_LANG ?= verilog -TOPLEVEL ?= cam_top +MODULE_TESTS := cam_core_banked match_engine_pipeline cam_write_noise cam_read_noise -COCOTB_TEST_MODULES ?= tests.test_cam_basic +.PHONY: help test-all test-top test-modules test-module test-model test-perf clean $(MODULE_TESTS:%=test-module-%) -NUM_ROWS ?= 4096 -HASH_BITS ?= 512 -LANES ?= 8 +help: + @echo "Available hw/sim targets:" + @echo " make test-model" + @echo " make test-top" + @echo " make test-module MODULE=cam_core_banked" + @echo " make test-modules" + @echo " make test-perf" + @echo " make test-all" + @echo " make clean" -EXTRA_ARGS += +define+NUM_ROWS=$(NUM_ROWS) +define+HASH_BITS=$(HASH_BITS) +define+LANES=$(LANES) +test-all: test-model test-top test-modules -COMPILE_ARGS += -Wall -Wno-fatal -COMPILE_ARGS += -I$(PWD)/../rtl -I$(PWD)/../rtl/core -I$(PWD)/../rtl/noise -COMPILE_ARGS += +define+SIM_DEBUG -COMPILE_ARGS += $(EXTRA_DEFINES) +test-top: + $(MAKE) -C tests/top -# Noise parameters — only passed when explicitly set (non-empty). -# For cam_noisy/cam_top tests, pass WRITE_NOISE_*=... READ_NOISE_*=... -# For individual module tests, leave them unset to skip. -WRITE_NOISE_EN ?= $(NOISE_EN) -WRITE_NOISE_RATE_NUM ?= $(NOISE_RATE_NUM) -WRITE_NOISE_RATE_DEN ?= $(NOISE_RATE_DEN) -WRITE_NOISE_BITS ?= $(NOISE_BITS) -READ_NOISE_EN ?= -READ_NOISE_RATE_NUM ?= -READ_NOISE_RATE_DEN ?= -READ_NOISE_BITS ?= +test-modules: $(MODULE_TESTS:%=test-module-%) -# Perf-test compatibility override: when running cam_perf, force deterministic -# noise parameters so noise_mask_grouped.sv elaborates correctly for perf -# sweep HASH_BITS values (64, 128, 192, 256, 320, 384, 448, 512 — all -# divisible by 64 such that HASH_BITS / NOISE_BITS == 64 in the RTL). -# This is a testbench parameter, not a hardware performance/resource claim. -ifeq ($(COCOTB_TEST_MODULES),tests.test_cam_perf) -WRITE_NOISE_EN := 0 -READ_NOISE_EN := 0 -WRITE_NOISE_BITS := $(shell echo $$(( $(HASH_BITS) / 64 ))) -READ_NOISE_BITS := $(shell echo $$(( $(HASH_BITS) / 64 ))) -endif +test-module: + @test -n "$(MODULE)" || (echo "Usage: make test-module MODULE="; exit 2) + $(MAKE) -C tests/modules/$(MODULE) -ifneq ($(strip $(WRITE_NOISE_EN)),) -COMPILE_ARGS += -GWRITE_NOISE_EN=$(WRITE_NOISE_EN) -endif -ifneq ($(strip $(WRITE_NOISE_RATE_NUM)),) -COMPILE_ARGS += -GWRITE_NOISE_RATE_NUM=$(WRITE_NOISE_RATE_NUM) -endif -ifneq ($(strip $(WRITE_NOISE_RATE_DEN)),) -COMPILE_ARGS += -GWRITE_NOISE_RATE_DEN=$(WRITE_NOISE_RATE_DEN) -endif -ifneq ($(strip $(WRITE_NOISE_BITS)),) -COMPILE_ARGS += -GWRITE_NOISE_BITS=$(WRITE_NOISE_BITS) -endif -ifneq ($(strip $(READ_NOISE_EN)),) -COMPILE_ARGS += -GREAD_NOISE_EN=$(READ_NOISE_EN) -endif -ifneq ($(strip $(READ_NOISE_RATE_NUM)),) -COMPILE_ARGS += -GREAD_NOISE_RATE_NUM=$(READ_NOISE_RATE_NUM) -endif -ifneq ($(strip $(READ_NOISE_RATE_DEN)),) -COMPILE_ARGS += -GREAD_NOISE_RATE_DEN=$(READ_NOISE_RATE_DEN) -endif -ifneq ($(strip $(READ_NOISE_BITS)),) -COMPILE_ARGS += -GREAD_NOISE_BITS=$(READ_NOISE_BITS) -endif +$(MODULE_TESTS:%=test-module-%): + $(MAKE) -C tests/modules/$(@:test-module-%=%) -# Cleaner terminal output -export QUIET ?= 1 -export VERBOSE ?= 0 -export COCOTB_LOG_LEVEL ?= INFO -export PYTHONWARNINGS ?= ignore::pytest.PytestDeprecationWarning +test-model: + uv run pytest tests/model -q -# Optional temporary suppression -SUPPRESS_VERILATOR_WARNINGS ?= 0 -ifeq ($(SUPPRESS_VERILATOR_WARNINGS),1) -COMPILE_ARGS += -Wno-WIDTHEXPAND -COMPILE_ARGS += -Wno-UNOPTFLAT -endif +test-perf: + $(MAKE) -C tests/perf -VERILOG_SOURCES += $(PWD)/../rtl/random/random128.sv -VERILOG_SOURCES += $(PWD)/../rtl/noise/noise_mask_grouped.sv -VERILOG_SOURCES += $(PWD)/../rtl/core/cam_core_banked.sv -VERILOG_SOURCES += $(PWD)/../rtl/noise/cam_write_noise.sv -VERILOG_SOURCES += $(PWD)/../rtl/noise/cam_read_noise.sv -VERILOG_SOURCES += $(PWD)/../rtl/core/popcount_pipeline.sv -VERILOG_SOURCES += $(PWD)/../rtl/core/match_engine_pipeline.sv -VERILOG_SOURCES += $(PWD)/../rtl/cam_noisy.sv -VERILOG_SOURCES += $(PWD)/../rtl/cam_top.sv - -include $(shell uv run cocotb-config --makefiles)/Makefile.sim +clean: + $(MAKE) -C tests/top clean + @for module in $(MODULE_TESTS); do \ + $(MAKE) -C tests/modules/$$module clean || exit $$?; \ + done + $(MAKE) -C tests/perf clean + rm -rf .pytest_cache tests/model/.pytest_cache diff --git a/hw/sim/mk/cocotb-common.mk b/hw/sim/mk/cocotb-common.mk new file mode 100644 index 0000000..29f8003 --- /dev/null +++ b/hw/sim/mk/cocotb-common.mk @@ -0,0 +1,82 @@ +ifndef SIM_ROOT +$(error SIM_ROOT must be set before including mk/cocotb-common.mk) +endif + +ifndef RTL_ROOT +$(error RTL_ROOT must be set before including mk/cocotb-common.mk) +endif + +ifndef TOPLEVEL +$(error TOPLEVEL must be set before including mk/cocotb-common.mk) +endif + +ifndef COCOTB_TEST_MODULES +$(error COCOTB_TEST_MODULES must be set before including mk/cocotb-common.mk) +endif + +ifndef VERILOG_SOURCES +$(error VERILOG_SOURCES must be set before including mk/cocotb-common.mk) +endif + +SIM ?= verilator +TOPLEVEL_LANG ?= verilog + +NUM_ROWS ?= 4096 +HASH_BITS ?= 512 +LANES ?= 8 + +EXTRA_ARGS += +define+NUM_ROWS=$(NUM_ROWS) +define+HASH_BITS=$(HASH_BITS) +define+LANES=$(LANES) +EXTRA_ARGS += --trace --trace-fst --trace-structs + +COMPILE_ARGS += -Wall -Wno-fatal +COMPILE_ARGS += -I$(RTL_ROOT) -I$(RTL_ROOT)/core -I$(RTL_ROOT)/noise -I$(RTL_ROOT)/random +COMPILE_ARGS += +define+SIM_DEBUG +COMPILE_ARGS += $(EXTRA_DEFINES) + +WRITE_NOISE_EN ?= $(NOISE_EN) +WRITE_NOISE_RATE_NUM ?= $(NOISE_RATE_NUM) +WRITE_NOISE_RATE_DEN ?= $(NOISE_RATE_DEN) +WRITE_NOISE_BITS ?= $(NOISE_BITS) +READ_NOISE_EN ?= +READ_NOISE_RATE_NUM ?= +READ_NOISE_RATE_DEN ?= +READ_NOISE_BITS ?= + +ifneq ($(strip $(WRITE_NOISE_EN)),) +COMPILE_ARGS += -GWRITE_NOISE_EN=$(WRITE_NOISE_EN) +endif +ifneq ($(strip $(WRITE_NOISE_RATE_NUM)),) +COMPILE_ARGS += -GWRITE_NOISE_RATE_NUM=$(WRITE_NOISE_RATE_NUM) +endif +ifneq ($(strip $(WRITE_NOISE_RATE_DEN)),) +COMPILE_ARGS += -GWRITE_NOISE_RATE_DEN=$(WRITE_NOISE_RATE_DEN) +endif +ifneq ($(strip $(WRITE_NOISE_BITS)),) +COMPILE_ARGS += -GWRITE_NOISE_BITS=$(WRITE_NOISE_BITS) +endif +ifneq ($(strip $(READ_NOISE_EN)),) +COMPILE_ARGS += -GREAD_NOISE_EN=$(READ_NOISE_EN) +endif +ifneq ($(strip $(READ_NOISE_RATE_NUM)),) +COMPILE_ARGS += -GREAD_NOISE_RATE_NUM=$(READ_NOISE_RATE_NUM) +endif +ifneq ($(strip $(READ_NOISE_RATE_DEN)),) +COMPILE_ARGS += -GREAD_NOISE_RATE_DEN=$(READ_NOISE_RATE_DEN) +endif +ifneq ($(strip $(READ_NOISE_BITS)),) +COMPILE_ARGS += -GREAD_NOISE_BITS=$(READ_NOISE_BITS) +endif + +export PYTHONPATH := $(SIM_ROOT):$(PYTHONPATH) +export QUIET ?= 1 +export VERBOSE ?= 0 +export COCOTB_LOG_LEVEL ?= INFO +export PYTHONWARNINGS ?= ignore::pytest.PytestDeprecationWarning + +SUPPRESS_VERILATOR_WARNINGS ?= 0 +ifeq ($(SUPPRESS_VERILATOR_WARNINGS),1) +COMPILE_ARGS += -Wno-WIDTHEXPAND +COMPILE_ARGS += -Wno-UNOPTFLAT +endif + +include $(shell uv run cocotb-config --makefiles)/Makefile.sim diff --git a/hw/sim/mk/rtl-sources.mk b/hw/sim/mk/rtl-sources.mk new file mode 100644 index 0000000..b38827c --- /dev/null +++ b/hw/sim/mk/rtl-sources.mk @@ -0,0 +1,23 @@ +ifndef RTL_ROOT +$(error RTL_ROOT must be set before including mk/rtl-sources.mk) +endif + +RTL_RANDOM := $(RTL_ROOT)/random/random128.sv + +RTL_NOISE_MASK := $(RTL_ROOT)/noise/noise_mask_grouped.sv +RTL_WRITE_NOISE := $(RTL_NOISE_MASK) $(RTL_RANDOM) $(RTL_ROOT)/noise/cam_write_noise.sv +RTL_READ_NOISE := $(RTL_NOISE_MASK) $(RTL_RANDOM) $(RTL_ROOT)/noise/cam_read_noise.sv + +RTL_CAM_CORE_BANKED := $(RTL_ROOT)/core/cam_core_banked.sv +RTL_MATCH_ENGINE := \ + $(RTL_ROOT)/core/popcount_pipeline.sv \ + $(RTL_ROOT)/core/match_engine_pipeline.sv + +RTL_CAM_NOISY := \ + $(RTL_CAM_CORE_BANKED) \ + $(RTL_WRITE_NOISE) \ + $(RTL_READ_NOISE) \ + $(RTL_MATCH_ENGINE) \ + $(RTL_ROOT)/cam_noisy.sv + +RTL_CAM_TOP := $(RTL_CAM_NOISY) $(RTL_ROOT)/cam_top.sv diff --git a/hw/sim/sweep_noise.py b/hw/sim/scripts/sweep_noise.py similarity index 95% rename from hw/sim/sweep_noise.py rename to hw/sim/scripts/sweep_noise.py index d852246..33135f6 100644 --- a/hw/sim/sweep_noise.py +++ b/hw/sim/scripts/sweep_noise.py @@ -7,6 +7,12 @@ then queries the noisy rows and compares top-1 results against clean rows. from __future__ import annotations import argparse +import sys +from pathlib import Path + +SIM_ROOT = Path(__file__).resolve().parents[1] +if str(SIM_ROOT) not in sys.path: + sys.path.insert(0, str(SIM_ROOT)) import numpy as np from model.ref_model import ( diff --git a/hw/sim/tests/__init__.py b/hw/sim/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/model/__init__.py b/hw/sim/tests/model/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/test_ref_model_noise.py b/hw/sim/tests/model/test_ref_model_noise.py similarity index 100% rename from hw/sim/tests/test_ref_model_noise.py rename to hw/sim/tests/model/test_ref_model_noise.py diff --git a/hw/sim/tests/modules/__init__.py b/hw/sim/tests/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/modules/cam_core_banked/Makefile b/hw/sim/tests/modules/cam_core_banked/Makefile new file mode 100644 index 0000000..a3b84fd --- /dev/null +++ b/hw/sim/tests/modules/cam_core_banked/Makefile @@ -0,0 +1,9 @@ +SIM_ROOT := $(abspath ../../..) +RTL_ROOT := $(abspath $(SIM_ROOT)/../rtl) +include $(SIM_ROOT)/mk/rtl-sources.mk + +TOPLEVEL := cam_core_banked +COCOTB_TEST_MODULES := tests.modules.cam_core_banked.test_cam_core_banked +VERILOG_SOURCES := $(RTL_CAM_CORE_BANKED) + +include $(SIM_ROOT)/mk/cocotb-common.mk diff --git a/hw/sim/tests/modules/cam_core_banked/__init__.py b/hw/sim/tests/modules/cam_core_banked/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/test_cam_core_banked.py b/hw/sim/tests/modules/cam_core_banked/test_cam_core_banked.py similarity index 87% rename from hw/sim/tests/test_cam_core_banked.py rename to hw/sim/tests/modules/cam_core_banked/test_cam_core_banked.py index d2757d6..43341f0 100644 --- a/hw/sim/tests/test_cam_core_banked.py +++ b/hw/sim/tests/modules/cam_core_banked/test_cam_core_banked.py @@ -24,8 +24,9 @@ async def banked_core_reads_aligned_eight_row_batch_after_one_cycle(dut): cocotb.start_soon(Clock(dut.clk, 10, unit="ns").start()) await reset_core(dut) - LANES = 8 + LANES = len(dut.rd_lane_valid_o) ROW_BITS = len(dut.rd_row_ids_o) // LANES + HASH_BITS = len(dut.rd_hashes_o) // LANES for row in range(LANES): dut.wr_valid.value = 1 @@ -43,6 +44,6 @@ async def banked_core_reads_aligned_eight_row_batch_after_one_cycle(dut): assert int(dut.rd_valid_o.value) == 1 for lane in range(LANES): got_row = (int(dut.rd_row_ids_o.value) >> (lane * ROW_BITS)) & ((1 << ROW_BITS) - 1) - got_hash = (int(dut.rd_hashes_o.value) >> (lane * 512)) & ((1 << 512) - 1) + got_hash = (int(dut.rd_hashes_o.value) >> (lane * HASH_BITS)) & ((1 << HASH_BITS) - 1) assert got_row == lane assert got_hash == lane + 0x100 diff --git a/hw/sim/tests/modules/cam_read_noise/Makefile b/hw/sim/tests/modules/cam_read_noise/Makefile new file mode 100644 index 0000000..8eb63dd --- /dev/null +++ b/hw/sim/tests/modules/cam_read_noise/Makefile @@ -0,0 +1,15 @@ +SIM_ROOT := $(abspath ../../..) +RTL_ROOT := $(abspath $(SIM_ROOT)/../rtl) +include $(SIM_ROOT)/mk/rtl-sources.mk + +TOPLEVEL := cam_read_noise +COCOTB_TEST_MODULES := tests.modules.cam_read_noise.test_cam_read_noise +VERILOG_SOURCES := $(RTL_READ_NOISE) + +HASH_BITS ?= 512 +READ_NOISE_EN ?= 0 +READ_NOISE_RATE_NUM ?= 0 +READ_NOISE_RATE_DEN ?= 100 +READ_NOISE_BITS ?= $(shell echo $$(( $(HASH_BITS) / 64 ))) + +include $(SIM_ROOT)/mk/cocotb-common.mk diff --git a/hw/sim/tests/modules/cam_read_noise/__init__.py b/hw/sim/tests/modules/cam_read_noise/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/test_cam_read_noise.py b/hw/sim/tests/modules/cam_read_noise/test_cam_read_noise.py similarity index 87% rename from hw/sim/tests/test_cam_read_noise.py rename to hw/sim/tests/modules/cam_read_noise/test_cam_read_noise.py index bd635b0..f171623 100644 --- a/hw/sim/tests/test_cam_read_noise.py +++ b/hw/sim/tests/modules/cam_read_noise/test_cam_read_noise.py @@ -23,9 +23,10 @@ async def read_noise_disabled_forwards_hashes_after_one_stage(dut): cocotb.start_soon(Clock(dut.clk, 10, unit="ns").start()) await reset_read_noise(dut) - LANES = 8 + LANES = len(dut.lane_valid_i) ROW_BITS = len(dut.row_ids_i) // LANES HASH_BITS_PER_LANE = len(dut.hashes_i) // LANES + all_lanes_valid = (1 << LANES) - 1 hashes = 0 rows = 0 @@ -35,7 +36,7 @@ async def read_noise_disabled_forwards_hashes_after_one_stage(dut): dut.hashes_i.value = hashes dut.row_ids_i.value = rows - dut.lane_valid_i.value = 0xFF + dut.lane_valid_i.value = all_lanes_valid dut.valid_i.value = 1 await RisingEdge(dut.clk) dut.valid_i.value = 0 @@ -45,4 +46,4 @@ async def read_noise_disabled_forwards_hashes_after_one_stage(dut): assert int(dut.valid_o.value) == 1 assert int(dut.hashes_noisy_o.value) == hashes assert int(dut.row_ids_o.value) == rows - assert int(dut.lane_valid_o.value) == 0xFF + assert int(dut.lane_valid_o.value) == all_lanes_valid diff --git a/hw/sim/tests/modules/cam_write_noise/Makefile b/hw/sim/tests/modules/cam_write_noise/Makefile new file mode 100644 index 0000000..e3ae76e --- /dev/null +++ b/hw/sim/tests/modules/cam_write_noise/Makefile @@ -0,0 +1,15 @@ +SIM_ROOT := $(abspath ../../..) +RTL_ROOT := $(abspath $(SIM_ROOT)/../rtl) +include $(SIM_ROOT)/mk/rtl-sources.mk + +TOPLEVEL := cam_write_noise +COCOTB_TEST_MODULES := tests.modules.cam_write_noise.test_cam_write_noise +VERILOG_SOURCES := $(RTL_WRITE_NOISE) + +HASH_BITS ?= 512 +WRITE_NOISE_EN ?= 1 +WRITE_NOISE_RATE_NUM ?= 1 +WRITE_NOISE_RATE_DEN ?= 100 +WRITE_NOISE_BITS ?= $(shell echo $$(( $(HASH_BITS) / 64 ))) + +include $(SIM_ROOT)/mk/cocotb-common.mk diff --git a/hw/sim/tests/modules/cam_write_noise/__init__.py b/hw/sim/tests/modules/cam_write_noise/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/test_cam_write_noise.py b/hw/sim/tests/modules/cam_write_noise/test_cam_write_noise.py similarity index 86% rename from hw/sim/tests/test_cam_write_noise.py rename to hw/sim/tests/modules/cam_write_noise/test_cam_write_noise.py index 591ed00..0b635a8 100644 --- a/hw/sim/tests/test_cam_write_noise.py +++ b/hw/sim/tests/modules/cam_write_noise/test_cam_write_noise.py @@ -34,6 +34,8 @@ async def write_noise_outputs_grouped_noisy_hash(dut): await RisingEdge(dut.clk) seed = 0xB504_F32D_B504_F32D - flip, _ = generate_write_flip_mask((seed << 64) | seed, 512, 8, 1, 100) + hash_bits = len(dut.wr_hash) + noise_bits = hash_bits // 64 + flip, _ = generate_write_flip_mask((seed << 64) | seed, hash_bits, noise_bits, 1, 100) assert int(dut.core_wr_row.value) == 3 assert int(dut.core_wr_hash.value) == (value ^ flip) diff --git a/hw/sim/tests/modules/match_engine_pipeline/Makefile b/hw/sim/tests/modules/match_engine_pipeline/Makefile new file mode 100644 index 0000000..8509d40 --- /dev/null +++ b/hw/sim/tests/modules/match_engine_pipeline/Makefile @@ -0,0 +1,9 @@ +SIM_ROOT := $(abspath ../../..) +RTL_ROOT := $(abspath $(SIM_ROOT)/../rtl) +include $(SIM_ROOT)/mk/rtl-sources.mk + +TOPLEVEL := match_engine_pipeline +COCOTB_TEST_MODULES := tests.modules.match_engine_pipeline.test_match_engine_pipeline +VERILOG_SOURCES := $(RTL_MATCH_ENGINE) + +include $(SIM_ROOT)/mk/cocotb-common.mk diff --git a/hw/sim/tests/modules/match_engine_pipeline/__init__.py b/hw/sim/tests/modules/match_engine_pipeline/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/test_match_engine_pipeline.py b/hw/sim/tests/modules/match_engine_pipeline/test_match_engine_pipeline.py similarity index 95% rename from hw/sim/tests/test_match_engine_pipeline.py rename to hw/sim/tests/modules/match_engine_pipeline/test_match_engine_pipeline.py index c3961e4..909e330 100644 --- a/hw/sim/tests/test_match_engine_pipeline.py +++ b/hw/sim/tests/modules/match_engine_pipeline/test_match_engine_pipeline.py @@ -26,7 +26,7 @@ async def match_engine_returns_top1_after_pipeline_drain(dut): cocotb.start_soon(Clock(dut.clk, 10, unit="ns").start()) await reset_match(dut) - LANES = 8 + LANES = len(dut.rd_lane_valid_i) ROW_BITS = len(dut.rd_row_ids_i) // LANES HASH_BITS = len(dut.rd_hashes_i) // LANES NUM_ROWS = 1 << len(dut.rd_base_row_o) @@ -51,7 +51,7 @@ async def match_engine_returns_top1_after_pipeline_drain(dut): hashes |= row_hash << (lane * HASH_BITS) dut.rd_row_ids_i.value = rows dut.rd_hashes_i.value = hashes - dut.rd_lane_valid_i.value = 0xFF + dut.rd_lane_valid_i.value = (1 << LANES) - 1 dut.rd_valid_i.value = 1 await RisingEdge(dut.clk) dut.rd_valid_i.value = 0 diff --git a/hw/sim/tests/perf/Makefile b/hw/sim/tests/perf/Makefile new file mode 100644 index 0000000..cbdbd3b --- /dev/null +++ b/hw/sim/tests/perf/Makefile @@ -0,0 +1,15 @@ +SIM_ROOT := $(abspath ../..) +RTL_ROOT := $(abspath $(SIM_ROOT)/../rtl) +include $(SIM_ROOT)/mk/rtl-sources.mk + +TOPLEVEL := cam_top +COCOTB_TEST_MODULES := tests.perf.test_cam_perf +VERILOG_SOURCES := $(RTL_CAM_TOP) + +HASH_BITS ?= 512 +WRITE_NOISE_EN := 0 +READ_NOISE_EN := 0 +WRITE_NOISE_BITS := $(shell echo $$(( $(HASH_BITS) / 64 ))) +READ_NOISE_BITS := $(shell echo $$(( $(HASH_BITS) / 64 ))) + +include $(SIM_ROOT)/mk/cocotb-common.mk diff --git a/hw/sim/tests/perf/__init__.py b/hw/sim/tests/perf/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/test_cam_perf.py b/hw/sim/tests/perf/test_cam_perf.py similarity index 100% rename from hw/sim/tests/test_cam_perf.py rename to hw/sim/tests/perf/test_cam_perf.py diff --git a/hw/sim/tests/top/Makefile b/hw/sim/tests/top/Makefile new file mode 100644 index 0000000..1aca101 --- /dev/null +++ b/hw/sim/tests/top/Makefile @@ -0,0 +1,9 @@ +SIM_ROOT := $(abspath ../..) +RTL_ROOT := $(abspath $(SIM_ROOT)/../rtl) +include $(SIM_ROOT)/mk/rtl-sources.mk + +TOPLEVEL := cam_top +COCOTB_TEST_MODULES := tests.top.test_cam_basic +VERILOG_SOURCES := $(RTL_CAM_TOP) + +include $(SIM_ROOT)/mk/cocotb-common.mk diff --git a/hw/sim/tests/top/__init__.py b/hw/sim/tests/top/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hw/sim/tests/test_cam_basic.py b/hw/sim/tests/top/test_cam_basic.py similarity index 100% rename from hw/sim/tests/test_cam_basic.py rename to hw/sim/tests/top/test_cam_basic.py