aboutsummaryrefslogtreecommitdiffstats
path: root/icebox
diff options
context:
space:
mode:
Diffstat (limited to 'icebox')
-rw-r--r--icebox/icebox.py110
-rwxr-xr-xicebox/icebox_chipdb.py32
2 files changed, 138 insertions, 4 deletions
diff --git a/icebox/icebox.py b/icebox/icebox.py
index e23d4f0..60c73d1 100644
--- a/icebox/icebox.py
+++ b/icebox/icebox.py
@@ -242,7 +242,64 @@ class iceconfig:
return entries
assert False
-
+
+ # Return a map between HDL name and routing net and location for a given DSP cell
+ def get_dsp_nets_db(self, x, y):
+ assert ((x, y) in self.dsp_tiles[0])
+ # Control signals
+ nets = {
+ "CLK": (x, y+2, "lutff_global/clk"),
+ "CE": (x, y+2, "lutff_global/cen"),
+ "IRSTTOP": (x, y+1, "lutff_global/s_r"),
+ "IRSTBOT": (x, y+0, "lutff_global/s_r"),
+ "ORSTTOP": (x, y+3, "lutff_global/s_r"),
+ "ORSTBOT": (x, y+2, "lutff_global/s_r"),
+ "AHOLD": (x, y+2, "lutff_0/in_0"),
+ "BHOLD": (x, y+1, "lutff_0/in_0"),
+ "CHOLD": (x, y+3, "lutff_0/in_0"),
+ "DHOLD": (x, y+0, "lutff_0/in_0"),
+ "OHOLDTOP": (x, y+3, "lutff_1/in_0"),
+ "OHOLDBOT": (x, y+0, "lutff_1/in_0"),
+ "ADDSUBTOP": (x, y+3, "lutff_3/in_0"),
+ "ADDSUBBOT": (x, y+0, "lutff_3/in_0"),
+ "OLOADTOP": (x, y+3, "lutff_2/in_0"),
+ "OLOADBOT": (x, y+0, "lutff_2/in_0"),
+ "CI": (x, y+0, "lutff_4/in_0"),
+ "CO": (x, y+4, "slf_op_0")
+ }
+ #Data ports
+ for i in range(8):
+ nets["C_%d" % i] = (x, y+3, "lutff_%d/in_3" % i)
+ nets["C_%d" % (i+8)] = (x, y+3, "lutff_%d/in_1" % i)
+
+ nets["A_%d" % i] = (x, y+2, "lutff_%d/in_3" % i)
+ nets["A_%d" % (i+8)] = (x, y+2, "lutff_%d/in_1" % i)
+
+ nets["B_%d" % i] = (x, y+1, "lutff_%d/in_3" % i)
+ nets["B_%d" % (i+8)] = (x, y+1, "lutff_%d/in_1" % i)
+
+ nets["D_%d" % i] = (x, y+0, "lutff_%d/in_3" % i)
+ nets["D_%d" % (i+8)] = (x, y+0, "lutff_%d/in_1" % i)
+ for i in range(32):
+ nets["O_%d" % i] = (x, y+(i//8), "mult/O_%d" % i)
+ return nets
+
+ # Return the location of configuration bits for a given DSP cell
+ def get_dsp_config_db(self, x, y):
+ assert ((x, y) in self.dsp_tiles[0])
+
+ override = { }
+ if (("%s_%d_%d" % (self.device, x, y)) in dsp_config_db):
+ override = dsp_config_db["%s_%d_%d" % (self.device, x, y)]
+ default_db = dsp_config_db["default"]
+ merged = { }
+ for cfgkey in default_db:
+ cx, cy, cbit = default_db[cfgkey]
+ if cfgkey in override:
+ cx, cy, cbit = override[cfgkey]
+ merged[cfgkey] = (x + cx, y + cy, cbit)
+ return merged
+
def tile_db(self, x, y):
# Only these devices have IO on the left and right sides.
if self.device in ["384", "1k", "8k"]:
@@ -467,9 +524,9 @@ class iceconfig:
h_idx = (idx ^ 1) - 8
elif corner == "tr":
#TODO: bounds check for v_idx case?
- if idx <= 24:
+ if idx <= 16:
v_idx = (idx + 12) ^ 1
- if idx >= 12 and idx < 36:
+ if idx >= 12 and idx < 28:
h_idx = (idx ^ 1) - 12
elif corner == "br":
#TODO: bounds check for v_idx case?
@@ -4340,6 +4397,47 @@ pinloc_db = {
],
}
+# This database contains the locations of configuration bits of the DSP tiles
+# The standard configuration is stored under the key "default". If it is necessary to
+# override it for a certain DSP on a certain device use the key "{device}_{x}_{y}" where
+# {x} and {y} are the location of the DSP0 tile of the DSP (NOT the tile the cbit is in).
+# x and y are relative to the DSP0 tile.
+dsp_config_db = {
+ "default" : {
+ "C_REG": (0, 0, "CBIT_0"),
+ "A_REG": (0, 0, "CBIT_1"),
+ "B_REG": (0, 0, "CBIT_2"),
+ "D_REG": (0, 0, "CBIT_3"),
+ "TOP_8x8_MULT_REG": (0, 0, "CBIT_4"),
+ "BOT_8x8_MULT_REG": (0, 0, "CBIT_5"),
+ "PIPELINE_16x16_MULT_REG1": (0, 0, "CBIT_6"),
+ "PIPELINE_16x16_MULT_REG2": (0, 0, "CBIT_7"),
+ "TOPOUTPUT_SELECT_0": (0, 1, "CBIT_0"),
+ "TOPOUTPUT_SELECT_1": (0, 1, "CBIT_1"),
+ "TOPADDSUB_LOWERINPUT_0": (0, 1, "CBIT_2"),
+ "TOPADDSUB_LOWERINPUT_1": (0, 1, "CBIT_3"),
+ "TOPADDSUB_UPPERINPUT": (0, 1, "CBIT_4"),
+ "TOPADDSUB_CARRYSELECT_0": (0, 1, "CBIT_5"),
+ "TOPADDSUB_CARRYSELECT_1": (0, 1, "CBIT_6"),
+ "BOTOUTPUT_SELECT_0": (0, 1, "CBIT_7"),
+ "BOTOUTPUT_SELECT_1": (0, 2, "CBIT_0"),
+ "BOTADDSUB_LOWERINPUT_0": (0, 2, "CBIT_1"),
+ "BOTADDSUB_LOWERINPUT_1": (0, 2, "CBIT_2"),
+ "BOTADDSUB_UPPERINPUT": (0, 2, "CBIT_3"),
+ "BOTADDSUB_CARRYSELECT_0": (0, 2, "CBIT_4"),
+ "BOTADDSUB_CARRYSELECT_1": (0, 2, "CBIT_5"),
+ "MODE_8x8": (0, 2, "CBIT_6"),
+ "A_SIGNED": (0, 2, "CBIT_7"),
+ "B_SIGNED": (0, 3, "CBIT_0")
+ },
+ "5k_0_15": {
+ "TOPOUTPUT_SELECT_1": (0, 4, "CBIT_3"),
+ "TOPADDSUB_LOWERINPUT_0": (0, 4, "CBIT_4"),
+ "TOPADDSUB_LOWERINPUT_1": (0, 4, "CBIT_5"),
+ "TOPADDSUB_UPPERINPUT": (0, 4, "CBIT_6")
+ }
+}
+
iotile_full_db = parse_db(iceboxdb.database_io_txt)
logictile_db = parse_db(iceboxdb.database_logic_txt, "1k")
logictile_5k_db = parse_db(iceboxdb.database_logic_txt, "5k")
@@ -4355,6 +4453,12 @@ ramttile_8k_db = parse_db(iceboxdb.database_ramt_8k_txt, "8k")
ipcon_5k_db = parse_db(iceboxdb.database_ipcon_5k_txt, "5k")
dsp0_5k_db = parse_db(iceboxdb.database_dsp0_5k_txt, "5k")
dsp1_5k_db = parse_db(iceboxdb.database_dsp1_5k_txt, "5k")
+
+#This bit doesn't exist in DB because icecube won't ever set it,
+#but it exists
+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")
diff --git a/icebox/icebox_chipdb.py b/icebox/icebox_chipdb.py
index ca7f483..7d75670 100755
--- a/icebox/icebox_chipdb.py
+++ b/icebox/icebox_chipdb.py
@@ -129,7 +129,8 @@ print("""#
# .logic_tile X Y
# .ramb_tile X Y
# .ramt_tile X Y
-#
+# .dsp[0..3]_tile X Y
+# .ipcon_tile X Y
# declares the existence of a IO/LOGIC/RAM tile with the given coordinates
#
#
@@ -137,6 +138,8 @@ print("""#
# .logic_tile_bits COLUMNS ROWS
# .ramb_tile_bits COLUMNS ROWS
# .ramt_tile_bits COLUMNS ROWS
+# .dsp[0..3]_tile_bits X Y
+# .ipcon_tile_bits X Y
# FUNCTION_1 CONFIG_BITS_NAMES_1
# FUNCTION_2 CONFIG_BITS_NAMES_2
# ...
@@ -145,6 +148,7 @@ print("""#
#
#
# .extra_cell X Y <cell-type>
+# .extra_cell X Y Z <cell-type>
# KEY MULTI-FIELD-VALUE
# ....
#
@@ -238,6 +242,16 @@ for idx in sorted(ic.ramt_tiles):
print(".ramt_tile %d %d" % idx)
print()
+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()
+
+for idx in sorted(ic.ipcon_tiles):
+ print(".ipcon_tile %d %d" % idx)
+print()
+
def print_tile_nonrouting_bits(tile_type, idx):
tx = idx[0]
ty = idx[1]
@@ -266,6 +280,11 @@ if not mode_384:
print_tile_nonrouting_bits("ramb", list(ic.ramb_tiles.keys())[0])
print_tile_nonrouting_bits("ramt", list(ic.ramt_tiles.keys())[0])
+if ic.is_ultra():
+ for dsp_idx in range(4):
+ print_tile_nonrouting_bits("dsp%d" % dsp_idx, list(ic.dsp_tiles[dsp_idx].keys())[0])
+ print_tile_nonrouting_bits("ipcon", list(ic.ipcon_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]])))
@@ -285,6 +304,17 @@ for pllid in ic.pll_list():
print("%s %s" % (key, " ".join([str(k) for k in pllinfo[key]])))
print()
+for dsploc in ic.dsp_tiles[0]:
+ x, y = dsploc
+ print(".extra_cell %d %d 0 MAC16" % dsploc)
+ 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(".extra_bits")
extra_bits = dict()
for idx in sorted(ic.extra_bits_db()):