aboutsummaryrefslogtreecommitdiffstats
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
parent84174702764ef5b6989cae84f16571a6519d9c17 (diff)
downloadnextpnr-9c37aef499b584ca464d8ceb238aec9321c0a274.tar.gz
nextpnr-9c37aef499b584ca464d8ceb238aec9321c0a274.tar.bz2
nextpnr-9c37aef499b584ca464d8ceb238aec9321c0a274.zip
machxo2: Detect LOC attributes during packing to implement rudimentary user constraints.
-rw-r--r--machxo2/arch.cc15
-rw-r--r--machxo2/arch.h3
-rw-r--r--machxo2/pack.cc43
3 files changed, 61 insertions, 0 deletions
diff --git a/machxo2/arch.cc b/machxo2/arch.cc
index 20c68065..abc281cb 100644
--- a/machxo2/arch.cc
+++ b/machxo2/arch.cc
@@ -262,6 +262,21 @@ std::vector<IdString> Arch::getBelPins(BelId bel) const
// ---------------------------------------------------------------
+BelId Arch::getPackagePinBel(const std::string &pin) const
+{
+ for (int i = 0; i < package_info->num_pins; i++) {
+ if (package_info->pin_data[i].name.get() == pin) {
+ BelId bel;
+ bel.location = package_info->pin_data[i].abs_loc;
+ bel.index = package_info->pin_data[i].bel_index;
+ return bel;
+ }
+ }
+ return BelId();
+}
+
+// ---------------------------------------------------------------
+
WireId Arch::getWireByName(IdString name) const { return WireId(); }
IdString Arch::getWireName(WireId wire) const { return IdString(); }
diff --git a/machxo2/arch.h b/machxo2/arch.h
index bcac5390..d620be4e 100644
--- a/machxo2/arch.h
+++ b/machxo2/arch.h
@@ -606,6 +606,9 @@ struct Arch : BaseCtx
PortType getBelPinType(BelId bel, IdString pin) const;
std::vector<IdString> getBelPins(BelId bel) const;
+ // Package
+ BelId getPackagePinBel(const std::string &pin) const;
+
// Wires
WireId getWireByName(IdString name) const;
IdString getWireName(WireId wire) const;
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);
}
}