aboutsummaryrefslogtreecommitdiffstats
path: root/icebox
diff options
context:
space:
mode:
authorSimon Schubert <2@0x2c.org>2019-02-20 11:06:01 +0100
committerSimon Schubert <2@0x2c.org>2019-02-22 22:35:55 +0100
commitd76ac32ec939e421190d8e41ee0ad5e5eacbddd5 (patch)
tree278fbc981bb8c34a70adcf96a15b67709118103a /icebox
parentc0cbae88ab47a3879aacf80d53b6a85710682a6b (diff)
downloadicestorm-d76ac32ec939e421190d8e41ee0ad5e5eacbddd5.tar.gz
icestorm-d76ac32ec939e421190d8e41ee0ad5e5eacbddd5.tar.bz2
icestorm-d76ac32ec939e421190d8e41ee0ad5e5eacbddd5.zip
iCE40 Ultra = iCE5LP = u4k port
Diffstat (limited to 'icebox')
-rw-r--r--icebox/.gitignore1
-rw-r--r--icebox/Makefile10
-rw-r--r--icebox/icebox.py330
-rwxr-xr-xicebox/icebox_chipdb.py20
-rwxr-xr-xicebox/icebox_vlog.py4
5 files changed, 316 insertions, 49 deletions
diff --git a/icebox/.gitignore b/icebox/.gitignore
index 0cd67f6..d6ffcf0 100644
--- a/icebox/.gitignore
+++ b/icebox/.gitignore
@@ -3,4 +3,5 @@ chipdb-5k.txt
chipdb-lm4k.txt
chipdb-8k.txt
chipdb-384.txt
+chipdb-u4k.txt
__pycache__
diff --git a/icebox/Makefile b/icebox/Makefile
index 5f4d47a..6906681 100644
--- a/icebox/Makefile
+++ b/icebox/Makefile
@@ -1,6 +1,6 @@
include ../config.mk
-all: chipdb-384.txt chipdb-1k.txt chipdb-8k.txt chipdb-5k.txt chipdb-lm4k.txt
+all: chipdb-384.txt chipdb-1k.txt chipdb-8k.txt chipdb-5k.txt chipdb-lm4k.txt chipdb-u4k.txt
chipdb-384.txt: icebox.py iceboxdb.py icebox_chipdb.py
python3 icebox_chipdb.py -3 > chipdb-384.new
@@ -14,6 +14,10 @@ chipdb-5k.txt: icebox.py iceboxdb.py icebox_chipdb.py
python3 icebox_chipdb.py -5 > chipdb-5k.new
mv chipdb-5k.new chipdb-5k.txt
+chipdb-u4k.txt: icebox.py iceboxdb.py icebox_chipdb.py
+ python3 icebox_chipdb.py -u > chipdb-u4k.new
+ mv chipdb-u4k.new chipdb-u4k.txt
+
chipdb-lm4k.txt: icebox.py iceboxdb.py icebox_chipdb.py
python3 icebox_chipdb.py -4 > chipdb-lm4k.new
mv chipdb-lm4k.new chipdb-lm4k.txt
@@ -28,7 +32,7 @@ check: all
python3 tc_logic_xpr.py
clean:
- rm -f chipdb-1k.txt chipdb-8k.txt chipdb-384.txt chipdb-5k.txt chipdb-lm4k.txt
+ rm -f chipdb-1k.txt chipdb-8k.txt chipdb-384.txt chipdb-5k.txt chipdb-lm4k.txt chipdb-u4k.txt
rm -f icebox.pyc iceboxdb.pyc
install: all
@@ -38,6 +42,7 @@ install: all
cp chipdb-1k.txt $(DESTDIR)$(PREFIX)/share/icebox/
cp chipdb-8k.txt $(DESTDIR)$(PREFIX)/share/icebox/
cp chipdb-5k.txt $(DESTDIR)$(PREFIX)/share/icebox/
+ cp chipdb-u4k.txt $(DESTDIR)$(PREFIX)/share/icebox/
cp chipdb-lm4k.txt $(DESTDIR)$(PREFIX)/share/icebox/
cp icebox.py $(DESTDIR)$(PREFIX)/bin/icebox.py
cp iceboxdb.py $(DESTDIR)$(PREFIX)/bin/iceboxdb.py
@@ -69,6 +74,7 @@ uninstall:
rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-1k.txt
rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-8k.txt
rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-lm4k.txt
+ rm -f $(DESTDIR)$(PREFIX)/share/icebox/chipdb-u4k.txt
-rmdir $(DESTDIR)$(PREFIX)/share/icebox
.PHONY: all check clean install uninstall
diff --git a/icebox/icebox.py b/icebox/icebox.py
index f49d7ed..7cf6085 100644
--- a/icebox/icebox.py
+++ b/icebox/icebox.py
@@ -103,6 +103,39 @@ class iceconfig:
self.io_tiles[(0, y)] = ["0" * 18 for i in range(16)]
self.io_tiles[(self.max_x, y)] = ["0" * 18 for i in range(16)]
+ def setup_empty_u4k(self):
+ self.clear()
+ self.device = "u4k"
+ self.max_x = 25
+ self.max_y = 21
+
+ for x in range(1, self.max_x):
+ for y in range(1, self.max_y):
+ if x in (6, 19):
+ if y % 2 == 1:
+ self.ramb_tiles[(x, y)] = ["0" * 42 for i in range(16)]
+ else:
+ self.ramt_tiles[(x, y)] = ["0" * 42 for i in range(16)]
+ else:
+ self.logic_tiles[(x, y)] = ["0" * 54 for i in range(16)]
+
+ for x in range(1, self.max_x):
+ self.io_tiles[(x, 0)] = ["0" * 18 for i in range(16)]
+ self.io_tiles[(x, self.max_y)] = ["0" * 18 for i in range(16)]
+
+ for x in [0, self.max_x]:
+ for y in range(1, self.max_y):
+ if y in [5, 13]:
+ self.dsp_tiles[0][(x, y)] = ["0" * 54 for i in range(16)]
+ elif y in [6, 14]:
+ self.dsp_tiles[1][(x, y)] = ["0" * 54 for i in range(16)]
+ elif y in [7, 15]:
+ self.dsp_tiles[2][(x, y)] = ["0" * 54 for i in range(16)]
+ elif y in [8, 16]:
+ self.dsp_tiles[3][(x, y)] = ["0" * 54 for i in range(16)]
+ else:
+ self.ipcon_tiles[(x, y)] = ["0" * 54 for i in range(16)]
+
def setup_empty_5k(self):
self.clear()
self.device = "5k"
@@ -179,6 +212,7 @@ class iceconfig:
if self.device == "384": return pinloc_db["384-qn32"]
if self.device == "1k": return pinloc_db["1k-tq144"]
if self.device == "lm4k": return pinloc_db["lm4k-cm49"]
+ if self.device == "u4k": return pinloc_db["u4k-sg48"]
if self.device == "5k": return pinloc_db["5k-sg48"]
if self.device == "8k": return pinloc_db["8k-ct256"]
else:
@@ -205,6 +239,8 @@ class iceconfig:
return ["1k"]
if self.device == "lm4k":
return ["lm4k"]
+ if self.device == "u4k":
+ return ["u4k"]
if self.device == "5k":
return ["5k"]
if self.device == "8k":
@@ -212,12 +248,12 @@ class iceconfig:
if self.device == "384":
return [ ]
assert False
-
+
# Return true if device is Ultra/UltraPlus series, i.e. has
# IpConnect/DSP at the sides instead of IO
def is_ultra(self):
- return self.device in ["5k"]
-
+ return self.device in ["5k", "u4k"]
+
def colbuf_db(self):
if self.device == "1k":
entries = list()
@@ -241,8 +277,20 @@ class iceconfig:
src_y = None
if 0 <= y <= 4: src_y = 4
if 5 <= y <= 10: src_y = 5
- if 11 <= y <= 16: src_y = 16
- if 17 <= y <= 21: src_y = 17
+ if 11 <= y <= 16: src_y = 16
+ if 17 <= y <= 21: src_y = 17
+ entries.append((x, src_y, x, y))
+ return entries
+
+ if self.device == "u4k":
+ entries = list()
+ for x in range(self.max_x+1):
+ for y in range(self.max_y+1):
+ src_y = None
+ if 0 <= y <= 4: src_y = 4
+ if 5 <= y <= 10: src_y = 5
+ if 11 <= y <= 16: src_y = 16
+ if 17 <= y <= 21: src_y = 17
entries.append((x, src_y, x, y))
return entries
@@ -349,9 +397,9 @@ class iceconfig:
if x == 0: return iotile_l_db
if x == self.max_x: return iotile_r_db
# The 5k needs an IO db including the extra bits
- if self.device == "5k":
+ if self.device == "5k" or self.device == "u4k":
if y == 0: return iotile_b_5k_db
- if y == self.max_y: return iotile_t_5k_db
+ if y == self.max_y: return iotile_t_5k_db
else:
if y == 0: return iotile_b_db
if y == self.max_y: return iotile_t_db
@@ -359,7 +407,7 @@ class iceconfig:
if (x, y) in self.logic_tiles: return logictile_db
if (x, y) in self.ramb_tiles: return rambtile_db
if (x, y) in self.ramt_tiles: return ramttile_db
- elif self.device == "5k":
+ elif self.device == "5k" or self.device == "u4k":
if (x, y) in self.logic_tiles: return logictile_5k_db
if (x, y) in self.ramb_tiles: return rambtile_8k_db
if (x, y) in self.ramt_tiles: return ramttile_8k_db
@@ -388,16 +436,11 @@ class iceconfig:
if (x, y) in self.ramt_tiles: return "RAMT"
if (x, y) in self.logic_tiles: return "LOGIC"
if (x == 0 or x == self.max_x) and self.is_ultra():
- if y in [5, 10, 15, 23]:
- return "DSP0"
- elif y in [6, 11, 16, 24]:
- return "DSP1"
- elif y in [7, 12, 17, 25]:
- return "DSP2"
- elif y in [8, 13, 18, 26]:
- return "DSP3"
- else:
- return "IPCON"
+ if (x, y) in self.dsp_tiles[0]: return "DSP0"
+ elif (x, y) in self.dsp_tiles[1]: return "DSP1"
+ elif (x, y) in self.dsp_tiles[2]: return "DSP2"
+ elif (x, y) in self.dsp_tiles[3]: return "DSP3"
+ else: return "IPCON"
assert False
def tile_pos(self, x, y):
@@ -490,7 +533,7 @@ class iceconfig:
if (nx, ny) in self.ramb_tiles:
if self.device == "1k":
return (nx, ny, "ram/RDATA_%d" % func)
- elif self.device == "5k":
+ elif self.device == "5k" or self.device == "u4k":
return (nx, ny, "ram/RDATA_%d" % (15-func))
elif self.device == "8k" or self.device == "lm4k":
return (nx, ny, "ram/RDATA_%d" % (15-func))
@@ -499,7 +542,7 @@ class iceconfig:
if (nx, ny) in self.ramt_tiles:
if self.device == "1k":
return (nx, ny, "ram/RDATA_%d" % (8+func))
- elif self.device == "5k":
+ elif self.device == "5k" or self.device == "u4k":
return (nx, ny, "ram/RDATA_%d" % (7-func))
elif self.device == "8k" or self.device == "lm4k":
return (nx, ny, "ram/RDATA_%d" % (7-func))
@@ -541,7 +584,7 @@ class iceconfig:
if match:
if self.device == "1k":
funcnets |= self.follow_funcnet(x, y, int(match.group(1)) % 8)
- elif self.device == "5k":
+ elif self.device == "5k" or self.device == "u4k":
funcnets |= self.follow_funcnet(x, y, 7 - int(match.group(1)) % 8)
elif self.device == "8k" or self.device == "lm4k":
funcnets |= self.follow_funcnet(x, y, 7 - int(match.group(1)) % 8)
@@ -775,7 +818,7 @@ class iceconfig:
seed_segments.add((idx[0], idx[1], "lutff_7/cout"))
if self.device == "1k":
add_seed_segments(idx, tile, logictile_db)
- elif self.device == "5k":
+ elif self.device == "5k" or self.device == "u4k":
add_seed_segments(idx, tile, logictile_5k_db)
elif self.device == "8k" or self.device == "lm4k":
add_seed_segments(idx, tile, logictile_8k_db)
@@ -787,7 +830,7 @@ class iceconfig:
for idx, tile in self.ramb_tiles.items():
if self.device == "1k":
add_seed_segments(idx, tile, rambtile_db)
- elif self.device == "5k":
+ elif self.device == "5k" or self.device == "u4k":
add_seed_segments(idx, tile, rambtile_8k_db)
elif self.device == "8k" or self.device == "lm4k":
add_seed_segments(idx, tile, rambtile_8k_db)
@@ -797,28 +840,28 @@ class iceconfig:
for idx, tile in self.ramt_tiles.items():
if self.device == "1k":
add_seed_segments(idx, tile, ramttile_db)
- elif self.device == "5k":
+ elif self.device == "5k" or self.device == "u4k":
add_seed_segments(idx, tile, ramttile_8k_db)
elif self.device == "8k" or self.device == "lm4k":
add_seed_segments(idx, tile, ramttile_8k_db)
else:
assert False
-
+
for idx, tile in self.dsp_tiles[0].items():
- if self.device == "5k":
+ if self.device == "5k" or self.device == "u4k":
add_seed_segments(idx, tile, dsp0_5k_db)
for idx, tile in self.dsp_tiles[1].items():
- if self.device == "5k":
- add_seed_segments(idx, tile, dsp1_5k_db)
+ if self.device == "5k" or self.device == "u4k":
+ add_seed_segments(idx, tile, dsp1_5k_db)
for idx, tile in self.dsp_tiles[2].items():
- if self.device == "5k":
- add_seed_segments(idx, tile, dsp2_5k_db)
+ if self.device == "5k" or self.device == "u4k":
+ add_seed_segments(idx, tile, dsp2_5k_db)
for idx, tile in self.dsp_tiles[3].items():
- if self.device == "5k":
- add_seed_segments(idx, tile, dsp3_5k_db)
+ if self.device == "5k" or self.device == "u4k":
+ add_seed_segments(idx, tile, dsp3_5k_db)
for idx, tile in self.ipcon_tiles.items():
- if self.device == "5k":
- add_seed_segments(idx, tile, ipcon_5k_db)
+ if self.device == "5k" or self.device == "u4k":
+ add_seed_segments(idx, tile, ipcon_5k_db)
for padin, pio in enumerate(self.padin_pio_db()):
s1 = (pio[0], pio[1], "padin_%d" % pio[2])
s2 = (pio[0], pio[1], "glb_netwk_%d" % padin)
@@ -944,7 +987,7 @@ class iceconfig:
self.extra_bits.add((int(line[1]), int(line[2]), int(line[3])))
continue
if line[0] == ".device":
- assert line[1] in ["1k", "lm4k", "5k", "8k", "384"]
+ assert line[1] in ["1k", "lm4k", "u4k", "5k", "8k", "384"]
self.device = line[1]
continue
if line[0] == ".warmboot":
@@ -1368,8 +1411,9 @@ def run_checks_neigh():
print("Running consistency checks on neighbour finder..")
ic = iceconfig()
# ic.setup_empty_1k()
- ic.setup_empty_lm4k()
- # ic.setup_empty_5k()
+ #ic.setup_empty_lm4k()
+ ic.setup_empty_u4k()
+ #ic.setup_empty_5k()
# ic.setup_empty_8k()
# ic.setup_empty_384()
@@ -1419,8 +1463,8 @@ def parse_db(text, device="1k"):
continue
line = line_1k
elif line_8k != line:
- # global network is the same for 8k, 5k, and lm4k
- if device != "8k" and device != "5k" and device != "lm4k":
+ # global network is the same for 8k, 5k, lm4k, and u4k
+ if device != "8k" and device != "5k" and device != "lm4k" and device != "u4k":
continue
line = line_8k
elif line_384 != line:
@@ -1465,6 +1509,16 @@ extra_bits_db = {
(0, 690, 335): ("padin_glb_netwk", "6"), # check
(0, 691, 335): ("padin_glb_netwk", "7"), # good
},
+ "u4k": {
+ (0, 691, 175): ("padin_glb_netwk", "0"), # good
+ (1, 690, 175): ("padin_glb_netwk", "1"), # good
+ (0, 690, 175): ("padin_glb_netwk", "2"), # made up
+ (0, 690, 174): ("padin_glb_netwk", "3"), # good
+ (1, 690, 174): ("padin_glb_netwk", "4"), # HFOSC, good
+ (1, 691, 174): ("padin_glb_netwk", "5"), # LFOSC, good
+ (0, 691, 174): ("padin_glb_netwk", "6"), # good
+ (1, 691, 175): ("padin_glb_netwk", "7"), # made up
+ },
"8k": {
(0, 870, 270): ("padin_glb_netwk", "0"),
(0, 871, 270): ("padin_glb_netwk", "1"),
@@ -1508,6 +1562,16 @@ gbufin_db = {
(13, 31, 1), #checked
(19, 31, 2), #checked
],
+ "u4k": [
+ (13, 0, 0), # 0 ok
+ (13, 21, 1), # 1 ok
+ (19, 21, 2), # 2 ok
+ ( 6, 21, 3), # 3 ok
+ (12, 21, 4), # 4 ok
+ (12, 0, 5), # 5 ok
+ ( 6, 0, 6), # 6 ok
+ (19, 0, 7), # 7 ok
+ ],
"lm4k": [
( 6, 0, 6),
(12, 0, 5),
@@ -1563,6 +1627,10 @@ iolatch_db = {
(14, 0),
(14, 31),
],
+ "u4k": [
+ (14, 0),
+ (14, 21),
+ ],
"8k": [
( 0, 15),
(33, 18),
@@ -1591,6 +1659,12 @@ warmbootinfo_db = {
"S0": ( 23, 0, "fabout" ),
"S1": ( 24, 0, "fabout" ),
},
+ "u4k": {
+ # These are the right locations but may be the wrong order.
+ "BOOT": ( 22, 0, "fabout" ),
+ "S0": ( 23, 0, "fabout" ),
+ "S1": ( 24, 0, "fabout" ),
+ },
"lm4k": {
# These are the right locations but may be the wrong order.
"BOOT": ( 23, 0, "fabout" ),
@@ -1901,6 +1975,70 @@ pllinfo_db = {
"SDI": ( 18, 31, "fabout"),
"SCLK": ( 17, 31, "fabout"),
},
+ "u4k": {
+ "LOC" : (12, 21),
+
+ "PLLTYPE_1": (14, 21, "PLLCONFIG_1"),
+ "PLLTYPE_2": (14, 21, "PLLCONFIG_3"),
+ "PLLTYPE_0": (12, 21, "PLLCONFIG_5"),
+ "FEEDBACK_PATH_0": (14, 21, "PLLCONFIG_5"),
+ "FEEDBACK_PATH_1": (11, 21, "PLLCONFIG_9"),
+ "FEEDBACK_PATH_2": (12, 21, "PLLCONFIG_1"),
+ "PLLOUT_SELECT_A_0": (12, 21, "PLLCONFIG_6"),
+ "PLLOUT_SELECT_A_1": (12, 21, "PLLCONFIG_7"),
+ "PLLOUT_SELECT_B_0": (12, 21, "PLLCONFIG_2"),
+ "PLLOUT_SELECT_B_1": (12, 21, "PLLCONFIG_3"),
+ "SHIFTREG_DIV_MODE": (12, 21, "PLLCONFIG_4"),
+ "FDA_FEEDBACK_0": (12, 21, "PLLCONFIG_9"),
+ "FDA_FEEDBACK_1": (13, 21, "PLLCONFIG_1"),
+ "FDA_FEEDBACK_2": (13, 21, "PLLCONFIG_2"),
+ "FDA_FEEDBACK_3": (13, 21, "PLLCONFIG_3"),
+ "FDA_RELATIVE_0": (13, 21, "PLLCONFIG_5"),
+ "FDA_RELATIVE_1": (13, 21, "PLLCONFIG_6"),
+ "FDA_RELATIVE_2": (13, 21, "PLLCONFIG_7"),
+ "FDA_RELATIVE_3": (13, 21, "PLLCONFIG_8"),
+ "DIVR_0": (10, 21, "PLLCONFIG_1"),
+ "DIVR_1": (10, 21, "PLLCONFIG_2"),
+ "DIVR_2": (10, 21, "PLLCONFIG_3"),
+ "DIVR_3": (10, 21, "PLLCONFIG_4"),
+ "DIVF_0": (10, 21, "PLLCONFIG_5"),
+ "DIVF_1": (10, 21, "PLLCONFIG_6"),
+ "DIVF_2": (10, 21, "PLLCONFIG_7"),
+ "DIVF_3": (10, 21, "PLLCONFIG_8"),
+ "DIVF_4": (10, 21, "PLLCONFIG_9"),
+ "DIVF_5": (11, 21, "PLLCONFIG_1"),
+ "DIVF_6": (11, 21, "PLLCONFIG_2"),
+ "DIVQ_0": (11, 21, "PLLCONFIG_3"),
+ "DIVQ_1": (11, 21, "PLLCONFIG_4"),
+ "DIVQ_2": (11, 21, "PLLCONFIG_5"),
+ "FILTER_RANGE_0": (11, 21, "PLLCONFIG_6"),
+ "FILTER_RANGE_1": (11, 21, "PLLCONFIG_7"),
+ "FILTER_RANGE_2": (11, 21, "PLLCONFIG_8"),
+ "TEST_MODE": (12, 21, "PLLCONFIG_8"),
+ "DELAY_ADJMODE_FB": (13, 21, "PLLCONFIG_4"),
+ "DELAY_ADJMODE_REL": (13, 21, "PLLCONFIG_9"),
+
+ # PLL Ports
+ "PLLOUT_A": ( 12, 21, 1),
+ "PLLOUT_B": ( 13, 21, 0),
+ "REFERENCECLK": ( 10, 21, "fabout"),
+ "EXTFEEDBACK": ( 11, 21, "fabout"),
+ "DYNAMICDELAY_0": ( 1, 21, "fabout"),
+ "DYNAMICDELAY_1": ( 2, 21, "fabout"),
+ "DYNAMICDELAY_2": ( 3, 21, "fabout"),
+ "DYNAMICDELAY_3": ( 4, 21, "fabout"),
+ "DYNAMICDELAY_4": ( 5, 21, "fabout"),
+ "DYNAMICDELAY_5": ( 7, 21, "fabout"),
+ "DYNAMICDELAY_6": ( 8, 21, "fabout"),
+ "DYNAMICDELAY_7": ( 9, 21, "fabout"),
+ "LOCK": ( 1, 20, "neigh_op_tnl_1"), #check?
+ "BYPASS": ( 15, 21, "fabout"),
+ "RESETB": ( 16, 21, "fabout"),
+ "LATCHINPUTVALUE": ( 14, 21, "fabout"),
+ "SDO": ( 24, 20, "neigh_op_tnr_1"), #check?
+ "SDI": ( 18, 21, "fabout"),
+ "SCLK": ( 17, 21, "fabout"),
+ },
"8k_0": {
"LOC" : (16, 0),
@@ -2124,6 +2262,17 @@ padin_pio_db = {
(12, 0, 1), #6 fixed
(12, 31, 1), #7 fixed
],
+ "u4k": [
+ (19, 0, 1), # 0 ok
+ ( 6, 0, 1), # 1 ok
+
+ (13, 21, 0), # 2 ok
+ (13, 0, 0), # 3 unclear
+ (19, 21, 0), # 4 HFOSC unclear
+ ( 6, 21, 0), # 5 LFOSC unclear
+ (12, 0, 1), # 6 unclear
+ (12, 21, 1), # 7 ok
+ ],
"8k": [
(33, 16, 1),
( 0, 16, 1),
@@ -2597,6 +2746,47 @@ ieren_db = {
(12, 0, 0, 12, 0, 1),
(13, 0, 0, 13, 0, 1),
(12, 0, 1, 12, 0, 0)
+ ],
+ "u4k": [
+ ( 4, 21, 0, 4, 21, 1),
+ ( 5, 0, 0, 5, 0, 1),
+ ( 5, 21, 0, 5, 21, 1),
+ ( 6, 0, 0, 6, 0, 1),
+ ( 6, 0, 1, 6, 0, 0),
+ ( 6, 21, 0, 6, 21, 1),
+ ( 7, 0, 0, 7, 0, 1),
+ ( 7, 0, 1, 7, 0, 0),
+ ( 8, 0, 0, 8, 0, 1),
+ ( 8, 21, 0, 8, 21, 1),
+ ( 8, 21, 1, 8, 21, 0),
+ ( 9, 0, 0, 9, 0, 1),
+ ( 9, 0, 1, 9, 0, 0),
+ ( 9, 21, 0, 9, 21, 1),
+ ( 9, 21, 1, 9, 21, 0),
+ (12, 21, 1, 12, 21, 0),
+ (13, 0, 1, 13, 0, 0),
+ (13, 21, 0, 13, 21, 1),
+ (13, 21, 1, 13, 21, 0),
+ (15, 0, 0, 15, 0, 1),
+ (16, 0, 0, 16, 0, 1),
+ (16, 21, 0, 16, 21, 1),
+ (16, 21, 1, 16, 21, 0),
+ (17, 0, 0, 17, 0, 1),
+ (17, 21, 0, 17, 21, 1),
+ (18, 0, 0, 18, 0, 1),
+ (18, 0, 1, 18, 0, 0),
+ (18, 21, 0, 18, 21, 1),
+ (18, 21, 1, 18, 21, 0),
+ (19, 0, 0, 19, 0, 1),
+ (19, 0, 1, 19, 0, 0),
+ (19, 21, 0, 19, 21, 1),
+ (19, 21, 1, 19, 21, 0),
+ (21, 0, 1, 21, 0, 0),
+ (22, 0, 1, 22, 0, 0),
+ (23, 0, 0, 23, 0, 1),
+ (23, 0, 1, 23, 0, 0),
+ (24, 0, 0, 24, 0, 1),
+ (24, 0, 1, 24, 0, 0)
]
}
@@ -4838,6 +5028,47 @@ pinloc_db = {
( "47", 6, 0, 0),
( "48", 7, 0, 0),
],
+ "u4k-sg48": [
+ ( "2", 8, 0, 0),
+ ( "3", 9, 0, 1),
+ ( "4", 9, 0, 0),
+ ( "6", 13, 0, 1),
+ ( "9", 15, 0, 0),
+ ( "10", 16, 0, 0),
+ ( "11", 17, 0, 0),
+ ( "12", 18, 0, 0),
+ ( "13", 19, 0, 0),
+ ( "14", 23, 0, 0),
+ ( "15", 24, 0, 0),
+ ( "16", 24, 0, 1),
+ ( "17", 23, 0, 1),
+ ( "18", 22, 0, 1),
+ ( "19", 21, 0, 1),
+ ( "20", 19, 0, 1),
+ ( "21", 18, 0, 1),
+ ( "23", 19, 21, 0),
+ ( "25", 19, 21, 1),
+ ( "26", 18, 21, 0),
+ ( "27", 18, 21, 1),
+ ( "28", 17, 21, 0),
+ ( "31", 16, 21, 1),
+ ( "32", 16, 21, 0),
+ ( "34", 13, 21, 1),
+ ( "35", 12, 21, 1),
+ ( "36", 9, 21, 1),
+ ( "37", 13, 21, 0),
+ ( "38", 8, 21, 1),
+ ( "39", 6, 21, 0),
+ ( "40", 5, 21, 0),
+ ( "41", 4, 21, 0),
+ ( "42", 8, 21, 0),
+ ( "43", 9, 21, 0),
+ ( "44", 6, 0, 1),
+ ( "45", 7, 0, 1),
+ ( "46", 5, 0, 0),
+ ( "47", 6, 0, 0),
+ ( "48", 7, 0, 0),
+ ],
"5k-uwg30": [
( "A1", 19, 31, 1),
( "A2", 19, 31, 0),
@@ -5522,6 +5753,23 @@ extra_cells_db = {
"WEAK_PU_ENB": (25, 27, "lutff_5/in_0"),
"PACKAGE_PIN": (19, 31, 1)
}
+ },
+
+ "u4k" : {
+ ("HFOSC", (0, 21, 1)) : {
+ "CLKHFPU": (0, 19, "lutff_0/in_1"),
+ "CLKHFEN": (0, 19, "lutff_7/in_3"),
+ "CLKHF": (0, 19, "glb_netwk_4"),
+ "CLKLF_FABRIC": (0, 18, "slf_op_7"),
+ "CLKHF_DIV_1": (0, 16, "CBIT_4"),
+ "CLKHF_DIV_0": (0, 16, "CBIT_3")
+ },
+ ("LFOSC", (25, 21, 1)) : {
+ "CLKLFPU": (25, 19, "lutff_0/in_1"),
+ "CLKLFEN": (25, 19, "lutff_7/in_3"),
+ "CLKLF": (25, 19, "glb_netwk_5"),
+ "CLKLF_FABRIC": (25, 19, "slf_op_0")
+ },
}
}
@@ -5547,6 +5795,10 @@ dsp1_5k_db.append([["B4[7]"], "IpConfig", "CBIT_5"])
dsp2_5k_db = parse_db(iceboxdb.database_dsp2_5k_txt, "5k")
dsp3_5k_db = parse_db(iceboxdb.database_dsp3_5k_txt, "5k")
+dsp3_5k_db.append([["B2[7]"], "IpConfig", "CBIT_3"]) # for u4k HFOSC.CLKHF_DIV
+dsp3_5k_db.append([["B5[7]"], "IpConfig", "CBIT_4"])
+
+
#Add missing LC_ bits to DSP and IPCon databases
for db_to_fix in [ipcon_5k_db, dsp0_5k_db, dsp1_5k_db, dsp2_5k_db, dsp3_5k_db]:
for entry in db_to_fix:
diff --git a/icebox/icebox_chipdb.py b/icebox/icebox_chipdb.py
index 6497ae2..9c8d6df 100755
--- a/icebox/icebox_chipdb.py
+++ b/icebox/icebox_chipdb.py
@@ -21,6 +21,7 @@ import getopt, sys, re
mode_384 = False
mode_lm4k = False
mode_5k = False
+mode_u4k = False
mode_8k = False
def usage():
@@ -38,11 +39,14 @@ Usage: icebox_chipdb [options] [bitmap.asc]
-4
create chipdb for lm4k device
+
+ -u
+ create chipdb for u4k device
""")
sys.exit(0)
try:
- opts, args = getopt.getopt(sys.argv[1:], "3584")
+ opts, args = getopt.getopt(sys.argv[1:], "3584u")
except:
usage()
@@ -55,6 +59,8 @@ for o, a in opts:
mode_384 = True
elif o == "-4":
mode_lm4k = True
+ elif o == "-u":
+ mode_u4k = True
else:
usage()
@@ -67,6 +73,8 @@ elif mode_384:
ic.setup_empty_384()
elif mode_lm4k:
ic.setup_empty_lm4k()
+elif mode_u4k:
+ ic.setup_empty_u4k()
else:
ic.setup_empty_1k()
@@ -254,7 +262,7 @@ for dsp_idx in range(4):
for idx in sorted(ic.dsp_tiles[dsp_idx]):
x, y = idx
print(".dsp%d_tile %d %d" % (dsp_idx, x, y))
- print()
+ print()
for idx in sorted(ic.ipcon_tiles):
print(".ipcon_tile %d %d" % idx)
@@ -320,12 +328,12 @@ for dsploc in ic.dsp_tiles[0]:
nets = ic.get_dsp_nets_db(x, y)
for key in sorted(nets):
print("%s %s" % (key, " ".join([str(k) for k in nets[key]])))
-
+
cfg = ic.get_dsp_config_db(x, y)
for key in sorted(cfg):
print("%s %s" % (key, " ".join([str(k) for k in cfg[key]])))
print()
-
+
if ic.device in icebox.extra_cells_db:
for cell in sorted(icebox.extra_cells_db[ic.device]):
name, loc = cell
@@ -335,7 +343,7 @@ if ic.device in icebox.extra_cells_db:
for key in sorted(cellinfo):
print("%s %s" % (key, " ".join([str(k) for k in cellinfo[key]])))
print()
-
+
if ic.device in icebox.spram_db:
for cell in sorted(icebox.spram_db[ic.device]):
loc = cell
@@ -345,7 +353,7 @@ if ic.device in icebox.spram_db:
for key in sorted(cellinfo):
print("%s %s" % (key, " ".join([str(k) for k in cellinfo[key]])))
print()
-
+
print(".extra_bits")
extra_bits = dict()
for idx in sorted(ic.extra_bits_db()):
diff --git a/icebox/icebox_vlog.py b/icebox/icebox_vlog.py
index 0080f34..64e9ea5 100755
--- a/icebox/icebox_vlog.py
+++ b/icebox/icebox_vlog.py
@@ -325,7 +325,7 @@ for segs in sorted(ic.group_segments(extra_connections=extra_connections, extra_
match = re.match("lutff_(\d+)/", s[2])
if match:
#IpCon and DSP tiles look like logic tiles, but aren't.
- if ic.device == "5k" and (s[0] == 0 or s[0] == ic.max_x):
+ if ic.device in ["5k", "u4k"] and (s[0] == 0 or s[0] == ic.max_x):
special_5k_queue.add((s[0], s[1]))
else:
luts_queue.add((s[0], s[1], int(match.group(1))))
@@ -743,7 +743,7 @@ for tile in ic.ramb_tiles:
if len(wire_bits) > 1:
return "{%s}" % ", ".join(wire_bits)
return wire_bits[0]
- if get_ram_config('PowerUp') == (ic.device in ("8k", "5k")):
+ if get_ram_config('PowerUp') == (ic.device in ("8k", "5k", "u4k")):
if not strip_comments:
text_func.append("// RAM TILE %d %d" % tile)
text_func.append("SB_RAM40_4K%s%s #(" % ("NR" if negclk_rd else "", "NW" if negclk_wr else ""));