nutshell-cache-verification/Makefile

122 lines
4.7 KiB
Makefile

VSRC_DIR := ./rtl
PICKER ?= picker
NAME := Cache
NAME_L := cache
SIM := verilator
WAVE_FORMAT := fst
TARGET_LANG := python
PYTHON ?= $(shell if command -v python3.11 >/dev/null 2>&1; then command -v python3.11; elif [ -x /opt/homebrew/opt/python@3.11/bin/python3.11 ]; then echo /opt/homebrew/opt/python@3.11/bin/python3.11; else command -v python3; fi)
PYTEST ?= $(PYTHON) -m pytest
PYTHON_ROOT ?= $(shell "$(PYTHON)" -c 'import sys; print(sys.prefix)' 2>/dev/null || true)
CMAKE_ARGS ?= -DPython3_ROOT_DIR=$(PYTHON_ROOT)
PYTHONPATH_BASE := .:./src:./$(NAME):$(HOME)/.local/share/picker/python
BUG ?= mask_merge
BUG_RTL := faults/Cache_$(BUG)_bug.v
FAULT_TESTS ?= tests/test_smoke.py tests/test_directed.py
export PATH := $(HOME)/.local/bin:$(PATH)
export PYTHONPATH := $(PYTHONPATH_BASE):$(PYTHONPATH)
.PHONY: help setup env-check gen_dut ensure-dut test test-model test-hw regression report rtl-coverage coverage clean wave inject-bug inject-mask-bug fault-audit fault-audit-all
help:
@echo "NutShell Cache verification targets:"
@echo " make setup - install Python dependencies"
@echo " make env-check - print Picker/Verilator/Toffee environment"
@echo " make gen_dut - build Picker Python DUT package from rtl/Cache.v"
@echo " make test-model - run pure Python generator/oracle/scoreboard tests"
@echo " make test-hw - run Toffee hardware tests (requires gen_dut)"
@echo " make regression - model tests + gen_dut + hardware tests"
@echo " make report - regenerate functional coverage helper artifacts"
@echo " make rtl-coverage - generate Verilator RTL code coverage report"
@echo " make inject-bug BUG=mask_merge|mmio_decode|read_data_lsb"
@echo " make fault-audit BUG=mask_merge - build a mutant, expect tests to fail, then restore golden DUT"
@echo " make fault-audit-all - run all supported RTL mutant audits"
setup:
$(PYTHON) -m pip install -r requirements.txt
env-check:
@PYTHON="$(PYTHON)" PICKER="$(PICKER)" ./scripts/check_env.sh
gen_dut:
@rm -rf $(NAME)
$(PICKER) export --autobuild=false $(VSRC_DIR)/$(NAME).v \
-w $(NAME).$(WAVE_FORMAT) \
--sname $(NAME) \
--tdir $(NAME) \
--lang $(TARGET_LANG) \
--sim $(SIM) \
-e -c
$(PYTHON) scripts/patch_picker_makefiles.py $(NAME)
CMAKE_ARGS="$(CMAKE_ARGS)" make -C $(NAME)
ensure-dut:
@if [ ! -d "$(NAME)" ]; then \
echo "ERROR: missing Picker DUT package '$(NAME)/'. Run 'make gen_dut' before hardware tests."; \
exit 1; \
fi
@$(PYTHON) scripts/check_dut_import.py
test: test-model test-hw
test-model:
$(PYTEST) -q tests/test_model_unit.py
test-hw: ensure-dut
$(PYTEST) -q tests/test_smoke.py tests/test_directed.py tests/test_coherence.py tests/test_coverage_stress.py tests/test_random_crv.py
regression: test-model gen_dut test-hw
report:
PYTHONPATH=$(PYTHONPATH_BASE) $(PYTHON) scripts/run_model_regression.py --json reports/model_coverage.json --md reports/model_coverage.md
rtl-coverage:
./scripts/run_rtl_coverage.sh reports/rtl_coverage reports/rtl_coverage_summary.md
coverage: report rtl-coverage
wave:
gtkwave -r .gtkwaverc $(NAME_L).$(WAVE_FORMAT)
inject-mask-bug:
$(PYTHON) scripts/inject_bug.py --bug mask_merge --output faults/Cache_mask_merge_bug.v
inject-bug:
$(PYTHON) scripts/inject_bug.py --bug $(BUG) --output $(BUG_RTL)
fault-audit: inject-bug
@mkdir -p reports
@rm -rf $(NAME)
@$(PICKER) export --autobuild=false $(BUG_RTL) \
-w $(NAME).$(WAVE_FORMAT) \
--sname $(NAME) \
--tdir $(NAME) \
--lang $(TARGET_LANG) \
--sim $(SIM) \
-e -c > reports/fault_$(BUG)_build.log 2>&1
@$(PYTHON) scripts/patch_picker_makefiles.py $(NAME) >> reports/fault_$(BUG)_build.log 2>&1
@CMAKE_ARGS="$(CMAKE_ARGS)" make -C $(NAME) >> reports/fault_$(BUG)_build.log 2>&1
@set +e; $(PYTEST) -q $(FAULT_TESTS) > reports/fault_$(BUG)_pytest.log 2>&1; rc=$$?; set -e; \
{ \
echo "# Fault Injection Audit: $(BUG)"; \
echo; \
echo "Command: \`pytest -q $(FAULT_TESTS)\`"; \
echo; \
if [ $$rc -eq 0 ]; then echo "Result: **FAILED AUDIT** — mutant survived."; else echo "Result: **PASS** — mutant killed; pytest exit code $$rc."; fi; \
echo; \
echo "\`\`\`text"; \
tail -80 reports/fault_$(BUG)_pytest.log; \
echo "\`\`\`"; \
} > reports/fault_$(BUG)_audit.md; \
make gen_dut > reports/golden_rebuild.log 2>&1; \
if [ $$rc -eq 0 ]; then echo "ERROR: mutant $(BUG) survived"; exit 1; else echo "PASS: mutant $(BUG) killed and golden DUT restored"; fi
fault-audit-all:
$(MAKE) fault-audit BUG=mask_merge
$(MAKE) fault-audit BUG=mmio_decode
$(MAKE) fault-audit BUG=read_data_lsb
clean:
-rm -rf $(NAME) *.dat *.fst *.vcd reports/*.log reports/*.xml reports/*.html .pytest_cache __pycache__ src/**/__pycache__ tests/**/__pycache__