Add CPE input inverters

This commit is contained in:
Miodrag Milanovic 2025-01-08 14:08:41 +01:00
parent 91a88dda77
commit 1fc8809e18
3 changed files with 46 additions and 0 deletions

View File

@ -37,6 +37,7 @@ enum MuxFlags
MUX_INVERT = 1,
MUX_VISIBLE = 2,
MUX_CONFIG = 4,
MUX_CPE_INV = 8,
};
enum PipExtra

View File

@ -68,6 +68,28 @@ bool GateMateImpl::isBelLocationValid(BelId bel, bool explain_invalid) const
return true;
}
void updateLUT(Context *ctx, CellInfo *cell, IdString port, IdString init)
{
if (cell->params.count(init) == 0) return;
unsigned init_val = int_or_default(cell->params, init);
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)) {
if (port.in(id_IN1,id_IN3,id_IN5,id_IN7))
init_val = (init_val & 0b1010) >> 1 | (init_val & 0b0101) << 1;
else
init_val = (init_val & 0b0011) << 2 | (init_val & 0b1100) >> 2;
cell->params[init] = Property(init_val, 4);
}
}
}
void GateMateImpl::postRoute()
{
ctx->assignArchInfo();
@ -104,6 +126,21 @@ void GateMateImpl::postRoute()
}
}
for (auto &cell : ctx->cells) {
if (cell.second->type == id_CPE) {
// if LUT part used
updateLUT(ctx, cell.second.get(), id_IN1, id_INIT_L00);
updateLUT(ctx, cell.second.get(), id_IN2, id_INIT_L00);
updateLUT(ctx, cell.second.get(), id_IN3, id_INIT_L01);
updateLUT(ctx, cell.second.get(), id_IN4, id_INIT_L01);
updateLUT(ctx, cell.second.get(), id_IN5, id_INIT_L02);
updateLUT(ctx, cell.second.get(), id_IN6, id_INIT_L02);
updateLUT(ctx, cell.second.get(), id_IN7, id_INIT_L03);
updateLUT(ctx, cell.second.get(), id_IN8, id_INIT_L03);
}
}
print_utilisation(ctx);
const ArchArgs &args = ctx->args;

View File

@ -30,6 +30,7 @@ PIP_EXTRA_CPE = 2
MUX_INVERT = 1
MUX_VISIBLE = 2
MUX_CONFIG = 4
MUX_CPE_INV = 8
parser = argparse.ArgumentParser()
parser.add_argument("--lib", help="Project Peppercorn python database script path", type=str, required=True)
@ -91,6 +92,12 @@ def main():
if "CPE" in type_name:
pp = tt.create_pip("CPE.IN1", "CPE.RAM_O2")
pp.extra_data = PipExtraData(PIP_EXTRA_CPE,ch.strs.id("RAM_O2"))
for i in range(1,9):
tt.create_wire(f"CPE.V_IN{i}", "CPE_VIRTUAL_WIRE")
pp = tt.create_pip(f"CPE.V_IN{i}", f"CPE.IN{i}")
pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(f"CPE.IN{i}_INV"), 1, i, 0)
pp = tt.create_pip(f"CPE.V_IN{i}", f"CPE.IN{i}")
pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(f"CPE.IN{i}_INV"), 1, i, MUX_CPE_INV | MUX_INVERT)
if "GPIO" in type_name:
tt.create_wire("GPIO.OUT_D1", "WIRE_INTERNAL")
tt.create_wire("GPIO.OUT_D2", "WIRE_INTERNAL")
@ -167,6 +174,7 @@ def main():
for _,nodes in dev.get_connections():
node = []
for conn in nodes:
conn.name = conn.name.replace("CPE.IN", "CPE.V_IN")
node.append(NodeWire(conn.x + 2, conn.y + 2, conn.name))
ch.add_node(node)
set_timings(ch)