From 9c37aef499b584ca464d8ceb238aec9321c0a274 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 8 Dec 2020 01:42:58 -0500 Subject: machxo2: Detect LOC attributes during packing to implement rudimentary user constraints. --- machxo2/arch.cc | 15 +++++++++++++++ machxo2/arch.h | 3 +++ machxo2/pack.cc | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) 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 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 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); } } -- cgit v1.2.3