diff --git a/himbaechel/uarch/gatemate/extra_data.h b/himbaechel/uarch/gatemate/extra_data.h index 3b48313d..ce33be74 100644 --- a/himbaechel/uarch/gatemate/extra_data.h +++ b/himbaechel/uarch/gatemate/extra_data.h @@ -37,6 +37,7 @@ enum MuxFlags MUX_INVERT = 1, MUX_VISIBLE = 2, MUX_CONFIG = 4, + MUX_CPE_INV = 8, }; enum PipExtra diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index cb7aa8ae..3ce01300 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -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( + 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; diff --git a/himbaechel/uarch/gatemate/gen/arch_gen.py b/himbaechel/uarch/gatemate/gen/arch_gen.py index 0404def8..68ad47b9 100644 --- a/himbaechel/uarch/gatemate/gen/arch_gen.py +++ b/himbaechel/uarch/gatemate/gen/arch_gen.py @@ -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)