.PRECIOUS:${BOOT_CODE}

########## BUILD OPTIONS ##########

QUIET=1
# QUIET: 1=clean, non-verbose output
#        2=normal make output

####### SIMULATION OPTIONS ########

SIM=VERILATOR
# SIM: VERILATOR: use Verilator
#      ICARUS: use Icarus Verilog

NUMACTL=#numactl -m 0 -C 0,1 --

######## SYNTHESIS OPTIONS ########

# BOARD: the options are the directories in system/fpga_config/.
#        Select the one you have
FPGA_BOARD=OrangeCrab_r0.2.1

# If this options is set to 1, builds with different seeds will be
# considered separate, in combination with the fact that this build
# system by default is generating a new seed for each build, it means
# that for each build a new set of files gets created in the build 
# directory with the seed number on the filename without overwriting
# the old ones.
BUILD_SEED_DIFFERENTIATION=0

VERSION="v0.3.0-dev"

# TODO: handle case where the source code is not part of a git repository
COMMIT=$(shell if which git >/dev/null 2>/dev/null ;then git log --pretty=format:'%H' -1 |cat ;else echo git-not-installed; fi)

ifeq "${QUIET}" "1"
       QUIET_AS		= @echo   '  AS         '${PRINT_PATH_PREFIX}$@;

       QUIET_VVP	= @echo   '  VVP        '${PRINT_PATH_PREFIX}$@;
       QUIET_IVERILOG	= @echo   '  IVERILOG   '${PRINT_PATH_PREFIX}$@;

       QUIET_VERILATOR	= @echo   '  VERILATOR  '${PRINT_PATH_PREFIX}$@;
       QUIET_CC		= @echo   '  CC         '${PRINT_PATH_PREFIX}$@;

       QUIET_YOSYS	= @echo   '  YOSYS      '${PRINT_PATH_PREFIX}$@;
       QUIET_NEXTPNR	= @echo   '  NEXTPNR    '${PRINT_PATH_PREFIX}$@;
       QUIET_ECPPACK	= @echo   '  ECPPACK    '${PRINT_PATH_PREFIX}$@;
       QUIET_DFU_SUFFIX	= @echo   '  DFU-SUFFIX '${PRINT_PATH_PREFIX}$@;
       QUIET_DFU_UTIL	= @echo   '  DFU-UTIL   '${PRINT_PATH_PREFIX}$<;
       QUIET_MINIPRO	= @echo   '  MINIPRO    '${PRINT_PATH_PREFIX}${ROM_FILE};

       QUIET_DOWNLOAD	= @echo   '  DOWNLOAD   '${PRINT_PATH_PREFIX}$@;

       QUIET_CLEAN	= @echo   '  CLEAN      '${PRINT_PATH_PREFIX};
       QUIET_MRPROPER	= @echo   '  MRPROPER   '${PRINT_PATH_PREFIX};
       QUIET_VERILATOR_RUN = @printf '  %s  %s\n' $(shell basename "$1") $2;
       Q = @
       MAKEOPTS=--no-print-directory
.SILENT:
else
	Q =
endif


.PHONY: run wave disas
run: $(subst .txt,.run,${BOOT_CODE})
wave: $(subst .txt,.wave,${BOOT_CODE})
disas: $(subst .txt,.disas,${BOOT_CODE})

# Assembling code
%.stxt: %.bin
	${Q}dd if=/dev/zero bs=1 count=2048 of="$(subst .bin,.stage,$<)" status=none
	${Q}dd if="$<" bs=1 skip=63488 of="$(subst .bin,.stage,$<)" conv=notrunc,nocreat status=none
	${Q}xxd -ps -c 2 "$(subst .bin,.stage,$<)" > "$@"
	${Q}rm "$(subst .bin,.stage,$<)"

# Assembling code
%.txt:%.bin
	${Q}dd if=/dev/zero bs=1 count=65536 of="$(subst .bin,.stage_short,$<)" status=none
	${Q}dd if="$<" of="$(subst .bin,.stage_short,$<)" conv=notrunc,nocreat status=none
	${Q}xxd -ps -c 2 "$(subst .bin,.stage_short,$<)" > "$@"
	${Q}rm "$(subst .bin,.stage_short,$<)"


ifeq "${NO_ASM}" "0"
%.bin:%.asm
	${QUIET_AS}
	${Q}as86 -0 "$<" -b "$@"
endif

# Running simulation
ifeq "${SIM}" "ICARUS"
%.fst %.memdump: %.txt ${SYSTEM_VVP} ${MICROCODE}
	${QUIET_VVP}
	${Q}vvp "${SYSTEM_VVP}" -fst +VERSION=${VERSION} +COMMIT=${COMMIT} +BOOT_CODE="$<" +WAVEFORM="$(subst .txt,.fst,$<)" +MEMDUMP="$(subst .txt,.memdumptxt,$<)" +MICROCODE="${MICROCODE}"
	${Q}grep -v '^//' "$(subst .txt,.memdumptxt,$<)" | xxd -ps -c 2 -r > "$(subst .txt,.memdump,$<)"
	${Q}rm "$(subst .txt,.memdumptxt,$<)"

%.run: %.txt ${SYSTEM_VVP} ${MICROCODE}
	${QUIET_VVP}
	${Q}vvp -i "${SYSTEM_VVP}" +VERSION=${VERSION} +COMMIT=${COMMIT} +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
%.json: %.txt ${SYSTEM_VVP} ${MICROCODE}
	${QUIET_VVP}
	${Q}vvp -i "${SYSTEM_VVP}" +VERSION=${VERSION} +COMMIT=${COMMIT} +STATS="$@" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
else ifeq "${SIM}" "VERILATOR"
%.fst %.memdump: %.txt ${VERILATOR_BIN} ${MICROCODE}
	$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
	${Q}"${VERILATOR_BIN}" +VERSION=${VERSION} +COMMIT=${COMMIT} +BOOT_CODE="$<" +WAVEFORM="$(subst .txt,.fst,$<)" +MEMDUMP="$(subst .txt,.memdumptxt,$<)" +MICROCODE="${MICROCODE}"
	${Q}grep -v '^//' "$(subst .txt,.memdumptxt,$<)" | xxd -ps -c 2 -r > "$(subst .txt,.memdump,$<)"
	${Q}rm "$(subst .txt,.memdumptxt,$<)"

%.json: %.txt ${VERILATOR_BIN} ${MICROCODE}
	$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
	${Q} ${NUMACTL} "${VERILATOR_BIN}" +VERSION=${VERSION} +COMMIT=${COMMIT} +STATS=$@ +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
%.run: %.txt ${VERILATOR_BIN} ${MICROCODE}
	$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
	${Q} ${NUMACTL} "${VERILATOR_BIN}" +VERSION=${VERSION} +COMMIT=${COMMIT} +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
endif

%.disas: %.bin
	objdump -D -b binary -m i8086 $^ | less

# Tools
%.wave : %.fst
	gtkwave "$<" "${GTKWSAVE}"
