Few more DFF features

This commit is contained in:
Miodrag Milanovic 2025-01-14 16:45:48 +01:00
parent 3e6e0273dd
commit 1eac0528ab
3 changed files with 62 additions and 7 deletions

View File

@ -120,6 +120,7 @@ X(SR_VAL)
X(SR_INV)
X(EN_INV)
X(CLK_INV)
X(EN_SR)
X(CC_BUFG)
X(BUFG)

View File

@ -108,6 +108,23 @@ void updateINV(Context *ctx, CellInfo *cell, IdString port)
}
}
void updateSR_INV(Context *ctx, CellInfo *cell, IdString port, IdString param)
{
if (cell->params.count(param) == 0) return;
unsigned init_val = int_or_default(cell->params, param);
WireId pin_wire = ctx->getBelPinWire(cell->bel, port);
for (PipId pip : ctx->getPipsUphill(pin_wire)) {
if (!ctx->getBoundPipNet(pip))
continue;
const auto extra_data = *reinterpret_cast<const GateMatePipExtraDataPOD *>(
chip_pip_info(ctx->chip_info, pip).extra_data.get());
if (!extra_data.name)
continue;
if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_CPE_INV)) {
cell->params[param] = Property(3 - init_val, 2);
}
}
}
void GateMateImpl::postRoute()
{
@ -178,7 +195,11 @@ void GateMateImpl::postRoute()
updateLUT(ctx, cell.second.get(), id_IN8, id_INIT_L03);
updateINV(ctx, cell.second.get(), id_CLK);
updateINV(ctx, cell.second.get(), id_EN);
updateINV(ctx, cell.second.get(), id_SR);
bool set = int_or_default(cell.second->params, id_EN_SR, 0) == 1;
if (set)
updateSR_INV(ctx, cell.second.get(), id_SR, id_S);
else
updateSR_INV(ctx, cell.second.get(), id_SR, id_R);
}
}

View File

@ -361,7 +361,6 @@ void GateMatePacker::pack_cpe()
continue;
ci.renamePort(id_D, id_IN1);
ci.renamePort(id_Q, id_OUT2);
ci.disconnectPort(id_SR);
ci.params[id_O2] = Property(0b00, 2);
ci.params[id_2D_IN] = Property(1, 1);
ci.params[id_INIT_L00] = Property(0b1010, 4);
@ -372,8 +371,8 @@ void GateMatePacker::pack_cpe()
ci.params[id_INIT_L20] = Property(0b1100, 4);
NetInfo *en_net = ci.getPort(id_EN);
bool invert = int_or_default(ci.params, id_EN_INV, 0) == 1;
if (en_net) {
bool invert = int_or_default(ci.params, id_EN_INV, 0) == 1;
if (en_net->name == ctx->id("$PACKER_GND")) {
ci.params[id_EN] = Property(invert ? 0b11 : 0b00, 2);
ci.disconnectPort(id_EN);
@ -383,12 +382,14 @@ void GateMatePacker::pack_cpe()
} else {
ci.params[id_EN] = Property(invert ? 0b01 : 0b10, 2);
}
} else {
ci.params[id_EN] = Property(invert ? 0b11 : 0b00, 2);
}
ci.unsetParam(id_EN_INV);
NetInfo *clk_net = ci.getPort(id_CLK);
invert = int_or_default(ci.params, id_CLK_INV, 0) == 1;
if (clk_net) {
bool invert = int_or_default(ci.params, id_CLK_INV, 0) == 1;
if (clk_net->name == ctx->id("$PACKER_GND")) {
ci.params[id_CLK] = Property(invert ? 0b11 : 0b00, 2);
ci.disconnectPort(id_CLK);
@ -398,14 +399,46 @@ void GateMatePacker::pack_cpe()
} else {
ci.params[id_CLK] = Property(invert ? 0b01 : 0b10, 2);
}
} else {
ci.params[id_CLK] = Property(invert ? 0b11 : 0b00, 2);
}
ci.unsetParam(id_CLK_INV);
ci.params[id_R] = Property(0b11, 2);
ci.params[id_S] = Property(0b11, 2);
NetInfo *sr_net = ci.getPort(id_SR);
invert = int_or_default(ci.params, id_SR_INV, 0) == 1;
int sr_val = int_or_default(ci.params, id_SR_VAL, 0) == 1;
if (sr_net) {
if (sr_net->name == ctx->id("$PACKER_GND")) {
if (invert)
log_error("Invalid DFF configuration\n.");
ci.params[id_R] = Property(0b11, 2);
ci.params[id_S] = Property(0b11, 2);
ci.disconnectPort(id_SR);
} else if (sr_net->name == ctx->id("$PACKER_VCC")) {
if (!invert)
log_error("Invalid DFF configuration\n.");
ci.params[id_R] = Property(0b11, 2);
ci.params[id_S] = Property(0b11, 2);
ci.disconnectPort(id_SR);
} else {
if (sr_val) {
ci.params[id_R] = Property(0b11, 2);
ci.params[id_S] = Property(invert ? 0b01 : 0b10, 2);
ci.params[id_EN_SR] = Property(0b1, 1);
} else {
ci.params[id_R] = Property(invert ? 0b01 : 0b10, 2);
ci.params[id_S] = Property(0b11, 2);
}
}
} else {
if (invert)
log_error("Invalid DFF configuration\n.");
ci.params[id_R] = Property(0b11, 2);
ci.params[id_S] = Property(0b11, 2);
}
ci.unsetParam(id_SR_VAL);
ci.unsetParam(id_SR_INV);
bool init = int_or_default(ci.params, id_INIT, 0) == 1;
if (init)
ci.params[id_FF_INIT] = Property(0b11, 2);