machxo2: Use attrmvcp in yosys to implement LOC constraint and only check for LOC on FACADE_IO.

This commit is contained in:
William D. Jones 2020-12-12 22:05:39 -05:00 committed by gatecat
parent 9c37aef499
commit 31ea8f8719

View File

@ -176,38 +176,22 @@ static void pack_io(Context *ctx)
disconnect_port(ctx, ci, p.first); disconnect_port(ctx, ci, p.first);
packed_cells.insert(ci->name); packed_cells.insert(ci->name);
} else if(is_facade_iob(ctx, ci)) { } else if(is_facade_iob(ctx, ci)) {
// If net attached to PAD port of FACADE_IO has a LOC attribute OR // If FACADE_IO has LOC attribute, convert the LOC (pin) to a BEL
// FACADE_IO has LOC attribute, convert the LOC (pin) to a BEL // attribute and place FACADE_IO at resulting BEL location. A BEL
// attribute and place FACADE_IO at resulting BEL location. // attribute already on a FACADE_IO is an error. Attributes on
// the pin attached to the PAD of FACADE_IO are ignored by this
auto pad_net = ci->ports[id_PAD].net; // packing phase.
auto loc_attr_pad = pad_net->attrs.find(ctx->id("LOC"));
auto loc_attr_cell = ci->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")); auto bel_attr_cell = ci->attrs.find(ctx->id("BEL"));
// Handle errors if(loc_attr_cell != ci->attrs.end()) {
if(loc_attr_pad != pad_net->attrs.end() && loc_attr_cell != ci->attrs.end()) if (bel_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", log_error("IO buffer %s has both a BEL attribute and LOC attribute.\n",
ci->name.c_str(ctx)); 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)); log_info("found LOC attribute on IO buffer %s.\n", ci->name.c_str(ctx));
pin = loc_attr_cell->second.as_string(); std::string pin = loc_attr_cell->second.as_string();
} else
// Nothing to do if no LOC attrs.
continue;
BelId pinBel = ctx->getPackagePinBel(pin); BelId pinBel = ctx->getPackagePinBel(pin);
if (pinBel == BelId()) { if (pinBel == BelId()) {
@ -220,6 +204,7 @@ static void pack_io(Context *ctx)
ci->attrs[ctx->id("BEL")] = ctx->getBelName(pinBel).str(ctx); ci->attrs[ctx->id("BEL")] = ctx->getBelName(pinBel).str(ctx);
} }
} }
}
for (auto pcell : packed_cells) { for (auto pcell : packed_cells) {
ctx->cells.erase(pcell); ctx->cells.erase(pcell);