ice40: Move global net test to Arch

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-06-23 12:09:01 +02:00
parent 2e6916ecab
commit 289fca0976
6 changed files with 39 additions and 26 deletions

View File

@ -168,6 +168,9 @@ Arch::Arch(ArchArgs args) : args(args)
wire_to_net.resize(chip_info->num_wires); wire_to_net.resize(chip_info->num_wires);
pip_to_net.resize(chip_info->num_pips); pip_to_net.resize(chip_info->num_pips);
switches_locked.resize(chip_info->num_switches); switches_locked.resize(chip_info->num_switches);
// Initialise regularly used IDStrings for performance
id_glb_buf_out = id("GLOBAL_BUFFER_OUTPUT");
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -501,4 +504,11 @@ bool Arch::isClockPort(const CellInfo *cell, IdString port) const
return false; return false;
} }
bool Arch::isGlobalNet(const NetInfo *net) const
{
if (net == nullptr)
return false;
return net->driver.cell != nullptr && net->driver.port == id_glb_buf_out;
}
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -800,6 +800,10 @@ struct Arch : BaseCtx
IdString getPortClock(const CellInfo *cell, IdString port) const; IdString getPortClock(const CellInfo *cell, IdString port) const;
// Return true if a port is a clock // Return true if a port is a clock
bool isClockPort(const CellInfo *cell, IdString port) const; bool isClockPort(const CellInfo *cell, IdString port) const;
// Return true if a port is a net
bool isGlobalNet(const NetInfo *net) const;
IdString id_glb_buf_out;
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -58,11 +58,11 @@ bool PlaceValidityChecker::logicCellsCompatible(
clk = get_net_or_empty(cell, id_clk); clk = get_net_or_empty(cell, id_clk);
sr = get_net_or_empty(cell, id_sr); sr = get_net_or_empty(cell, id_sr);
if (!is_global_net(ctx, cen) && cen != nullptr) if (!ctx->isGlobalNet(cen) && cen != nullptr)
locals_count++; locals_count++;
if (!is_global_net(ctx, clk) && clk != nullptr) if (!ctx->isGlobalNet(clk) && clk != nullptr)
locals_count++; locals_count++;
if (!is_global_net(ctx, sr) && sr != nullptr) if (!ctx->isGlobalNet(sr) && sr != nullptr)
locals_count++; locals_count++;
if (bool_or_default(cell->params, id_neg_clk)) { if (bool_or_default(cell->params, id_neg_clk)) {
@ -140,7 +140,8 @@ bool PlaceValidityChecker::isValidBelForCell(CellInfo *cell, BelId bel)
} else if (cell->type == id_sb_gb) { } else if (cell->type == id_sb_gb) {
bool is_reset = false, is_cen = false; bool is_reset = false, is_cen = false;
assert(cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net != nullptr); assert(cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net != nullptr);
for (auto user : cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net->users) { for (auto user :
cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net->users) {
if (is_reset_port(ctx, user)) if (is_reset_port(ctx, user))
is_reset = true; is_reset = true;
if (is_enable_port(ctx, user)) if (is_enable_port(ctx, user))

View File

@ -36,8 +36,8 @@ CellInfo *create_ice_cell(Context *ctx, IdString type, std::string name)
static int auto_idx = 0; static int auto_idx = 0;
CellInfo *new_cell = new CellInfo(); CellInfo *new_cell = new CellInfo();
if (name.empty()) { if (name.empty()) {
new_cell->name = ctx->id( "$nextpnr_" + type.str(ctx) + "_" + new_cell->name = ctx->id("$nextpnr_" + type.str(ctx) + "_" +
std::to_string(auto_idx++)); std::to_string(auto_idx++));
} else { } else {
new_cell->name = ctx->id(name); new_cell->name = ctx->id(name);
} }
@ -269,10 +269,4 @@ bool is_enable_port(const Context *ctx, const PortRef &port)
return false; return false;
} }
bool is_global_net(const Context *ctx, const NetInfo *net)
{
return bool(
net_driven_by(ctx, net, is_gbuf, ctx->id("GLOBAL_BUFFER_OUTPUT")));
}
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -117,9 +117,6 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc,
// Convert a nextpnr IO buffer to a SB_IO // Convert a nextpnr IO buffer to a SB_IO
void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio); void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio);
// Return true if a net is a global net
bool is_global_net(const Context *ctx, const NetInfo *net);
// Return true if a port is a clock port // Return true if a port is a clock port
bool is_clock_port(const Context *ctx, const PortRef &port); bool is_clock_port(const Context *ctx, const PortRef &port);

View File

@ -131,8 +131,9 @@ static void pack_carries(Context *ctx)
CellInfo *ci = cell.second; CellInfo *ci = cell.second;
if (is_carry(ctx, ci)) { if (is_carry(ctx, ci)) {
packed_cells.insert(cell.first); packed_cells.insert(cell.first);
CellInfo *carry_ci_lc = net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, CellInfo *carry_ci_lc =
is_lc, ctx->id("I3"), false); net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, is_lc,
ctx->id("I3"), false);
if (!ci->ports.at(ctx->id("I0")).net) if (!ci->ports.at(ctx->id("I0")).net)
log_error("SB_CARRY '%s' has disconnected port I0\n", log_error("SB_CARRY '%s' has disconnected port I0\n",
cell.first.c_str(ctx)); cell.first.c_str(ctx));
@ -227,7 +228,8 @@ static void pack_ram(Context *ctx)
newname.substr(bpos + 1, newname.substr(bpos + 1,
(newname.size() - bpos) - 2); (newname.size() - bpos) - 2);
} }
replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed, ctx->id(newname)); replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed,
ctx->id(newname));
} }
} }
} }
@ -268,14 +270,16 @@ static void pack_constants(Context *ctx)
{ {
log_info("Packing constants..\n"); log_info("Packing constants..\n");
CellInfo *gnd_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_GND"); CellInfo *gnd_cell =
create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_GND");
gnd_cell->params[ctx->id("LUT_INIT")] = "0"; gnd_cell->params[ctx->id("LUT_INIT")] = "0";
NetInfo *gnd_net = new NetInfo; NetInfo *gnd_net = new NetInfo;
gnd_net->name = ctx->id("$PACKER_GND_NET"); gnd_net->name = ctx->id("$PACKER_GND_NET");
gnd_net->driver.cell = gnd_cell; gnd_net->driver.cell = gnd_cell;
gnd_net->driver.port = ctx->id("O"); gnd_net->driver.port = ctx->id("O");
CellInfo *vcc_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC"); CellInfo *vcc_cell =
create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC");
vcc_cell->params[ctx->id("LUT_INIT")] = "1"; vcc_cell->params[ctx->id("LUT_INIT")] = "1";
NetInfo *vcc_net = new NetInfo; NetInfo *vcc_net = new NetInfo;
vcc_net->name = ctx->id("$PACKER_VCC_NET"); vcc_net->name = ctx->id("$PACKER_VCC_NET");
@ -336,12 +340,14 @@ static void pack_io(Context *ctx)
CellInfo *sb = nullptr; CellInfo *sb = nullptr;
if (ci->type == ctx->id("$nextpnr_ibuf") || if (ci->type == ctx->id("$nextpnr_ibuf") ||
ci->type == ctx->id("$nextpnr_iobuf")) { ci->type == ctx->id("$nextpnr_iobuf")) {
sb = net_only_drives(ctx, ci->ports.at(ctx->id("O")).net, is_sb_io, sb = net_only_drives(ctx, ci->ports.at(ctx->id("O")).net,
ctx->id("PACKAGE_PIN"), true, ci); is_sb_io, ctx->id("PACKAGE_PIN"), true,
ci);
} else if (ci->type == ctx->id("$nextpnr_obuf")) { } else if (ci->type == ctx->id("$nextpnr_obuf")) {
sb = net_only_drives(ctx, ci->ports.at(ctx->id("I")).net, is_sb_io, sb = net_only_drives(ctx, ci->ports.at(ctx->id("I")).net,
ctx->id("PACKAGE_PIN"), true, ci); is_sb_io, ctx->id("PACKAGE_PIN"), true,
ci);
} }
if (sb != nullptr) { if (sb != nullptr) {
// Trivial case, SB_IO used. Just destroy the net and the // Trivial case, SB_IO used. Just destroy the net and the
@ -416,7 +422,7 @@ static void promote_globals(Context *ctx)
std::map<IdString, int> clock_count, reset_count, cen_count; std::map<IdString, int> clock_count, reset_count, cen_count;
for (auto net : sorted(ctx->nets)) { for (auto net : sorted(ctx->nets)) {
NetInfo *ni = net.second; NetInfo *ni = net.second;
if (ni->driver.cell != nullptr && !is_global_net(ctx, ni)) { if (ni->driver.cell != nullptr && !ctx->isGlobalNet(ni)) {
clock_count[net.first] = 0; clock_count[net.first] = 0;
reset_count[net.first] = 0; reset_count[net.first] = 0;
cen_count[net.first] = 0; cen_count[net.first] = 0;
@ -503,7 +509,8 @@ static void pack_intosc(Context *ctx)
replace_port(ci, ctx->id("CLKLFEN"), packed, ctx->id("CLKLFEN")); replace_port(ci, ctx->id("CLKLFEN"), packed, ctx->id("CLKLFEN"));
replace_port(ci, ctx->id("CLKLFPU"), packed, ctx->id("CLKLFPU")); replace_port(ci, ctx->id("CLKLFPU"), packed, ctx->id("CLKLFPU"));
if (bool_or_default(ci->attrs, ctx->id("ROUTE_THROUGH_FABRIC"))) { if (bool_or_default(ci->attrs, ctx->id("ROUTE_THROUGH_FABRIC"))) {
replace_port(ci, ctx->id("CLKLF"), packed, ctx->id("CLKLF_FABRIC")); replace_port(ci, ctx->id("CLKLF"), packed,
ctx->id("CLKLF_FABRIC"));
} else { } else {
replace_port(ci, ctx->id("CLKLF"), packed, ctx->id("CLKLF")); replace_port(ci, ctx->id("CLKLF"), packed, ctx->id("CLKLF"));
} }