diff options
-rw-r--r-- | common/design_utils.cc | 24 | ||||
-rw-r--r-- | common/design_utils.h | 10 | ||||
-rw-r--r-- | nexus/constids.inc | 77 | ||||
-rw-r--r-- | nexus/pack.cc | 48 |
4 files changed, 135 insertions, 24 deletions
diff --git a/common/design_utils.cc b/common/design_utils.cc index 7f339bac..5227585f 100644 --- a/common/design_utils.cc +++ b/common/design_utils.cc @@ -164,25 +164,13 @@ void rename_net(Context *ctx, NetInfo *net, IdString new_name) net->name = new_name; } -std::vector<NetInfo *> create_bus(Context *ctx, IdString base_name, const std::string &postfix, int width) +void replace_bus(Context *ctx, CellInfo *old_cell, IdString old_name, int old_offset, CellInfo *new_cell, + IdString new_name, int new_offset, int width, bool square_brackets) { - std::vector<NetInfo *> nets; - for (int i = 0; i < width; i++) - nets.push_back(ctx->createNet(ctx->id(stringf("%s/%s[%d]", base_name.c_str(ctx), postfix.c_str(), i)))); - return nets; -} - -void connect_bus(Context *ctx, CellInfo *cell, IdString port, std::vector<NetInfo *> &bus, PortType dir) -{ - for (int i = 0; i < int(bus.size()); i++) { - IdString p = ctx->id(stringf("%s%d", port.c_str(ctx), i)); - if (!cell->ports.count(p)) { - cell->ports[p].name = p; - cell->ports[p].type = dir; - } else { - NPNR_ASSERT(cell->ports.at(p).type == dir); - } - connect_port(ctx, bus.at(i), cell, p); + for (int i = 0; i < width; i++) { + IdString old_port = ctx->id(stringf(square_brackets ? "%s[%d]" : "%s%d", old_name.c_str(ctx), i + old_offset)); + IdString new_port = ctx->id(stringf(square_brackets ? "%s[%d]" : "%s%d", new_name.c_str(ctx), i + new_offset)); + replace_port(old_cell, old_port, new_cell, new_port); } } diff --git a/common/design_utils.h b/common/design_utils.h index 3a2245a7..2014e7ad 100644 --- a/common/design_utils.h +++ b/common/design_utils.h @@ -104,14 +104,12 @@ void rename_port(Context *ctx, CellInfo *cell, IdString old_name, IdString new_n // Rename a net without invalidating pointers to it void rename_net(Context *ctx, NetInfo *net, IdString new_name); -// Create a bus of nets -std::vector<NetInfo *> create_bus(Context *ctx, IdString base_name, const std::string &postfix, int width); - -// Connect a bus of nets to a bus of ports -void connect_bus(Context *ctx, CellInfo *cell, IdString port, std::vector<NetInfo *> &bus, PortType dir); - void print_utilisation(const Context *ctx); +// Disconnect a bus of nets (if connected) from old, and connect it to the new ports +void replace_bus(Context *ctx, CellInfo *old_cell, IdString old_name, int old_offset, CellInfo *new_cell, + IdString new_name, int new_offset, int new_width, bool square_brackets = true); + NEXTPNR_NAMESPACE_END #endif diff --git a/nexus/constids.inc b/nexus/constids.inc index a43104e2..a996f0f8 100644 --- a/nexus/constids.inc +++ b/nexus/constids.inc @@ -165,6 +165,16 @@ X(MULT18X36_CORE) X(MULT36_CORE) X(ACC54_CORE) +X(PREADD9) +X(MULT9) +X(MULT18) +X(REG18) +X(M18X36) +X(MULT36) +X(ACC54) + +X(MULT9X9) + X(DCC) X(CLKI) X(CLKO) @@ -215,3 +225,70 @@ X(DWS4) X(WEAMUX) X(VCC_DRV) + +X(RSTCL) +X(CECL) +X(B2) +X(B3) +X(B4) +X(B5) +X(B6) +X(B7) +X(B8) +X(BSIGNED) +X(C2) +X(C3) +X(C4) +X(C5) +X(C6) +X(C7) +X(C8) +X(C9) + +X(RSTP) +X(CEP) +X(A2) +X(A3) +X(A4) +X(A5) +X(A6) +X(A7) +X(A8) +X(ASIGNED) + +X(SFTCTRL0) +X(SFTCTRL1) +X(SFTCTRL2) +X(SFTCTRL3) +X(ROUNDEN) + +X(LOAD) +X(M9ADDSUB1) +X(M9ADDSUB0) +X(ADDSUB1) +X(ADDSUB0) + +X(CEO) +X(RSTO) +X(CEC) +X(RSTC) +X(SIGNEDI) +X(CECIN) +X(CECTRL) +X(RSTCIN) +X(RSTCTRL) + +X(SIGNEDSTATIC_EN) +X(SUBSTRACT_EN) +X(CSIGNED) +X(BSIGNED_OPERAND_EN) +X(BYPASS_PREADD9) +X(REGBYPSBR0) +X(REGBYPSBR1) +X(REGBYPSBL) +X(SHIFTBR) +X(SHIFTBL) +X(PREADDCAS_EN) +X(SR_18BITSHIFT_EN) +X(OPC) +X(RESET) diff --git a/nexus/pack.cc b/nexus/pack.cc index 50278d48..d39a1c89 100644 --- a/nexus/pack.cc +++ b/nexus/pack.cc @@ -1351,6 +1351,54 @@ struct NexusPacker auto_cascade_cell(child, cell2bel.at(child->name), bel2cell); } + // Create a DSP cell + CellInfo *create_dsp_cell(IdString base_name, IdString type, CellInfo *constr_base, int dx, int dz) + { + IdString name = ctx->id(stringf("%s/%s_x%d_z%d", ctx->nameOf(base_name), ctx->nameOf(type), dx, dz)); + CellInfo *cell = ctx->createCell(name, type); + if (constr_base != nullptr) { + // We might be constraining against an already-constrained cell + if (constr_base->constr_parent != nullptr) { + cell->constr_x = dx + constr_base->constr_x; + cell->constr_y = constr_base->constr_y; + cell->constr_z = dz + constr_base->constr_z; + cell->constr_abs_z = false; + cell->constr_parent = constr_base->constr_parent; + constr_base->constr_parent->constr_children.push_back(cell); + } else { + cell->constr_x = dx; + cell->constr_y = 0; + cell->constr_z = dz; + cell->constr_abs_z = false; + cell->constr_parent = constr_base; + constr_base->constr_children.push_back(cell); + } + } + // Setup some default parameters + if (type == id_PREADD9_CORE) { + cell->params[id_SIGNEDSTATIC_EN] = std::string("DISABLED"); + cell->params[id_BYPASS_PREADD9] = std::string("BYPASS"); + cell->params[id_CSIGNED] = std::string("DISABLED"); + cell->params[id_GSR] = std::string("DISABLED"); + cell->params[id_OPC] = std::string("INPUT_B_AS_PREADDER_OPERAND"); + cell->params[id_PREADDCAS_EN] = std::string("DISABLED"); + cell->params[id_PREADDCAS_EN] = std::string("DISABLED"); + cell->params[id_PREADDCAS_EN] = std::string("DISABLED"); + cell->params[id_REGBYPSBL] = std::string("REGISTER"); + cell->params[id_REGBYPSBR0] = std::string("BYPASS"); + cell->params[id_REGBYPSBR1] = std::string("BYPASS"); + cell->params[id_RESET] = std::string("SYNC"); + cell->params[id_SHIFTBL] = std::string("BYPASS"); + cell->params[id_SHIFTBR] = std::string("REGISTER"); + cell->params[id_SIGNEDSTATIC_EN] = std::string("DISABLED"); + cell->params[id_SR_18BITSHIFT_EN] = std::string("DISABLED"); + cell->params[id_SUBSTRACT_EN] = std::string("SUBTRACTION"); + } + return cell; + } + + void pack_dsps() { log_info("Packing DSPs...\n"); } + explicit NexusPacker(Context *ctx) : ctx(ctx) {} void operator()() |