aboutsummaryrefslogtreecommitdiffstats
path: root/gowin/pack.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gowin/pack.cc')
-rw-r--r--gowin/pack.cc132
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;