From 88eebff7db9d76e418ccbddd884c4e617596a428 Mon Sep 17 00:00:00 2001
From: David Shah
+Project IceStorm 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.
+ The ice40 UltraPlus devices have a number of new features compared to the older LP/HX series
+ devices, in particular:
+ Project IceStorm – UltraPlus Features Documentation
+
+
+
+ In order to implement these new features, a significant architecural change has been made: the
+ left and right sides of the device are no longer IO, but instead DSP and IPConnect tiles.
+
Each MAC16 DSP comprises of 4 DSP tiles, all of which perform part of the DSP function and have +different routing bit configurations. Structually they are similar to logic tiles, but with the DSP +function wired into where the LUTs and DFFs would be. The four types of DSP tiles will be referred to +as DSP0 through DSP3, with DSP0 at the lowest y-position. One signal CO, is also routed through the +IPConnect tile above the DSP tile, referred to as IPCON4 in this context. + +A work-in-progress effort to determine where signals and configuration bits are located is below:
+
+Signal Assignments
+
| SB_MAC16 port | DSP0 | DSP1 | DSP2 | DSP3 | IPCON4 |
|---|---|---|---|---|---|
| CLK | - | - | lutff_global/clk | - | - |
| CE | - | - | lutff_global/cen | - | - |
| C[7:0] | - | - | - | lutff_[7:0]/in_3 | - |
| C[15:8] | - | - | - | lutff_[7:0]/in_1 | - |
| A[7:0] | - | - | lutff_[7:0]/in_3 | - | - |
| A[15:8] | - | - | lutff_[7:0]/in_1 | - | - |
| B[7:0] | - | lutff_[7:0]/in_3 | - | - | - |
| B[15:8] | - | lutff_[7:0]/in_1 | - | - | - |
| D[7:0] | lutff_[7:0]/in_3 | - | - | - | - |
| D[15:8] | lutff_[7:0]/in_1 | - | - | - | - |
| IRSTTOP | - | lutff_global/s_r | - | - | - |
| IRSTBOT | lutff_global/s_r | - | - | - | - |
| ORSTTOP | - | - | - | lutff_global/s_r | - |
| ORSTBOT | - | - | lutff_global/s_r | - | - |
| AHOLD | - | - | lutff_0/in_0 | - | - |
| BHOLD | - | lutff_0/in_0 | - | - | - |
| CHOLD | - | - | - | lutff_0/in_0 | - |
| DHOLD | lutff_0/in_0 | - | - | - | - |
| OHOLDTOP | - | - | - | lutff_1/in_0 | - |
| OHOLDBOT | lutff_1/in_0 | - | - | - | - |
| ADDSUBTOP | - | - | - | lutff_3/in_0 | - |
| ADDSUBBOT | lutff_3/in_0 | - | - | - | - |
| OLOADTOP | - | - | - | lutff_2/in_0 | - |
| OLOADBOT | lutff_2/in_0 | - | - | - | - |
| CI | lutff_4/in_0 | - | - | - | - |
| O[31:0] | mult/O_[7:0] | mult/O_[15:8] | mult/O_[23:16] | mult/O_[31:24] | - |
| CO | - | - | - | - | slf_op_0 |
+Configuration Bits
+
The DSP configuration bits mostly follow the order stated in the ICE Technology Library document, where they are described asCBIT[24:0]. For most DSP tiles, + these follow a logical order where CBIT[7:0] maps to DSP0 CBIT[7:0]; CBIT[15:8] + to DSP1 CBIT[7:0], CBIT[23:16] to DSP2 CBIT[7:0] + and CBIT[24] to DSP3 CBIT0. +
+However, there are some locations where configuration bits are swapped between DSP tiles and IPConnect tiles. For example, DSP1 (0, 16) CBIT[4:3] is used + for the internal oscillator, and the DSP configuration bits are then located in IPConnect tile (0, 19) CBIT[6:5].
+The exact permutations are not yet known, but a script will be developed to find them.
+
+Other Implementation Notes
+
+ All active DSP tiles, and all IPConnect tiles whether used or not, have some bits set which reflect their logic tile heritage. The LC_x
+ bits which would be used to configure the logic cell, are set to the below pattern for each "logic cell" (interpreting them like a logic tile):
+
0000111100001111 0000
+ Coincidentally or not, this corresponds to a buffer passing through input 2 to the output. For each "cell" the cascade bit LC0x_inmux02_5 is
+ also set, effectively creating one large chain, as this connects input 2 to the output of the previous LUT. It is not yet known if this serves any purpose, or is merely a remainder of Lattice's
+ internal testing.
+
IPConnect tiles are used for connections to all of the other UltraPlus features, such as I2C/SPI, SPRAM, RGB and oscillators. Like DSP tiles, +they are structually similar to logic tiles. The outputs of IP functions are connected to nets named slf_op_0 through slf_op_7, +and the inputs use the LUT/FF inputs in the same way as DSP tiles.
+ + + +The CLKHFPU input connects through IPConnect tile (0, 29) input lutff_0/in_1;
+and the CLKHFEN input connects through input lutff_7/in_3 of the same tile.
+
+The CLKHF output of SB_HFOSC is connected to both IPConnect tile (0, 28) output slf_op_7 and to the padin
+ of glb_netwk_4.
Configuration bit CLKHF_DIV[1] maps to DSP1 tile (0, 16) config bit CBIT_4, and +CLKHF_DIV[0] maps to DSP1 tile (0, 16) config bit CBIT_3.
+ +The CLKLFPU input connects through IPConnect tile (25, 29) input lutff_0/in_1;
+and the CLKLFEN input connects through input lutff_7/in_3 of the same tile.
+
+The CLKLF output of SB_LFOSC is connected to both IPConnect tile (25, 29) output slf_op_0 and to the padin
+ of glb_netwk_5.
SB_LFOSC has no configuration bits.
+ + -- cgit v1.2.3 From 64e3c1a9cd81e61d9a3b163c9e9f9390fa4c5c21 Mon Sep 17 00:00:00 2001 From: David ShahHowever, there are some locations where configuration bits are swapped between DSP tiles and IPConnect tiles. For example, DSP1 (0, 16) CBIT[4:3] is used - for the internal oscillator, and the DSP configuration bits are then located in IPConnect tile (0, 19) CBIT[6:5].
-The exact permutations are not yet known, but a script will be developed to find them.
+However, there is one location where configuration bits are swapped between DSP tiles and IPConnect tiles. In DSP1 (0, 16) CBIT[4:1] are used + for IP such as the internal oscillator, and the DSP configuration bits are then located in IPConnect tile (0, 19) CBIT[6:3].
+The full list of configuration bits, including the changes for the DSP at (0, 15) are described in the table below.
+ +| Parameter | Normal Position | DSP (0, 15) Changes |
|---|---|---|
| C_REG | DSP0.CBIT_0 | |
| A_REG | DSP0.CBIT_1 | |
| B_REG | DSP0.CBIT_2 | |
| D_REG | DSP0.CBIT_3 | |
| TOP_8x8_MULT_REG | DSP0.CBIT_4 | |
| BOT_8x8_MULT_REG | DSP0.CBIT_5 | |
| PIPELINE_16x16_MULT_REG1 | DSP0.CBIT_6 | |
| PIPELINE_16x16_MULT_REG2 | DSP0.CBIT_7 | |
| TOPOUTPUT_SELECT[0] | DSP1.CBIT_0 | |
| TOPOUTPUT_SELECT[1] | DSP1.CBIT_1 | (0, 19).CBIT_3 |
| TOPADDSUB_LOWERINPUT[1:0] | DSP1.CBIT_[3:2] | (0, 19).CBIT_[5:4] |
| TOPADDSUB_UPPERINUT | DSP1.CBIT_4 | (0, 19).CBIT_6 |
| TOPADDSUB_CARRYSELECT[1:0] | DSP1.CBIT_[6:5] | |
| BOTOUTPUT_SELECT[0] | DSP1.CBIT_7 | |
| BOTOUTPUT_SELECT[1] | DSP2.CBIT_0 | |
| BOTADDSUB_LOWERINPUT[1:0] | DSP2.CBIT_[2:1] | |
| BOTADDSUB_UPPERINPUT | DSP2.CBIT_3 | |
| BOTADDSUB_CARRYSELECT | DSP2.CBIT_[5:4] | |
| MODE_8x8 | DSP2.CBIT_6 | |
| A_SIGNED | DSP2.CBIT_7 | |
| B_SIGNED | DSP3.CBIT_0 |
Lattice document a limited number of supported configurations in the ICE Technology Library document, and Lattice's EDIF parser will + reject designs not following a supported configuration. It is not yet known whether unsupported configurations (such as mixed + signed and unsigned) function correctly or not. +
Other Implementation Notes
diff --git a/icefuzz/tests/dsp_cbit/.gitignore b/icefuzz/tests/dsp_cbit/.gitignore
new file mode 100644
index 0000000..83d459d
--- /dev/null
+++ b/icefuzz/tests/dsp_cbit/.gitignore
@@ -0,0 +1 @@
+work_dsp_cbit/
\ No newline at end of file
diff --git a/icefuzz/tests/dsp_cbit/dsp_cbits_up5k.txt b/icefuzz/tests/dsp_cbit/dsp_cbits_up5k.txt
new file mode 100644
index 0000000..e90c647
--- /dev/null
+++ b/icefuzz/tests/dsp_cbit/dsp_cbits_up5k.txt
@@ -0,0 +1,9 @@
+DSP (0, 15):
+ Missing (0, 16, CBIT_1)
+ Missing (0, 16, CBIT_2)
+ Missing (0, 16, CBIT_3)
+ Missing (0, 16, CBIT_4)
+ New: (0, 19, CBIT_3)
+ New: (0, 19, CBIT_5)
+ New: (0, 19, CBIT_4)
+ New: (0, 19, CBIT_6)
diff --git a/icefuzz/tests/dsp_cbit/fuzz_dsp_cbit.py b/icefuzz/tests/dsp_cbit/fuzz_dsp_cbit.py
new file mode 100755
index 0000000..79f376c
--- /dev/null
+++ b/icefuzz/tests/dsp_cbit/fuzz_dsp_cbit.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+
+import os, sys
+
+device = "up5k"
+
+# This script is designed to determine which DSPs have configuration bits
+# not in their usual position, as in some cases DSP and IPConnect tiles have
+# their config bits swapped
+
+# Unfortunately, arbitrary configurations are not allowed by icecube, so
+# we define a set that gives us maximum coverage (full coverage is not
+# possible as one CBIT is never set)
+
+allowed_configs = ["1110000010000001001110110", "0010000101000010111111111", "0001111000101100000000000"]
+
+coverage = set()
+for c in allowed_configs:
+ for i in range(25):
+ if c[i] == "1":
+ coverage.add(i)
+
+assert len(coverage) >= 24
+
+def parse_exp(f):
+ current_x = 0
+ current_y = 0
+ bits = set()
+ for line in f:
+ splitline = line.split(' ')
+ if splitline[0].endswith("_tile"):
+ current_x = int(splitline[1])
+ current_y = int(splitline[2])
+ elif splitline[0] == "IpConfig":
+ if splitline[1][:5] == "CBIT_":
+ bitidx = int(splitline[1][5:])
+ bits.add((current_x, current_y, bitidx))
+ return bits
+dsp_locs = [( 0, 5, 0), ( 0, 10, 0), ( 0, 15, 0), ( 0, 23, 0),
+ (25, 5, 0), (25, 10, 0), (25, 15, 0), (25, 23, 0)]
+
+dsp_data = {}
+
+if not os.path.exists("./work_dsp_cbit"):
+ os.mkdir("./work_dsp_cbit")
+
+for loc in dsp_locs:
+ x, y, z = loc
+ missing_bits = set()
+ new_bits = set()
+ for config in allowed_configs:
+ params = config[::-1]
+ with open("./work_dsp_cbit/dsp_cbit.v","w") as f:
+ print("""
+ module top(input clk, input a, input b, input c, input d, output y);
+ """, file=f)
+ print("""
+ SB_MAC16 #(
+ .C_REG(1'b%s),
+ .A_REG(1'b%s),
+ .B_REG(1'b%s),
+ .D_REG(1'b%s),
+ .TOP_8x8_MULT_REG(1'b%s),
+ .BOT_8x8_MULT_REG(1'b%s),
+ .PIPELINE_16x16_MULT_REG1(1'b%s),
+ .PIPELINE_16x16_MULT_REG2(1'b%s),
+ .TOPOUTPUT_SELECT(2'b%s),
+ .TOPADDSUB_LOWERINPUT(2'b%s),
+ .TOPADDSUB_UPPERINPUT(1'b%s),
+ .TOPADDSUB_CARRYSELECT(2'b%s),
+ .BOTOUTPUT_SELECT(2'b%s),
+ .BOTADDSUB_LOWERINPUT(2'b%s),
+ .BOTADDSUB_UPPERINPUT(1'b%s),
+ .BOTADDSUB_CARRYSELECT(2'b%s),
+ .MODE_8x8(1'b%s),
+ .A_SIGNED(1'b%s),
+ .B_SIGNED(1'b%s)
+ ) dsp (
+ .CLK(clk),
+ .C(c),
+ .A(a),
+ .B(b),
+ .D(d),
+ .O(y)
+ );"""
+ % (
+ params[0], params[1], params[2], params[3],
+ params[4], params[5], params[6], params[7],
+ params[8:10][::-1], params[10:12][::-1], params[12], params[13:15][::-1],
+ params[15:17][::-1], params[17:19][::-1], params[19], params[20:22][::-1],
+ params[22], params[23], params[24]), file=f)
+ print("endmodule",file=f)
+ with open("./work_dsp_cbit/dsp_cbit.pcf","w") as f:
+ print("set_location dsp %d %d %d" % loc, file=f)
+ retval = os.system("bash ../../icecube.sh -" + device + " ./work_dsp_cbit/dsp_cbit.v > ./work_dsp_cbit/icecube.log 2>&1")
+ if retval != 0:
+ sys.stderr.write('ERROR: icecube returned non-zero error code\n')
+ sys.exit(1)
+ retval = os.system("../../../icebox/icebox_explain.py ./work_dsp_cbit/dsp_cbit.asc > ./work_dsp_cbit/dsp_cbit.exp")
+ if retval != 0:
+ sys.stderr.write('ERROR: icebox_explain returned non-zero error code\n')
+ sys.exit(1)
+ bits = set()
+ known = set()
+ with open('./work_dsp_cbit/dsp_cbit.exp', 'r') as f:
+ bits = parse_exp(f)
+ for i in range(25):
+ if params[i] == "1":
+ exp_pos = (x, y + (i // 8), i % 8)
+ if exp_pos not in bits:
+ missing_bits.add(exp_pos)
+ else:
+ known.add(exp_pos)
+ for bit in bits:
+ if bit not in known:
+ new_bits.add(bit)
+ if len(missing_bits) > 0 or len(new_bits) > 0:
+ print("DSP (%d, %d):" % (x, y))
+ for bit in missing_bits:
+ print("\tMissing (%d, %d, CBIT_%d)" % bit)
+ for bit in new_bits:
+ print("\tNew: (%d, %d, CBIT_%d)" % bit)
+ dsp_data[loc] = (missing_bits, new_bits)
+with open("dsp_cbits_%s.txt" % device, 'w') as f:
+ for loc in dsp_data:
+ x, y, z = loc
+ missing_bits, new_bits = dsp_data[loc]
+ print("DSP (%d, %d):" % (x, y), file=f)
+ for bit in missing_bits:
+ print("\tMissing (%d, %d, CBIT_%d)" % bit,file=f)
+ for bit in new_bits:
+ print("\tNew: (%d, %d, CBIT_%d)" % bit,file=f)
--
cgit v1.2.3
From 2f962ac92e018370793b9db3635fabd5b599afef Mon Sep 17 00:00:00 2001
From: David Shah SB_LFOSC has no configuration bits. The UltraPlus devices have 1Mbit of extra single-ported RAM, split into 4 256kbit blocks. The full list of connections for each SPRAM block in the 5k device is shown below,
+ as well as the location of the 1 configuration bit which is set to enable use of that SPRAM block.SPRAM
+
+
+
+ Signal SPRAM (0, 0, 1) SPRAM (0, 0, 2) SPRAM (25, 0, 3) SPRAM (25, 0, 4)
+ ADDRESS[1:0] (0, 2, lutff_[1:0]/in_1) (0, 2, lutff_[7:6]/in_0) (25, 2, lutff_[1:0]/in_1) (25, 2, lutff_[7:6]/in_0)
+ ADDRESS[7:2] (0, 2, lutff_[7:2]/in_1) (0, 3, lutff_[5:0]/in_3) (25, 2, lutff_[7:2]/in_1) (25, 3, lutff_[5:0]/in_3)
+ ADDRESS[9:8] (0, 2, lutff_[1:0]/in_0) (0, 3, lutff_[7:6]/in_3) (25, 2, lutff_[1:0]/in_0) (25, 3, lutff_[7:6]/in_3)
+ ADDRESS[13:10] (0, 2, lutff_[5:2]/in_0) (0, 3, lutff_[3:0]/in_1) (25, 2, lutff_[5:2]/in_0) (25, 3, lutff_[3:0]/in_1)
+ DATAIN[7:0] (0, 1, lutff_[7:0]/in_3) (0, 1, lutff_[7:0]/in_0) (25, 1, lutff_[7:0]/in_3) (25, 1, lutff_[7:0]/in_0)
+ DATAIN[15:8] (0, 1, lutff_[7:0]/in_1) (0, 2, lutff_[7:0]/in_3) (25, 1, lutff_[7:0]/in_1) (25, 2, lutff_[7:0]/in_3)
+ MASKWREN[3:0] (0, 3, lutff_[3:0]/in_0) (0, 3, lutff_[7:4]/in_0) (25, 3, lutff_[3:0]/in_0) (25, 3, lutff_[7:4]/in_0)
+ WREN (0, 3, lutff_4/in_1) (0, 3, lutff_5/in_1) (25, 3, lutff_4/in_1) (25, 3, lutff_5/in_1)
+ CHIPSELECT (0, 3, lutff_6/in_1) (0, 3, lutff_7/in_1) (25, 3, lutff_6/in_1) (25, 3, lutff_7/in_1)
+ CLOCK (0, 1, clk) (0, 2, clk) (25, 1, clk) (25, 2, clk)
+ STANDBY (0, 4, lutff_0/in_3) (0, 4, lutff_1/in_3) (25, 4, lutff_0/in_3) (25, 4, lutff_1/in_3)
+ SLEEP (0, 4, lutff_2/in_3) (0, 4, lutff_3/in_3) (25, 4, lutff_2/in_3) (25, 4, lutff_3/in_3)
+ POWEROFF (0, 4, lutff_4/in_3) (0, 4, lutff_5/in_3) (25, 4, lutff_4/in_3) (25, 4, lutff_5/in_3)
+ DATAOUT[7:0] (0, 1, slf_op_[7:0]) (0, 3, slf_op_[7:0]) (25, 1, slf_op_[7:0]) (25, 3, slf_op_[7:0])
+ DATAOUT[15:8] (0, 2, slf_op_[7:0]) (0, 4, slf_op_[7:0]) (25, 2, slf_op_[7:0]) (25, 4, slf_op_[7:0])
+ SPRAM_ENABLE (0, 1, CBIT_0) (0, 1, CBIT_1) (25, 1, CBIT_0) (25, 1, CBIT_1)