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.
+ + diff --git a/icebox/icebox.py b/icebox/icebox.py index f27d749..a6d7155 100644 --- a/icebox/icebox.py +++ b/icebox/icebox.py @@ -956,7 +956,7 @@ def netname_normalize(netname, edge="", ramb=False, ramt=False, ramb_8k=False, r if ramb_8k: netname="ram/RADDR_%d" % ([7, 6, 5, 4, 3, 2, 1, 0, -1, -1, -1, -1, -1, 10, 9, 8][idx1*4 + idx2]) if ramt_8k: netname="ram/WADDR_%d" % ([7, 6, 5, 4, 3, 2, 1, 0, -1, -1, -1, -1, -1, 10, 9, 8][idx1*4 + idx2]) match = re.match(r"(...)_op_(.*)", netname) - if match: + if match and (match.group(1) != "slf"): netname = "neigh_op_%s_%s" % (match.group(1), match.group(2)) if re.match(r"lutff_7/(cen|clk|s_r)", netname): netname = netname.replace("lutff_7/", "lutff_global/") diff --git a/icebox/icebox_vlog.py b/icebox/icebox_vlog.py index 8f6bf7c..873e4b2 100755 --- a/icebox/icebox_vlog.py +++ b/icebox/icebox_vlog.py @@ -161,6 +161,7 @@ def is_interconn(netname): if netname.startswith("span12_"): return True if netname.startswith("logic_op_"): return True if netname.startswith("neigh_op_"): return True + if netname.startswith("slf_op_"): return True if netname.startswith("local_"): return True return False @@ -768,7 +769,7 @@ for i in range(4): #TEMP: for tracing only text_func.append("/* DSP%d %2d %2d */ assign dsp%d_%d_%d_clk = %s;" % (i, x, y, i, x, y, net_clk)) text_func.append("/* DSP%d %2d %2d */ assign dsp%d_%d_%d_sr = %s;" % (i, x, y, i, x, y, net_sr)) - for j in range(7): + for j in range(8): net_in0 = seg_to_net((x, y, "lutff_%d/in_0" % j), "1'b0") net_in1 = seg_to_net((x, y, "lutff_%d/in_1" % j), "1'b0") net_in2 = seg_to_net((x, y, "lutff_%d/in_2" % j), "1'b0") -- cgit v1.2.3