nexus: Use dedicated Vcc routing for OXIDE_COMB pins

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2020-10-22 20:05:04 +01:00
parent e6c2887773
commit 0a59cbb8ce
3 changed files with 18 additions and 12 deletions

View File

@ -121,6 +121,7 @@ enum RelLocType : uint8_t
REL_LOC_BRANCH_R = 4,
REL_LOC_SPINE = 5,
REL_LOC_HROW = 6,
REL_LOC_VCC = 7,
};
enum ArcFlags
@ -421,6 +422,7 @@ inline bool chip_rel_loc_tile(const ChipInfoPOD *chip, int32_t base, const RelWi
return true;
}
case REL_LOC_GLOBAL:
case REL_LOC_VCC:
next = 0;
return true;
default:

View File

@ -1 +1 @@
6
7

View File

@ -292,6 +292,8 @@ struct NexusPacker
continue;
if (cell->ports.count(pin))
continue;
if (cell->type == id_OXIDE_COMB && pin == id_SEL)
continue; // doesn't always exist and not needed
cell->ports[pin].name = pin;
cell->ports[pin].type = dir;
}
@ -313,7 +315,7 @@ struct NexusPacker
NetInfo *new_net = ctx->createNet(ctx->id(stringf("$CONST_%s_NET_", type.c_str(ctx))));
CellInfo *new_cell = ctx->createCell(ctx->id(stringf("$CONST_%s_DRV_", type.c_str(ctx))), type);
new_cell->addInput(id_Z);
new_cell->addOutput(id_Z);
connect_port(ctx, new_net, new_cell, id_Z);
return new_net;
}
@ -369,7 +371,7 @@ struct NexusPacker
std::vector<IdString> trim_nets;
for (auto cell : sorted(ctx->cells)) {
CellInfo *ci = cell.second;
if (ci->type != id_INV && ci->type != id_VLO && ci->type != id_VHI)
if (ci->type != id_INV && ci->type != id_VLO && ci->type != id_VHI && ci->type != id_VCC_DRV)
continue;
NetInfo *z = get_net_or_empty(ci, id_Z);
if (z == nullptr) {
@ -417,7 +419,7 @@ struct NexusPacker
}
}
NetInfo *gnd_net = nullptr, *vcc_net = nullptr;
NetInfo *gnd_net = nullptr, *vcc_net = nullptr, *dedi_vcc_net = nullptr;
void process_inv_constants(CellInfo *cell)
{
@ -449,11 +451,11 @@ struct NexusPacker
// If there is a hard constant option; use it
if ((pin_style & int(req_mux)) == req_mux) {
if (cell->type == id_OXIDE_COMB) {
// Due to potentially overlapping routing, explicitly keep the one-driver
// until can correctly use the dedicated Vcc route
if (str_or_default(cell->params, id_MODE, "LOGIC") != "LOGIC")
continue;
if ((cell->type == id_OXIDE_COMB) && (req_mux == PINMUX_1)) {
// We need to add a connection to the dedicated Vcc resource that can feed these cell ports
disconnect_port(ctx, cell, port_name);
connect_port(ctx, dedi_vcc_net, cell, port_name);
continue;
}
disconnect_port(ctx, cell, port_name);
@ -654,13 +656,15 @@ struct NexusPacker
void pack_constants()
{
// Make sure we have high and low nets available
get_const_net(id_VHI);
get_const_net(id_VLO);
vcc_net = get_const_net(id_VHI);
gnd_net = get_const_net(id_VLO);
dedi_vcc_net = get_const_net(id_VCC_DRV);
// Iterate through cells
for (auto cell : sorted(ctx->cells)) {
CellInfo *ci = cell.second;
// Skip certain cells at this point
if (ci->type != id_LUT4 && ci->type != id_INV && ci->type != id_VHI && ci->type != id_VLO)
if (ci->type != id_LUT4 && ci->type != id_INV && ci->type != id_VHI && ci->type != id_VLO &&
ci->type != id_VCC_DRV)
process_inv_constants(cell.second);
}
// Remove superfluous inverters and constant drivers