PROJECT = ultranes_system

SHELL := /bin/bash

QUARTUS_SH = quartus_sh --64bit
QUARTUS_PGM = quartus_pgm

SRC = $(PROJECT).sv cpu.v

TCL = $(PROJECT).tcl
QPF = $(PROJECT).qpf
QSF = $(PROJECT).qsf
SDC = $(PROJECT).sdc
QSYS = $(PROJECT).qsys

SOPCINFO = $(PROJECT).sopcinfo
QIP = $(PROJECT)/synthesis/$(PROJECT).qip
HPS_PIN_TCL = $(PROJECT)/synthesis/submodules/hps_sdram_p0_pin_assignments.tcl
HPS_PIN_MAP = hps_sdram_p0_all_pins.txt

BOARD_INFO = $(PROJECT)_board_info.xml
DTS = $(PROJECT).dts
DTB = $(PROJECT).dtb

SOF = output_files/$(PROJECT).sof
RBF = output_files/$(PROJECT).rbf

all: qsys quartus dtb rbf

.PHONY: project
project: $(QPF) $(QSF) $(SDC)

$(QPF) $(QSF) $(SDC): $(TCL)
	$(QUARTUS_SH) -t $(TCL)

# qsys
#
# From the .qsys file, generate the .sopcinfo, .qip, and directory
# (named according to the system) with all the Verilog files, etc.

.PHONY : qsys
qsys : $(SOPCINFO)

$(SOPCINFO) $(QIP) $(HPS_PIN_TCL) $(PROJECT)/: $(QSYS)
	rm -rf $(SOPCINFO) $(PROJECT)/
	qsys-generate $(QSYS) --synthesis=VERILOG

# quartus
#
# Run Quartus on the Qsys-generated files
#
#    Build netlist
# quartus_map soc_system
#
#    Use netlist information to determine HPS stuff
# quartus_sta -t hps_sdram_p0_pin_assignments.tcl soc_system
#
#    Do the rest
#   FIXME: this is wasteful.  Really want not to repeat the "map" step
# quartus_sh --flow compile 
#
# quartus_fit
# quartus_asm
# quartus_sta

.PHONY : quartus
quartus : $(SOF)

$(SOF) $(HPS_PIN_MAP) : $(QIP) $(QPF) $(QSF) $(HPS_PIN_TCL)
	quartus_map $(PROJECT)
	quartus_sta -t $(HPS_PIN_TCL) $(PROJECT)
	quartus_fit $(PROJECT)
	quartus_asm $(PROJECT)
#	quartus_sh --flow compile $(QPF)

# rbf
#
# Convert the .sof file (for programming through the USB blaster)
# to an .rbf file to be placed on an SD card and written by u-boot
.PHONY : rbf
rbf : $(RBF)

$(RBF) : $(SOF)
	quartus_cpf -c $(SOF) $(RBF)

# dtb
#
# Use the .sopcinfo file to generate a device tree blob file
# with information about the memory map of the peripherals
.PHONY : dtb
dtb : $(DTB)

$(DTB) : $(DTS)
	dtc -I dts -O dtb -o $(DTB) $(DTS)

$(DTS) : $(SOPCINFO) $(BOARD_INFO)
	sopc2dts --input $(SOPCINFO) \
		--output $(DTS) \
		--type dts \
		--board $(BOARD_INFO) \
		--clocks

.PHONY: lint
lint:
	verilator --lint-only $(SRC)

.PHONY: flash
flash: $(RBF)
	ssh fpga 'mount /dev/mmcblk0p1 /mnt'
	scp $(RBF) fpga:/mnt/soc_system.rbf

# have to run this after 'make flash'
.PHONY: dtb_install
dtb_install: $(DTB)
	scp $(DTB) fpga:/mnt/soc_system.dtb

.PHONY: clean
clean:
	rm -rf db incremental_db *.qpf *.qsf *.sof obj_dir *.vcd *.sdc $(DTS) $(DTB) output_files $(HPS_PIN_MAP) c5_pin_model_dump.txt hps_isw_handoff/ $(PROJECT)/ .qsys_edit/ $(SOPCINFO) *.csv *.bak *.tcl~
