ice40: Move global net test to Arch
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
2e6916ecab
commit
289fca0976
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user