# Xilinx ISE Makefile

PROJECT     := PROJ_NAME
PART        := PART_NO

XILINX := /opt/Xilinx/14.7/ISE_DS/ISE
PROG   := impact

CONSTRAINTS := src/BOARD_NAME.ucf
WCFGPATH    := src/tb/
VSOURCE     := VERILOG_SOURCES
VTEST       := VERILOG_TESTBENCH_SOURCES
VHDSOURCE   := VHDL_SOURCES
VHDTEST     := VHDL_TESTBENCH_SOURCE

#####################################################################
.PHONY: all clean prog sim_%

all: $(PROJECT).bit

clean:
	rm -rf build/

BANNER = @printf "\033[30;43m===> $(1)\033[0K\033[0m\n"

### Bitstream Generation ############################################
build/$(PROJECT).prj: Makefile
	$(call BANNER,MKDIR $@)
	@mkdir -p build/
	$(call BANNER,GEN $@)
	@rm -f $@
	@$(foreach file,$(VSOURCE),echo "verilog work \"../$(file)\"" >> $@;)
	@$(foreach file,$(VHDSOURCE),echo "vhdl work \"../$(file)\"" >> $@;)

build/$(PROJECT).scr: build/$(PROJECT).prj
	$(call BANNER,GEN $@)
	@echo "run" \
	    "-ifn $(PROJECT).prj" \
	    "-ofn $(PROJECT).ngc" \
	    "-ifmt mixed" \
	    "-top $(PROJECT)" \
	    "-ofmt NGC" \
	    "-p $(PART)" \
	    > $@

build/$(PROJECT).ngc: build/$(PROJECT).scr $(VSOURCE) $(VHDSOURCE)
	$(call BANNER,XST $@)
	@cd build && \
	    LANGUAGE=usenglish $(XILINX)/bin/lin64/xst \
	    -intstyle xflow \
	    -ifn "$(PROJECT).scr"

build/$(PROJECT).ngd: build/$(PROJECT).ngc
	$(call BANNER,NGDBUILD $@)
	@cd build && \
	    LANGUAGE=usenglish $(XILINX)/bin/lin64/ngdbuild \
	    -intstyle xflow -quiet \
	    -p "$(PART)" -uc "../$(CONSTRAINTS)" \
	    "$(PROJECT).ngc" "$(PROJECT).ngd"

build/$(PROJECT).map.ncd: build/$(PROJECT).ngd
	$(call BANNER,MAP $@)
	@cd build && \
	    LANGUAGE=usenglish $(XILINX)/bin/lin64/map \
	    -intstyle xflow \
	    -p "$(PART)" -o "$(PROJECT).map.ncd" \
	    -w "$(PROJECT).ngd" "$(PROJECT).pcf"

build/$(PROJECT).ncd: build/$(PROJECT).map.ncd
	$(call BANNER,PAR $@)
	@cd build && \
	    LANGUAGE=usenglish $(XILINX)/bin/lin64/par \
	    -intstyle xflow \
	    -w "$(PROJECT).map.ncd" "$(PROJECT).ncd" "$(PROJECT).pcf"

build/$(PROJECT).bit: build/$(PROJECT).ncd
	$(call BANNER,BITGEN $@)
	@cd build && \
	    LANGUAGE=usenglish $(XILINX)/bin/lin64/bitgen \
	    -intstyle xflow \
	    -w "$(PROJECT).ncd" "$(PROJECT).bit"

$(PROJECT).bit: build/$(PROJECT).bit
	$(call BANNER,COPY $@)
	@cp "build/$(PROJECT).bit" "$(PROJECT).bit"

### Simulation ######################################################
build/$(PROJECT)_sim.prj: Makefile
	$(call BANNER,MKDIR $@)
	@mkdir -p build/
	$(call BANNER,GEN $@)
	@echo "verilog work $(XILINX)/verilog/src/glbl.v" > $@
	@$(foreach file,$(VSOURCE),echo "verilog work \"../$(file)\"" >> $@;)
	@$(foreach file,$(VHDSOURCE),echo "vhdl work \"../$(file)\"" >> $@;)
	@$(foreach file,$(VTEST),echo "verilog work \"../$(file)\"" >> $@;)
	@$(foreach file,$(VHDTEST),echo "vhdl work \"../$(file)\"" >> $@;)

build/isim_%: build/$(PROJECT)_sim.prj $(VSOURCE) $(VHDSOURCE) $(VTEST) $(VHDTEST)
	$(call BANNER,FUSE $@)
	@cd build && \
	    LANGUAGE=usenglish $(XILINX)/bin/lin64/fuse \
	    -intstyle xflow \
	    -incremental \
	    -prj $(PROJECT)_sim.prj -o $(notdir $@) \
	    work.$(notdir $*) work.glbl

ISIM_WCFG = $(addprefix -view ../,$(wildcard $(WCFGPATH)/$(notdir $*).wcfg))
sim_%: build/isim_%
	$(call BANNER,RUN $*)
	@echo "run all" > build/isim_$(notdir $*).cmd
	cd build && \
	    LANGUAGE=usenglish XILINX=$(XILINX) PATH=$(XILINX)/bin/lin64:$(PATH) \
	    ./isim_$(notdir $*) -gui -tclbatch isim_$(notdir $*).cmd $(ISIM_WCFG)

### Programming #####################################################
ifeq ($(PROG), impact)
build/impact.cmd: build/$(PROJECT).bit
	$(call BANNER,GEN $@)
	@echo "setMode -bscan" > $@
	@echo "setCable -p auto" >> $@
	@echo "addDevice -p 1 -file $(PROJECT).bit" >> $@
	@echo "program -p 1" >> $@
	@echo "quit" >> $@

prog: build/impact.cmd
	$(call BANNER,IMPACT build/$(PROJECT).bit)
	@cd build && \
	    PATH=$(XILINX)/bin/lin64:$(PATH) \
	    LANGUAGE=usenglish $(XILINX)/bin/lin64/impact -batch impact.cmd

else
prog:
	$(error PROG not set or unknown programmer)
endif
