MAKEFLAGS += --no-builtin-rules MAKEFLAGS += --no-builtin-variables .SUFFIXES: CST ?= tangnano9k.cst FLASH_OPTS ?= # https://github.com/YosysHQ/apicula/wiki/Nextpnr%E2%80%90Himbaechel-Gowin # but # https://github.com/YosysHQ/apicula/wiki/gowin_pack says something different. huh? DEVICE_NAME ?= GW1NR-LV9QN88PC6/I5 DEVICE_FAMILY ?= GW1N-9C # Can't use this for deps: # -E $(PROGRAM).deps # as yosys needs to have -o specified for this to work # but I specify the command manually # also, yosys inserts /tmp/ files which makes this useless. YOSYS_OPTS = -Q -q -l $*.yosys.log -e "conflict|is used but has no driver" NEXTPNR_OPTS = -q -l $*.pnr.log \ --sdc clock.sdc \ --placed-svg $*.plc.svg \ --routed-svg $*.rt.svg DEPS := $(wildcard *.dep) # this is "bad", as it runs the deps target every time # probably because of the include below # SOURCES := $(wildcard *$(HARDWARE_SUFFIX)) # DEPS := $(SOURCES:$(HARDWARE_SUFFIX)=.dep) ## default target all: $(PROGRAM).fs ## dependencies tangnano9k.cst: wget https://github.com/YosysHQ/apicula/raw/refs/heads/master/examples/tangnano9k.cst || \ curl -LO https://github.com/YosysHQ/apicula/raw/refs/heads/master/examples/tangnano9k.cst ## helper targets .PHONY: clean flash show show: $(PROGRAM)$(HARDWARE_SUFFIX) yosys -p "read_verilog $(YOSYS_READFLAGS) $<; prep; show $(PROGRAM)" flash: $(PROGRAM).fs openFPGALoader -b tangnano9k $(FLASH_OPTS) $(PROGRAM).fs clean: rm -rf *.json *.fs *.svg *.log *.dep *.vvp *.lxt2 simu: $(PROGRAM).lxt2 simu2: verilator.$(PROGRAM)/dump.vvp lint: $(PROGRAM)$(HARDWARE_SUFFIX) verilator --quiet --lint-only -Wall -Wno-PROCASSINIT $(PROGRAM)$(HARDWARE_SUFFIX) ## Patterns # synthesize %.json: %$(HARDWARE_SUFFIX) # sh resolvedeps.sh $< # only used for dep-generation, output file is needed for dep file, but otherwise useless # this must happen *without* synth_gowin, as this includes additional files, which ruin the depfile. yosys -q $< -E $*.dep -o $@ && rm -f $@ yosys -p "read_verilog $(YOSYS_READFLAGS) $<; synth_gowin -top $* -json $@" $(YOSYS_OPTS) # because yosys -E is buggy, or behaves differently than expected, # use gawk to force-create deps. %.dep: %$(HARDWARE_SUFFIX) # sh resolvedeps.sh $< yosys $< -E $*.dep -o $*.json && rm -f $*.json # place and route? %.pnr.json: %.json $(CST) nextpnr-himbaechel --json $< --write $@ \ --device $(DEVICE_NAME) --vopt family=$(DEVICE_FAMILY) \ --vopt cst=$(CST) \ $(NEXTPNR_OPTS) \ || \ nextpnr-gowin --json $< --write $@ \ --device $(DEVICE_NAME) --family $(DEVICE_FAMILY) \ --cst $(CST) \ $(NEXTPNR_OPTS) # pack bitstream %.fs: %.pnr.json gowin_pack -d $(DEVICE_FAMILY) -o $@ $< ### simulation %.lxt2: %.vvp ./$< -lxt2 .NOTINTERMEDIATE: %.vvp %.vvp: %$(HARDWARE_SUFFIX) %$(TESTBENCH_SUFFIX) iverilog -DDUMP_FILE_NAME='"$*.lxt2"' -g2012 -o $*.vvp $*$(HARDWARE_SUFFIX) $*$(TESTBENCH_SUFFIX) # verilog unfortunately exits on any warning # also on warnings "boohoo, you specified timings in some modules and not in others" # since this is fucking annoying, I choose to ignore the exit code. verilator.%: %$(HARDWARE_SUFFIX) %$(TESTBENCH_SUFFIX) verilator --quiet -DDUMP_FILE_NAME='"dump.vvp"' --trace --timing --main --exe --Mdir verilator.$(*) $(*)$(TESTBENCH_SUFFIX) || true # need to specify RM for some reason # verilators makefiles doesn't specify the variable verilator.%/dump.vvp: verilator.% # for whatever reason, some version of vlor started to append _tb. ($(MAKE) -j4 -C verilator.$(*) -f V$(*).mk RM=rm || \ $(MAKE) -j4 -C verilator.$(*) -f V$(*)_tb.mk RM=rm) cd verilator.$(*) && (./V$(*) || ./V$(*)_tb) ## inter-file dependencies -include $(DEPS) -include $($(wildcard *.fs:.fs=.dep)