diff options
Diffstat (limited to 'gowin/pack.cc')
-rw-r--r-- | gowin/pack.cc | 132 |
1 files changed, 65 insertions, 67 deletions
diff --git a/gowin/pack.cc b/gowin/pack.cc index 553eeb4e..268f26ef 100644 --- a/gowin/pack.cc +++ b/gowin/pack.cc @@ -96,7 +96,7 @@ static void pack_alus(Context *ctx) log_info("packed ALU head into %s. CIN net is %s\n", ctx->nameOf(packed_head.get()), ctx->nameOf(cin_netId)); } - connect_port(ctx, ctx->nets[ctx->id("$PACKER_VCC_NET")].get(), packed_head.get(), id_C); + packed_head->connectPort(id_C, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); if (cin_netId == ctx->id("$PACKER_GND_NET")) { // CIN = 0 packed_head->params[id_ALU_MODE] = std::string("C2L"); @@ -106,15 +106,15 @@ static void pack_alus(Context *ctx) packed_head->params[id_ALU_MODE] = std::string("ONE2C"); } else { // CIN from logic - connect_port(ctx, ctx->nets[cin_netId].get(), packed_head.get(), id_B); - connect_port(ctx, ctx->nets[cin_netId].get(), packed_head.get(), id_D); + packed_head->connectPort(id_B, ctx->nets[cin_netId].get()); + packed_head->connectPort(id_D, ctx->nets[cin_netId].get()); packed_head->params[id_ALU_MODE] = std::string("0"); // ADD } } int alu_idx = 1; do { // go through the ALU chain - auto alu_bel = ci->attrs.find(ctx->id("BEL")); + auto alu_bel = ci->attrs.find(id_BEL); if (alu_bel != ci->attrs.end()) { log_error("ALU %s placement restrictions are not supported.\n", ctx->nameOf(ci)); return; @@ -123,9 +123,9 @@ static void pack_alus(Context *ctx) packed_cells.insert(ci->name); // CIN/COUT are hardwired, delete - disconnect_port(ctx, ci, id_CIN); + ci->disconnectPort(id_CIN); NetInfo *cout = ci->ports.at(id_COUT).net; - disconnect_port(ctx, ci, id_COUT); + ci->disconnectPort(id_COUT); std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_ALULC"); if (ctx->verbose) { @@ -135,9 +135,9 @@ static void pack_alus(Context *ctx) int mode = int_or_default(ci->params, id_ALU_MODE); packed->params[id_ALU_MODE] = mode; if (mode == 9) { // MULT - connect_port(ctx, ctx->nets[ctx->id("$PACKER_GND_NET")].get(), packed.get(), id_C); + packed->connectPort(id_C, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); } else { - connect_port(ctx, ctx->nets[ctx->id("$PACKER_VCC_NET")].get(), packed.get(), id_C); + packed->connectPort(id_C, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); } // add to cluster @@ -149,30 +149,30 @@ static void pack_alus(Context *ctx) ++alu_idx; // connect all remainig ports - replace_port(ci, id_SUM, packed.get(), id_F); + ci->movePortTo(id_SUM, packed.get(), id_F); switch (mode) { case 0: // ADD - replace_port(ci, id_I0, packed.get(), id_B); - replace_port(ci, id_I1, packed.get(), id_D); + ci->movePortTo(id_I0, packed.get(), id_B); + ci->movePortTo(id_I1, packed.get(), id_D); break; case 1: // SUB - replace_port(ci, id_I0, packed.get(), id_A); - replace_port(ci, id_I1, packed.get(), id_D); + ci->movePortTo(id_I0, packed.get(), id_A); + ci->movePortTo(id_I1, packed.get(), id_D); break; case 5: // LE - replace_port(ci, id_I0, packed.get(), id_A); - replace_port(ci, id_I1, packed.get(), id_B); + ci->movePortTo(id_I0, packed.get(), id_A); + ci->movePortTo(id_I1, packed.get(), id_B); break; case 9: // MULT - replace_port(ci, id_I0, packed.get(), id_A); - replace_port(ci, id_I1, packed.get(), id_B); - disconnect_port(ctx, packed.get(), id_D); - connect_port(ctx, ctx->nets[ctx->id("$PACKER_VCC_NET")].get(), packed.get(), id_D); + ci->movePortTo(id_I0, packed.get(), id_A); + ci->movePortTo(id_I1, packed.get(), id_B); + packed->disconnectPort(id_D); + packed->connectPort(id_D, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); break; default: - replace_port(ci, id_I0, packed.get(), id_A); - replace_port(ci, id_I1, packed.get(), id_B); - replace_port(ci, id_I3, packed.get(), id_D); + ci->movePortTo(id_I0, packed.get(), id_A); + ci->movePortTo(id_I1, packed.get(), id_B); + ci->movePortTo(id_I3, packed.get(), id_D); } new_cells.push_back(std::move(packed)); @@ -191,7 +191,7 @@ static void pack_alus(Context *ctx) ctx->nameOf(cout)); } packed_tail->params[id_ALU_MODE] = std::string("C2L"); - connect_port(ctx, cout, packed_tail.get(), id_F); + packed_tail->connectPort(id_F, cout); // add to cluster packed_tail->cluster = packed_head->name; packed_tail->constr_z = alu_idx % 6; @@ -243,7 +243,7 @@ static void pack_mux2_lut5(Context *ctx, CellInfo *ci, pool<IdString> &packed_ce std::vector<std::unique_ptr<CellInfo>> &new_cells) { - if (bool_or_default(ci->attrs, ctx->id("SINGLE_INPUT_MUX"))) { + if (bool_or_default(ci->attrs, id_SINGLE_INPUT_MUX)) { // find the muxed LUT NetInfo *i1 = ci->ports.at(id_I1).net; @@ -257,14 +257,14 @@ static void pack_mux2_lut5(Context *ctx, CellInfo *ci, pool<IdString> &packed_ce } // XXX enable the placement constraints - auto mux_bel = ci->attrs.find(ctx->id("BEL")); - auto lut1_bel = lut1->attrs.find(ctx->id("BEL")); + auto mux_bel = ci->attrs.find(id_BEL); + auto lut1_bel = lut1->attrs.find(id_BEL); if (lut1_bel != lut1->attrs.end() || mux_bel != ci->attrs.end()) { log_error("MUX2_LUT5 '%s' placement restrictions are not supported yet\n", ctx->nameOf(ci)); return; } - std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, ctx->id("GW_MUX2_LUT5"), ci->name.str(ctx) + "_LC"); + std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, id_GW_MUX2_LUT5, ci->name.str(ctx) + "_LC"); if (ctx->verbose) { log_info("packed cell %s into %s\n", ctx->nameOf(ci), ctx->nameOf(packed.get())); } @@ -275,8 +275,8 @@ static void pack_mux2_lut5(Context *ctx, CellInfo *ci, pool<IdString> &packed_ce packed->constr_children.clear(); // reconnect MUX ports - replace_port(ci, id_O, packed.get(), id_OF); - replace_port(ci, id_I1, packed.get(), id_I1); + ci->movePortTo(id_O, packed.get(), id_OF); + ci->movePortTo(id_I1, packed.get(), id_I1); // remove cells packed_cells.insert(ci->name); @@ -299,15 +299,15 @@ static void pack_mux2_lut5(Context *ctx, CellInfo *ci, pool<IdString> &packed_ce } // XXX enable the placement constraints - auto mux_bel = ci->attrs.find(ctx->id("BEL")); - auto lut0_bel = lut0->attrs.find(ctx->id("BEL")); - auto lut1_bel = lut1->attrs.find(ctx->id("BEL")); + auto mux_bel = ci->attrs.find(id_BEL); + auto lut0_bel = lut0->attrs.find(id_BEL); + auto lut1_bel = lut1->attrs.find(id_BEL); if (lut0_bel != lut0->attrs.end() || lut1_bel != lut1->attrs.end() || mux_bel != ci->attrs.end()) { log_error("MUX2_LUT5 '%s' placement restrictions are not supported yet\n", ctx->nameOf(ci)); return; } - std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, ctx->id("GW_MUX2_LUT5"), ci->name.str(ctx) + "_LC"); + std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, id_GW_MUX2_LUT5, ci->name.str(ctx) + "_LC"); if (ctx->verbose) { log_info("packed cell %s into %s\n", ctx->nameOf(ci), ctx->nameOf(packed.get())); } @@ -320,10 +320,10 @@ static void pack_mux2_lut5(Context *ctx, CellInfo *ci, pool<IdString> &packed_ce packed->constr_children.clear(); // reconnect MUX ports - replace_port(ci, id_O, packed.get(), id_OF); - replace_port(ci, id_S0, packed.get(), id_SEL); - replace_port(ci, id_I0, packed.get(), id_I0); - replace_port(ci, id_I1, packed.get(), id_I1); + ci->movePortTo(id_O, packed.get(), id_OF); + ci->movePortTo(id_S0, packed.get(), id_SEL); + ci->movePortTo(id_I0, packed.get(), id_I0); + ci->movePortTo(id_I1, packed.get(), id_I1); // remove cells packed_cells.insert(ci->name); @@ -354,9 +354,9 @@ static void pack_mux2_lut(Context *ctx, CellInfo *ci, bool (*pred)(const BaseCtx } // XXX enable the placement constraints - auto mux_bel = ci->attrs.find(ctx->id("BEL")); - auto mux0_bel = mux0->attrs.find(ctx->id("BEL")); - auto mux1_bel = mux1->attrs.find(ctx->id("BEL")); + auto mux_bel = ci->attrs.find(id_BEL); + auto mux0_bel = mux0->attrs.find(id_BEL); + auto mux1_bel = mux1->attrs.find(id_BEL); if (mux0_bel != mux0->attrs.end() || mux1_bel != mux1->attrs.end() || mux_bel != ci->attrs.end()) { log_error("MUX2_LUT%c '%s' placement restrictions are not supported yet\n", type_suffix, ctx->nameOf(ci)); return; @@ -394,10 +394,10 @@ static void pack_mux2_lut(Context *ctx, CellInfo *ci, bool (*pred)(const BaseCtx packed->constr_children.push_back(mux1); // reconnect MUX ports - replace_port(ci, id_O, packed.get(), id_OF); - replace_port(ci, id_S0, packed.get(), id_SEL); - replace_port(ci, id_I0, packed.get(), id_I0); - replace_port(ci, id_I1, packed.get(), id_I1); + ci->movePortTo(id_O, packed.get(), id_OF); + ci->movePortTo(id_S0, packed.get(), id_SEL); + ci->movePortTo(id_I0, packed.get(), id_I0); + ci->movePortTo(id_I1, packed.get(), id_I1); // remove cells packed_cells.insert(ci->name); @@ -512,7 +512,7 @@ static void pack_lut_lutffs(Context *ctx) if (ctx->verbose) log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); if (is_lut(ctx, ci)) { - std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, ctx->id("SLICE"), ci->name.str(ctx) + "_LC"); + std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_LC"); for (auto &attr : ci->attrs) packed->attrs[attr.first] = attr.second; packed_cells.insert(ci->name); @@ -520,14 +520,14 @@ static void pack_lut_lutffs(Context *ctx) log_info("packed cell %s into %s\n", ctx->nameOf(ci), ctx->nameOf(packed.get())); // See if we can pack into a DFF // TODO: LUT cascade - NetInfo *o = ci->ports.at(ctx->id("F")).net; - CellInfo *dff = net_only_drives(ctx, o, is_ff, ctx->id("D"), true); - auto lut_bel = ci->attrs.find(ctx->id("BEL")); + NetInfo *o = ci->ports.at(id_F).net; + CellInfo *dff = net_only_drives(ctx, o, is_ff, id_D, true); + auto lut_bel = ci->attrs.find(id_BEL); bool packed_dff = false; if (dff) { if (ctx->verbose) log_info("found attached dff %s\n", ctx->nameOf(dff)); - auto dff_bel = dff->attrs.find(ctx->id("BEL")); + auto dff_bel = dff->attrs.find(id_BEL); if (lut_bel != ci->attrs.end() && dff_bel != dff->attrs.end() && lut_bel->second != dff_bel->second) { // Locations don't match, can't pack } else { @@ -535,7 +535,7 @@ static void pack_lut_lutffs(Context *ctx) dff_to_lc(ctx, dff, packed.get(), false); ctx->nets.erase(o->name); if (dff_bel != dff->attrs.end()) - packed->attrs[ctx->id("BEL")] = dff_bel->second; + packed->attrs[id_BEL] = dff_bel->second; packed_cells.insert(dff->name); if (ctx->verbose) log_info("packed cell %s into %s\n", ctx->nameOf(dff), ctx->nameOf(packed.get())); @@ -567,7 +567,7 @@ static void pack_nonlut_ffs(Context *ctx) for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); if (is_ff(ctx, ci)) { - std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, ctx->id("SLICE"), ci->name.str(ctx) + "_DFFLC"); + std::unique_ptr<CellInfo> packed = create_generic_cell(ctx, id_SLICE, ci->name.str(ctx) + "_DFFLC"); for (auto &attr : ci->attrs) packed->attrs[attr.first] = attr.second; if (ctx->verbose) @@ -610,22 +610,20 @@ static void pack_constants(Context *ctx) { log_info("Packing constants..\n"); - std::unique_ptr<CellInfo> gnd_cell = create_generic_cell(ctx, ctx->id("SLICE"), "$PACKER_GND"); - gnd_cell->params[ctx->id("INIT")] = Property(0, 1 << 4); - std::unique_ptr<NetInfo> gnd_net = std::unique_ptr<NetInfo>(new NetInfo); - gnd_net->name = ctx->id("$PACKER_GND_NET"); + std::unique_ptr<CellInfo> gnd_cell = create_generic_cell(ctx, id_SLICE, "$PACKER_GND"); + gnd_cell->params[id_INIT] = Property(0, 1 << 4); + auto gnd_net = std::make_unique<NetInfo>(ctx->id("$PACKER_GND_NET")); gnd_net->driver.cell = gnd_cell.get(); - gnd_net->driver.port = ctx->id("F"); - gnd_cell->ports.at(ctx->id("F")).net = gnd_net.get(); + gnd_net->driver.port = id_F; + gnd_cell->ports.at(id_F).net = gnd_net.get(); - std::unique_ptr<CellInfo> vcc_cell = create_generic_cell(ctx, ctx->id("SLICE"), "$PACKER_VCC"); + std::unique_ptr<CellInfo> vcc_cell = create_generic_cell(ctx, id_SLICE, "$PACKER_VCC"); // Fill with 1s - vcc_cell->params[ctx->id("INIT")] = Property(Property::S1).extract(0, (1 << 4), Property::S1); - std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo); - vcc_net->name = ctx->id("$PACKER_VCC_NET"); + vcc_cell->params[id_INIT] = Property(Property::S1).extract(0, (1 << 4), Property::S1); + auto vcc_net = std::make_unique<NetInfo>(ctx->id("$PACKER_VCC_NET")); vcc_net->driver.cell = vcc_cell.get(); - vcc_net->driver.port = ctx->id("F"); - vcc_cell->ports.at(ctx->id("F")).net = vcc_net.get(); + vcc_net->driver.port = id_F; + vcc_cell->ports.at(id_F).net = vcc_net.get(); std::vector<IdString> dead_nets; @@ -633,13 +631,13 @@ static void pack_constants(Context *ctx) for (auto &net : ctx->nets) { NetInfo *ni = net.second.get(); - if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("GND")) { + if (ni->driver.cell != nullptr && ni->driver.cell->type == id_GND) { IdString drv_cell = ni->driver.cell->name; set_net_constant(ctx, ni, gnd_net.get(), false); gnd_used = true; dead_nets.push_back(net.first); ctx->cells.erase(drv_cell); - } else if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("VCC")) { + } else if (ni->driver.cell != nullptr && ni->driver.cell->type == id_VCC) { IdString drv_cell = ni->driver.cell->name; set_net_constant(ctx, ni, vcc_net.get(), true); dead_nets.push_back(net.first); @@ -713,7 +711,7 @@ static void pack_io(Context *ctx) // delete the $nexpnr_[io]buf for (auto &p : iob->ports) { IdString netname = p.second.net->name; - disconnect_port(ctx, iob, p.first); + iob->disconnectPort(p.first); delete_nets.insert(netname); } packed_cells.insert(iob->name); @@ -782,7 +780,7 @@ bool Arch::pack() pack_alus(ctx); pack_lut_lutffs(ctx); pack_nonlut_ffs(ctx); - ctx->settings[ctx->id("pack")] = 1; + ctx->settings[id_pack] = 1; ctx->assignArchInfo(); log_info("Checksum: 0x%08x\n", ctx->checksum()); return true; |