PYTHON ?= python3
VERILATOR ?= verilator

.DEFAULT_GOAL := test
TRACE_FLAGS = $(if $(filter 1,$(TRACE)),--trace -DENABLE_TRACE,)
SIGMOID_DUT ?= vsrc/src/sigmoid.v
PE_DUT ?= vsrc/src/pe.v
SYSTOLIC_DUT ?= vsrc/src/systolic_array.v vsrc/src/pe.v

.PHONY: test pe systolic sigmoid sigmoid-vectors clean

define run_all_checks
	+@mkdir -p build; failed=""; \
	for part in $(1); do \
		printf 'Running %s...\n' "$$part"; \
		if $(MAKE) $$part > "build/$${part}_test.log" 2>&1; then \
			printf 'PASS: %s\n' "$$part"; \
		else failed="$$failed $$part"; fi; \
	done; \
	if [ -n "$$failed" ]; then \
		for part in $$failed; do \
			awk -v part="$$part" '/^FAIL:/ { print; found=1 } END { if (!found) print "FAIL: " part " (see build/" part "_test.log)" }' "build/$${part}_test.log"; \
		done; \
		exit 1; \
	fi
endef

test:
	$(call run_all_checks,sigmoid pe systolic)

sigmoid-vectors:
	mkdir -p build
	$(PYTHON) scripts/generate_vectors.py --output build/vectors_q5_11.hex \
		--schedule build/sigmoid_schedule.hex

sigmoid: sigmoid-vectors
	rm -rf build/sigmoid_obj_dir
	$(VERILATOR) --binary --timing --top-module tb_sigmoid -Wno-fatal $(TRACE_FLAGS) \
		-Mdir build/sigmoid_obj_dir vsrc/sim/tb_sigmoid.sv $(SIGMOID_DUT)
	build/sigmoid_obj_dir/Vtb_sigmoid
	$(PYTHON) scripts/test.py --vectors build/vectors_q5_11.hex \
		--schedule build/sigmoid_schedule.hex --results build/sigmoid_results.txt

pe:
	mkdir -p build
	rm -rf build/pe_obj_dir
	$(VERILATOR) --binary --timing --top-module tb_pe -Wno-fatal $(TRACE_FLAGS) \
		-Mdir build/pe_obj_dir vsrc/sim/tb_pe.sv $(PE_DUT)
	build/pe_obj_dir/Vtb_pe
	@test "$$(cat build/pe_status.txt)" = PASS

systolic:
	mkdir -p build
	$(PYTHON) scripts/generate_systolic_vectors.py --output build/systolic_cases.hex
	rm -rf build/systolic_obj_dir
	$(VERILATOR) --binary --timing --top-module tb_systolic_array -Wno-fatal $(TRACE_FLAGS) \
		-Mdir build/systolic_obj_dir vsrc/sim/tb_systolic_array.sv \
		$(SYSTOLIC_DUT)
	build/systolic_obj_dir/Vtb_systolic_array
	$(PYTHON) scripts/check_systolic.py --vectors build/systolic_cases.hex --results build/systolic_results.txt

clean:
	rm -rf build
