MAKEFLAGS += -R -r PROJECT = max80 REVISIONS = v1 v2 EXTRAREVS = bypass VARIANTS = QU = quartus ALLREVS = $(REVISIONS) $(EXTRAREVS) # Common options for all Quartus tools QPRI = --lower_priority QCPF = $(QU)_cpf $(QPRI) QSH = $(QU)_sh $(QPRI) QSTA = $(QU)_sta $(QPRI) QPGM = $(QU)_pgm $(QPRI) # Common options for Quartus in-flow tools QOPT = --write_settings_files=off $(QPRI) QMAP = $(QU)_map $(QOPT) QFIT = $(QU)_fit $(QOPT) QCDB = $(QU)_cdb $(QOPT) QASM = $(QU)_asm $(QOPT) QPOW = $(QU)_pow $(QOPT) outdir = output mifdir = mif PERL = perl PYTHON = python SED = sed GZIP = gzip BUILDDATE := $(shell LC_ALL=C date) SUBDIRS = usb PREREQFILES = $(mifdir)/sram.mif \ $(foreach rev,$(ALLREVS),$(foreach coffmt,jic pof, \ $(outdir)/$(rev).$(coffmt).cof)) alltarg := sof pof jic svf svf.gz xsvf xsvf.gz rbf rbf.gz rpf rpf.gz \ rpd rpd.gz pow.rpt sta.rpt allout = $(foreach o,$(alltarg),$(outdir)/$(1).$(o)) #vartarg := sof svf svf.gz rbf rbf.gz #varout = $(foreach o,$(vartarg),$(outdir)/$(1).$(o)) #uptarg := update.svf update.svf.gz update.xsvf update.xsvf.gz #upout = $(foreach o,$(uptarg),$(outdir)/$(1).$(o)) sram_src = ../rv32/ MKFW = ../tools/mkfwimage.pl RPF_ADDR := 0 DRAM_ADDR := 0x100000 DRAM_IMAGE := ../rv32/dram.bin ESP_ADDR := 0x10000 ESP_IMAGE := ../esp32/output/max80.ino.bin ESP_BOOT_ADDR := 0x1000 ESP_BOOT_IMAGE := ../esp32/output/max80.ino.bootloader.bin ESP_PART_ADDR := 0x8000 ESP_PART_IMAGE := ../esp32/output/max80.ino.partitions.bin ESP_OTACTL_ADDR := 0xe000 ESP_OTACTL_IMAGE := ../esp32/boot_app0.bin ESP_TOOL_OPT := ../esp32/esptool.opt IDCODE := 0x020f20dd # JTAG IDCODE of FPGA BOARDINFO_ADDR := 0xff000 FWDEPS = $(MKFW) $(DRAM_IMAGE) $(ESP_IMAGE) $(ESP_BOOT_IMAGE) \ $(ESP_PART_IMAGE) $(ESP_OTACTL_IMAGE) .SUFFIXES: .SECONDARY: .DELETE_ON_ERROR: all: prereq $(MAKE) $(ALLREVS:=.targets) $(MAKE) fwimages # $(MAKE) $(VARIANTS) # $(MAKE) $(ALLREVS:=.update) -include $(ALLREVS:=.deps) .PHONY: fwimages fwimages: $(patsubst %,$(outdir)/%.fw,$(REVISIONS) $(PROJECT)) .PHONY: $(ALLREVS) $(ALLREVS): prereq $(MAKE) $@.targets .PHONY: %.targets %.targets: $(MAKE) $(call allout,$*) .PHONY: %.update %.update: $(MAKE) $(call upout,$*) .PHONY: $(VARIANTS) $(VARIANTS): $(MAKE) $(outdir)/$@/variant.stamp .PHONY: %.vtargets %.vtargets: $(MAKE) --old-file=$(outdir)/$*.fit.rpt $(call varout,$*) $(outdir)/%/variant.stamp: mif/%.mif \ $(foreach rev,$(ALLREVS),$(outdir)/$(rev).fit.rpt) -rm -rf var/$* $(outdir)/$* mkdir -p var/$* var/$*/mif $(outdir)/$* ( cd $(outdir)/$* && ln -sf ../*.asm.rpt ../*.fit.rpt . ) cp -alf Makefile *.deps *.qpf *.qsf *.pins scripts \ db incremental_db var/$*/ ln -f $< var/$*/mif/sram.mif ( cd var/$* && ln -sf ../../$(outdir)/$* ./output ) $(MAKE) -C var/$* $(ALLREVS:=.vtargets) echo '$(BUILDDATE)' > $@ $(outdir)/%.map.rpt: %.qsf | $(mifdir)/sram.mif $(QMAP) $(PROJECT) -c $* $(outdir)/%.fit.rpt: $(outdir)/%.map.rpt $(QFIT) $(PROJECT) -c $* $(mifdir)/%.bin: $(sram_src)/%.bin $(all_map_deps) $(mifdir) cp -f $< $@ printf '%s\0' '$(BUILDDATE)' >> $@ sram_depth := 8192 sram_width := 32 sram_stride := 1 $(mifdir)/%.mif: $(mifdir)/%.bin ../tools/bin2mif.pl $(PERL) ../tools/bin2mif.pl $< $@ \ $(sram_depth) $(sram_width) $(sram_stride) $(outdir)/%.mif_update.rpt: $(outdir)/%.fit.rpt [ -z '$($*_asm_deps)' ] || $(QCDB) --update_mif $(PROJECT) -c $* $(outdir)/%.sof: $(outdir)/%.mif_update.rpt $(QASM) $(PROJECT) -c $* $(outdir)/%.sta.rpt: $(outdir)/%.fit.rpt | $(outdir)/%.sof $(QSTA) $(PROJECT) -c $* $(outdir)/%.pow.rpt: $(outdir)/%.sta.rpt | $(outdir)/%.sof $(QPOW) $(PROJECT) -c $* $(foreach rev,$(ALLREVS),$(outdir)/$(rev).%.cof): %.cof.xml $(outdir) $(SED) -e 's/@@PROJECT@@/$(@F:.$*.cof=)/g' $< > $@ $(outdir)/%.jic: $(outdir)/%.jic.cof $(outdir)/%.sof ../rv32/dram.hex $(QCPF) -o bitstream_compression=on -c $< $(outdir)/%.pof: $(outdir)/%.pof.cof $(outdir)/%.sof $(QCPF) -o bitstream_compression=on -c $< # This produces a transient-load .svf file # 6 MHz is the speed of USB-Blaster... $(outdir)/%.svf: $(outdir)/%.sof $(QCPF) -c -q 6.0MHz -g 3.3 -n p $< $@ # xsvf: compact representation of .svf; more or less a wrapper around # the raw binary file. $(outdir)/%.xsvf: $(outdir)/%.svf ../tools/svf2xsvf.py $(PYTHON) ../tools/svf2xsvf.py $< $@ # Raw Binary File, compact data for transient programming. $(outdir)/%.rbf: $(outdir)/%.sof $(QCPF) -c $< $@ # Raw Programmer Data, for loading into flash, includes all contents # but is rather large if not compressed. Adjust bit ordering to match # SPI... $(outdir)/%.rpd: $(outdir)/%.pof $(QCPF) -c -o bitstream_compression=on -o rpd_little_endian=off $< $@ # RPD file for the FPGA only. The necessary length can be gotten from # generating a compressed .rbf, but that file is not valid for flashing # even if bit-reversed due to header(?) differences. $(outdir)/%.z.rbf: $(outdir)/%.sof $(QCPF) -c -o bitstream_compression=on $< $@ $(outdir)/%.rpf: $(outdir)/%.rpd $(outdir)/%.z.rbf dd if=$< of=$@ bs=$$(wc -c < $(@:.rpf=.z.rbf)) count=1 $(outdir)/%.gz: $(outdir)/% $(GZIP) -9 < $< > $@ # New-style combined firmware image ALLRPFS = $(foreach rev,$(REVISIONS),$(outdir)/$(rev).rpf) everyrev = $(shell n=1; for r in $(REVISIONS); do echo "$(1)" -ver 0,0,$$n,$$n "$(2)"; n=$$((n+1)); done) $(outdir)/$(PROJECT).fw: $(ALLRPFS) $(FWDEPS) $(PERL) $(MKFW) -o - -fwmin 2 \ $(call everyrev,-type target,-str 'MAX80 $$r') \ -type fpgainit -addr $(IDCODE) -file $(outdir)/bypass.rbf \ $(call everyrev,-type data -addr $(RPF_ADDR),-file $(outdir)/$$r.rpf) \ -type data -addr $(DRAM_ADDR) -file $(DRAM_IMAGE) \ -type boardinfo -addr $(BOARDINFO_ADDR) -empty \ -type esptool -optional -file $(ESP_TOOL_OPT) \ -type espota -addr $(ESP_ADDR) -file $(ESP_IMAGE) \ -type esppart -addr $(ESP_PART_ADDR) -file $(ESP_PART_IMAGE) \ -type espsys -addr $(ESP_BOOT_ADDR) -file $(ESP_BOOT_IMAGE) \ -type espsys -addr $(ESP_OTACTL_ADDR) -file $(ESP_OTACTL_IMAGE) \ | $(GZIP) -9 > $@ # Old-style single version firmware images $(outdir)/%.fw: $(outdir)/%.rpf $(outdir)/bypass.rbf \ $(DRAM_IMAGE) $(ESP_IMAGE) \ ../tools/mkfwimage.pl $(PERL) ../tools/mkfwimage.pl -o - \ -type target -str 'MAX80 $*' \ -type fpgainit -addr $(IDCODE) -optional -file $(outdir)/bypass.rbf \ -type data -addr $(RPF_ADDR) -file $< \ -type data -addr $(DRAM_ADDR) -file $(DRAM_IMAGE) \ -type boardinfo -optional -addr $(BOARDINFO_ADDR) -empty \ -type esptool -optional -file $(ESP_TOOL_OPT) \ -type espota -addr $(ESP_ADDR) -file $(ESP_IMAGE) \ -type esppart -optional -addr $(ESP_PART_ADDR) -file $(ESP_PART_IMAGE) \ -type espsys -optional -addr $(ESP_BOOT_ADDR) -file $(ESP_BOOT_IMAGE) \ -type espsys -optional -addr $(ESP_OTACTL_ADDR) -file $(ESP_OTACTL_IMAGE) \ | $(GZIP) -9 > $@ $(outdir)/%.update.svf: ./scripts/flashsvf.pl \ $(outdir)/jtagupd/%.svf $(outdir)/%.map.rpt $(outdir)/%.fw $(PERL) $^ $@ # Prerequisite directories and files $(outdir) $(mifdir): mkdir -p $@ .PHONY: prereq prereq: $(outdir) $(mifdir) for d in $(SUBDIRS); do $(MAKE) -C $$d; done $(MAKE) $(PREREQFILES) # Clean out SignalTap signalclean: for f in *.qsf; do \ $(PERL) -ne 'print unless (/(SIGNALTAP_FILE\b|\bENABLE_SIGNALTAP\b|\bSLD_FILE\b|SLD_NODE_)/);' < $$f > $$f.tmp && \ mv -f $$f.tmp $$f ; \ done # Programming targets. Environment JTAG_CABLE can override the default, # which is otherwise the first cable found. rpar := ) JTAG_CABLE ?= $(shell jtagconfig --enum | sed -ne 's/^1$(rpar) //p') # Transient programming program-%: $(outdir)/%.sof $(QPGM) -c '$(JTAG_CABLE)' -m JTAG -o 'p;$(outdir)/$*.sof' # Permanent programming in flash flash-%: $(outdir)/%.jic $(QPGM) -c '$(JTAG_CABLE)' -m JTAG -i -o 'pvbi;$(outdir)/$*.jic' %.deps: %.qsf scripts/qsfdeps.pl $(PERL) scripts/qsfdeps.pl $* $@ $< clean: for d in $(SUBDIRS); do $(MAKE) -C $$d clean; done rm -rf db incremental_db var simulation/modelsim \ greybox_tmp */greybox_tmp iodevs.vh output_files $(mifdir) for d in $(ALLREVS); do \ rm -f $$d/*.rpt $$d/*.rpt $$d/*.summary $$d/*.smsg \ $$d/*.htm $$d/*.htm_files $$d/*.map $$d/*.eqn $$d/*.sld \ $$d/*.done ; \ done spotless: clean for d in $(SUBDIRS); do $(MAKE) -C $$d spotless; done rm -rf $(outdir) $(mifdir) *.deps *~ \#*~ iodevs.vh: ../common/iodevs.conf ../tools/iodevs.pl $(PERL) ../tools/iodevs.pl v $< $@ deps: Makefile # Verilog header dependencies max80.sv: iodevs.vh