aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-06-20 14:04:10 +0200
committerClifford Wolf <clifford@clifford.at>2018-06-20 14:04:10 +0200
commit2da90889efb194be4140ebfd5893bdf0ced223f3 (patch)
treec0d985f653d72c329849ab57730422f5569a4f74
parentc4e544856ab315908793949ee8e1e2ab1e11f9e0 (diff)
downloadnextpnr-2da90889efb194be4140ebfd5893bdf0ced223f3.tar.gz
nextpnr-2da90889efb194be4140ebfd5893bdf0ced223f3.tar.bz2
nextpnr-2da90889efb194be4140ebfd5893bdf0ced223f3.zip
Add "nextpnr-ice40 --tmfuzz"
Signed-off-by: Clifford Wolf <clifford@clifford.at>
-rw-r--r--common/route.cc10
-rw-r--r--common/route.h2
-rw-r--r--ice40/main.cc40
3 files changed, 52 insertions, 0 deletions
diff --git a/common/route.cc b/common/route.cc
index 657075ce..39e420d3 100644
--- a/common/route.cc
+++ b/common/route.cc
@@ -161,6 +161,7 @@ struct Router
std::unordered_map<WireId, delay_t> src_wires;
src_wires[src_wire] = 0;
route(src_wires, dst_wire);
+ routedOkay = visited.count(dst_wire);
}
Router(Context *ctx, IdString net_name, bool ripup = false,
@@ -526,4 +527,13 @@ bool route_design(Context *ctx)
return true;
}
+bool get_actual_route_delay(Context *ctx, WireId src_wire, WireId dst_wire,
+ delay_t &delay)
+{
+ Router router(ctx, src_wire, dst_wire);
+ if (router.routedOkay)
+ delay = router.visited.at(dst_wire).delay;
+ return router.routedOkay;
+}
+
NEXTPNR_NAMESPACE_END
diff --git a/common/route.h b/common/route.h
index 33927f26..af0de42e 100644
--- a/common/route.h
+++ b/common/route.h
@@ -25,6 +25,8 @@
NEXTPNR_NAMESPACE_BEGIN
extern bool route_design(Context *ctx);
+extern bool get_actual_route_delay(Context *ctx, WireId src_wire,
+ WireId dst_wire, delay_t &delay);
NEXTPNR_NAMESPACE_END
diff --git a/ice40/main.cc b/ice40/main.cc
index 8a04caf6..ea7c9a66 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -86,6 +86,7 @@ int main(int argc, char *argv[])
options.add_options()("seed", po::value<int>(),
"seed value for random number generator");
options.add_options()("version,V", "show version");
+ options.add_options()("tmfuzz", "run path delay estimate fuzzer");
options.add_options()("lp384", "set device type to iCE40LP384");
options.add_options()("lp1k", "set device type to iCE40LP1K");
options.add_options()("lp8k", "set device type to iCE40LP8K");
@@ -220,6 +221,45 @@ int main(int argc, char *argv[])
std::cout << "</svg>\n";
}
+ if (vm.count("tmfuzz")) {
+ std::vector<WireId> src_wires, dst_wires;
+
+ for (auto w : ctx.getWires())
+ src_wires.push_back(w);
+
+ for (auto b : ctx.getBels()) {
+ if (ctx.getBelType(b) == TYPE_ICESTORM_LC) {
+ dst_wires.push_back(ctx.getWireBelPin(b, PIN_I0));
+ dst_wires.push_back(ctx.getWireBelPin(b, PIN_I1));
+ dst_wires.push_back(ctx.getWireBelPin(b, PIN_I2));
+ dst_wires.push_back(ctx.getWireBelPin(b, PIN_I3));
+ dst_wires.push_back(ctx.getWireBelPin(b, PIN_CEN));
+ dst_wires.push_back(ctx.getWireBelPin(b, PIN_CIN));
+ }
+ if (ctx.getBelType(b) == TYPE_SB_IO) {
+ dst_wires.push_back(ctx.getWireBelPin(b, PIN_D_OUT_0));
+ dst_wires.push_back(ctx.getWireBelPin(b, PIN_OUTPUT_ENABLE));
+ }
+ }
+
+ ctx.shuffle(src_wires);
+ ctx.shuffle(dst_wires);
+
+ for (int i = 0; i < int(src_wires.size()) && i < int(dst_wires.size());
+ i++) {
+ delay_t actual_delay;
+ if (!get_actual_route_delay(&ctx, src_wires[i], dst_wires[i],
+ actual_delay))
+ continue;
+ printf("%s %s %.3f %.3f\n",
+ ctx.getWireName(src_wires[i]).c_str(&ctx),
+ ctx.getWireName(dst_wires[i]).c_str(&ctx),
+ ctx.getDelayNS(actual_delay),
+ ctx.getDelayNS(
+ ctx.estimateDelay(src_wires[i], dst_wires[i])));
+ }
+ }
+
if (vm.count("json")) {
std::string filename = vm["json"].as<std::string>();
std::istream *f = new std::ifstream(filename);