From da6837659ff024da84b9fdcaf38f97ff1927128c Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 7 Jul 2025 16:33:00 +0200 Subject: [PATCH] Optimize CC_LUT1 --- himbaechel/uarch/gatemate/pack.cc | 58 ++++++++++++++++++++++++++- himbaechel/uarch/gatemate/pack.h | 8 ++++ himbaechel/uarch/gatemate/pack_cpe.cc | 2 + 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/himbaechel/uarch/gatemate/pack.cc b/himbaechel/uarch/gatemate/pack.cc index 66a81df1..e52741ae 100644 --- a/himbaechel/uarch/gatemate/pack.cc +++ b/himbaechel/uarch/gatemate/pack.cc @@ -260,6 +260,7 @@ void GateMatePacker::remove_not_used() NetInfo *net = ci.getPort(p.first); if (net && net->users.entries() == 0) { ci.disconnectPort(p.first); + count++; } } } @@ -283,6 +284,61 @@ void GateMatePacker::copy_constraint(NetInfo *in_net, NetInfo *out_net) } } +void GateMatePacker::move_connections(NetInfo *from_net, NetInfo *to_net) +{ + for (const auto &usr : from_net->users) { + IdString port = usr.port; + usr.cell->disconnectPort(port); + usr.cell->connectPort(port, to_net); + } +} + +void GateMatePacker::optimize_lut() +{ + for (auto &cell : ctx->cells) { + CellInfo &ci = *cell.second; + if (!ci.type.in(id_CC_LUT1)) + continue; + uint8_t val = int_or_default(ci.params, id_INIT, 0); + NetInfo *o_net = ci.getPort(id_O); + if (!o_net) { + packed_cells.insert(ci.name); + count++; + continue; + } + switch (val) { + case 0: // constant 0 + move_connections(o_net, gnd_net); + packed_cells.insert(ci.name); + count++; + break; + case 2: // propagate + move_connections(o_net, ci.getPort(id_I0)); + packed_cells.insert(ci.name); + count++; + break; + case 3: // constant 1 + move_connections(o_net, vcc_net); + packed_cells.insert(ci.name); + count++; + break; + default: + break; + } + } + flush_cells(); +} + +void GateMatePacker::cleanup() +{ + log_info("Running cleanups..\n"); + do { + count = 0; + remove_not_used(); + optimize_lut(); + } while (count != 0); +} + void GateMateImpl::pack() { const ArchArgs &args = ctx->args; @@ -292,7 +348,7 @@ void GateMateImpl::pack() GateMatePacker packer(ctx, this); packer.pack_constants(); - packer.remove_not_used(); + packer.cleanup(); packer.pack_io(); packer.insert_pll_bufg(); packer.sort_bufg(); diff --git a/himbaechel/uarch/gatemate/pack.h b/himbaechel/uarch/gatemate/pack.h index 0e870256..4a648312 100644 --- a/himbaechel/uarch/gatemate/pack.h +++ b/himbaechel/uarch/gatemate/pack.h @@ -66,12 +66,17 @@ struct GateMatePacker void remove_clocking(); void remove_not_used(); + void cleanup(); + private: void dff_to_cpe(CellInfo *dff); void insert_bufg(CellInfo *cell, IdString port); void disconnect_if_gnd(CellInfo *cell, IdString input); void pll_out(CellInfo *cell, IdString origPort, Loc fixed); + void optimize_lut(); + void move_connections(NetInfo *from_net, NetInfo *to_net); + PllCfgRecord get_pll_settings(double f_ref, double f_core, int mode, int low_jitter, bool pdiv0_mux, bool feedback); std::pair move_ram_i(CellInfo *cell, IdString origPort, bool place = true, @@ -101,6 +106,9 @@ struct GateMatePacker GateMateImpl *uarch; HimbaechelHelpers h; + NetInfo *vcc_net; + NetInfo *gnd_net; + int count; }; NEXTPNR_NAMESPACE_END diff --git a/himbaechel/uarch/gatemate/pack_cpe.cc b/himbaechel/uarch/gatemate/pack_cpe.cc index bd360f43..bf8f7f8a 100644 --- a/himbaechel/uarch/gatemate/pack_cpe.cc +++ b/himbaechel/uarch/gatemate/pack_cpe.cc @@ -597,6 +597,8 @@ void GateMatePacker::pack_constants() const dict gnd_params = {{id_INIT_L10, Property(0b0000, 4)}}; h.replace_constants(CellTypePort(id_CPE_L2T4, id_OUT), CellTypePort(id_CPE_L2T4, id_OUT), vcc_params, gnd_params); + vcc_net = ctx->nets.at(ctx->id("$PACKER_VCC")).get(); + gnd_net = ctx->nets.at(ctx->id("$PACKER_GND")).get(); } void GateMatePacker::remove_constants()