aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-08-02 15:20:43 +0200
committerDavid Shah <davey1576@gmail.com>2018-08-02 15:20:43 +0200
commitc0aaac8dfab08f753bdb1f4d4e0315b65bbaf98a (patch)
tree1d411fa8d58bd9688c1d4626c489bbdd6e0217a7
parent0208897aa3b5bbe91810e728c825566f87c6fa0c (diff)
downloadnextpnr-c0aaac8dfab08f753bdb1f4d4e0315b65bbaf98a.tar.gz
nextpnr-c0aaac8dfab08f753bdb1f4d4e0315b65bbaf98a.tar.bz2
nextpnr-c0aaac8dfab08f753bdb1f4d4e0315b65bbaf98a.zip
ice40: Adding cell timings to chipdb
Signed-off-by: David Shah <davey1576@gmail.com>
-rw-r--r--ice40/arch.h15
-rw-r--r--ice40/chipdb.py72
2 files changed, 87 insertions, 0 deletions
diff --git a/ice40/arch.h b/ice40/arch.h
index bfec7c16..cf63a993 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -172,10 +172,24 @@ NPNR_PACKED_STRUCT(struct BelConfigPOD {
RelPtr<BelConfigEntryPOD> entries;
});
+NPNR_PACKED_STRUCT(struct CellPathDelayPOD {
+ PortPin from_port;
+ PortPin to_port;
+ int32_t fast_delay;
+ int32_t slow_delay;
+});
+
+NPNR_PACKED_STRUCT(struct CellTimingPOD {
+ BelType type;
+ int32_t num_paths;
+ RelPtr<CellPathDelayPOD> path_delays;
+});
+
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
int32_t width, height;
int32_t num_bels, num_wires, num_pips;
int32_t num_switches, num_belcfgs, num_packages;
+ int32_t num_timing_cells;
RelPtr<BelInfoPOD> bel_data;
RelPtr<WireInfoPOD> wire_data;
RelPtr<PipInfoPOD> pip_data;
@@ -183,6 +197,7 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
RelPtr<BitstreamInfoPOD> bits_info;
RelPtr<BelConfigPOD> bel_config;
RelPtr<PackageInfoPOD> packages_data;
+ RelPtr<CellTimingPOD> cell_timing;
});
#if defined(_MSC_VER)
diff --git a/ice40/chipdb.py b/ice40/chipdb.py
index 97ccbe48..842ae2a2 100644
--- a/ice40/chipdb.py
+++ b/ice40/chipdb.py
@@ -663,6 +663,60 @@ def add_bel_ec(ec):
else:
extra_cell_config[bel].append(entry)
+cell_timings = {}
+tmport_to_portpin = {
+ "posedge:clk": "CLK",
+ "ce": "CE",
+ "sr": "SR",
+ "in0": "I0",
+ "in1": "I1",
+ "in2": "I2",
+ "in3": "I3",
+ "carryin": "CIN",
+ "carrout": "COUT",
+ "lcout": "O",
+ "ltout": "LO",
+ "posedge:RCLK": "RCLK",
+ "posedge:WCLK": "WCLK",
+ "RCLKE": "RCLKE",
+ "RE": "RE",
+ "WCLKE": "WCLKE",
+ "WE": "WE",
+ "posedge:CLOCK": "CLOCK",
+ "posedge:SLEEP": "SLEEP"
+}
+
+for i in range(16):
+ tmport_to_portpin["RDATA[%d]" % i] = "RDATA_%d" % i
+ tmport_to_portpin["WDATA[%d]" % i] = "WDATA_%d" % i
+ tmport_to_portpin["MASK[%d]" % i] = "MASK_%d" % i
+ tmport_to_portpin["DATAOUT[%d]" % i] = "DATAOUT_%d" % i
+
+for i in range(11):
+ tmport_to_portpin["RADDR[%d]" % i] = "RADDR_%d" % i
+ tmport_to_portpin["WADDR[%d]" % i] = "WADDR_%d" % i
+
+def add_cell_timingdata(bel_type, timing_cell, fast_db, slow_db):
+ timing_entries = []
+ database = slow_db if slow_db is not None else fast_db
+ for key in database.keys():
+ skey = key.split(".")
+ if skey[0] == timing_cell:
+ if skey[1] in tmport_to_portpin and skey[2] in tmport_to_portpin:
+ iport = tmport_to_portpin[skey[1]]
+ oport = tmport_to_portpin[skey[2]]
+ fastdel = fast_db[key] if fast_db is not None else 0
+ slowdel = slow_db[key] if slow_db is not None else 0
+ timing_entries.append((iport, oport, fastdel, slowdel))
+ cell_timings[bel_type] = timing_entries
+
+add_cell_timingdata("ICESTORM_LC", "LogicCell40", fast_timings, slow_timings)
+add_cell_timingdata("ICESTORM_RAM", "SB_RAM40_4K", fast_timings, slow_timings)
+
+if dev_name == "5k":
+ add_cell_timingdata("SPRAM", "SB_SPRAM256KA", fast_timings, slow_timings)
+
+
for tile_xy, tile_type in sorted(tiles.items()):
if tile_type == "logic":
for i in range(8):
@@ -1074,6 +1128,23 @@ for info in packageinfo:
bba.u32(info[1], "num_pins")
bba.r(info[2], "pins")
+for cell, timings in sorted(cell_timings.items()):
+ beltype = beltypes[cell]
+ bba.l("cell_paths_%d" % beltype, "CellPathDelayPOD")
+ for entry in timings:
+ fromport, toport, fast, slow = entry
+ bba.u32(portpins[fromport], "from_port")
+ bba.u32(portpins[toport], "to_port")
+ bba.u32(fast, "fast_delay")
+ bba.u32(slow, "slow_delay")
+
+bba.l("cell_timings_%s" % dev_name, "CellTimingPOD")
+for cell, timings in sorted(cell_timings.items()):
+ beltype = beltypes[cell]
+ bba.u32(beltype, "type")
+ bba.u32(len(timings), "num_paths")
+ bba.r("cell_paths_%d" % beltype, "path_delays")
+
bba.l("chip_info_%s" % dev_name)
bba.u32(dev_width, "dev_width")
bba.u32(dev_height, "dev_height")
@@ -1090,5 +1161,6 @@ bba.r("tile_grid_%s" % dev_name, "tile_grid")
bba.r("bits_info_%s" % dev_name, "bits_info")
bba.r("bel_config_%s" % dev_name if len(extra_cell_config) > 0 else None, "bel_config")
bba.r("package_info_%s" % dev_name, "packages_data")
+bba.r("cell_timing_%s" % dev_name, "cell_timing")
bba.pop()