mirror of https://github.com/YosysHQ/icestorm.git
322 lines
11 KiB
HTML
322 lines
11 KiB
HTML
|
|
<title>Project IceStorm</title>
|
||
|
|
<h1>Project IceStorm</h1>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
<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-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>
|
||
|
|
|
||
|
|
<h2>What is Project IceStorm?</h2>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
Project IceStorm aims at documenting the bitstream format of Lattice iCE40
|
||
|
|
FPGAs and providing simple tools for analyzing and creating bitstream files.
|
||
|
|
At the moment the focus of the project is on the HX1K-TQ144 device, but
|
||
|
|
most of the information is device-independent.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<h2>Why the Lattice iCE40?</h2>
|
||
|
|
|
||
|
|
<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.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
Also, with the <a href="http://www.latticesemi.com/icestick">iCEstick</a> there is
|
||
|
|
a cheap and easy to use development platform available, which makes the part interesting
|
||
|
|
for all kinds of projects.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<h2>What is the Status of the Project?</h2>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
We have enough bits mapped that we can create a functional verilog model for almost all
|
||
|
|
bitstreams generated by Lattice iCEcube2 for the iCE40 HX1K-TQ144, as long as no
|
||
|
|
block memories or PLLs are used. (Both are fully documented, but the
|
||
|
|
<tt>icebox_vlog.py</tt> script does not create verilog models for them yet.)
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
Next on the TODO list: PLLs, Timing Analysis, support for HX8K chips.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<h2>What is the Status of 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>.
|
||
|
|
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
|
||
|
|
arachne-pnr</a> (this example targets the iCEstick development board):
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<pre style="padding-left: 3em">yosys -p "synth_ice40 -blif rot.blif" rot.v
|
||
|
|
arachne-pnr -d 1k -p rot.pcf rot.blif -o rot.txt
|
||
|
|
icepack rot.txt rot.bin
|
||
|
|
iceprog rot.bin</pre>
|
||
|
|
|
||
|
|
<h2>Where are the Tools?</h2>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
Here is the current snapshot of our toolchain: <a href="icestorm-snapshot-150526.zip">icestorm-snapshot-150526.zip</a><br/>
|
||
|
|
<i>This is work under construction and highly experimental! Use at your own risk!</i>
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p style="margin-bottom: 0.5em;">
|
||
|
|
All snapshots in reverse chronological order:
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<ul style="margin-top: 0.5em;">
|
||
|
|
<li><a href="icestorm-snapshot-150526.zip">icestorm-snapshot-150526.zip</a></li>
|
||
|
|
<li><a href="icestorm-snapshot-150413.zip">icestorm-snapshot-150413.zip</a></li>
|
||
|
|
<li><a href="icestorm-snapshot-150401.zip">icestorm-snapshot-150401.zip</a></li>
|
||
|
|
<li><a href="icestorm-snapshot-150322.zip">icestorm-snapshot-150322.zip</a></li>
|
||
|
|
</ul>
|
||
|
|
|
||
|
|
<h3>IcePack/IceUnpack</h3>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
The <tt>iceunpack</tt> program converts an iCE40 <tt>.bin</tt> file into the IceBox ASCII format
|
||
|
|
that has blocks of <tt>0</tt> and <tt>1</tt> for the config bits for each tile in the chip. The
|
||
|
|
<tt>icepack</tt> program converts such an ASCII file back to an iCE40 <tt>.bin</tt> file.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<h3>IceBox</h3>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
A python library and various tools for working with IceBox ASCII files and accessing
|
||
|
|
the device database. For example <tt>icebox_vlog.py</tt> converts our ASCII file
|
||
|
|
dump of a bitstream into a verilog file that implements an equivalent circuit.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<h3>IceProg</h3>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
A small driver programm for the FTDI-based programmer used on the iCEstick and HX8K development boards.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
<i>The tools are written by Clifford Wolf. IcePack/IceUnpack is based on a reference implementation provided by Mathias Lasser.</i>
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<h2>Where is the Documentation?</h2>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
Recommended reading:
|
||
|
|
<a href="http://www.latticesemi.com/~/media/LatticeSemi/Documents/DataSheets/iCE/iCE40LPHXFamilyDataSheet.pdf">Lattice iCE40 LP/HX Family Datasheet</a>,
|
||
|
|
<a href="http://www.latticesemi.com/~/media/LatticeSemi/Documents/TechnicalBriefs/SBTICETechnologyLibrary201412.pdf">Lattice iCE Technology Library</a>
|
||
|
|
(Especially the three pages on "Architecture Overview", "PLB Blocks", "Routing", and "Clock/Control Distribution Network" in
|
||
|
|
the Lattice iCE40 LP/HX Family Datasheet. Read that first, then come back here.)
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
The FPGA fabric is divided into tiles. There are IO, RAM and LOGIC tiles.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<ul>
|
||
|
|
<li><a href="logic_tile.html">LOGIC Tile Documentation</a></li>
|
||
|
|
<li><a href="io_tile.html">IO Tile Documentation</a></li>
|
||
|
|
<li><a href="ram_tile.html">RAM Tile Documentation</a></li>
|
||
|
|
<li><a href="format.html">The Bitstream File Format</a></li>
|
||
|
|
<li><a href="bitdocs/">Tile Bits Reference Docs</a></li>
|
||
|
|
</ul>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
The <tt>iceunpack</tt> program can be used to convert the bitstream into an ASCII file
|
||
|
|
that has a block of <tt>0</tt> and <tt>1</tt> characters for each tile. For example:
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<pre style="padding-left: 3em">.logic_tile 12 12
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000011010000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000001011000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000000000000000000000000000000000
|
||
|
|
000000000000000000000000001000001000010101010000000000
|
||
|
|
000000000000000000000000000101010000101010100000000000</pre>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
This bits are referred to as <tt>B<i>y</i>[<i>x</i>]</tt> in the documentation. For example, <tt>B0</tt> is the first
|
||
|
|
line, <tt>B0[0]</tt> the first bit in the first line, and <tt>B15[53]</tt> the last bit in the last line.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
The <tt>icebox_explain.py</tt> program can be used to turn this block of config bits into a description of the cell
|
||
|
|
configuration:
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<pre style="padding-left: 3em">.logic_tile 12 12
|
||
|
|
LC_7 0101010110101010 0000
|
||
|
|
buffer local_g0_2 lutff_7/in_3
|
||
|
|
buffer local_g1_4 lutff_7/in_0
|
||
|
|
buffer sp12_h_r_18 local_g0_2
|
||
|
|
buffer sp12_h_r_20 local_g1_4</pre>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
IceBox contains a database of the wires and configuration bits that can be found in iCE40 tiles. This database can be accessed
|
||
|
|
via the IceBox Python API. But IceBox is a large hack. So it is recommended to only use the IceBox API
|
||
|
|
to export this database into a format that fits the target application. See <tt>icebox_chipdb.py</tt> for
|
||
|
|
an example program that does that.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
The recommended approach for learning how to use this documentation is to synthesize very simple circuits using
|
||
|
|
Lattice iCEcube2, run our toolchain on the resulting bitstream files, and analyze the results using the HTML export of the database
|
||
|
|
mentioned above. <tt>icebox_vlog.py</tt> can be used to convert the bitstream to verilog. The output file of
|
||
|
|
this tool will also outline the signal paths in comments added to the generated verilog.
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
For example, using the <tt>top_bitmap.bin</tt> from the following Verilog and PCF files:
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<pre style="padding-left: 3em">module top (input a, b, output y);
|
||
|
|
assign y = a & b;
|
||
|
|
endmodule
|
||
|
|
|
||
|
|
set_io a 1
|
||
|
|
set_io b 10
|
||
|
|
set_io y 11</pre>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
We would get something like the following <tt>icebox_explain.py</tt> output:
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<pre style="padding-left: 3em">$ iceunpack top_bitmap.bin top_bitmap.txt
|
||
|
|
$ icebox_explain top_bitmap.txt
|
||
|
|
Reading file 'top_bitmap.txt'..
|
||
|
|
Fabric size (without IO tiles): 12 x 16
|
||
|
|
|
||
|
|
.io_tile 0 10
|
||
|
|
IOB_1 PINTYPE_0
|
||
|
|
IOB_1 PINTYPE_3
|
||
|
|
IOB_1 PINTYPE_4
|
||
|
|
IoCtrl IE_0
|
||
|
|
IoCtrl IE_1
|
||
|
|
IoCtrl REN_0
|
||
|
|
buffer local_g1_2 io_1/D_OUT_0
|
||
|
|
buffer logic_op_tnr_2 local_g1_2
|
||
|
|
|
||
|
|
.io_tile 0 14
|
||
|
|
IOB_1 PINTYPE_0
|
||
|
|
IoCtrl IE_1
|
||
|
|
IoCtrl REN_0
|
||
|
|
buffer io_1/D_IN_0 span4_horz_28
|
||
|
|
|
||
|
|
.io_tile 0 11
|
||
|
|
IOB_0 PINTYPE_0
|
||
|
|
IoCtrl IE_0
|
||
|
|
IoCtrl REN_1
|
||
|
|
|
||
|
|
.logic_tile 1 11
|
||
|
|
LC_2 0000000001010101 0000
|
||
|
|
buffer local_g1_4 lutff_2/in_3
|
||
|
|
buffer local_g3_1 lutff_2/in_0
|
||
|
|
buffer neigh_op_lft_4 local_g1_4
|
||
|
|
buffer sp4_r_v_b_41 local_g3_1
|
||
|
|
|
||
|
|
.logic_tile 2 14
|
||
|
|
routing sp4_h_l_41 sp4_v_b_4</pre>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
And something like the following <tt>icebox_vlog.py</tt> output:
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<pre style="padding-left: 3em">$ icebox_vlog top_bitmap.txt
|
||
|
|
// Reading file 'top_bitmap.txt'..
|
||
|
|
|
||
|
|
module chip (output io_0_10_1, input io_0_11_0, input io_0_14_1);
|
||
|
|
|
||
|
|
wire io_0_10_1;
|
||
|
|
// io_0_10_1
|
||
|
|
// (0, 10, 'io_1/D_OUT_0')
|
||
|
|
// (0, 10, 'io_1/PAD')
|
||
|
|
// (0, 10, 'local_g1_2')
|
||
|
|
// (0, 10, 'logic_op_tnr_2')
|
||
|
|
// (0, 11, 'logic_op_rgt_2')
|
||
|
|
// (0, 12, 'logic_op_bnr_2')
|
||
|
|
// (1, 10, 'neigh_op_top_2')
|
||
|
|
// (1, 11, 'lutff_2/out')
|
||
|
|
// (1, 12, 'neigh_op_bot_2')
|
||
|
|
// (2, 10, 'neigh_op_tnl_2')
|
||
|
|
// (2, 11, 'neigh_op_lft_2')
|
||
|
|
// (2, 12, 'neigh_op_bnl_2')
|
||
|
|
|
||
|
|
wire io_0_11_0;
|
||
|
|
// io_0_11_0
|
||
|
|
// (0, 11, 'io_0/D_IN_0')
|
||
|
|
// (0, 11, 'io_0/PAD')
|
||
|
|
// (1, 10, 'neigh_op_tnl_0')
|
||
|
|
// (1, 10, 'neigh_op_tnl_4')
|
||
|
|
// (1, 11, 'local_g1_4')
|
||
|
|
// (1, 11, 'lutff_2/in_3')
|
||
|
|
// (1, 11, 'neigh_op_lft_0')
|
||
|
|
// (1, 11, 'neigh_op_lft_4')
|
||
|
|
// (1, 12, 'neigh_op_bnl_0')
|
||
|
|
// (1, 12, 'neigh_op_bnl_4')
|
||
|
|
|
||
|
|
wire io_0_14_1;
|
||
|
|
// io_0_14_1
|
||
|
|
// (0, 14, 'io_1/D_IN_0')
|
||
|
|
// (0, 14, 'io_1/PAD')
|
||
|
|
// (0, 14, 'span4_horz_28')
|
||
|
|
// (1, 11, 'local_g3_1')
|
||
|
|
// (1, 11, 'lutff_2/in_0')
|
||
|
|
// (1, 11, 'sp4_r_v_b_41')
|
||
|
|
// (1, 12, 'sp4_r_v_b_28')
|
||
|
|
// (1, 13, 'neigh_op_tnl_2')
|
||
|
|
// (1, 13, 'neigh_op_tnl_6')
|
||
|
|
// (1, 13, 'sp4_r_v_b_17')
|
||
|
|
// (1, 14, 'neigh_op_lft_2')
|
||
|
|
// (1, 14, 'neigh_op_lft_6')
|
||
|
|
// (1, 14, 'sp4_h_r_41')
|
||
|
|
// (1, 14, 'sp4_r_v_b_4')
|
||
|
|
// (1, 15, 'neigh_op_bnl_2')
|
||
|
|
// (1, 15, 'neigh_op_bnl_6')
|
||
|
|
// (2, 10, 'sp4_v_t_41')
|
||
|
|
// (2, 11, 'sp4_v_b_41')
|
||
|
|
// (2, 12, 'sp4_v_b_28')
|
||
|
|
// (2, 13, 'sp4_v_b_17')
|
||
|
|
// (2, 14, 'sp4_h_l_41')
|
||
|
|
// (2, 14, 'sp4_v_b_4')
|
||
|
|
|
||
|
|
assign io_0_10_1 = /* LUT 1 11 2 */ io_0_11_0 ? io_0_14_1 : 0;
|
||
|
|
|
||
|
|
endmodule</pre>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
<hr>
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
In papers and reports, please refer to Project IceStorm as follows: Clifford Wolf, Mathias Lasser. Project IceStorm. http://www.clifford.at/icestorm/,
|
||
|
|
e.g. using the following BibTeX code:
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<pre>@MISC{IceStorm,
|
||
|
|
author = {Clifford Wolf and Mathias Lasser},
|
||
|
|
title = {Project IceStorm},
|
||
|
|
howpublished = "\url{http://www.clifford.at/icestorm/}"
|
||
|
|
}</pre>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
<hr>
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<p>
|
||
|
|
<i>Documentation mostly by Clifford Wolf <clifford@clifford.at> in 2015. Based on research by Mathias Lasser and Clifford Wolf.<br/>
|
||
|
|
Buy an <a href="http://www.latticesemi.com/icestick">iCEstick</a> from Lattice and see what you can do with the information provided here. Buy a few because you might break some..</i>
|
||
|
|
</p>
|