CC = gcc CFLAGS = -std=c89 -pedantic -Wall -Werror -O2 IV = iverilog YOSYS = git-yosys PNR = git-nextpnr-ice40 ICEPACK = git-icepack ICETIME = git-icetime TOPMODULE = soc PCF = design/pins.pcf IVFLAGS = -Iinclude/ -DSIMULATION # The macroassembly header file is somewhat different thing, but I don't know # what place would be more suitable for it than include/ dir MACROASM_FLAGS := -Iinclude/ -E # It made sense to just list all of those in this variable # and then prepend stack_machine_ to each element STACK_MACHINE_OLD_TESTS := \ store \ load_store \ multiinstructions_load_store \ add \ sub \ div \ mul \ jump \ tee \ swap \ cond_jump STACK_MACHINE_TESTS := \ store \ load_store \ multiinstructions_load_store \ tee \ swap \ add \ sub \ div \ mul \ jump \ cond_jump # Add other tests here if You need TESTS := \ self \ self_32bit_word \ slave_dispatcher \ div \ vga \ sram_slave \ embedded_bram_slave \ soc_simple_display \ interface_wrapper \ master_arbiter \ $(addprefix stack_machine_old_,$(STACK_MACHINE_OLD_TESTS)) \ $(addprefix stack_machine_,$(STACK_MACHINE_TESTS)) # For each of these Makefile will attempt to generate VGAdump.ppm # and compare it to VGAdump_expected.ppm inside that test's directory TESTS_WITH_VGA := \ vga \ soc_simple_display # Short C programs TOOLS := VGAdump2ppm ifdef DEBUG IVFLAGS += -DDEBUG DBG&SAVE = tee "$(1)" else DBG&SAVE = cat > "$(1)" # putting cat through pipe - what an animal cruelty! endif TEST_TARGETS := $(addprefix test_,$(TESTS)) VGA_TEST_TARGETS := $(addprefix test_,$(TESTS_WITH_VGA)) NO_VGA_TEST_TARGETS := $(foreach TARGET,$(TEST_TARGETS), \ $(if $(filter $(TARGET),$(VGA_TEST_TARGETS)),,$(TARGET)) \ ) TEST_LOGS := $(foreach TEST,$(TESTS),tests/$(TEST)/report.log) TOOLS_TARGETS := $(addprefix tools/,$(TOOLS)) GENERATED_MEM_FILES := $(shell find . -name "*.s.tcl") GENERATED_MEM_FILES := $(basename $(basename $(GENERATED_MEM_FILES))) GENERATED_MEM_FILES += $(basename $(shell find tests/ -name "*.memv")) GENERATED_MEM_FILES := $(addsuffix .mem,$(GENERATED_MEM_FILES)) # TODO: check if this function can be changed to use $(shell grep ...) FILE_LINES = `grep -E '^[[:space:]]*[^[:space:]/]' -c $(1)` all : design.bin design.v : design/rom.mem design/*.v $(IV) -E $(filter %.v,$^) -DROM_WORDS_COUNT=$(call FILE_LINES,$<) -o $@ design.json : design.v design/rom.mem design/font.mem $(YOSYS) -p 'read_verilog -defer $<' \ -p 'synth_ice40 -top $(TOPMODULE) -json $@' design.asc : design.json $(PCF) $(PNR) --hx8k --asc $@ --pcf $(PCF) --json $< --package ct256 design.bin : design.asc $(ICEPACK) $< $@ timing.rpt : design.asc $(ICETIME) -d hx8k -mtr $@ $< prog : design.bin sudo iceprogduino $< test : $(TEST_TARGETS) quicktest : $(NO_VGA_TEST_TARGETS) # VGA tests take loooong time tests/%.mem : tests/%.memv $(IV) $(MACROASM_FLAGS) $^ -o $@ %.mem : %.s.tcl tclasm_old.tcl tclasm.tcl $< > $@ tests/self/test.vvp : tests/self/operations.mem tests/self/test.v \ models/slave.v models/master.v include/messages.vh $(IV) $(IVFLAGS) -s self_test \ -DMASTER_OPERATIONS_COUNT=$(call FILE_LINES,$<) \ $(filter %.v,$^) -o $@ tests/self_32bit_word/test.vvp : tests/self_32bit_word/operations.mem \ tests/self_32bit_word/test.v models/slave.v models/master.v \ include/messages.vh $(IV) $(IVFLAGS) -s self_32bit_test \ -DMASTER_OPERATIONS_COUNT=$(call FILE_LINES,$<) \ $(filter %.v,$^) -o $@ tests/sram_slave/test.vvp : tests/sram_slave/operations.mem \ tests/sram_slave/test.v models/sram.v models/master.v \ design/sram_slave.v include/messages.vh $(IV) $(IVFLAGS) -s sram_slave_test \ -DMASTER_OPERATIONS_COUNT=$(call FILE_LINES,$<) \ $(filter %.v,$^) -o $@ tests/slave_dispatcher/test.vvp : tests/slave_dispatcher/operations.mem \ tests/slave_dispatcher/test.v models/slave.v models/master.v \ design/slave_dispatcher.v include/messages.vh $(IV) $(IVFLAGS) -s slave_dispatcher_test \ -DMASTER_OPERATIONS_COUNT=$(call FILE_LINES,$<) \ $(filter %.v,$^) -o $@ tests/interface_wrapper/test.vvp : tests/interface_wrapper/operations.mem \ tests/interface_wrapper/test.v models/slave.v models/master.v \ design/interface_wrapper.v include/messages.vh $(IV) $(IVFLAGS) -s interface_wrapper_test \ -DMASTER_OPERATIONS_COUNT=$(call FILE_LINES,$<) \ $(filter %.v,$^) -o $@ tests/master_arbiter/test.vvp : tests/master_arbiter/operations0.mem \ tests/master_arbiter/operations1.mem \ tests/master_arbiter/test.v models/slave.v models/master.v \ design/master_arbiter.v include/messages.vh $(IV) $(IVFLAGS) -s master_arbiter_test \ -DMASTER0_OPERATIONS_COUNT=$(call FILE_LINES,$<) \ -DMASTER1_OPERATIONS_COUNT=$(call FILE_LINES,\ $(filter %1.mem,$^)) \ $(filter %.v,$^) -o $@ tests/embedded_bram_slave/test.vvp : tests/embedded_bram_slave/operations.mem \ tests/embedded_bram_slave/rom.mem \ tests/embedded_bram_slave/test.v models/master.v \ design/embedded_bram_slave.v include/messages.vh $(IV) $(IVFLAGS) -s embedded_bram_test \ -DMASTER_OPERATIONS_COUNT=$(call FILE_LINES,$<) \ -DROM_WORDS_COUNT=$(call FILE_LINES,$(filter %rom.mem,$^)) \ $(filter %.v,$^) -o $@ tests/div/test.vvp : tests/div/test.v design/div.v include/messages.vh $(IV) $(IVFLAGS) -s div_test $(filter %.v,$^) -o $@ tests/vga/test.vvp : tests/vga/test.v design/vga.v models/vga_display.v \ include/messages.vh $(IV) $(IVFLAGS) -s vga_test $^ -o $@ tests/stack_machine_%/test.vvp : \ tests/stack_machine_%/words_to_verify.mem \ tests/stack_machine_%/instructions.mem \ tests/stack_machine_%/test.v models/slave.v \ design/stack_machine.v design/div.v include/messages.vh $(IV) $(IVFLAGS) -s stack_machine_test \ -DINSTRUCTIONS_COUNT=$(call FILE_LINES,$(filter %ions.mem,$^)) \ -DWORDS_TO_VERIFY_COUNT=$(call FILE_LINES,$<) \ $(filter %.v,$^) -o $@ tests/stack_machine_old_%/test.vvp : \ tests/stack_machine_old_%/words_to_verify.mem \ tests/stack_machine_old_%/instructions.mem \ tests/stack_machine_old_%/test.v models/slave.v \ design/stack_machine_old.v design/div.v include/messages.vh $(IV) $(IVFLAGS) -s stack_machine_test \ -DINSTRUCTIONS_COUNT=$(call FILE_LINES,$(filter %ions.mem,$^)) \ -DWORDS_TO_VERIFY_COUNT=$(call FILE_LINES,$<) \ $(filter %.v,$^) -o $@ tests/soc_simple_display/test.vvp : tests/soc_simple_display/instructions.mem \ tests/soc_simple_display/test.v models/sram.v \ models/vga_display.v design/*.v include/messages.vh $(IV) $(IVFLAGS) -s soc_test -DROM_WORDS_COUNT=$(call FILE_LINES,$<) \ $(filter %.v,$^) -o $@ $(foreach TEST,$(TESTS_WITH_VGA),tests/$(TEST)/report.log) \ $(foreach TEST,$(TESTS_WITH_VGA),tests/$(TEST)/VGAdump.ppm) : design/font.mem tests/%/VGAdump.mem tests/%/report.log : tests/%/test.vvp cd $(dir $<) && vvp $(notdir $<) | $(call DBG&SAVE,report.log) tests/%/VGAdump.ppm : tests/%/VGAdump.mem tools/VGAdump2ppm grep -v // < $< | ./tools/VGAdump2ppm > $@ $(VGA_TEST_TARGETS) : test_% : tests/%/VGAdump_expected.ppm tests/%/VGAdump.ppm $(TEST_TARGETS) : test_% : tests/%/report.log if grep error $<; then false; fi if [ "$(filter $@,$(VGA_TEST_TARGETS))" != "" ]; then \ diff $(dir $<)VGAdump.ppm $(dir $<)VGAdump_expected.ppm; \ fi tools : $(TOOLS_TARGETS) $(TOOLS_TARGETS) : tools/% : tools/%.c $(CC) $(CFLAGS) $^ -o $@ clean : -find tests/ -name "*.vvp" -delete -find tests/ -name "*.log" -delete -find tests/ -name "VGAdump.mem" -delete -find tests/ -name "VGAdump.ppm" -delete -rm $(GENERATED_MEM_FILES) -rm design.json design.v design.asc design.bin timing.rpt -rm $(TOOLS_TARGETS) .PHONY : all tools test quicktest $(TEST_TARGETS)