aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--config.mk2
-rw-r--r--docs/format.html12
-rw-r--r--docs/index.html2
-rw-r--r--icebox/Makefile66
-rw-r--r--icebox/icebox.py1
-rw-r--r--icebram/.gitignore2
-rw-r--r--icefuzz/Makefile40
-rw-r--r--icemulti/.gitignore1
-rw-r--r--icepack/.gitignore3
-rw-r--r--icepll/.gitignore1
-rw-r--r--iceprog/Makefile7
-rw-r--r--iceprog/iceprog.c74
-rw-r--r--icetime/Makefile4
-rw-r--r--icetime/icetime.cc53
15 files changed, 187 insertions, 83 deletions
diff --git a/README b/README
index 270875c..0f72781 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
Project IceStorm aims at documenting the bitstream format of Lattice iCE40
FPGAs and providing simple tools for analyzing and creating bitstream files.
-See http://www.clifford.at/icestorm/ for more information.
+See http://bygone.clairexen.net/icestorm/ for more information.
Most of Project IceStorm is licensed under the ISC license:
diff --git a/config.mk b/config.mk
index c7f80a3..4831f8b 100644
--- a/config.mk
+++ b/config.mk
@@ -40,3 +40,5 @@ PREFIX = /
LDFLAGS = -O2 --memory-init-file 0 -s TOTAL_MEMORY=64*1024*1024
SUBDIRS = icebox icepack icemulti icepll icetime icebram
endif
+
+PYTHON3 ?= python3
diff --git a/docs/format.html b/docs/format.html
index 8d36151..ee7a655 100644
--- a/docs/format.html
+++ b/docs/format.html
@@ -47,8 +47,10 @@ The following commands are known:
<table class="ctab">
<tr><th>Opcode</th><th>Description</th></tr>
-<tr><td>0</td><td>payload=1: CRAM Data<br/>
- payload=3: BRAM Data<br/>
+<tr><td>0</td><td>payload=1: Write CRAM Data<br/>
+ payload=2: Read BRAM Data<br/>
+ payload=3: Write BRAM Data<br/>
+ payload=4: Read BRAM Data<br/>
payload=5: Reset CRC<br/>
payload=6: Wakeup<br/>
payload=8: Reboot</td></tr>
@@ -59,9 +61,9 @@ The following commands are known:
payload=0: low<br/>
payload=1: medium<br/>
payload=2: high</td></tr>
-<tr><td>6</td><td>Set bank width</td></tr>
-<tr><td>7</td><td>Set bank height</td></tr>
-<tr><td>8</td><td>Set bank offset</td></tr>
+<tr><td>6</td><td>Set bank width (16-bits, MSB first)</td></tr>
+<tr><td>7</td><td>Set bank height (16-bits, MSB first)</td></tr>
+<tr><td>8</td><td>Set bank offset (16-bits, MSB first)</td></tr>
<tr><td>9</td><td>payload=0: Disable warm boot<br/>
payload=16: Enable cold boot<br/>
payload=32: Enable warm boot</td></tr>
diff --git a/docs/index.html b/docs/index.html
index a667d87..9f6b6eb 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -183,7 +183,7 @@ sudo make install</pre>
Installing <a href="https://github.com/YosysHQ/nextpnr">NextPNR</a> (place&amp;route tool, Arachne-PNR replacement):
</p>
-<pre style="padding-left: 3em">git clone https://github.com/YosysHQ/nextpnr nextpnr
+<pre style="padding-left: 3em">git clone --recursive https://github.com/YosysHQ/nextpnr nextpnr
cd nextpnr
cmake -DARCH=ice40 -DCMAKE_INSTALL_PREFIX=/usr/local .
make -j$(nproc)
diff --git a/icebox/Makefile b/icebox/Makefile
index 2897dfb..ffe439a 100644
--- a/icebox/Makefile
+++ b/icebox/Makefile
@@ -1,35 +1,41 @@
include ../config.mk
+ifneq ($(shell uname -s),Darwin)
+ SED_I = sed -i
+else
+ SED_I = sed -i ''
+endif
+
all: chipdb-384.txt chipdb-1k.txt chipdb-8k.txt chipdb-5k.txt chipdb-lm4k.txt chipdb-u4k.txt
chipdb-384.txt: icebox.py iceboxdb.py icebox_chipdb.py
- python3 icebox_chipdb.py -3 > chipdb-384.new
+ $(PYTHON3) icebox_chipdb.py -3 > chipdb-384.new
mv chipdb-384.new chipdb-384.txt
chipdb-1k.txt: icebox.py iceboxdb.py icebox_chipdb.py
- python3 icebox_chipdb.py > chipdb-1k.new
+ $(PYTHON3) icebox_chipdb.py > chipdb-1k.new
mv chipdb-1k.new chipdb-1k.txt
chipdb-5k.txt: icebox.py iceboxdb.py icebox_chipdb.py
- python3 icebox_chipdb.py -5 > chipdb-5k.new
+ $(PYTHON3) icebox_chipdb.py -5 > chipdb-5k.new
mv chipdb-5k.new chipdb-5k.txt
chipdb-u4k.txt: icebox.py iceboxdb.py icebox_chipdb.py
- python3 icebox_chipdb.py -u > chipdb-u4k.new
+ $(PYTHON3) icebox_chipdb.py -u > chipdb-u4k.new
mv chipdb-u4k.new chipdb-u4k.txt
chipdb-lm4k.txt: icebox.py iceboxdb.py icebox_chipdb.py
- python3 icebox_chipdb.py -4 > chipdb-lm4k.new
+ $(PYTHON3) icebox_chipdb.py -4 > chipdb-lm4k.new
mv chipdb-lm4k.new chipdb-lm4k.txt
chipdb-8k.txt: icebox.py iceboxdb.py icebox_chipdb.py
- python3 icebox_chipdb.py -8 > chipdb-8k.new
+ $(PYTHON3) icebox_chipdb.py -8 > chipdb-8k.new
mv chipdb-8k.new chipdb-8k.txt
check: all
- python3 tc_xlat_netnames.py
- python3 tc_rxlat_netnames.py
- python3 tc_logic_xpr.py
+ $(PYTHON3) tc_xlat_netnames.py
+ $(PYTHON3) tc_rxlat_netnames.py
+ $(PYTHON3) tc_logic_xpr.py
clean:
rm -f chipdb-1k.txt chipdb-8k.txt chipdb-384.txt chipdb-5k.txt chipdb-lm4k.txt chipdb-u4k.txt
@@ -56,27 +62,27 @@ install: all
cp icebox_maps.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_maps$(PY_EXE)
cp icebox_vlog.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_vlog$(PY_EXE)
cp icebox_stat.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_stat$(PY_EXE)
- sed -i 's+import iceboxdb+import $(subst -,_,$(PROGRAM_PREFIX))iceboxdb as iceboxdb+g' $(DESTDIR)$(PREFIX)/bin/$(subst -,_,$(PROGRAM_PREFIX))icebox.py
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_chipdb$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_diff$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_diff$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_explain$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_explain$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_asc2hlc$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_asc2hlc$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_hlc2asc$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_hlc2asc$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_colbuf$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_colbuf$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_html$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_html$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_maps$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_maps$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_vlog$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_vlog$(PY_EXE)
- sed -i 's+/usr/local/share/icebox+$(PREFIX)/share/$(PROGRAM_PREFIX)icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_vlog$(PY_EXE)
- sed -i 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_stat$(PY_EXE)
- sed -i 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_stat$(PY_EXE)
+ $(SED_I) 's+import iceboxdb+import $(subst -,_,$(PROGRAM_PREFIX))iceboxdb as iceboxdb+g' $(DESTDIR)$(PREFIX)/bin/$(subst -,_,$(PROGRAM_PREFIX))icebox.py
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_chipdb$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_diff$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_diff$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_explain$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_explain$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_asc2hlc$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_asc2hlc$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_hlc2asc$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_hlc2asc$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_colbuf$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_colbuf$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_html$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_html$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_maps$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_maps$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_vlog$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_vlog$(PY_EXE)
+ $(SED_I) 's+/usr/local/share/icebox+$(PREFIX)/share/$(PROGRAM_PREFIX)icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_vlog$(PY_EXE)
+ $(SED_I) 's+import icebox+import $(subst -,_,$(PROGRAM_PREFIX))icebox as icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_stat$(PY_EXE)
+ $(SED_I) 's+from icebox+from $(subst -,_,$(PROGRAM_PREFIX))icebox+g' $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_stat$(PY_EXE)
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/$(subst -,_,$(PROGRAM_PREFIX))cebox.py
diff --git a/icebox/icebox.py b/icebox/icebox.py
index a7631a2..ef5478b 100644
--- a/icebox/icebox.py
+++ b/icebox/icebox.py
@@ -1719,7 +1719,6 @@ noplls_db = {
"8k-cm81:4k": [ "8k_1" ],
"1k-qn48": [ "1k" ],
"1k-cb81": [ "1k" ],
- "1k-cb121": [ "1k" ],
"1k-vq100": [ "1k" ],
"384-qn32": [ "384" ],
}
diff --git a/icebram/.gitignore b/icebram/.gitignore
index 10fbc8a..d329cf5 100644
--- a/icebram/.gitignore
+++ b/icebram/.gitignore
@@ -11,3 +11,5 @@ demo_tb.v
icebram
icebram.d
icebram.o
+icebram.exe
+icebram.wasm
diff --git a/icefuzz/Makefile b/icefuzz/Makefile
index 9b8916e..91d0136 100644
--- a/icefuzz/Makefile
+++ b/icefuzz/Makefile
@@ -76,8 +76,8 @@ ifneq ($(RAM_SUFFIX),_5k)
cp cached_dsp3_5k.txt bitdata_dsp3_5k.txt
cp cached_ipcon_5k.txt bitdata_ipcon_5k.txt
endif
- ICEDEVICE=$(DEVICECLASS) python3 database.py
- python3 export.py
+ ICEDEVICE=$(DEVICECLASS) $(PYTHON3) database.py
+ $(PYTHON3) export.py
diff -U0 cached_io.txt bitdata_io.txt || cp -v bitdata_io.txt cached_io.txt
diff -U0 cached_logic.txt bitdata_logic.txt || cp -v bitdata_logic.txt cached_logic.txt
diff -U0 cached_ramb$(RAM_SUFFIX).txt bitdata_ramb$(RAM_SUFFIX).txt || cp -v bitdata_ramb$(RAM_SUFFIX).txt cached_ramb$(RAM_SUFFIX).txt
@@ -91,53 +91,53 @@ endif
timings:
ifeq ($(DEVICECLASS),5k)
cp tmedges.txt tmedges.tmp
- set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; sed '/defparam/d' < $$f > $$f.fixed; yosys -q -f verilog -s tmedges.ys $$f.fixed; python3 rename_dsps.py $$f; done
+ set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; sed '/defparam/d' < $$f > $$f.fixed; yosys -q -f verilog -s tmedges.ys $$f.fixed; $(PYTHON3) rename_dsps.py $$f; done
sort -u tmedges.tmp > tmedges.txt && rm -f tmedges.tmp
- python3 timings.py -t timings_up5k.txt work_*/*.sdf > timings_up5k.new
+ $(PYTHON3) timings.py -t timings_up5k.txt work_*/*.sdf > timings_up5k.new
mv timings_up5k.new timings_up5k.txt
else
ifeq ($(DEVICECLASS),u4k)
cp tmedges.txt tmedges.tmp
- set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; sed '/defparam/d' < $$f > $$f.fixed; yosys -q -f verilog -s tmedges.ys $$f.fixed; python3 rename_dsps.py $$f; done
+ set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; sed '/defparam/d' < $$f > $$f.fixed; yosys -q -f verilog -s tmedges.ys $$f.fixed; $(PYTHON3) rename_dsps.py $$f; done
sort -u tmedges.tmp > tmedges.txt && rm -f tmedges.tmp
- python3 timings.py -t timings_u4k.txt work_*/*.sdf > timings_u4k.new
+ $(PYTHON3) timings.py -t timings_u4k.txt work_*/*.sdf > timings_u4k.new
mv timings_u4k.new timings_u4k.txt
else
ifeq ($(DEVICECLASS),8k)
cp tmedges.txt tmedges.tmp
set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
sort -u tmedges.tmp > tmedges.txt && rm -f tmedges.tmp
- python3 timings.py -t timings_hx8k.txt work_*/*.sdf > timings_hx8k.new
+ $(PYTHON3) timings.py -t timings_hx8k.txt work_*/*.sdf > timings_hx8k.new
mv timings_hx8k.new timings_hx8k.txt
- python3 timings.py -t timings_lp8k.txt work_*/*.slp > timings_lp8k.new
+ $(PYTHON3) timings.py -t timings_lp8k.txt work_*/*.slp > timings_lp8k.new
mv timings_lp8k.new timings_lp8k.txt
else
ifeq ($(DEVICECLASS),384)
cp tmedges.txt tmedges.tmp
set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
sort -u tmedges.tmp > tmedges.txt && rm -f tmedges.tmp
- python3 timings.py -t timings_lp384.txt work_*/*.slp > timings_lp384.new
+ $(PYTHON3) timings.py -t timings_lp384.txt work_*/*.slp > timings_lp384.new
mv timings_lp384.new timings_lp384.txt
else
cp tmedges.txt tmedges.tmp
set -e; for f in work_$(DEVICECLASS)_*/*.vsb; do echo $$f; yosys -q -f verilog -s tmedges.ys $$f; done
sort -u tmedges.tmp > tmedges.txt && rm -f tmedges.tmp
- python3 timings.py -t timings_hx1k.txt work_*/*.sdf > timings_hx1k.new
+ $(PYTHON3) timings.py -t timings_hx1k.txt work_*/*.sdf > timings_hx1k.new
mv timings_hx1k.new timings_hx1k.txt
- python3 timings.py -t timings_lp1k.txt work_*/*.slp > timings_lp1k.new
+ $(PYTHON3) timings.py -t timings_lp1k.txt work_*/*.slp > timings_lp1k.new
mv timings_lp1k.new timings_lp1k.txt
endif
endif
endif
endif
timings_html:
- python3 timings.py -h tmedges.txt -t timings_hx1k.txt -l "HX1K with default temp/volt settings" > timings_hx1k.html
- python3 timings.py -h tmedges.txt -t timings_hx8k.txt -l "HX8K with default temp/volt settings" > timings_hx8k.html
- python3 timings.py -h tmedges.txt -t timings_lp1k.txt -l "LP1K with default temp/volt settings" > timings_lp1k.html
- python3 timings.py -h tmedges.txt -t timings_lp8k.txt -l "LP8K with default temp/volt settings" > timings_lp8k.html
- python3 timings.py -h tmedges.txt -t timings_lp384.txt -l "LP384 with default temp/volt settings" > timings_lp384.html
- python3 timings.py -h tmedges.txt -t timings_up5k.txt -l "UP5K with default temp/volt settings" > timings_up5k.html
- python3 timings.py -h tmedges.txt -t timings_u4k.txt -l "U4K with default temp/volt settings" > timings_u4k.html
+ $(PYTHON3) timings.py -h tmedges.txt -t timings_hx1k.txt -l "HX1K with default temp/volt settings" > timings_hx1k.html
+ $(PYTHON3) timings.py -h tmedges.txt -t timings_hx8k.txt -l "HX8K with default temp/volt settings" > timings_hx8k.html
+ $(PYTHON3) timings.py -h tmedges.txt -t timings_lp1k.txt -l "LP1K with default temp/volt settings" > timings_lp1k.html
+ $(PYTHON3) timings.py -h tmedges.txt -t timings_lp8k.txt -l "LP8K with default temp/volt settings" > timings_lp8k.html
+ $(PYTHON3) timings.py -h tmedges.txt -t timings_lp384.txt -l "LP384 with default temp/volt settings" > timings_lp384.html
+ $(PYTHON3) timings.py -h tmedges.txt -t timings_up5k.txt -l "UP5K with default temp/volt settings" > timings_up5k.html
+ $(PYTHON3) timings.py -h tmedges.txt -t timings_u4k.txt -l "U4K with default temp/volt settings" > timings_u4k.html
data_cached.txt: cached_io.txt cached_logic.txt cached_ramb$(RAM_SUFFIX).txt cached_ramt$(RAM_SUFFIX).txt cached_dsp0_5k.txt cached_dsp1_5k.txt cached_dsp2_5k.txt cached_dsp3_5k.txt cached_ipcon_5k.txt
gawk '{ print "io", $$0; }' cached_io.txt > data_cached.new
gawk '{ print "logic", $$0; }' cached_logic.txt >> data_cached.new
@@ -186,9 +186,9 @@ datafiles: $(addprefix data_,$(addsuffix .txt,$(TESTS)))
define data_template
data_$(DEVICECLASS)_$(1).txt: make_$(1).py ../icepack/icepack
- ICEDEVICE=$(DEVICECLASS) python3 make_$(1).py
+ ICEDEVICE=$(DEVICECLASS) $(PYTHON3) make_$(1).py
+ICEDEV=$(DEVICE) $(MAKE) -C work_$(DEVICECLASS)_$(1)
- ICEDEVICE=$(DEVICECLASS) python3 extract.py work_$(DEVICECLASS)_$(1)/*.glb > $$@
+ ICEDEVICE=$(DEVICECLASS) $(PYTHON3) extract.py work_$(DEVICECLASS)_$(1)/*.glb > $$@
endef
$(foreach test,$(TESTS),$(eval $(call data_template,$(test))))
diff --git a/icemulti/.gitignore b/icemulti/.gitignore
index 9254c71..43ef5a2 100644
--- a/icemulti/.gitignore
+++ b/icemulti/.gitignore
@@ -1,4 +1,5 @@
icemulti
icemulti.exe
+icemulti.wasm
icemulti.o
icemulti.d
diff --git a/icepack/.gitignore b/icepack/.gitignore
index ef4173d..a277e88 100644
--- a/icepack/.gitignore
+++ b/icepack/.gitignore
@@ -1,5 +1,8 @@
icepack
icepack.exe
+icepack.wasm
iceunpack
+iceunpack.exe
+iceunpack.wasm
icepack.o
icepack.d
diff --git a/icepll/.gitignore b/icepll/.gitignore
index 418d25b..8ed93c2 100644
--- a/icepll/.gitignore
+++ b/icepll/.gitignore
@@ -1,4 +1,5 @@
icepll
icepll.exe
+icepll.wasm
icepll.o
icepll.d
diff --git a/iceprog/Makefile b/iceprog/Makefile
index 3cb07b8..f41263e 100644
--- a/iceprog/Makefile
+++ b/iceprog/Makefile
@@ -1,12 +1,5 @@
include ../config.mk
-ifneq ($(shell uname -s),Darwin)
- LDLIBS = -L/usr/local/lib -lm
-else
- LIBFTDI_NAME = $(shell $(PKG_CONFIG) --exists libftdi1 && echo ftdi1 || echo ftdi)
- LDLIBS = -L/usr/local/lib -l$(LIBFTDI_NAME) -lm
-endif
-
ifeq ($(STATIC),1)
LDFLAGS += -static
LDLIBS += $(shell for pkg in libftdi1 libftdi; do $(PKG_CONFIG) --silence-errors --static --libs $$pkg && exit; done; echo -lftdi; )
diff --git a/iceprog/iceprog.c b/iceprog/iceprog.c
index b04fe65..8ee6443 100644
--- a/iceprog/iceprog.c
+++ b/iceprog/iceprog.c
@@ -96,16 +96,16 @@ enum flash_cmd {
static void set_cs_creset(int cs_b, int creset_b)
{
uint8_t gpio = 0;
- uint8_t direction = 0x93;
+ uint8_t direction = 0x03;
- if (cs_b) {
+ if (!cs_b) {
// ADBUS4 (GPIOL0)
- gpio |= 0x10;
+ direction |= 0x10;
}
- if (creset_b) {
+ if (!creset_b) {
// ADBUS7 (GPIOL3)
- gpio |= 0x80;
+ direction |= 0x80;
}
mpsse_set_gpio(gpio, direction);
@@ -180,7 +180,7 @@ static void flash_read_id()
if (data[4] == 0xFF)
fprintf(stderr, "Extended Device String Length is 0xFF, "
- "this is likely a read error. Ignorig...\n");
+ "this is likely a read error. Ignoring...\n");
else {
// Read extended JEDEC ID bytes
if (data[4] != 0) {
@@ -202,9 +202,15 @@ static void flash_reset()
{
uint8_t data[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ // This disables CRM is if it was enabled
flash_chip_select();
mpsse_xfer_spi(data, 8);
flash_chip_deselect();
+
+ // This disables QPI if it was enable
+ flash_chip_select();
+ mpsse_xfer_spi_bits(0xFF, 2);
+ flash_chip_deselect();
}
static void flash_power_up()
@@ -446,6 +452,34 @@ static void flash_disable_protection()
}
+static void flash_enable_quad()
+{
+ fprintf(stderr, "Enabling Quad operation...\n");
+
+ // Allow write
+ flash_write_enable();
+
+ // Write Status Register 2 <- 0x02
+ uint8_t data[2] = { FC_WSR2, 0x02 };
+ flash_chip_select();
+ mpsse_xfer_spi(data, 2);
+ flash_chip_deselect();
+
+ flash_wait();
+
+ // Read Status Register 1
+ data[0] = FC_RSR2;
+
+ flash_chip_select();
+ mpsse_xfer_spi(data, 2);
+ flash_chip_deselect();
+
+ if ((data[1] & 0x02) != 0x02)
+ fprintf(stderr, "failed to set QE=1, SR2 now equal to 0x%02x (expected 0x%02x)\n", data[1], data[1] | 0x02);
+
+ fprintf(stderr, "SR2: %08x\n", data[1]);
+}
+
// ---------------------------------------------------------
// iceprog implementation
// ---------------------------------------------------------
@@ -484,6 +518,7 @@ static void help(const char *progname)
fprintf(stderr, " -c do not write flash, only verify (`check')\n");
fprintf(stderr, " -S perform SRAM programming\n");
fprintf(stderr, " -t just read the flash ID sequence\n");
+ fprintf(stderr, " -Q just set the flash QE=1 bit\n");
fprintf(stderr, "\n");
fprintf(stderr, "Erase mode (only meaningful in default mode):\n");
fprintf(stderr, " [default] erase aligned chunks of 64kB in write mode\n");
@@ -543,7 +578,7 @@ int main(int argc, char **argv)
bool bulk_erase = false;
bool dont_erase = false;
bool prog_sram = false;
- bool test_mode = false;
+ int test_mode = 0;
bool slow_clock = false;
bool disable_protect = false;
bool disable_verify = false;
@@ -565,7 +600,7 @@ int main(int argc, char **argv)
/* Decode command line parameters */
int opt;
char *endptr;
- while ((opt = getopt_long(argc, argv, "d:i:I:rR:e:o:cbnStvspXk", long_options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "d:i:I:rR:e:o:cbnStQvspXk", long_options, NULL)) != -1) {
switch (opt) {
case 'd': /* device string */
devstr = optarg;
@@ -653,7 +688,10 @@ int main(int argc, char **argv)
prog_sram = true;
break;
case 't': /* just read flash id */
- test_mode = true;
+ test_mode = 1;
+ break;
+ case 'Q': /* just read flash id */
+ test_mode = 2;
break;
case 'v': /* provide verbose output */
verbose = true;
@@ -682,7 +720,7 @@ int main(int argc, char **argv)
/* Make sure that the combination of provided parameters makes sense */
- if (read_mode + erase_mode + check_mode + prog_sram + test_mode > 1) {
+ if (read_mode + erase_mode + check_mode + prog_sram + !!test_mode > 1) {
fprintf(stderr, "%s: options `-r'/`-R', `-e`, `-c', `-S', and `-t' are mutually exclusive\n", my_name);
return EXIT_FAILURE;
}
@@ -840,7 +878,10 @@ int main(int argc, char **argv)
flash_reset();
flash_power_up();
- flash_read_id();
+ if (test_mode == 1)
+ flash_read_id();
+ else
+ flash_enable_quad();
flash_power_down();
@@ -966,10 +1007,14 @@ int main(int argc, char **argv)
rc = fread(buffer, 1, page_size, f);
if (rc <= 0)
break;
+ fprintf(stderr, " \r");
+ fprintf(stderr, "addr 0x%06X %3ld%%\r", rw_offset + addr, 100 * addr / file_size);
flash_write_enable();
flash_prog(rw_offset + addr, buffer, rc);
flash_wait();
}
+ fprintf(stderr, " \r");
+ fprintf(stderr, "done.\n");
/* seek to the beginning for second pass */
fseek(f, 0, SEEK_SET);
@@ -984,9 +1029,13 @@ int main(int argc, char **argv)
fprintf(stderr, "reading..\n");
for (int addr = 0; addr < read_size; addr += 256) {
uint8_t buffer[256];
+ fprintf(stderr, " \r");
+ fprintf(stderr, "addr 0x%06X %3d%%\r", rw_offset + addr, 100 * addr / read_size);
flash_read(rw_offset + addr, buffer, 256);
fwrite(buffer, read_size - addr > 256 ? 256 : read_size - addr, 1, f);
}
+ fprintf(stderr, " \r");
+ fprintf(stderr, "done.\n");
} else if (!erase_mode && !disable_verify) {
fprintf(stderr, "reading..\n");
for (int addr = 0; true; addr += 256) {
@@ -994,6 +1043,8 @@ int main(int argc, char **argv)
int rc = fread(buffer_file, 1, 256, f);
if (rc <= 0)
break;
+ fprintf(stderr, " \r");
+ fprintf(stderr, "addr 0x%06X %3ld%%\r", rw_offset + addr, 100 * addr / file_size);
flash_read(rw_offset + addr, buffer_flash, rc);
if (memcmp(buffer_file, buffer_flash, rc)) {
fprintf(stderr, "Found difference between flash and file!\n");
@@ -1001,6 +1052,7 @@ int main(int argc, char **argv)
}
}
+ fprintf(stderr, " \r");
fprintf(stderr, "VERIFY OK\n");
}
diff --git a/icetime/Makefile b/icetime/Makefile
index 7d0ca32..1dfc926 100644
--- a/icetime/Makefile
+++ b/icetime/Makefile
@@ -32,7 +32,7 @@ $(PROGRAM_PREFIX)icetime$(EXE): icetime.o iceutil.o $(addsuffix .o, $(addprefix
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
timings-%.cc: timings.py ../icefuzz/timings_%.txt
- python3 timings.py $* > $@
+ $(PYTHON3) timings.py $* > $@
.PRECIOUS: timings-%.cc
@@ -51,7 +51,7 @@ uninstall:
# yosys -qp 'read_verilog -lib cells.v; prep; show' test0_out.v
test0 test1 test2 test3 test4 test5 test6 test7 test8 test9: icetime
- test -f $@_ref.v || python3 mktest.py $@
+ test -f $@_ref.v || $(PYTHON3) mktest.py $@
./icetime -m -d hx1k -P tq144 -p $@.pcf -o $@_out.v $@.asc
yosys $@.ys
diff --git a/icetime/icetime.cc b/icetime/icetime.cc
index d730fc6..fef65d2 100644
--- a/icetime/icetime.cc
+++ b/icetime/icetime.cc
@@ -59,6 +59,7 @@ std::set<std::tuple<int, int, int>> extra_bits;
std::set<std::string> io_names;
std::map<int, std::string> net_symbols;
+std::map<std::string, unsigned> lc_lut_in_mask;
bool get_config_bit(int tile_x, int tile_y, int bit_row, int bit_col)
{
@@ -221,10 +222,20 @@ void read_pcf(const char *filename)
if (tok == nullptr || strcmp(tok, "set_io"))
continue;
+ bool skip_next = false;
std::vector<std::string> args;
while ((tok = strtok(nullptr, " \t\r\n")) != nullptr) {
+ if(skip_next) {
+ skip_next = false;
+ continue;
+ }
if (!strcmp(tok, "--warn-no-port"))
continue;
+ if (!strcmp(tok, "-pullup") || !strcmp(tok, "-pullup_resistor")) {
+ skip_next = true; // skip argument
+ continue;
+ }
+
args.push_back(tok);
}
@@ -836,6 +847,15 @@ struct TimingAnalysis
}
if (driver_type == "LogicCell40" && (driver_port == "ltout" || driver_port == "lcout")) {
+ unsigned mask = lc_lut_in_mask.at(driver_cell);
+ if (inport == "in0" && ((mask & 0x1) == 0))
+ continue;
+ if (inport == "in1" && ((mask & 0x2) == 0))
+ continue;
+ if (inport == "in2" && ((mask & 0x4) == 0))
+ continue;
+ if (inport == "in3" && ((mask & 0x8) == 0))
+ continue;
if (inport == "carryin")
continue;
}
@@ -1221,14 +1241,37 @@ std::string make_lc40(int x, int y, int z)
for (int i = 0; i < 20; i++)
lcbits[i] = get_config_bit(x, y, lcbits_pos[i].first, lcbits_pos[i].second) ? '1' : '0';
+ static const std::vector<int> lut_perm = {
+ 4, 14, 15, 5, 6, 16, 17, 7, 3, 13, 12, 2, 1, 11, 10, 0,
+ };
+
+ unsigned lut_init = 0;
+ for (unsigned i = 0; i < lut_perm.size(); i++)
+ if (lcbits[lut_perm[i]] == '1')
+ lut_init |= (1U << i);
+
// FIXME: fill in the '0'
netlist_cell_params[cell]["C_ON"] = stringf("1'b%c", lcbits[8]);
netlist_cell_params[cell]["SEQ_MODE"] = stringf("4'b%c%c%c%c", lcbits[9], '0', '0', '0');
- netlist_cell_params[cell]["LUT_INIT"] = stringf("16'b%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
- lcbits[0], lcbits[10], lcbits[11], lcbits[1],
- lcbits[2], lcbits[12], lcbits[13], lcbits[3],
- lcbits[7], lcbits[17], lcbits[16], lcbits[6],
- lcbits[5], lcbits[15], lcbits[14], lcbits[4]);
+
+ std::string init = "16'b";
+ for (int i = 15; i >= 0; i--)
+ init += ((lut_init >> i) & 0x1) ? '1' : '0';
+
+ netlist_cell_params[cell]["LUT_INIT"] = init;
+
+ // Find which LUT inputs are "don't care" in the function, to avoid false paths for bits
+ // only affecting the carry.
+ lc_lut_in_mask[cell] = 0;
+ for (unsigned k = 0; k < 4; k++) {
+ for (unsigned i = 0; i < 16; i++) {
+ // If toggling the LUT input makes a difference it's not a don't care
+ if (((lut_init >> i) & 0x1U) != ((lut_init >> (i ^ (1U << k))) & 0x1U)) {
+ lc_lut_in_mask[cell] |= (1 << k);
+ break;
+ }
+ }
+ }
if (lcbits[8] == '1')
{