Merge pull request #71 from SymbiFlow/ddrn

IO primitive fixes
diff --git a/database b/database
index 23630bc..d0b219a 160000
--- a/database
+++ b/database
@@ -1 +1 @@
-Subproject commit 23630bcb9492e125b58907832c258cc3ecc91936
+Subproject commit d0b219af41ae3da6150645fbc5cc5613b530603f
diff --git a/examples/ecp5_evn/Makefile b/examples/ecp5_evn/Makefile
index b977449..51f1a6f 100644
--- a/examples/ecp5_evn/Makefile
+++ b/examples/ecp5_evn/Makefile
@@ -1,12 +1,13 @@
 PROJ=blinky
+TRELLIS=/usr/share/trellis
 
 all: ${PROJ}.bit
 
 %.json: %.v
-	yosys -p "synth_ecp5 -noccu2 -nobram -nomux -json $@" $<
+	yosys -p "synth_ecp5 -json $@" $<
 
 %_out.config: %.json
-	nextpnr-ecp5 --json $< --basecfg ../../misc/basecfgs/empty_lfe5um5g-85f.config --textcfg $@ --um5g-85k --package CABGA381 --lpf ecp5evn.lpf
+	nextpnr-ecp5 --json $< --textcfg $@ --um5g-85k --package CABGA381 --lpf ecp5evn.lpf
 
 %.bit: %_out.config
 	ecppack --svf ${PROJ}.svf $< $@
@@ -14,7 +15,7 @@
 ${PROJ}.svf : ${PROJ}.bit
 
 prog: ${PROJ}.svf
-	openocd -f ../../misc/openocd/ecp5-evn.cfg -c "transport select jtag; init; svf $<; exit"
+	openocd -f ${TRELLIS}/misc/openocd/ecp5-evn.cfg -c "transport select jtag; init; svf $<; exit"
 
 clean:
 	rm -f *.svf *.bit *.config *.json
diff --git a/examples/picorv32_tinyfpga/Makefile b/examples/picorv32_tinyfpga/Makefile
index d4ac46b..38c541d 100644
--- a/examples/picorv32_tinyfpga/Makefile
+++ b/examples/picorv32_tinyfpga/Makefile
@@ -11,10 +11,10 @@
 	vvp -N $<
 
 attosoc.json: io_wrapper.v attosoc.v picorv32.v firmware.hex
-	yosys -p "synth_ecp5 -noccu2 -nomux -nodram -json $@" io_wrapper.v attosoc.v picorv32.v
+	yosys -p "synth_ecp5 -json $@" io_wrapper.v attosoc.v picorv32.v
 
 attosoc_out.config: attosoc.json
-	nextpnr-ecp5 --json $< --basecfg ../../misc/basecfgs/empty_lfe5um5g-85f.config --textcfg $@ --85k --package CSFBGA285 --seed 4
+	nextpnr-ecp5 --json $< --textcfg $@ --85k --package CSFBGA285 --seed 4
 attosoc.bit: attosoc_out.config
 	ecppack $< $@
 
diff --git a/examples/picorv32_ulx3s/Makefile b/examples/picorv32_ulx3s/Makefile
index 763b293..d0e0d48 100644
--- a/examples/picorv32_ulx3s/Makefile
+++ b/examples/picorv32_ulx3s/Makefile
@@ -11,10 +11,10 @@
 	vvp -N $<
 
 attosoc.json: io_wrapper.v attosoc.v picorv32.v firmware.hex
-	yosys -p "synth_ecp5 -noccu2 -nomux -nodram -json $@" io_wrapper.v attosoc.v picorv32.v
+	yosys -p "synth_ecp5 -json $@" io_wrapper.v attosoc.v picorv32.v
 
 attosoc_out.config: attosoc.json
-	nextpnr-ecp5 --json $< --basecfg ../../misc/basecfgs/empty_lfe5u-45f.config --textcfg $@ --45k --no-tmdriv
+	nextpnr-ecp5 --json $< --textcfg $@ --45k --no-tmdriv
 
 attosoc.bit: attosoc_out.config
 	ecppack $< $@
diff --git a/examples/picorv32_versa5g/Makefile b/examples/picorv32_versa5g/Makefile
index 409ae79..d8ce55d 100644
--- a/examples/picorv32_versa5g/Makefile
+++ b/examples/picorv32_versa5g/Makefile
@@ -1,3 +1,5 @@
+TRELLIS=/usr/share/trellis
+
 firmware.elf: sections.lds firmware.s
 	riscv32-unknown-elf-gcc -march=rv32i -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o firmware.elf firmware.s
 
@@ -14,16 +16,15 @@
 	yosys -p "synth_ecp5 -nomux -json $@ -top top" io_wrapper.v attosoc.v picorv32.v
 
 attosoc_out.config: attosoc.json
-	nextpnr-ecp5 --json $< --basecfg ../../misc/basecfgs/empty_lfe5um5g-45f.config --textcfg $@ --um5g-45k
+	nextpnr-ecp5 --json $< --textcfg $@ --um5g-45k
 
 attosoc.bit: attosoc_out.config
-	ecppack $< $@
+	ecppack --svf-rowsize 100000 --svf attosoc.svf $< $@
 
-%.svf: %.bit
-	../../tools/bit_to_svf.py $< $@
+attosoc.svf: attosoc.bit
 
 prog: attosoc.svf
-	openocd -f ../../misc/openocd/ecp5-versa5g.cfg -c "transport select jtag; init; svf $<; exit"
+	openocd -f ${TRELLIS}/misc/openocd/ecp5-versa5g.cfg -c "transport select jtag; init; svf $<; exit"
 
 .PHONY: attosoc_sim clean prog
 .PRECIOUS: attosoc.json attosoc_out.config attosoc.bit
diff --git a/examples/soc_ecp5_evn/Makefile b/examples/soc_ecp5_evn/Makefile
index 16d763c..2e45d3b 100644
--- a/examples/soc_ecp5_evn/Makefile
+++ b/examples/soc_ecp5_evn/Makefile
@@ -1,3 +1,5 @@
+TRELLIS=/usr/share/trellis
+
 firmware.elf: sections.lds start.s firmware.c
 	riscv32-unknown-elf-gcc -march=rv32i -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o firmware.elf start.s firmware.c
 
@@ -17,16 +19,15 @@
 	yosys -p "synth_ecp5 -json $@ -top top" top.v pll.v attosoc.v picorv32.v simpleuart.v
 
 attosoc_out.config: attosoc.json ecp5evn.lpf
-	nextpnr-ecp5 --json attosoc.json --lpf ecp5evn.lpf --basecfg ../../misc/basecfgs/empty_lfe5um5g-85f.config --textcfg $@ --um5g-85k --freq 50
+	nextpnr-ecp5 --json attosoc.json --lpf ecp5evn.lpf --textcfg $@ --um5g-85k --freq 50
 
 attosoc.bit: attosoc_out.config
-	ecppack $< $@
+	ecppack --svf-rowsize 100000 --svf attosoc.svf $< $@
 
 %.svf: %.bit
-	../../tools/bit_to_svf.py $< $@
 
 prog: attosoc.svf
-	openocd -f ../../misc/openocd/ecp5-evn.cfg -c "transport select jtag; init; svf $<; exit"
+	openocd -f ${TRELLIS}/misc/openocd/ecp5-evn.cfg -c "transport select jtag; init; svf $<; exit"
 
 .PHONY: attosoc_sim clean prog
 .PRECIOUS: attosoc.json attosoc_out.config attosoc.bit
diff --git a/examples/soc_versa5g/Makefile b/examples/soc_versa5g/Makefile
index 0cf51cd..d62934d 100644
--- a/examples/soc_versa5g/Makefile
+++ b/examples/soc_versa5g/Makefile
@@ -1,3 +1,5 @@
+TRELLIS=/usr/share/trellis
+
 firmware.elf: sections.lds start.s firmware.c
 	riscv32-unknown-elf-gcc -march=rv32i -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o firmware.elf start.s firmware.c
 
@@ -17,16 +19,15 @@
 	yosys -p "synth_ecp5 -json $@ -top top" top.v pll.v attosoc.v picorv32.v simpleuart.v
 
 attosoc_out.config: attosoc.json versa.lpf
-	nextpnr-ecp5 --json attosoc.json --lpf versa.lpf --basecfg ../../misc/basecfgs/empty_lfe5um5g-45f.config --textcfg $@ --um5g-45k --freq 50
+	nextpnr-ecp5 --json attosoc.json --lpf versa.lpf --textcfg $@ --um5g-45k --freq 50
 
 attosoc.bit: attosoc_out.config
-	ecppack $< $@
+	ecppack --svf-rowsize 100000 --svf attosoc.svf $< $@
 
 %.svf: %.bit
-	../../tools/bit_to_svf.py $< $@
 
 prog: attosoc.svf
-	openocd -f ../../misc/openocd/ecp5-versa5g.cfg -c "transport select jtag; init; svf $<; exit"
+	openocd -f ${TRELLIS}/misc/openocd/ecp5-versa5g.cfg -c "transport select jtag; init; svf $<; exit"
 
 .PHONY: attosoc_sim clean prog
 .PRECIOUS: attosoc.json attosoc_out.config attosoc.bit
diff --git a/examples/tinyfpga_rev1/Makefile b/examples/tinyfpga_rev1/Makefile
index 70c3da0..0c291f2 100644
--- a/examples/tinyfpga_rev1/Makefile
+++ b/examples/tinyfpga_rev1/Makefile
@@ -6,7 +6,7 @@
 	yosys -p "synth_ecp5 -noccu2 -nomux -nodram -json $@" $<
 
 %_out.config: %.json
-	nextpnr-ecp5 --json $< --basecfg empty_85k.config --textcfg $@ --85k --package CSFBGA285
+	nextpnr-ecp5 --json $< --textcfg $@ --85k --package CSFBGA285
 
 %.bit: %_out.config
 	ecppack $< $@
diff --git a/examples/tinyfpga_rev2/Makefile b/examples/tinyfpga_rev2/Makefile
index 0ff72dd..57e6352 100644
--- a/examples/tinyfpga_rev2/Makefile
+++ b/examples/tinyfpga_rev2/Makefile
@@ -6,7 +6,7 @@
 	yosys -p "synth_ecp5 -json $@" $<
 
 %_out.config: %.json
-	nextpnr-ecp5 --json $< --basecfg ../../misc/basecfgs/empty_lfe5um5g-85f.config --textcfg $@ --um5g-85k --package CSFBGA285 --lpf morse.lpf
+	nextpnr-ecp5 --json $< --textcfg $@ --um5g-85k --package CSFBGA285 --lpf morse.lpf
 
 %.bit: %_out.config
 	ecppack $< $@
diff --git a/examples/ulx3s/Makefile b/examples/ulx3s/Makefile
index 338216d..067ba4d 100644
--- a/examples/ulx3s/Makefile
+++ b/examples/ulx3s/Makefile
@@ -1,10 +1,10 @@
 all: blinky.bit
 
 blinky.json: blinky.v
-	yosys -p "synth_ecp5 -noccu2 -nomux -nodram -json blinky.json" blinky.v
+	yosys -p "synth_ecp5 -json blinky.json" blinky.v
 
 blinky_out.config: blinky.json
-	nextpnr-ecp5 --json blinky.json --basecfg ulx3s_empty.config --textcfg blinky_out.config --45k
+	nextpnr-ecp5 --json blinky.json --textcfg blinky_out.config --45k
 
 blinky.bit: blinky_out.config
 	ecppack blinky_out.config blinky.bit
diff --git a/examples/ulx3s/ulx3s_empty.config b/examples/ulx3s/ulx3s_empty.config
deleted file mode 100644
index 815e7f0..0000000
--- a/examples/ulx3s/ulx3s_empty.config
+++ /dev/null
@@ -1,439 +0,0 @@
-.device LFE5U-45F
-
-.tile CIB_R10C3:PVT_COUNT2
-unknown: F2B0
-unknown: F3B0
-unknown: F5B0
-unknown: F11B0
-unknown: F13B0
-
-.tile CIB_R5C1:CIB_PLL1
-enum: CIB.JA3MUX 0
-enum: CIB.JB3MUX 0
-
-
-.tile CIB_R5C89:CIB_PLL1
-enum: CIB.JA3MUX 0
-enum: CIB.JB3MUX 0
-
-
-.tile CIB_R70C3:CIB_PLL3
-enum: CIB.JA3MUX 0
-enum: CIB.JB3MUX 0
-
-
-.tile CIB_R70C42:VCIB_DCU0
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C43:VCIB_DCUA
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C44:VCIB_DCUB
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C45:VCIB_DCUC
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C46:VCIB_DCUD
-enum: CIB.JA1MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C47:VCIB_DCUF
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C48:VCIB_DCU3
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C49:VCIB_DCU2
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C50:VCIB_DCUG
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C51:VCIB_DCUH
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C52:VCIB_DCUI
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C53:VCIB_DCU1
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-
-
-.tile CIB_R70C69:VCIB_DCU0
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C6:CIB_EFB0
-enum: CIB.JB3MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C70:VCIB_DCUA
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C71:VCIB_DCUB
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C72:VCIB_DCUC
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C73:VCIB_DCUD
-enum: CIB.JA1MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C74:VCIB_DCUF
-enum: CIB.JA1MUX 0
-enum: CIB.JA3MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC2MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C75:VCIB_DCU3
-enum: CIB.JA5MUX 0
-enum: CIB.JA7MUX 0
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JC0MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC6MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C76:VCIB_DCU2
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C77:VCIB_DCUG
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C78:VCIB_DCUH
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C79:VCIB_DCUI
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB7MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD6MUX 0
-
-
-.tile CIB_R70C7:CIB_EFB1
-enum: CIB.JA3MUX 0
-enum: CIB.JA4MUX 0
-enum: CIB.JA5MUX 0
-enum: CIB.JA6MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB4MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JB6MUX 0
-enum: CIB.JC3MUX 0
-enum: CIB.JC4MUX 0
-enum: CIB.JC5MUX 0
-enum: CIB.JD3MUX 0
-enum: CIB.JD4MUX 0
-enum: CIB.JD5MUX 0
-
-
-.tile CIB_R70C80:VCIB_DCU1
-enum: CIB.JB1MUX 0
-enum: CIB.JB3MUX 0
-enum: CIB.JB5MUX 0
-enum: CIB.JD0MUX 0
-enum: CIB.JD2MUX 0
-
-
-.tile CIB_R70C87:CIB_PLL3
-enum: CIB.JA3MUX 0
-enum: CIB.JB3MUX 0
-
-
-.tile MIB_R10C40:CMUX_UL_0
-arc: G_DCS0CLK0 G_VPFN0000
-
-
-.tile MIB_R10C41:CMUX_UR_0
-arc: G_DCS0CLK1 G_VPFN0000
-
-
-.tile MIB_R58C40:CMUX_LL_0
-arc: G_DCS1CLK0 G_VPFN0000
-
-
-.tile MIB_R58C41:CMUX_LR_0
-arc: G_DCS1CLK1 G_VPFN0000
-
-
-.tile MIB_R71C4:EFB0_PICB0
-unknown: F54B1
-unknown: F56B1
-unknown: F82B1
-unknown: F94B1
-
-.tile MIB_R71C3:BANKREF8
-unknown: F18B0
-
diff --git a/examples/versa5g/Makefile b/examples/versa5g/Makefile
index 76ac577..811295c 100644
--- a/examples/versa5g/Makefile
+++ b/examples/versa5g/Makefile
@@ -1,5 +1,6 @@
 PROJ=demo
 CONSTR=versa.lpf
+TRELLIS=/usr/share/trellis
 
 all: ${PROJ}.bit
 
@@ -7,10 +8,10 @@
 	python3 make_14seg.py < text.in > pattern.vh
 
 %.json: %.v pattern.vh
-	yosys -p "synth_ecp5 -nomux -json $@" $<
+	yosys -p "synth_ecp5 -json $@" $<
 
 %_out.config: %.json
-	nextpnr-ecp5 --json $< --lpf ${CONSTR} --basecfg ../../misc/basecfgs/empty_lfe5um5g-45f.config --textcfg $@ --um5g-45k --package CABGA381
+	nextpnr-ecp5 --json $< --lpf ${CONSTR} --textcfg $@ --um5g-45k --package CABGA381
 
 %.bit: %_out.config
 	ecppack --svf-rowsize 100000 --svf ${PROJ}.svf $< $@
@@ -18,7 +19,7 @@
 ${PROJ}.svf: ${PROJ}.bit
 
 prog: ${PROJ}.svf
-	openocd -f ../../misc/openocd/ecp5-versa5g.cfg -c "transport select jtag; init; svf $<; exit"
+	openocd -f ${TRELLIS}/misc/openocd/ecp5-versa5g.cfg -c "transport select jtag; init; svf $<; exit"
 
 .PHONY: prog
 .PRECIOUS: ${PROJ}.json ${PROJ}_out.config
diff --git a/fuzzers/ECP5/144-bootaddr/fuzzer.py b/fuzzers/ECP5/144-bootaddr/fuzzer.py
new file mode 100644
index 0000000..c42eb7d
--- /dev/null
+++ b/fuzzers/ECP5/144-bootaddr/fuzzer.py
@@ -0,0 +1,45 @@
+import pytrellis
+
+# BOOTADDR is bit 23..16 of the address for the next image to boot
+# when PROGRAMN is asserted.
+# This Config word is as far as I can tell never generated by
+# Diamond itself, but instead by the Deployment tool
+# For this reason, I have manually "fuzzed" the info for it.
+# The name is arbitrarily chosen.
+
+
+def main():
+    pytrellis.load_database("../../../database")
+
+    config = [
+        (46, 1, 0),
+        (48, 1, 0),
+        (50, 1, 0),
+        (54, 1, 0),
+        (56, 1, 0),
+        (58, 1, 0),
+        (60, 1, 0),
+        (62, 1, 0),
+    ]
+
+    tile = pytrellis.get_tile_bitdata(
+        pytrellis.TileLocator("ECP5", "LFE5U-25F", "EFB1_PICB1"))
+    wsb = pytrellis.WordSettingBits()
+    wsb.name = "BOOTADDR"
+
+    for bframe, bbit, inv in config:
+        bg = pytrellis.BitGroup()
+        cb = pytrellis.ConfigBit()
+        cb.frame = bframe
+        cb.bit = bbit
+        cb.inv = inv
+        bg.bits.add(cb)
+        wsb.bits.append(bg)
+        wsb.defval.append(False)
+
+    tile.add_setting_word(wsb)
+    tile.save()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/libtrellis/CMakeLists.txt b/libtrellis/CMakeLists.txt
index 4f3edb9..4a3b9c0 100644
--- a/libtrellis/CMakeLists.txt
+++ b/libtrellis/CMakeLists.txt
@@ -108,16 +108,23 @@
 
 find_package(Boost REQUIRED COMPONENTS program_options)
 
+get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+if ("${LIB64}" STREQUAL "TRUE")
+    set(LIBDIR "lib64")
+else()
+    set(LIBDIR "lib")
+endif()
+
 function(setup_rpath name)
   if(APPLE)
     set_target_properties(${name} PROPERTIES
                           BUILD_WITH_INSTALL_RPATH ON
-                          INSTALL_RPATH "@loader_path/../lib"
+                          INSTALL_RPATH "@loader_path/../${LIBDIR}/trellis"
                           INSTALL_NAME_DIR "@rpath")
   elseif(UNIX)
     set_target_properties(${name} PROPERTIES
                           BUILD_WITH_INSTALL_RPATH ON
-                          INSTALL_RPATH "\$ORIGIN/../lib")
+                          INSTALL_RPATH "\$ORIGIN/../${LIBDIR}/trellis")
   endif()
 endfunction()
 
@@ -137,14 +144,14 @@
 setup_rpath(ecppll)
 
 if (BUILD_SHARED)
-    install(TARGETS trellis ecppack ecppll ecpunpack LIBRARY DESTINATION lib  RUNTIME DESTINATION bin)
+    install(TARGETS trellis ecppack ecppll ecpunpack LIBRARY DESTINATION ${LIBDIR}/trellis  RUNTIME DESTINATION bin)
 else()
     install(TARGETS ecppack ecpunpack ecppll RUNTIME DESTINATION bin)
 endif()
 install(DIRECTORY ../database DESTINATION share/trellis PATTERN ".git" EXCLUDE)
 install(DIRECTORY ../misc DESTINATION share/trellis)
 install(DIRECTORY ../util/common DESTINATION share/trellis/util)
-install(DIRECTORY ../timing/util DESTINATION share/trellis/timing)
+install(DIRECTORY ../timing/util DESTINATION share/trellis/timing USE_SOURCE_PERMISSIONS)
 if (BUILD_SHARED)
-   install(TARGETS pytrellis DESTINATION share/trellis/libtrellis)
+   install(TARGETS pytrellis DESTINATION ${LIBDIR}/trellis)
 endif()
diff --git a/libtrellis/include/Bitstream.hpp b/libtrellis/include/Bitstream.hpp
index 7e00910..08b2d82 100644
--- a/libtrellis/include/Bitstream.hpp
+++ b/libtrellis/include/Bitstream.hpp
@@ -12,6 +12,7 @@
 
 namespace Trellis {
 enum class BitstreamCommand : uint8_t {
+    SPI_MODE = 0b01111001,
     LSC_RESET_CRC = 0b00111011,
     VERIFY_ID = 0b11100010,
     LSC_WRITE_COMP_DIC = 0b00000010,
diff --git a/libtrellis/src/Bitstream.cpp b/libtrellis/src/Bitstream.cpp
index 16d6c8c..d87186a 100644
--- a/libtrellis/src/Bitstream.cpp
+++ b/libtrellis/src/Bitstream.cpp
@@ -23,6 +23,11 @@
      {"38.8", 0x38},
      {"62.0", 0x3b}};
 
+static const vector<pair<std::string, uint8_t>> spi_modes =
+    {{"fast-read", 0x49},
+     {"dual-spi", 0x51},
+     {"qspi", 0x59}};
+
 // The BitstreamReadWriter class stores state (including CRC16) whilst reading
 // the bitstream
 class BitstreamReadWriter {
@@ -356,6 +361,20 @@
                 rd.check_crc16();
             }
                 break;
+            case BitstreamCommand::SPI_MODE: {
+                uint8_t spi_mode;
+                rd.get_bytes(&spi_mode, 1);
+                rd.skip_bytes(2);
+
+                auto spimode = find_if(spi_modes.begin(), spi_modes.end(), [&](const pair<string, uint8_t> &fp){
+                    return fp.second == spi_mode;
+                });
+                if (spimode == spi_modes.end())
+                    throw runtime_error("bad SPI mode" + std::to_string(spi_mode));
+
+                BITSTREAM_NOTE("SPI Mode " <<  spimode->first);
+            }
+                break;
             case BitstreamCommand::DUMMY:
                 break;
             default: BITSTREAM_FATAL("unsupported command 0x" << hex << setw(2) << setfill('0') << int(cmd),
@@ -375,6 +394,19 @@
     wr.write_bytes(preamble.begin(), preamble.size());
     // Padding
     wr.insert_dummy(4);
+
+    if (options.count("spimode")) {
+        auto spimode = find_if(spi_modes.begin(), spi_modes.end(), [&](const pair<string, uint8_t> &fp){
+            return fp.first == options.at("spimode");
+        });
+        if (spimode == spi_modes.end())
+            throw runtime_error("bad spimode option " + options.at("spimode"));
+
+        wr.write_byte(uint8_t(BitstreamCommand::SPI_MODE));
+        wr.write_byte(uint8_t(spimode->second));
+        wr.insert_zeros(2);
+    }
+
     // Reset CRC
     wr.write_byte(uint8_t(BitstreamCommand::LSC_RESET_CRC));
     wr.insert_zeros(3);
diff --git a/libtrellis/tools/ecppack.cpp b/libtrellis/tools/ecppack.cpp
index 5ae362e..31a3f2b 100644
--- a/libtrellis/tools/ecppack.cpp
+++ b/libtrellis/tools/ecppack.cpp
@@ -35,6 +35,7 @@
     options.add_options()("freq", po::value<std::string>(), "config frequency in MHz");
     options.add_options()("svf", po::value<std::string>(), "output SVF file");
     options.add_options()("svf-rowsize", po::value<int>(), "SVF row size in bits (default 8000)");
+    options.add_options()("spimode", po::value<std::string>(), "SPI Mode to use (fast-read, dual-spi, qspi)");
 
     po::positional_options_description pos;
     options.add_options()("input", po::value<std::string>()->required(), "input textual configuration");
@@ -110,6 +111,9 @@
     if (vm.count("freq"))
         bitopts["freq"] = vm["freq"].as<string>();
 
+    if (vm.count("spimode"))
+        bitopts["spimode"] = vm["spimode"].as<string>();
+
     Bitstream b = Bitstream::serialise_chip(c, bitopts);
     if (vm.count("bit")) {
         ofstream bit_file(vm["bit"].as<string>(), ios::binary);