ice40: make PLL packing more robust
This commit is contained in:
parent
26be6f9761
commit
1bf22a7f64
@ -28,6 +28,7 @@ NEXTPNR_NAMESPACE_BEGIN
|
|||||||
void add_port(const Context *ctx, CellInfo *cell, std::string name, PortType dir)
|
void add_port(const Context *ctx, CellInfo *cell, std::string name, PortType dir)
|
||||||
{
|
{
|
||||||
IdString id = ctx->id(name);
|
IdString id = ctx->id(name);
|
||||||
|
NPNR_ASSERT(cell->ports.count(id) == 0);
|
||||||
cell->ports[id] = PortInfo{id, nullptr, dir};
|
cell->ports[id] = PortInfo{id, nullptr, dir};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +238,7 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
|
|||||||
|
|
||||||
add_port(ctx, new_cell.get(), "SCLK", PORT_IN);
|
add_port(ctx, new_cell.get(), "SCLK", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "SDI", PORT_IN);
|
add_port(ctx, new_cell.get(), "SDI", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "SDI", PORT_OUT);
|
add_port(ctx, new_cell.get(), "SDO", PORT_OUT);
|
||||||
|
|
||||||
add_port(ctx, new_cell.get(), "LOCK", PORT_OUT);
|
add_port(ctx, new_cell.get(), "LOCK", PORT_OUT);
|
||||||
add_port(ctx, new_cell.get(), "PLLOUT_A", PORT_OUT);
|
add_port(ctx, new_cell.get(), "PLLOUT_A", PORT_OUT);
|
||||||
|
@ -746,6 +746,19 @@ static void pack_special(Context *ctx)
|
|||||||
log_error("PLL '%s' has a REFERENCECLK but is not a CORE PLL", ci->name.c_str(ctx));
|
log_error("PLL '%s' has a REFERENCECLK but is not a CORE PLL", ci->name.c_str(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packed->ports.count(ctx->id(newname)) == 0) {
|
||||||
|
if (ci->ports[pi.name].net == nullptr) {
|
||||||
|
log_warning("PLL '%s' has unknown unconnected port '%s' - ignoring\n", ci->name.c_str(ctx), pi.name.c_str(ctx));
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (ctx->force) {
|
||||||
|
log_error("PLL '%s' has unknown connected port '%s'\n", ci->name.c_str(ctx), pi.name.c_str(ctx));
|
||||||
|
} else {
|
||||||
|
log_warning("PLL '%s' has unknown connected port '%s' - ignoring\n", ci->name.c_str(ctx), pi.name.c_str(ctx));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed.get(), ctx->id(newname));
|
replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed.get(), ctx->id(newname));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,13 +806,13 @@ static void pack_special(Context *ctx)
|
|||||||
packagepin_cell->ports.erase(pll_packagepin_driver.port);
|
packagepin_cell->ports.erase(pll_packagepin_driver.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info(" constrained '%s' to %s\n", packed->name.c_str(ctx), ctx->getBelName(bel).c_str(ctx));
|
log_info(" constrained PLL '%s' to %s\n", packed->name.c_str(ctx), ctx->getBelName(bel).c_str(ctx));
|
||||||
packed->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx);
|
packed->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx);
|
||||||
pll_bel = bel;
|
pll_bel = bel;
|
||||||
constrained = true;
|
constrained = true;
|
||||||
}
|
}
|
||||||
if (!constrained) {
|
if (!constrained) {
|
||||||
log_error(" could not constrain '%s' to any PLL Bel\n", packed->name.c_str(ctx));
|
log_error("Could not constrain PLL '%s' to any PLL Bel (too many PLLs?)\n", packed->name.c_str(ctx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -818,6 +831,8 @@ static void pack_special(Context *ctx)
|
|||||||
// If we have a net connected to LOCK, make sure it only drives LUTs.
|
// If we have a net connected to LOCK, make sure it only drives LUTs.
|
||||||
auto port = packed->ports[ctx->id("LOCK")];
|
auto port = packed->ports[ctx->id("LOCK")];
|
||||||
if (port.net != nullptr) {
|
if (port.net != nullptr) {
|
||||||
|
log_info(" PLL '%s' has LOCK output, need to pass all outputs via LUT\n",
|
||||||
|
ci->name.c_str(ctx));
|
||||||
bool found_lut = false;
|
bool found_lut = false;
|
||||||
bool all_luts = true;
|
bool all_luts = true;
|
||||||
unsigned int lut_count = 0;
|
unsigned int lut_count = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user