aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.mk7
-rw-r--r--docs/index.html58
-rw-r--r--icebox/Makefile101
-rw-r--r--icebox/icebox.py195
-rwxr-xr-xicebox/icebox_asc2hlc.py8
-rwxr-xr-xicebox/icebox_chipdb.py6
-rwxr-xr-xicebox/icebox_colbuf.py6
-rwxr-xr-xicebox/icebox_diff.py6
-rwxr-xr-xicebox/icebox_explain.py6
-rwxr-xr-xicebox/icebox_hlc2asc.py8
-rwxr-xr-xicebox/icebox_html.py2
-rwxr-xr-xicebox/icebox_maps.py19
-rwxr-xr-xicebox/icebox_stat.py6
-rwxr-xr-xicebox/icebox_vlog.py11
-rw-r--r--icebram/.gitignore2
-rw-r--r--icebram/Makefile14
-rw-r--r--icebram/icebram.cc26
-rwxr-xr-xicefuzz/tests/ip/trace_ip_u4k.py347
-rw-r--r--icefuzz/tests/ip/u4k_I2C_data.txt84
-rw-r--r--icefuzz/tests/ip/u4k_SPI_data.txt108
-rw-r--r--icemulti/.gitignore1
-rw-r--r--icemulti/Makefile12
-rw-r--r--icemulti/icemulti.cc8
-rw-r--r--icepack/.gitignore3
-rw-r--r--icepack/Makefile24
-rw-r--r--icepack/icepack.cc20
-rw-r--r--icepll/.gitignore1
-rw-r--r--icepll/Makefile12
-rw-r--r--icepll/icepll.cc207
-rw-r--r--iceprog/Makefile19
-rw-r--r--iceprog/iceprog.c77
-rw-r--r--icetime/Makefile20
-rw-r--r--icetime/icetime.cc31
-rw-r--r--icetime/iceutil.cc2
34 files changed, 1209 insertions, 248 deletions
diff --git a/config.mk b/config.mk
index 96f6dee..66870fe 100644
--- a/config.mk
+++ b/config.mk
@@ -1,6 +1,7 @@
PREFIX ?= /usr/local
DEBUG ?= 0
ICEPROG ?= 1
+PROGRAM_PREFIX ?=
CXX ?= clang++
CC ?= clang
@@ -18,11 +19,11 @@ endif
WARN_LEVEL ?= all
LDLIBS = -lm -lstdc++
-CFLAGS += -MD -O$(OPT_LEVEL) $(DBG_LEVEL) -W$(WARN_LEVEL) -std=$(C_STD) -I$(PREFIX)/include
-CXXFLAGS += -MD -O$(OPT_LEVEL) $(DBG_LEVEL) -W$(WARN_LEVEL) -std=$(CXX_STD) -I$(PREFIX)/include
+CFLAGS += -MD -MP -O$(OPT_LEVEL) $(DBG_LEVEL) -W$(WARN_LEVEL) -std=$(C_STD) -I$(PREFIX)/include
+CXXFLAGS += -MD -MP -O$(OPT_LEVEL) $(DBG_LEVEL) -W$(WARN_LEVEL) -std=$(CXX_STD) -I$(PREFIX)/include
DESTDIR ?=
-CHIPDB_SUBDIR ?= icebox
+CHIPDB_SUBDIR ?= $(PROGRAM_PREFIX)icebox
ifeq ($(MXE),1)
EXE = .exe
diff --git a/docs/index.html b/docs/index.html
index 3ca1721..9f6b6eb 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -20,9 +20,9 @@
<b>2017-03-13:</b> Released support for LP384 chips (in all package variants).<br/>
<b>2016-02-07:</b> Support for all package variants of LP1K, LP4K, LP8K and HX1K, HX4K, and HX8K.<br/>
<b>2016-01-17:</b> First release of IceTime timing analysis. Video: <a href="https://youtu.be/IG5CpFJRnOk">https://youtu.be/IG5CpFJRnOk</a><br/>
-<b>2015-12-27:</b> <a href="http://www.clifford.at/papers/2015/icestorm-flow/">Presentation</a> of the IceStorm flow at 32C3 (<a href="https://www.youtube.com/watch?v=SOn0g3k0FlE">Video on Youtube</a>).<br/>
+<b>2015-12-27:</b> <a href="http://bygone.clairexen.net/papers/2015/icestorm-flow/">Presentation</a> of the IceStorm flow at 32C3 (<a href="https://www.youtube.com/watch?v=SOn0g3k0FlE">Video on Youtube</a>).<br/>
<b>2015-07-19:</b> Released support for 8k chips. Moved IceStorm source code to GitHub.<br/>
-<b>2015-05-27:</b> We have a working fully Open Source flow with <a href="http://www.clifford.at/yosys/">Yosys</a> and <a href="https://github.com/cseed/arachne-pnr">Arachne-pnr</a>! Video: <a href="http://youtu.be/yUiNlmvVOq8">http://youtu.be/yUiNlmvVOq8</a><br/>
+<b>2015-05-27:</b> We have a working fully Open Source flow with <a href="http://bygone.clairexen.net/yosys/">Yosys</a> and <a href="https://github.com/cseed/arachne-pnr">Arachne-pnr</a>! Video: <a href="http://youtu.be/yUiNlmvVOq8">http://youtu.be/yUiNlmvVOq8</a><br/>
<b>2015-04-13:</b> Complete rewrite of IceUnpack, added IcePack, some major documentation updates<br/>
<b>2015-03-22:</b> First public release and short YouTube video demonstrating our work: <a href="http://youtu.be/u1ZHcSNDQMM">http://youtu.be/u1ZHcSNDQMM</a>
</p>
@@ -30,10 +30,10 @@
<h2>What is Project IceStorm?</h2>
<p>
-Project IceStorm aims at reverse engineering and documenting the bitstream
+Project IceStorm aims at documenting the bitstream
format of Lattice iCE40 FPGAs and providing simple tools for analyzing and
creating bitstream files. The IceStorm flow (<a
-href="http://www.clifford.at/yosys/">Yosys</a>, <a
+href="http://bygone.clairexen.net/yosys/">Yosys</a>, <a
href="https://github.com/cseed/arachne-pnr">Arachne-pnr</a>, and IceStorm) is a
fully open source Verilog-to-Bitstream flow for iCE40 FPGAs.
</p>
@@ -49,8 +49,8 @@ and UltraLite parts are not yet supported.
<p>
It has a very minimalistic architecture with a very regular structure. There are not many
-different kinds of tiles or special function units. This makes it both ideal for
-reverse engineering and as a reference platform for general purpose FPGA tool development.
+different kinds of tiles or special function units. This makes it both ideal for creating
+bitstream documentations and as a reference platform for general purpose FPGA tool development.
</p>
<p>
@@ -64,8 +64,8 @@ Breakout Board</a> featuring an HX8K chip.)
<h2>What is the Status of the Project?</h2>
<p>
-We are pretty confident that we have the 1K and 8K devices completely reverse
-engineered. For example, it seems we can create correct functional Verilog
+We are pretty confident that we have the 1K and 8K devices completely
+documented. For example, it seems we can create correct functional Verilog
models for all bitstreams generated by Lattice iCEcube2 for the iCE40
HX1K-TQ144 and the iCE40 HX8K-CT256 using our <tt>icebox_vlog</tt> tool.
</p>
@@ -115,7 +115,7 @@ Current work focuses on further improving our timing analysis flow.
<h2>How do I use the Fully Open Source iCE40 Flow?</h2>
<p>
-Synthesis for iCE40 FPGAs can be done with <a href="http://www.clifford.at/yosys/">Yosys</a>.
+Synthesis for iCE40 FPGAs can be done with <a href="http://bygone.clairexen.net/yosys/">Yosys</a>.
Place-and-route can be done with <a href="https://github.com/cseed/arachne-pnr">arachne-pnr</a>.
Here is an example script for implementing and programming the <a
href="https://github.com/cseed/arachne-pnr/tree/master/examples/rot">rot example from
@@ -162,10 +162,10 @@ Note: All tools will be installed relative to /usr/local
</p>
<p>
-Installing the <a href="https://github.com/cliffordwolf/icestorm">IceStorm Tools</a> (icepack, icebox, iceprog, icetime, chip databases):
+Installing the <a href="https://github.com/YosysHQ/icestorm">IceStorm Tools</a> (icepack, icebox, iceprog, icetime, chip databases):
</p>
-<pre style="padding-left: 3em">git clone https://github.com/cliffordwolf/icestorm.git icestorm
+<pre style="padding-left: 3em">git clone https://github.com/YosysHQ/icestorm.git icestorm
cd icestorm
make -j$(nproc)
sudo make install</pre>
@@ -183,17 +183,17 @@ 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)
sudo make install</pre>
<p>
-Installing <a href="http://www.clifford.at/yosys/">Yosys</a> (Verilog synthesis):
+Installing <a href="http://bygone.clairexen.net/yosys/">Yosys</a> (Verilog synthesis):
</p>
-<pre style="padding-left: 3em">git clone https://github.com/cliffordwolf/yosys.git yosys
+<pre style="padding-left: 3em">git clone https://github.com/YosysHQ/yosys.git yosys
cd yosys
make -j$(nproc)
sudo make install</pre>
@@ -220,7 +220,7 @@ bit-streams to a Lattice iCEstick and/or a Lattice iCE40-HX8K Breakout Board as
</p>
<p>
-Please <a href="https://github.com/cliffordwolf/icestorm/issues/new">file an issue on github</a> if you have additional notes to
+Please <a href="https://github.com/YosysHQ/icestorm/issues/new">file an issue on github</a> if you have additional notes to
share regarding the install procedures on the operating system of your choice.
</p>
@@ -229,9 +229,9 @@ share regarding the install procedures on the operating system of your choice.
<p>
The IceStorm Tools are a couple of small programs for working with iCE40 bitstream files and our
ASCII representation of it. The complete Open Source iCE40 Flow consists of the <a
-href="https://github.com/cliffordwolf/icestorm">IceStorm Tools</a>, <a
+href="https://github.com/YosysHQ/icestorm">IceStorm Tools</a>, <a
href="https://github.com/cseed/arachne-pnr">Arachne-PNR</a>, and <a
-href="http://www.clifford.at/yosys/">Yosys</a>.
+href="http://bygone.clairexen.net/yosys/">Yosys</a>.
</p>
<h3>IcePack/IceUnpack</h3>
@@ -293,7 +293,7 @@ create an IceStorm ASCII file for the placed and routed design.
</p>
<p>
-<i>IcePack/IceUnpack, IceBox, IceProg, IceTime, and IcePLL are written by Clifford Wolf. IcePack/IceUnpack is based on a reference implementation provided by Mathias Lasser. IceMulti is written by Marcus Comstedt.</i>
+<i>IcePack/IceUnpack, IceBox, IceProg, IceTime, and IcePLL are written by Claire Wolf. IcePack/IceUnpack is based on a reference implementation provided by Mathias Lasser. IceMulti is written by Marcus Comstedt.</i>
</p>
<h2>Where do I get support or meet other IceStorm users?</h2>
@@ -309,8 +309,8 @@ For general discussions go to the <a href="https://www.reddit.com/r/yosys/">Yosy
</p>
<p>
-If you have a bug report please file an issue on github. (<a href="https://github.com/cliffordwolf/icestorm/issues">IceStorm Issue Tracker</a>,
-<a href="https://github.com/cliffordwolf/yosys/issues">Yosys Issue Tracker</a>, <a href="https://github.com/cseed/arachne-pnr/issues">Arachne-PNR Issue Tracker</a>)
+If you have a bug report please file an issue on github. (<a href="https://github.com/YosysHQ/icestorm/issues">IceStorm Issue Tracker</a>,
+<a href="https://github.com/YosysHQ/yosys/issues">Yosys Issue Tracker</a>, <a href="https://github.com/cseed/arachne-pnr/issues">Arachne-PNR Issue Tracker</a>)
</p>
<h2 id="docs">Where is the Documentation?</h2>
@@ -521,7 +521,7 @@ endmodule</pre>
<h2>Links</h2>
<p>
-Links to related projects. Contact me at clifford@clifford.at if you have an interesting and relevant link.
+Links to related projects. Contact me at claire@clairexen.net if you have an interesting and relevant link.
</p>
<ul>
@@ -557,31 +557,33 @@ Links to related projects. Contact me at clifford@clifford.at if you have an int
<li><a href="http://hedmen.org/icestorm-doc/icestorm.html">IceStorm Learner’s Documentation</a>
</ul>
-<h3>Other FPGA reverse engineering projects</h3>
+<h3>Other FPGA bitstream documentation projects</h3>
<ul>
-<li><a href="https://github.com/Wolfgang-Spraul/fpgatools">Xilinx xc6slx9 reverse engineering, Wolfgang Spraul</a>
+<li><a href="https://github.com/SymbiFlow/prjtrellis">ECP5 bitstream documentation (Project Trellis)</a>
+<li><a href="https://github.com/SymbiFlow/prjxray">Xilinx 7-series bitstream documentation (Project X-Ray)</a>
+<li><a href="https://github.com/Wolfgang-Spraul/fpgatools">Xilinx xc6slx9 documentation, Wolfgang Spraul</a>
<li><a href="http://www.fabienm.eu/flf/wp-content/uploads/2014/11/Note2008.pdf">From the bitstream to the netlist, Jean-Baptiste Note and Éric Rannaud</a>
-<li><a href="http://git.bfuser.eu/?p=marex/typhoon.git;a=commit">Cyclone IV EP4CE6 reverse engineering, Marek Vasut</a>
+<li><a href="http://git.bfuser.eu/?p=marex/typhoon.git;a=commit">Cyclone IV EP4CE6 documentation, Marek Vasut</a>
</ul>
<hr>
<p>
-In papers and reports, please refer to Project IceStorm as follows: Clifford Wolf, Mathias Lasser. Project IceStorm. http://www.clifford.at/icestorm/,
+In papers and reports, please refer to Project IceStorm as follows: Claire Wolf, Mathias Lasser. Project IceStorm. http://bygone.clairexen.net/icestorm/,
e.g. using the following BibTeX code:
</p>
<pre>@MISC{IceStorm,
- author = {Clifford Wolf and Mathias Lasser},
+ author = {Claire Wolf and Mathias Lasser},
title = {Project IceStorm},
- howpublished = "\url{http://www.clifford.at/icestorm/}"
+ howpublished = "\url{http://bygone.clairexen.net/icestorm/}"
}</pre>
<hr>
<p>
-<i>Documentation mostly by Clifford Wolf &lt;clifford@clifford.at&gt; in 2015. Based on research by Mathias Lasser and Clifford Wolf.<br/>
+<i>Documentation mostly by Claire Wolf &lt;claire@clairexen.net&gt; in 2015. Based on research by Mathias Lasser and Claire Wolf.<br/>
Buy an <a href="http://www.latticesemi.com/icestick">iCEstick</a> or <a href="http://www.latticesemi.com/en/Products/DevelopmentBoardsAndKits/iCE40HX8KBreakoutBoard.aspx">iCE40-HX8K Breakout Board</a> from Lattice and see what you can do with the tools and information provided here.</i>
</p>
diff --git a/icebox/Makefile b/icebox/Makefile
index 5088f46..38ec8a4 100644
--- a/icebox/Makefile
+++ b/icebox/Makefile
@@ -1,5 +1,11 @@
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
@@ -36,45 +42,66 @@ clean:
rm -f icebox.pyc iceboxdb.pyc
install: all
- mkdir -p $(DESTDIR)$(PREFIX)/share/icebox
+ mkdir -p $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox
mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp chipdb-384.txt $(DESTDIR)$(PREFIX)/share/icebox/
- cp chipdb-1k.txt $(DESTDIR)$(PREFIX)/share/icebox/
- cp chipdb-8k.txt $(DESTDIR)$(PREFIX)/share/icebox/
- cp chipdb-5k.txt $(DESTDIR)$(PREFIX)/share/icebox/
- cp chipdb-u4k.txt $(DESTDIR)$(PREFIX)/share/icebox/
- cp chipdb-lm4k.txt $(DESTDIR)$(PREFIX)/share/icebox/
- cp icebox.py $(DESTDIR)$(PREFIX)/bin/icebox.py
- cp iceboxdb.py $(DESTDIR)$(PREFIX)/bin/iceboxdb.py
- cp icebox_chipdb.py $(DESTDIR)$(PREFIX)/bin/icebox_chipdb$(PY_EXE)
- cp icebox_diff.py $(DESTDIR)$(PREFIX)/bin/icebox_diff$(PY_EXE)
- cp icebox_explain.py $(DESTDIR)$(PREFIX)/bin/icebox_explain$(PY_EXE)
- cp icebox_asc2hlc.py $(DESTDIR)$(PREFIX)/bin/icebox_asc2hlc$(PY_EXE)
- cp icebox_hlc2asc.py $(DESTDIR)$(PREFIX)/bin/icebox_hlc2asc$(PY_EXE)
- cp icebox_colbuf.py $(DESTDIR)$(PREFIX)/bin/icebox_colbuf$(PY_EXE)
- cp icebox_html.py $(DESTDIR)$(PREFIX)/bin/icebox_html$(PY_EXE)
- cp icebox_maps.py $(DESTDIR)$(PREFIX)/bin/icebox_maps$(PY_EXE)
- cp icebox_vlog.py $(DESTDIR)$(PREFIX)/bin/icebox_vlog$(PY_EXE)
- cp icebox_stat.py $(DESTDIR)$(PREFIX)/bin/icebox_stat$(PY_EXE)
+ cp chipdb-384.txt $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/
+ cp chipdb-1k.txt $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/
+ cp chipdb-8k.txt $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/
+ cp chipdb-5k.txt $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/
+ cp chipdb-u4k.txt $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/
+ cp chipdb-lm4k.txt $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/
+ cp icebox.py $(DESTDIR)$(PREFIX)/bin/$(subst -,_,$(PROGRAM_PREFIX))icebox.py
+ cp iceboxdb.py $(DESTDIR)$(PREFIX)/bin/$(subst -,_,$(PROGRAM_PREFIX))iceboxdb.py
+ cp icebox_chipdb.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_chipdb$(PY_EXE)
+ cp icebox_diff.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_diff$(PY_EXE)
+ cp icebox_explain.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_explain$(PY_EXE)
+ cp icebox_asc2hlc.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_asc2hlc$(PY_EXE)
+ cp icebox_hlc2asc.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_hlc2asc$(PY_EXE)
+ cp icebox_colbuf.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_colbuf$(PY_EXE)
+ cp icebox_html.py $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_html$(PY_EXE)
+ 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)
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox.py
- rm -f $(DESTDIR)$(PREFIX)/bin/iceboxdb.py
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_chipdb$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_diff$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_explain$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_asc2hlc$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_hlc2asc$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_colbuf$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_html$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_maps$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_vlog$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/icebox_stat$(PY_EXE)
- rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-384.txt
- rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-1k.txt
- rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-8k.txt
- rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-lm4k.txt
- rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-u4k.txt
- -rmdir $(DESTDIR)$(PREFIX)/share/icebox
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(subst -,_,$(PROGRAM_PREFIX))cebox.py
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(subst -,_,$(PROGRAM_PREFIX))iceboxdb.py
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_chipdb$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_diff$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_explain$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_asc2hlc$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_hlc2asc$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_colbuf$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_html$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_maps$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_vlog$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebox_stat$(PY_EXE)
+ rm -f $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/chipdb-384.txt
+ rm -f $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/chipdb-1k.txt
+ rm -f $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/chipdb-8k.txt
+ rm -f $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/chipdb-lm4k.txt
+ rm -f $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/chipdb-u4k.txt
+ -rmdir $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox
.PHONY: all check clean install uninstall
diff --git a/icebox/icebox.py b/icebox/icebox.py
index 0422f13..a7631a2 100644
--- a/icebox/icebox.py
+++ b/icebox/icebox.py
@@ -1954,7 +1954,8 @@ pllinfo_db = {
"PLLOUT_SELECT_B_1": (12, 31, "PLLCONFIG_3"),
# Numeric Parameters
- "SHIFTREG_DIV_MODE": (12, 31, "PLLCONFIG_4"),
+ "SHIFTREG_DIV_MODE_0": (12, 31, "PLLCONFIG_4"),
+ "SHIFTREG_DIV_MODE_1": (14, 31, "PLLCONFIG_6"),
"FDA_FEEDBACK_0": (12, 31, "PLLCONFIG_9"),
"FDA_FEEDBACK_1": (13, 31, "PLLCONFIG_1"),
"FDA_FEEDBACK_2": (13, 31, "PLLCONFIG_2"),
@@ -5785,6 +5786,198 @@ extra_cells_db = {
},
"u4k" : {
+ ("SPI", (0, 0, 0)): {
+ "MCSNO0": (0, 3, "slf_op_1"),
+ "MCSNO1": (0, 3, "slf_op_3"),
+ "MCSNO2": (0, 3, "slf_op_6"),
+ "MCSNO3": (0, 4, "slf_op_0"),
+ "MCSNOE0": (0, 3, "slf_op_2"),
+ "MCSNOE1": (0, 3, "slf_op_4"),
+ "MCSNOE2": (0, 3, "slf_op_7"),
+ "MCSNOE3": (0, 4, "slf_op_1"),
+ "MI": (0, 2, "lutff_0/in_1"),
+ "MO": (0, 2, "slf_op_5"),
+ "MOE": (0, 2, "slf_op_6"),
+ "SBACKO": (0, 2, "slf_op_0"),
+ "SBADRI0": (0, 1, "lutff_1/in_1"),
+ "SBADRI1": (0, 1, "lutff_2/in_1"),
+ "SBADRI2": (0, 2, "lutff_0/in_3"),
+ "SBADRI3": (0, 2, "lutff_1/in_3"),
+ "SBADRI4": (0, 2, "lutff_2/in_3"),
+ "SBADRI5": (0, 2, "lutff_3/in_3"),
+ "SBADRI6": (0, 2, "lutff_4/in_3"),
+ "SBADRI7": (0, 2, "lutff_5/in_3"),
+ "SBCLKI": (0, 1, "clk"),
+ "SBDATI0": (0, 1, "lutff_1/in_3"),
+ "SBDATI1": (0, 1, "lutff_2/in_3"),
+ "SBDATI2": (0, 1, "lutff_3/in_3"),
+ "SBDATI3": (0, 1, "lutff_4/in_3"),
+ "SBDATI4": (0, 1, "lutff_5/in_3"),
+ "SBDATI5": (0, 1, "lutff_6/in_3"),
+ "SBDATI6": (0, 1, "lutff_7/in_3"),
+ "SBDATI7": (0, 1, "lutff_0/in_1"),
+ "SBDATO0": (0, 1, "slf_op_0"),
+ "SBDATO1": (0, 1, "slf_op_1"),
+ "SBDATO2": (0, 1, "slf_op_2"),
+ "SBDATO3": (0, 1, "slf_op_3"),
+ "SBDATO4": (0, 1, "slf_op_4"),
+ "SBDATO5": (0, 1, "slf_op_5"),
+ "SBDATO6": (0, 1, "slf_op_6"),
+ "SBDATO7": (0, 1, "slf_op_7"),
+ "SBRWI": (0, 1, "lutff_0/in_3"),
+ "SBSTBI": (0, 2, "lutff_6/in_3"),
+ "SCKI": (0, 2, "lutff_1/in_1"),
+ "SCKO": (0, 2, "slf_op_7"),
+ "SCKOE": (0, 3, "slf_op_0"),
+ "SCSNI": (0, 2, "lutff_2/in_1"),
+ "SI": (0, 2, "lutff_7/in_3"),
+ "SO": (0, 2, "slf_op_3"),
+ "SOE": (0, 2, "slf_op_4"),
+ "SPIIRQ": (0, 2, "slf_op_1"),
+ "SPIWKUP": (0, 2, "slf_op_2"),
+ "SPI_ENABLE_0": (7, 0, "cbit2usealt_in_0"),
+ "SPI_ENABLE_1": (6, 0, "cbit2usealt_in_0"),
+ "SPI_ENABLE_2": (7, 0, "cbit2usealt_in_1"),
+ "SPI_ENABLE_3": (6, 0, "cbit2usealt_in_1"),
+ },
+ ("SPI", (25, 0, 1)): {
+ "MCSNO0": (25, 3, "slf_op_1"),
+ "MCSNO1": (25, 3, "slf_op_3"),
+ "MCSNO2": (25, 3, "slf_op_6"),
+ "MCSNO3": (25, 4, "slf_op_0"),
+ "MCSNOE0": (25, 3, "slf_op_2"),
+ "MCSNOE1": (25, 3, "slf_op_4"),
+ "MCSNOE2": (25, 3, "slf_op_7"),
+ "MCSNOE3": (25, 4, "slf_op_1"),
+ "MI": (25, 2, "lutff_0/in_1"),
+ "MO": (25, 2, "slf_op_5"),
+ "MOE": (25, 2, "slf_op_6"),
+ "SBACKO": (25, 2, "slf_op_0"),
+ "SBADRI0": (25, 1, "lutff_1/in_1"),
+ "SBADRI1": (25, 1, "lutff_2/in_1"),
+ "SBADRI2": (25, 2, "lutff_0/in_3"),
+ "SBADRI3": (25, 2, "lutff_1/in_3"),
+ "SBADRI4": (25, 2, "lutff_2/in_3"),
+ "SBADRI5": (25, 2, "lutff_3/in_3"),
+ "SBADRI6": (25, 2, "lutff_4/in_3"),
+ "SBADRI7": (25, 2, "lutff_5/in_3"),
+ "SBCLKI": (25, 1, "clk"),
+ "SBDATI0": (25, 1, "lutff_1/in_3"),
+ "SBDATI1": (25, 1, "lutff_2/in_3"),
+ "SBDATI2": (25, 1, "lutff_3/in_3"),
+ "SBDATI3": (25, 1, "lutff_4/in_3"),
+ "SBDATI4": (25, 1, "lutff_5/in_3"),
+ "SBDATI5": (25, 1, "lutff_6/in_3"),
+ "SBDATI6": (25, 1, "lutff_7/in_3"),
+ "SBDATI7": (25, 1, "lutff_0/in_1"),
+ "SBDATO0": (25, 1, "slf_op_0"),
+ "SBDATO1": (25, 1, "slf_op_1"),
+ "SBDATO2": (25, 1, "slf_op_2"),
+ "SBDATO3": (25, 1, "slf_op_3"),
+ "SBDATO4": (25, 1, "slf_op_4"),
+ "SBDATO5": (25, 1, "slf_op_5"),
+ "SBDATO6": (25, 1, "slf_op_6"),
+ "SBDATO7": (25, 1, "slf_op_7"),
+ "SBRWI": (25, 1, "lutff_0/in_3"),
+ "SBSTBI": (25, 2, "lutff_6/in_3"),
+ "SCKI": (25, 2, "lutff_1/in_1"),
+ "SCKO": (25, 2, "slf_op_7"),
+ "SCKOE": (25, 3, "slf_op_0"),
+ "SCSNI": (25, 2, "lutff_2/in_1"),
+ "SI": (25, 2, "lutff_7/in_3"),
+ "SO": (25, 2, "slf_op_3"),
+ "SOE": (25, 2, "slf_op_4"),
+ "SPIIRQ": (25, 2, "slf_op_1"),
+ "SPIWKUP": (25, 2, "slf_op_2"),
+ "SPI_ENABLE_0": (24, 0, "cbit2usealt_in_0"),
+ "SPI_ENABLE_1": (24, 0, "cbit2usealt_in_1"),
+ "SPI_ENABLE_2": (23, 0, "cbit2usealt_in_0"),
+ "SPI_ENABLE_3": (23, 0, "cbit2usealt_in_1"),
+ },
+ ("I2C", (0, 21, 0)): {
+ "I2CIRQ": (0, 20, "slf_op_7"),
+ "I2CWKUP": (0, 19, "slf_op_5"),
+ "I2C_ENABLE_0": (13, 21, "cbit2usealt_in_0"),
+ "I2C_ENABLE_1": (12, 21, "cbit2usealt_in_1"),
+ "SBACKO": (0, 20, "slf_op_6"),
+ "SBADRI0": (0, 20, "lutff_1/in_0"),
+ "SBADRI1": (0, 20, "lutff_2/in_0"),
+ "SBADRI2": (0, 20, "lutff_3/in_0"),
+ "SBADRI3": (0, 20, "lutff_4/in_0"),
+ "SBADRI4": (0, 20, "lutff_5/in_0"),
+ "SBADRI5": (0, 20, "lutff_6/in_0"),
+ "SBADRI6": (0, 20, "lutff_7/in_0"),
+ "SBADRI7": (0, 19, "lutff_2/in_0"),
+ "SBCLKI": (0, 20, "clk"),
+ "SBDATI0": (0, 19, "lutff_5/in_0"),
+ "SBDATI1": (0, 19, "lutff_6/in_0"),
+ "SBDATI2": (0, 19, "lutff_7/in_0"),
+ "SBDATI3": (0, 20, "lutff_0/in_3"),
+ "SBDATI4": (0, 20, "lutff_5/in_1"),
+ "SBDATI5": (0, 20, "lutff_6/in_1"),
+ "SBDATI6": (0, 20, "lutff_7/in_1"),
+ "SBDATI7": (0, 20, "lutff_0/in_0"),
+ "SBDATO0": (0, 19, "slf_op_6"),
+ "SBDATO1": (0, 19, "slf_op_7"),
+ "SBDATO2": (0, 20, "slf_op_0"),
+ "SBDATO3": (0, 20, "slf_op_1"),
+ "SBDATO4": (0, 20, "slf_op_2"),
+ "SBDATO5": (0, 20, "slf_op_3"),
+ "SBDATO6": (0, 20, "slf_op_4"),
+ "SBDATO7": (0, 20, "slf_op_5"),
+ "SBRWI": (0, 19, "lutff_4/in_0"),
+ "SBSTBI": (0, 19, "lutff_3/in_0"),
+ "SCLI": (0, 19, "lutff_2/in_1"),
+ "SCLO": (0, 19, "slf_op_3"),
+ "SCLOE": (0, 19, "slf_op_4"),
+ "SDAI": (0, 19, "lutff_1/in_1"),
+ "SDAO": (0, 19, "slf_op_1"),
+ "SDAOE": (0, 19, "slf_op_2"),
+ "SDA_INPUT_DELAYED": (12, 21, "SDA_input_delay"),
+ "SDA_OUTPUT_DELAYED": (12, 21, "SDA_output_delay"),
+ },
+ ("I2C", (25, 21, 0)): {
+ "I2CIRQ": (25, 20, "slf_op_7"),
+ "I2CWKUP": (25, 19, "slf_op_5"),
+ "I2C_ENABLE_0": (19, 21, "cbit2usealt_in_1"),
+ "I2C_ENABLE_1": (19, 21, "cbit2usealt_in_0"),
+ "SBACKO": (25, 20, "slf_op_6"),
+ "SBADRI0": (25, 20, "lutff_1/in_0"),
+ "SBADRI1": (25, 20, "lutff_2/in_0"),
+ "SBADRI2": (25, 20, "lutff_3/in_0"),
+ "SBADRI3": (25, 20, "lutff_4/in_0"),
+ "SBADRI4": (25, 20, "lutff_5/in_0"),
+ "SBADRI5": (25, 20, "lutff_6/in_0"),
+ "SBADRI6": (25, 20, "lutff_7/in_0"),
+ "SBADRI7": (25, 19, "lutff_2/in_0"),
+ "SBCLKI": (25, 20, "clk"),
+ "SBDATI0": (25, 19, "lutff_5/in_0"),
+ "SBDATI1": (25, 19, "lutff_6/in_0"),
+ "SBDATI2": (25, 19, "lutff_7/in_0"),
+ "SBDATI3": (25, 20, "lutff_0/in_3"),
+ "SBDATI4": (25, 20, "lutff_5/in_1"),
+ "SBDATI5": (25, 20, "lutff_6/in_1"),
+ "SBDATI6": (25, 20, "lutff_7/in_1"),
+ "SBDATI7": (25, 20, "lutff_0/in_0"),
+ "SBDATO0": (25, 19, "slf_op_6"),
+ "SBDATO1": (25, 19, "slf_op_7"),
+ "SBDATO2": (25, 20, "slf_op_0"),
+ "SBDATO3": (25, 20, "slf_op_1"),
+ "SBDATO4": (25, 20, "slf_op_2"),
+ "SBDATO5": (25, 20, "slf_op_3"),
+ "SBDATO6": (25, 20, "slf_op_4"),
+ "SBDATO7": (25, 20, "slf_op_5"),
+ "SBRWI": (25, 19, "lutff_4/in_0"),
+ "SBSTBI": (25, 19, "lutff_3/in_0"),
+ "SCLI": (25, 19, "lutff_2/in_1"),
+ "SCLO": (25, 19, "slf_op_3"),
+ "SCLOE": (25, 19, "slf_op_4"),
+ "SDAI": (25, 19, "lutff_1/in_1"),
+ "SDAO": (25, 19, "slf_op_1"),
+ "SDAOE": (25, 19, "slf_op_2"),
+ "SDA_INPUT_DELAYED": (19, 21, "SDA_input_delay"),
+ "SDA_OUTPUT_DELAYED": (19, 21, "SDA_output_delay"),
+ },
("HFOSC", (0, 21, 1)) : {
"CLKHFPU": (0, 19, "lutff_0/in_1"),
"CLKHFEN": (0, 19, "lutff_7/in_3"),
diff --git a/icebox/icebox_asc2hlc.py b/icebox/icebox_asc2hlc.py
index 003106f..8e64997 100755
--- a/icebox/icebox_asc2hlc.py
+++ b/icebox/icebox_asc2hlc.py
@@ -1068,7 +1068,7 @@ def main():
except getopt.GetoptError as e:
sys.stderr.write("%s: %s\n" % (program_short_name, e.msg))
sys.stderr.write("Try `%s --help' for more information.\n"
- % sys.argv[0])
+ % program_short_name)
sys.exit(1)
for opt, arg in opts:
@@ -1085,7 +1085,7 @@ Usage: %s [OPTION]... FILE
If you have a bug report, please file an issue on github:
https://github.com/rlutz/icestorm/issues
-""" % sys.argv[0])
+""" % program_short_name)
sys.exit(0)
if opt == '--version':
@@ -1113,13 +1113,13 @@ GNU General Public License for more details.
if not args:
sys.stderr.write("%s: missing argument\n" % (program_short_name))
sys.stderr.write("Try `%s --help' for more information.\n"
- % sys.argv[0])
+ % program_short_name)
sys.exit(1)
if len(args) != 1:
sys.stderr.write("%s: too many arguments\n" % (program_short_name))
sys.stderr.write("Try `%s --help' for more information.\n"
- % sys.argv[0])
+ % program_short_name)
sys.exit(1)
ic = icebox.iceconfig()
diff --git a/icebox/icebox_chipdb.py b/icebox/icebox_chipdb.py
index 9c8d6df..722ec37 100755
--- a/icebox/icebox_chipdb.py
+++ b/icebox/icebox_chipdb.py
@@ -16,7 +16,7 @@
#
import icebox
-import getopt, sys, re
+import getopt, sys, re, os
mode_384 = False
mode_lm4k = False
@@ -26,7 +26,7 @@ mode_8k = False
def usage():
print("""
-Usage: icebox_chipdb [options] [bitmap.asc]
+Usage: %s [options] [bitmap.asc]
-3
create chipdb for 384 device
@@ -42,7 +42,7 @@ Usage: icebox_chipdb [options] [bitmap.asc]
-u
create chipdb for u4k device
-""")
+""" % os.path.basename(sys.argv[0]))
sys.exit(0)
try:
diff --git a/icebox/icebox_colbuf.py b/icebox/icebox_colbuf.py
index ec6843e..3003a90 100755
--- a/icebox/icebox_colbuf.py
+++ b/icebox/icebox_colbuf.py
@@ -17,21 +17,21 @@
import icebox
from icebox import re_match_cached
-import getopt, sys, re
+import getopt, sys, re, os
check_mode = False
fixup_mode = False
def usage():
print("""
-Usage: icebox_colbuf [options] [input.asc [output.asc]]
+Usage: %s [options] [input.asc [output.asc]]
-c
check colbuf bits
-f
fix colbuf bits
-""")
+""" % os.path.basename(sys.argv[0]))
sys.exit(1)
try:
diff --git a/icebox/icebox_diff.py b/icebox/icebox_diff.py
index 5252fc4..f433bcf 100755
--- a/icebox/icebox_diff.py
+++ b/icebox/icebox_diff.py
@@ -17,13 +17,13 @@
import icebox
from icebox import re_match_cached
-import sys
+import sys, os
import re
if len(sys.argv) != 3:
print("""
-Usage: icebox_diff bitmap1.asc bitmap2.asc
-""")
+Usage: %s bitmap1.asc bitmap2.asc
+""" % os.path.basename(sys.argv[0]))
sys.exit(0)
print("Reading file '%s'.." % sys.argv[1])
diff --git a/icebox/icebox_explain.py b/icebox/icebox_explain.py
index f843c09..25061ab 100755
--- a/icebox/icebox_explain.py
+++ b/icebox/icebox_explain.py
@@ -17,7 +17,7 @@
import icebox
from icebox import re_match_cached, re_search_cached
-import getopt, sys, re
+import getopt, sys, re, os
print_bits = False
print_map = False
@@ -26,7 +26,7 @@ print_all = False
def usage():
print("""
-Usage: icebox_explain [options] [bitmap.asc]
+Usage: %s [options] [bitmap.asc]
-b
print config bit names for each config statement
@@ -39,7 +39,7 @@ Usage: icebox_explain [options] [bitmap.asc]
-t '<x-coordinate> <y-coordinate>'
print only the specified tile
-""")
+""" % os.path.basename(sys.argv[0]))
sys.exit(0)
try:
diff --git a/icebox/icebox_hlc2asc.py b/icebox/icebox_hlc2asc.py
index a95f610..59d2f69 100755
--- a/icebox/icebox_hlc2asc.py
+++ b/icebox/icebox_hlc2asc.py
@@ -1147,7 +1147,7 @@ def main():
except getopt.GetoptError as e:
sys.stderr.write("%s: %s\n" % (program_short_name, e.msg))
sys.stderr.write("Try `%s --help' for more information.\n"
- % sys.argv[0])
+ % program_short_name)
sys.exit(1)
for opt, arg in opts:
@@ -1161,7 +1161,7 @@ Usage: %s [OPTION]... FILE
If you have a bug report, please file an issue on github:
https://github.com/rlutz/icestorm/issues
-""" % sys.argv[0])
+""" % program_short_name)
sys.exit(0)
if opt == '--version':
@@ -1184,13 +1184,13 @@ GNU General Public License for more details.
if not args:
sys.stderr.write("%s: missing argument\n" % (program_short_name))
sys.stderr.write("Try `%s --help' for more information.\n"
- % sys.argv[0])
+ % program_short_name)
sys.exit(1)
if len(args) != 1:
sys.stderr.write("%s: too many arguments\n" % (program_short_name))
sys.stderr.write("Try `%s --help' for more information.\n"
- % sys.argv[0])
+ % program_short_name)
sys.exit(1)
if args[0] == '-':
diff --git a/icebox/icebox_html.py b/icebox/icebox_html.py
index b710f61..3785a45 100755
--- a/icebox/icebox_html.py
+++ b/icebox/icebox_html.py
@@ -27,7 +27,7 @@ mode384 = False
tx, ty = 0, 0
def usage():
- print("Usage: %s [options]" % sys.argv[0])
+ print("Usage: %s [options]" % os.path.basename(sys.argv[0]))
print(" -x tile_x_coordinate")
print(" -y tile_y_coordinate")
print(" -d outdir")
diff --git a/icebox/icebox_maps.py b/icebox/icebox_maps.py
index 35ff316..062335d 100755
--- a/icebox/icebox_maps.py
+++ b/icebox/icebox_maps.py
@@ -17,20 +17,21 @@
import icebox
from icebox import re_match_cached
-import getopt, sys, re
+import getopt, sys, re, os
mode = None
def usage():
+ program_short_name = os.path.basename(sys.argv[0])
print("Usage:")
- print(" icebox_maps -m bitmaps")
- print(" icebox_maps -m io_tile_nets_l")
- print(" icebox_maps -m io_tile_nets_r")
- print(" icebox_maps -m io_tile_nets_t")
- print(" icebox_maps -m io_tile_nets_b")
- print(" icebox_maps -m logic_tile_nets")
- print(" icebox_maps -m ramb_tile_nets")
- print(" icebox_maps -m ramt_tile_nets")
+ print(" %s -m bitmaps" % program_short_name)
+ print(" %s -m io_tile_nets_l" % program_short_name)
+ print(" %s -m io_tile_nets_r" % program_short_name)
+ print(" %s -m io_tile_nets_t" % program_short_name)
+ print(" %s -m io_tile_nets_b" % program_short_name)
+ print(" %s -m logic_tile_nets" % program_short_name)
+ print(" %s -m ramb_tile_nets" % program_short_name)
+ print(" %s -m ramt_tile_nets" % program_short_name)
sys.exit(0)
try:
diff --git a/icebox/icebox_stat.py b/icebox/icebox_stat.py
index ec404fb..5752267 100755
--- a/icebox/icebox_stat.py
+++ b/icebox/icebox_stat.py
@@ -17,18 +17,18 @@
import icebox
from icebox import re_match_cached
-import getopt, sys, re
+import getopt, sys, re, os
verbose = False
def usage():
print("""
-Usage: icebox_stat [options] [bitmap.asc]
+Usage: %s [options] [bitmap.asc]
-v
verbose output
-""")
+""" % os.path.basename(sys.argv[0]))
sys.exit(0)
try:
diff --git a/icebox/icebox_vlog.py b/icebox/icebox_vlog.py
index a2c7950..74ac3d3 100755
--- a/icebox/icebox_vlog.py
+++ b/icebox/icebox_vlog.py
@@ -17,7 +17,7 @@
import icebox
from icebox import re_match_cached, re_sub_cached, re_search_cached
-import getopt, sys, re
+import getopt, sys, re, os
strip_comments = False
strip_interconn = False
@@ -34,7 +34,7 @@ modname = "chip"
def usage():
print("""
-Usage: icebox_vlog [options] [bitmap.asc]
+Usage: %s [options] [bitmap.asc]
-s
strip comments from output
@@ -70,7 +70,7 @@ Usage: icebox_vlog [options] [bitmap.asc]
-D
enable exactly-one-driver checks
-""")
+""" % os.path.basename(sys.argv[0]))
sys.exit(0)
try:
@@ -477,7 +477,10 @@ for pllid in ic.pll_list():
if plltype != "100":
text_func.append(" .PLLOUT_SELECT_PORTA(\"%s\")," % get_pll_outsel(pllinfo, "PLLOUT_SELECT_A"))
text_func.append(" .PLLOUT_SELECT_PORTB(\"%s\")," % get_pll_outsel(pllinfo, "PLLOUT_SELECT_B"))
- text_func.append(" .SHIFTREG_DIV_MODE(1'b%s)," % get_pll_bit(pllinfo, "SHIFTREG_DIV_MODE"))
+ if ic.device == "5k":
+ text_func.append(" .SHIFTREG_DIV_MODE(2'b%s)," % get_pll_bits(pllinfo, "SHIFTREG_DIV_MODE", 2))
+ else:
+ text_func.append(" .SHIFTREG_DIV_MODE(1'b%s)," % get_pll_bit(pllinfo, "SHIFTREG_DIV_MODE"))
text_func.append(" .FDA_FEEDBACK(4'b%s)," % get_pll_bits(pllinfo, "FDA_FEEDBACK", 4))
text_func.append(" .FDA_RELATIVE(4'b%s)," % get_pll_bits(pllinfo, "FDA_RELATIVE", 4))
text_func.append(" .DIVR(4'b%s)," % get_pll_bits(pllinfo, "DIVR", 4))
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/icebram/Makefile b/icebram/Makefile
index 34801da..219be59 100644
--- a/icebram/Makefile
+++ b/icebram/Makefile
@@ -4,24 +4,24 @@ ifeq ($(STATIC),1)
LDFLAGS += -static
endif
-all: icebram$(EXE)
+all: $(PROGRAM_PREFIX)icebram$(EXE)
-icebram$(EXE): icebram.o
+$(PROGRAM_PREFIX)icebram$(EXE): icebram.o
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
-test: icebram
+test: $(PROGRAM_PREFIX)icebram
bash rundemo.sh
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp icebram$(EXE) $(DESTDIR)$(PREFIX)/bin/icebram$(EXE)
+ cp $(PROGRAM_PREFIX)icebram$(EXE) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebram$(EXE)
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/icebram$(EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icebram$(EXE)
clean:
- rm -f icebram$(EXE)
- rm -f icebram.exe
+ rm -f $(PROGRAM_PREFIX)icebram$(EXE)
+ rm -f $(PROGRAM_PREFIX)icebram.exe
rm -f demo.* demo_*.*
rm -f *.o *.d
diff --git a/icebram/icebram.cc b/icebram/icebram.cc
index f585fcf..aacf00c 100644
--- a/icebram/icebram.cc
+++ b/icebram/icebram.cc
@@ -131,7 +131,7 @@ int main(int argc, char **argv)
bool verbose = false;
bool generate = false;
bool seed = false;
- uint32_t seed_nr = getpid();
+ uint32_t seed_opt = 0;
int opt;
while ((opt = getopt(argc, argv, "vgs:")) != -1)
@@ -146,7 +146,7 @@ int main(int argc, char **argv)
break;
case 's':
seed = true;
- seed_nr = atoi(optarg);
+ seed_opt = atoi(optarg);
break;
default:
help(argv[0]);
@@ -172,7 +172,21 @@ int main(int argc, char **argv)
}
if (verbose && seed)
- fprintf(stderr, "Seed: %d\n", seed_nr);
+ fprintf(stderr, "Seed: %d\n", seed_opt);
+
+ // If -s is provided: seed with the given value.
+ // If -s is not provided: seed with the PID and current time, which are unlikely
+ // to repeat simultaneously.
+ uint32_t seed_nr;
+ if (!seed) {
+#if defined(__wasm)
+ seed_nr = 0;
+#else
+ seed_nr = getpid();
+#endif
+ } else {
+ seed_nr = seed_opt;
+ }
x = uint64_t(seed_nr) << 32;
x ^= uint64_t(depth) << 16;
@@ -182,16 +196,12 @@ int main(int argc, char **argv)
xorshift64star();
xorshift64star();
- if (!seed){
+ if (!seed) {
struct timeval tv;
gettimeofday(&tv, NULL);
x ^= uint64_t(tv.tv_sec) << 20;
x ^= uint64_t(tv.tv_usec);
}
- else {
- x ^= uint64_t(seed) << 20;
- x ^= uint64_t(seed);
- }
xorshift64star();
xorshift64star();
diff --git a/icefuzz/tests/ip/trace_ip_u4k.py b/icefuzz/tests/ip/trace_ip_u4k.py
new file mode 100755
index 0000000..8e94faf
--- /dev/null
+++ b/icefuzz/tests/ip/trace_ip_u4k.py
@@ -0,0 +1,347 @@
+#!/usr/bin/env python3
+
+import os, sys, re
+
+device = "u4k"
+
+pins = "2 3 4 6 9 10 11 12 13 14 15 16 17 18 19 20 21 23 25 26 27 28 31 32 34 35 36 37 38 42 43 44 45 46 47 48".split()
+#up5k
+# pins = "2 3 4 6 9 10 11 12 13 18 19 20 21 25 26 27 28 31 32 34 35 36 37 38 42 43 44 45 46 47 48".split()
+
+# This is the master IP reverse engineering script for three similar IPs: I2C, SPI
+ip_types = ["I2C", "SPI"]
+ip_locs = { }
+ip_locs["I2C"] = [(0, 21, 0), (25, 21, 0)]
+ip_locs["SPI"] = [(0, 0, 0), (25, 0, 1)]
+#spram_locs = [(0, 0, 1)]
+ip_data = { }
+
+#up5k
+# ip_types = ["I2C", "SPI", "LEDDA_IP"]
+# ip_locs = { }
+# ip_locs["I2C"] = [(0, 31, 0), (25, 31, 0)]
+# ip_locs["SPI"] = [(0, 0, 0), (25, 0, 1)]
+# ip_locs["LEDDA_IP"] = [(0, 31, 2)]
+# #spram_locs = [(0, 0, 1)]
+# ip_data = { }
+
+#signals[x][0] -> inputs, signals[x][1] ->outputs
+ip_signals = {}
+ip_signals["I2C"] = [["SBCLKI", "SBRWI", "SBSTBI", "SCLI", "SDAI"],
+ ["SBACKO", "I2CIRQ", "I2CWKUP", "SCLO", "SCLOE", "SDAO", "SDAOE"]]
+ip_signals["SPI"] = [["SBCLKI", "SBRWI", "SBSTBI", "MI", "SI", "SCKI", "SCSNI"],
+ ["SBACKO", "SPIIRQ", "SPIWKUP", "SO", "SOE", "MO", "MOE", "SCKO", "SCKOE"]]
+
+fixed_cbits = {}
+
+fixed_cbits[("I2C", (0, 21, 0))] = ["BUS_ADDR74_0", "I2C_SLAVE_INIT_ADDR_0"]
+fixed_cbits[("I2C", (25, 21, 0))] = ["BUS_ADDR74_0", "BUS_ADDR74_1", "I2C_SLAVE_INIT_ADDR_1"]
+
+fixed_cbits[("SPI", (0, 0, 0))] = []
+fixed_cbits[("SPI", (25, 0, 1))] = ["BUS_ADDR74_1"] # WARNING: this is documented as BUS_ADDR74_0, but this is wrong and will cause icecube to fail. May be the same across devices
+
+#up5k
+# fixed_cbits[("I2C", (0, 31, 0))] = ["BUS_ADDR74_0", "I2C_SLAVE_INIT_ADDR_0"]
+# fixed_cbits[("I2C", (25, 31, 0))] = ["BUS_ADDR74_0", "BUS_ADDR74_1", "I2C_SLAVE_INIT_ADDR_1"]
+
+# fixed_cbits[("SPI", (0, 10, 0))] = []
+# fixed_cbits[("SPI", (25, 10, 1))] = ["BUS_ADDR74_1"] # WARNING: this is documented as BUS_ADDR74_0, but this is wrong and will cause icecube to fail. May be the same across devices
+
+fuzz_cbits = {}
+fuzz_cbits["I2C"] = ["SDA_INPUT_DELAYED", "SDA_OUTPUT_DELAYED"]
+
+# Don't add slave address to the list, despite confusing primitive declaration,
+# it's only set in registers not the bitstream
+
+#for i in range(2, 10):
+ #fuzz_cbits["I2C"].append("I2C_SLAVE_INIT_ADDR_%d" % i)
+
+for i in range(8):
+ ip_signals["I2C"][0].append("SBADRI%d" % i)
+ ip_signals["SPI"][0].append("SBADRI%d" % i)
+
+for i in range(8):
+ ip_signals["I2C"][0].append("SBDATI%d" % i)
+ ip_signals["SPI"][0].append("SBDATI%d" % i)
+
+for i in range(8):
+ ip_signals["I2C"][1].append("SBDATO%d" % i)
+ ip_signals["SPI"][1].append("SBDATO%d" % i)
+
+for i in range(4):
+ ip_signals["SPI"][1].append("MCSNO%d" % i)
+ ip_signals["SPI"][1].append("MCSNOE%d" % i)
+
+fuzz_net_options = {}
+fuzz_net_options["I2C"] = ["SBADRI", "SBDATI", "SBDATO"]
+fuzz_net_options["SPI"] = ["SBADRI", "SBDATI", "SBDATO", "MCSN"]
+
+available_cbits = {}
+available_cbits["I2C"] = [("BUS_ADDR74", 4), ("I2C_SLAVE_INIT_ADDR", 10)]
+available_cbits["SPI"] = [("BUS_ADDR74", 4)]
+
+# Return a param value in "Lattice style"
+def get_param_value(param_size, param_name, set_cbits):
+ val = "\"0b"
+ for i in range(param_size):
+ if param_name + "_" + str((param_size - 1) - i) in set_cbits:
+ val += "1"
+ else:
+ val += "0"
+ val += "\""
+ return val
+
+# Build the output files for a given IP and config, returning
+# the pin2net map
+def make_ip(ip_type, ip_loc, fuzz_opt, set_cbits):
+ used_inputs = [ ]
+ used_outputs = [ ]
+ for insig in ip_signals[ip_type][0]:
+ ignore = False
+ for o in fuzz_net_options[ip_type]:
+ if o != fuzz_opt and insig.startswith(o):
+ ignore = True
+ if not ignore:
+ used_inputs.append(insig)
+ for outsig in ip_signals[ip_type][1]:
+ ignore = False
+ for o in fuzz_net_options[ip_type]:
+ if o != fuzz_opt and outsig.startswith(o):
+ ignore = True
+ if not ignore:
+ used_outputs.append(outsig)
+ all_sigs = used_inputs + used_outputs
+ all_cbits = set()
+ all_cbits.update(set_cbits)
+ if (ip_type, ip_loc) in fixed_cbits:
+ all_cbits.update(fixed_cbits[(ip_type, ip_loc)])
+ with open("./work_ip/ip.v", "w") as f:
+ print("module top(", file=f)
+ for s in used_inputs:
+ print("input %s," % s, file=f)
+ for s in used_outputs[:-1]:
+ print("output %s," % s, file=f)
+ print("output %s);" % used_outputs[-1], file=f)
+ print("SB_%s" % ip_type, file=f)
+ if ip_type in available_cbits:
+ print("\t#(", file=f)
+ for p in available_cbits[ip_type]:
+ name, width = p
+ comma = "," if p != available_cbits[ip_type][-1] else ""
+ print("\t\t.%s(%s)%s" % (name, get_param_value(width, name, all_cbits), comma), file=f)
+ print("\t)", file=f)
+ print("\tip_inst (",file=f)
+ for sig in all_sigs[:-1]:
+ print("\t\t.%s(%s)," % (sig, sig), file=f)
+ print("\t\t.%s(%s)" % (all_sigs[-1], all_sigs[-1]), file=f)
+ print("\t)", file=f)
+ if "SDA_INPUT_DELAYED" in all_cbits:
+ print("\t/* synthesis SDA_INPUT_DELAYED=1 */", file=f)
+ else:
+ print("\t/* synthesis SDA_INPUT_DELAYED=0 */", file=f)
+ if "SDA_OUTPUT_DELAYED" in all_cbits:
+ print("\t/* synthesis SDA_OUTPUT_DELAYED=1 */", file=f)
+ else:
+ print("\t/* synthesis SDA_OUTPUT_DELAYED=0 */", file=f)
+ print(";", file=f)
+ print("endmodule", file=f)
+ pin2net = {}
+ with open("./work_ip/ip.pcf","w") as f:
+ temp_pins = list(pins)
+ for sig in all_sigs:
+ if len(temp_pins) == 0:
+ sys.stderr.write("ERROR: no remaining pins to alloc")
+ sys.exit(1)
+ pin = temp_pins.pop()
+ pin2net[pin] = sig
+ print("set_io %s %s" % (sig, pin), file=f)
+ print("set_location ip_inst %d %d %d" % ip_loc, file=f)
+ return pin2net
+
+def check_for_pin_assignment(pin):
+ out = None
+ with open("./work_ip/ip.vlog", "r") as f:
+ for l in f:
+ if l.startswith("assign pin_{}".format(pin)):
+ rhs = l.split("=")
+ o_cen = rhs[1].split(" ")[1]
+ out = rhs[1].split(" ")[3]
+
+ return out
+
+#Parse the output of an icebox vlog file to determine connectivity
+def parse_vlog(f, pin2net, net_map):
+ wires_to_check = dict()
+
+ current_net = None
+
+ for line in f:
+ if line == "\n":
+ current_net = None
+
+ m = re.match(r"wire ([a-zA-Z0-9_]+);", line)
+ if m:
+ net = m.group(1)
+ mp = re.match(r"pin_([a-zA-Z0-9]+)", net)
+ if mp:
+ pin = mp.group(1)
+ if pin in pin2net:
+ current_net = pin2net[pin]
+ else:
+ current_net = None
+
+ #search for assignment
+ data_input = check_for_pin_assignment(pin)
+ if data_input:
+ wires_to_check[data_input] = pin
+
+ else:
+ current_net = None
+ elif current_net is not None:
+ m = re.match(r"// \((\d+), (\d+), '([a-zA-Z0-9_/]+)'\)", line)
+ if m:
+ x = int(m.group(1))
+ y = int(m.group(2))
+ net = m.group(3)
+ if not (net.startswith("sp") or net.startswith("glb") or net.startswith("neigh") or net.startswith("io") or net.startswith("local") or net.startswith("fabout")):
+ net_map[current_net].add((x, y, net))
+
+ f.seek(0)
+ for line in f:
+ if line == "\n":
+ current_net = None
+
+ m = re.match(r"wire ([a-zA-Z0-9]+);", line)
+ if m:
+ net = m.group(1)
+ if net in wires_to_check:
+ pin = wires_to_check[net]
+ if pin in pin2net:
+ current_net = pin2net[pin]
+ else:
+ current_net = None
+ else:
+ current_net = None
+ elif current_net is not None:
+ m = re.match(r"// \((\d+), (\d+), '([a-zA-Z0-9_/]+)'\)", line)
+ if m:
+ x = int(m.group(1))
+ y = int(m.group(2))
+ net = m.group(3)
+ if not (net.startswith("sp") or net.startswith("glb") or net.startswith("neigh") or net.startswith("io") or net.startswith("local") or net.startswith("fabout")):
+ net_map[current_net].add((x, y, net))
+
+def parse_exp(f):
+ current_x = 0
+ current_y = 0
+ bits = set()
+ for line in f:
+ splitline = line.split(' ')
+ if splitline[0].endswith("_tile"):
+ current_x = int(splitline[1])
+ current_y = int(splitline[2])
+ elif splitline[0] == "IpConfig":
+ bits.add((current_x, current_y, splitline[1].strip()))
+ return bits
+
+if not os.path.exists("./work_ip"):
+ os.mkdir("./work_ip")
+for ip in ip_types:
+ ip_data[ip] = {}
+ for loc in ip_locs[ip]:
+ x, y, z = loc
+ net_cbit_map = {}
+ init_cbits = []
+ for sig in ip_signals[ip][0]:
+ net_cbit_map[sig] = set()
+ for sig in ip_signals[ip][1]:
+ net_cbit_map[sig] = set()
+ first = True
+ for state in ["FUZZ_NETS", "FUZZ_CBITS"]:
+ fuzz_options = None
+ if state == "FUZZ_NETS":
+ fuzz_options = fuzz_net_options[ip]
+ else:
+ if ip in fuzz_cbits:
+ fuzz_options = fuzz_cbits[ip]
+ else:
+ fuzz_options = []
+ for n in fuzz_options:
+ # if n != "SBDATO":
+ # continue
+ print("Fuzzing %s (%d, %d, %d) %s" % (ip, x, y, z, n))
+ fuzz_nets = fuzz_net_options[ip][0]
+ if state == "FUZZ_NETS":
+ fuzz_nets = n
+ set_cbits = set()
+ if state == "FUZZ_CBITS":
+ set_cbits.add(n)
+ pin2net = make_ip(ip, loc, fuzz_nets, set_cbits)
+ retval = os.system("bash ../../icecube.sh -" + device + " ./work_ip/ip.v > ./work_ip/icecube.log 2>&1")
+ if retval != 0:
+ sys.stderr.write('ERROR: icecube returned non-zero error code\n')
+ sys.exit(1)
+ retval = os.system("../../../icebox/icebox_explain.py ./work_ip/ip.asc > ./work_ip/ip.exp")
+ if retval != 0:
+ sys.stderr.write('ERROR: icebox_explain returned non-zero error code\n')
+ sys.exit(1)
+ retval = os.system("../../../icebox/icebox_vlog.py -l ./work_ip/ip.asc > ./work_ip/ip.vlog")
+ if retval != 0:
+ sys.stderr.write('ERROR: icebox_vlog returned non-zero error code\n')
+ sys.exit(1)
+ with open("./work_ip/ip.vlog", "r") as f:
+ parse_vlog(f, pin2net, net_cbit_map)
+ bits = []
+ with open("./work_ip/ip.exp", "r") as f:
+ bits = parse_exp(f)
+ if first:
+ idx = 0
+ for bit in bits:
+ init_cbits.append(bit)
+ if len(bits) == 1:
+ net_cbit_map[ip + "_ENABLE"] = [bit]
+ else:
+ net_cbit_map[ip + "_ENABLE_" + str(idx)] = [bit]
+ idx += 1
+ for bit in init_cbits:
+ if bit not in bits:
+ bx, by, bn = bit
+ print('WARNING: while fuzzing %s (%d, %d, %d) bit (%d, %d, %s) has unknown function (not always set)' %
+ (ip, x, y, z, bx, by, bn))
+ new_bits = []
+ for bit in bits:
+ if bit not in init_cbits:
+ new_bits.append(bit)
+ if state == "FUZZ_NETS" and len(new_bits) != 0:
+ for bit in new_bits:
+ bx, by, bn = bit
+ print('WARNING: while fuzzing %s (%d, %d, %d) bit (%d, %d, %s) has unknown function (not always set)' %
+ (ip, x, y, z, bx, by, bn))
+ elif state == "FUZZ_CBITS":
+ if len(new_bits) == 0:
+ print('WARNING: while fuzzing %s (%d, %d, %d) param %s causes no change' %
+ (ip, x, y, z, n))
+ else:
+ idx = 0
+ for bit in new_bits:
+ if len(new_bits) == 1:
+ net_cbit_map[n] = [bit]
+ else:
+ net_cbit_map[n + "_" + str(idx)] = [bit]
+ idx += 1
+ first = False
+ # if n == "SBDATO":
+ # exit()
+ ip_data[ip][loc] = net_cbit_map
+
+ with open(device + "_" + ip + "_data.txt", "w") as f:
+ for loc in ip_data[ip]:
+ x, y, z = loc
+ print("\t(\"%s\", (%d, %d, %d)): {" % (ip, x, y, z), file=f)
+ data = ip_data[ip][loc]
+ for net in sorted(data):
+ cnets = []
+ for cnet in data[net]:
+ cnets.append("(%d, %d, \"%s\")" % cnet)
+ print("\t\t%s %s, " % (("\"" + net.replace("[","_").replace("]","") + "\":").ljust(24), " ".join(cnets)), file=f)
+ print("\t},", file=f)
diff --git a/icefuzz/tests/ip/u4k_I2C_data.txt b/icefuzz/tests/ip/u4k_I2C_data.txt
new file mode 100644
index 0000000..6338608
--- /dev/null
+++ b/icefuzz/tests/ip/u4k_I2C_data.txt
@@ -0,0 +1,84 @@
+ ("I2C", (0, 21, 0)): {
+ "I2CIRQ": (0, 20, "slf_op_7"),
+ "I2CWKUP": (0, 19, "slf_op_5"),
+ "I2C_ENABLE_0": (13, 21, "cbit2usealt_in_0"),
+ "I2C_ENABLE_1": (12, 21, "cbit2usealt_in_1"),
+ "SBACKO": (0, 20, "slf_op_6"),
+ "SBADRI0": (0, 20, "lutff_1/in_0"),
+ "SBADRI1": (0, 20, "lutff_2/in_0"),
+ "SBADRI2": (0, 20, "lutff_3/in_0"),
+ "SBADRI3": (0, 20, "lutff_4/in_0"),
+ "SBADRI4": (0, 20, "lutff_5/in_0"),
+ "SBADRI5": (0, 20, "lutff_6/in_0"),
+ "SBADRI6": (0, 20, "lutff_7/in_0"),
+ "SBADRI7": (0, 19, "lutff_2/in_0"),
+ "SBCLKI": (0, 20, "clk"),
+ "SBDATI0": (0, 19, "lutff_5/in_0"),
+ "SBDATI1": (0, 19, "lutff_6/in_0"),
+ "SBDATI2": (0, 19, "lutff_7/in_0"),
+ "SBDATI3": (0, 20, "lutff_0/in_3"),
+ "SBDATI4": (0, 20, "lutff_5/in_1"),
+ "SBDATI5": (0, 20, "lutff_6/in_1"),
+ "SBDATI6": (0, 20, "lutff_7/in_1"),
+ "SBDATI7": (0, 20, "lutff_0/in_0"),
+ "SBDATO0": (0, 19, "slf_op_6"),
+ "SBDATO1": (0, 19, "slf_op_7"),
+ "SBDATO2": (0, 20, "slf_op_0"),
+ "SBDATO3": (0, 20, "slf_op_1"),
+ "SBDATO4": (0, 20, "slf_op_2"),
+ "SBDATO5": (0, 20, "slf_op_3"),
+ "SBDATO6": (0, 20, "slf_op_4"),
+ "SBDATO7": (0, 20, "slf_op_5"),
+ "SBRWI": (0, 19, "lutff_4/in_0"),
+ "SBSTBI": (0, 19, "lutff_3/in_0"),
+ "SCLI": (0, 19, "lutff_2/in_1"),
+ "SCLO": (0, 19, "slf_op_3"),
+ "SCLOE": (0, 19, "slf_op_4"),
+ "SDAI": (0, 19, "lutff_1/in_1"),
+ "SDAO": (0, 19, "slf_op_1"),
+ "SDAOE": (0, 19, "slf_op_2"),
+ "SDA_INPUT_DELAYED": (12, 21, "SDA_input_delay"),
+ "SDA_OUTPUT_DELAYED": (12, 21, "SDA_output_delay"),
+ },
+ ("I2C", (25, 21, 0)): {
+ "I2CIRQ": (25, 20, "slf_op_7"),
+ "I2CWKUP": (25, 19, "slf_op_5"),
+ "I2C_ENABLE_0": (19, 21, "cbit2usealt_in_1"),
+ "I2C_ENABLE_1": (19, 21, "cbit2usealt_in_0"),
+ "SBACKO": (25, 20, "slf_op_6"),
+ "SBADRI0": (25, 20, "lutff_1/in_0"),
+ "SBADRI1": (25, 20, "lutff_2/in_0"),
+ "SBADRI2": (25, 20, "lutff_3/in_0"),
+ "SBADRI3": (25, 20, "lutff_4/in_0"),
+ "SBADRI4": (25, 20, "lutff_5/in_0"),
+ "SBADRI5": (25, 20, "lutff_6/in_0"),
+ "SBADRI6": (25, 20, "lutff_7/in_0"),
+ "SBADRI7": (25, 19, "lutff_2/in_0"),
+ "SBCLKI": (25, 20, "clk"),
+ "SBDATI0": (25, 19, "lutff_5/in_0"),
+ "SBDATI1": (25, 19, "lutff_6/in_0"),
+ "SBDATI2": (25, 19, "lutff_7/in_0"),
+ "SBDATI3": (25, 20, "lutff_0/in_3"),
+ "SBDATI4": (25, 20, "lutff_5/in_1"),
+ "SBDATI5": (25, 20, "lutff_6/in_1"),
+ "SBDATI6": (25, 20, "lutff_7/in_1"),
+ "SBDATI7": (25, 20, "lutff_0/in_0"),
+ "SBDATO0": (25, 19, "slf_op_6"),
+ "SBDATO1": (25, 19, "slf_op_7"),
+ "SBDATO2": (25, 20, "slf_op_0"),
+ "SBDATO3": (25, 20, "slf_op_1"),
+ "SBDATO4": (25, 20, "slf_op_2"),
+ "SBDATO5": (25, 20, "slf_op_3"),
+ "SBDATO6": (25, 20, "slf_op_4"),
+ "SBDATO7": (25, 20, "slf_op_5"),
+ "SBRWI": (25, 19, "lutff_4/in_0"),
+ "SBSTBI": (25, 19, "lutff_3/in_0"),
+ "SCLI": (25, 19, "lutff_2/in_1"),
+ "SCLO": (25, 19, "slf_op_3"),
+ "SCLOE": (25, 19, "slf_op_4"),
+ "SDAI": (25, 19, "lutff_1/in_1"),
+ "SDAO": (25, 19, "slf_op_1"),
+ "SDAOE": (25, 19, "slf_op_2"),
+ "SDA_INPUT_DELAYED": (19, 21, "SDA_input_delay"),
+ "SDA_OUTPUT_DELAYED": (19, 21, "SDA_output_delay"),
+ },
diff --git a/icefuzz/tests/ip/u4k_SPI_data.txt b/icefuzz/tests/ip/u4k_SPI_data.txt
new file mode 100644
index 0000000..b6463a7
--- /dev/null
+++ b/icefuzz/tests/ip/u4k_SPI_data.txt
@@ -0,0 +1,108 @@
+ ("SPI", (0, 0, 0)): {
+ "MCSNO0": (0, 3, "slf_op_1"),
+ "MCSNO1": (0, 3, "slf_op_3"),
+ "MCSNO2": (0, 3, "slf_op_6"),
+ "MCSNO3": (0, 4, "slf_op_0"),
+ "MCSNOE0": (0, 3, "slf_op_2"),
+ "MCSNOE1": (0, 3, "slf_op_4"),
+ "MCSNOE2": (0, 3, "slf_op_7"),
+ "MCSNOE3": (0, 4, "slf_op_1"),
+ "MI": (0, 2, "lutff_0/in_1"),
+ "MO": (0, 2, "slf_op_5"),
+ "MOE": (0, 2, "slf_op_6"),
+ "SBACKO": (0, 2, "slf_op_0"),
+ "SBADRI0": (0, 1, "lutff_1/in_1"),
+ "SBADRI1": (0, 1, "lutff_2/in_1"),
+ "SBADRI2": (0, 2, "lutff_0/in_3"),
+ "SBADRI3": (0, 2, "lutff_1/in_3"),
+ "SBADRI4": (0, 2, "lutff_2/in_3"),
+ "SBADRI5": (0, 2, "lutff_3/in_3"),
+ "SBADRI6": (0, 2, "lutff_4/in_3"),
+ "SBADRI7": (0, 2, "lutff_5/in_3"),
+ "SBCLKI": (0, 1, "clk"),
+ "SBDATI0": (0, 1, "lutff_1/in_3"),
+ "SBDATI1": (0, 1, "lutff_2/in_3"),
+ "SBDATI2": (0, 1, "lutff_3/in_3"),
+ "SBDATI3": (0, 1, "lutff_4/in_3"),
+ "SBDATI4": (0, 1, "lutff_5/in_3"),
+ "SBDATI5": (0, 1, "lutff_6/in_3"),
+ "SBDATI6": (0, 1, "lutff_7/in_3"),
+ "SBDATI7": (0, 1, "lutff_0/in_1"),
+ "SBDATO0": (0, 1, "slf_op_0"),
+ "SBDATO1": (0, 1, "slf_op_1"),
+ "SBDATO2": (0, 1, "slf_op_2"),
+ "SBDATO3": (0, 1, "slf_op_3"),
+ "SBDATO4": (0, 1, "slf_op_4"),
+ "SBDATO5": (0, 1, "slf_op_5"),
+ "SBDATO6": (0, 1, "slf_op_6"),
+ "SBDATO7": (0, 1, "slf_op_7"),
+ "SBRWI": (0, 1, "lutff_0/in_3"),
+ "SBSTBI": (0, 2, "lutff_6/in_3"),
+ "SCKI": (0, 2, "lutff_1/in_1"),
+ "SCKO": (0, 2, "slf_op_7"),
+ "SCKOE": (0, 3, "slf_op_0"),
+ "SCSNI": (0, 2, "lutff_2/in_1"),
+ "SI": (0, 2, "lutff_7/in_3"),
+ "SO": (0, 2, "slf_op_3"),
+ "SOE": (0, 2, "slf_op_4"),
+ "SPIIRQ": (0, 2, "slf_op_1"),
+ "SPIWKUP": (0, 2, "slf_op_2"),
+ "SPI_ENABLE_0": (7, 0, "cbit2usealt_in_0"),
+ "SPI_ENABLE_1": (6, 0, "cbit2usealt_in_0"),
+ "SPI_ENABLE_2": (7, 0, "cbit2usealt_in_1"),
+ "SPI_ENABLE_3": (6, 0, "cbit2usealt_in_1"),
+ },
+ ("SPI", (25, 0, 1)): {
+ "MCSNO0": (25, 3, "slf_op_1"),
+ "MCSNO1": (25, 3, "slf_op_3"),
+ "MCSNO2": (25, 3, "slf_op_6"),
+ "MCSNO3": (25, 4, "slf_op_0"),
+ "MCSNOE0": (25, 3, "slf_op_2"),
+ "MCSNOE1": (25, 3, "slf_op_4"),
+ "MCSNOE2": (25, 3, "slf_op_7"),
+ "MCSNOE3": (25, 4, "slf_op_1"),
+ "MI": (25, 2, "lutff_0/in_1"),
+ "MO": (25, 2, "slf_op_5"),
+ "MOE": (25, 2, "slf_op_6"),
+ "SBACKO": (25, 2, "slf_op_0"),
+ "SBADRI0": (25, 1, "lutff_1/in_1"),
+ "SBADRI1": (25, 1, "lutff_2/in_1"),
+ "SBADRI2": (25, 2, "lutff_0/in_3"),
+ "SBADRI3": (25, 2, "lutff_1/in_3"),
+ "SBADRI4": (25, 2, "lutff_2/in_3"),
+ "SBADRI5": (25, 2, "lutff_3/in_3"),
+ "SBADRI6": (25, 2, "lutff_4/in_3"),
+ "SBADRI7": (25, 2, "lutff_5/in_3"),
+ "SBCLKI": (25, 1, "clk"),
+ "SBDATI0": (25, 1, "lutff_1/in_3"),
+ "SBDATI1": (25, 1, "lutff_2/in_3"),
+ "SBDATI2": (25, 1, "lutff_3/in_3"),
+ "SBDATI3": (25, 1, "lutff_4/in_3"),
+ "SBDATI4": (25, 1, "lutff_5/in_3"),
+ "SBDATI5": (25, 1, "lutff_6/in_3"),
+ "SBDATI6": (25, 1, "lutff_7/in_3"),
+ "SBDATI7": (25, 1, "lutff_0/in_1"),
+ "SBDATO0": (25, 1, "slf_op_0"),
+ "SBDATO1": (25, 1, "slf_op_1"),
+ "SBDATO2": (25, 1, "slf_op_2"),
+ "SBDATO3": (25, 1, "slf_op_3"),
+ "SBDATO4": (25, 1, "slf_op_4"),
+ "SBDATO5": (25, 1, "slf_op_5"),
+ "SBDATO6": (25, 1, "slf_op_6"),
+ "SBDATO7": (25, 1, "slf_op_7"),
+ "SBRWI": (25, 1, "lutff_0/in_3"),
+ "SBSTBI": (25, 2, "lutff_6/in_3"),
+ "SCKI": (25, 2, "lutff_1/in_1"),
+ "SCKO": (25, 2, "slf_op_7"),
+ "SCKOE": (25, 3, "slf_op_0"),
+ "SCSNI": (25, 2, "lutff_2/in_1"),
+ "SI": (25, 2, "lutff_7/in_3"),
+ "SO": (25, 2, "slf_op_3"),
+ "SOE": (25, 2, "slf_op_4"),
+ "SPIIRQ": (25, 2, "slf_op_1"),
+ "SPIWKUP": (25, 2, "slf_op_2"),
+ "SPI_ENABLE_0": (24, 0, "cbit2usealt_in_0"),
+ "SPI_ENABLE_1": (24, 0, "cbit2usealt_in_1"),
+ "SPI_ENABLE_2": (23, 0, "cbit2usealt_in_0"),
+ "SPI_ENABLE_3": (23, 0, "cbit2usealt_in_1"),
+ },
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/icemulti/Makefile b/icemulti/Makefile
index 7e2fe1c..1719f39 100644
--- a/icemulti/Makefile
+++ b/icemulti/Makefile
@@ -4,21 +4,21 @@ ifeq ($(STATIC),1)
LDFLAGS += -static
endif
-all: icemulti$(EXE)
+all: $(PROGRAM_PREFIX)icemulti$(EXE)
-icemulti$(EXE): icemulti.o
+$(PROGRAM_PREFIX)icemulti$(EXE): icemulti.o
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp icemulti$(EXE) $(DESTDIR)$(PREFIX)/bin/icemulti$(EXE)
+ cp $(PROGRAM_PREFIX)icemulti$(EXE) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icemulti$(EXE)
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/icemulti$(EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icemulti$(EXE)
clean:
- rm -f icemulti$(EXE)
- rm -f icemulti.exe
+ rm -f $(PROGRAM_PREFIX)icemulti$(EXE)
+ rm -f $(PROGRAM_PREFIX)icemulti.exe
rm -f *.o *.d
-include *.d
diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc
index 4bc0919..52a7800 100644
--- a/icemulti/icemulti.cc
+++ b/icemulti/icemulti.cc
@@ -157,10 +157,10 @@ static void write_header(std::ostream &ofs, uint32_t &file_offset,
write_byte(ofs, file_offset, 0x00);
}
-void usage()
+void usage(const char *cmd)
{
log("\n");
- log("Usage: icemulti [options] input-files\n");
+ log("Usage: %s [options] input-files\n", cmd);
log("\n");
log(" -c\n");
log(" coldboot mode, power on reset image is selected by CBSEL0/CBSEL1\n");
@@ -252,12 +252,12 @@ int main(int argc, char **argv)
print_offsets = true;
break;
default:
- usage();
+ usage(argv[0]);
}
if (optind == argc) {
fprintf(stderr, "%s: missing argument\n", program_short_name);
- usage();
+ usage(argv[0]);
}
while (optind != argc) {
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/icepack/Makefile b/icepack/Makefile
index 3e8c774..46f2410 100644
--- a/icepack/Makefile
+++ b/icepack/Makefile
@@ -5,30 +5,30 @@ ifeq ($(STATIC),1)
LDFLAGS += -static
endif
-all: icepack$(EXE) iceunpack$(EXE)
+all: $(PROGRAM_PREFIX)icepack$(EXE) $(PROGRAM_PREFIX)iceunpack$(EXE)
-icepack$(EXE): icepack.o
+$(PROGRAM_PREFIX)icepack$(EXE): icepack.o
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
-iceunpack$(EXE): icepack$(EXE)
- ln -sf icepack$(EXE) iceunpack$(EXE)
+$(PROGRAM_PREFIX)iceunpack$(EXE): $(PROGRAM_PREFIX)icepack$(EXE)
+ ln -sf $(PROGRAM_PREFIX)icepack$(EXE) $(PROGRAM_PREFIX)iceunpack$(EXE)
-iceunpack.exe:
+$(PROGRAM_PREFIX)iceunpack.exe:
# no iceunpack.exe, use icepack -u
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp icepack$(EXE) $(DESTDIR)$(PREFIX)/bin/icepack$(EXE)
- ln -sf icepack$(EXE) $(DESTDIR)$(PREFIX)/bin/iceunpack$(EXE)
+ cp $(PROGRAM_PREFIX)icepack$(EXE) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icepack$(EXE)
+ ln -sf $(PROGRAM_PREFIX)icepack$(EXE) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)iceunpack$(EXE)
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/icepack$(EXE)
- rm -f $(DESTDIR)$(PREFIX)/bin/iceunpack$(EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icepack$(EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)iceunpack$(EXE)
clean:
- rm -f icepack$(EXE)
- rm -f iceunpack$(EXE)
- rm -f icepack.exe
+ rm -f $(PROGRAM_PREFIX)icepack$(EXE)
+ rm -f $(PROGRAM_PREFIX)iceunpack$(EXE)
+ rm -f $(PROGRAM_PREFIX)icepack.exe
rm -f *.o *.d
-include *.d
diff --git a/icepack/icepack.cc b/icepack/icepack.cc
index 9b38ab5..565d5f9 100644
--- a/icepack/icepack.cc
+++ b/icepack/icepack.cc
@@ -968,7 +968,17 @@ void FpgaConfig::write_cram_pbm(std::ostream &ofs, int bank_num) const
ofs << "P3\n";
ofs << stringf("%d %d\n", 2*this->cram_width, 2*this->cram_height);
ofs << "255\n";
- uint32_t tile_type[4][this->cram_width][this->cram_height];
+
+ vector<vector<uint32_t>> tile_type[4];
+
+ // We require random access to tile_type, so ensure that each column of each
+ // bank is initialised so that all possible indices are valid
+ for (int bank = 0; bank < 4; bank++) {
+ tile_type[bank].resize(this->cram_width);
+ for (int x = 0; x < this->cram_width; x++)
+ tile_type[bank][x].resize(this->cram_height);
+ }
+
for (int y = 0; y <= this->chip_height()+1; y++)
for (int x = 0; x <= this->chip_width()+1; x++)
{
@@ -1321,10 +1331,10 @@ void BramIndexConverter::get_bram_index(int bit_x, int bit_y, int &bram_bank, in
// ==================================================================
// Main program
-void usage()
+void usage(const char *cmd)
{
log("\n");
- log("Usage: icepack [options] [input-file [output-file]]\n");
+ log("Usage: %s [options] [input-file [output-file]]\n", cmd);
log("\n");
log(" -u\n");
log(" unpack mode (implied when called as 'iceunpack')\n");
@@ -1416,7 +1426,7 @@ int main(int argc, char **argv)
} else if (arg[i] == 'n') {
skip_bram_initialization = true;
} else
- usage();
+ usage(argv[0]);
continue;
}
@@ -1448,7 +1458,7 @@ int main(int argc, char **argv)
}
if (parameters.size() > 2)
- usage();
+ usage(argv[0]);
FpgaConfig fpga_config;
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/icepll/Makefile b/icepll/Makefile
index 13a1d81..6e9467b 100644
--- a/icepll/Makefile
+++ b/icepll/Makefile
@@ -4,21 +4,21 @@ ifeq ($(STATIC),1)
LDFLAGS += -static
endif
-all: icepll$(EXE)
+all: $(PROGRAM_PREFIX)icepll$(EXE)
-icepll$(EXE): icepll.o
+$(PROGRAM_PREFIX)icepll$(EXE): icepll.o
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp icepll$(EXE) $(DESTDIR)$(PREFIX)/bin/icepll$(EXE)
+ cp $(PROGRAM_PREFIX)icepll$(EXE) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icepll$(EXE)
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/icepll$(EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icepll$(EXE)
clean:
- rm -f icepll$(EXE)
- rm -f icepll.exe
+ rm -f $(PROGRAM_PREFIX)icepll$(EXE)
+ rm -f $(PROGRAM_PREFIX)icepll.exe
rm -f *.o *.d
-include *.d
diff --git a/icepll/icepll.cc b/icepll/icepll.cc
index f9ebecf..398b545 100644
--- a/icepll/icepll.cc
+++ b/icepll/icepll.cc
@@ -51,6 +51,14 @@ void help(const char *cmd)
printf(" -S\n");
printf(" Disable SIMPLE feedback path mode\n");
printf("\n");
+ printf(" -b\n");
+ printf(" Find best input frequency for desired PLL Output frequency\n");
+ printf(" using the normally stocked oscillators at Mouser\n");
+ printf("\n");
+ printf(" -B <filename>\n");
+ printf(" Find best input frequency for desired PLL Output frequency\n");
+ printf(" using frequencies read from <filename>\n");
+ printf("\n");
printf(" -f <filename>\n");
printf(" Save PLL configuration as Verilog to file\n");
printf(" If <filename> is - then the Verilog is written to stdout.\n");
@@ -67,6 +75,119 @@ void help(const char *cmd)
exit(1);
}
+bool analyze(
+ bool simple_feedback, double f_pllin, double f_pllout,
+ double *best_fout, int *best_divr, int *best_divf, int *best_divq
+ )
+{
+ bool found_something = false;
+ *best_fout = 0;
+ *best_divr = 0;
+ *best_divf = 0;
+ *best_divq = 0;
+
+ int divf_max = simple_feedback ? 127 : 63;
+ // The documentation in the iCE40 PLL Usage Guide incorrectly lists the
+ // maximum value of DIVF as 63, when it is only limited to 63 when using
+ // feedback modes other that SIMPLE.
+
+ if (f_pllin < 10 || f_pllin > 133) {
+ fprintf(stderr, "Error: PLL input frequency %.3f MHz is outside range 10 MHz - 133 MHz!\n", f_pllin);
+ exit(1);
+ }
+
+ if (f_pllout < 16 || f_pllout > 275) {
+ fprintf(stderr, "Error: PLL output frequency %.3f MHz is outside range 16 MHz - 275 MHz!\n", f_pllout);
+ exit(1);
+ }
+
+ for (int divr = 0; divr <= 15; divr++)
+ {
+ double f_pfd = f_pllin / (divr + 1);
+ if (f_pfd < 10 || f_pfd > 133) continue;
+
+ for (int divf = 0; divf <= divf_max; divf++)
+ {
+ if (simple_feedback)
+ {
+ double f_vco = f_pfd * (divf + 1);
+ if (f_vco < 533 || f_vco > 1066) continue;
+
+ for (int divq = 1; divq <= 6; divq++)
+ {
+ double fout = f_vco * exp2(-divq);
+
+ if (fabs(fout - f_pllout) < fabs(*best_fout - f_pllout) || !found_something) {
+ *best_fout = fout;
+ *best_divr = divr;
+ *best_divf = divf;
+ *best_divq = divq;
+ found_something = true;
+ }
+ }
+ }
+ else
+ {
+ for (int divq = 1; divq <= 6; divq++)
+ {
+ double f_vco = f_pfd * (divf + 1) * exp2(divq);
+ if (f_vco < 533 || f_vco > 1066) continue;
+
+ double fout = f_vco * exp2(-divq);
+
+ if (fabs(fout - f_pllout) < fabs(*best_fout - f_pllout) || !found_something) {
+ *best_fout = fout;
+ *best_divr = divr;
+ *best_divf = divf;
+ *best_divq = divq;
+ found_something = true;
+ }
+ }
+ }
+ }
+ }
+
+ return found_something;
+}
+
+ // Table of frequencies to test in "best" mode defaults to ABRACOM Crystal
+ // oscillators "Normally stocked" at Mouser
+ double freq_table[100] =
+ {
+ 10, 11.0592, 11.2896, 11.7846, 12, 12.288, 12.352, 12.5, 13, 13.5, 13.6, 14.31818, 14.7456, 15, 16, 16.384, 17.2032, 18.432, 19.2, 19.44, 19.6608,
+ 20, 24, 24.576, 25, 26, 27, 27.12, 28.63636, 28.9, 29.4912,
+ 30, 32, 32.768, 33, 33.206, 33.333, 35.328, 36, 37.03, 37.4, 38.4, 38.88,
+ 40, 40.95, 40.97, 44, 44.736, 48,
+ 50, 54, 57.692,
+ 60, 64, 65, 66, 66.666, 68,
+ 70, 72, 75, 76.8,
+ 80, 80.92,
+ 92.16, 96, 98.304,
+ 100, 104, 106.25, 108,
+ 114.285,
+ 120, 122.88, 125,
+ 0
+ };
+
+void readfreqfile(const char *filename) {
+ FILE *f;
+ f = fopen(filename, "r");
+ if (f == NULL) {
+ fprintf(stderr, "Error: Can't open file %s!\n",filename);
+ exit(1);
+ }
+
+ // Clear and overwrite the default values in the table
+ memset(freq_table, 0, sizeof(freq_table));
+ int i = 0;
+ double freq=0;
+ while((i < int(sizeof(freq_table)/sizeof(double))) && (fscanf(f, "%lf", &freq) > 0))
+ {
+ freq_table[i++] = freq;
+ }
+ fclose(f);
+}
+
int main(int argc, char **argv)
{
#ifdef __EMSCRIPTEN__
@@ -88,10 +209,12 @@ int main(int argc, char **argv)
bool file_stdout = false;
const char* module_name = NULL;
bool save_as_module = false;
+ bool best_mode = false;
+ const char* freqfile = NULL;
bool quiet = false;
int opt;
- while ((opt = getopt(argc, argv, "i:o:Smf:n:q")) != -1)
+ while ((opt = getopt(argc, argv, "i:o:Smf:n:bB:q")) != -1)
{
switch (opt)
{
@@ -113,6 +236,13 @@ int main(int argc, char **argv)
case 'n':
module_name = optarg;
break;
+ case 'b':
+ best_mode = true;
+ break;
+ case 'B':
+ best_mode = true;
+ freqfile = optarg;
+ break;
case 'q':
quiet = true;
break;
@@ -137,68 +267,37 @@ int main(int argc, char **argv)
quiet = true;
}
+ if (freqfile) {
+ readfreqfile(freqfile);
+ }
+
bool found_something = false;
double best_fout = 0;
int best_divr = 0;
int best_divf = 0;
int best_divq = 0;
- // The documentation in the iCE40 PLL Usage Guide incorrectly lists the
- // maximum value of DIVF as 63, when it is only limited to 63 when using
- // feedback modes other that SIMPLE.
- int divf_max = simple_feedback ? 127 : 63;
-
- if (f_pllin < 10 || f_pllin > 133) {
- fprintf(stderr, "Error: PLL input frequency %.3f MHz is outside range 10 MHz - 133 MHz!\n", f_pllin);
- exit(1);
- }
-
- if (f_pllout < 16 || f_pllout > 275) {
- fprintf(stderr, "Error: PLL output frequency %.3f MHz is outside range 16 MHz - 275 MHz!\n", f_pllout);
- exit(1);
- }
-
- for (int divr = 0; divr <= 15; divr++)
- {
- double f_pfd = f_pllin / (divr + 1);
- if (f_pfd < 10 || f_pfd > 133) continue;
-
- for (int divf = 0; divf <= divf_max; divf++)
+ if (!best_mode) {
+ // Use only specified input frequency
+ found_something = analyze(simple_feedback, f_pllin, f_pllout, &best_fout, &best_divr, &best_divf, &best_divq);
+ } else {
+ // Iterate over all standard crystal frequencies and select the best
+ for (int i = 0; freq_table[i]>0.0 ; i++)
{
- if (simple_feedback)
- {
- double f_vco = f_pfd * (divf + 1);
- if (f_vco < 533 || f_vco > 1066) continue;
-
- for (int divq = 1; divq <= 6; divq++)
- {
- double fout = f_vco * exp2(-divq);
-
- if (fabs(fout - f_pllout) < fabs(best_fout - f_pllout) || !found_something) {
- best_fout = fout;
- best_divr = divr;
- best_divf = divf;
- best_divq = divq;
- found_something = true;
- }
- }
- }
- else
+ double fout = 0;
+ int divr = 0;
+ int divf = 0;
+ int divq = 0;
+ if (analyze(simple_feedback, freq_table[i], f_pllout, &fout, &divr, &divf, &divq))
{
- for (int divq = 1; divq <= 6; divq++)
+ found_something = true;
+ if (abs(fout - f_pllout) < abs(best_fout - f_pllout))
{
- double f_vco = f_pfd * (divf + 1) * exp2(divq);
- if (f_vco < 533 || f_vco > 1066) continue;
-
- double fout = f_vco * exp2(-divq);
-
- if (fabs(fout - f_pllout) < fabs(best_fout - f_pllout) || !found_something) {
- best_fout = fout;
- best_divr = divr;
- best_divf = divf;
- best_divq = divq;
- found_something = true;
- }
+ f_pllin = freq_table[i];
+ best_fout = fout;
+ best_divr = divr;
+ best_divf = divf;
+ best_divq = divq;
}
}
}
diff --git a/iceprog/Makefile b/iceprog/Makefile
index 9727257..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; )
@@ -16,21 +9,21 @@ LDLIBS += $(shell for pkg in libftdi1 libftdi; do $(PKG_CONFIG) --silence-errors
CFLAGS += $(shell for pkg in libftdi1 libftdi; do $(PKG_CONFIG) --silence-errors --cflags $$pkg && exit; done; )
endif
-all: iceprog$(EXE)
+all: $(PROGRAM_PREFIX)iceprog$(EXE)
-iceprog$(EXE): iceprog.o mpsse.o
+$(PROGRAM_PREFIX)iceprog$(EXE): iceprog.o mpsse.o
$(CC) -o $@ $(LDFLAGS) $^ $(LDLIBS)
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp iceprog$(EXE) $(DESTDIR)$(PREFIX)/bin/iceprog$(EXE)
+ cp $(PROGRAM_PREFIX)iceprog$(EXE) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)iceprog$(EXE)
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/iceprog$(EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)iceprog$(EXE)
clean:
- rm -f iceprog
- rm -f iceprog.exe
+ rm -f $(PROGRAM_PREFIX)iceprog
+ rm -f $(PROGRAM_PREFIX)iceprog.exe
rm -f *.o *.d
-include *.d
diff --git a/iceprog/iceprog.c b/iceprog/iceprog.c
index f38b133..c5243b9 100644
--- a/iceprog/iceprog.c
+++ b/iceprog/iceprog.c
@@ -310,6 +310,28 @@ static void flash_bulk_erase()
flash_chip_deselect();
}
+static void flash_4kB_sector_erase(int addr)
+{
+ fprintf(stderr, "erase 4kB sector at 0x%06X..\n", addr);
+
+ uint8_t command[4] = { FC_SE, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr };
+
+ flash_chip_select();
+ mpsse_send_spi(command, 4);
+ flash_chip_deselect();
+}
+
+static void flash_32kB_sector_erase(int addr)
+{
+ fprintf(stderr, "erase 64kB sector at 0x%06X..\n", addr);
+
+ uint8_t command[4] = { FC_BE32, (uint8_t)(addr >> 16), (uint8_t)(addr >> 8), (uint8_t)addr };
+
+ flash_chip_select();
+ mpsse_send_spi(command, 4);
+ flash_chip_deselect();
+}
+
static void flash_64kB_sector_erase(int addr)
{
fprintf(stderr, "erase 64kB sector at 0x%06X..\n", addr);
@@ -448,7 +470,9 @@ static void help(const char *progname)
fprintf(stderr, " (append 'k' to the argument for size in kilobytes,\n");
fprintf(stderr, " or 'M' for size in megabytes)\n");
fprintf(stderr, " -s slow SPI (50 kHz instead of 6 MHz)\n");
+ fprintf(stderr, " -k keep flash in powered up state (i.e. skip power down command)\n");
fprintf(stderr, " -v verbose output\n");
+ fprintf(stderr, " -i [4,32,64] select erase block size [default: 64k]\n");
fprintf(stderr, "\n");
fprintf(stderr, "Mode of operation:\n");
fprintf(stderr, " [default] write file contents to flash, then verify\n");
@@ -509,6 +533,7 @@ int main(int argc, char **argv)
my_name = argv[0] + i + 1;
int read_size = 256 * 1024;
+ int erase_block_size = 64;
int erase_size = 0;
int rw_offset = 0;
@@ -522,6 +547,7 @@ int main(int argc, char **argv)
bool slow_clock = false;
bool disable_protect = false;
bool disable_verify = false;
+ bool disable_powerdown = false;
const char *filename = NULL;
const char *devstr = NULL;
int ifnum = 0;
@@ -539,11 +565,23 @@ int main(int argc, char **argv)
/* Decode command line parameters */
int opt;
char *endptr;
- while ((opt = getopt_long(argc, argv, "d:I:rR:e:o:cbnStvspX", long_options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "d:i:I:rR:e:o:cbnStvspXk", long_options, NULL)) != -1) {
switch (opt) {
case 'd': /* device string */
devstr = optarg;
break;
+ case 'i': /* block erase size */
+ if (!strcmp(optarg, "4"))
+ erase_block_size = 4;
+ else if (!strcmp(optarg, "32"))
+ erase_block_size = 32;
+ else if (!strcmp(optarg, "64"))
+ erase_block_size = 64;
+ else {
+ fprintf(stderr, "%s: `%s' is not a valid erase block size (must be `4', `32' or `64')\n", my_name, optarg);
+ return EXIT_FAILURE;
+ }
+ break;
case 'I': /* FTDI Chip interface select */
if (!strcmp(optarg, "A"))
ifnum = 0;
@@ -629,6 +667,9 @@ int main(int argc, char **argv)
case 'X': /* disable verification */
disable_verify = true;
break;
+ case 'k': /* disable power down command */
+ disable_powerdown = true;
+ break;
case -2:
help(argv[0]);
return EXIT_SUCCESS;
@@ -888,12 +929,24 @@ int main(int argc, char **argv)
{
fprintf(stderr, "file size: %ld\n", file_size);
- int begin_addr = rw_offset & ~0xffff;
- int end_addr = (rw_offset + file_size + 0xffff) & ~0xffff;
+ int block_size = erase_block_size << 10;
+ int block_mask = block_size - 1;
+ int begin_addr = rw_offset & ~block_mask;
+ int end_addr = (rw_offset + file_size + block_mask) & ~block_mask;
- for (int addr = begin_addr; addr < end_addr; addr += 0x10000) {
+ for (int addr = begin_addr; addr < end_addr; addr += block_size) {
flash_write_enable();
- flash_64kB_sector_erase(addr);
+ switch(erase_block_size) {
+ case 4:
+ flash_4kB_sector_erase(addr);
+ break;
+ case 32:
+ flash_32kB_sector_erase(addr);
+ break;
+ case 64:
+ flash_64kB_sector_erase(addr);
+ break;
+ }
if (verbose) {
fprintf(stderr, "Status after block erase:\n");
flash_read_status();
@@ -913,10 +966,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, addr / (file_size / 100));
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);
@@ -931,9 +988,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, addr / (read_size / 100));
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) {
@@ -941,6 +1002,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, addr / (file_size / 100));
flash_read(rw_offset + addr, buffer_flash, rc);
if (memcmp(buffer_file, buffer_flash, rc)) {
fprintf(stderr, "Found difference between flash and file!\n");
@@ -948,6 +1011,7 @@ int main(int argc, char **argv)
}
}
+ fprintf(stderr, " \r");
fprintf(stderr, "VERIFY OK\n");
}
@@ -956,7 +1020,8 @@ int main(int argc, char **argv)
// Reset
// ---------------------------------------------------------
- flash_power_down();
+ if (!disable_powerdown)
+ flash_power_down();
set_cs_creset(1, 1);
usleep(250000);
diff --git a/icetime/Makefile b/icetime/Makefile
index acf5b8f..4834709 100644
--- a/icetime/Makefile
+++ b/icetime/Makefile
@@ -6,12 +6,12 @@ ifeq ($(STATIC),1)
LDFLAGS += -static
endif
-all: icetime$(EXE)
+all: $(PROGRAM_PREFIX)icetime$(EXE)
-CHIPS=lp384 lp1k lp8k hx1k hx8k up5k
+CHIPS=lp384 lp1k lp8k hx1k hx8k up5k u4k
ifeq ($(EXE),.js)
-icetime$(EXE): | share/$(CHIPDB_SUBDIR)/chipdb-384.txt share/$(CHIPDB_SUBDIR)/chipdb-1k.txt share/$(CHIPDB_SUBDIR)/chipdb-8k.txt share/$(CHIPDB_SUBDIR)/chipdb-5k.txt
+$(PROGRAM_PREFIX)icetime$(EXE): | share/$(CHIPDB_SUBDIR)/chipdb-384.txt share/$(CHIPDB_SUBDIR)/chipdb-1k.txt share/$(CHIPDB_SUBDIR)/chipdb-8k.txt share/$(CHIPDB_SUBDIR)/chipdb-5k.txt
share/$(CHIPDB_SUBDIR)/chipdb-384.txt: ../icebox/chipdb-384.txt
mkdir -p share/$(CHIPDB_SUBDIR)
@@ -28,20 +28,22 @@ share/$(CHIPDB_SUBDIR)/chipdb-5k.txt: ../icebox/chipdb-5k.txt
override LDFLAGS += --embed-file share
endif
-icetime$(EXE): icetime.o iceutil.o $(addsuffix .o, $(addprefix timings-, $(CHIPS)))
+$(PROGRAM_PREFIX)icetime$(EXE): icetime.o iceutil.o $(addsuffix .o, $(addprefix timings-, $(CHIPS)))
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
timings-%.cc: timings.py ../icefuzz/timings_%.txt
$(PYTHON) timings.py $* > $@
+.PRECIOUS: timings-%.cc
+
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
- mkdir -p $(DESTDIR)$(PREFIX)/share/icebox
- cp icetime$(EXE) $(DESTDIR)$(PREFIX)/bin/icetime$(EXE)
- cp ../icefuzz/timings_*.txt $(DESTDIR)$(PREFIX)/share/icebox/
+ mkdir -p $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox
+ cp $(PROGRAM_PREFIX)icetime$(EXE) $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icetime$(EXE)
+ cp ../icefuzz/timings_*.txt $(DESTDIR)$(PREFIX)/share/$(PROGRAM_PREFIX)icebox/
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/icetime$(EXE)
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(PROGRAM_PREFIX)icetime$(EXE)
# View timing netlist:
@@ -65,7 +67,7 @@ test: test0 test1 test2 test3 test4 test5 test6 test7 test8 test9
show: show0 show1 show2 show3 show4 show5 show6 show7 show8 show9
clean:
- rm -f icetime$(EXE) icetime.exe *.o *.d timings-*.cc
+ rm -f $(PROGRAM_PREFIX)icetime$(EXE) $(PROGRAM_PREFIX)icetime.exe *.o *.d timings-*.cc
rm -rf test[0-9]*
-include *.d
diff --git a/icetime/icetime.cc b/icetime/icetime.cc
index cc37625..d730fc6 100644
--- a/icetime/icetime.cc
+++ b/icetime/icetime.cc
@@ -30,6 +30,7 @@
#include <functional>
#include <map>
#include <set>
+#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
@@ -61,16 +62,16 @@ std::map<int, std::string> net_symbols;
bool get_config_bit(int tile_x, int tile_y, int bit_row, int bit_col)
{
- if (int(config_bits.size()) < tile_x)
+ if (int(config_bits.size()) <= tile_x)
return false;
- if (int(config_bits[tile_x].size()) < tile_y)
+ if (int(config_bits[tile_x].size()) <= tile_y)
return false;
- if (int(config_bits[tile_x][tile_y].size()) < bit_row)
+ if (int(config_bits[tile_x][tile_y].size()) <= bit_row)
return false;
- if (int(config_bits[tile_x][tile_y][bit_row].size()) < bit_col)
+ if (int(config_bits[tile_x][tile_y][bit_row].size()) <= bit_col)
return false;
return config_bits[tile_x][tile_y][bit_row][bit_col];
@@ -752,6 +753,7 @@ double get_delay_lp8k(std::string cell_type, std::string in_port, std::string ou
double get_delay_hx1k(std::string cell_type, std::string in_port, std::string out_port);
double get_delay_hx8k(std::string cell_type, std::string in_port, std::string out_port);
double get_delay_up5k(std::string cell_type, std::string in_port, std::string out_port);
+double get_delay_u4k(std::string cell_type, std::string in_port, std::string out_port);
double get_delay(std::string cell_type, std::string in_port, std::string out_port)
{
@@ -764,17 +766,20 @@ double get_delay(std::string cell_type, std::string in_port, std::string out_por
if (device_type == "lp1k")
return get_delay_lp1k(cell_type, in_port, out_port);
- if (device_type == "lp8k")
+ if (device_type == "lp8k" || device_type == "lp4k")
return get_delay_lp8k(cell_type, in_port, out_port);
if (device_type == "hx1k")
return get_delay_hx1k(cell_type, in_port, out_port);
- if (device_type == "hx8k")
+ if (device_type == "hx8k" || device_type == "hx4k")
return get_delay_hx8k(cell_type, in_port, out_port);
- if (device_type == "up5k")
+ if (device_type == "up5k" || device_type == "up3k")
return get_delay_up5k(cell_type, in_port, out_port);
+
+ if (device_type == "u4k" || device_type == "u1k" || device_type == "u2k")
+ return get_delay_u4k(cell_type, in_port, out_port);
fprintf(stderr, "No built-in timing database for '%s' devices!\n", device_type.c_str());
exit(1);
}
@@ -1593,7 +1598,7 @@ void make_seg_cell(int net, const net_segment_t &seg)
if (sscanf(seg.name.c_str(), "lutff_%d/in_%d", &a, &b) == 2) {
//"logic" wires at the side of the device are actually IP or DSP
- if(device_type == "up5k" && ((seg.x == 0) || (seg.x == int(config_tile_type.size()) - 1))) {
+ if((device_type == "up5k" || device_type == "up3k") && ((seg.x == 0) || (seg.x == int(config_tile_type.size()) - 1))) {
std::string primnet;
auto cell = make_dsp_ip(seg.x, seg.y, seg.name, primnet);
if(cell != "") {
@@ -2209,7 +2214,7 @@ void help(const char *cmd)
printf(" -j <output_file>\n");
printf(" write timing report in json format to the file\n");
printf("\n");
- printf(" -d lp384|lp1k|hx1k|lp8k|hx8k|up5k\n");
+ printf(" -d lp384|lp1k|hx1k|lp4k|hx4k|lp8k|hx8k|up3k|up5k|u1k|u2k|u4k\n");
printf(" select the device type (default = lp variant)\n");
printf("\n");
printf(" -C <chipdb-file>\n");
@@ -2366,13 +2371,17 @@ int main(int argc, char **argv)
if (config_device != "1k")
goto device_chip_mismatch;
} else
- if (device_type == "lp8k" || device_type == "hx8k") {
+ if (device_type == "lp8k" || device_type == "hx8k" || device_type == "lp4k" || device_type == "hx4k") {
if (config_device != "8k")
goto device_chip_mismatch;
} else
- if (device_type == "up5k") {
+ if (device_type == "up5k" || device_type == "up3k") {
if (config_device != "5k")
goto device_chip_mismatch;
+ } else
+ if (device_type == "u4k" || device_type == "u1k" || device_type == "u2k") {
+ if (config_device != "u4k")
+ goto device_chip_mismatch;
} else {
fprintf(stderr, "Error: Invalid device type '%s'.\n", device_type.c_str());
exit(1);
diff --git a/icetime/iceutil.cc b/icetime/iceutil.cc
index ad8d662..440b9a8 100644
--- a/icetime/iceutil.cc
+++ b/icetime/iceutil.cc
@@ -155,7 +155,7 @@ std::string find_chipdb(std::string config_device)
#else
homepath += getenv("HOME");
#endif
- homepath += std::string(PREFIX + 1) + "/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
+ homepath += std::string(&PREFIX[1]) + "/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
if (verbose)
fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), homepath.c_str());
if (file_test_open(homepath))