.PHONY: help sim phase1 phase2 sim-lms sim-i2s qsys qsys-component qsys-clean quartus program rbf dtb phase5-check flash flash-sd clean deploy

PROJECT_NAME := soc_system
QUARTUS_DIR := quartus
OUTPUT_DIR := $(QUARTUS_DIR)/output_files
SOF := $(OUTPUT_DIR)/$(PROJECT_NAME).sof
RBF := $(OUTPUT_DIR)/$(PROJECT_NAME).rbf
DTB := $(OUTPUT_DIR)/$(PROJECT_NAME).dtb
PATCHED_DTB := $(OUTPUT_DIR)/$(PROJECT_NAME)_patched.dtb
PATCHED_DTS := $(OUTPUT_DIR)/$(PROJECT_NAME)_patched.dts
EMBEDDED_SHELL := /tools/intel/intelFPGA/21.1/embedded/embedded_command_shell.sh

help:
	@echo "Real-Time Two-Microphone Adaptive Noise Cancellation"
	@echo
	@echo "Targets:"
	@echo "  make sim             Run workstation Verilator simulations"
	@echo "  make qsys-component  Register/generate the Platform Designer component"
	@echo "  make qsys            Regenerate the Platform Designer system"
	@echo "  make quartus         Run full Quartus compilation"
	@echo "  make phase1          Run Phase 1 skeleton checks"
	@echo "  make phase2          Run Phase 2 LMS simulation"
	@echo "  make sim-lms         Run the Phase 2 LMS Verilator testbench"
	@echo "  make sim-i2s         Run the Phase 3 I2S loopback testbench"
	@echo "  make program         JTAG-load quartus/output_files/$(PROJECT_NAME).sof"
	@echo "  make rbf             Convert the .sof into an SD-bootable .rbf"
	@echo "  make dtb             Generate or verify quartus/output_files/$(PROJECT_NAME).dtb"
	@echo "  make phase5-check    Validate Phase 5 .rbf/.dtb artifacts before flashing"
	@echo "  make flash           Copy .rbf + .dtb to the board (BOARD_IP=<ip>)"
	@echo "  make flash-sd        Copy .rbf + .dtb to a mounted SD boot partition (SD_BOOT=<path>)"
	@echo "  make deploy          Sync sw/ to the DE1-SoC board (BOARD_IP=<ip>)"
	@echo "  make clean           Remove generated local build outputs"

sim:
	$(MAKE) -C sim all

phase1: qsys
	$(MAKE) -C sim phase1

sim-lms:
	$(MAKE) -C sim lms

sim-i2s:
	$(MAKE) -C sim i2s_loopback

phase2: phase1 sim-lms

qsys-component:
	@tmp_dir=$$(mktemp -d); \
	ip-generate --component-file=hw/noise_cancel_hw.tcl --file-set=QUARTUS_SYNTH \
		--output-directory="$$tmp_dir" --output-name=noise_cancel_0 \
		--part=5CSEMA5F31C6 --remove-qsys-generate-warning; \
	status=$$?; rm -rf "$$tmp_dir"; exit $$status

qsys:
	@if [ ! -f "$(QUARTUS_DIR)/$(PROJECT_NAME).qsys" ]; then \
		echo "Phase 1: no $(PROJECT_NAME).qsys file available yet; skipping qsys generation."; \
	else \
		qsys-script --system-file="$(QUARTUS_DIR)/$(PROJECT_NAME).qsys" \
			--search-path="$(CURDIR)/hw,$$" \
			--script=scripts/configure_phase5_qsys.tcl; \
		cd $(QUARTUS_DIR) && qsys-generate $(PROJECT_NAME).qsys \
			--synthesis=VERILOG \
			--search-path="$(CURDIR)/hw,$$"; \
	fi

qsys-clean:
	$(RM) -r $(QUARTUS_DIR)/$(PROJECT_NAME) $(QUARTUS_DIR)/synthesis

quartus:
	cd $(QUARTUS_DIR) && quartus_sh -t $(PROJECT_NAME).tcl
	cd $(QUARTUS_DIR) && quartus_map $(PROJECT_NAME)
	cd $(QUARTUS_DIR) && quartus_sta -t $(PROJECT_NAME)/synthesis/submodules/hps_sdram_p0_pin_assignments.tcl $(PROJECT_NAME)
	cd $(QUARTUS_DIR) && quartus_sh --flow compile $(PROJECT_NAME)

program: $(SOF)
	quartus_pgm -m JTAG -o "p;$(SOF)"

rbf: $(RBF)
	./scripts/validate_phase5_artifacts.sh --sof-only

$(RBF): $(SOF)
	./scripts/validate_phase5_artifacts.sh --sof-only
	quartus_cpf -c $(SOF) $(RBF)

dtb:
	@if [ ! -f "$(QUARTUS_DIR)/$(PROJECT_NAME).sopcinfo" ]; then \
		echo "Missing $(QUARTUS_DIR)/$(PROJECT_NAME).sopcinfo. Generate the Lab 3 Platform Designer system first."; \
		exit 1; \
	fi
	@if [ -f "$(EMBEDDED_SHELL)" ]; then \
		cmd='source "$(EMBEDDED_SHELL)" && sopc2dts --input "$(QUARTUS_DIR)/$(PROJECT_NAME).sopcinfo" --output "$(DTB).dts" --type dtb --board $(QUARTUS_DIR)/soc_system_board_info.xml && dtc -I dts -O dtb -o "$(DTB)" "$(DTB).dts"'; \
	elif command -v sopc2dts >/dev/null 2>&1 && command -v dtc >/dev/null 2>&1; then \
		cmd='sopc2dts --input "$(QUARTUS_DIR)/$(PROJECT_NAME).sopcinfo" --output "$(DTB).dts" --type dtb --board $(QUARTUS_DIR)/soc_system_board_info.xml && dtc -I dts -O dtb -o "$(DTB)" "$(DTB).dts"'; \
	elif [ -s "$(PATCHED_DTB)" ] && [ -s "$(PATCHED_DTS)" ]; then \
		echo "sopc2dts/dtc not found; reusing verified $(PATCHED_DTB) from the prior Lab 3-compatible Phase 5 run."; \
		cp "$(PATCHED_DTB)" "$(DTB)"; \
		cp "$(PATCHED_DTS)" "$(DTB).dts"; \
		cmd='true'; \
	else \
		echo "Missing sopc2dts/dtc tooling. Install/source Intel SoC EDS, then rerun make dtb."; \
		exit 1; \
	fi; \
	mkdir -p $(OUTPUT_DIR); \
	bash -lc "$$cmd"
	./scripts/validate_phase5_artifacts.sh --dtb-only

phase5-check:
	./scripts/validate_phase5_artifacts.sh

deploy:
	@if [ -z "$(BOARD_IP)" ]; then \
		echo "Usage: make deploy BOARD_IP=<board-ip>"; \
		exit 1; \
	fi
	./scripts/deploy.sh $(BOARD_IP)

flash:
	@if [ -z "$(BOARD_IP)" ]; then \
		echo "Usage: make flash BOARD_IP=<board-ip>"; \
		exit 1; \
	fi
	./scripts/flash_bitstream.sh $(BOARD_IP)

flash-sd:
	@if [ -z "$(SD_BOOT)" ]; then \
		echo "Usage: make flash-sd SD_BOOT=<mounted-sd-boot-partition>"; \
		exit 1; \
	fi
	./scripts/copy_to_sd_boot.sh $(SD_BOOT)

clean:
	$(MAKE) -C sim clean
	$(MAKE) -C sw clean
	$(RM) -r $(QUARTUS_DIR)/db $(QUARTUS_DIR)/incremental_db $(QUARTUS_DIR)/output_files
	$(RM) -r $(QUARTUS_DIR)/qdb $(QUARTUS_DIR)/synthesis $(QUARTUS_DIR)/$(PROJECT_NAME)
