aboutsummaryrefslogtreecommitdiffstats
path: root/machxo2/pack.cc
diff options
context:
space:
mode:
authorWilliam D. Jones <thor0505@comcast.net>2020-12-08 01:42:58 -0500
committergatecat <gatecat@ds0.me>2021-02-12 10:36:59 +0000
commit9c37aef499b584ca464d8ceb238aec9321c0a274 (patch)
tree6dd207fcfebf2bb5638447494f5cbc8030c88efe /machxo2/pack.cc
parent84174702764ef5b6989cae84f16571a6519d9c17 (diff)
downloadnextpnr-9c37aef499b584ca464d8ceb238aec9321c0a274.tar.gz
nextpnr-9c37aef499b584ca464d8ceb238aec9321c0a274.tar.bz2
nextpnr-9c37aef499b584ca464d8ceb238aec9321c0a274.zip
machxo2: Detect LOC attributes during packing to implement rudimentary user constraints.
Diffstat (limited to 'machxo2/pack.cc')
-rw-r--r--machxo2/pack.cc43
1 files changed, 43 insertions, 0 deletions
diff --git a/machxo2/pack.cc b/machxo2/pack.cc
index 5984b740..7c05b22a 100644
--- a/machxo2/pack.cc
+++ b/machxo2/pack.cc
@@ -175,6 +175,49 @@ static void pack_io(Context *ctx)
for (auto &p : ci->ports)
disconnect_port(ctx, ci, p.first);
packed_cells.insert(ci->name);
+ } else if(is_facade_iob(ctx, ci)) {
+ // If net attached to PAD port of FACADE_IO has a LOC attribute OR
+ // FACADE_IO has LOC attribute, convert the LOC (pin) to a BEL
+ // attribute and place FACADE_IO at resulting BEL location.
+
+ auto pad_net = ci->ports[id_PAD].net;
+ auto loc_attr_pad = pad_net->attrs.find(ctx->id("LOC"));
+ auto loc_attr_cell = ci->attrs.find(ctx->id("LOC"));
+ auto bel_attr_cell = ci->attrs.find(ctx->id("BEL"));
+
+ // Handle errors
+ if(loc_attr_pad != pad_net->attrs.end() && loc_attr_cell != ci->attrs.end())
+ log_error("IO buffer %s and attached PAD net %s both have LOC attributes.\n",
+ ci->name.c_str(ctx), pad_net->name.c_str(ctx));
+ else if(loc_attr_pad != pad_net->attrs.end() && bel_attr_cell != ci->attrs.end())
+ log_error("IO buffer %s has a BEL attribute and attached PAD net %s has a LOC attribute.\n",
+ ci->name.c_str(ctx), pad_net->name.c_str(ctx));
+ else if(loc_attr_cell != ci->attrs.end() && bel_attr_cell != ci->attrs.end())
+ log_error("IO buffer %s has both a BEL attribute and LOC attribute.\n",
+ ci->name.c_str(ctx));
+
+ std::string pin;
+ // At this point only PAD net or FACADE_IO has LOC attribute.
+ if(loc_attr_pad != pad_net->attrs.end()) {
+ pin = loc_attr_pad->second.as_string();
+ log_info("found LOC attribute on net %s. Will constrain IO buffer %s.\n",
+ pad_net->name.c_str(ctx), ci->name.c_str(ctx));
+ } else if(loc_attr_cell != ci->attrs.end()) {
+ log_info("found LOC attribute on IO buffer %s.\n", ci->name.c_str(ctx));
+ pin = loc_attr_cell->second.as_string();
+ } else
+ // Nothing to do if no LOC attrs.
+ continue;
+
+ BelId pinBel = ctx->getPackagePinBel(pin);
+ if (pinBel == BelId()) {
+ log_error("IO buffer '%s' constrained to pin '%s', which does not exist for package '%s'.\n",
+ ci->name.c_str(ctx), pin.c_str(), ctx->args.package.c_str());
+ } else {
+ log_info("pin '%s' constrained to Bel '%s'.\n", ci->name.c_str(ctx),
+ ctx->getBelName(pinBel).c_str(ctx));
+ }
+ ci->attrs[ctx->id("BEL")] = ctx->getBelName(pinBel).str(ctx);
}
}