Imported full dev sources

This commit is contained in:
Clifford Wolf 2015-07-18 13:10:40 +02:00
parent 13e63e6b65
commit 48154cb6f4
112 changed files with 37659 additions and 362 deletions

BIN
docs/checkerboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

21
docs/checkerboard.sh Normal file
View File

@ -0,0 +1,21 @@
#!/bin/bash
pbm_to_ppm() {
read line; echo "P3"
read line; echo "$line"; echo "2"
sed "s,0,x,g; s,1,y,g; s,x,$1,g; s,y,$2,g;"
}
../icepack/icepack -uc -B0 ../tests/example.bin | pbm_to_ppm "0 0 0" "0 0 2" > checkerboard_0.ppm
../icepack/icepack -ucc -B0 ../tests/example.bin | pbm_to_ppm "0 0 0" "0 1 0" > checkerboard_1.ppm
../icepack/icepack -uc -B1 ../tests/example.bin | pbm_to_ppm "0 0 0" "0 1 1" > checkerboard_2.ppm
../icepack/icepack -ucc -B1 ../tests/example.bin | pbm_to_ppm "0 0 0" "1 0 0" > checkerboard_3.ppm
../icepack/icepack -uc -B2 ../tests/example.bin | pbm_to_ppm "0 0 0" "1 0 1" > checkerboard_4.ppm
../icepack/icepack -ucc -B2 ../tests/example.bin | pbm_to_ppm "0 0 0" "1 1 0" > checkerboard_5.ppm
../icepack/icepack -uc -B3 ../tests/example.bin | pbm_to_ppm "0 0 0" "1 1 1" > checkerboard_6.ppm
../icepack/icepack -ucc -B3 ../tests/example.bin | pbm_to_ppm "0 0 0" "0 1 0" > checkerboard_7.ppm
convert -evaluate-sequence add checkerboard_[01234567].ppm checkerboard.png
rm -f checkerboard_[01234567].ppm

184
docs/colbuf.svg Normal file
View File

@ -0,0 +1,184 @@
<svg xmlns="http://www.w3.org/2000/svg" height="580" width="460">
<line x1="40" y1="10" x2="40" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="70" y1="10" x2="70" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="100" y1="10" x2="100" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="130" y1="10" x2="130" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="160" y1="10" x2="160" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="190" y1="10" x2="190" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="220" y1="10" x2="220" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="250" y1="10" x2="250" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="280" y1="10" x2="280" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="310" y1="10" x2="310" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="340" y1="10" x2="340" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="370" y1="10" x2="370" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="400" y1="10" x2="400" y2="550" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="40" x2="430" y2="40" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="70" x2="430" y2="70" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="100" x2="430" y2="100" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="130" x2="430" y2="130" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="160" x2="430" y2="160" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="190" x2="430" y2="190" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="220" x2="430" y2="220" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="250" x2="430" y2="250" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="280" x2="430" y2="280" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="310" x2="430" y2="310" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="340" x2="430" y2="340" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="370" x2="430" y2="370" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="400" x2="430" y2="400" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="430" x2="430" y2="430" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="460" x2="430" y2="460" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="490" x2="430" y2="490" style="stroke:rgb(0,0,0);stroke-width:3" />
<line x1="10" y1="520" x2="430" y2="520" style="stroke:rgb(0,0,0);stroke-width:3" />
<text x="17" y="565" fill="black">0</text>
<text x="47" y="565" fill="black">1</text>
<text x="77" y="565" fill="black">2</text>
<text x="107" y="565" fill="black">3</text>
<text x="137" y="565" fill="black">4</text>
<text x="167" y="565" fill="black">5</text>
<text x="197" y="565" fill="black">6</text>
<text x="227" y="565" fill="black">7</text>
<text x="257" y="565" fill="black">8</text>
<text x="287" y="565" fill="black">9</text>
<text x="317" y="565" fill="black">10</text>
<text x="347" y="565" fill="black">11</text>
<text x="377" y="565" fill="black">12</text>
<text x="407" y="565" fill="black">13</text>
<text x="435" y="540" fill="black">0</text>
<text x="435" y="510" fill="black">1</text>
<text x="435" y="480" fill="black">2</text>
<text x="435" y="450" fill="black">3</text>
<text x="435" y="420" fill="black">4</text>
<text x="435" y="390" fill="black">5</text>
<text x="435" y="360" fill="black">6</text>
<text x="435" y="330" fill="black">7</text>
<text x="435" y="300" fill="black">8</text>
<text x="435" y="270" fill="black">9</text>
<text x="435" y="240" fill="black">10</text>
<text x="435" y="210" fill="black">11</text>
<text x="435" y="180" fill="black">12</text>
<text x="435" y="150" fill="black">13</text>
<text x="435" y="120" fill="black">14</text>
<text x="435" y="90" fill="black">15</text>
<text x="435" y="60" fill="black">16</text>
<text x="435" y="30" fill="black">17</text>
<line x1="25" y1="415" x2="25" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="25" y1="385" x2="25" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="25" y1="175" x2="25" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="25" y1="145" x2="25" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="55" y1="415" x2="55" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="55" y1="385" x2="55" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="55" y1="175" x2="55" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="55" y1="145" x2="55" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="85" y1="415" x2="85" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="85" y1="385" x2="85" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="85" y1="175" x2="85" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="85" y1="145" x2="85" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="145" y1="415" x2="145" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="145" y1="385" x2="145" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="145" y1="175" x2="145" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="145" y1="145" x2="145" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="175" y1="415" x2="175" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="175" y1="385" x2="175" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="175" y1="175" x2="175" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="175" y1="145" x2="175" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="205" y1="415" x2="205" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="205" y1="385" x2="205" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="205" y1="175" x2="205" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="205" y1="145" x2="205" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="235" y1="415" x2="235" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="235" y1="385" x2="235" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="235" y1="175" x2="235" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="235" y1="145" x2="235" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="265" y1="415" x2="265" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="265" y1="385" x2="265" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="265" y1="175" x2="265" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="265" y1="145" x2="265" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="295" y1="415" x2="295" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="295" y1="385" x2="295" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="295" y1="175" x2="295" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="295" y1="145" x2="295" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="355" y1="415" x2="355" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="355" y1="385" x2="355" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="355" y1="175" x2="355" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="355" y1="145" x2="355" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="385" y1="415" x2="385" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="385" y1="385" x2="385" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="385" y1="175" x2="385" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="385" y1="145" x2="385" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="415" y1="415" x2="415" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="415" y1="385" x2="415" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="415" y1="175" x2="415" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="415" y1="145" x2="415" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="115" y1="445" x2="115" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="115" y1="445" x2="115" y2="415" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="115" y1="385" x2="115" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="115" y1="205" x2="115" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="115" y1="205" x2="115" y2="175" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="115" y1="145" x2="115" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="325" y1="445" x2="325" y2="535" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="325" y1="445" x2="325" y2="415" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="325" y1="385" x2="325" y2="295" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="325" y1="205" x2="325" y2="265" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="325" y1="205" x2="325" y2="175" style="stroke:rgb(255,0,0);stroke-width:5" />
<line x1="325" y1="145" x2="325" y2="25" style="stroke:rgb(255,0,0);stroke-width:5" />
<circle cx="25" cy="415" r="5" fill="gray" />
<circle cx="25" cy="385" r="5" fill="gray" />
<circle cx="25" cy="175" r="5" fill="gray" />
<circle cx="25" cy="145" r="5" fill="gray" />
<circle cx="55" cy="415" r="5" fill="gray" />
<circle cx="55" cy="385" r="5" fill="gray" />
<circle cx="55" cy="175" r="5" fill="gray" />
<circle cx="55" cy="145" r="5" fill="gray" />
<circle cx="85" cy="415" r="5" fill="gray" />
<circle cx="85" cy="385" r="5" fill="gray" />
<circle cx="85" cy="175" r="5" fill="gray" />
<circle cx="85" cy="145" r="5" fill="gray" />
<circle cx="145" cy="415" r="5" fill="gray" />
<circle cx="145" cy="385" r="5" fill="gray" />
<circle cx="145" cy="175" r="5" fill="gray" />
<circle cx="145" cy="145" r="5" fill="gray" />
<circle cx="175" cy="415" r="5" fill="gray" />
<circle cx="175" cy="385" r="5" fill="gray" />
<circle cx="175" cy="175" r="5" fill="gray" />
<circle cx="175" cy="145" r="5" fill="gray" />
<circle cx="205" cy="415" r="5" fill="gray" />
<circle cx="205" cy="385" r="5" fill="gray" />
<circle cx="205" cy="175" r="5" fill="gray" />
<circle cx="205" cy="145" r="5" fill="gray" />
<circle cx="235" cy="415" r="5" fill="gray" />
<circle cx="235" cy="385" r="5" fill="gray" />
<circle cx="235" cy="175" r="5" fill="gray" />
<circle cx="235" cy="145" r="5" fill="gray" />
<circle cx="265" cy="415" r="5" fill="gray" />
<circle cx="265" cy="385" r="5" fill="gray" />
<circle cx="265" cy="175" r="5" fill="gray" />
<circle cx="265" cy="145" r="5" fill="gray" />
<circle cx="295" cy="415" r="5" fill="gray" />
<circle cx="295" cy="385" r="5" fill="gray" />
<circle cx="295" cy="175" r="5" fill="gray" />
<circle cx="295" cy="145" r="5" fill="gray" />
<circle cx="355" cy="415" r="5" fill="gray" />
<circle cx="355" cy="385" r="5" fill="gray" />
<circle cx="355" cy="175" r="5" fill="gray" />
<circle cx="355" cy="145" r="5" fill="gray" />
<circle cx="385" cy="415" r="5" fill="gray" />
<circle cx="385" cy="385" r="5" fill="gray" />
<circle cx="385" cy="175" r="5" fill="gray" />
<circle cx="385" cy="145" r="5" fill="gray" />
<circle cx="415" cy="415" r="5" fill="gray" />
<circle cx="415" cy="385" r="5" fill="gray" />
<circle cx="415" cy="175" r="5" fill="gray" />
<circle cx="415" cy="145" r="5" fill="gray" />
<circle cx="115" cy="445" r="5" fill="gray" />
<circle cx="115" cy="445" r="5" fill="gray" />
<circle cx="115" cy="385" r="5" fill="gray" />
<circle cx="115" cy="205" r="5" fill="gray" />
<circle cx="115" cy="205" r="5" fill="gray" />
<circle cx="115" cy="145" r="5" fill="gray" />
<circle cx="325" cy="445" r="5" fill="gray" />
<circle cx="325" cy="445" r="5" fill="gray" />
<circle cx="325" cy="385" r="5" fill="gray" />
<circle cx="325" cy="205" r="5" fill="gray" />
<circle cx="325" cy="205" r="5" fill="gray" />
<circle cx="325" cy="145" r="5" fill="gray" />
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

151
docs/format.html Normal file
View File

@ -0,0 +1,151 @@
<title>Project IceStorm &ndash; Bitstream File Format Documentation</title>
<h1>Project IceStorm &ndash; Bitstream File Format Documentation</h1>
<p>
<i><a href=".">Project IceStorm</a> aims at documenting the bitstream format of Lattice iCE40
FPGAs and providing simple tools for analyzing and creating bitstream files.
This is work in progress.</i>
</p>
<h2>General Description of the File Format</h2>
<p>
The bitstream file starts with the bytes 0xFF 0x00, followed by a sequence of
zero-terminated comment strings, followed by 0x00 0xFF. However, there seems to be
a bug in the Lattice "bitstream" tool that moves the terminating 0x00 0xFF a few
bytes into the comment string in some cases.
</p>
<p>
After the comment sections the token 0x7EAA997E (MSB first) starts the actual
bit stream. The bitstream consists of one-byte commands, followed by a payload
word, followed by an optional block of data. The MSB nibble of the command byte
is the command opcode, the LSB nibble is the length of the command payload in
bytes. The commands that do not require a payload are using the opcode 0, with
the command encoded in the payload field. Note that this "payload" in this
context refers to a single integer argument, not the blocks of data that
follows the command in case of the CRAM and BRAM commands.
</p>
<p>
The following commands are known:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>Opcode</th><th>Description</th></tr>
<tr><td>0</td><td>payload=0: CRAM Data<br/>
payload=3: BRAM Data<br/>
payload=5: Reset CRC<br/>
payload=6: Wakeup</td></tr>
<tr><td>1</td><td>Set bank number</td></tr>
<tr><td>2</td><td>CRC check</td></tr>
<tr><td>5</td><td>Set internal oscillator frequency range<br/>
payload=0: low<br/>
payload=1: medium<br/>
payload=2: high</td></tr>
<tr><td>6</td><td>Set bank width</td></tr>
<tr><td>7</td><td>Set bank height</td></tr>
<tr><td>8</td><td>Set bank offset</td></tr>
<tr><td>9</td><td>payload=0: Disable warm boot<br/>
payload=32: Enable warm boot</td></tr>
</table>
</p>
<p>
Use <tt>iceunpack -vv</tt> to display the commands as they are interpreted by the tool.
</p>
<p>
Note: The format itself seems to be very flexible. At the moment it is unclear what the FPGA
devices will do when presented with a bitstream that use the commands in a different way
than the bitstreams generated by the lattice tools.
</p>
<h2>Writing SRAM content</h2>
<p>
Most bytes in the bitstream are SRAM data bytes that should be written to the various SRAM banks
in the FPGA. The following sequence is used to program an SRAM cell:
</p>
<p><ul>
<li>Set bank width (opcode 6)</li>
<li>Set bank height (opcode 7)</li>
<li>Set bank offset (opcode 8)</li>
<li>Set bank number (opcode 1)</li>
<li>CRAM or BRAM Data Command</li>
<li>(width * height / 8) data bytes</li>
<li>two zero bytes</li>
</ul></p>
<p>
The bank width and height parameters reflect the width and height of the SRAM bank. A large SRAM can
be written in smaller junks. In this case height parameter may be smaller and the offset parameter
reflects the vertical start position.
</p>
<p>
There are four CRAM and four BRAM banks in an iCE40 FPGA. The different devices from the family
use different widths and heights, but the same number of banks.
</p>
<p>
The CRAM banks hold the configuration bits for the FPGA fabric and hard IP blocks, the BRAM
corresponds to the contents of the block ram resources.
</p>
<p>
The ordering of the data bits is in MSB first row-major order.
</p>
<h2>Organization of the CRAM</h2>
<p><a href="checkerboard.png"><img style="float:right; padding:1em; padding-top:0" height="200" src="checkerboard.png" border="0"></a></p>
<p>
The chip is organized into four quadrants. Each CRAM memory bank contains the configuration bits for one quadrant.
The address 0 is always the corner of the quadrant, i.e. in one quadrant the bit addresses increase with the tile x/y
coordinates, in another they increase with the tile x coordinate but decrease with the tile y coordinate, and so on.
</p>
<p>
For an iCE40 1k device, that has 12 x 16 tiles (not counting the io tiles), the CRAM bank 0 is the one containing the corner tile (1 1),
the CRAM bank 1 contains the corner tile (1 16), the CRAM bank 2 contains the corner tile (12 1) and the CRAM bank 3 contains the
corner tile (12 16). The entire CRAM of such a device is depicted on the right (bank 0 is in the lower left corner in blue/green).
</p>
<p>
The checkerboard pattern in the picture visualizes which bits are assoziated
with which tile. The height of the configuration block is 16 for all tile
types, but the width is different for each tile type. IO tiles have
configurations that are 18 bits wide, LOGIC tiles are 54 bits wide, and
RAM tiles are 42 bits wide. (Notice the two slightly smaller columns for the RAM tiles.)
</p>
<p>
The IO tiles on the top and bottom of the chip use a strange permutation pattern for their bits. It can be seen in the picture that
their columns are spread out horizontally. What cannot be seen in the picture is the columns also are not in order and the bit
positions are vertically permutated as well. The <tt>CramIndexConverter</tt> class in <tt>icepack.cc</tt> encapsulates the calculations
that are neccessary to convert between tile-relative bit addresses and CRAM bank-relative bit addresses.
</p>
<p>
The black pixels in the image correspond to CRAM bits that are not assoziated with any IO, LOGIC or RAM tile.
Some of them are unused, others are used by hard IPs or other global resources. The <tt>iceunpack</tt> tool reports
such bits, when set, with the "<tt>.extra_bit <i>bank x y</i></tt>" statement in the ASCII output format.
</p>
<h2>Organization of the BRAM</h2>
<p>
This part of the documentation has not been written yet.
</p>
<h2>CRC Check</h2>
<p>
The CRC is a 16 bit CRC. The (truncated) polynomial is 0x1021 (CRC-16-CCITT). The "Reset CRC" command sets
the CRC to 0xFFFF. No zero padding is performed.
</p>

321
docs/index.html Normal file
View File

@ -0,0 +1,321 @@
<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 &amp; 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 &lt;clifford@clifford.at&gt; 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>

496
docs/io_tile.html Normal file
View File

@ -0,0 +1,496 @@
<title>Project IceStorm &ndash; IO Tile Documentation</title>
<h1>Project IceStorm &ndash; IO Tile Documentation</h1>
<p>
<i><a href=".">Project IceStorm</a> aims at documenting the bitstream format of Lattice iCE40
FPGAs and providing simple tools for analyzing and creating bitstream files.
This is work in progress.</i>
</p>
<h2>Span-4 and Span-12 Wires</h2>
<p><a href="iosp.svg"><img style="float:right; padding:1em; padding-top:0" height="200" src="iosp.svg" border="0"></a></p>
<p>
The image on the right shows the span-wires of a left (or right) io cell (click to enlarge).
</p>
<p>
A left/right io cell has 16 connections named <tt>span4_vert_t_0</tt> to <tt>span4_vert_t_15</tt> on its top edge and
16 connections named <tt>span4_vert_b_0</tt> to <tt>span4_vert_b_15</tt> on its bottom edge. The nets <tt>span4_vert_t_0</tt>
to <tt>span4_vert_t_11</tt> are connected to <tt>span4_vert_b_4</tt> to <tt>span4_vert_b_15</tt>. The span-4 and span-12 wires
of the adjacent logic cell are connected to the nets <tt>span4_horz_0</tt> to <tt>span4_horz_47</tt> and <tt>span12_horz_0</tt>
to <tt>span12_horz_23</tt>.
</p>
<p>
A top/bottom io cell has 16 connections named <tt>span4_vert_l_0</tt> to <tt>span4_vert_l_15</tt> on its top edge and
16 connections named <tt>span4_vert_r_0</tt> to <tt>span4_vert_r_15</tt> on its bottom edge. The nets <tt>span4_vert_l_0</tt>
to <tt>span4_vert_l_11</tt> are connected to <tt>span4_vert_r_4</tt> to <tt>span4_vert_r_15</tt>. The span-4 and span-12 wires
of the adjacent logic cell are connected to the nets <tt>span4_vert_0</tt> to <tt>span4_vert_47</tt> and <tt>span12_vert_0</tt>
to <tt>span12_vert_23</tt>.
</p>
<p>
The vertical span4 wires of left/right io cells are connected "around the corner" to the horizontal span4 wires of the top/bottom
io cells. For example <tt>span4_vert_b_0</tt> of IO cell (0 1) is connected to <tt>span4_horz_l_0</tt> (<tt>span4_horz_r_4</tt>)
of IO cell (1 0).
</p>
<p>
Note that unlike the span-wires connection LOGIC and RAM tiles, the span-wires
connecting IO tiles to each other are not pairwised crossed out.
</p>
<h2>IO Blocks</h2>
<p>
Each IO tile contains two IO blocks. Each IO block essentially implements the <tt>SB_IO</tt>
primitive from the <a href="http://www.latticesemi.com/~/media/Documents/TechnicalBriefs/iCETechnologyLibrary.PDF">Lattice iCE Technology Library</a>.
Some inputs are shared between the two IO blocks. The following table lists how the
wires in the logic tile map to the <tt>SB_IO</tt> primitive ports:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>SB_IO Port</th><th>IO Block 0</th><th>IO Block 1</th></tr>
<tr><td>D_IN_0</td><td><tt>io_0/D_IN_0</tt></td><td><tt>io_1/D_IN_0</tt></td></tr>
<tr><td>D_IN_1</td><td><tt>io_0/D_IN_1</tt></td><td><tt>io_1/D_IN_1</tt></td></tr>
<tr><td>D_OUT_0</td><td><tt>io_0/D_OUT_0</tt></td><td><tt>io_1/D_OUT_0</tt></td></tr>
<tr><td>D_OUT_1</td><td><tt>io_0/D_OUT_1</tt></td><td><tt>io_1/D_OUT_1</tt></td></tr>
<tr><td>OUTPUT_ENABLE</td><td><tt>io_0/OUT_ENB</tt></td><td><tt>io_1/OUT_ENB</tt></td></tr>
<tr><td>CLOCK_ENABLE</td><td colspan="2"><tt>io_global/cen</tt></td></tr>
<tr><td>INPUT_CLK</td><td colspan="2"><tt>io_global/inclk</tt></td></tr>
<tr><td>OUTPUT_CLK</td><td colspan="2"><tt>io_global/outclk</tt></td></tr>
<tr><td>LATCH_INPUT_VALUE</td><td colspan="2"><tt>io_global/latch</tt></td></tr>
</table>
</p>
<p>
Like the inputs to logic cells, the inputs to IO blocks are routed to the IO block via a two-stage process. A signal
is first routed to one of 16 local tracks in the IO tile and then from the local track to the IO block.
</p>
<p>
The <tt>io_global/latch</tt> signal is shared among all IO tiles on an edge of the chip and is driven by <tt>wire_gbuf/in</tt>
from one dedicated IO tile on that edge. For the HX1K chips the tiles driving the <tt>io_global/latch</tt> signal are:
(0, 7), (13, 10), (5, 0), and (8, 17)
</p>
<p>
A logic tile sends the output of its eight logic cells to its neighbour tiles. An IO tile does the same thing with the four <tt>D_IN</tt>
signals created by its two IO blocks. The <tt>D_IN</tt> signals map to logic function indices as follows:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>Function Index</th><th>D_IN Wire</th></tr>
<tr><td>0</td><td><tt>io_0/D_IN_0</tt></td></tr>
<tr><td>1</td><td><tt>io_0/D_IN_1</tt></td></tr>
<tr><td>2</td><td><tt>io_1/D_IN_0</tt></td></tr>
<tr><td>3</td><td><tt>io_1/D_IN_1</tt></td></tr>
<tr><td>4</td><td><tt>io_0/D_IN_0</tt></td></tr>
<tr><td>5</td><td><tt>io_0/D_IN_1</tt></td></tr>
<tr><td>6</td><td><tt>io_1/D_IN_0</tt></td></tr>
<tr><td>7</td><td><tt>io_1/D_IN_1</tt></td></tr>
</table>
</p>
<p>
For example the signal <tt>io_1/D_IN_0</tt> in IO tile (0, 5) can be seen as <tt>neigh_op_lft_2</tt> and <tt>neigh_op_lft_6</tt> in LOGIC tile (1, 5).
</p>
<p>
Each IO Tile has 2 <tt>NegClk</tt> configuration bits, suggesting that the
clock signals can be inverted independently for the the two IO blocks in the
tile. However, the Lattice tools refuse to pack to IO blocks with different block
polarity into the same IO tile. In our tests we only managed to either set or clear
both NegClk bits.
</p>
<p>
Each IO block has two <tt>IoCtrl IE</tt> bits that enable the input buffers and
two <tt>IoCtrl REN</tt> bits that enable the pull up resistors. Both bits are active
low, i.e. an unused IO tile will have both IE bits set and both REN bits cleared (the
default behavior is to enable pullup resistors on all unused pins). Note that
<tt>icebox_explain.py</tt> will ignore all IO tiles that only have the two <tt>IoCtrl
IE</tt> bits set.
</p>
<p>
However, the <tt>IoCtrl IE_0/IE_1</tt> and <tt>IoCtrl REN_0/REN_1</tt> do not
necessarily configure the IO PIN that are connected to the IO block in the same tile,
and if they do the numbers (0/1) do not necessarily match. As a general rule, the pins
on the right and bottom side of the chips match up with the IO blocks and for the pins
on the left and top side the numbers must be swapped. But in some cases the IO block
and the set of <tt>IE/REN</tt> are not even located in the same tile. The following
table lists the correlation between IO blocks and <tt>IE/REN</tt> bits for the
1K chip:
</p>
<p align="center">
<table cellpadding="10">
<tr><td valign="top">
<table cellpadding="3" border>
<tr><th>IO Block</th><th>IE/REN Block</th></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 14 1</td><td align="center">0 14 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 14 0</td><td align="center">0 14 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 13 1</td><td align="center">0 13 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 13 0</td><td align="center">0 13 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 12 1</td><td align="center">0 12 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 12 0</td><td align="center">0 12 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 11 1</td><td align="center">0 11 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 11 0</td><td align="center">0 11 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 10 1</td><td align="center">0 10 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 10 0</td><td align="center">0 10 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 9 1</td><td align="center">0 9 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 9 0</td><td align="center">0 9 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 8 1</td><td align="center">0 8 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 8 0</td><td align="center">0 8 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 6 1</td><td align="center">0 6 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 6 0</td><td align="center">0 6 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 5 1</td><td align="center">0 5 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 5 0</td><td align="center">0 5 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 4 1</td><td align="center">0 4 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 4 0</td><td align="center">0 4 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 3 1</td><td align="center">0 3 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 3 0</td><td align="center">0 3 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 2 1</td><td align="center">0 2 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0 2 0</td><td align="center">0 2 1</td></tr>
</table>
</td><td valign="top">
<table cellpadding="3" border>
<tr><th>IO Block</th><th>IE/REN Block</th></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 1 0 0</td><td align="center"> 1 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 1 0 1</td><td align="center"> 1 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 2 0 0</td><td align="center"> 2 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 2 0 1</td><td align="center"> 2 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 3 0 0</td><td align="center"> 3 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 3 0 1</td><td align="center"> 3 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 4 0 0</td><td align="center"> 4 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 4 0 1</td><td align="center"> 4 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 5 0 0</td><td align="center"> 5 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 5 0 1</td><td align="center"> 5 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 6 0 1</td><td align="center"> 6 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 7 0 0</td><td align="center"> 6 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 6 0 0</td><td align="center"> 7 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 7 0 1</td><td align="center"> 7 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 8 0 0</td><td align="center"> 8 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 8 0 1</td><td align="center"> 8 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 9 0 0</td><td align="center"> 9 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 9 0 1</td><td align="center"> 9 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">10 0 0</td><td align="center">10 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">10 0 1</td><td align="center">10 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">11 0 0</td><td align="center">11 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">11 0 1</td><td align="center">11 0 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">12 0 0</td><td align="center">12 0 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">12 0 1</td><td align="center">12 0 1</td></tr>
</table>
</td><td valign="top">
<table cellpadding="3" border>
<tr><th>IO Block</th><th>IE/REN Block</th></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 1 0</td><td align="center">13 1 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 1 1</td><td align="center">13 1 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 2 0</td><td align="center">13 2 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 2 1</td><td align="center">13 2 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 3 1</td><td align="center">13 3 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 4 0</td><td align="center">13 4 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 4 1</td><td align="center">13 4 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 6 0</td><td align="center">13 6 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 6 1</td><td align="center">13 6 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 7 0</td><td align="center">13 7 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 7 1</td><td align="center">13 7 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 8 0</td><td align="center">13 8 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 8 1</td><td align="center">13 8 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 9 0</td><td align="center">13 9 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 9 1</td><td align="center">13 9 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 11 0</td><td align="center">13 10 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 11 1</td><td align="center">13 10 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 12 0</td><td align="center">13 11 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 12 1</td><td align="center">13 11 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 13 0</td><td align="center">13 13 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 13 1</td><td align="center">13 13 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 14 0</td><td align="center">13 14 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 14 1</td><td align="center">13 14 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 15 0</td><td align="center">13 15 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">13 15 1</td><td align="center">13 15 1</td></tr>
</table>
</td><td valign="top">
<table cellpadding="3" border>
<tr><th>IO Block</th><th>IE/REN Block</th></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">12 17 1</td><td align="center">12 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">12 17 0</td><td align="center">12 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">11 17 1</td><td align="center">11 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">11 17 0</td><td align="center">11 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">10 17 1</td><td align="center"> 9 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">10 17 0</td><td align="center"> 9 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 9 17 1</td><td align="center">10 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 9 17 0</td><td align="center">10 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 8 17 1</td><td align="center"> 8 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 8 17 0</td><td align="center"> 8 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 7 17 1</td><td align="center"> 7 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 7 17 0</td><td align="center"> 7 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 6 17 1</td><td align="center"> 6 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 5 17 1</td><td align="center"> 5 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 5 17 0</td><td align="center"> 5 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 4 17 1</td><td align="center"> 4 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 4 17 0</td><td align="center"> 4 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 3 17 1</td><td align="center"> 3 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 3 17 0</td><td align="center"> 3 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 2 17 1</td><td align="center"> 2 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 2 17 0</td><td align="center"> 2 17 0</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 1 17 1</td><td align="center"> 1 17 1</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center"> 1 17 0</td><td align="center"> 1 17 0</td></tr>
</table>
</table>
</p>
<p>
When an input pin pair is used as LVDS pair (IO standard
<tt>SB_LVDS_INPUT</tt>, bank 3 / left edge only), then the four bits
<tt>IoCtrl IE_0/IE_1</tt> and <tt>IoCtrl REN_0/REN_1</tt> are all set, as well
as the <tt>IoCtrl LVDS</tt> bit.
</p>
<p>
In the iCE 8k devices the <tt>IoCtrl IE</tt> bits are active high. So an unused
IO tile on an 8k chip has all bits cleared.
</p>
<h2>Global Nets</h2>
<p>
iCE40 FPGAs have 8 global nets. Each global net can be driven directly from an
IO pin. In the FPGA bitstream, routing of external signals to global nets is
not controlled by bits in the IO tile. Instead bits that do not belong to any
tile are used. In IceBox nomenclature such bits are called "extra bits".
</p>
<p>
The following table lists which pins / IO blocks may be used to drive
which global net, and what <tt>.extra</tt> statements in the IceBox ASCII file
format to represent the corresponding configuration bits:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>Glb Net</th><th>Pin<br/>(HX1K-TQ144)</th><th>IO Tile +<br/>Block #</th><th>IceBox Statement</th></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">0</td><td align="center"> 93</td><td align="center">13 8 1</td><td align="center">.extra_bit 0 330 142</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">1</td><td align="center"> 21</td><td align="center"> 0 8 1</td><td align="center">.extra_bit 0 331 142</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">2</td><td align="center">128</td><td align="center"> 7 17 0</td><td align="center">.extra_bit 1 330 143</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">3</td><td align="center"> 50</td><td align="center"> 7 0 0</td><td align="center">.extra_bit 1 331 143</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">4</td><td align="center"> 20</td><td align="center"> 0 9 0</td><td align="center">.extra_bit 1 330 142</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">5</td><td align="center"> 94</td><td align="center">13 9 0</td><td align="center">.extra_bit 1 331 142</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">6</td><td align="center"> 49</td><td align="center"> 6 0 1</td><td align="center">.extra_bit 0 330 143</td></tr>
<tr style="white-space: pre; font-family: monospace"><td align="center">7</td><td align="center">129</td><td align="center"> 6 17 1</td><td align="center">.extra_bit 0 331 143</td></tr>
</table>
</p>
<p>
Signals internal to the FPGA can also be routed to the global nets. This is done by routing the signal
to the <tt>wire_gbuf/in</tt> net on an IO tile. The same set of I/O tiles is used for this, but in this
case each of the I/O tiles corresponds to a different global net:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>Glb Net</th>
<td align="center">0</td>
<td align="center">1</td>
<td align="center">2</td>
<td align="center">3</td>
<td align="center">4</td>
<td align="center">5</td>
<td align="center">6</td>
<td align="center">7</td></tr>
<tr><th>IO Tile</th>
<td style="white-space: pre; font-family: monospace" align="center"> 7 0</td>
<td style="white-space: pre; font-family: monospace" align="center"> 7 17</td>
<td style="white-space: pre; font-family: monospace" align="center">13 9</td>
<td style="white-space: pre; font-family: monospace" align="center"> 0 9</td>
<td style="white-space: pre; font-family: monospace" align="center"> 6 17</td>
<td style="white-space: pre; font-family: monospace" align="center"> 6 0</td>
<td style="white-space: pre; font-family: monospace" align="center"> 0 8</td>
<td style="white-space: pre; font-family: monospace" align="center">13 8</td></tr>
</table>
</p>
<p><a href="colbuf.svg"><img style="float:right; padding:1em; padding-top:0" height="200" src="colbuf.svg" border="0"></a></p>
<h3>Column Buffer Control Bits</h3>
<p>
Each LOGIC, IO, and RAMB tile has 8 ColBufCtrl bits, one for each global net. In most tiles this
bits have no function, but in tiles in rows 4, 5, 12, and 13 (for RAM columns: rows 3, 5, 11, and 13) this bits
control which global nets are driven to the column of tiles below and/or above that tile (including that tile),
as illustrated in the image to the right (click to enlarge).
</p>
<p>
In 8k chips the rows 8, 9, 24, and 25 contain the column buffers. 8k RAMB and
RAMT tiles can control column buffers, so the pattern looks the same for RAM, LOGIC, and
IO columns.
</p>
<h2>Warmboot</h2>
<p>
The <tt>SB_WARMBOOT</tt> primitive in iCE40 FPGAs has three inputs and no outputs. The three inputs of that cell
are driven by the <tt>wire_gbuf/in</tt> signal from three IO tiles. In HX1K chips the tiles connected to the
<tt>SB_WARMBOOT</tt> primitive are:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>Warmboot Pin</th><th>IO Tile</th></tr>
<tr><td>BOOT</td><td><tt>12 0</tt></td></tr>
<tr><td>S0</td><td><tt>13 1</tt></td></tr>
<tr><td>S1</td><td><tt>13 2</tt></td></tr>
</table>
</p>
<h2>PLL Cores</h2>
<p>
The PLL primitives in iCE40 FPGAs are configured using the <tt>PLLCONFIG_*</tt>
bits in the IO tiles. The configuration for a single PLL cell is spread out
over many IO tiles. For example, the PLL cell in the 1K chip are configured as
follows (bits listed from LSB to MSB):
</p>
<p align="center">
<table cellpadding="10"><tr><td valign="top">
<table cellpadding="3" border>
<tr><th>IO Tile</th><th>Config Bit</th><th>SB_PLL40_* Parameter</th></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_5</tt></td><td rowspan="3">Select PLL Type:<br/>
000 = DISABLED<br/>
010 = SB_PLL40_PAD<br/>
100 = SB_PLL40_2_PAD<br/>
110 = SB_PLL40_2F_PAD<br/>
011 = SB_PLL40_CORE<br/>
111 = SB_PLL40_2F_CORE</td></tr>
<tr><td>0 5</td><td><tt>PLLCONFIG_1</tt></td></tr>
<tr><td>0 5</td><td><tt>PLLCONFIG_3</tt></td></tr>
<tr><td>0 5</td><td><tt>PLLCONFIG_5</tt></td><td rowspan="3"><tt>FEEDBACK_PATH</tt><br/>
000 = "DELAY"<br/>
001 = "SIMPLE"<br/>
010 = "PHASE_AND_DELAY"<br/>
110 = "EXTERNAL"</td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_9</tt></td></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_1</tt></td></tr>
<tr><td>0 4</td><td><tt>PLLCONFIG_4</tt></td><td rowspan="1"><tt>DELAY_ADJUSTMENT_MODE_FEEDBACK</tt><br/>
0 = "FIXED"<br/>
1 = "DYNAMIC"</td></tr>
<tr><td>0 4</td><td><tt>PLLCONFIG_9</tt></td><td rowspan="1"><tt>DELAY_ADJUSTMENT_MODE_RELATIVE</tt><br/>
0 = "FIXED"<br/>
1 = "DYNAMIC"</td></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_6</tt></td><td rowspan="2"><tt>PLLOUT_SELECT<br/>PLLOUT_SELECT_PORTA</tt><br/>
00 = "GENCLK"<br/>
01 = "GENCLK_HALF"<br/>
10 = "SHIFTREG_90deg"<br/>
11 = "SHIFTREG_0deg"</td></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_7</tt></td></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_2</tt></td><td rowspan="2"><tt>PLLOUT_SELECT_PORTB</tt><br/>
00 = "GENCLK"<br/>
01 = "GENCLK_HALF"<br/>
10 = "SHIFTREG_90deg"<br/>
11 = "SHIFTREG_0deg"</td></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_3</tt></td></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_4</tt></td><td rowspan="1"><tt>SHIFTREG_DIV_MODE</tt></td></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_8</tt></td><td rowspan="1"><tt>TEST_MODE</tt></td></tr>
</table></td><td valign="top">
<table cellpadding="3" border>
<tr><th>IO Tile</th><th>Config Bit</th><th>SB_PLL40_* Parameter</th></tr>
<tr><td>0 3</td><td><tt>PLLCONFIG_9</tt></td><td rowspan="4"><tt>FDA_FEEDBACK</tt></td></tr>
<tr><td>0 4</td><td><tt>PLLCONFIG_1</tt></td></tr>
<tr><td>0 4</td><td><tt>PLLCONFIG_2</tt></td></tr>
<tr><td>0 4</td><td><tt>PLLCONFIG_3</tt></td></tr>
<tr><td>0 5</td><td><tt>PLLCONFIG_5</tt></td><td rowspan="4"><tt>FDA_RELATIVE</tt></td></tr>
<tr><td>0 4</td><td><tt>PLLCONFIG_6</tt></td></tr>
<tr><td>0 4</td><td><tt>PLLCONFIG_7</tt></td></tr>
<tr><td>0 4</td><td><tt>PLLCONFIG_8</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_1</tt></td><td rowspan="4"><tt>DIVR</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_2</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_3</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_4</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_5</tt></td><td rowspan="7"><tt>DIVF</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_6</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_7</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_8</tt></td></tr>
<tr><td>0 1</td><td><tt>PLLCONFIG_9</tt></td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_1</tt></td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_2</tt></td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_3</tt></td><td rowspan="3"><tt>DIVQ</tt></td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_4</tt></td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_5</tt></td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_6</tt></td><td rowspan="3"><tt>FILTER_RANGE</tt></td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_7</tt></td></tr>
<tr><td>0 2</td><td><tt>PLLCONFIG_8</tt></td></tr>
</table>
</table>
</p>
<p>
The PLL inputs are routed to the PLL via the <tt>wire_gbuf/in</tt> signal from various IO tiles. The non-clock
PLL outputs are routed via otherwise unused <tt>neigh_op_*</tt> signals in fabric corners. For example in case
of the 1k chip:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>Tile</th><th>Net-Segment</th><th>SB_PLL40_* Port Name</th></tr>
<tr><td>0 1</td><td><tt>wire_gbuf/in</tt></td><td rowspan="1"><tt>REFERENCECLK</tt></td></tr>
<tr><td>0 2</td><td><tt>wire_gbuf/in</tt></td><td rowspan="1"><tt>EXTFEEDBACK</tt></td></tr>
<tr><td>0 4</td><td><tt>wire_gbuf/in</tt></td><td rowspan="8"><tt>DYNAMICDELAY</tt></td></tr>
<tr><td>0 5</td><td><tt>wire_gbuf/in</tt></td></tr>
<tr><td>0 6</td><td><tt>wire_gbuf/in</tt></td></tr>
<tr><td>0 10</td><td><tt>wire_gbuf/in</tt></td></tr>
<tr><td>0 11</td><td><tt>wire_gbuf/in</tt></td></tr>
<tr><td>0 12</td><td><tt>wire_gbuf/in</tt></td></tr>
<tr><td>0 13</td><td><tt>wire_gbuf/in</tt></td></tr>
<tr><td>0 14</td><td><tt>wire_gbuf/in</tt></td></tr>
<tr><td>1 1</td><td><tt>neigh_op_bnl_1</tt></td><td rowspan="1"><tt>LOCK</tt></td></tr>
<tr><td>1 0</td><td><tt>wire_gbuf/in</tt></td><td rowspan="1"><tt>BYPASS</tt></td></tr>
<tr><td>2 0</td><td><tt>wire_gbuf/in</tt></td><td rowspan="1"><tt>RESETB</tt></td></tr>
<tr><td>5 0</td><td><tt>wire_gbuf/in</tt></td><td rowspan="1"><tt>LATCHINPUTVALUE</tt></td></tr>
<tr><td>12 1</td><td><tt>neigh_op_bnl_1</tt></td><td rowspan="1"><tt>SDO</tt></td></tr>
<tr><td>4 0</td><td><tt>wire_gbuf/in</tt></td><td rowspan="1"><tt>SDI</tt></td></tr>
<tr><td>5 0</td><td><tt>wire_gbuf/in</tt></td><td rowspan="1"><tt>SCLK</tt></td></tr>
</table>
</p>
<p>
The PLL clock outputs are fed directly into the input path of certain IO tiles.
In case of the 1k chip the PORTA clock is fed into PIO 1 of IO Tile (6 0) and
the PORTB clock is fed into PIO 0 of IO Tile (7 0). Because of this, those two
PIOs can only be used as output Pins by the FPGA fabric when the PLL ports
are being used.
</p>

1394
docs/iosp.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 54 KiB

327
docs/logic_tile.html Normal file
View File

@ -0,0 +1,327 @@
<title>Project IceStorm &ndash; LOGIC Tile Documentation</title>
<h1>Project IceStorm &ndash; LOGIC Tile Documentation</h1>
<p>
<i><a href=".">Project IceStorm</a> aims at documenting the bitstream format of Lattice iCE40
FPGAs and providing simple tools for analyzing and creating bitstream files.
This is work in progress.</i>
</p>
<h2>Span-4 and Span-12 Wires</h2>
<p>
The <i>span-4</i> and <i>span-12</i> wires are the main interconnect resource in iCE40 FPGAs. They "span" (have a length of)
4 or 12 cells in horizontal or vertical direction.
</p>
<p>
The bits marked <tt>routing</tt> in the bitstream do enable switches (transfer gates) that can
be used to connect wire segments bidirectionally to each other in order to create larger
segments. The bits marked <tt>buffer</tt> in the bitstream enable tristate buffers that drive
the signal in one direction from one wire to another. Both types of bits exist for routing between
span-wires. See the auto generated documentation for the LOGIC Tile configuration bits for details.
</p>
<p>
Only directional tristate buffers are used to route signals between the span-wires and the logic cells.
</p>
<h3 style="clear:both">Span-4 Horizontal</h3>
<p><a href="sp4h.svg"><img style="float:right; padding:1em; padding-top:0" height="200" src="sp4h.svg" border="0"></a></p>
<p>
The image on the right shows the <i>horizontal span-4</i> wires of a logic or ram cell (click to enlarge).
</p>
<p>
On the left side of the cell there are 48 connections named <tt>sp4_h_l_0</tt> to <tt>sp4_h_l_47</tt>. The lower 36 of those
wires are connected to <tt>sp4_h_r_12</tt> to <tt>sp4_h_r_47</tt> on the right side of the cell. (IceStorm normalizes this
wire names to <tt>sp4_h_r_0</tt> to <tt>sp4_h_r_35</tt>. Note: the Lattice tools use a different normalization scheme
for this wire names.) The wires connecting the left and right horizontal span-4 ports are pairwise crossed-out.
</p>
<p>
The wires <tt>sp4_h_l_36</tt> to <tt>sp4_h_l_47</tt> terminate in the cell, so do the wires <tt>sp4_h_r_0</tt> to <tt>sp4_h_r_11</tt>.
</p>
<p>
This wires "span" 4 cells, i.e. they connect 5 cells if you count the cells on
both ends of the wire.
</p>
<p>
For example, the wire <tt>sp4_h_r_0</tt> in cell (x, y) has the following names:
</p>
<p align="center">
<table border>
<tr><th>Cell Coordinates</th><th>sp4_h_l_* wire name</th><th>sp4_h_r_* wire name</th></tr>
<tr><td>x, y</td><td><tt>-</tt></td><td><tt>sp4_h_r_0</tt></td></tr>
<tr><td>x+1, y</td><td><tt>sp4_h_l_0</tt></td><td><tt>sp4_h_r_13</tt></td></tr>
<tr><td>x+2, y</td><td><tt>sp4_h_l_13</tt></td><td><tt>sp4_h_r_24</tt></td></tr>
<tr><td>x+3, y</td><td><tt>sp4_h_l_24</tt></td><td><tt>sp4_h_r_37</tt></td></tr>
<tr><td>x+4, y</td><td><tt>sp4_h_l_37</tt></td><td><tt>-</tt></td></tr>
</table>
</p>
<h3 style="clear:both">Span-4 Vertical</h3>
<p><a href="sp4v.svg"><img style="float:right; padding:1em; padding-top:0" height="200" src="sp4v.svg" border="0"></a></p>
<p>
The image on the right shows the <i>veritical span-4</i> wires of a logic or ram cell (click to enlarge).
</p>
<p>
Similar to the horizontal span-4 wires there are 48 connections on the top (<tt>sp4_v_t_0</tt> to <tt>sp4_v_t_47</tt>) and
48 connections on the bottom (<tt>sp4_v_b_0</tt> to <tt>sp4_v_b_47</tt>). The wires <tt>sp4_v_t_0</tt> to <tt>sp4_v_t_35</tt>
are connected to <tt>sp4_v_b_12</tt> to <tt>sp4_v_b_47</tt> (with pairwise crossing out). Wire names are normalized
to <tt>sp4_v_b_12</tt> to <tt>sp4_v_b_47</tt>.
</p>
<p>
But in addition to that, each cell also has access to <tt>sp4_v_b_0</tt> to <tt>sp4_v_b_47</tt> of its right neighbour.
This are the wires <tt>sp4_r_v_b_0</tt> to <tt>sp4_r_v_b_47</tt>. So over all a single veritical span-4 wire
connects 9 cells. For example, the wire <tt>sp4_v_b_0</tt> in cell (x, y) has the following names:
</p>
<p align="center">
<table border>
<tr><th>Cell Coordinates</th><th>sp4_v_t_* wire name</th><th>sp4_v_b_* wire name</th><th>sp4_r_v_b_* wire name</th></tr>
<tr><td>x, y</td><td><tt>-</tt></td><td><tt>sp4_v_b_0</tt></td><td><tt>-</tt></td></tr>
<tr><td>x, y-1</td><td><tt>sp4_v_t_0</tt></td><td><tt>sp4_v_b_13</tt></td><td><tt>-</tt></td></tr>
<tr><td>x, y-2</td><td><tt>sp4_v_t_13</tt></td><td><tt>sp4_v_b_24</tt></td><td><tt>-</tt></td></tr>
<tr><td>x, y-3</td><td><tt>sp4_v_t_24</tt></td><td><tt>sp4_v_b_37</tt></td><td><tt>-</tt></td></tr>
<tr><td>x, y-4</td><td><tt>sp4_v_t_37</tt></td><td><tt>-</tt></td><td><tt>-</tt></td></tr>
<tr><td>x-1, y</td><td><tt>-</tt></td><td><tt>-</tt></td><td><tt>sp4_r_v_b_0</tt></td></tr>
<tr><td>x-1, y-1</td><td><tt>-</tt></td><td><tt>-</tt></td><td><tt>sp4_r_v_b_13</tt></td></tr>
<tr><td>x-1, y-2</td><td><tt>-</tt></td><td><tt>-</tt></td><td><tt>sp4_r_v_b_24</tt></td></tr>
<tr><td>x-1, y-3</td><td><tt>-</tt></td><td><tt>-</tt></td><td><tt>sp4_r_v_b_37</tt></td></tr>
</table>
</p>
<h3 style="clear:both">Span-12 Horizontal and Vertical</h3>
<p>
Similar to the span-4 wires there are also longer horizontal and vertical span-12 wires.
</p>
<p>
There are 24 connections <tt>sp12_v_t_0</tt> to <tt>sp12_v_t_23</tt> on the top of the
cell and 24 connections <tt>sp12_v_b_0</tt> to <tt>sp12_v_b_23</tt> on the bottom of the
cell. The wires <tt>sp12_v_t_0</tt> to <tt>sp12_v_t_21</tt> are connected to
<tt>sp12_v_b_2</tt> to <tt>sp12_v_b_23</tt> (with pairwise crossing out). The connections
<tt>sp12_v_b_0</tt>, <tt>sp12_v_b_1</tt>, <tt>sp12_v_t_22</tt>, and <tt>sp12_v_t_23</tt>
terminate in the cell. Wire names are normalized to <tt>sp12_v_b_2</tt> to <tt>sp12_v_b_23</tt>.
</p>
<p>
There are also 24 connections <tt>sp12_h_l_0</tt> to <tt>sp12_h_l_23</tt> on the left of the
cell and 24 connections <tt>sp12_h_r_0</tt> to <tt>sp12_h_r_23</tt> on the right of the
cell. The wires <tt>sp12_h_l_0</tt> to <tt>sp12_h_l_21</tt> are connected to
<tt>sp12_h_r_2</tt> to <tt>sp12_h_r_23</tt> (with pairwise crossing out). The connections
<tt>sp12_h_r_0</tt>, <tt>sp12_h_r_1</tt>, <tt>sp12_h_l_22</tt>, and <tt>sp12_h_l_23</tt>
terminate in the cell. Wire names are normalized to <tt>sp12_v_r_2</tt> to <tt>sp12_h_r_23</tt>.
</p>
<h2>Local Tracks</h2>
<p>
The <i>local tracks</i> are the gateway to the logic cell inputs. Signals from the span-wires
and the logic cell ouputs of the eight neighbour cells can be routed to the local tracks and
signals from the local tracks can be routed to the logic cell inputs.
</p>
<p>
Each logic tile has 32 local tracks. They are organized in 4 groups of 8 wires each:
<tt>local_g0_0</tt> to <tt>local_g3_7</tt>.
</p>
<p>
The span wires, global signals, and neighbour outputs can be routed to the local tracks. But not
every of those signals can be routed to every of the local tracks. Instead there is a different
mix of 16 signals for each local track.
</p>
<p>
The buffer driving the local track has 5 configuration bits. One enable bit and 4 bits that select
the input wire. For example for <tt>local_g0_0</tt> (copy&amp;paste from the bitstream doku):
</p>
<p align="center">
<table border=""><tbody><tr>
<th style="width:5em"><a name="B.0.14">B0[14]</a></th>
<th style="width:5em"><a name="B.1.14">B1[14]</a></th>
<th style="width:5em"><a name="B.1.15">B1[15]</a></th>
<th style="width:5em"><a name="B.1.16">B1[16]</a></th>
<th style="width:5em"><a name="B.1.17">B1[17]</a></th>
<th style="width:5em">Function</th><th style="width:15em">Source-Net</th><th style="width:15em">Destination-Net</th></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp4_r_v_b_24</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp12_h_r_8</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>neigh_op_bot_0</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp4_v_b_16</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp4_r_v_b_35</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp12_h_r_16</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>neigh_op_top_0</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp4_h_r_0</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>lutff_0/out</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp4_v_b_0</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>neigh_op_lft_0</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp4_h_r_8</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>neigh_op_bnr_0</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp4_v_b_8</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp12_h_r_0</tt></td><td><tt>local_g0_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>sp4_h_r_16</tt></td><td><tt>local_g0_0</tt></td></tr>
</tbody></table>
</p>
<p>
Then the signals on the local tracks can be routed to the input pins of the logic cells. Like before,
not every local track can be routed to every logic cell input pin. Instead there is a different mix
of 16 local track for each logic cell input. For example for <tt>lutff_0/in_0</tt>:
</p>
<p align="center">
<table border=""><tbody><tr>
<th style="width:5em"><a name="B.0.26">B0[26]</a></th>
<th style="width:5em"><a name="B.1.26">B1[26]</a></th>
<th style="width:5em"><a name="B.1.27">B1[27]</a></th>
<th style="width:5em"><a name="B.1.28">B1[28]</a></th>
<th style="width:5em"><a name="B.1.29">B1[29]</a></th>
<th style="width:5em">Function</th><th style="width:15em">Source-Net</th><th style="width:15em">Destination-Net</th></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g0_0</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g2_0</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g1_1</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g3_1</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g0_2</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g2_2</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g1_3</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g3_3</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g0_4</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g2_4</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g1_5</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g3_5</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g0_6</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g2_6</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g1_7</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">buffer</td><td><tt>local_g3_7</tt></td><td><tt>lutff_0/in_0</tt></td></tr>
</tbody></table>
</p>
<p>
The 8 global nets on the iCE40 can be routed to the local track via the <tt>glb2local_0</tt> to <tt>glb2local_3</tt>
nets using a similar two-stage process. The logic block clock-enable and set-reset inputs can be driven
directly from one of 4 global nets or from one of 4 local tracks. The logic block clock input can be driven
from any of the global nets and from a few local tracks. See the bitstream documentation for details.
</p>
<h2>Logic Block</h2>
<p>
Each logic tile has a logic block containing 8 logic cells. Each logic cell contains a 4-input LUT, a carry
unit and a flip-flop. Clock, clock enable, and set/reset inputs are shared along the 8 logic cells. So is the
bit that configures positive/negative edge for the flip flops. But the three configuration bits that specify if
the flip flop should be used, if it is set or reset by the set/reset input, and if the set/reset is synchronous
or asynchrouns exist for each logic cell individually.
</p>
<p>
Each LUT <i>i</i> has four input wires <tt>lutff_<i>i</i>/in_0</tt> to <tt>lutff_<i>i</i>/in_3</tt>. Input
<tt>lutff_<i>i</i>/in_3</tt> can be configured to be driven by the carry output of the previous logic cell,
or by <tt>carry_in_mux</tt> in case of <i>i</i>=0. Input <tt>lutff_<i>i</i>/in_2</tt> can be configured to
be driven by the output of the previous LUT for <i>i</i>&gt;0. The LUT uses its 4 input signals to
calculate <tt>lutff_<i>i</i>/out</tt>.
</p>
<p>
The carry unit calculates <tt>lutff_<i>i</i>/cout</tt> = <tt>lutff_<i>i</i>/in_1</tt> + <tt>lutff_<i>i</i>/in_2</tt> + <tt>lutff_<i>(i-1)</i>/cout</tt> &gt; 1</tt>. In case of <i>i</i>=0, <tt>carry_in_mux</tt> is used as third input. <tt>carry_in_mux</tt> can be configured to be constant 0, 1 or the <tt>lutff_7/cout</tt> signal from the logic tile below.
</p>
<p>
Part of the functionality described above is documented as part of the routing
bitstream documentation (see the buffers for <tt>luttff_</tt> inputs). The <tt>NegClk</tt>
bit switches all 8 FFs in the tile to negative edge mode. The <tt>CarryInSet</tt>
bit drives the <tt>carry_in_mux</tt> high (it defaults to low when not driven via the buffer from
<tt>carry_in</tt>).
</p>
<p>
The remaining functions of the logic cell are configured via the <tt>LC_<i>i</i></tt> bits. This
are 20 bit per logic cell. We have arbitrarily labeld those bits as follows:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>Label</th><th>LC_0</th><th>LC_1</th><th>LC_2</th><th>LC_3</th><th>LC_4</th><th>LC_5</th><th>LC_6</th><th>LC_7</th></tr>
<tr><td>LC_<i>i</i>[0]</tt></td><td>B0[36]</td><td>B2[36]</td><td>B4[36]</td><td>B6[36]</td><td>B8[36]</td><td>B10[36]</td><td>B12[36]</td><td>B14[36]</td></tr>
<tr><td>LC_<i>i</i>[1]</tt></td><td>B0[37]</td><td>B2[37]</td><td>B4[37]</td><td>B6[37]</td><td>B8[37]</td><td>B10[37]</td><td>B12[37]</td><td>B14[37]</td></tr>
<tr><td>LC_<i>i</i>[2]</tt></td><td>B0[38]</td><td>B2[38]</td><td>B4[38]</td><td>B6[38]</td><td>B8[38]</td><td>B10[38]</td><td>B12[38]</td><td>B14[38]</td></tr>
<tr><td>LC_<i>i</i>[3]</tt></td><td>B0[39]</td><td>B2[39]</td><td>B4[39]</td><td>B6[39]</td><td>B8[39]</td><td>B10[39]</td><td>B12[39]</td><td>B14[39]</td></tr>
<tr><td>LC_<i>i</i>[4]</tt></td><td>B0[40]</td><td>B2[40]</td><td>B4[40]</td><td>B6[40]</td><td>B8[40]</td><td>B10[40]</td><td>B12[40]</td><td>B14[40]</td></tr>
<tr><td>LC_<i>i</i>[5]</tt></td><td>B0[41]</td><td>B2[41]</td><td>B4[41]</td><td>B6[41]</td><td>B8[41]</td><td>B10[41]</td><td>B12[41]</td><td>B14[41]</td></tr>
<tr><td>LC_<i>i</i>[6]</tt></td><td>B0[42]</td><td>B2[42]</td><td>B4[42]</td><td>B6[42]</td><td>B8[42]</td><td>B10[42]</td><td>B12[42]</td><td>B14[42]</td></tr>
<tr><td>LC_<i>i</i>[7]</tt></td><td>B0[43]</td><td>B2[43]</td><td>B4[43]</td><td>B6[43]</td><td>B8[43]</td><td>B10[43]</td><td>B12[43]</td><td>B14[43]</td></tr>
<tr><td>LC_<i>i</i>[8]</tt></td><td>B0[44]</td><td>B2[44]</td><td>B4[44]</td><td>B6[44]</td><td>B8[44]</td><td>B10[44]</td><td>B12[44]</td><td>B14[44]</td></tr>
<tr><td>LC_<i>i</i>[9]</tt></td><td>B0[45]</td><td>B2[45]</td><td>B4[45]</td><td>B6[45]</td><td>B8[45]</td><td>B10[45]</td><td>B12[45]</td><td>B14[45]</td></tr>
<tr><td>LC_<i>i</i>[10]</tt></td><td>B1[36]</td><td>B3[36]</td><td>B5[36]</td><td>B7[36]</td><td>B9[36]</td><td>B11[36]</td><td>B13[36]</td><td>B15[36]</td></tr>
<tr><td>LC_<i>i</i>[11]</tt></td><td>B1[37]</td><td>B3[37]</td><td>B5[37]</td><td>B7[37]</td><td>B9[37]</td><td>B11[37]</td><td>B13[37]</td><td>B15[37]</td></tr>
<tr><td>LC_<i>i</i>[12]</tt></td><td>B1[38]</td><td>B3[38]</td><td>B5[38]</td><td>B7[38]</td><td>B9[38]</td><td>B11[38]</td><td>B13[38]</td><td>B15[38]</td></tr>
<tr><td>LC_<i>i</i>[13]</tt></td><td>B1[39]</td><td>B3[39]</td><td>B5[39]</td><td>B7[39]</td><td>B9[39]</td><td>B11[39]</td><td>B13[39]</td><td>B15[39]</td></tr>
<tr><td>LC_<i>i</i>[14]</tt></td><td>B1[40]</td><td>B3[40]</td><td>B5[40]</td><td>B7[40]</td><td>B9[40]</td><td>B11[40]</td><td>B13[40]</td><td>B15[40]</td></tr>
<tr><td>LC_<i>i</i>[15]</tt></td><td>B1[41]</td><td>B3[41]</td><td>B5[41]</td><td>B7[41]</td><td>B9[41]</td><td>B11[41]</td><td>B13[41]</td><td>B15[41]</td></tr>
<tr><td>LC_<i>i</i>[16]</tt></td><td>B1[42]</td><td>B3[42]</td><td>B5[42]</td><td>B7[42]</td><td>B9[42]</td><td>B11[42]</td><td>B13[42]</td><td>B15[42]</td></tr>
<tr><td>LC_<i>i</i>[17]</tt></td><td>B1[43]</td><td>B3[43]</td><td>B5[43]</td><td>B7[43]</td><td>B9[43]</td><td>B11[43]</td><td>B13[43]</td><td>B15[43]</td></tr>
<tr><td>LC_<i>i</i>[18]</tt></td><td>B1[44]</td><td>B3[44]</td><td>B5[44]</td><td>B7[44]</td><td>B9[44]</td><td>B11[44]</td><td>B13[44]</td><td>B15[44]</td></tr>
<tr><td>LC_<i>i</i>[19]</tt></td><td>B1[45]</td><td>B3[45]</td><td>B5[45]</td><td>B7[45]</td><td>B9[45]</td><td>B11[45]</td><td>B13[45]</td><td>B15[45]</td></tr>
</table>
</p>
<p>
<tt>LC_<i>i</i>[8]</tt> is the <tt>CarryEnable</tt> bit. This bit must be set if the carry logic is used.
</p>
<p>
<tt>LC_<i>i</i>[9]</tt> is the <tt>DffEnable</tt> bit. It enables the output flip-flop for the LUT.
</p>
<p>
<tt>LC_<i>i</i>[18]</tt> is the <tt>Set_NoReset</tt> bit. When this bit is set then the set/reset signal will set, not reset the flip-flop.
</p>
<p>
<tt>LC_<i>i</i>[19]</tt> is the <tt>AsyncSetReset</tt> bit. When this bit is set then the set/reset signal is asynchronous to the clock.
</p>
<p>
The LUT implements the following truth table:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>in_3</th><th>in_2</th><th>in_1</th><th>in_0</th><th>out</th></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td><tt>LC_<i>i</i>[4]</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td><tt>LC_<i>i</i>[14]</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">0</td><td><tt>LC_<i>i</i>[15]</tt></td></tr>
<tr><td align="center">0</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td><tt>LC_<i>i</i>[5]</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">0</td><td><tt>LC_<i>i</i>[6]</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td><tt>LC_<i>i</i>[16]</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">0</td><td><tt>LC_<i>i</i>[17]</tt></td></tr>
<tr><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td><tt>LC_<i>i</i>[7]</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td><tt>LC_<i>i</i>[3]</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">0</td><td align="center">1</td><td><tt>LC_<i>i</i>[13]</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">0</td><td><tt>LC_<i>i</i>[12]</tt></td></tr>
<tr><td align="center">1</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td><tt>LC_<i>i</i>[2]</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">0</td><td><tt>LC_<i>i</i>[1]</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">0</td><td align="center">1</td><td><tt>LC_<i>i</i>[11]</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">0</td><td><tt>LC_<i>i</i>[10]</tt></td></tr>
<tr><td align="center">1</td><td align="center">1</td><td align="center">1</td><td align="center">1</td><td><tt>LC_<i>i</i>[0]</tt></td></tr>
</table>
</p>
<p>
LUT inputs that are not connected to anything are driven low. The set/reset
signal is also driven low if not connected to any other driver, and the clock
enable signal is driven high when left unconnected.
</p>

95
docs/ram_tile.html Normal file
View File

@ -0,0 +1,95 @@
<title>Project IceStorm &ndash; RAM Tile Documentation</title>
<h1>Project IceStorm &ndash; RAM Tile Documentation</h1>
<p>
<i><a href=".">Project IceStorm</a> aims at documenting the bitstream format of Lattice iCE40
FPGAs and providing simple tools for analyzing and creating bitstream files.
This is work in progress.</i>
</p>
<h2>Span-4 and Span-12 Wires</h2>
<p>
Regarding the Span-4 and Span-12 Wires a RAM tile behaves exactly like a LOGIC tile. So for simple
applications that do not need the block ram resources, the RAM tiles can be handled like a LOGIC
tiles without logic cells in them.
</p>
<h2>Block RAM Resources</h2>
<p>
A pair or RAM tiles (odd and even y-coordinates) provides an interface to a block ram cell. Like with
LOGIC tiles, signals entering the RAM tile have to be routed over local tracks to the block ram
inputs. Tiles with odd y-coordinates are "bottom" RAM Tiles (RAMB Tiles), and tiles with even y-coordinates
are "top" RAM Tiles (RAMT Tiles). Each pair of RAMB/RAMT tiles implements a <tt>SB_RAM40_4K</tt> cell. The
cell ports are spread out over the two tiles as follows:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>SB_RAM40_4K</th><th>RAMB Tile</th><th>RAMT Tile</th></tr>
<tr><td><tt>RDATA[15:0]</tt></td><td><tt>RDATA[7:0]</tt></td><td><tt>RDATA[15:8]</tt></td></tr>
<tr><td><tt>RADDR[10:0]</tt></td><td><tt>-</tt></td><td><tt>RADDR[10:0]</tt></td></tr>
<tr><td><tt>WADDR[10:0]</tt></td><td><tt>WADDR[10:0]</tt></td><td><tt>-</tt></td></tr>
<tr><td><tt>MASK[15:0]</tt></td><td><tt>MASK[7:0]</tt></td><td><tt>MASK[15:8]</tt></td></tr>
<tr><td><tt>WDATA[15:0]</tt></td><td><tt>WDATA[7:0]</tt></td><td><tt>WDATA[15:8]</tt></td></tr>
<tr><td><tt>RCLKE</tt></td><td><tt>-</tt></td><td><tt>RCLKE</tt></td></tr>
<tr><td><tt>RCLK</tt></td><td><tt>-</tt></td><td><tt>RCLK</tt></td></tr>
<tr><td><tt>RE</tt></td><td><tt>-</tt></td><td><tt>RE</tt></td></tr>
<tr><td><tt>WCLKE</tt></td><td><tt>WCLKE</tt></td><td><tt>-</tt></td></tr>
<tr><td><tt>WCLK</tt></td><td><tt>WCLK</tt></td><td><tt>-</tt></td></tr>
<tr><td><tt>WE</tt></td><td><tt>WE</tt></td><td><tt>-</tt></td></tr>
</table>
</p>
<p>
The configuration bit <tt>RamConfig PowerUp</tt> in the RAMB tile enables the memory. This bit
is active-low in 1k chips, i.e. an unused RAM block has only this bit set. Note that <tt>icebox_explain.py</tt>
will ignore all RAMB tiles that only have the <tt>RamConfig PowerUp</tt> bit set.
</p>
<p>
In 8k chips the <tt>RamConfig PowerUp</tt> bit is active-high. So an unused RAM block has all bits cleared
in the 8k config bitstream.
</p>
<p>
The <tt>RamConfig CBIT_*</tt> bits in the RAMT tile configure the read/write width of the
memory. Those bits map to the <tt>SB_RAM40_4K</tt> cell parameters as follows:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>SB_RAM40_4K</th><th>RAMT Config Bit</th></tr>
<tr><td><tt>WRITE_MODE[0]</tt></td><td><tt>RamConfig CBIT_0</tt></td></tr>
<tr><td><tt>WRITE_MODE[1]</tt></td><td><tt>RamConfig CBIT_1</tt></td></tr>
<tr><td><tt>READ_MODE[0]</tt></td><td><tt>RamConfig CBIT_2</tt></td></tr>
<tr><td><tt>READ_MODE[1]</tt></td><td><tt>RamConfig CBIT_3</tt></td></tr>
</table>
</p>
<p>
The read/write mode selects the width of the read/write port:
</p>
<p align="center">
<table cellpadding="3" border>
<tr><th>MODE</th><th>DATA Width</th><th>Used WDATA/RDATA Bits</th></tr>
<tr><td>0</td><td>16</td><td>15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0</td></tr>
<tr><td>1</td><td>8</td><td>14, 12, 10, 8, 6, 4, 2, 0</td></tr>
<tr><td>2</td><td>4</td><td>13, 9, 5, 1</td></tr>
<tr><td>3</td><td>2</td><td>11, 3</td></tr>
</table>
</p>
<p>
The <tt>NegClk</tt> bit in the RAMB tile negates the polarity of the <tt>WCLK</tt> port,
and the <tt>NegClk</tt> bit in the RAMT tile negates the polarity of the <tt>RCLK</tt> port.
</p>
<p>
A logic tile sends the output of its eight logic cells to its neighbour tiles. A RAM tile does the same thing
with the <tt>RDATA</tt> outputs. Each RAMB tile exports its <tt>RDATA[7:0]</tt> outputs and each RAMT tile
exports its <tt>RDATA[15:8]</tt> outputs via this mechanism.
</p>

2076
docs/sp4h.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 89 KiB

3982
docs/sp4v.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 173 KiB

View File

@ -1,13 +1,18 @@
chipdb: chipdb-1k.txt
chipdb: chipdb-1k.txt chipdb-8k.txt
chipdb-1k.txt: icebox.py iceboxdb.py icebox_chipdb.py
python icebox_chipdb.py > chipdb-1k.new
mv chipdb-1k.new chipdb-1k.txt
chipdb-8k.txt: icebox.py iceboxdb.py icebox_chipdb.py
python icebox_chipdb.py -8 > chipdb-8k.new
mv chipdb-8k.new chipdb-8k.txt
install: chipdb
mkdir -p /usr/local/share/icebox
cp chipdb-1k.txt /usr/local/share/icebox/
cp chipdb-8k.txt /usr/local/share/icebox/
cp icebox.py /usr/local/bin/icebox.py
cp iceboxdb.py /usr/local/bin/iceboxdb.py
cp icebox_chipdb.py /usr/local/bin/icebox_chipdb
@ -27,6 +32,7 @@ uninstall:
rm -f /usr/local/bin/icebox_maps
rm -f /usr/local/bin/icebox_vlog
rm -f /usr/local/share/icebox/chipdb-1k.txt
rm -f /usr/local/share/icebox/chipdb-8k.txt
-rmdir /usr/local/share/icebox
.PHONY: install uninstall

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,33 @@ from __future__ import print_function
import icebox
import getopt, sys, re
mode_8k = False
def usage():
print("""
Usage: icebox_chipdb [options] [bitmap.txt]
-8
create chipdb for 8k device
""")
sys.exit(0)
try:
opts, args = getopt.getopt(sys.argv[1:], "8")
except:
usage()
for o, a in opts:
if o == "-8":
mode_8k = True
else:
usage()
ic = icebox.iceconfig()
ic.setup_empty_1k()
if mode_8k:
ic.setup_empty_8k()
else:
ic.setup_empty_1k()
all_tiles = set()
for x in range(ic.max_x+1):
@ -34,7 +59,7 @@ seg_to_net = dict()
net_to_segs = list()
print("""#
# IceBox Database Dump for iCE40 HX1K / LP1K
# IceBox Chip Database Dump (iCE40 %s)
#
#
# Quick File Format Reference:
@ -42,11 +67,11 @@ print("""#
#
# .device DEVICE WIDTH HEIGHT NUM_NETS
#
# declares the device type (e.g. "1k")
# declares the device type
#
#
# .pins PACKAGE
# PIN_NUM TILE_X TILE_Y PIO_NUM GLB_NUM
# PIN_NUM TILE_X TILE_Y PIO_NUM
# ...
#
# associates a package pin with an IO tile and block, and global network
@ -56,14 +81,21 @@ print("""#
# TILE_X TILE_Y GLB_NUM
# ...
#
# associates an IO tile with the global network it drives via wire_gbuf/in
# associates an IO tile with the global network can drive via fabout
#
#
# .gbufpin
# TILE_X TILE_Y PIO_NUM GLB_NUM
# ...
#
# associates an IO tile with the global network can drive via the pad
#
#
# .iolatch
# TILE_X TILE_Y
# ...
#
# specifies the IO tiles that drive the latch signal for the bank via wire_gbuf/in
# specifies the IO tiles that drive the latch signal for the bank via fabout
#
#
# .ieren
@ -99,6 +131,13 @@ print("""#
# declares non-routing configuration bits of IO/LOGIC/RAM tiles
#
#
# .extra_cell X Y <cell-type>
# KEY MULTI-FIELD-VALUE
# ....
#
# declares a special-purpose cell that is not part of the FPGA fabric
#
#
# .extra_bits
# FUNCTION BANK_NUM ADDR_X ADDR_Y
# ...
@ -129,27 +168,32 @@ print("""#
#
# declares a routing switch in the specified tile
#
""")
""" % ic.device)
all_group_segments = ic.group_segments(all_tiles, connect_gb=False)
print(".device 1k %d %d %d" % (ic.max_x+1, ic.max_y+1, len(all_group_segments)))
print(".device %s %d %d %d" % (ic.device, ic.max_x+1, ic.max_y+1, len(all_group_segments)))
print()
print(".pins tq144")
pio_to_padin = dict()
for padin, pio in enumerate(ic.padin_pio_db()):
pio_to_padin[pio] = padin
for entry in sorted(ic.pinloc_db()):
pio = (entry[1], entry[2], entry[3])
print("%d %d %d %d %d" % tuple(entry + [pio_to_padin[pio] if pio in pio_to_padin else -1]))
print()
for key in icebox.pinloc_db.keys():
key_dev, key_package = key.split("-")
if key_dev == ic.device:
print(".pins %s" % (key_package))
for entry in sorted(icebox.pinloc_db[key]):
print("%s %d %d %d" % entry)
print()
print(".gbufin")
for entry in sorted(ic.gbufin_db()):
print(" ".join(["%d" % k for k in entry]))
print()
print(".gbufpin")
for padin, pio in enumerate(ic.padin_pio_db()):
entry = pio + (padin,)
print(" ".join(["%d" % k for k in entry]))
print()
print(".iolatch")
for entry in sorted(ic.iolatch_db()):
print(" ".join(["%d" % k for k in entry]))
@ -208,6 +252,19 @@ print_tile_nonrouting_bits("io", ic.io_tiles.keys()[0])
print_tile_nonrouting_bits("ramb", ic.ramb_tiles.keys()[0])
print_tile_nonrouting_bits("ramt", ic.ramt_tiles.keys()[0])
print(".extra_cell 0 0 WARMBOOT")
for key in sorted(icebox.warmbootinfo_db[ic.device]):
print("%s %s" % (key, " ".join([str(k) for k in icebox.warmbootinfo_db[ic.device][key]])))
print()
for pllid in ic.pll_list():
pllinfo = icebox.pllinfo_db[pllid]
print(".extra_cell %d %d PLL" % pllinfo["LOC"])
for key in sorted(pllinfo):
if key != "LOC":
print("%s %s" % (key, " ".join([str(k) for k in pllinfo[key]])))
print()
print(".extra_bits")
extra_bits = dict()
for idx in sorted(ic.extra_bits_db()):

View File

@ -20,6 +20,7 @@ from __future__ import print_function
import icebox
import sys
import re
print("Reading file '%s'.." % sys.argv[1])
ic1 = icebox.iceconfig()
@ -38,7 +39,29 @@ def format_bits(line_nr, this_line, other_line):
else:
text += "%8s" % ""
return text
def explained_bits(db, tile):
bits = set()
mapped_bits = set()
for k, line in enumerate(tile):
for i in range(len(line)):
if line[i] == "1":
bits.add("B%d[%d]" % (k, i))
else:
bits.add("!B%d[%d]" % (k, i))
text = set()
for entry in db:
if re.match(r"LC_", entry[1]):
continue
if entry[1] in ("routing", "buffer"):
continue
match = True
for bit in entry[0]:
if not bit in bits:
match = False
if match:
text.add("<%s> %s" % (",".join(entry[0]), " ".join(entry[1:])))
return text
def diff_tiles(stmt, tiles1, tiles2):
for i in sorted(set(tiles1.keys() + tiles2.keys())):
@ -46,11 +69,13 @@ def diff_tiles(stmt, tiles1, tiles2):
print("+ %s %d %d" % (stmt, i[0], i[1]))
for line in tiles2[i]:
print("+ %s" % line)
print()
continue
if not i in tiles2:
print("- %s %d %d" % (stmt, i[0], i[1]))
for line in tiles1[i]:
print("- %s" % line)
print()
continue
if tiles1[i] == tiles2[i]:
continue
@ -61,6 +86,15 @@ def diff_tiles(stmt, tiles1, tiles2):
else:
print("- %s%s" % (tiles1[i][c], format_bits(c, tiles1[i][c], tiles2[i][c])))
print("+ %s%s" % (tiles2[i][c], format_bits(c, tiles2[i][c], tiles1[i][c])))
bits1 = explained_bits(ic1.tile_db(i[0], i[1]), tiles1[i])
bits2 = explained_bits(ic2.tile_db(i[0], i[1]), tiles2[i])
for bit in sorted(bits1):
if bit not in bits2:
print("- %s" % bit)
for bit in sorted(bits2):
if bit not in bits1:
print("+ %s" % bit)
print()
diff_tiles(".io_tile", ic1.io_tiles, ic2.io_tiles)
diff_tiles(".logic_tile", ic1.logic_tiles, ic2.logic_tiles)

View File

@ -275,7 +275,7 @@ nets are connected with nets from cells in its neighbourhood.</p>""")
cat = (99, "Unsorted")
if netname.startswith("glb_netwk_"): cat = (10, "Global Networks")
if netname.startswith("glb2local_"): cat = (10, "Global Networks")
if netname.startswith("wire_gbuf"): cat = (10, "Global Networks")
if netname.startswith("fabout"): cat = (10, "Global Networks")
if netname.startswith("local_"): cat = (20, "Local Tracks")
if netname.startswith("carry_in"): cat = (25, "Logic Block")
if netname.startswith("io_"): cat = (25, "IO Block")

View File

@ -96,7 +96,10 @@ for o, a in opts:
if not re.match(r"[a-zA-Z_][a-zA-Z0-9_]*$", p):
p = "\\%s " % p
unmatched_ports.add(p)
pinloc = tuple([int(s) for s in line[2:]])
if len(line) > 3:
pinloc = tuple([int(s) for s in line[2:]])
else:
pinloc = (line[2],)
pcf_data[pinloc] = p
elif o == "-R":
check_ieren = True
@ -135,6 +138,8 @@ iocells_special = set()
iocells_type = dict()
iocells_negclk = set()
iocells_inbufs = set()
iocells_skip = set()
iocells_pll = set()
def is_interconn(netname):
if netname.startswith("sp4_"): return True
@ -146,6 +151,36 @@ def is_interconn(netname):
if netname.startswith("local_"): return True
return False
pll_config_bitidx = dict()
pll_gbuf = dict()
for entry in icebox.iotile_l_db:
if entry[1] == "PLL":
match = re.match(r"B(\d+)\[(\d+)\]", entry[0][0]);
assert match
pll_config_bitidx[entry[2]] = (int(match.group(1)), int(match.group(2)))
def get_pll_bit(pllinfo, name):
bit = pllinfo[name]
assert bit[2] in pll_config_bitidx
return ic.tile(bit[0], bit[1])[pll_config_bitidx[bit[2]][0]][pll_config_bitidx[bit[2]][1]]
def get_pll_bits(pllinfo, name, n):
return "".join([get_pll_bit(pllinfo, "%s_%d" % (name, i)) for i in range(n-1, -1, -1)])
for pllid in ic.pll_list():
pllinfo = icebox.pllinfo_db[pllid]
plltype = get_pll_bits(pllinfo, "PLLTYPE", 3)
if plltype != "000":
if plltype in ["010", "100", "110"]:
iocells_special.add(pllinfo["PLLOUT_A"])
else:
iocells_skip.add(pllinfo["PLLOUT_A"])
iocells_pll.add(pllinfo["PLLOUT_A"])
if plltype not in ["010", "011"]:
iocells_skip.add(pllinfo["PLLOUT_B"])
iocells_pll.add(pllinfo["PLLOUT_B"])
extra_connections = list()
extra_segments = list()
@ -154,11 +189,15 @@ for bit in ic.extra_bits:
if entry[0] == "padin_glb_netwk":
glb = int(entry[1])
pin_entry = ic.padin_pio_db()[glb]
iocells.add((pin_entry[0], pin_entry[1], pin_entry[2]))
iocells_in.add((pin_entry[0], pin_entry[1], pin_entry[2]))
s1 = (pin_entry[0], pin_entry[1], "io_%d/PAD" % pin_entry[2])
s2 = (pin_entry[0], pin_entry[1], "wire_gbuf/padin_%d" % pin_entry[2])
extra_connections.append((s1, s2))
if pin_entry in iocells_pll:
pll_gbuf[pin_entry] = (pin_entry[0], pin_entry[1], "padin_%d" % pin_entry[2])
extra_segments.append(pll_gbuf[pin_entry])
else:
iocells.add((pin_entry[0], pin_entry[1], pin_entry[2]))
iocells_in.add((pin_entry[0], pin_entry[1], pin_entry[2]))
s1 = (pin_entry[0], pin_entry[1], "io_%d/PAD" % pin_entry[2])
s2 = (pin_entry[0], pin_entry[1], "padin_%d" % pin_entry[2])
extra_connections.append((s1, s2))
for idx, tile in ic.io_tiles.items():
tc = icebox.tileconfig(tile)
@ -187,6 +226,8 @@ for segs in sorted(ic.group_segments()):
match = re.match("io_(\d+)/D_(IN|OUT)_(\d+)", seg[2])
if match:
cell = (seg[0], seg[1], int(match.group(1)))
if cell in iocells_skip:
continue
iocells.add(cell)
if match.group(2) == "IN":
if check_ieren:
@ -231,7 +272,7 @@ for segs in sorted(ic.group_segments(extra_connections=extra_connections, extra_
p = "io_%d_%d_%d" % idx
net_segs.add(p)
if lookup_pins or pcf_data:
for entry in icebox.pinloc_db:
for entry in ic.pinloc_db():
if idx[0] == entry[1] and idx[1] == entry[2] and idx[2] == entry[3]:
if (entry[0],) in pcf_data:
p = pcf_data[(entry[0],)]
@ -310,6 +351,167 @@ def seg_to_net(seg, default=None):
text_wires.append("")
return seg2net[seg]
wb_boot = seg_to_net(icebox.warmbootinfo_db[ic.device]["BOOT"], "")
wb_s0 = seg_to_net(icebox.warmbootinfo_db[ic.device]["S0"], "")
wb_s1 = seg_to_net(icebox.warmbootinfo_db[ic.device]["S1"], "")
if wb_boot != "" or wb_s0 != "" or wb_s1 != "":
text_func.append("SB_WARMBOOT (")
text_func.append(" .BOOT(%s)," % wb_boot)
text_func.append(" .S0(%s)," % wb_s0)
text_func.append(" .S1(%s)," % wb_s1)
text_func.append(");")
text_func.append("")
def get_pll_feedback_path(pllinfo):
v = get_pll_bits(pllinfo, "FEEDBACK_PATH", 3)
if v == "000": return "DELAY"
if v == "001": return "SIMPLE"
if v == "010": return "PHASE_AND_DELAY"
if v == "110": return "EXTERNAL"
assert False
def get_pll_adjmode(pllinfo, name):
v = get_pll_bit(pllinfo, name)
if v == "0": return "FIXED"
if v == "1": return "DYNAMIC"
assert False
def get_pll_outsel(pllinfo, name):
v = get_pll_bits(pllinfo, name, 2)
if v == "00": return "GENCLK"
if v == "01": return "GENCLK_HALF"
if v == "10": return "SHIFTREG_90deg"
if v == "11": return "SHIFTREG_0deg"
assert False
for pllid in ic.pll_list():
pllinfo = icebox.pllinfo_db[pllid]
plltype = get_pll_bits(pllinfo, "PLLTYPE", 3)
if plltype == "000":
continue
if not strip_comments:
text_func.append("// plltype = %s" % plltype)
for ti in sorted(ic.io_tiles):
for bit in sorted(pll_config_bitidx):
if ic.io_tiles[ti][pll_config_bitidx[bit][0]][pll_config_bitidx[bit][1]] == "1":
resolved_bitname = ""
for bitname in pllinfo:
if pllinfo[bitname] == (ti[0], ti[1], bit):
resolved_bitname = " " + bitname
text_func.append("// (%2d, %2d, \"%s\")%s" % (ti[0], ti[1], bit, resolved_bitname))
if plltype in ["010", "100", "110"]:
if plltype == "010": text_func.append("SB_PLL40_PAD #(")
if plltype == "100": text_func.append("SB_PLL40_2_PAD #(")
if plltype == "110": text_func.append("SB_PLL40_2F_PAD #(")
text_func.append(" .FEEDBACK_PATH(\"%s\")," % get_pll_feedback_path(pllinfo))
text_func.append(" .DELAY_ADJUSTMENT_MODE_FEEDBACK(\"%s\")," % get_pll_adjmode(pllinfo, "DELAY_ADJMODE_FB"))
text_func.append(" .DELAY_ADJUSTMENT_MODE_RELATIVE(\"%s\")," % get_pll_adjmode(pllinfo, "DELAY_ADJMODE_REL"))
if plltype == "010":
text_func.append(" .PLLOUT_SELECT(\"%s\")," % get_pll_outsel(pllinfo, "PLLOUT_SELECT_A"))
else:
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"))
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))
text_func.append(" .DIVF(7'b%s)," % get_pll_bits(pllinfo, "DIVF", 7))
text_func.append(" .DIVQ(3'b%s)," % get_pll_bits(pllinfo, "DIVQ", 3))
text_func.append(" .FILTER_RANGE(3'b%s)," % get_pll_bits(pllinfo, "FILTER_RANGE", 3))
if plltype == "010":
text_func.append(" .ENABLE_ICEGATE(1'b0),")
else:
text_func.append(" .ENABLE_ICEGATE_PORTA(1'b0),")
text_func.append(" .ENABLE_ICEGATE_PORTB(1'b0),")
text_func.append(" .TEST_MODE(1'b%s)" % get_pll_bit(pllinfo, "TEST_MODE"))
text_func.append(") PLL_%d_%d (" % pllinfo["LOC"])
if plltype == "010":
pad_segment = (pllinfo["PLLOUT_A"][0], pllinfo["PLLOUT_A"][1], "io_%d/PAD" % pllinfo["PLLOUT_A"][2])
text_func.append(" .PACKAGEPIN(%s)," % seg_to_net(pad_segment))
del seg2net[pad_segment]
text_func.append(" .PLLOUTCORE(%s)," % seg_to_net(pad_segment))
if pllinfo["PLLOUT_A"] in pll_gbuf:
text_func.append(" .PLLOUTGLOBAL(%s)," % seg_to_net(pll_gbuf[pllinfo["PLLOUT_A"]]))
else:
pad_segment = (pllinfo["PLLOUT_A"][0], pllinfo["PLLOUT_A"][1], "io_%d/PAD" % pllinfo["PLLOUT_A"][2])
text_func.append(" .PACKAGEPIN(%s)," % seg_to_net(pad_segment))
del seg2net[pad_segment]
text_func.append(" .PLLOUTCOREA(%s)," % seg_to_net(pad_segment))
if pllinfo["PLLOUT_A"] in pll_gbuf:
text_func.append(" .PLLOUTGLOBALA(%s)," % seg_to_net(pll_gbuf[pllinfo["PLLOUT_A"]]))
pad_segment = (pllinfo["PLLOUT_B"][0], pllinfo["PLLOUT_B"][1], "io_%d/D_IN_0" % pllinfo["PLLOUT_B"][2])
text_func.append(" .PLLOUTCOREB(%s)," % seg_to_net(pad_segment))
if pllinfo["PLLOUT_B"] in pll_gbuf:
text_func.append(" .PLLOUTGLOBALB(%s)," % seg_to_net(pll_gbuf[pllinfo["PLLOUT_B"]]))
text_func.append(" .EXTFEEDBACK(%s)," % seg_to_net(pllinfo["EXTFEEDBACK"], "1'b0"))
text_func.append(" .DYNAMICDELAY({%s})," % ", ".join([seg_to_net(pllinfo["DYNAMICDELAY_%d" % i], "1'b0") for i in range(7, -1, -1)]))
text_func.append(" .LOCK(%s)," % seg_to_net(pllinfo["LOCK"]))
text_func.append(" .BYPASS(%s)," % seg_to_net(pllinfo["BYPASS"], "1'b0"))
text_func.append(" .RESETB(%s)," % seg_to_net(pllinfo["RESETB"], "1'b0"))
text_func.append(" .LATCHINPUTVALUE(%s)," % seg_to_net(pllinfo["LATCHINPUTVALUE"], "1'b0"))
text_func.append(" .SDO(%s)," % seg_to_net(pllinfo["SDO"]))
text_func.append(" .SDI(%s)," % seg_to_net(pllinfo["SDI"], "1'b0"))
text_func.append(" .SCLK(%s)" % seg_to_net(pllinfo["SCLK"], "1'b0"))
text_func.append(");")
if plltype in ["011", "111"]:
if plltype == "011": text_func.append("SB_PLL40_CORE #(")
if plltype == "111": text_func.append("SB_PLL40_2F_CORE #(")
text_func.append(" .FEEDBACK_PATH(\"%s\")," % get_pll_feedback_path(pllinfo))
text_func.append(" .DELAY_ADJUSTMENT_MODE_FEEDBACK(\"%s\")," % get_pll_adjmode(pllinfo, "DELAY_ADJMODE_FB"))
text_func.append(" .DELAY_ADJUSTMENT_MODE_RELATIVE(\"%s\")," % get_pll_adjmode(pllinfo, "DELAY_ADJMODE_REL"))
if plltype == "011":
text_func.append(" .PLLOUT_SELECT(\"%s\")," % get_pll_outsel(pllinfo, "PLLOUT_SELECT_A"))
else:
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"))
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))
text_func.append(" .DIVF(7'b%s)," % get_pll_bits(pllinfo, "DIVF", 7))
text_func.append(" .DIVQ(3'b%s)," % get_pll_bits(pllinfo, "DIVQ", 3))
text_func.append(" .FILTER_RANGE(3'b%s)," % get_pll_bits(pllinfo, "FILTER_RANGE", 3))
if plltype == "011":
text_func.append(" .ENABLE_ICEGATE(1'b0),")
else:
text_func.append(" .ENABLE_ICEGATE_PORTA(1'b0),")
text_func.append(" .ENABLE_ICEGATE_PORTB(1'b0),")
text_func.append(" .TEST_MODE(1'b%s)" % get_pll_bit(pllinfo, "TEST_MODE"))
text_func.append(") PLL_%d_%d (" % pllinfo["LOC"])
text_func.append(" .REFERENCECLK(%s)," % seg_to_net(pllinfo["REFERENCECLK"], "1'b0"))
if plltype == "011":
pad_segment = (pllinfo["PLLOUT_A"][0], pllinfo["PLLOUT_A"][1], "io_%d/D_IN_0" % pllinfo["PLLOUT_A"][2])
text_func.append(" .PLLOUTCORE(%s)," % seg_to_net(pad_segment))
if pllinfo["PLLOUT_A"] in pll_gbuf:
text_func.append(" .PLLOUTGLOBAL(%s)," % seg_to_net(pll_gbuf[pllinfo["PLLOUT_A"]]))
else:
pad_segment = (pllinfo["PLLOUT_A"][0], pllinfo["PLLOUT_A"][1], "io_%d/D_IN_0" % pllinfo["PLLOUT_A"][2])
text_func.append(" .PLLOUTCOREA(%s)," % seg_to_net(pad_segment))
if pllinfo["PLLOUT_A"] in pll_gbuf:
text_func.append(" .PLLOUTGLOBALA(%s)," % seg_to_net(pll_gbuf[pllinfo["PLLOUT_A"]]))
pad_segment = (pllinfo["PLLOUT_B"][0], pllinfo["PLLOUT_B"][1], "io_%d/D_IN_0" % pllinfo["PLLOUT_B"][2])
text_func.append(" .PLLOUTCOREB(%s)," % seg_to_net(pad_segment))
if pllinfo["PLLOUT_B"] in pll_gbuf:
text_func.append(" .PLLOUTGLOBALB(%s)," % seg_to_net(pll_gbuf[pllinfo["PLLOUT_B"]]))
text_func.append(" .EXTFEEDBACK(%s)," % seg_to_net(pllinfo["EXTFEEDBACK"], "1'b0"))
text_func.append(" .DYNAMICDELAY({%s})," % ", ".join([seg_to_net(pllinfo["DYNAMICDELAY_%d" % i], "1'b0") for i in range(7, -1, -1)]))
text_func.append(" .LOCK(%s)," % seg_to_net(pllinfo["LOCK"]))
text_func.append(" .BYPASS(%s)," % seg_to_net(pllinfo["BYPASS"], "1'b0"))
text_func.append(" .RESETB(%s)," % seg_to_net(pllinfo["RESETB"], "1'b0"))
text_func.append(" .LATCHINPUTVALUE(%s)," % seg_to_net(pllinfo["LATCHINPUTVALUE"], "1'b0"))
text_func.append(" .SDO(%s)," % seg_to_net(pllinfo["SDO"]))
text_func.append(" .SDI(%s)," % seg_to_net(pllinfo["SDI"], "1'b0"))
text_func.append(" .SCLK(%s)" % seg_to_net(pllinfo["SCLK"], "1'b0"))
text_func.append(");")
text_func.append("")
for cell in iocells:
if cell in iocells_type:
net_pad = seg_to_net((cell[0], cell[1], "io_%d/PAD" % cell[2]))
@ -438,6 +640,65 @@ for cell in iocells:
for p in unmatched_ports:
text_ports.append("input %s" % p)
ram_config_bitidx = dict()
for tile in ic.ramb_tiles:
for entry in ic.tile_db(tile[0], tile[1]):
if entry[1] == "RamConfig":
assert entry[2] not in ram_config_bitidx
ram_config_bitidx[entry[2]] = ('B', entry[0])
for entry in ic.tile_db(tile[0], tile[1]+1):
if entry[1] == "RamConfig":
assert entry[2] not in ram_config_bitidx
ram_config_bitidx[entry[2]] = ('T', entry[0])
break
for tile in ic.ramb_tiles:
ramb_config = icebox.tileconfig(ic.tile(tile[0], tile[1]))
ramt_config = icebox.tileconfig(ic.tile(tile[0], tile[1]+1))
def get_ram_config(name):
assert name in ram_config_bitidx
if ram_config_bitidx[name][0] == 'B':
return ramb_config.match(ram_config_bitidx[name][1])
elif ram_config_bitidx[name][0] == 'T':
return ramt_config.match(ram_config_bitidx[name][1])
else:
assert False
def get_ram_wire(name, msb, lsb):
wire_bits = []
for i in range(msb, lsb-1, -1):
if msb != lsb:
n = "ram/%s_%d" % (name, i)
else:
n = "ram/" + name
b = seg_to_net((tile[0], tile[1], n), "1'b0")
b = seg_to_net((tile[0], tile[1]+1, n), b)
if len(wire_bits) != 0 or b != "1'b0" or i == lsb:
wire_bits.append(b)
if len(wire_bits) > 1:
return "{%s}" % ", ".join(wire_bits)
return wire_bits[0]
if get_ram_config('PowerUp') == (ic.device == "8k"):
if not strip_comments:
text_func.append("// RAM TILE %d %d" % tile)
text_func.append("SB_RAM40_4K #(");
text_func.append(" .READ_MODE(%d)," % ((1 if get_ram_config('CBIT_2') else 0) + (2 if get_ram_config('CBIT_3') else 0)));
text_func.append(" .WRITE_MODE(%d)" % ((1 if get_ram_config('CBIT_0') else 0) + (2 if get_ram_config('CBIT_1') else 0)));
text_func.append(") ram40_%d_%d (" % tile);
text_func.append(" .WADDR(%s)," % get_ram_wire('WADDR', 10, 0))
text_func.append(" .RADDR(%s)," % get_ram_wire('RADDR', 10, 0))
text_func.append(" .MASK(%s)," % get_ram_wire('MASK', 15, 0))
text_func.append(" .WDATA(%s)," % get_ram_wire('WDATA', 15, 0))
text_func.append(" .RDATA(%s)," % get_ram_wire('RDATA', 15, 0))
text_func.append(" .WE(%s)," % get_ram_wire('WE', 0, 0))
text_func.append(" .WCLKE(%s)," % get_ram_wire('WCLKE', 0, 0))
text_func.append(" .WCLK(%s)," % get_ram_wire('WCLK', 0, 0))
text_func.append(" .RE(%s)," % get_ram_wire('RE', 0, 0))
text_func.append(" .RCLKE(%s)," % get_ram_wire('RCLKE', 0, 0))
text_func.append(" .RCLK(%s)" % get_ram_wire('RCLK', 0, 0))
text_func.append(");")
text_func.append("")
wire_to_reg = set()
lut_assigns = list()
const_assigns = list()

File diff suppressed because it is too large Load Diff

97
icefuzz/Makefile Normal file
View File

@ -0,0 +1,97 @@
export LC_ALL=C
TESTS =
TESTS += binop
TESTS += pin2pin
TESTS += mesh
TESTS += fanout
TESTS += logic
TESTS += cluster
TESTS += iopack
TESTS += io
TESTS += gbio
TESTS += gbio2
TESTS += prim
TESTS += fflogic
TESTS += ram40
TESTS += pll
EIGTHK = _8k
database: bitdata_io.txt bitdata_logic.txt bitdata_ramb$(EIGTHK).txt bitdata_ramt$(EIGTHK).txt
ifeq ($(EIGTHK),_8k)
cp cached_ramb.txt bitdata_ramb.txt
cp cached_ramt.txt bitdata_ramt.txt
else
cp cached_ramb_8k.txt bitdata_ramb_8k.txt
cp cached_ramt_8k.txt bitdata_ramt_8k.txt
endif
python database.py
python export.py
diff -U0 cached_io.txt bitdata_io.txt || cp -v bitdata_io.txt cached_io.txt
diff -U0 cached_logic.txt bitdata_logic.txt || cp -v bitdata_logic.txt cached_logic.txt
diff -U0 cached_ramb.txt bitdata_ramb.txt || cp -v bitdata_ramb.txt cached_ramb.txt
diff -U0 cached_ramt.txt bitdata_ramt.txt || cp -v bitdata_ramt.txt cached_ramt.txt
diff -U0 cached_ramb_8k.txt bitdata_ramb_8k.txt || cp -v bitdata_ramb_8k.txt cached_ramb_8k.txt
diff -U0 cached_ramt_8k.txt bitdata_ramt_8k.txt || cp -v bitdata_ramt_8k.txt cached_ramt_8k.txt
data_cached.txt: cached_io.txt cached_logic.txt cached_ramb$(EIGTHK).txt cached_ramt$(EIGTHK).txt
gawk '{ print "io", $$0; }' cached_io.txt > data_cached.new
gawk '{ print "logic", $$0; }' cached_logic.txt >> data_cached.new
gawk '{ print "ramb$(EIGTHK)", $$0; }' cached_ramb$(EIGTHK).txt >> data_cached.new
gawk '{ print "ramt$(EIGTHK)", $$0; }' cached_ramt$(EIGTHK).txt >> data_cached.new
mv data_cached.new data_cached.txt
bitdata_io.txt: data_cached.txt $(addprefix data_,$(addsuffix .txt,$(TESTS)))
grep ^io $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
bitdata_logic.txt: data_cached.txt $(addprefix data_,$(addsuffix .txt,$(TESTS)))
grep ^logic $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
bitdata_ramb$(EIGTHK).txt: data_cached.txt $(addprefix data_,$(addsuffix .txt,$(TESTS)))
grep ^ramb$(EIGTHK) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
bitdata_ramt$(EIGTHK).txt: data_cached.txt $(addprefix data_,$(addsuffix .txt,$(TESTS)))
grep ^ramt$(EIGTHK) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
datafiles: $(addprefix data_,$(addsuffix .txt,$(TESTS)))
../icepack/icepack:
$(MAKE) -C ../icepack
define data_template
data_$(1).txt: make_$(1).py ../icepack/icepack
ifeq ($(EIGTHK),_8k)
ICE8KPINS=1 python make_$(1).py
ICEDEV=hx8k-ct256 $$(MAKE) -C work_$(1)
python extract.py -8 work_$(1)/*.glb > $$@
else
python make_$(1).py
$$(MAKE) -C work_$(1)
python extract.py work_$(1)/*.glb > $$@
endif
endef
$(foreach test,$(TESTS),$(eval $(call data_template,$(test))))
%.ok: %.bin
bash check.sh $<
check: $(addsuffix .ok,$(basename $(wildcard work_binop/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_pin2pin/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_mesh/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_fanout/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_logic/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_cluster/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_iopack/*.bin)))
check: $(addsuffix .ok,$(basename $(wildcard work_pll/*.bin)))
clean:
rm -rf work_*
rm -rf data_*.txt
rm -rf bitdata_*.txt
rm -rf database_*.txt
.PHONY: database datafiles check clean

2270
icefuzz/cached_io.txt Normal file

File diff suppressed because it is too large Load Diff

4140
icefuzz/cached_logic.txt Normal file

File diff suppressed because it is too large Load Diff

3586
icefuzz/cached_ramb.txt Normal file

File diff suppressed because it is too large Load Diff

3575
icefuzz/cached_ramb_8k.txt Normal file

File diff suppressed because it is too large Load Diff

3586
icefuzz/cached_ramt.txt Normal file

File diff suppressed because it is too large Load Diff

3597
icefuzz/cached_ramt_8k.txt Normal file

File diff suppressed because it is too large Load Diff

50
icefuzz/check.sh Normal file
View File

@ -0,0 +1,50 @@
#!/bin/bash
set -ex
for id; do
id=${id%.bin}
icebox_vlog_opts="-Sa"
if test -f $id.pcf; then icebox_vlog_opts="$icebox_vlog_opts -p $id.pcf"; fi
if test -f $id.psb; then icebox_vlog_opts="$icebox_vlog_opts -P $id.psb"; fi
../icepack/iceunpack $id.bin $id.txt
../icebox/icebox_vlog.py $icebox_vlog_opts $id.txt > $id.ve
yosys -p "
read_verilog $id.v
read_verilog $id.ve
read_verilog -lib +/ice40/cells_sim.v
rename top gold
rename chip gate
proc
splitnets -ports
clean -purge
## Variant 1 ##
# miter -equiv -flatten gold gate equiv
# tee -q synth -top equiv
# sat -verify -prove trigger 0 -show-ports equiv
## Variant 2 ##
# miter -equiv -flatten -ignore_gold_x -make_outcmp -make_outputs gold gate equiv
# hierarchy -top equiv
# sat -max_undef -prove trigger 0 -show-ports equiv
## Variant 3 ##
equiv_make gold gate equiv
hierarchy -top equiv
opt -share_all
equiv_simple
equiv_induct
equiv_status -assert
"
touch $id.ok
done

28
icefuzz/convert_ram8k.py Normal file
View File

@ -0,0 +1,28 @@
#!/usr/bin/python
# convert 1k ramb/ramt to 8k ramb/ramt and vice versa
subst_rules = [
["/RE", "/WE" ],
["/RCLK", "/WCLK" ],
["/RCLKE", "/WCLKE"],
["DATA_8", "DATA_7"],
["DATA_9", "DATA_6"],
["DATA_10", "DATA_5"],
["DATA_11", "DATA_4"],
["DATA_12", "DATA_3"],
["DATA_13", "DATA_2"],
["DATA_14", "DATA_1"],
["DATA_15", "DATA_0"],
]
import fileinput
for line in fileinput.input():
line = line.strip()
for r in subst_rules:
if line.endswith(r[0]):
line = line[:-len(r[0])] + r[1]
break
if line.endswith(r[1]):
line = line[:-len(r[1])] + r[0]
break
print(line)

140
icefuzz/database.py Normal file
View File

@ -0,0 +1,140 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
import re, sys, os
def cmp_bits(a, b):
if a[0] == "!": a = a[1:]
if b[0] == "!": b = b[1:]
a = re.sub(r"\d+", lambda m: "%02d" % int(m.group(0)), a)
b = re.sub(r"\d+", lambda m: "%02d" % int(m.group(0)), b)
return cmp(a, b)
def read_database(filename, tile_type):
raw_db = list()
route_to_buffer = set()
add_mux_bits = dict()
with open(filename, "r") as f:
for line in f:
line = line.strip()
m = re.match(r"\s*\((\d+)\s+(\d+)\)\s+(.*)", line)
assert m
bit = "B%d[%d]" % (int(m.group(2)), int(m.group(1)))
line = m.group(3)
line = re.sub(r"^Enable bit of Mux", "MuxEn", line)
line = re.sub(r"^IO control bit:", "IoCtrl", line)
line = re.sub(r"^Column buffer control bit:", "ColBufCtrl", line)
line = re.sub(r"^Negative Clock bit", "NegClk", line)
line = re.sub(r"^Cascade (buffer Enable )?bit:", "Cascade", line)
line = re.sub(r"^Ram config bit:", "RamConfig", line)
line = re.sub(r"^PLL config bit:", "PLL", line)
line = re.sub(r"^Icegate Enable bit:", "Icegate", line)
line = line.split()
if line[0] == "routing":
if line[3] == "wire_gbuf/in": line[3] = "fabout"
raw_db.append((bit, (line[0], line[1], line[3])))
elif line[0] == "IoCtrl":
raw_db.append((bit, (line[0], re.sub(r"^.*?_", "", line[1]).replace("_en", ""))))
elif line[0] in ("IOB_0", "IOB_1"):
if line[1] != "IO":
raw_db.append((bit, (line[0], line[1])))
elif line[0] == "PLL":
line[1] = re.sub(r"CLOCK_T_\d+_\d+_IO(LEFT|RIGHT|UP|DOWN)_", "pll_", line[1])
line[1] = re.sub(r"pll_cf_bit_", "PLLCONFIG_", line[1])
raw_db.append((bit, (line[0], line[1])))
elif line[0] == "ColBufCtrl":
line[1] = re.sub(r"B?IO(LEFT|RIGHT)_", "IO_", line[1])
line[1] = re.sub(r"IO_half_column_clock_enable_", "glb_netwk_", line[1])
line[1] = re.sub(r"(LH|MEM[BT])_colbuf_cntl_", "glb_netwk_", line[1])
if m.group(1) == "7":
line[1] = re.sub(r"glb_netwk_", "8k_glb_netwk_", line[1])
elif m.group(1) in ["1", "2"]:
line[1] = re.sub(r"glb_netwk_", "1k_glb_netwk_", line[1])
raw_db.append((bit, (line[0], line[1])))
elif line[0] == "Cascade":
match = re.match("LH_LC0(\d)_inmux02_5", line[1])
if match:
raw_db.append((bit, ("buffer", "wire_logic_cluster/lc_%d/out" % (int(match.group(1))-1), "input_2_%s" % match.group(1))))
else:
raw_db.append((bit, (line[0], line[1])))
elif line[0] == "RamConfig":
if line[1] == "MEMB_Power_Up_Control": line[1] = "PowerUp"
line[1] = re.sub(r"MEMT_bram_cbit_", "CBIT_", line[1])
raw_db.append((bit, (line[0], line[1])))
elif line[0] == "MuxEn":
if line[4] == "wire_gbuf/in": line[4] = "fabout"
if line[3].startswith("logic_op_"):
for prefix in ["IO_L.", "IO_R.", "IO_T.", "IO_B."]:
route_to_buffer.add((prefix + line[3], line[4]))
add_mux_bits.setdefault(prefix + line[3], set()).add((bit, ("buffer", prefix + line[3], line[4])))
else:
raw_db.append((bit, ("buffer", line[3], line[4])))
route_to_buffer.add((line[3], line[4]))
elif line[0] == "NegClk" or line[0] == "Icegate" or re.match(r"LC_\d+", line[0]):
raw_db.append((bit, (line[0],)))
elif line[0] == "Carry_In_Mux":
continue
else:
print("unsupported statement: %s: %s" % (bit, line))
assert False
for i in range(len(raw_db)):
if raw_db[i][1][0] == "routing" and (raw_db[i][1][1], raw_db[i][1][2]) in route_to_buffer:
if raw_db[i][1][1] in add_mux_bits:
for entry in add_mux_bits[raw_db[i][1][1]]:
raw_db.append(entry)
raw_db[i] = (raw_db[i][0], ("buffer", raw_db[i][1][1], raw_db[i][1][2]))
func_to_bits = dict()
for entry in raw_db:
func_to_bits.setdefault(entry[1], set()).add(entry[0])
bit_groups = dict()
for func, bits in func_to_bits.items():
for bit in bits:
bit_groups[bit] = bit_groups.setdefault(bit, set()).union(bits)
for func in func_to_bits:
new_bits = set()
for bit2 in func_to_bits[func]:
for bit in bit_groups[bit2]:
if bit in func_to_bits[func]:
new_bits.add(bit)
else:
new_bits.add("!" + bit)
func_to_bits[func] = new_bits
database = list()
for func in sorted(func_to_bits):
bits = func_to_bits[func]
entry = (",".join(sorted(bits, cmp_bits)),) + func
database.append(entry)
return database
with open("database_io.txt", "w") as f:
for entry in read_database("bitdata_io.txt", "io"):
print("\t".join(entry), file=f)
with open("database_logic.txt", "w") as f:
for entry in read_database("bitdata_logic.txt", "logic"):
print("\t".join(entry), file=f)
with open("database_ramb.txt", "w") as f:
for entry in read_database("bitdata_ramb.txt", "ramb"):
print("\t".join(entry), file=f)
with open("database_ramt.txt", "w") as f:
for entry in read_database("bitdata_ramt.txt", "ramt"):
print("\t".join(entry), file=f)
with open("database_ramb_8k.txt", "w") as f:
for entry in read_database("bitdata_ramb_8k.txt", "ramb_8k"):
print("\t".join(entry), file=f)
with open("database_ramt_8k.txt", "w") as f:
for entry in read_database("bitdata_ramt_8k.txt", "ramt_8k"):
print("\t".join(entry), file=f)

13
icefuzz/export.py Normal file
View File

@ -0,0 +1,13 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
with open("../icebox/iceboxdb.py", "w") as f:
for i in [ "database_io", "database_logic", "database_ramb", "database_ramt", "database_ramb_8k", "database_ramt_8k" ]:
print('%s_txt = """' % i, file=f)
with open("%s.txt" % i, "r") as fi:
for line in fi:
print(line, end="", file=f)
print('"""', file=f)

60
icefuzz/extract.py Normal file
View File

@ -0,0 +1,60 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
import sys, re
db = set()
text_db = dict()
mode_8k = False
cur_text_db = None
max_x, max_y = 0, 0
if sys.argv[1] == '-8':
sys.argv = sys.argv[1:]
mode_8k = True
for filename in sys.argv[1:]:
with open(filename, "r") as f:
for line in f:
if line == "\n":
pass
elif line.startswith("GlobalNetwork"):
cur_text_db = set()
elif line.startswith("IO"):
match = re.match("IO_Tile_(\d+)_(\d+)", line)
assert match
max_x = max(max_x, int(match.group(1)))
max_y = max(max_y, int(match.group(2)))
cur_text_db = text_db.setdefault("io", set())
elif line.startswith("Logic"):
cur_text_db = text_db.setdefault("logic", set())
elif line.startswith("RAM"):
match = re.match(r"RAM_Tile_\d+_(\d+)", line)
if int(match.group(1)) % 2 == 1:
cur_text_db = text_db.setdefault("ramb_8k" if mode_8k else "ramb", set())
else:
cur_text_db = text_db.setdefault("ramt_8k" if mode_8k else "ramt", set())
else:
assert line.startswith(" ")
cur_text_db.add(line)
def logic_op_prefix(match):
x = int(match.group(1))
y = int(match.group(2))
if x == 0: return " IO_L.logic_op_"
if y == 0: return " IO_B.logic_op_"
if x == max_x: return " IO_R.logic_op_"
if y == max_y: return " IO_T.logic_op_"
assert False
for tile_type in text_db:
for line in text_db[tile_type]:
line = re.sub(" T_(\d+)_(\d+)\.logic_op_", logic_op_prefix, line)
line = re.sub(" T_\d+_\d+\.", " ", line)
m = re.match(" *(\([\d ]+\)) +\([\d ]+\) +\([\d ]+\) +(.*\S)", line)
if m: db.add("%s %s %s" % (tile_type, m.group(1), m.group(2)))
for line in sorted(db):
print(line)

36
icefuzz/fuzzconfig.py Normal file
View File

@ -0,0 +1,36 @@
import os
num = 20
if os.getenv('ICE8KPINS'):
num_ramb40 = 32
pins="""
A1 A2 A5 A6 A7 A9 A10 A11 A15 A16
B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C16
D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D13 D14 D15 D16
E2 E3 E4 E5 E6 E9 E10 E11 E13 E14 E16
F1 F2 F3 F4 F5 F7 F9 F11 F12 F13 F14 F15 F16
G1 G2 G3 G4 G5 G10 G11 G12 G13 G14 G15 G16
H1 H2 H3 H4 H5 H6 H11 H12 H13 H14 H16
J1 J2 J3 J4 J5 J10 J11 J12 J13 J14 J15 J16
K1 K3 K4 K5 K9 K11 K12 K13 K14 K15 K16
L1 L3 L4 L5 L6 L7 L9 L10 L11 L12 L13 L14 L16
M1 M2 M3 M4 M5 M6 M7 M8 M9 M11 M12 M13 M14 M15 M16
N2 N3 N4 N5 N6 N7 N9 N10 N12 N16
P1 P2 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16
R1 R2 R3 R4 R5 R6 R9 R10 R11 R12 R14 R15 R16
T1 T2 T3 T5 T6 T7 T8 T9 T10 T11 T13 T14 T15 T16
""".split()
else:
num_ramb40 = 16
pins = """
1 2 3 4 7 8 9 10 11 12 19 22 23 24 25 26 28 29 31 32 33 34
37 38 41 42 43 44 45 47 48 52 56 58 60 61 62 63 64
73 74 75 76 78 79 80 81 87 88 90 91 95 96 97 98 101 102 104 105 106 107
112 113 114 115 116 117 118 119 120 121 122 134 135 136 137 138 139 141 142 143 144
""".split()

34
icefuzz/glbmapbits.py Normal file
View File

@ -0,0 +1,34 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
import re
import fileinput
tiletype = ""
x, y = 0, 0
for line in fileinput.input():
if line.startswith("LogicTile"):
fields = line.split("_")
tiletype = "Logic"
x, y = int(fields[1]), int(fields[2])
continue
if line.startswith("RAM_Tile") or line.startswith("IO_Tile"):
fields = line.split("_")
tiletype = fields[0]
x, y = int(fields[2]), int(fields[3])
continue
if line.startswith("GlobalNetwork"):
tiletype = ""
continue
if tiletype != "":
fields = re.split('[ ()]*', line.strip())
if len(fields) <= 1: continue
fields = [int(fields[i+1]) for i in range(4)]
print("%-5s %2d %2d %2d %2d %3d %3d" % (tiletype, x, y, fields[0], fields[1], fields[2], fields[3]))

190
icefuzz/icecube.sh Normal file
View File

@ -0,0 +1,190 @@
#!/bin/bash
#
# Installing iCEcube2:
# - Install iCEcube2.2014.08 in /opt/lscc/iCEcube2.2014.08
# - Install License in /opt/lscc/iCEcube2.2014.08/license.dat
#
# Creating a project:
# - <project_name>.v ## HDL sources (use "top" as name for the top module)
# - <project_name>.sdc ## timing constraint file
# - <project_name>.pcf ## physical constraint file
#
# Running iCEcube2:
# - bash icecuberun.sh <project_name> ## creates <project_name>.bin
#
#
#
# Additional notes for installing iCEcube2 on 64 Bit Ubuntu:
#
# sudo apt-get install ibc6-i386 zlib1g:i386 libxext6:i386 libpng12-0:i386 libsm6:i386
# sudo apt-get install libxi6:i386 libxrender1:i386 libxrandr2:i386 libxfixes3:i386
# sudo apt-get install libxcursor1:i386 libXinerama.so.1:i386 libXinerama1:i386 libfreetype6:i386
# sudo apt-get install libfontconfig1:i386 libglib2.0-0:i386 libstdc++6:i386 libelf1:i386
#
# icecubedir="/opt/lscc/iCEcube2.2014.08"
# sudo sed -ri "1 s,/bin/sh,/bin/bash,;" $icecubedir/synpbase/bin/synplify_pro
# sudo sed -ri "1 s,/bin/sh,/bin/bash,;" $icecubedir/synpbase/bin/c_hdl
# sudo sed -ri "1 s,/bin/sh,/bin/bash,;" $icecubedir/synpbase/bin/syn_nfilter
# sudo sed -ri "1 s,/bin/sh,/bin/bash,;" $icecubedir/synpbase/bin/m_generic
#
scriptdir=${BASH_SOURCE%/*}
if [ -z "$scriptdir" ]; then scriptdir="."; fi
set -ex
set -- ${1%.v}
icecubedir="${ICECUBEDIR:-/opt/lscc/iCEcube2.2014.08}"
export SBT_DIR="$icecubedir/sbt_backend"
export SYNPLIFY_PATH="$icecubedir/synpbase"
export LM_LICENSE_FILE="$icecubedir/license.dat"
export TCL_LIBRARY="$icecubedir/sbt_backend/bin/linux/lib/tcl8.4"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/sbt_backend/bin/linux/opt"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/sbt_backend/bin/linux/opt/synpwrap"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/sbt_backend/lib/linux/opt"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$icecubedir/LSE/bin/lin"
case "${ICEDEV:-hx1k-tq144}" in
hx1k-cb132)
iCEPACKAGE="CB132"
iCE40DEV="iCE40HX1K"
;;
hx1k-vq100)
iCEPACKAGE="VQ100"
iCE40DEV="iCE40HX1K"
;;
hx1k-tq144)
iCEPACKAGE="TQ144"
iCE40DEV="iCE40HX1K"
;;
hx8k-cm225)
iCEPACKAGE="CM225"
iCE40DEV="iCE40HX8K"
;;
hx8k-ct256)
iCEPACKAGE="CT256"
iCE40DEV="iCE40HX8K"
;;
hx8k-cb132)
iCEPACKAGE="CB132"
iCE40DEV="iCE40HX8K"
;;
*)
echo "ERROR: Invalid \$ICEDEV device config '$ICEDEV'."
exit 1
esac
case "$iCE40DEV" in
iCE40HX1K)
libfile="ice40HX1K.lib"
devfile="ICE40P01.dev"
;;
iCE40HX8K)
libfile="ice40HX8K.lib"
devfile="ICE40P08.dev"
;;
esac
(
rm -rf "$1.tmp"
mkdir -p "$1.tmp"
cp "$1.v" "$1.tmp/input.v"
if test -f "$1.sdc"; then cp "$1.sdc" "$1.tmp/input.sdc"; fi
if test -f "$1.pcf"; then cp "$1.pcf" "$1.tmp/input.pcf"; fi
cd "$1.tmp"
touch input.sdc
touch input.pcf
mkdir -p outputs/packer
mkdir -p outputs/placer
mkdir -p outputs/router
mkdir -p outputs/bitmap
mkdir -p outputs/netlist
mkdir -p netlist/Log/bitmap
cat > impl_syn.prj << EOT
add_file -verilog -lib work input.v
impl -add impl -type fpga
# implementation attributes
set_option -vlog_std v2001
set_option -project_relative_includes 1
# device options
set_option -technology SBTiCE40
set_option -part $iCE40DEV
set_option -package $iCEPACKAGE
set_option -speed_grade
set_option -part_companion ""
# mapper_options
set_option -frequency auto
set_option -write_verilog 0
set_option -write_vhdl 0
# Silicon Blue iCE40
set_option -maxfan 10000
set_option -disable_io_insertion 0
set_option -pipe 1
set_option -retiming 0
set_option -update_models_cp 0
set_option -fixgatedclocks 2
set_option -fixgeneratedclocks 0
# NFilter
set_option -popfeed 0
set_option -constprop 0
set_option -createhierarchy 0
# sequential_optimization_options
set_option -symbolic_fsm_compiler 1
# Compiler Options
set_option -compiler_compatible 0
set_option -resource_sharing 1
# automatic place and route (vendor) options
set_option -write_apr_constraint 1
# set result format/file last
project -result_format edif
project -result_file impl.edf
impl -active impl
project -run synthesis -clean
EOT
try_rerun() {
for i in {0..3}; do
if "$@"; then return 0; fi
done
return 1
}
# synthesis
"$icecubedir"/sbt_backend/bin/linux/opt/synpwrap/synpwrap -prj impl_syn.prj -log impl.srr
# convert netlist
"$icecubedir"/sbt_backend/bin/linux/opt/edifparser "$icecubedir"/sbt_backend/devices/$devfile impl/impl.edf netlist -p$iCEPACKAGE -yinput.pcf -sinput.sdc -c --devicename $iCE40DEV
# run placer
try_rerun "$icecubedir"/sbt_backend/bin/linux/opt/sbtplacer --des-lib netlist/oadb-top --outdir outputs/placer --device-file "$icecubedir"/sbt_backend/devices/$devfile --package $iCEPACKAGE --deviceMarketName $iCE40DEV --sdc-file netlist/Temp/sbt_temp.sdc --lib-file "$icecubedir"/sbt_backend/devices/$libfile --effort_level std --out-sdc-file outputs/placer/top_pl.sdc
# run packer
"$icecubedir"/sbt_backend/bin/linux/opt/packer "$icecubedir"/sbt_backend/devices/$devfile netlist/oadb-top --package $iCEPACKAGE --outdir outputs/packer --translator "$icecubedir"/sbt_backend/bin/sdc_translator.tcl --src_sdc_file outputs/placer/top_pl.sdc --dst_sdc_file outputs/packer/top_pk.sdc --devicename $iCE40DEV
# run router
"$icecubedir"/sbt_backend/bin/linux/opt/sbrouter "$icecubedir"/sbt_backend/devices/$devfile netlist/oadb-top "$icecubedir"/sbt_backend/devices/$libfile outputs/packer/top_pk.sdc --outdir outputs/router --sdf_file outputs/simulation_netlist/top_sbt.sdf --pin_permutation
# run netlister
"$icecubedir"/sbt_backend/bin/linux/opt/netlister --verilog outputs/netlist/top_sbt.v --vhdl outputs/netlist/top_sbt.vhd --lib netlist/oadb-top --view rt --device "$icecubedir"/sbt_backend/devices/$devfile --splitio --in-sdc-file outputs/packer/top_pk.sdc --out-sdc-file netlister/top_sbt.sdc
# make bitmap
"$icecubedir"/sbt_backend/bin/linux/opt/bitmap "$icecubedir"/sbt_backend/devices/$devfile --design netlist/oadb-top --device_name $iCE40DEV --package $iCEPACKAGE --outdir outputs/bitmap --debug --low_power on --init_ram on --init_ram_bank 1111 --frequency low --warm_boot on
)
cp "$1.tmp"/outputs/bitmap/top_bitmap.bin "$1.bin"
cp "$1.tmp"/outputs/bitmap/top_bitmap_glb.txt "$1.glb"
cp "$1.tmp"/outputs/placer/top_sbt.pcf "$1.psb"
cp "$1.tmp"/outputs/netlist/top_sbt.v "$1.vsb"
$scriptdir/../icepack/iceunpack "$1.bin" "$1.txt"

28
icefuzz/make_binop.py Normal file
View File

@ -0,0 +1,28 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_binop")
os.mkdir("work_binop")
for idx in range(num):
with open("work_binop/binop_%02d.v" % idx, "w") as f:
print("module top(input a, b, output y);", file=f)
print(" assign y = a%sb;" % np.random.choice([" ^ ", " ^ ~", " & ", " & ~", " | ", " | ~"]), file=f)
print("endmodule", file=f)
with open("work_binop/binop_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
print("set_io a %s" % p[0], file=f)
print("set_io b %s" % p[1], file=f)
print("set_io y %s" % p[2], file=f)
with open("work_binop/Makefile", "w") as f:
print("all: %s" % " ".join(["binop_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("binop_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh binop_%02d > binop_%02d.log 2>&1 && rm -rf binop_%02d.tmp || tail binop_%02d.log" % (i, i, i, i), file=f)

29
icefuzz/make_cluster.py Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_cluster")
os.mkdir("work_cluster")
for idx in range(num):
with open("work_cluster/cluster_%02d.v" % idx, "w") as f:
print("module top(input [3:0] a, output [3:0] y);", file=f)
print(" assign y = {|a, &a, ^a, a[3:2] == a[1:0]};", file=f)
print("endmodule", file=f)
with open("work_cluster/cluster_%02d.pcf" % idx, "w") as f:
i = np.random.randint(len(pins))
netnames = np.random.permutation(["a[%d]" % i for i in range(4)] + ["y[%d]" % i for i in range(4)])
for net in netnames:
print("set_io %s %s" % (net, pins[i]), file=f)
i = (i + 1) % len(pins)
with open("work_cluster/Makefile", "w") as f:
print("all: %s" % " ".join(["cluster_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("cluster_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh cluster_%02d > cluster_%02d.log 2>&1 && rm -rf cluster_%02d.tmp || tail cluster_%02d.log" % (i, i, i, i), file=f)

29
icefuzz/make_fanout.py Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_fanout")
os.mkdir("work_fanout")
for idx in range(num):
with open("work_fanout/fanout_%02d.v" % idx, "w") as f:
print("module top(input [1:0] a, output [63:0] y);", file=f)
print(" assign y = {32{a}};", file=f)
print("endmodule", file=f)
with open("work_fanout/fanout_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
for i in range(64):
print("set_io y[%d] %s" % (i, p[i]), file=f)
print("set_io a[0] %s" % p[64], file=f)
print("set_io a[1] %s" % p[65], file=f)
with open("work_fanout/Makefile", "w") as f:
print("all: %s" % " ".join(["fanout_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("fanout_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh fanout_%02d > fanout_%02d.log 2>&1 && rm -rf fanout_%02d.tmp || tail fanout_%02d.log" % (i, i, i, i), file=f)

54
icefuzz/make_fflogic.py Normal file
View File

@ -0,0 +1,54 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_fflogic")
os.mkdir("work_fflogic")
def random_op():
return np.random.choice(["+", "-", "*", "^", "&", "|"])
def print_seq_op(dst, src1, src2, op, f):
mode = np.random.choice(list("abc"))
negreset = np.random.choice(["!", ""])
enable = np.random.choice(["if (en) ", ""])
if mode == "a":
print(" always @(%sedge clk) begin" % np.random.choice(["pos", "neg"]), file=f)
print(" %s%s <= %s %s %s;" % (enable, dst, src1, op, src2), file=f)
print(" end", file=f)
elif mode == "b":
print(" always @(%sedge clk) begin" % np.random.choice(["pos", "neg"]), file=f)
print(" if (%srst)" % negreset, file=f)
print(" %s <= %d;" % (dst, np.random.randint(2**16)), file=f)
print(" else", file=f)
print(" %s%s <= %s %s %s;" % (enable, dst, src1, op, src2), file=f)
print(" end", file=f)
elif mode == "c":
print(" always @(%sedge clk, %sedge rst) begin" % (np.random.choice(["pos", "neg"]), "neg" if negreset == "!" else "pos"), file=f)
print(" if (%srst)" % negreset, file=f)
print(" %s <= %d;" % (dst, np.random.randint(2**16)), file=f)
print(" else", file=f)
print(" %s%s <= %s %s %s;" % (enable, dst, src1, op, src2), file=f)
print(" end", file=f)
else:
assert False
for idx in range(num):
with open("work_fflogic/fflogic_%02d.v" % idx, "w") as f:
print("module top(input clk, rst, en, input [15:0] a, b, c, d, output [15:0] y, output z);", file=f)
print(" reg [15:0] p, q;", file=f)
print_seq_op("p", "a", "b", random_op(), f)
print_seq_op("q", "c", "d", random_op(), f)
print(" assign y = p %s q, z = clk ^ rst ^ en;" % random_op(), file=f)
print("endmodule", file=f)
with open("work_fflogic/Makefile", "w") as f:
print("all: %s" % " ".join(["fflogic_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("fflogic_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh fflogic_%02d > fflogic_%02d.log 2>&1 && rm -rf fflogic_%02d.tmp || tail fflogic_%02d.log" % (i, i, i, i), file=f)

84
icefuzz/make_gbio.py Normal file
View File

@ -0,0 +1,84 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_gbio")
os.mkdir("work_gbio")
for idx in range(num):
with open("work_gbio/gbio_%02d.v" % idx, "w") as f:
glbs = np.random.permutation(range(8))
print("""
module top (
inout [7:0] pin,
input latch_in,
input clk_en,
input clk_in,
input clk_out,
input oen,
input dout_0,
input dout_1,
output [7:0] din_0,
output [7:0] din_1,
output [7:0] globals,
output reg q
);
SB_GB_IO #(
.PIN_TYPE(6'b 1100_00),
.PULLUP(1'b0),
.NEG_TRIGGER(1'b0),
.IO_STANDARD("SB_LVCMOS")
) PINS [7:0] (
.PACKAGE_PIN(pin),
.LATCH_INPUT_VALUE(%s),
.CLOCK_ENABLE(%s),
.INPUT_CLK(%s),
.OUTPUT_CLK(%s),
.OUTPUT_ENABLE(%s),
.D_OUT_0(%s),
.D_OUT_1(%s),
.D_IN_0(%s),
.D_IN_1(%s),
.GLOBAL_BUFFER_OUTPUT(%s)
);
always @(posedge globals[%d], posedge globals[%d])
if (globals[%d])
q <= 0;
else if (globals[%d])
q <= globals[%d];
endmodule
""" % (
np.random.choice(["latch_in", "globals", "din_0+din_1", "din_0^din_1"]),
np.random.choice(["clk_en", "globals", "din_0+din_1", "din_0^din_1"]),
np.random.choice(["clk_in", "globals", "din_0+din_1", "din_0^din_1"]),
np.random.choice(["clk_out", "globals", "din_0+din_1", "din_0^din_1"]),
np.random.choice(["oen", "globals", "din_0+din_1", "din_0^din_1"]),
np.random.choice(["dout_1", "globals", "globals^dout_0", "din_0+din_1", "~din_0"]),
np.random.choice(["dout_0", "globals", "globals^dout_1", "din_0+din_1", "~din_1"]),
np.random.choice(["din_0", "{din_0[3:0], din_0[7:4]}"]),
np.random.choice(["din_1", "{din_1[1:0], din_1[7:2]}"]),
np.random.choice(["globals", "{globals[0], globals[7:1]}"]),
glbs[0], glbs[1], glbs[1], glbs[2], glbs[3]
), file=f)
with open("work_gbio/gbio_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
for i in range(8):
print("set_io pin[%d] %s" % (i, p[i]), file=f)
print("set_io din_0[%d] %s" % (i, p[8+i]), file=f)
print("set_io din_1[%d] %s" % (i, p[2*8+i]), file=f)
print("set_io globals[%d] %s" % (i, p[3*8+i]), file=f)
for i, n in enumerate("latch_in clk_en clk_in clk_out oen dout_0 dout_1".split()):
print("set_io %s %s" % (n, p[4*8+i]), file=f)
print("set_io q %s" % (p[-1]), file=f)
with open("work_gbio/Makefile", "w") as f:
print("all: %s" % " ".join(["gbio_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("gbio_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh gbio_%02d > gbio_%02d.log 2>&1 && rm -rf gbio_%02d.tmp || tail gbio_%02d.log" % (i, i, i, i), file=f)

83
icefuzz/make_gbio2.py Normal file
View File

@ -0,0 +1,83 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_gbio2")
os.mkdir("work_gbio2")
for idx in range(num):
with open("work_gbio2/gbio2_%02d.v" % idx, "w") as f:
glbs = np.random.permutation(range(8))
print("""
module top (
inout [7:0] pin,
input latch_in,
input clk_en,
input clk_in,
input clk_out,
input oen,
input dout_0,
input dout_1,
output [7:0] din_0,
output [7:0] din_1,
output [7:0] globals,
output reg q
);
""", file=f);
for k in range(8):
print("""
SB_GB_IO #(
.PIN_TYPE(6'b %s),
.PULLUP(1'b %s),
.NEG_TRIGGER(1'b %s),
.IO_STANDARD("SB_LVCMOS")
) \pin[%d]_gb_io (
.PACKAGE_PIN(pin[%d]),
.LATCH_INPUT_VALUE(latch_in),
.CLOCK_ENABLE(clk_en),
.INPUT_CLK(clk_in),
.OUTPUT_CLK(clk_out),
.OUTPUT_ENABLE(oen),
.D_OUT_0(dout_0),
.D_OUT_1(dout_1),
.D_IN_0(din_0[%d]),
.D_IN_1(din_1[%d]),
.GLOBAL_BUFFER_OUTPUT(globals[%d])
);
""" % (
np.random.choice(["1100_00", "1010_10", "1010_00", "0000_11", "1111_00"]),
np.random.choice(["0", "1"]),
np.random.choice(["0", "1"]),
k, k, k, k, k
), file=f)
print("""
always @(posedge globals[%d], posedge globals[%d])
if (globals[%d])
q <= 0;
else if (globals[%d])
q <= globals[%d];
endmodule
""" % (
glbs[0], glbs[1], glbs[1], glbs[2], glbs[3]
), file=f)
with open("work_gbio2/gbio2_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
for i in range(8):
print("set_io pin[%d] %s" % (i, p[i]), file=f)
print("set_io din_0[%d] %s" % (i, p[8+i]), file=f)
print("set_io din_1[%d] %s" % (i, p[2*8+i]), file=f)
print("set_io globals[%d] %s" % (i, p[3*8+i]), file=f)
for i, n in enumerate("latch_in clk_en clk_in clk_out oen dout_0 dout_1".split()):
print("set_io %s %s" % (n, p[4*8+i]), file=f)
print("set_io q %s" % (p[-1]), file=f)
with open("work_gbio2/Makefile", "w") as f:
print("all: %s" % " ".join(["gbio2_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("gbio2_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh gbio2_%02d > gbio2_%02d.log 2>&1 && rm -rf gbio2_%02d.tmp || tail gbio2_%02d.log" % (i, i, i, i), file=f)

61
icefuzz/make_io.py Normal file
View File

@ -0,0 +1,61 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_io")
os.mkdir("work_io")
for idx in range(num):
with open("work_io/io_%02d.v" % idx, "w") as f:
glbs = np.random.permutation(range(8))
print("""
module top (
inout [3:0] pin,
input [3:0] latch_in,
input [3:0] clk_en,
input [3:0] clk_in,
input [3:0] clk_out,
input [3:0] oen,
input [3:0] dout_0,
input [3:0] dout_1,
output [3:0] din_0,
output [3:0] din_1
);
SB_IO #(
.PIN_TYPE(6'b %s_%s),
.PULLUP(1'b %s),
.NEG_TRIGGER(1'b %s),
.IO_STANDARD("SB_LVCMOS")
) PINS [3:0] (
.PACKAGE_PIN(pin),
.LATCH_INPUT_VALUE(latch_in),
.CLOCK_ENABLE(clk_en),
.INPUT_CLK(clk_in),
.OUTPUT_CLK(clk_out),
.OUTPUT_ENABLE(oen),
.D_OUT_0(dout_0),
.D_OUT_1(dout_1),
.D_IN_0(din_0),
.D_IN_1(din_1)
);
endmodule
""" % (
np.random.choice(["0000", "0110", "1010", "1110", "0101", "1001", "1101", "0100", "1000", "1100", "0111", "1111"]),
np.random.choice(["00", "01", "10", "11"]), np.random.choice(["0", "1"]), np.random.choice(["0", "1"])
), file=f)
with open("work_io/io_%02d.pcf" % idx, "w") as f:
p = list(np.random.permutation(pins))
for k in ["pin", "latch_in", "clk_en", "clk_in", "clk_out", "oen", "dout_0", "dout_1", "din_0", "din_1"]:
for i in range(4):
print("set_io %s[%d] %s" % (k, i, p.pop()), file=f)
with open("work_io/Makefile", "w") as f:
print("all: %s" % " ".join(["io_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("io_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh io_%02d > io_%02d.log 2>&1 && rm -rf io_%02d.tmp || tail io_%02d.log" % (i, i, i, i), file=f)

59
icefuzz/make_iopack.py Normal file
View File

@ -0,0 +1,59 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
from numpy.random import randint, choice, permutation
num_xor = 8
num_luts = 8
num_outputs_range = (5, 20)
os.system("rm -rf work_iopack")
os.mkdir("work_iopack")
def get_pin_directions():
pindirs = ["i" for i in range(len(pins))]
for i in range(randint(num_outputs_range[0], num_outputs_range[1])):
pindirs[randint(len(pins))] = "o"
return pindirs
def get_nearby_inputs(p, n, r):
while True:
ipins = list()
for i in range(-r, +r):
ip = (p + i + len(pins)) % len(pins)
if pindirs[ip] == "i":
ipins.append(ip)
if len(ipins) >= n:
break
r += 4
return [choice(ipins) for i in range(n)]
for idx in range(num):
with open("work_iopack/iopack_%02d.v" % idx, "w") as f:
pindirs = get_pin_directions()
print("module top(%s);" % ", ".join(["%sput p%d" % ("in" if pindirs[i] == "i" else "out", i) for i in range(len(pins))]), file=f)
for outp in range(len(pins)):
if pindirs[outp] == "o":
xor_nets = set(["%sp%d" % (choice(["~", ""]), p) for p in get_nearby_inputs(outp, num_xor, 2 + randint(10))])
for i in range(num_luts):
print(" localparam [15:0] p%d_lut%d = 16'd %d;" % (outp, i, randint(2**16)), file=f)
print(" wire p%d_in%d = p%d_lut%d >> {%s};" % (outp, i, outp, i,
", ".join(["p%d" % p for p in get_nearby_inputs(outp + randint(-10, +11), 4, 4)])), file=f)
xor_nets.add("%sp%d_in%d" % (choice(["~", ""]), outp, i))
print(" assign p%d = ^{%s};" % (outp, ", ".join(sorted(xor_nets))), file=f)
print("endmodule", file=f)
with open("work_iopack/iopack_%02d.pcf" % idx, "w") as f:
for i in range(len(pins)):
print("set_io p%d %s" % (i, pins[i]), file=f)
with open("work_iopack/Makefile", "w") as f:
print("all: %s" % " ".join(["iopack_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("iopack_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh iopack_%02d > iopack_%02d.log 2>&1 && rm -rf iopack_%02d.tmp || tail iopack_%02d.log" % (i, i, i, i), file=f)

34
icefuzz/make_logic.py Normal file
View File

@ -0,0 +1,34 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_logic")
os.mkdir("work_logic")
def random_op():
return np.random.choice(["+", "-", "^", "&", "|", "&~", "|~"])
for idx in range(num):
with open("work_logic/logic_%02d.v" % idx, "w") as f:
print("module top(input [15:0] a, b, c, d, output [15:0] y);", file=f)
print(" assign y = (a %s b) %s (c %s d);" % (random_op(), random_op(), random_op()), file=f)
print("endmodule", file=f)
with open("work_logic/logic_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
for i in range(16):
print("set_io a[%d] %s" % (i, p[i]), file=f)
print("set_io b[%d] %s" % (i, p[i+16]), file=f)
print("set_io c[%d] %s" % (i, p[i+32]), file=f)
print("set_io d[%d] %s" % (i, p[i+48]), file=f)
print("set_io y[%d] %s" % (i, p[i+64]), file=f)
with open("work_logic/Makefile", "w") as f:
print("all: %s" % " ".join(["logic_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("logic_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh logic_%02d > logic_%02d.log 2>&1 && rm -rf logic_%02d.tmp || tail logic_%02d.log" % (i, i, i, i), file=f)

29
icefuzz/make_mesh.py Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_mesh")
os.mkdir("work_mesh")
for idx in range(num):
with open("work_mesh/mesh_%02d.v" % idx, "w") as f:
print("module top(input [39:0] a, output [39:0] y);", file=f)
print(" assign y = a;", file=f)
print("endmodule", file=f)
with open("work_mesh/mesh_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
for i in range(40):
print("set_io a[%d] %s" % (i, p[i]), file=f)
for i in range(40):
print("set_io y[%d] %s" % (i, p[40+i]), file=f)
with open("work_mesh/Makefile", "w") as f:
print("all: %s" % " ".join(["mesh_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("mesh_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh mesh_%02d > mesh_%02d.log 2>&1 && rm -rf mesh_%02d.tmp || tail mesh_%02d.log" % (i, i, i, i), file=f)

27
icefuzz/make_pin2pin.py Normal file
View File

@ -0,0 +1,27 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_pin2pin")
os.mkdir("work_pin2pin")
for idx in range(num):
with open("work_pin2pin/pin2pin_%02d.v" % idx, "w") as f:
print("module top(input a, output y);", file=f)
print(" assign y = a;", file=f)
print("endmodule", file=f)
with open("work_pin2pin/pin2pin_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
print("set_io a %s" % p[0], file=f)
print("set_io y %s" % p[1], file=f)
with open("work_pin2pin/Makefile", "w") as f:
print("all: %s" % " ".join(["pin2pin_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("pin2pin_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh pin2pin_%02d > pin2pin_%02d.log 2>&1 && rm -rf pin2pin_%02d.tmp || tail pin2pin_%02d.log" % (i, i, i, i), file=f)

139
icefuzz/make_pll.py Normal file
View File

@ -0,0 +1,139 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
import numpy as np
import os
from numpy.random import randint, choice, permutation
def randbin(n):
return "".join([choice(["0", "1"]) for i in range(n)])
num = 20
pins = [int(i) for i in """
1 2 3 4 7 8 9 10 11 12 19 20 21 22 23 24 25 26 28 29 31 32 33 34
37 38 39 41 42 43 44 45 47 48 49 50 52 56 58 60 61 62 63 64 67 68 70 71
73 74 75 76 78 79 80 81 87 88 90 91 93 94 95 96 97 98 99 101 102 104 105 106 107
112 113 114 115 116 117 118 119 120 121 122 128 129 134 135 136 137 138 139 141 142 143 144
""".split()]
pins.remove(49)
pins.remove(50)
os.system("rm -rf work_pll")
os.mkdir("work_pll")
for idx in range(num):
pin_names = list()
vlog_body = list()
pll_inst = list()
pll_type = choice(["SB_PLL40_CORE", "SB_PLL40_2F_CORE", "SB_PLL40_PAD", "SB_PLL40_2_PAD", "SB_PLL40_2F_PAD"])
pll_inst.append("%s uut (" % pll_type)
if pll_type.endswith("_PAD"):
pin_names.append("packagepin")
vlog_body.append("input packagepin;")
pll_inst.append(" .PACKAGEPIN(packagepin),")
else:
pin_names.append("referenceclk")
vlog_body.append("input referenceclk;")
pll_inst.append(" .REFERENCECLK(referenceclk),")
for pin in ["a", "b"]:
pin_names.append(pin)
vlog_body.append("input %s;" % pin)
for pin in ["w", "x", "y", "z"]:
pin_names.append(pin)
vlog_body.append("output %s%s;" % ("reg " if pin in ["y", "z"] else "", pin))
for pin in ["EXTFEEDBACK", "BYPASS", "RESETB", "LOCK", "LATCHINPUTVALUE", "SDI", "SDO", "SCLK"]:
pin_names.append(pin.lower())
vlog_body.append("%sput %s;" % ("out" if pin in ["LOCK", "SDO"] else "in", pin.lower()))
pll_inst.append(" .%s(%s)," % (pin, pin.lower()))
if pll_type.find("_2_") < 0 and pll_type.find("_2F_") < 0:
for pin in ["PLLOUTCORE", "PLLOUTGLOBAL"]:
vlog_body.append("wire %s;" % pin.lower())
pll_inst.append(" .%s(%s)," % (pin, pin.lower()))
vlog_body.append("assign w = plloutcore ^ a;")
vlog_body.append("assign x = plloutcore ^ b;")
vlog_body.append("always @(posedge plloutglobal) y <= a;")
vlog_body.append("always @(posedge plloutglobal) z <= b;")
else:
for pin in ["PLLOUTCOREA", "PLLOUTCOREB", "PLLOUTGLOBALA", "PLLOUTGLOBALB"]:
vlog_body.append("wire %s;" % pin.lower())
pll_inst.append(" .%s(%s)," % (pin, pin.lower()))
vlog_body.append("assign w = plloutcorea ^ a;")
vlog_body.append("assign x = plloutcoreb ^ b;")
vlog_body.append("always @(posedge plloutglobala) y <= a;")
vlog_body.append("always @(posedge plloutglobalb) z <= b;")
for i in range(8):
pin_names.append("dynamicdelay_%d" % i)
vlog_body.append("input dynamicdelay_%d;" % i)
pll_inst.append(" .DYNAMICDELAY({%s})" % ", ".join(["dynamicdelay_%d" % i for i in range(7, -1, -1)]))
pll_inst.append(");")
divq = randbin(3)
if divq == "000": divq = "001"
if divq == "111": divq = "110"
pll_inst.append("defparam uut.DIVR = 4'b%s;" % randbin(4))
pll_inst.append("defparam uut.DIVF = 7'b%s;" % randbin(7))
pll_inst.append("defparam uut.DIVQ = 3'b%s;" % divq)
pll_inst.append("defparam uut.FILTER_RANGE = 3'b%s;" % randbin(3))
pll_inst.append("defparam uut.FEEDBACK_PATH = \"%s\";" % choice(["DELAY", "SIMPLE", "PHASE_AND_DELAY", "EXTERNAL"]))
if choice([True, False]):
pll_inst.append("defparam uut.DELAY_ADJUSTMENT_MODE_FEEDBACK = \"FIXED\";")
pll_inst.append("defparam uut.FDA_FEEDBACK = 4'b%s;" % randbin(4))
else:
pll_inst.append("defparam uut.DELAY_ADJUSTMENT_MODE_FEEDBACK = \"DYNAMIC\";")
pll_inst.append("defparam uut.FDA_FEEDBACK = 4'b1111;")
if choice([True, False]):
pll_inst.append("defparam uut.DELAY_ADJUSTMENT_MODE_RELATIVE = \"FIXED\";")
pll_inst.append("defparam uut.FDA_RELATIVE = 4'b%s;" % randbin(4))
else:
pll_inst.append("defparam uut.DELAY_ADJUSTMENT_MODE_RELATIVE = \"DYNAMIC\";")
pll_inst.append("defparam uut.FDA_RELATIVE = 4'b1111;")
pll_inst.append("defparam uut.SHIFTREG_DIV_MODE = 1'b%s;" % randbin(1))
if pll_type.find("_2_") < 0 and pll_type.find("_2F_") < 0:
pll_inst.append("defparam uut.PLLOUT_SELECT = \"%s\";" % choice(["GENCLK", "GENCLK_HALF", "SHIFTREG_90deg", "SHIFTREG_0deg"]))
elif pll_type.find("_2F_") < 0:
pll_inst.append("defparam uut.PLLOUT_SELECT_PORTB = \"%s\";" % choice(["GENCLK", "GENCLK_HALF", "SHIFTREG_90deg", "SHIFTREG_0deg"]))
else:
pll_inst.append("defparam uut.PLLOUT_SELECT_PORTA = \"%s\";" % choice(["GENCLK", "GENCLK_HALF", "SHIFTREG_90deg", "SHIFTREG_0deg"]))
pll_inst.append("defparam uut.PLLOUT_SELECT_PORTB = \"%s\";" % choice(["GENCLK", "GENCLK_HALF", "SHIFTREG_90deg", "SHIFTREG_0deg"]))
if pll_type.find("_2_") < 0 and pll_type.find("_2F_") < 0:
pll_inst.append("defparam uut.ENABLE_ICEGATE = 1'b0;")
else:
pll_inst.append("defparam uut.ENABLE_ICEGATE_PORTA = 1'b0;")
pll_inst.append("defparam uut.ENABLE_ICEGATE_PORTB = 1'b0;")
pll_inst.append("defparam uut.TEST_MODE = 1'b0;")
with open("work_pll/pll_%02d.v" % idx, "w") as f:
print("module top(%s);" % ", ".join(pin_names), file=f)
print("\n".join(vlog_body), file=f)
print("\n".join(pll_inst), file=f)
print("endmodule", file=f)
with open("work_pll/pll_%02d.pcf" % idx, "w") as f:
for pll_pin, package_pin in zip(pin_names, list(permutation(pins))[0:len(pin_names)]):
if pll_pin == "packagepin": package_pin = 49
print("set_io %s %d" % (pll_pin, package_pin), file=f)
with open("work_pll/Makefile", "w") as f:
print("all: %s" % " ".join(["pll_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("pll_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh pll_%02d > pll_%02d.log 2>&1 && rm -rf pll_%02d.tmp || tail pll_%02d.log" % (i, i, i, i), file=f)

51
icefuzz/make_prim.py Normal file
View File

@ -0,0 +1,51 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_prim")
os.mkdir("work_prim")
for idx in range(num):
with open("work_prim/prim_%02d.v" % idx, "w") as f:
clkedge = np.random.choice(["pos", "neg"])
print("module top(input clk, input [23:0] a, b, output reg x, output reg [23:0] y);", file=f)
print(" reg [23:0] aa, bb;", file=f)
print(" always @(%sedge clk) aa <= a;" % clkedge, file=f)
print(" always @(%sedge clk) bb <= b;" % clkedge, file=f)
if np.random.choice([True, False]):
print(" always @(%sedge clk) x <= %s%s;" % (clkedge, np.random.choice(["^", "&", "|", "!"]), np.random.choice(["a", "b", "y"])), file=f)
else:
print(" always @(%sedge clk) x <= a%sb;" % (clkedge, np.random.choice(["&&", "||"])), file=f)
if np.random.choice([True, False]):
print(" always @(%sedge clk) y <= a%sb;" % (clkedge, np.random.choice(["+", "-", "&", "|"])), file=f)
else:
print(" always @(%sedge clk) y <= %s%s;" % (clkedge, np.random.choice(["~", "-", ""]), np.random.choice(["a", "b"])), file=f)
print("endmodule", file=f)
with open("work_prim/prim_%02d.pcf" % idx, "w") as f:
p = np.random.permutation(pins)
if np.random.choice([True, False]):
for i in range(24):
print("set_io a[%d] %s" % (i, p[i]), file=f)
if np.random.choice([True, False]):
for i in range(24):
print("set_io b[%d] %s" % (i, p[24+i]), file=f)
if np.random.choice([True, False]):
for i in range(24):
print("set_io y[%d] %s" % (i, p[2*24+i]), file=f)
if np.random.choice([True, False]):
print("set_io x %s" % p[3*24], file=f)
if np.random.choice([True, False]):
print("set_io y %s" % p[3*24+1], file=f)
if np.random.choice([True, False]):
print("set_io clk %s" % p[3*24+2], file=f)
with open("work_prim/Makefile", "w") as f:
print("all: %s" % " ".join(["prim_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("prim_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh prim_%02d > prim_%02d.log 2>&1 && rm -rf prim_%02d.tmp || tail prim_%02d.log" % (i, i, i, i), file=f)

113
icefuzz/make_ram40.py Normal file
View File

@ -0,0 +1,113 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
from fuzzconfig import *
import numpy as np
import os
os.system("rm -rf work_ram40")
os.mkdir("work_ram40")
for idx in range(num):
with open("work_ram40/ram40_%02d.v" % idx, "w") as f:
glbs = ["glb[%d]" % i for i in range(np.random.randint(9))]
glbs_choice = ["wa", "ra", "msk", "wd", "we", "wce", "wc", "re", "rce", "rc"]
print("""
module top (
input [%d:0] glb_pins,
input [59:0] in_pins,
output [15:0] out_pins
);
wire [%d:0] glb, glb_pins;
SB_GB gbufs [%d:0] (
.USER_SIGNAL_TO_GLOBAL_BUFFER(glb_pins),
.GLOBAL_BUFFER_OUTPUT(glb)
);
""" % (len(glbs)-1, len(glbs)-1, len(glbs)-1), file=f)
bits = ["in_pins[%d]" % i for i in range(60)]
bits = list(np.random.permutation(bits))
for i in range(num_ramb40):
tmp = list(np.random.permutation(bits))
rmode = np.random.randint(4)
if rmode == 3:
wmode = np.random.randint(1, 4)
else:
wmode = np.random.randint(4)
raddr_bits = (8, 9, 10, 11)[rmode]
waddr_bits = (8, 9, 10, 11)[wmode]
rdata_bits = (16, 8, 4, 2)[rmode]
wdata_bits = (16, 8, 4, 2)[wmode]
bits_waddr = [tmp.pop() for k in range(waddr_bits)]
bits_raddr = [tmp.pop() for k in range(raddr_bits)]
bits_mask = [tmp.pop() for k in range(16)]
bits_wdata = [tmp.pop() for k in range(wdata_bits)]
bit_we = tmp.pop()
bit_wclke = tmp.pop()
bit_wclk = tmp.pop()
bit_re = tmp.pop()
bit_rclke = tmp.pop()
bit_rclk = tmp.pop()
if len(glbs) != 0:
s = np.random.choice(glbs_choice)
glbs_choice.remove(s)
if s == "wa": bits_waddr[np.random.randint(len(bits_waddr))] = glbs.pop()
if s == "ra": bits_raddr[np.random.randint(len(bits_raddr))] = glbs.pop()
if s == "msk": bits_mask [np.random.randint(len(bits_mask ))] = glbs.pop()
if s == "wd": bits_wdata[np.random.randint(len(bits_wdata))] = glbs.pop()
if s == "we": bit_we = glbs.pop()
if s == "wce": bit_wclke = glbs.pop()
if s == "wc": bit_wclk = glbs.pop()
if s == "re": bit_re = glbs.pop()
if s == "rce": bit_rclke = glbs.pop()
if s == "rc": bit_rclk = glbs.pop()
bits_waddr = "{%s}" % ", ".join(bits_waddr)
bits_raddr = "{%s}" % ", ".join(bits_raddr)
bits_mask = "{%s}" % ", ".join(bits_mask)
bits_wdata = "{%s}" % ", ".join(bits_wdata)
if wmode != 0: bits_mask = ""
memtype = np.random.choice(["", "NR", "NW", "NRNW"])
wclksuffix = "N" if memtype in ["NW", "NRNW"] else ""
rclksuffix = "N" if memtype in ["NR", "NRNW"] else ""
print("""
wire [%d:0] rdata_%d;
SB_RAM40_4K%s #(
.READ_MODE(%d),
.WRITE_MODE(%d)
) ram_%d (
.WADDR(%s),
.RADDR(%s),
.MASK(%s),
.WDATA(%s),
.RDATA(rdata_%d),
.WE(%s),
.WCLKE(%s),
.WCLK%s(%s),
.RE(%s),
.RCLKE(%s),
.RCLK%s(%s)
);
""" % (
rdata_bits-1, i, memtype, rmode, wmode, i,
bits_waddr, bits_raddr, bits_mask, bits_wdata, i,
bit_we, bit_wclke, wclksuffix, bit_wclk,
bit_re, bit_rclke, rclksuffix, bit_rclk
), file=f)
bits = list(np.random.permutation(bits))
for k in range(rdata_bits):
bits[k] = "rdata_%d[%d] ^ %s" % (i, k, bits[k])
print("assign out_pins = rdata_%d;" % i, file=f)
print("endmodule", file=f)
with open("work_ram40/ram40_%02d.pcf" % idx, "w") as f:
p = list(np.random.permutation(pins))
for i in range(60):
print("set_io in_pins[%d] %s" % (i, p.pop()), file=f)
for i in range(16):
print("set_io out_pins[%d] %s" % (i, p.pop()), file=f)
with open("work_ram40/Makefile", "w") as f:
print("all: %s" % " ".join(["ram40_%02d.bin" % i for i in range(num)]), file=f)
for i in range(num):
print("ram40_%02d.bin:" % i, file=f)
print("\t-bash ../icecube.sh ram40_%02d > ram40_%02d.log 2>&1 && rm -rf ram40_%02d.tmp || tail ram40_%02d.log" % (i, i, i, i), file=f)

View File

@ -0,0 +1,33 @@
#!/bin/bash
pins="
1 2 3 4 7 8 9 10 11 12 19 20 21 22 23 24 25 26 28 29 31 32 33 34
37 38 39 41 42 43 44 45 47 48 49 50 52 56 58 60 61 62 63 64 67 68 70 71
73 74 75 76 78 79 80 81 87 88 90 91 93 94 95 96 97 98 99 101 102 104 105 106 107
112 113 114 115 116 117 118 119 120 121 122 128 129 134 135 136 137 138 139 141 142 143 144
"
{
echo -n "all:"
for pin in $pins; do
id="pinloc-1k-tq144_${pin}"
echo -n " ${id}.exp"
done
echo
for pin in $pins; do
id="pinloc-1k-tq144_${pin}"
echo "module top(output y); assign y = 0; endmodule" > ${id}.v
echo "set_io y ${pin}" >> ${id}.pcf
echo; echo "${id}.exp:"
echo " ICEDEV=hx1k-tq144 bash ../icecube.sh ${id} > ${id}.log 2>&1"
echo " ../../icebox/icebox_explain.py ${id}.txt > ${id}.exp.new"
echo " rm -rf ${id}.tmp"
echo " mv ${id}.exp.new ${id}.exp"
done
} > pinloc-1k-tq144.mk
set -ex
make -f pinloc-1k-tq144.mk -j4
python pinlocdb.py pinloc-1k-tq144_*.exp > pinloc-1k-tq144.txt

View File

@ -0,0 +1,44 @@
#!/bin/bash
pins="
A1 A2 A5 A6 A7 A9 A10 A11 A15 A16
B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C16
D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D13 D14 D15 D16
E2 E3 E4 E5 E6 E9 E10 E11 E13 E14 E16
F1 F2 F3 F4 F5 F7 F9 F11 F12 F13 F14 F15 F16
G1 G2 G3 G4 G5 G10 G11 G12 G13 G14 G15 G16
H1 H2 H3 H4 H5 H6 H11 H12 H13 H14 H16
J1 J2 J3 J4 J5 J10 J11 J12 J13 J14 J15 J16
K1 K3 K4 K5 K9 K11 K12 K13 K14 K15 K16
L1 L3 L4 L5 L6 L7 L9 L10 L11 L12 L13 L14 L16
M1 M2 M3 M4 M5 M6 M7 M8 M9 M11 M12 M13 M14 M15 M16
N2 N3 N4 N5 N6 N7 N9 N10 N12 N16
P1 P2 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16
R1 R2 R3 R4 R5 R6 R9 R10 R11 R12 R14 R15 R16
T1 T2 T3 T5 T6 T7 T8 T9 T10 T11 T13 T14 T15 T16
"
{
echo -n "all:"
for pin in $pins; do
id="pinloc-8k-ct256_${pin}"
echo -n " ${id}.exp"
done
echo
for pin in $pins; do
id="pinloc-8k-ct256_${pin}"
echo "module top(output y); assign y = 0; endmodule" > ${id}.v
echo "set_io y ${pin}" >> ${id}.pcf
echo; echo "${id}.exp:"
echo " ICEDEV=hx8k-ct256 bash ../icecube.sh ${id} > ${id}.log 2>&1"
echo " ../../icebox/icebox_explain.py ${id}.txt > ${id}.exp.new"
echo " rm -rf ${id}.tmp"
echo " mv ${id}.exp.new ${id}.exp"
done
} > pinloc-8k-ct256.mk
set -ex
make -f pinloc-8k-ct256.mk -j4
python pinlocdb.py pinloc-8k-ct256_*.exp > pinloc-8k-ct256.txt

View File

@ -0,0 +1,46 @@
#!/usr/bin/python
from __future__ import division
from __future__ import print_function
import re
from sys import argv
ieren_db = [ ]
pinloc_db = [ ]
for arg in argv[1:]:
pin = re.search(r"_([^.]*)", arg).group(1)
with open(arg, "r") as f:
tile = [0, 0]
iob = [0, 0, 0]
ioctrl = [0, 0, 0]
for line in f:
match = re.match(r"^\.io_tile (\d+) (\d+)", line)
if match:
tile = [int(match.group(1)), int(match.group(2))]
match = re.match(r"^IOB_(\d+)", line)
if match:
iob = tile + [int(match.group(1))]
match = re.match(r"^IoCtrl REN_(\d+)", line)
if match:
ioctrl = tile + [int(match.group(1))]
ieren_db.append(tuple(iob + ioctrl))
pinloc_db.append(tuple(['"' + pin + '"'] + iob))
print()
print("# ieren_db")
for entry in sorted(ieren_db):
print("(%2d, %2d, %d, %2d, %2d, %d)," % entry)
print()
print("# pinloc_db")
for entry in sorted(pinloc_db):
print("(%5s, %2d, %2d, %d)," % entry)
print()

19
icefuzz/runloop.sh Normal file
View File

@ -0,0 +1,19 @@
#!/bin/bash
i=0
while true; do
echo; svn diff cached_*.txt | diffstat
echo; echo -n "[$(date '+%H:%M:%S')] Iteration $(( ++i )) "
{ echo; echo; echo; echo; echo; echo; echo "Iteration $i"; date; } >> runloop.log
if make clean > >( gawk '{ print >> "runloop.log"; printf("x"); fflush(""); }'; ) 2>&1 &&
make -j6 > >( gawk '{ print >> "runloop.log"; printf("m"); fflush(""); }'; ) 2>&1 &&
make -j6 check > >( gawk '{ print >> "runloop.log"; if (NR % 100 == 0) printf("c"); fflush(""); }'; ) 2>&1
then
echo -n " OK"
else
echo " ERROR"; echo
tail runloop.log
exit 1
fi
done

Binary file not shown.

3
icefuzz/tests/bitop.pcf Normal file
View File

@ -0,0 +1,3 @@
set_io a 1
set_io b 10
set_io y 11

3
icefuzz/tests/bitop.v Normal file
View File

@ -0,0 +1,3 @@
module top (input a, b, output y);
assign y = a & b;
endmodule

1
icefuzz/tests/bram.pcf Normal file
View File

@ -0,0 +1 @@
set_location ram 3 1

40
icefuzz/tests/bram.v Normal file
View File

@ -0,0 +1,40 @@
module top (
input clk,
input [15:0] wdata,
output [15:0] rdata,
input [7:0] addr
);
SB_RAM40_4K #(
.WRITE_MODE(0),
.READ_MODE(0)
) ram (
.RDATA(rdata),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(1'b1),
.MASK(16'b0)
);
defparam ram.INIT_0 = 256'h123456789abcdef00000dddd0000eeee00000012483569ac0111044400000001;
defparam ram.INIT_1 = 256'h56789abcdef123400000dddd0000eeee00000012483569ac0111044401000002;
defparam ram.INIT_2 = 256'habcdef12345678900000dddd0000eeee00000012483569ac0111044402000004;
defparam ram.INIT_3 = 256'h00000000000000000000dddd0000eeee00000012483569ac0111044403000008;
defparam ram.INIT_4 = 256'hffff000022220000444400006666000088880012483569ac0111044404000010;
defparam ram.INIT_5 = 256'hffff000022220000444400006666000088880012483569ac0111044405000020;
defparam ram.INIT_6 = 256'hffff000022220000444400006666000088880012483569ac0111044406000040;
defparam ram.INIT_7 = 256'hffff000022220000444400006666000088880012483569ac0111044407000080;
defparam ram.INIT_8 = 256'h0000111100003333000055550000777700000012483569ac0111044408000100;
defparam ram.INIT_9 = 256'h0000111100003333000055550000777700000012483569ac0111044409000200;
defparam ram.INIT_A = 256'h0000111100003333000055550000777700000012483569ac011104440a000400;
defparam ram.INIT_B = 256'h0000111100003333000055550000777700000012483569ac011104440b000800;
defparam ram.INIT_C = 256'h0123000099990000aaaa0000bbbb0000cccc0012483569ac011104440c001000;
defparam ram.INIT_D = 256'h4567000099990000aaaa0000bbbb0000cccc0012483569ac011104440d002000;
defparam ram.INIT_E = 256'h89ab000099990000aaaa0000bbbb0000cccc0012483569ac011104440e004000;
defparam ram.INIT_F = 256'hcdef000099990000aaaa0000bbbb0000cccc0012483569ac011104440f008000;
endmodule

8
icefuzz/tests/carry.v Normal file
View File

@ -0,0 +1,8 @@
module top (input a, b, ci, output co);
SB_CARRY carry_cell (
.I0(a),
.I1(b),
.CI(ci),
.CO(co)
);
endmodule

22
icefuzz/tests/colbuf.py Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/python
import fileinput
colbuf_tile = None
glbnet_tile = None
for line in fileinput.input():
line = line.split()
if len(line) == 0:
continue
if line[0] in [".io_tile", ".logic_tile", ".ramb_tile", ".ramt_tile"]:
current_tile = (int(line[1]), int(line[2]))
if line[0] == "ColBufCtrl":
assert colbuf_tile is None
colbuf_tile = current_tile
if line[0] == "buffer" and line[1].startswith("glb_netwk_"):
assert glbnet_tile is None
glbnet_tile = current_tile
print("(%2d, %2d, %2d, %2d)," % (colbuf_tile[0], colbuf_tile[1], glbnet_tile[0], glbnet_tile[1]))

48
icefuzz/tests/colbuf.sh Normal file
View File

@ -0,0 +1,48 @@
#!/bin/bash
# for f in colbuf_io.work/*.exp colbuf_logic.work/*.exp colbuf_ram.work/*.exp; do
# python colbuf.py $f
# done | sort -u > colbuf.txt
get_colbuf_data()
{
# tr -d '(,)' < colbuf.txt
for x in {0..2} {4..9} {11..13}; do
echo $x 4 $x 0
echo $x 5 $x 8
echo $x 12 $x 9
echo $x 13 $x 17
done
for x in 3 10; do
echo $x 3 $x 0
echo $x 3 $x 4
echo $x 5 $x 8
echo $x 11 $x 9
echo $x 11 $x 12
echo $x 13 $x 17
done
}
{
echo "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"580\" width=\"460\">"
for x in {1..13}; do
echo "<line x1=\"$((10+x*30))\" y1=\"10\" x2=\"$((10+x*30))\" y2=\"$((10+18*30))\" style=\"stroke:rgb(0,0,0);stroke-width:3\" />"
done
for y in {1..17}; do
echo "<line x1=\"10\" y1=\"$((10+y*30))\" x2=\"$((10+14*30))\" y2=\"$((10+y*30))\" style=\"stroke:rgb(0,0,0);stroke-width:3\" />"
done
for x in {0..13}; do
echo "<text x=\"$((10+$x*30+7))\" y=\"$((10+18*30+15))\" fill=\"black\">$x</text>"
done
for y in {0..17}; do
echo "<text x=\"$((10+14*30+5))\" y=\"$((10+(17-y)*30+20))\" fill=\"black\">$y</text>"
done
while read x1 y1 x2 y2; do
echo "<line x1=\"$((10+x1*30+15))\" y1=\"$((10+(17-y1)*30+15))\" x2=\"$((10+x2*30+15))\" y2=\"$((10+(17-y2)*30+15))\" style=\"stroke:rgb(255,0,0);stroke-width:5\" />"
done < <( get_colbuf_data; )
while read x1 y1 x2 y2; do
echo "<circle cx=\"$((10+x1*30+15))\" cy=\"$((10+(17-y1)*30+15))\" r=\"5\" fill=\"gray\" />"
done < <( get_colbuf_data; )
echo "</svg>"
} > colbuf.svg

View File

@ -0,0 +1,52 @@
#!/bin/bash
for f in colbuf_io_8k.work/*.exp colbuf_logic_8k.work/*.exp colbuf_ram_8k.work/*.exp; do
echo $f >&2
python colbuf.py $f
done | sort -u > colbuf_8k.txt
get_colbuf_data()
{
tr -d '(,)' < colbuf_8k.txt
# for x in {0..2} {4..9} {11..13}; do
# echo $x 4 $x 0
# echo $x 5 $x 8
# echo $x 12 $x 9
# echo $x 13 $x 17
# done
# for x in 3 10; do
# echo $x 3 $x 0
# echo $x 3 $x 4
# echo $x 5 $x 8
# echo $x 11 $x 9
# echo $x 11 $x 12
# echo $x 13 $x 17
# done
}
{
echo "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1050\" width=\"1050\">"
for x in {1..33}; do
echo "<line x1=\"$((10+x*30))\" y1=\"10\" x2=\"$((10+x*30))\" y2=\"$((10+34*30))\" style=\"stroke:rgb(0,0,0);stroke-width:3\" />"
done
for y in {1..33}; do
echo "<line x1=\"10\" y1=\"$((10+y*30))\" x2=\"$((10+34*30))\" y2=\"$((10+y*30))\" style=\"stroke:rgb(0,0,0);stroke-width:3\" />"
done
for x in {0..33}; do
echo "<text x=\"$((10+$x*30+7))\" y=\"$((10+34*30+15))\" fill=\"black\">$x</text>"
done
for y in {0..33}; do
echo "<text x=\"$((10+34*30+5))\" y=\"$((10+(33-y)*30+20))\" fill=\"black\">$y</text>"
done
while read x1 y1 x2 y2; do
echo "<line x1=\"$((10+x1*30+15))\" y1=\"$((10+(33-y1)*30+15))\" x2=\"$((10+x2*30+15))\" y2=\"$((10+(33-y2)*30+15))\" style=\"stroke:rgb(255,0,0);stroke-width:5\" />"
done < <( get_colbuf_data; )
while read x1 y1 x2 y2; do
echo "<circle cx=\"$((10+x2*30+15))\" cy=\"$((10+(33-y2)*30+15))\" r=\"4\" fill=\"blue\" />"
done < <( get_colbuf_data; )
while read x1 y1 x2 y2; do
echo "<circle cx=\"$((10+x1*30+15))\" cy=\"$((10+(33-y1)*30+15))\" r=\"5\" fill=\"gray\" />"
done < <( get_colbuf_data; )
echo "</svg>"
} > colbuf_8k.svg

View File

@ -0,0 +1,38 @@
#!/bin/bash
set -ex
mkdir -p colbuf_io.work
cd colbuf_io.work
glb_pins="93 21 128 50 20 94 49 129"
pins="
1 2 3 4 7 8 9 10 11 12 19 22 23 24 25 26 28 29 31 32 33 34
37 38 41 42 43 44 45 47 48 52 56 58 60 61 62 63 64
73 74 75 76 78 79 80 81 87 88 90 91 95 96 97 98 101 102 104 105 106 107
112 113 114 115 116 117 118 119 120 121 122 134 135 136 137 138 139 141 142 143 144
"
pins="$( echo $pins )"
for pin in $pins; do
pf="colbuf_io_$pin"
gpin=$( echo $glb_pins | tr ' ' '\n' | grep -v $pin | sort -R | head -n1; )
cat > ${pf}.v <<- EOT
module top (input clk, data, output pin);
SB_IO #(
.PIN_TYPE(6'b 0101_00)
) pin_obuf (
.PACKAGE_PIN(pin),
.OUTPUT_CLK(clk),
.D_OUT_0(data)
);
endmodule
EOT
echo "set_io pin $pin" > ${pf}.pcf
echo "set_io clk $gpin" >> ${pf}.pcf
bash ../../icecube.sh ${pf}.v > ${pf}.log 2>&1
../../../icebox/icebox_explain.py ${pf}.txt > ${pf}.exp
rm -rf ${pf}.tmp
done

View File

@ -0,0 +1,50 @@
#!/bin/bash
set -ex
mkdir -p colbuf_io_8k.work
cd colbuf_io_8k.work
glb_pins="C8 F7 G1 H11 H16 J3 K9 R9"
pins="
A1 A2 A5 A6 A7 A9 A10 A11 A15 A16
B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C16
D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D13 D14 D15 D16
E2 E3 E4 E5 E6 E9 E10 E11 E13 E14 E16
F1 F2 F3 F4 F5 F7 F9 F11 F12 F13 F14 F15 F16
G1 G2 G3 G4 G5 G10 G11 G12 G13 G14 G15 G16
H1 H2 H3 H4 H5 H6 H11 H12 H13 H14 H16
J1 J2 J3 J4 J5 J10 J11 J12 J13 J14 J15 J16
K1 K3 K4 K5 K9 K11 K12 K13 K14 K15 K16
L1 L3 L4 L5 L6 L7 L9 L10 L11 L12 L13 L14 L16
M1 M2 M3 M4 M5 M6 M7 M8 M9 M11 M12 M13 M14 M15 M16
N2 N3 N4 N5 N6 N7 N9 N10 N12 N16
P1 P2 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16
R1 R2 R3 R4 R5 R6 R9 R10 R11 R12 R14 R15 R16
T1 T2 T3 T5 T6 T7 T8 T9 T10 T11 T13 T14 T15 T16
"
pins="$( echo $pins )"
for pin in $pins; do
pf="colbuf_io_8k_$pin"
gpin=$( echo $glb_pins | tr ' ' '\n' | grep -v $pin | sort -R | head -n1; )
cat > ${pf}.v <<- EOT
module top (input clk, data, output pin);
SB_IO #(
.PIN_TYPE(6'b 0101_00)
) pin_obuf (
.PACKAGE_PIN(pin),
.OUTPUT_CLK(clk),
.D_OUT_0(data)
);
endmodule
EOT
echo "set_io pin $pin" > ${pf}.pcf
echo "set_io clk $gpin" >> ${pf}.pcf
ICEDEV=hx8k-ct256 bash ../../icecube.sh ${pf}.v > ${pf}.log 2>&1
../../../icebox/icebox_explain.py ${pf}.txt > ${pf}.exp
rm -rf ${pf}.tmp
done

View File

@ -0,0 +1,29 @@
#!/bin/bash
set -ex
mkdir -p colbuf_logic.work
cd colbuf_logic.work
glb_pins="93 21 128 50 20 94 49 129"
for x in 1 2 {4..9} 11 12; do
for y in {1..16}; do
pf="colbuf_logic_${x}_${y}"
gpin=$( echo $glb_pins | tr ' ' '\n' | sort -R | head -n1; )
cat > ${pf}.v <<- EOT
module top (input c, d, output q);
SB_DFF dff (
.C(c),
.D(d),
.Q(q)
);
endmodule
EOT
echo "set_location dff $x $y 0" > ${pf}.pcf
echo "set_io c $gpin" >> ${pf}.pcf
bash ../../icecube.sh ${pf}.v > ${pf}.log 2>&1
../../../icebox/icebox_explain.py ${pf}.txt > ${pf}.exp
rm -rf ${pf}.tmp
done; done

View File

@ -0,0 +1,29 @@
#!/bin/bash
set -ex
mkdir -p colbuf_logic_8k.work
cd colbuf_logic_8k.work
glb_pins="C8 F7 G1 H11 H16 J3 K9 R9"
for x in {1..7} {9..24} {26..32}; do
for y in {1..32}; do
pf="colbuf_logic_8k_${x}_${y}"
gpin=$( echo $glb_pins | tr ' ' '\n' | sort -R | head -n1; )
cat > ${pf}.v <<- EOT
module top (input c, d, output q);
SB_DFF dff (
.C(c),
.D(d),
.Q(q)
);
endmodule
EOT
echo "set_location dff $x $y 0" > ${pf}.pcf
echo "set_io c $gpin" >> ${pf}.pcf
ICEDEV=hx8k-ct256 bash ../../icecube.sh ${pf}.v > ${pf}.log 2>&1
../../../icebox/icebox_explain.py ${pf}.txt > ${pf}.exp
rm -rf ${pf}.tmp
done; done

View File

@ -0,0 +1,57 @@
#!/bin/bash
set -ex
mkdir -p colbuf_ram.work
cd colbuf_ram.work
glb_pins="93 21 128 50 20 94 49 129"
for x in 3 10; do
for y in {1..16}; do
pf="colbuf_ram_${x}_${y}"
gpin=$( echo $glb_pins | tr ' ' '\n' | sort -R | head -n1; )
if [ $((y % 2)) == 1 ]; then
clkport="WCLK"
other_clkport="RCLK"
else
clkport="RCLK"
other_clkport="WCLK"
fi
cat > ${pf}.v <<- EOT
module top (input c, oc, input [1:0] d, output [1:0] q);
wire gc;
SB_GB_IO #(
.PIN_TYPE(6'b 0000_00),
.PULLUP(1'b0),
.NEG_TRIGGER(1'b0),
.IO_STANDARD("SB_LVCMOS")
) gbuf (
.PACKAGE_PIN(c),
.GLOBAL_BUFFER_OUTPUT(gc)
);
SB_RAM40_4K #(
.READ_MODE(3),
.WRITE_MODE(3)
) ram40 (
.WADDR(11'b0),
.RADDR(11'b0),
.$clkport(gc),
.$other_clkport(oc),
.RDATA(q),
.WDATA(d),
.WE(1'b1),
.WCLKE(1'b1),
.RE(1'b1),
.RCLKE(1'b1)
);
endmodule
EOT
echo "set_location ram40 $x $((y - (1 - y%2))) 0" > ${pf}.pcf
echo "set_io oc 1" >> ${pf}.pcf
echo "set_io c $gpin" >> ${pf}.pcf
bash ../../icecube.sh ${pf}.v > ${pf}.log 2>&1
../../../icebox/icebox_explain.py ${pf}.txt > ${pf}.exp
rm -rf ${pf}.tmp
done; done

View File

@ -0,0 +1,57 @@
#!/bin/bash
set -ex
mkdir -p colbuf_ram_8k.work
cd colbuf_ram_8k.work
glb_pins="C8 F7 G1 H11 H16 J3 K9 R9"
for x in 8 25; do
for y in {1..32}; do
pf="colbuf_ram_8k_${x}_${y}"
gpin=$( echo $glb_pins | tr ' ' '\n' | sort -R | head -n1; )
if [ $((y % 2)) == 1 ]; then
clkport="WCLK"
other_clkport="RCLK"
else
clkport="RCLK"
other_clkport="WCLK"
fi
cat > ${pf}.v <<- EOT
module top (input c, oc, input [1:0] d, output [1:0] q);
wire gc;
SB_GB_IO #(
.PIN_TYPE(6'b 0000_00),
.PULLUP(1'b0),
.NEG_TRIGGER(1'b0),
.IO_STANDARD("SB_LVCMOS")
) gbuf (
.PACKAGE_PIN(c),
.GLOBAL_BUFFER_OUTPUT(gc)
);
SB_RAM40_4K #(
.READ_MODE(3),
.WRITE_MODE(3)
) ram40 (
.WADDR(11'b0),
.RADDR(11'b0),
.$clkport(gc),
.$other_clkport(oc),
.RDATA(q),
.WDATA(d),
.WE(1'b1),
.WCLKE(1'b1),
.RE(1'b1),
.RCLKE(1'b1)
);
endmodule
EOT
echo "set_location ram40 $x $((y - (1 - y%2))) 0" > ${pf}.pcf
echo "set_io oc 1" >> ${pf}.pcf
echo "set_io c $gpin" >> ${pf}.pcf
ICEDEV=hx8k-ct256 bash ../../icecube.sh ${pf}.v > ${pf}.log 2>&1
../../../icebox/icebox_explain.py ${pf}.txt > ${pf}.exp
rm -rf ${pf}.tmp
done; done

17
icefuzz/tests/cross_0.pcf Normal file
View File

@ -0,0 +1,17 @@
# row 14, block 0
set_io in_left 2
set_io out_right 104
# row 4, block 0
set_io out_left 29
set_io in_right 79
# col 4, block 0
set_io in_bottom 44
set_io out_top 137
# col 8, block 0
set_io out_bottom 58
set_io in_top 121

9
icefuzz/tests/cross_0.v Normal file
View File

@ -0,0 +1,9 @@
module top (
input in_left, in_right, in_top, in_bottom,
output out_left, out_right, out_top, out_bottom
);
assign out_left = in_right;
assign out_right = in_left;
assign out_top = in_bottom;
assign out_bottom = in_top;
endmodule

View File

@ -0,0 +1,9 @@
set_io LED0 B5
set_io LED1 B4
set_io LED2 A2
set_io LED3 A1
set_io LED4 C5
set_io LED5 C4
set_io LED6 B3
set_io LED7 C3
set_io clk J3

View File

@ -0,0 +1 @@
create_clock -period 10.00 -name {top|clk} [get_ports {clk}]

View File

@ -0,0 +1,2 @@
#!/bin/bash
ICEDEV=hx8k-ct256 bash ../icecube.sh example_hx8kboard.v

View File

@ -0,0 +1,32 @@
module top (
input clk,
output LED0,
output LED1,
output LED2,
output LED3,
output LED4,
output LED5,
output LED6,
output LED7
);
localparam BITS = 8;
localparam LOG2DELAY = 22;
function [BITS-1:0] bin2gray(input [BITS-1:0] in);
integer i;
reg [BITS:0] temp;
begin
temp = in;
for (i=0; i<BITS; i=i+1)
bin2gray[i] = ^temp[i +: 2];
end
endfunction
reg [BITS+LOG2DELAY-1:0] counter = 0;
always@(posedge clk)
counter <= counter + 1;
assign {LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7} = bin2gray(counter >> LOG2DELAY);
endmodule

View File

@ -0,0 +1,6 @@
set_io LED1 99
set_io LED2 98
set_io LED3 97
set_io LED4 96
set_io LED5 95
set_io clk 21

View File

@ -0,0 +1 @@
create_clock -period 10.00 -name {top|clk} [get_ports {clk}]

View File

@ -0,0 +1,2 @@
#!/bin/bash
bash ../icecube.sh example_icestick.v

View File

@ -0,0 +1,29 @@
module top (
input clk,
output LED1,
output LED2,
output LED3,
output LED4,
output LED5
);
localparam BITS = 5;
localparam LOG2DELAY = 22;
function [BITS-1:0] bin2gray(input [BITS-1:0] in);
integer i;
reg [BITS:0] temp;
begin
temp = in;
for (i=0; i<BITS; i=i+1)
bin2gray[i] = ^temp[i +: 2];
end
endfunction
reg [BITS+LOG2DELAY-1:0] counter = 0;
always@(posedge clk)
counter <= counter + 1;
assign {LED1, LED2, LED3, LED4, LED5} = bin2gray(counter >> LOG2DELAY);
endmodule

View File

@ -0,0 +1,4 @@
set_io din_0 33
set_io global 97
set_io latch_in 112
set_io pin_gb_io 0 9 0

18
icefuzz/tests/icegate.v Normal file
View File

@ -0,0 +1,18 @@
module top (
inout pin,
input latch_in,
output din_0,
output global
);
SB_GB_IO #(
.PIN_TYPE(6'b 0000_11),
.PULLUP(1'b 0),
.NEG_TRIGGER(1'b 0),
.IO_STANDARD("SB_LVCMOS")
) \pin_gb_io (
.PACKAGE_PIN(pin),
.LATCH_INPUT_VALUE(latch_in),
.D_IN_0(din_0),
.GLOBAL_BUFFER_OUTPUT(globals)
);
endmodule

View File

@ -0,0 +1,10 @@
set_io in 1
set_io out 2
set_io pin[0] 20 # padin_4
set_io pin[1] 21 # padin_1
set_io pin[2] 49 # padin_6
set_io pin[3] 50 # padin_3
set_io pin[4] 93 # padin_0
set_io pin[5] 94 # padin_5
set_io pin[6] 128 # padin_2
set_io pin[7] 129 # padin_7

View File

@ -0,0 +1,42 @@
module top (
inout [7:0] pin,
input in,
output out
);
wire [7:0] glbl, clk;
reg [7:0] q;
SB_GB_IO #(
.PIN_TYPE(6'b 0000_11),
.PULLUP(1'b0),
.NEG_TRIGGER(1'b0),
.IO_STANDARD("SB_LVCMOS")
) PIO[7:0] (
.PACKAGE_PIN(pin),
.LATCH_INPUT_VALUE(1'b1),
.CLOCK_ENABLE(),
.INPUT_CLK(),
.OUTPUT_CLK(),
.OUTPUT_ENABLE(),
.D_OUT_0(),
.D_OUT_1(),
.D_IN_0(),
.D_IN_1(),
.GLOBAL_BUFFER_OUTPUT(glbl)
);
assign clk[0] = glbl[0]; // glb_netwk_4
assign clk[1] = glbl[1]; // glb_netwk_1
assign clk[2] = glbl[2]; // glb_netwk_6
assign clk[3] = glbl[3]; // glb_netwk_3
assign clk[4] = glbl[4]; // glb_netwk_0
assign clk[5] = glbl[5]; // glb_netwk_5
assign clk[6] = glbl[6]; // glb_netwk_2
assign clk[7] = glbl[7]; // glb_netwk_7
genvar i;
generate for (i = 0; i < 8; i=i+1) begin
always @(posedge clk[i]) q[i] <= in;
end endgenerate
assign out = ^{q, in};
endmodule

View File

@ -0,0 +1,28 @@
#!/bin/bash
set -ex
mkdir -p io_latched.work
cd io_latched.work
pins="
1 2 3 4 7 8 9 10 11 12 19 22 23 24 25 26 28 29 31 32 33 34
37 38 41 42 43 44 45 47 48 52 56 58 60 61 62 63 64
73 74 75 76 78 79 80 81 87 88 90 91 95 96 97 98 101 102 104 105 106 107
112 113 114 115 116 117 118 119 120 121 122 134 135 136 137 138 139 141 142 143 144
"
pins="$( echo $pins )"
for pin in $pins; do
pf="io_latched_$pin"
cp ../io_latched.v ${pf}.v
read pin_latch pin_data < <( echo $pins | tr ' ' '\n' | grep -v $pin | sort -R; )
{
echo "set_io pin $pin"
echo "set_io latch_in $pin_latch"
echo "set_io data_out $pin_data"
} > ${pf}.pcf
bash ../../icecube.sh ${pf}.v
../../../icebox/icebox_vlog.py -SP ${pf}.psb ${pf}.txt > ${pf}.ve
done

View File

@ -0,0 +1,23 @@
module top (
inout pin,
input latch_in,
output data_out
);
SB_IO #(
.PIN_TYPE(6'b0000_11),
.PULLUP(1'b0),
.NEG_TRIGGER(1'b0),
.IO_STANDARD("SB_LVCMOS")
) pin_ibuf (
.PACKAGE_PIN(pin),
.LATCH_INPUT_VALUE(latch_in),
.CLOCK_ENABLE(),
.INPUT_CLK(),
.OUTPUT_CLK(),
.OUTPUT_ENABLE(),
.D_OUT_0(),
.D_OUT_1(),
.D_IN_0(data_out),
.D_IN_1()
);
endmodule

21
icefuzz/tests/ioctrl.py Normal file
View File

@ -0,0 +1,21 @@
#!/usr/bin/python
import fileinput
for line in fileinput.input():
line = line.split()
if len(line) == 0:
continue
if line[0] == ".io_tile":
current_tile = (int(line[1]), int(line[2]))
if line[0] == "IoCtrl" and line[1] == "REN_0":
ren = (current_tile[0], current_tile[1], 0)
if line[0] == "IoCtrl" and line[1] == "REN_1":
ren = (current_tile[0], current_tile[1], 1)
if line[0] == "IOB_0":
iob = (current_tile[0], current_tile[1], 0)
if line[0] == "IOB_1":
iob = (current_tile[0], current_tile[1], 1)
print("(%2d, %2d, %2d, %2d, %2d, %2d)," % (iob[0], iob[1], iob[2], ren[0], ren[1], ren[2]))

30
icefuzz/tests/ioctrl.sh Normal file
View File

@ -0,0 +1,30 @@
#!/bin/bash
set -ex
mkdir -p ioctrl.work
cd ioctrl.work
pins="
1 2 3 4 7 8 9 10 11 12 19 20 21 22 23 24 25 26 28 29 31 32 33 34
37 38 39 41 42 43 44 45 47 48 49 50 52 56 58 60 61 62 63 64 67 68 70 71
73 74 75 76 78 79 80 81 87 88 90 91 93 94 95 96 97 98 99 101 102 104 105 106 107
112 113 114 115 116 117 118 119 120 121 122 128 129 134 135 136 137 138 139 141 142 143 144
"
pins="$( echo $pins )"
for pin in $pins; do
pf="ioctrl_$pin"
echo "module top (output pin); assign pin = 1; endmodule" > ${pf}.v
echo "set_io pin $pin" > ${pf}.pcf
bash ../../icecube.sh ${pf}.v > ${pf}.log 2>&1
../../../icebox/icebox_explain.py ${pf}.txt > ${pf}.exp
done
set +x
echo "--snip--"
for pin in $pins; do
python ../ioctrl.py ioctrl_${pin}.exp
done | tee ioctrl_db.txt
echo "--snap--"

View File

@ -0,0 +1,2 @@
set_location dst_lut 6 8 2 # SB_LUT4 (LogicCell: dst_lut_LC_0)
set_location src_lut 6 8 1 # SB_LUT4 (LogicCell: src_lut_LC_1)

View File

@ -0,0 +1,23 @@
module top (input a, b, c, d, e, f, g, output y);
wire cascade;
SB_LUT4 #(
.LUT_INIT(16'b 1100_1100_1100_1010)
) src_lut (
.O(cascade),
.I0(a),
.I1(b),
.I2(c),
.I3(d)
);
SB_LUT4 #(
.LUT_INIT(16'b 1000_0100_0010_0001)
) dst_lut (
.O(y),
.I0(e),
.I1(f),
.I2(cascade),
.I3(g)
);
endmodule

View File

@ -0,0 +1,16 @@
set_location ram_0301 3 1
set_location ram_0303 3 3
set_location ram_0305 3 5
set_location ram_0307 3 7
set_location ram_0309 3 9
set_location ram_0311 3 11
set_location ram_0313 3 13
set_location ram_0315 3 15
set_location ram_1001 10 1
set_location ram_1003 10 3
set_location ram_1005 10 5
set_location ram_1007 10 7
set_location ram_1009 10 9
set_location ram_1011 10 11
set_location ram_1013 10 13
set_location ram_1015 10 15

490
icefuzz/tests/raminits.v Normal file
View File

@ -0,0 +1,490 @@
// tmpfiles/ex_00.v
module top (
input clk,
input [7:0] sel,
input [15:0] wdata,
output [15:0] rdata,
input [7:0] addr
);
wire [15:0] rdata_0301;
SB_RAM256x16 ram_0301 (
.RDATA(rdata_0301),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 0),
.MASK(16'b0)
);
defparam ram_0301.INIT_0 = 256'heee7d4195b1ee583e83766c47c4279255c36fac37ffa2db1c7978834c0a7b756;
defparam ram_0301.INIT_1 = 256'haf36df1852690a6f4bd5a70c8cdc7ace32570591bdc9da916fdfebbf250ee920;
defparam ram_0301.INIT_2 = 256'h062ec86b566ae81511bdb1c797b09358fd7b8b55a4033809181a8590636ebc4a;
defparam ram_0301.INIT_3 = 256'he5647bccd28fcd7e1175dd08c07eee22b5f7a76ce80b814acc913a8bf6272489;
defparam ram_0301.INIT_4 = 256'h847367636b8515d939efbb8e215509b3639c2d42650023fde29a300331ea02dd;
defparam ram_0301.INIT_5 = 256'h1bfed331fc20e7d3855f6f57b704e77098ad9921daa03a251a0d4750cfdb8c5c;
defparam ram_0301.INIT_6 = 256'h5796d45e174c10a14c1c6296d8e71d33a2601b790ac8ace68483a4095b8b2f2c;
defparam ram_0301.INIT_7 = 256'h5c02f2a5a09d26529a93bdc1c3b2dad1edbdba8729e3ba1447b96a823b5e6ddb;
defparam ram_0301.INIT_8 = 256'he6c0da7b269cb3b8213608a7c38a5eb224f7d37981f337e1b1f4e4aa13a330bc;
defparam ram_0301.INIT_9 = 256'hd8aab74a136340b43c44e69b99233b7657c1faf8795e6e6513e399eccf835d64;
defparam ram_0301.INIT_A = 256'h76da9bfa7def43d27b289046765ebad19bd9853133aa79e7a4c53b489266b78b;
defparam ram_0301.INIT_B = 256'hd0be66fe7f334ca37b5cfa6fcfb84f2b5d7b556e3b179da25cb20a4bcf285dbc;
defparam ram_0301.INIT_C = 256'he36823bd57f798408173ee4e1a138496a319039e28f783015ad938818b1ffeef;
defparam ram_0301.INIT_D = 256'h19ad3217524d84a9eed19f6a88a3e6f6f3e27c256534dcefe6721a2eaf27e104;
defparam ram_0301.INIT_E = 256'hbb5e5ef9246e61ee24121f2169dc1d755429486f030b7ae134f83c35915a2f44;
defparam ram_0301.INIT_F = 256'hf0b5e781fb75db80882e0641026b6c4df0e61dd31d84c2f44bbe7073ccad1d01;
wire [15:0] rdata_0303;
SB_RAM256x16 ram_0303 (
.RDATA(rdata_0303),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 1),
.MASK(16'b0)
);
defparam ram_0303.INIT_0 = 256'h2b668f5787aef8f5025f79512dcefc91d4bebc46513598e42c93d37c931d8923;
defparam ram_0303.INIT_1 = 256'h7b9a84f2d5f65df84d4157495ab21e01e152dd7a886c33cb614e382e7fed9eab;
defparam ram_0303.INIT_2 = 256'h878bdd512303597de1345a1cc680af906dabb3a7ad0ff50221288bce8af64881;
defparam ram_0303.INIT_3 = 256'he36b5511c45aec1bba20d1791c3ccfa39cf93bde842f184cc1a93d70520529d6;
defparam ram_0303.INIT_4 = 256'haf4b39a9fdfb42ccae9f2eea59845f5a8c2fb07035d64d71722f4d656b703c69;
defparam ram_0303.INIT_5 = 256'h4c0cacce82085c0931587d9e7f4e6d074746cca6744b4a3b0ab1b54ec03fc84e;
defparam ram_0303.INIT_6 = 256'he937cdb315288fbfdcaf1d77b698da022e5f6cf1b4fa3249d0d50eaf876466ae;
defparam ram_0303.INIT_7 = 256'h1bd6d490c00964563d3f8438a32966a8f5de9447eae7b0e63dbf930d2dad4faa;
defparam ram_0303.INIT_8 = 256'h55f0e909449d025ca05f81ffe6a71641b98694281522061a7d60fc84447395af;
defparam ram_0303.INIT_9 = 256'h03cbdbbb3afb93d1360dc27ee9bc65b9dd407010717a2e5d5a2e6d7195875aef;
defparam ram_0303.INIT_A = 256'hc8f9ceb334e4c22b1bfbd0321ab6762af2d10f9e67282aa4b3c0b4784c061708;
defparam ram_0303.INIT_B = 256'h4a49021a4cf723dca9d9dba93f8ae9f3d5be64f54d61b5b40646bc8f11418390;
defparam ram_0303.INIT_C = 256'hd579caee533c14990f0ef6e2307cbfd1252414b9384802fa7b434e40cc8b1f21;
defparam ram_0303.INIT_D = 256'h17ff7be7f32b4e90a04b999795a68ecf923fd605ae58d82f9ddf78adfff85572;
defparam ram_0303.INIT_E = 256'h41f8121524de634c0801dc5f8c04c8dec086b1f63d3e3a769c9cd63fd8132a72;
defparam ram_0303.INIT_F = 256'h32d4549b468eba9a49fb496ff2d11b8e43d138b24a800e49853a6aba5bb5c5a2;
wire [15:0] rdata_0305;
SB_RAM256x16 ram_0305 (
.RDATA(rdata_0305),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 2),
.MASK(16'b0)
);
defparam ram_0305.INIT_0 = 256'h172521cfcd66a4e54fdd281bea4e877d13357371970a607c4f1ec21bb92550c1;
defparam ram_0305.INIT_1 = 256'h570a6f1ceb613a885a738b85084a55cf2e1d619a5392390c972d53e0b3c11f5d;
defparam ram_0305.INIT_2 = 256'hb630e33faca35036486f0b8f94f0a4b21f804a2d82799ab121141b3ab1ba8df4;
defparam ram_0305.INIT_3 = 256'haf7d9e3eb70911e8af4f2a1aad6cbfaa69248b89b36c222f7b1a5c32aa3844a4;
defparam ram_0305.INIT_4 = 256'h273c5c3dcea0d9942168d6181aaaa30efbc3efd5fff73c7f30de4bdacd018779;
defparam ram_0305.INIT_5 = 256'h559c7a4af1d4c9204d935d10817727b1ca5c554580e8b28dfc9e2fd6f2c71e77;
defparam ram_0305.INIT_6 = 256'h418602bdff1e69af57af6a198e57a59c68443f3934fdd09ee68e630304166940;
defparam ram_0305.INIT_7 = 256'h54aac47c7be964002b6c71aec829d69dc6ef2ee6f3640279b8c7f7947b4a2e61;
defparam ram_0305.INIT_8 = 256'h32b50c21a7bdbdfac5909853b9d0fa8915dadc18f087070e30fba834d6eab209;
defparam ram_0305.INIT_9 = 256'h02742ea4a2b626738ce04c7f6b4472739f981a7dd37413214228c9446ab320cb;
defparam ram_0305.INIT_A = 256'h5c70fe89a21724eb2d36ded6fd01f47da78a97db0666e038cc5284ffaf5e66e1;
defparam ram_0305.INIT_B = 256'h7ffdc072c4f7abc5888f3d30aa097195aa54f18635ad8308e08d3cda939db459;
defparam ram_0305.INIT_C = 256'h159a2eaace991c51eb3c61abe9fe74af235d51f04ebabf0b2c0f0dfe6e3bb4e6;
defparam ram_0305.INIT_D = 256'h460ded1b0a7f120b23cd292508e5a575fa8fd66f3033b69ab189e110fae0d668;
defparam ram_0305.INIT_E = 256'hc72b4562d113f6f9c58ba44a7edf53b39b664357e12296fc389bd05d098311ee;
defparam ram_0305.INIT_F = 256'h69bb7c5e08c96718f7ad092ba30a40c3b4347572251976ab0d1cae6bbac50333;
wire [15:0] rdata_0307;
SB_RAM256x16 ram_0307 (
.RDATA(rdata_0307),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 3),
.MASK(16'b0)
);
defparam ram_0307.INIT_0 = 256'hf59c43dc52bc3d2b7bd85cd8c56aabb48969aae3721d16db0ff0524dabde709b;
defparam ram_0307.INIT_1 = 256'heff0fb7181e53b6512b080104e27b8e18c62780045a8106caf69951ca6173db4;
defparam ram_0307.INIT_2 = 256'hbfcb9c012c6c74f22b40ebe0369f994c9e409a65cd018bacb6dc6c3da36a6652;
defparam ram_0307.INIT_3 = 256'h7ea21da12871042efd405fe9998f635050a02f99e9b802cfec48d38fe984f30a;
defparam ram_0307.INIT_4 = 256'h5b659e0511fe236eb30e9fe92c5d69a637a10ab807a98eb567c2e914431a96fe;
defparam ram_0307.INIT_5 = 256'h6a7816f542396924307d31d55501a35849b2531f4ca596a29e84cb3c650b4062;
defparam ram_0307.INIT_6 = 256'he278bbc6ce05e58f6d15b005337aa2abdc6866ce8fc74cda53e9393909662f49;
defparam ram_0307.INIT_7 = 256'h353257b35760e5d107ec73be367dbcef8e9d6f4c227f436758f569bc325ac59f;
defparam ram_0307.INIT_8 = 256'h83609202f72286d35700331a86c68f0b1f20d8c0dd39bf0e7652cda584bec453;
defparam ram_0307.INIT_9 = 256'hf24f9f1dca3539dcc73bd15a1c3b12e4f27d864325c1eb2f5f7c5e9ab0c6ec68;
defparam ram_0307.INIT_A = 256'h2f41690287a95877a8637624974e1d779aa82daa7f1439733a7bcd7ee6a7d6df;
defparam ram_0307.INIT_B = 256'h4d3e73056bebe5184c7fbacd65b2862c66c425d3b82ac573ab4b325035a9cff1;
defparam ram_0307.INIT_C = 256'hf2dd4cf5279f86c413dc082dfc3b8e1dd913b59118dac6c99cde6e4a487316a2;
defparam ram_0307.INIT_D = 256'haa901c2b6d47194f2157465b276bc2cb30c8af04f6372384f969e26235a1fc6b;
defparam ram_0307.INIT_E = 256'h7cacd0b5a31ca17fdf94837ffa560342e9aa8ec69626dfd0b33b4df263d1fb88;
defparam ram_0307.INIT_F = 256'h0da63678ff1980428f183ce9f9317dd0f2e0ad40f9c55b89342db6e18b832977;
wire [15:0] rdata_0309;
SB_RAM256x16 ram_0309 (
.RDATA(rdata_0309),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 4),
.MASK(16'b0)
);
defparam ram_0309.INIT_0 = 256'h07a51489176ecf26b26ba3d3f4acb14b927e4f80c1a3333e79f52b87d0052eba;
defparam ram_0309.INIT_1 = 256'he542c4ed986aef41e2c1f1f1e0eff957f5f7fe3c1a956f1b7e73f6c12c3e7b35;
defparam ram_0309.INIT_2 = 256'h08e0d0315d86c998bfce1650d75c4cba11db471ff568d0ad39078ee3ad2dd5ae;
defparam ram_0309.INIT_3 = 256'h0624c556f3b27168ca874071a2c037eba979cb6738a8983c26017669cd44f3f9;
defparam ram_0309.INIT_4 = 256'h8f3727f57d00cdfdb0766c85a68bb59c52691d4b154bc2017cb2f0cf9deac2de;
defparam ram_0309.INIT_5 = 256'he2d9ad2f0193ddb2ca738bed9d69fff0c4e181c5f6534a986fcb65d1756b0f5d;
defparam ram_0309.INIT_6 = 256'hd28fc8443c5006206c35efd0fb2e0504f8d08f788e276b9f642d6837897906bc;
defparam ram_0309.INIT_7 = 256'h9d25639c0a8e04cdb1fd5e02583734811a349e6ebfb3913e775e5fc09dbd8536;
defparam ram_0309.INIT_8 = 256'h845c59e1f7c470abce8fa54120e38a9ff002c46c0eb2b651d3120627df47fa65;
defparam ram_0309.INIT_9 = 256'h709ef0f92579008ec26a7bb4aa70870557693cc59c4e16347e23574429b1acaa;
defparam ram_0309.INIT_A = 256'hd3553eac767b972d7cbec91901fdf203768c337577e599929a02788bab131ba2;
defparam ram_0309.INIT_B = 256'hbcb398877ab4e802f93de666ee53147b4104a883e8fc58f704764bb0377457aa;
defparam ram_0309.INIT_C = 256'hcb6bcd60cbeec7d69627cb56da8e829171c72a8f9ae075ca73146cb3bb33895f;
defparam ram_0309.INIT_D = 256'hec0a7b61ca77b184a5da828074adee07b0bdaf9d3a75f0b4e496228906882c96;
defparam ram_0309.INIT_E = 256'h4fcaff83f49c993e1344167d32660a6693a730fa2f29d5d4cab9063853bd7bbe;
defparam ram_0309.INIT_F = 256'h0238e69d220727869654edd6fa05d2e9f17b82827fdf7e151d0078147fe5bdff;
wire [15:0] rdata_0311;
SB_RAM256x16 ram_0311 (
.RDATA(rdata_0311),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 5),
.MASK(16'b0)
);
defparam ram_0311.INIT_0 = 256'h1e29fa340abb28a034d044905ef2b7aa08b76a1dafc7e743bdfc4fe88d77bb02;
defparam ram_0311.INIT_1 = 256'h2fed2793ab9de32ba8d11df985a68371bdfb9564ccb8c12c63aa9c968b95b348;
defparam ram_0311.INIT_2 = 256'hc3603ba144d8f2e8273b7762172a862f179e043fc755912fe840c60eb0aafc5f;
defparam ram_0311.INIT_3 = 256'hbe3c00c259e270eec9ab5ca99a40653662bdc9ba0b0742eddc9da27441c29907;
defparam ram_0311.INIT_4 = 256'h2effdb8a2a1ad09741d463bafe42d24e684e5c271cb64911f33651abb2554217;
defparam ram_0311.INIT_5 = 256'h3d12ab8b32a2f8e90e616ba6136747522f6ef4b3ef3231750a6a6da587c46544;
defparam ram_0311.INIT_6 = 256'hb9b1d4f05a71ca7bc92e7ef599655af7ca4abdc9a6bdb0ca6c9a1b2de1b67e6f;
defparam ram_0311.INIT_7 = 256'ha2601f9d00bcab3ca1ec26151124156e6cf0f2c45f4761bdfb4f3ea6d0b9789c;
defparam ram_0311.INIT_8 = 256'h16012927b00b193efde7ca215c88573280cea742d31623de3e0ed88b5a08e23c;
defparam ram_0311.INIT_9 = 256'h5b1657e14902f7c08b6c154f96e04192d52439983d0a5c8810d0462f45d1c091;
defparam ram_0311.INIT_A = 256'hdc67eaa704ff2aa09386be4dc9448074c427139cbb5118273a954a53838ffecf;
defparam ram_0311.INIT_B = 256'h347c2253402c45890e871a1dbe53cd91e98b3cb4c1884c349e9536fcc1e5b53f;
defparam ram_0311.INIT_C = 256'hc22e14b25ffdfb89a0556700e8171d0dfc84eb865898e6280cdbf0dbf51ec78c;
defparam ram_0311.INIT_D = 256'h9fc88e0a32800fcb117c996b5dc252ec0256ccf1cecfccb0f2bfd5870219878c;
defparam ram_0311.INIT_E = 256'h69df52b9aa92b8f75eb961cb77e1753ce5da5400f412bd36bc5c274a58fe17c2;
defparam ram_0311.INIT_F = 256'h96dda78bb769a16e24ad1d9c34604b35c450c79d6fd2e51b28320a1bdd2408b0;
wire [15:0] rdata_0313;
SB_RAM256x16 ram_0313 (
.RDATA(rdata_0313),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 6),
.MASK(16'b0)
);
defparam ram_0313.INIT_0 = 256'hd9559cc61e3f4571d58b14ea4740e577d14c30ebdf4f73b8c782f46f3b6c08d1;
defparam ram_0313.INIT_1 = 256'h6f4efcd9b858d443ac63f0fd9225592fdba22f66c1eccb3714aa800ed71412ba;
defparam ram_0313.INIT_2 = 256'h0ab1107b6d650fdf66add2cc2a7e488108161e3e651486f00ad50b3c070e68c3;
defparam ram_0313.INIT_3 = 256'h37ffb1dc247db3f4b69ca946e62587246b0806f819735c9261c4cbfd46769b71;
defparam ram_0313.INIT_4 = 256'hb436465a2f3a75b373c8a2013106750d96cd433c935988591a46c2cf947a4fc0;
defparam ram_0313.INIT_5 = 256'h97752e46f2a5658b7a242904bbe1e26748ba95bf6f7e9a6ff72373e9a3f5dcc0;
defparam ram_0313.INIT_6 = 256'h2f25d930c7bea790540df0b90418e26c86c58cba0f3cfd2e20c1adfafc8b58b9;
defparam ram_0313.INIT_7 = 256'hf67a98264a755ad033da5a3f4f7bb0563a24c65f9e379e7ea24398ff770a1569;
defparam ram_0313.INIT_8 = 256'h1a9d43cfcd1ae2142b2f35e8eb1f961e20f3488685a817ea0f7147abefe92821;
defparam ram_0313.INIT_9 = 256'hb3c30dcac4dccdad0c7e14a9fa41edd57fb93a1560cfad9fffe812b476a66bcf;
defparam ram_0313.INIT_A = 256'hda6c916c9a250420b9470d5bb5f4895bc65f83f3418d7872734951b3c89f8157;
defparam ram_0313.INIT_B = 256'ha09ff972ebcbd082333bc97a4687b5b5f7b3a7939d7f4a6d3728cfa5a6599e93;
defparam ram_0313.INIT_C = 256'h38eb42c565b9f9ebe0596a1fa9f9fc33836fca4058e1e20f60069ecbde0a1a05;
defparam ram_0313.INIT_D = 256'h4beeab82252f2569fb56ffad4478db381e6b0d96b7f6d712c7073d8a118a5892;
defparam ram_0313.INIT_E = 256'h0b48f12af2ff6febee038a01ae79d93cac9f09ac76501e43bb4817d39f1d043d;
defparam ram_0313.INIT_F = 256'hdfbaa596a11d2248f849620d20cf3a6f856302c5bcc74dd6bfb3a756f59446c3;
wire [15:0] rdata_0315;
SB_RAM256x16 ram_0315 (
.RDATA(rdata_0315),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 7),
.MASK(16'b0)
);
defparam ram_0315.INIT_0 = 256'h2af31f7e9493844389075cf4a347ad1ded317b44870c068432d89047eeca2b37;
defparam ram_0315.INIT_1 = 256'hf51a6444eba4fb0b4baef416aa19593cf6ab473fe46255e53550cc8523ccb1fc;
defparam ram_0315.INIT_2 = 256'h09f3a52d859af19ba525a62fccf0b64d03a86be72316ce8f38acb5959db215f5;
defparam ram_0315.INIT_3 = 256'hfe309f2ae03cb8f724c01818371d5456ff5c9ef029f4806597554044d23fca5c;
defparam ram_0315.INIT_4 = 256'h13bbbf3bb5e83b3200dde2fa4ef0566f4fcb2bee140ab81acf351cfad0a9d1cb;
defparam ram_0315.INIT_5 = 256'h73b9f5bff710c59328c47ff675d8b68cdd2cfc07aa71d66b29ff98500b70e063;
defparam ram_0315.INIT_6 = 256'h24d0607d548133d0f4e50d79b643fc604de016ca3d849c9e1fa5d70357f443c7;
defparam ram_0315.INIT_7 = 256'hab53d6af5f0b3c6d7710bb402e21438013f3ac830c6405e219b3f114ad5b4db2;
defparam ram_0315.INIT_8 = 256'h268b8fc89f948592c8e2fb38912dbd2bc88e67e820d03f5b4cf494491ac36816;
defparam ram_0315.INIT_9 = 256'h846a486f199955e0852705305a805d5cece1647e839d3cd811a7a9d197f84815;
defparam ram_0315.INIT_A = 256'h09007c4a495b836c16a082cd2418b2962059924230aa7729d1bb2be706283998;
defparam ram_0315.INIT_B = 256'h336ee10a1530f40a98d338e2dceb777d8f6b456431c2267dcfda449bf5d28ed4;
defparam ram_0315.INIT_C = 256'h1b16770684b88454ab9db7e40b07802b36d741eeacebc9d1648723b857f2ba4b;
defparam ram_0315.INIT_D = 256'h9ccb7b57c9d5f4ac9eb293df84b6a124d1dde80bc7f262e38af79177e6520243;
defparam ram_0315.INIT_E = 256'hab117e08b2b8ddcd7f68311478c2e018799685480835f1dc30b9159377ff2d69;
defparam ram_0315.INIT_F = 256'hb05b0092e8d80ea1ff04a52f94d9b7f147f5651e8b624c1d800ce228e9db35e4;
wire [15:0] rdata_1001;
SB_RAM256x16 ram_1001 (
.RDATA(rdata_1001),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 8),
.MASK(16'b0)
);
defparam ram_1001.INIT_0 = 256'h9c7c41b50768a605cf8152a411317da39cf38541b53e6cab1f59fd2ff79f1b29;
defparam ram_1001.INIT_1 = 256'h2cb583fde53060648977748557fe9480afb7e331806f1955e4cb348795a15d4a;
defparam ram_1001.INIT_2 = 256'hfc57e12bed42aa24b833f3f2e8a254f8d17dbaefde4ef4fa78f14f96bb248b1d;
defparam ram_1001.INIT_3 = 256'h6fa44ad672bb75f06d5e00fe4d735e528400897f0eaec902ec089786e9e0968d;
defparam ram_1001.INIT_4 = 256'h1ce5e5112b8ab585513bcb8ef393e593ddd5d0e76af31aaa4e815e680eea7d1d;
defparam ram_1001.INIT_5 = 256'hc338e533ee20665b272c18f0b85424e41745d7649fad5736f68677b92feaba2c;
defparam ram_1001.INIT_6 = 256'hf1ba42579571926ee12e8abbd287acf12d22a10caecce7b310dd7e75dde1bb7d;
defparam ram_1001.INIT_7 = 256'hf4b97664ff2e90cb650c33d660c8e03898a7c0f608c58667867bb9f0c4042b77;
defparam ram_1001.INIT_8 = 256'h03c5c843009d4ce9457a900cc6c45ca871bcf29e8c206b85bc1f7637e5afddd2;
defparam ram_1001.INIT_9 = 256'hae78d5d9491ce25d1c833158e72dc0b440f91d1acce4bc33cddcf8a63885b8a6;
defparam ram_1001.INIT_A = 256'hff813a16814de988dd1d99c902ccba4c070623d63935bc59ca9a54f8811d97b8;
defparam ram_1001.INIT_B = 256'h0644e9960a194d65fed04e16f0f45d6ddf1aa911f13da01696dce1e5fdff6a9a;
defparam ram_1001.INIT_C = 256'h93aa1fbc2c2f92dbec99d4e59741569b7a5fef853715af2e069b19fb50a1b934;
defparam ram_1001.INIT_D = 256'hbdfc5a6a699eb6c6a6857c6b2ff4ef867084d4db40cdc5babd878ec8a5b9f0ea;
defparam ram_1001.INIT_E = 256'h0d3751acaa17328f1e52fd4443755392bc4d20b626185b200c87677191df6259;
defparam ram_1001.INIT_F = 256'h7772f629fcb9aff2a3318a98b9e4e58f44fd902bf544239968d748796577ca6a;
wire [15:0] rdata_1003;
SB_RAM256x16 ram_1003 (
.RDATA(rdata_1003),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 9),
.MASK(16'b0)
);
defparam ram_1003.INIT_0 = 256'h52f7a59fb8d848aad51bd38121e11d5175b3239b971a8bcbd270d276e4f21f90;
defparam ram_1003.INIT_1 = 256'h19a6611c09a950d1045425ecee7977d0f3bd3b70cce0ade0aa10f5fe3f15b1d3;
defparam ram_1003.INIT_2 = 256'hff16259d190b5d0dd4453df81d9375dc1768e22673be4905fcc51f0f975e2cd1;
defparam ram_1003.INIT_3 = 256'ha32a34f06674fd42bc1c9533c378d01b65cbce95a7200b64f9dde478cbb754b7;
defparam ram_1003.INIT_4 = 256'hf6d4f68fd768de9aa637f5755cc3f64248d0f9866c5fcb00bd79be9d247243f8;
defparam ram_1003.INIT_5 = 256'hb2411f4b8b21802fbce0082920a96856c9902897538f7068c10ebe6dca1ff7d6;
defparam ram_1003.INIT_6 = 256'h2b3b94e10d954bc10b97e227f5b2c1c629e62166ed06c2347bfb2fa4a44010ea;
defparam ram_1003.INIT_7 = 256'hff82fa877fbf9802434a2f8f8eff7a18e6b9ad444f736c1592db47627146289e;
defparam ram_1003.INIT_8 = 256'hfced2cd513690efbd52ded9fe01bb809a8d2b048326d0e7559d8c181cf6d075f;
defparam ram_1003.INIT_9 = 256'hba7672c199d70b9d2b3d5c980aad280086feeacbe16077b94941ac9ebe9c7aa4;
defparam ram_1003.INIT_A = 256'heb9d91de7a2ffabce82eead39a8ee44eb1b65a7274ead34013422c9f7cb0bcd7;
defparam ram_1003.INIT_B = 256'h2fbc5beec9c515ca4d0186e649eb7475e5170e7ea4b6e0e3de09f96b98a4216c;
defparam ram_1003.INIT_C = 256'hd146f604f32aea162557efc77e070a9edbbad0d276024acf16d1a5dd4629d48d;
defparam ram_1003.INIT_D = 256'h445080680263cbe9b1dec849f5dba0449c1a105981a3ad167e346303742edf2f;
defparam ram_1003.INIT_E = 256'h0527a9fbf0a68e910b8589e3bb1efa281615e6857d5cdb78ece71aeb9f69de3d;
defparam ram_1003.INIT_F = 256'h9282f9309931634a765f52b8eec225c309549d9a1045a9b700831ab3468223de;
wire [15:0] rdata_1005;
SB_RAM256x16 ram_1005 (
.RDATA(rdata_1005),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 10),
.MASK(16'b0)
);
defparam ram_1005.INIT_0 = 256'h0776006ec4d03f7a5c73c6057f7bbb99f7edd3d8a12be2e3861cd69aa1bc525c;
defparam ram_1005.INIT_1 = 256'hf24b4a0303bece261707dd7962cd9ab47513d64b793224f15562b4c4d72ec72c;
defparam ram_1005.INIT_2 = 256'hd30dbc4325341cdd5dcfb3d5f9410e1519c20e4b16d74676e855324ccd67af40;
defparam ram_1005.INIT_3 = 256'h4a60c84b1172429d7d8a0b7bbefc3e626e25187906cd7e14e1c316ac7e9ed288;
defparam ram_1005.INIT_4 = 256'h9d1c20f207820f24ba23a74a0da804ec13f8a1b7ed61e5a644c79e5932782489;
defparam ram_1005.INIT_5 = 256'ha2f4c117c4d10358b1b04ab329706816dce90617ee78102870d29889a7660488;
defparam ram_1005.INIT_6 = 256'h22b667287f6fed4bfee9b16292dc9c8123a2ab5dcfa8fefdfcedfe2cb1869519;
defparam ram_1005.INIT_7 = 256'hddfb1d4815eaa10a75bde6c4799ef3e1d4c0812fa1d808083bc054d21b3655f0;
defparam ram_1005.INIT_8 = 256'h6bebae5c4efe1bdf465dda9e4ca89a3a78d985462f017150b8f9d36783fc27d3;
defparam ram_1005.INIT_9 = 256'hde7dd3ae6e92319591c5d8647f2e51d38d1b0cad7683fd870d63f55fca8a1524;
defparam ram_1005.INIT_A = 256'hd27e172a81e83608bbc9ea610f3801d47a54d14a5309a4847f14abceda8fecb9;
defparam ram_1005.INIT_B = 256'ha151d1f63317c4515c9f5773a7e5812a3906738b26b9a9447ec9aceb93fe5636;
defparam ram_1005.INIT_C = 256'ha43c9e64daef57c028270e426fa141aa96209263021ae9d0c78fd98f9c148954;
defparam ram_1005.INIT_D = 256'h40d7f09924ea37080c9b7243c18c25243eeef757b2ddf45cd90f1552f2dc67f4;
defparam ram_1005.INIT_E = 256'hf09c320f602b1fa8d8321d0554a8a6613a67f43747362b7f5e2881a27d943bec;
defparam ram_1005.INIT_F = 256'h86a034c22751bb658bb02c3d653e7f3af4f1d23807a5d0850342092825c678d7;
wire [15:0] rdata_1007;
SB_RAM256x16 ram_1007 (
.RDATA(rdata_1007),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 11),
.MASK(16'b0)
);
defparam ram_1007.INIT_0 = 256'h4e39bcdedc4225f725553e52a5ac856ffce7ec677b03371f5cfcbdc088d25d3e;
defparam ram_1007.INIT_1 = 256'h3ae63a363e292263c3767b69693f590967b4a51b7545ef66197a9e81340625f4;
defparam ram_1007.INIT_2 = 256'hd143d96571dcf7c28197a18318537b93c8fcf207cbc9c28b02e6891faa1d2060;
defparam ram_1007.INIT_3 = 256'hd4cccc72f0bc14361256a0860cf83c4036056951417bd9e9c36bb443da137a45;
defparam ram_1007.INIT_4 = 256'h19fdfb40c38ba5c327ec0e928aa904b3c82003e48245d6665ea30e6de59d95b5;
defparam ram_1007.INIT_5 = 256'h1955f4d9c2eb2e65e772a58e15b472caa748bcdfe36ff847d6b40e3144fbeec3;
defparam ram_1007.INIT_6 = 256'h1731ac85d13545f4d691a4c6b53833936ba7bf84be95a37682d3d7e8f46105ae;
defparam ram_1007.INIT_7 = 256'hff2e1b21202bc8d4e6d0924ec4f3d650c383ddecef63c838ec35fdcdbfff217a;
defparam ram_1007.INIT_8 = 256'h6cba3ae658a500c33b92d92896b897b356daf59a114db811c6386201d9933a04;
defparam ram_1007.INIT_9 = 256'hfc3a2543ec498d95e4d91a702c848c7ac8bbd9a2e427f73c9103bf231eed364f;
defparam ram_1007.INIT_A = 256'h93e1884aeb0366366c841e1f542598c2bd8b2cf31f73055007bc12d74164191b;
defparam ram_1007.INIT_B = 256'hec77a7c083657e4af9e587b26a41f9951cbc47a4998066a06fbef31e4c703a84;
defparam ram_1007.INIT_C = 256'h2fe468d39c8459102279bb9b4ee58b644a36bf6473591f8ef3cbba2a994869ba;
defparam ram_1007.INIT_D = 256'h83776c239ddd7de3a1578433608dc6a4469bf2d56f488f12b726d8ce919ea9d2;
defparam ram_1007.INIT_E = 256'h3fdc7c39c3d78e24f206100c593ae13f3504e3fdb51d0c1e0ee8deb94c2e56f8;
defparam ram_1007.INIT_F = 256'h0cf5c0b04f44cb998f2666e53fb0821fce4cd86a56cf0d9294c63badae74ea58;
wire [15:0] rdata_1009;
SB_RAM256x16 ram_1009 (
.RDATA(rdata_1009),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 12),
.MASK(16'b0)
);
defparam ram_1009.INIT_0 = 256'h00dd22ab72977ee266ff25412fb075db016baeca9f13968d4616a585eee3090a;
defparam ram_1009.INIT_1 = 256'h13e38c740dfa42a0dd7630edf82bec6afc3e4444a24e308b45899e5c2179aa53;
defparam ram_1009.INIT_2 = 256'h46074c8da907cd884cf6a0d6c8f42c68d5aaeade7159ac472a3846993f283607;
defparam ram_1009.INIT_3 = 256'h6e9a5cdcc076f56aea6b66f2423f485b78289ed5c6192a7b88de6b149a0bcc77;
defparam ram_1009.INIT_4 = 256'hba3d1385e32eab4b82370495b8d90f5751a6dc1da47d33e82fef50b08904afa8;
defparam ram_1009.INIT_5 = 256'h070b3ab69f1e5ff13022fd403e3197f363bcf4b926a12265e8e7143b9ce57bff;
defparam ram_1009.INIT_6 = 256'h54e43106537fc4a6ee059ca2e4608f1ddf4c225a60c46b4b8c5aad9c0140e6e3;
defparam ram_1009.INIT_7 = 256'hf54a84ac1112cce38092c8ab9dc372da803fb1043313a44bc09e0ae9870882de;
defparam ram_1009.INIT_8 = 256'h7bea9c49dfce264c2887a4d75f8401384d3ecd8f4126ba767b0f559e9bc27589;
defparam ram_1009.INIT_9 = 256'hd83372f53ac2c6174a64540ebc7c0a604d6d739f6f7ec5c7c217b0f42ff28ce4;
defparam ram_1009.INIT_A = 256'h225c6c8d155ddc900609375ff62e940face07ecd4700b9a58e31f79ad4177031;
defparam ram_1009.INIT_B = 256'h6f3934aeb7cb9b817f7a1e742cd2b64c077f7b394ac65fcc5d67f2b13ef402ef;
defparam ram_1009.INIT_C = 256'h4634285a3fe505d87689ddd607abe8942354d1ff1ab96bbda0e3992cc51827f2;
defparam ram_1009.INIT_D = 256'h8f5ba84568337a4c48dd650d26e7774062012636b6be06c3d084e9e69505669d;
defparam ram_1009.INIT_E = 256'h9c8362ebbd6cdb77941d8dcc2cd9975ecf45bdab9cd5c6c6d96cd12439ba3416;
defparam ram_1009.INIT_F = 256'h6ac567c655b53b93d3dd0718c2bed6419eff6bb310b4865c1115d7d6a18dbe39;
wire [15:0] rdata_1011;
SB_RAM256x16 ram_1011 (
.RDATA(rdata_1011),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 13),
.MASK(16'b0)
);
defparam ram_1011.INIT_0 = 256'h362c2d793cc2cbefa8f0856599ae3092fc9d1899af1176c56cf4af5204ceff43;
defparam ram_1011.INIT_1 = 256'h24a47c459b500efbdbade11495dc1563d0eb10d855e616d158903f42c85f9d7f;
defparam ram_1011.INIT_2 = 256'h22dcae4b4ea436cfcfab001745d46d018985b37ca8967cfa1acd8092b04b8f54;
defparam ram_1011.INIT_3 = 256'hafc84dc99ccba1a754e8891edcd82ef3bb3b2c3ae1cb1ec0a14f572c60d12f08;
defparam ram_1011.INIT_4 = 256'h904aa0e37fa6c8da80ef6a8494b730ce7e422c4cf13aa527573671d153cf7ce1;
defparam ram_1011.INIT_5 = 256'h03f03529f73ed23835562295897065dee7cf99f593ccef4c545193d867ac7e08;
defparam ram_1011.INIT_6 = 256'h5d2fd0e50390eccf5322efa530c77ef20d5807ae44138ca9d55c7eb221c4a3ed;
defparam ram_1011.INIT_7 = 256'h5ecf2c470973a0d8a192a9aebb1fc0634a2bc4ad471a81a56dbef77148acc224;
defparam ram_1011.INIT_8 = 256'hb729ece2b3ebf4a36f769a6fa20a6e78f448a15ae707f593097b6d2aecaa6948;
defparam ram_1011.INIT_9 = 256'h0af41c521d3c94c64b76a424110a8d95fba2b51dbf72b0b34806cb2a1088fd7e;
defparam ram_1011.INIT_A = 256'h65f51a767a25bcf8c8b922d2291a81cb43d8fd14c4f28e3f6211e685cf6bf659;
defparam ram_1011.INIT_B = 256'h525643b65c204fbc4784701c8d27bc7272d622ce3b95f6cfc3dd99df69cb3b8e;
defparam ram_1011.INIT_C = 256'ha60853f8e9d0e538e106184173fdc70b496cc3048e65f3378e0b740b76bf594f;
defparam ram_1011.INIT_D = 256'h8359c3bc1e7be748e9e74c42b2ac4ff44fa6e1a5cd485e18bf2f1674d76fc7ad;
defparam ram_1011.INIT_E = 256'h19868c5139623b8823c1f62d69ba80469415a6766cb8c4e5827ada6e7b2c107c;
defparam ram_1011.INIT_F = 256'h1c7f1dd62f29a97250327ce5d9909876004e17f1532a2d218a67980a03ded845;
wire [15:0] rdata_1013;
SB_RAM256x16 ram_1013 (
.RDATA(rdata_1013),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 14),
.MASK(16'b0)
);
defparam ram_1013.INIT_0 = 256'h1c9b05f5062cf4c25ddeeac8024576874c7989e717a11770dca3747f29ae514a;
defparam ram_1013.INIT_1 = 256'h13cfb7cc84ef05f07fc8f83085878e6aab399c88815116dc4ad2f7c4cea680e2;
defparam ram_1013.INIT_2 = 256'h50b45abe6c1f167f5bccf97db6d7251da4321990172d4897804947f434e79b1c;
defparam ram_1013.INIT_3 = 256'hb2a152c418006c4a0e7bcc961cacaf37eedbb38830633b7fe3a124f7795f58e6;
defparam ram_1013.INIT_4 = 256'hc8b596be79c27aa527c94de1cee75f50e13465f1031d4f6e88866f2adb61806f;
defparam ram_1013.INIT_5 = 256'hcb2b6636db3b635aadfd796a226f128ff3d2005b501abee63f9caa1116367044;
defparam ram_1013.INIT_6 = 256'hfd2255e9d120bfd3df10e0dd1f3488243e58bf85058a960d9767ae3176090494;
defparam ram_1013.INIT_7 = 256'hdc0aec0de8936cc5843863a55f7d60326be11898381a27151ee3ba699a4e8d6d;
defparam ram_1013.INIT_8 = 256'h5219e84d5be7ff41723580327bf1d2931ebff70ac32a3219066af7ebe5b6d1d2;
defparam ram_1013.INIT_9 = 256'hcb5029f958e66f0e3d1b1b9df273b9131bc1d10abe226c03de9b15ff5ff9e282;
defparam ram_1013.INIT_A = 256'h02637bb03a384463fee3a500ca6b4614e19db03d8eec5214540767a13f4218d1;
defparam ram_1013.INIT_B = 256'h1d83eee108d925f34f15f03269d685d1132a5aa102f8a49ba0d216d4a2de5858;
defparam ram_1013.INIT_C = 256'h5b354f004e9a7d40dd6f4b38b9d258c6718a6db339eb23d591e96b31b4ffed14;
defparam ram_1013.INIT_D = 256'hc1c1c526ea60690e3bbf2bce2989a12e3deb4dcafc2818b37a591a15bc6fe402;
defparam ram_1013.INIT_E = 256'hc08c14e42ac9e3175d2c2ae617d71f3aac4c18ab51f4827f491bd8c7109c3db0;
defparam ram_1013.INIT_F = 256'h50929c51c7d605a973c3f518850e9ecc133cffd13a9942a69317b566dba8e78e;
wire [15:0] rdata_1015;
SB_RAM256x16 ram_1015 (
.RDATA(rdata_1015),
.RADDR(addr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(addr),
.WCLK(clk),
.WCLKE(1'b1),
.WDATA(wdata),
.WE(sel == 15),
.MASK(16'b0)
);
defparam ram_1015.INIT_0 = 256'h12be2212ed14b2640338f81dff4108d4ac3bf1e6a03d7a29cac03cfe50e1bff8;
defparam ram_1015.INIT_1 = 256'hf485c1d5ad53c47a71709a5fb8cfcbc329f0e18b7178c13872b52c7c6a285ce4;
defparam ram_1015.INIT_2 = 256'h0f7b97d175c184936b7626f2402e106ec7a53b31b97f05b87b224270da05e334;
defparam ram_1015.INIT_3 = 256'heb2844df6eb99634216dfe81c6287f7c55d047b08034e4c32b1d824d10c64fe0;
defparam ram_1015.INIT_4 = 256'ha28fff103cf00d3a51939c8eb633d49ed059a79bb70253ef6a145fa0fba30636;
defparam ram_1015.INIT_5 = 256'he8ac62e181b16da21e581e88f0a9faf89d14e1e2e1013d7522705f7dd64d2de4;
defparam ram_1015.INIT_6 = 256'h7b90b08c103dd63a3c5423a7ee83d6a144fbf40c6fb04befa7e116b1b8a5d6b6;
defparam ram_1015.INIT_7 = 256'h6d5eae0464fff912dcde27536baa0ce0831c559a90f63df5d7dc9c2ac9cd82a2;
defparam ram_1015.INIT_8 = 256'hff802d46b492cf02aff2dc259541586414f67b86fc8c4114969f39702d29830e;
defparam ram_1015.INIT_9 = 256'h7078b25fbb5914cd4dfc3c391beb54a2c47baabae73f3ee4da1b64cf7767be72;
defparam ram_1015.INIT_A = 256'hfc517c45f85fb461e326f7a886cebeb6c977d0b285b42d1ca35042cafadee9e3;
defparam ram_1015.INIT_B = 256'h5519034f258fa5c885ea5cf8d67b379a55859ae6b38f12236e559c4b19972731;
defparam ram_1015.INIT_C = 256'hcf4251d73f1054d3986f2ac746ac44d4e0e9a0b4f179126262ffef39f4ba1756;
defparam ram_1015.INIT_D = 256'h3cd68370c54a6b68802813bb1a3181ad13166a324cf1c3eba85f8651664dde8a;
defparam ram_1015.INIT_E = 256'h8a0896ac480c525a1c702b9856da6163328b36a3ec5c2e13bc07656b71bd1575;
defparam ram_1015.INIT_F = 256'hdbccace4967a5bbacc70d66dd227a1fbd11062e04cc1cb91d6d0dcd9750fd1b7;
assign rdata = sel == 0 ? rdata_0301 : sel == 1 ? rdata_0303 : sel == 2 ? rdata_0305 : sel == 3 ? rdata_0307 : sel == 4 ? rdata_0309 : sel == 5 ? rdata_0311 : sel == 6 ? rdata_0313 : sel == 7 ? rdata_0315 : sel == 8 ? rdata_1001 : sel == 9 ? rdata_1003 : sel == 10 ? rdata_1005 : sel == 11 ? rdata_1007 : sel == 12 ? rdata_1009 : sel == 13 ? rdata_1011 : sel == 14 ? rdata_1013 : sel == 15 ? rdata_1015 : 0;
endmodule

3
icefuzz/tests/sb_dff.v Normal file
View File

@ -0,0 +1,3 @@
module top (input C, D, output Q);
SB_DFF ff (.C(C), .D(D), .Q(Q));
endmodule

3
icefuzz/tests/sb_dffe.v Normal file
View File

@ -0,0 +1,3 @@
module top (input C, D, E, output Q);
SB_DFFE ff (.C(C), .D(D), .E(E), .Q(Q));
endmodule

3
icefuzz/tests/sb_dffer.v Normal file
View File

@ -0,0 +1,3 @@
module top (input C, D, E, R, output Q);
SB_DFFER ff (.C(C), .D(D), .E(E), .R(R), .Q(Q));
endmodule

3
icefuzz/tests/sb_dffes.v Normal file
View File

@ -0,0 +1,3 @@
module top (input C, D, E, S, output Q);
SB_DFFES ff (.C(C), .D(D), .E(E), .S(S), .Q(Q));
endmodule

View File

@ -0,0 +1,3 @@
module top (input C, D, E, R, output Q);
SB_DFFESR ff (.C(C), .D(D), .E(E), .R(R), .Q(Q));
endmodule

View File

@ -0,0 +1,3 @@
module top (input C, D, E, S, output Q);
SB_DFFESS ff (.C(C), .D(D), .E(E), .S(S), .Q(Q));
endmodule

3
icefuzz/tests/sb_dffr.v Normal file
View File

@ -0,0 +1,3 @@
module top (input C, D, R, output Q);
SB_DFFR ff (.C(C), .D(D), .R(R), .Q(Q));
endmodule

3
icefuzz/tests/sb_dffs.v Normal file
View File

@ -0,0 +1,3 @@
module top (input C, D, S, output Q);
SB_DFFS ff (.C(C), .D(D), .S(S), .Q(Q));
endmodule

3
icefuzz/tests/sb_dffsr.v Normal file
View File

@ -0,0 +1,3 @@
module top (input C, D, R, output Q);
SB_DFFSR ff (.C(C), .D(D), .R(R), .Q(Q));
endmodule

3
icefuzz/tests/sb_dffss.v Normal file
View File

@ -0,0 +1,3 @@
module top (input C, D, S, output Q);
SB_DFFSS ff (.C(C), .D(D), .S(S), .Q(Q));
endmodule

9
icefuzz/tests/sb_gb.v Normal file
View File

@ -0,0 +1,9 @@
module top (
input [7:0] a,
output [7:0] y
);
SB_GB gbufs [7:0] (
.USER_SIGNAL_TO_GLOBAL_BUFFER(a),
.GLOBAL_BUFFER_OUTPUT(y)
);
endmodule

32
icefuzz/tests/sb_gb_io.v Normal file
View File

@ -0,0 +1,32 @@
module top (
inout [7:0] pin,
input latch_in,
input clk_en,
input clk_in,
input clk_out,
input oen,
input dout_0,
input dout_1,
output [7:0] din_0,
output [7:0] din_1,
output [7:0] globals
);
SB_GB_IO #(
.PIN_TYPE(6'b 1100_00),
.PULLUP(1'b0),
.NEG_TRIGGER(1'b0),
.IO_STANDARD("SB_LVCMOS")
) PINS [7:0] (
.PACKAGE_PIN(pin),
.LATCH_INPUT_VALUE(latch_in),
.CLOCK_ENABLE(clk_en),
.INPUT_CLK(clk_in),
.OUTPUT_CLK(clk_out),
.OUTPUT_ENABLE(oen),
.D_OUT_0(dout_0),
.D_OUT_1(dout_1),
.D_IN_0(din_0),
.D_IN_1(din_1),
.GLOBAL_BUFFER_OUTPUT(globals)
);
endmodule

Some files were not shown because too many files have changed in this diff Show More