diff --git a/himbaechel/uarch/gatemate/bitstream.cc b/himbaechel/uarch/gatemate/bitstream.cc index f8560834..813a69ae 100644 --- a/himbaechel/uarch/gatemate/bitstream.cc +++ b/himbaechel/uarch/gatemate/bitstream.cc @@ -65,6 +65,11 @@ struct BitstreamBackend WireId cursor = dst_wire; bool invert = false; + if (net_info->driver.cell && net_info->driver.cell->type == id_CPE_BRIDGE && + net_info->driver.port == id_MUXOUT) { + int val = int_or_default(net_info->driver.cell->params, id_C_SN, 0) + 1; + invert ^= need_inversion(net_info->driver.cell, ctx->idf("IN%d", val)); + } while (cursor != WireId() && cursor != src_wire) { auto it = net_info->wires.find(cursor); @@ -147,8 +152,7 @@ struct BitstreamBackend void export_connection(ChipConfig &cc, PipId pip) { - const auto extra_data = - *reinterpret_cast(chip_pip_info(ctx->chip_info, pip).extra_data.get()); + const auto &extra_data = *uarch->pip_extra_data(pip); if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_VISIBLE)) { IdString name = IdString(extra_data.name); CfgLoc loc = get_config_loc(pip.tile); @@ -293,7 +297,8 @@ struct BitstreamBackend case id_IOSEL.index: for (auto &p : params) { bank[loc.die][ctx->get_bel_package_pin(cell.second.get()->bel)->pad_bank] = 1; - cc.tiles[loc].add_word(stringf("GPIO.%s", p.first.c_str(ctx)), p.second.as_bits()); + cc.tiles[loc].add_word(stringf("GPIO.%s", p.first.c_str(ctx)), p.second.as_bits(), + cell.second->name.c_str(ctx)); } break; case id_CPE_CPLINES.index: @@ -308,6 +313,7 @@ struct BitstreamBackend case id_CPE_LATCH.index: case id_CPE_RAMI.index: case id_CPE_RAMO.index: + case id_CPE_BRIDGE.index: case id_CPE_RAMIO.index: { // Update configuration bits based on signal inversion dict params = cell.second->params; @@ -409,23 +415,27 @@ struct BitstreamBackend } break; } - cc.tiles[loc].add_word(stringf("CPE%d.%s", id, name.c_str(ctx)), p.second.as_bits()); + cc.tiles[loc].add_word(stringf("CPE%d.%s", id, name.c_str(ctx)), p.second.as_bits(), + cell.second->name.c_str(ctx)); } } break; case id_CLKIN.index: { for (auto &p : params) { - cc.configs[loc.die].add_word(stringf("CLKIN.%s", p.first.c_str(ctx)), p.second.as_bits()); + cc.configs[loc.die].add_word(stringf("CLKIN.%s", p.first.c_str(ctx)), p.second.as_bits(), + cell.second->name.c_str(ctx)); } } break; case id_GLBOUT.index: { for (auto &p : params) { - cc.configs[loc.die].add_word(stringf("GLBOUT.%s", p.first.c_str(ctx)), p.second.as_bits()); + cc.configs[loc.die].add_word(stringf("GLBOUT.%s", p.first.c_str(ctx)), p.second.as_bits(), + cell.second->name.c_str(ctx)); } } break; case id_PLL.index: { Loc l = ctx->getBelLocation(cell.second->bel); for (auto &p : params) { - cc.configs[loc.die].add_word(stringf("PLL%d.%s", l.z - 2, p.first.c_str(ctx)), p.second.as_bits()); + cc.configs[loc.die].add_word(stringf("PLL%d.%s", l.z - 2, p.first.c_str(ctx)), p.second.as_bits(), + cell.second->name.c_str(ctx)); } } break; case id_RAM.index: { diff --git a/himbaechel/uarch/gatemate/config.cc b/himbaechel/uarch/gatemate/config.cc index 134a1455..b7c59902 100644 --- a/himbaechel/uarch/gatemate/config.cc +++ b/himbaechel/uarch/gatemate/config.cc @@ -43,12 +43,14 @@ std::ostream &operator<<(std::ostream &out, const ConfigWord &cw) std::ostream &operator<<(std::ostream &out, const TileConfig &tc) { - for (const auto &cword : tc.cwords) + auto sorted = tc.cwords; + std::sort(sorted.begin(), sorted.end(), [](const ConfigWord &a, const ConfigWord &b) { return a.name < b.name; }); + for (const auto &cword : sorted) out << cword; return out; } -void TileConfig::add_word(const std::string &name, const std::vector &value) +void TileConfig::add_word(const std::string &name, const std::vector &value, const char *c) { if (!added.count(name)) { cwords.push_back({name, value}); @@ -56,7 +58,7 @@ void TileConfig::add_word(const std::string &name, const std::vector &valu } else { auto val = added.at(name); if (val != value) - log_error("Trying to add value to already assigned word %s\n", name.c_str()); + log_error("Trying to add value to already assigned word %s for %s\n", name.c_str(), c ? c : ""); } } diff --git a/himbaechel/uarch/gatemate/config.h b/himbaechel/uarch/gatemate/config.h index b9ca9e6e..e6ae3cb4 100644 --- a/himbaechel/uarch/gatemate/config.h +++ b/himbaechel/uarch/gatemate/config.h @@ -39,7 +39,7 @@ struct TileConfig std::vector cwords; std::map> added; - void add_word(const std::string &name, const std::vector &value); + void add_word(const std::string &name, const std::vector &value, const char *c = nullptr); std::string to_string() const; diff --git a/himbaechel/uarch/gatemate/delay.cc b/himbaechel/uarch/gatemate/delay.cc index d87a8a82..6b57f1d8 100644 --- a/himbaechel/uarch/gatemate/delay.cc +++ b/himbaechel/uarch/gatemate/delay.cc @@ -112,6 +112,8 @@ bool GateMateImpl::getCellDelay(const CellInfo *cell, IdString fromPort, IdStrin return false; } else if (cell->type.in(id_CPE_CPLINES)) { return true; + } else if (cell->type.in(id_CPE_BRIDGE)) { + return true; } else if (cell->type.in(id_CPE_COMP)) { return get_delay_from_tmg_db(fromPort == id_COMB1 ? id_timing_comb1_compout : id_timing_comb2_compout, delay); } else if (cell->type.in(id_CPE_RAMI, id_CPE_RAMO, id_CPE_RAMIO)) { @@ -192,6 +194,10 @@ TimingPortClass GateMateImpl::getPortTimingClass(const CellInfo *cell, IdString if (port.in(id_OUT1, id_OUT2, id_COMPOUT, id_CINX, id_PINX, id_CINY1, id_PINY1, id_CINY2, id_PINY2)) return TMG_COMB_INPUT; return TMG_COMB_OUTPUT; + } else if (cell->type.in(id_CPE_BRIDGE)) { + if (port.in(id_MUXOUT)) + return TMG_COMB_OUTPUT; + return TMG_COMB_INPUT; } else if (cell->type.in(id_CPE_FF, id_CPE_FF_L, id_CPE_FF_U, id_CPE_LATCH)) { if (port == id_CLK) return TMG_CLOCK_INPUT; diff --git a/himbaechel/uarch/gatemate/extra_data.h b/himbaechel/uarch/gatemate/extra_data.h index 59aeabcb..108e666b 100644 --- a/himbaechel/uarch/gatemate/extra_data.h +++ b/himbaechel/uarch/gatemate/extra_data.h @@ -74,6 +74,7 @@ enum MuxFlags MUX_INVERT = 1, MUX_VISIBLE = 2, MUX_CONFIG = 4, + MUX_ROUTING = 8, }; enum PipExtra @@ -103,7 +104,7 @@ enum CPE_Z CPE_COMP_Z = 6, CPE_CPLINES_Z = 7, CPE_LT_FULL_Z = 8, - + CPE_BRIDGE_Z = 9, RAM_FULL_Z = 10, RAM_HALF_U_Z = 11, RAM_HALF_L_Z = 12, diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index 9cf39265..9cb86f7b 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -17,6 +17,8 @@ * */ +#include + #include "gatemate.h" #include "log.h" #include "placer_heap.h" @@ -278,6 +280,26 @@ void GateMateImpl::postPlace() { repack(); ctx->assignArchInfo(); + used_cpes.resize(ctx->getGridDimX() * ctx->getGridDimY()); + for (auto &cell : ctx->cells) { + // We need to skip CPE_MULT since using CP outputs is mandatory + // even if output is actually not connected + bool marked_used = cell.second.get()->type == id_CPE_MULT; + // Can not use FF for OUT2 if CPE is used in bridge mode + if (cell.second.get()->type == id_CPE_FF && ctx->getBelLocation(cell.second.get()->bel).z == CPE_FF_U_Z) + marked_used = true; + if (marked_used) + used_cpes[cell.second.get()->bel.tile] = true; + } +} +bool GateMateImpl::checkPipAvail(PipId pip) const +{ + const auto &extra_data = *pip_extra_data(pip); + if (extra_data.type != PipExtra::PIP_EXTRA_MUX || (extra_data.flags & MUX_ROUTING) == 0) + return true; + if (used_cpes[pip.tile]) + return false; + return true; } void GateMateImpl::preRoute() @@ -287,8 +309,120 @@ void GateMateImpl::preRoute() ctx->assignArchInfo(); } +void GateMateImpl::reassign_bridges(NetInfo *ni, const dict &net_wires, WireId wire, + dict &wire_to_net, int &num) +{ + wire_to_net.insert({wire, ni->name}); + + for (auto pip : ctx->getPipsDownhill(wire)) { + auto dst = ctx->getPipDstWire(pip); + + // Ignore wires not part of the net + auto it = net_wires.find(dst); + if (it == net_wires.end()) + continue; + // Ignore pips if the wire is driven by another pip. + if (pip != it->second.pip) + continue; + // Ignore wires already visited. + if (wire_to_net.count(dst)) + continue; + + const auto &extra_data = *pip_extra_data(pip); + // If not a bridge, just recurse. + if (extra_data.type != PipExtra::PIP_EXTRA_MUX || !(extra_data.flags & MUX_ROUTING)) { + reassign_bridges(ni, net_wires, dst, wire_to_net, num); + continue; + } + + // We have a bridge that needs to be translated to a bel. + IdString name = ctx->idf("%s$bridge%d", ni->name.c_str(ctx), num); + + IdStringList id = ctx->getPipName(pip); + Loc loc = ctx->getPipLocation(pip); + BelId bel = ctx->getBelByLocation({loc.x, loc.y, CPE_BRIDGE_Z}); + CellInfo *cell = ctx->createCell(name, id_CPE_BRIDGE); + ctx->bindBel(bel, cell, PlaceStrength::STRENGTH_FIXED); + cell->params[id_C_BR] = Property(Property::State::S1, 1); + cell->params[id_C_SN] = Property(extra_data.value, 3); + + NetInfo *new_net = ctx->createNet(ctx->idf("%s$muxout", name.c_str(ctx))); + IdString in_port = ctx->idf("IN%d", extra_data.value + 1); + + cell->addInput(in_port); + cell->connectPort(in_port, ni); + + cell->addOutput(id_MUXOUT); + cell->connectPort(id_MUXOUT, new_net); + + num++; + + reassign_bridges(new_net, net_wires, dst, wire_to_net, num); + } +} + void GateMateImpl::postRoute() { + int num = 0; + + pool nets_with_bridges; + + for (auto &net : ctx->nets) { + NetInfo *ni = net.second.get(); + for (auto &w : ni->wires) { + if (w.second.pip != PipId()) { + const auto &extra_data = *pip_extra_data(w.second.pip); + if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_ROUTING)) { + this->cpe_bridges.insert({w.second.pip, ni->name}); + nets_with_bridges.insert(ni->name); + } + } + } + } + + for (auto net_name : nets_with_bridges) { + auto *ni = ctx->nets.at(net_name).get(); + auto net_wires = ni->wires; // copy wires to preserve across unbind/rebind. + auto wire_to_net = dict{}; + auto wire_to_port = dict>{}; + + for (auto &usr : ni->users) + for (auto sink_wire : ctx->getNetinfoSinkWires(ni, usr)) { + auto result = wire_to_port.find(sink_wire); + if (result == wire_to_port.end()) + wire_to_port.insert({sink_wire, std::vector{usr}}); + else + result->second.push_back(usr); + } + + // traverse the routing tree to assign bridge nets to wires. + reassign_bridges(ni, net_wires, ctx->getNetinfoSourceWire(ni), wire_to_net, num); + + for (auto &pair : net_wires) + ctx->unbindWire(pair.first); + + for (auto &pair : net_wires) { + auto wire = pair.first; + auto pip = pair.second.pip; + auto strength = pair.second.strength; + auto *net = ctx->nets.at(wire_to_net.at(wire)).get(); + if (pip == PipId()) + ctx->bindWire(wire, net, strength); + else + ctx->bindPip(pip, net, strength); + + if (wire_to_port.count(wire)) { + for (auto sink : wire_to_port.at(wire)) { + NPNR_ASSERT(sink.cell != nullptr && sink.port != IdString()); + sink.cell->disconnectPort(sink.port); + sink.cell->connectPort(sink.port, net); + } + } + } + } + + ctx->assignArchInfo(); + const ArchArgs &args = ctx->args; if (args.options.count("out")) { write_bitstream(args.device, args.options.at("out")); @@ -430,8 +564,7 @@ bool GateMateImpl::isValidBelForCellType(IdString cell_type, BelId bel) const bool GateMateImpl::isPipInverting(PipId pip) const { - const auto &extra_data = - *reinterpret_cast(chip_pip_info(ctx->chip_info, pip).extra_data.get()); + const auto &extra_data = *pip_extra_data(pip); return extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_INVERT); } @@ -440,6 +573,11 @@ const GateMateBelExtraDataPOD *GateMateImpl::bel_extra_data(BelId bel) const return reinterpret_cast(chip_bel_info(ctx->chip_info, bel).extra_data.get()); } +const GateMatePipExtraDataPOD *GateMateImpl::pip_extra_data(PipId pip) const +{ + return reinterpret_cast(chip_pip_info(ctx->chip_info, pip).extra_data.get()); +} + struct GateMateArch : HimbaechelArch { GateMateArch() : HimbaechelArch("gatemate") {}; diff --git a/himbaechel/uarch/gatemate/gatemate.h b/himbaechel/uarch/gatemate/gatemate.h index d7b28753..371cd1f9 100644 --- a/himbaechel/uarch/gatemate/gatemate.h +++ b/himbaechel/uarch/gatemate/gatemate.h @@ -46,6 +46,8 @@ struct GateMateImpl : HimbaechelAPI BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override; void expandBoundingBox(BoundingBox &bb) const override; + bool checkPipAvail(PipId pip) const override; + bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); }; bool isBelLocationValid(BelId bel, bool explain_invalid = false) const override; delay_t estimateDelay(WireId src, WireId dst) const override; @@ -69,6 +71,7 @@ struct GateMateImpl : HimbaechelAPI bool isPipInverting(PipId pip) const override; const GateMateTileExtraDataPOD *tile_extra_data(int tile) const; + const GateMatePipExtraDataPOD *pip_extra_data(PipId pip) const; int get_dff_config(CellInfo *dff) const; int get_ram_config(CellInfo *ram) const; @@ -83,6 +86,8 @@ struct GateMateImpl : HimbaechelAPI pool multiplier_a_passthru_uppers; pool multiplier_zero_drivers; std::vector multipliers; + std::vector used_cpes; + dict cpe_bridges; int fpga_mode; int timing_mode; @@ -97,6 +102,8 @@ struct GateMateImpl : HimbaechelAPI void assign_cell_info(); void route_clock(); void route_mult(); + void reassign_bridges(NetInfo *net, const dict &net_wires, WireId wire, + dict &wire_to_net, int &num); void repack(); const GateMateBelExtraDataPOD *bel_extra_data(BelId bel) const; diff --git a/himbaechel/uarch/gatemate/gen/arch_gen.py b/himbaechel/uarch/gatemate/gen/arch_gen.py index 72c713d3..4acdb41e 100644 --- a/himbaechel/uarch/gatemate/gen/arch_gen.py +++ b/himbaechel/uarch/gatemate/gen/arch_gen.py @@ -30,6 +30,7 @@ PIP_EXTRA_MUX = 1 MUX_INVERT = 1 MUX_VISIBLE = 2 MUX_CONFIG = 4 +MUX_ROUTING = 8 parser = argparse.ArgumentParser() parser.add_argument("--lib", help="Project Peppercorn python database script path", type=str, required=True) @@ -193,7 +194,7 @@ def set_timings(ch): # assert k in timing, f"pip class {k} not found in timing data" # tmg.set_pip_class(grade=speed, name=k, delay=convert_timing(timing[k])) -EXPECTED_VERSION = 1.5 +EXPECTED_VERSION = 1.6 def main(): # Range needs to be +1, but we are adding +2 more to coordinates, since @@ -233,7 +234,7 @@ def main(): tt.create_wire(wire.name, wire.type) for prim in sorted(die.get_primitives_for_type(type_name)): bel = tt.create_bel(prim.name, prim.type, prim.z) - if (prim.name in ["CPE_LT_FULL", "RAM"]): + if (prim.name in ["CPE_LT_FULL", "CPE_BRIDGE", "RAM"]): bel.flags |= BEL_FLAG_HIDDEN extra = BelExtraData() for constr in sorted(die.get_pins_constraint(type_name, prim.name, prim.type)): @@ -256,6 +257,8 @@ def main(): plane = int(mux.name[8:10]) if mux.name.startswith("SB_DRIVE"): plane = int(mux.name[10:12]) + if mux.name == "CPE.C_SN": + mux_flags |= MUX_ROUTING pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(mux.name), mux.bits, mux.value, mux_flags, plane) # Setup tile grid diff --git a/himbaechel/uarch/gatemate/pack_clocking.cc b/himbaechel/uarch/gatemate/pack_clocking.cc index 32394dc0..d0e09f7a 100644 --- a/himbaechel/uarch/gatemate/pack_clocking.cc +++ b/himbaechel/uarch/gatemate/pack_clocking.cc @@ -272,8 +272,7 @@ void GateMatePacker::insert_bufg(CellInfo *cell, IdString port) CellInfo *bufg = create_cell_ptr(id_CC_BUFG, ctx->idf("%s$BUFG_%s", cell->name.c_str(ctx), port.c_str(ctx))); cell->movePortTo(port, bufg, id_O); - cell->ports[port].name = port; - cell->ports[port].type = PORT_OUT; + cell->addOutput(port); NetInfo *net = ctx->createNet(ctx->idf("%s", bufg->name.c_str(ctx))); cell->connectPort(port, net); bufg->connectPort(id_I, net); diff --git a/himbaechel/uarch/gatemate/pack_cpe.cc b/himbaechel/uarch/gatemate/pack_cpe.cc index 2735543f..7ecf0dcc 100644 --- a/himbaechel/uarch/gatemate/pack_cpe.cc +++ b/himbaechel/uarch/gatemate/pack_cpe.cc @@ -207,8 +207,7 @@ void GateMatePacker::pack_cpe() ci.renamePort(id_D1, id_IN1); NetInfo *sel = ci.getPort(id_S0); ci.renamePort(id_S0, id_IN2); - ci.ports[id_IN3].name = id_IN3; - ci.ports[id_IN3].type = PORT_IN; + ci.addInput(id_IN3); ci.connectPort(id_IN3, sel); ci.renamePort(id_D0, id_IN4); ci.disconnectPort(id_D1); @@ -262,8 +261,7 @@ void GateMatePacker::pack_cpe() // Reconnect net NetInfo *ci_out_conn = ctx->createNet(ctx->idf("%s$out", ci.name.c_str(ctx))); ci.connectPort(id_OUT, ci_out_conn); - lower->ports[id_COMBIN].name = id_COMBIN; - lower->ports[id_COMBIN].type = PORT_IN; + lower->addInput(id_COMBIN); lower->connectPort(id_COMBIN, ci_out_conn); dff->disconnectPort(id_DIN); dff->connectPort(id_DIN, ci_out_conn); @@ -291,8 +289,7 @@ void GateMatePacker::pack_cpe() NetInfo *ci_out_conn = ctx->createNet(ctx->idf("%s$combin", ci->name.c_str(ctx))); upper->connectPort(id_OUT, ci_out_conn); - ci->ports[id_COMBIN].name = id_COMBIN; - ci->ports[id_COMBIN].type = PORT_IN; + ci->addInput(id_COMBIN); ci->connectPort(id_COMBIN, ci_out_conn); } l2t5_list.clear(); @@ -388,8 +385,7 @@ void GateMatePacker::pack_cpe() ci.type = (ci.type == id_CC_DLT) ? id_CPE_LATCH : id_CPE_FF; NetInfo *conn = ctx->createNet(ctx->idf("%s$di", ci.name.c_str(ctx))); lt->connectPort(id_OUT, conn); - ci.ports[id_DIN].name = id_DIN; - ci.ports[id_DIN].type = PORT_IN; + ci.addInput(id_DIN); ci.connectPort(id_DIN, conn); } dff_list.clear(); @@ -577,8 +573,7 @@ void GateMatePacker::pack_addf() NetInfo *ci_conn = ctx->createNet(ctx->idf("%s$ci_net", root->name.c_str(ctx))); ci_cplines->connectPort(id_COUTY1, ci_conn); - root->ports[id_CINY1].name = id_CINY1; - root->ports[id_CINY1].type = PORT_IN; + root->addInput(id_CINY1); root->connectPort(id_CINY1, ci_conn); for (size_t i = 0; i < grp.size(); i++) { @@ -646,8 +641,7 @@ void GateMatePacker::pack_addf() NetInfo *co_conn = ctx->createNet(ctx->idf("%s$co_net", cy->name.c_str(ctx))); co_lower->connectPort(id_CINY1, co_conn); - cy->ports[id_COUTY1].name = id_COUTY1; - cy->ports[id_COUTY1].type = PORT_OUT; + cy->addOutput(id_COUTY1); cy->connectPort(id_COUTY1, co_conn); cy->movePortTo(id_CO, co_lower, id_OUT); @@ -660,8 +654,7 @@ void GateMatePacker::pack_addf() if (usr.cell->type == id_CC_ADDF || usr.port == id_CI) { usr.cell->disconnectPort(id_CI); NetInfo *co_conn = ctx->createNet(ctx->idf("%s$co_net", cy->name.c_str(ctx))); - cy->ports[id_COUTY1].name = id_COUTY1; - cy->ports[id_COUTY1].type = PORT_OUT; + cy->addOutput(id_COUTY1); cy->connectPort(id_COUTY1, co_conn); usr.cell->connectPort(id_CI, co_conn); break; diff --git a/himbaechel/uarch/gatemate/pack_io.cc b/himbaechel/uarch/gatemate/pack_io.cc index e6300c7e..3a12e0d8 100644 --- a/himbaechel/uarch/gatemate/pack_io.cc +++ b/himbaechel/uarch/gatemate/pack_io.cc @@ -518,8 +518,7 @@ void GateMatePacker::pack_io_sel() if (cpe_half) { if (cpe_half->getPort(id_IN1) != oddr->getPort(id_DDR)) log_error("DDR port use signal different than already occupied DDR source.\n"); - ci.ports[id_DDR].name = id_DDR; - ci.ports[id_DDR].type = PORT_IN; + ci.addInput(id_DDR); ci.connectPort(id_DDR, cpe_ramio->getPort(id_RAM_O)); } else { auto l = reinterpret_cast(pad->extra_data.get()); diff --git a/himbaechel/uarch/gatemate/pack_mult.cc b/himbaechel/uarch/gatemate/pack_mult.cc index 7da4b028..2ec849a3 100644 --- a/himbaechel/uarch/gatemate/pack_mult.cc +++ b/himbaechel/uarch/gatemate/pack_mult.cc @@ -430,8 +430,7 @@ void GateMatePacker::pack_mult() NetInfo *comb2_conn = ctx->createNet(ctx->idf("%s$carrycomb2", name.c_str(ctx))); carry_upper->connectPort(id_OUT, comb2_conn); - carry_lower->ports[id_COMBIN].name = id_COMBIN; - carry_lower->ports[id_COMBIN].type = PORT_IN; + carry_lower->addInput(id_COMBIN); carry_lower->connectPort(id_COMBIN, comb2_conn); NetInfo *comp_in = ctx->createNet(ctx->idf("%s$carry$comp_in", name.c_str(ctx))); @@ -461,8 +460,7 @@ void GateMatePacker::pack_mult() NetInfo *comb2_conn = ctx->createNet(ctx->idf("%s$multf%c$comb2", name.c_str(ctx), is_even_x ? 'a' : 'b')); multfab_upper->connectPort(id_OUT, comb2_conn); - multfab_lower->ports[id_COMBIN].name = id_COMBIN; - multfab_lower->ports[id_COMBIN].type = PORT_IN; + multfab_lower->addInput(id_COMBIN); multfab_lower->connectPort(id_COMBIN, comb2_conn); multfab_comp->connectPort(id_COMB2, comb2_conn); diff --git a/himbaechel/uarch/gatemate/route_clock.cc b/himbaechel/uarch/gatemate/route_clock.cc index db70e86e..12ec6ce3 100644 --- a/himbaechel/uarch/gatemate/route_clock.cc +++ b/himbaechel/uarch/gatemate/route_clock.cc @@ -57,8 +57,7 @@ void GateMateImpl::route_clock() }; auto pip_plane = [&](PipId pip) { - const auto &extra_data = - *reinterpret_cast(chip_pip_info(ctx->chip_info, pip).extra_data.get()); + const auto &extra_data = *pip_extra_data(pip); if (extra_data.type != PipExtra::PIP_EXTRA_MUX) return uint8_t{0}; return extra_data.plane;