# # Makefile - fpgatools # Author: Wolfgang Spraul # # This is free and unencumbered software released into the public domain. # For details see the UNLICENSE file at the root of the source tree. # CFLAGS += -I$(CURDIR)/libs LDFLAGS += -Wl,-rpath,$(CURDIR)/libs OBJS = autotest.o bit2fp.o draw_svg_tiles.o fp2bit.o hstrrep.o \ merge_seq.o new_fp.o pair2net.o sort_seq.o hello_world.o \ blinking_led.o DYNAMIC_LIBS = libs/libfpga-model.so libs/libfpga-bit.so \ libs/libfpga-floorplan.so libs/libfpga-control.so \ libs/libfpga-cores.so .PHONY: all test clean install uninstall FAKE .SECONDARY: .SECONDEXPANSION: all: new_fp fp2bit bit2fp draw_svg_tiles autotest hstrrep \ sort_seq merge_seq pair2net hello_world blinking_led include Makefile.common %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< $(MKDEP) libs/%.so: FAKE @make -C libs $(notdir $@) # # Testing section - there are three types of tests: # # 1. design # # design tests run a design binary to produce floorplan stdout, which is # converted to binary configuration and back to floorplan. The resulting # floorplan after conversion through binary must match the original # floorplan. Additionally, the original floorplan is compared to a gold # standard if one exists. # # ./binary -> .fp -> .bit -> .fp -> compare first .fp to second and gold .fp # # 2. autotest # # autotest runs an automated test of some fpga logic and produces a log output # which is compared against a gold standard. # # ./autotest -> stdout -> compare with gold standard # # 3. compare # # tool output is parsed to extract different types of model data and compare # against a gold standard. # # tool output -> awk/processing -> compare to gold standard # # - extensions # # .ftest = fpgatools run test (design, autotest, compare) # # .f2gd = fpgatools to-gold diff # .ffbd = diff between first fp and after roundtrip through binary config # .fb2f = fpgatools binary config back to floorplan # .ff2b = fpgatools floorplan to binary config # .fco = fpgatools compare output for missing/extra # .fcr = fpgatools compare missing/extra result # .fcm = fpgatools compare match # .fcd = fpgatools compare diff # .fce = fpgatools compare extra # .fao = fpgatools autotest output # .far = fpgatools autotest result (diff to gold output) # test_dirs := $(shell mkdir -p test.gold test.out) DESIGN_TESTS := hello_world blinking_led AUTO_TESTS := logic_cfg routing_sw io_sw iob_cfg lut_encoding COMPARE_TESTS := xc6slx9_tiles xc6slx9_devs xc6slx9_ports xc6slx9_conns xc6slx9_sw xc6slx9_swbits DESIGN_GOLD := $(foreach target, $(DESIGN_TESTS), test.gold/design_$(target).fp) AUTOTEST_GOLD := $(foreach target, $(AUTO_TESTS), test.gold/autotest_$(target).fao) COMPARE_GOLD := $(foreach target, $(COMPARE_TESTS), test.gold/compare_$(target).fco) test_gold: design_gold autotest_gold compare_gold design_gold: $(DESIGN_GOLD) autotest_gold: $(AUTOTEST_GOLD) compare_gold: $(COMPARE_GOLD) test: test_design test_auto test_compare test_design: $(foreach target, $(DESIGN_TESTS), test.out/design_$(target).ftest) test_auto: $(foreach target, $(AUTO_TESTS), test.out/autotest_$(target).ftest) test_compare: $(foreach target, $(COMPARE_TESTS), test.out/compare_$(target).ftest) # design testing targets design_%.ftest: design_%.ffbd @if test -s $<; then echo "Design test: $(*F) - failed, diff follows"; cat $<; else echo "Design test: $(*F) - succeeded"; fi; @if test -s test.gold/$(basename $(@F)).fp; then diff -U 0 test.gold/$(basename $(@F)).fp $(basename $@).fp > $(basename $@).f2gd || (echo Diff to gold: && cat $(basename $@).f2gd); fi; %.ffbd: %.fp %.fb2f @diff -u $(basename $@).fp $(basename $@).fb2f >$@ || true %.fb2f: %.ff2b bit2fp @./bit2fp $< >$@ 2>&1 %.ff2b: %.fp fp2bit @./fp2bit $< $@ design_%.fp: $$* @./$(*F) >$@ 2>&1 # autotest targets autotest_%.ftest: autotest_%.far @if test -s $<; then echo "Test failed: $(*F) (autotest), diff follows"; cat $<; else echo "Test succeeded: $(*F) (autotest)"; fi; %.far: %.fao @if test ! -e test.gold/$(*F).fao; then echo Gold test.gold/$(*F).fao does not exist, aborting.; false; fi; @diff -U 0 -I "^O #NODIFF" test.gold/$(*F).fao $< >$@ || true autotest_%.fao: autotest fp2bit bit2fp ./autotest --test=$(*F) >$@ 2>&1 # compare testing targets compare_%.ftest: compare_%.fcr @echo Test: $(*F) \(compare\) @cat $<|awk '{print " "$$0}' %.fcr: %.fcm %.fcd %.fce @echo Matching lines - $*.fcm >$@ @cat $*.fcm | wc -l >>$@ @echo Missing lines - $*.fcd >>$@ @cat $*.fcd | grep ^-[^-] | wc -l >>$@ @if test -s $*.fce; then echo Extra lines - $*.fce: >>$@; cat $*.fce >>$@; fi; %.fcm: %.fco @if test ! -e test.gold/$(*F).fco; then echo Gold test.gold/$(*F).fco does not exist, aborting.; false; fi; @comm -1 -2 $< test.gold/$(*F).fco >$@ %.fcd: %.fco @if test ! -e test.gold/$(*F).fco; then echo Gold test.gold/$(*F).fco does not exist, aborting.; false; fi; @diff -u test.gold/$(*F).fco $< >$@ || true %.fce: %.fcd @cat $< | grep ^+[^+] >$@ || true compare_%_tiles.fco: compare_%.fp @cat $<|awk '{if ($$1=="tile" && $$4=="name") printf "%s %s %s\n",$$2,$$3,$$5}'|sort >$@ compare_%_devs.fco: compare_%.fp @cat $<|awk '{if ($$1=="dev") {if ($$6=="type") printf "%s %s %s %s\n",$$2,$$3,$$4,$$7; else printf "%s %s %s\n",$$2,$$3,$$4; }}'|sort >$@ compare_%_ports.fco: compare_%.fp @cat $<|awk '{if ($$1=="port") printf "%s %s %s\n",$$2,$$3,$$4}'|sort >$@ compare_%_conns.fco: compare_%.fp sort_seq merge_seq @cat $<|awk '{if ($$1=="conn") printf "%s %s %s %s %s %s\n",$$2,$$3,$$5,$$6,$$4,$$7}'|sort|./sort_seq -|./merge_seq -|awk '{printf "%s %s %s %s %s %s\n",$$1,$$2,$$5,$$3,$$4,$$6}'|sort >$@ compare_%_sw.fco: compare_%.fp @cat $<|awk '{if ($$1=="sw") printf "%s %s %s %s %s\n",$$2,$$3,$$4,$$5,$$6}'|sort >$@ compare_%_swbits.fco: bit2fp @./bit2fp --printf-swbits | sort > $@ compare_%.fp: new_fp @./new_fp >$@ # todo: .cnets not integrated yet %.cnets: %.fp pair2net cat $<|awk '{if ($$1=="conn") printf "%s-%s-%s %s-%s-%s\n",$$2,$$3,$$4,$$5,$$6,$$7}' |./pair2net -|sort >$@ @echo Number of conn nets: @cat $@|wc -l @echo Number of connection points: @cat $@|wc -w @echo Largest net: @cat $@|awk '{if (NF>max) max=NF} END {print max}' # # end of testing section # autotest: autotest.o $(DYNAMIC_LIBS) hello_world: hello_world.o $(DYNAMIC_LIBS) blinking_led: blinking_led.o $(DYNAMIC_LIBS) fp2bit: fp2bit.o $(DYNAMIC_LIBS) bit2fp: bit2fp.o $(DYNAMIC_LIBS) new_fp: new_fp.o $(DYNAMIC_LIBS) draw_svg_tiles: CFLAGS += `pkg-config libxml-2.0 --cflags` draw_svg_tiles: LDLIBS += `pkg-config libxml-2.0 --libs` draw_svg_tiles: draw_svg_tiles.o $(DYNAMIC_LIBS) pair2net: pair2net.o $(DYNAMIC_LIBS) sort_seq: sort_seq.o $(DYNAMIC_LIBS) merge_seq: merge_seq.o $(DYNAMIC_LIBS) hstrrep: hstrrep.o $(DYNAMIC_LIBS) xc6slx9.fp: new_fp ./new_fp > $@ xc6slx9.svg: draw_svg_tiles ./draw_svg_tiles | xmllint --pretty 1 - > $@ clean: @make -C libs clean rm -f $(OBJS) *.d rm -f draw_svg_tiles new_fp hstrrep sort_seq merge_seq autotest rm -f fp2bit bit2fp pair2net hello_world blinking_led rm -f xc6slx9.fp xc6slx9.svg rm -f $(DESIGN_GOLD) $(AUTOTEST_GOLD) $(COMPARE_GOLD) rm -f test.gold/compare_xc6slx9.fp rm -f $(foreach f, $(DESIGN_TESTS), test.out/design_$(f).ffbd) rm -f $(foreach f, $(DESIGN_TESTS), test.out/design_$(f).ff2b) rm -f $(foreach f, $(DESIGN_TESTS), test.out/design_$(f).fb2f) rm -f $(foreach f, $(DESIGN_TESTS), test.out/design_$(f).f2gd) rm -f $(foreach f, $(DESIGN_TESTS), test.out/design_$(f).fp) rm -f test.out/autotest_* rm -f $(foreach f, $(COMPARE_TESTS), test.out/compare_$(f).fco) rm -f $(foreach f, $(COMPARE_TESTS), test.out/compare_$(f).fcr) rm -f $(foreach f, $(COMPARE_TESTS), test.out/compare_$(f).fcm) rm -f $(foreach f, $(COMPARE_TESTS), test.out/compare_$(f).fcd) rm -f $(foreach f, $(COMPARE_TESTS), test.out/compare_$(f).fce) rm -f test.out/compare_xc6slx9.fp rmdir --ignore-fail-on-non-empty test.out test.gold install: fp2bit bit2fp @make -C libs install mkdir -p $(DESTDIR)/$(PREFIX)/bin/ install -m 755 fp2bit $(DESTDIR)/$(PREFIX)/bin/ install -m 755 bit2fp $(DESTDIR)/$(PREFIX)/bin/ chrpath -d $(DESTDIR)/$(PREFIX)/bin/fp2bit chrpath -d $(DESTDIR)/$(PREFIX)/bin/bit2fp uninstall: @make -C libs uninstall rm -f $(DESTDIR)/$(PREFIX)/bin/{fp2bit,bit2fp}