aboutsummaryrefslogtreecommitdiffstats
path: root/icetime
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-01-26 19:08:16 +0000
committerDavid Shah <davey1576@gmail.com>2018-01-26 19:08:16 +0000
commita6b2ca91e58c3de2dbd403647eeea4de2915522e (patch)
tree53e237f053d3e0b0c4f377a4414a2246b8f0b28e /icetime
parentcd4352e0cea26ff983c1fc6608fc46c143c88b2d (diff)
downloadicestorm-a6b2ca91e58c3de2dbd403647eeea4de2915522e.tar.gz
icestorm-a6b2ca91e58c3de2dbd403647eeea4de2915522e.tar.bz2
icestorm-a6b2ca91e58c3de2dbd403647eeea4de2915522e.zip
Working DSP timing analysis
Diffstat (limited to 'icetime')
-rw-r--r--icetime/icetime.cc27
-rw-r--r--icetime/timings.py9
2 files changed, 33 insertions, 3 deletions
diff --git a/icetime/icetime.cc b/icetime/icetime.cc
index 788af21..51c9c03 100644
--- a/icetime/icetime.cc
+++ b/icetime/icetime.cc
@@ -599,6 +599,10 @@ bool is_primary(std::string cell_name, std::string out_port)
if (cell_type == "PRE_IO")
return true;
+ std::string dsp_prefix = "SB_MAC16";
+ if(cell_type.substr(0, dsp_prefix.length()) == dsp_prefix)
+ return true;
+
return false;
}
@@ -1260,6 +1264,26 @@ bool get_dsp_ip_cbit(std::tuple<int, int, std::string> cbit) {
return false;
}
+std::string ecnetname_to_vlog(std::string ec_name)
+{
+ // Convert a net name from the form A_0 used in the chipdb for extra cells to
+ // verilog form A[0]
+ size_t last_ = ec_name.find_last_of('_');
+ if(last_ == std::string::npos)
+ return ec_name;
+
+ std::string base = ec_name.substr(0, last_);
+ std::string end = ec_name.substr(last_+1);
+ size_t nidx = 0;
+
+ int num = std::stoi(end, &nidx, 10);
+ if(nidx == end.length()) {
+ return base + "[" + std::to_string(num) + "]";
+ } else {
+ return ec_name;
+ }
+}
+
std::string make_dsp_ip(int x, int y, std::string net, std::string &primnet)
{
std::tuple<int, int, std::string> ecnet(x, y, net);
@@ -1269,7 +1293,7 @@ std::string make_dsp_ip(int x, int y, std::string net, std::string &primnet)
for(auto entry : ec.second) {
if(entry.second == ecnet) {
key = ec.first;
- primnet = entry.first;
+ primnet = ecnetname_to_vlog(entry.first);
found = true;
break;
}
@@ -1536,6 +1560,7 @@ void make_seg_cell(int net, const net_segment_t &seg)
if(device_type == "up5k" && ((seg.x == 0) || (seg.x == config_tile_type.size() - 1))) {
std::string primnet;
auto cell = make_dsp_ip(seg.x, seg.y, seg.name, primnet);
+ netlist_cell_ports[cell][primnet] = net_name(net);
if(cell != "") {
make_inmux(seg.x, seg.y, net);
}
diff --git a/icetime/timings.py b/icetime/timings.py
index 43d54ae..7ac2a7b 100644
--- a/icetime/timings.py
+++ b/icetime/timings.py
@@ -10,7 +10,7 @@ def timings_to_c(chip, f):
print("{")
in_cell = False
-
+ last_cell = ""
for line in f:
fields = line.split()
if len(fields) == 0:
@@ -18,8 +18,14 @@ def timings_to_c(chip, f):
if fields[0] == "CELL":
if in_cell:
+ if last_cell.startswith("SB_MAC16"):
+ # DSPs have incomplete timing specification, as some paths
+ # don't mathematically exist - e.g. there is no path from
+ # A[1] to O[0]
+ print(" if (in_port != \"*clkedge*\" && out_port != \"*setup*\") return 0.0;")
print(" }")
print(" if (cell_type == \"%s\") {" % fields[1])
+ last_cell = fields[1]
in_cell = True
if fields[0] == "SETUP":
@@ -44,4 +50,3 @@ def timings_to_c(chip, f):
for db in "lp384 lp1k lp8k hx1k hx8k up5k".split():
with open("../icefuzz/timings_%s.txt" % db, "r") as f:
timings_to_c(db, f);
-