diff options
-rw-r--r-- | 3rdparty/QtPropertyBrowser/src/qtbuttonpropertybrowser.cpp | 6 | ||||
-rw-r--r-- | 3rdparty/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp | 6 | ||||
-rw-r--r-- | 3rdparty/QtPropertyBrowser/src/qtpropertybrowser.cpp | 4 | ||||
-rw-r--r-- | common/log.cc | 2 | ||||
-rw-r--r-- | common/place_sa.cc | 37 | ||||
-rw-r--r-- | common/place_sa.h | 2 | ||||
-rw-r--r-- | gui/pythontab.cc | 2 | ||||
-rw-r--r-- | ice40/arch.cc | 10 | ||||
-rw-r--r-- | ice40/arch.h | 4 | ||||
-rw-r--r-- | ice40/arch_place.cc | 13 | ||||
-rw-r--r-- | ice40/arch_place.h | 2 | ||||
-rw-r--r-- | ice40/bitstream.cc | 56 | ||||
-rw-r--r-- | ice40/cells.cc | 50 | ||||
-rw-r--r-- | ice40/cells.h | 3 | ||||
-rw-r--r-- | ice40/main.cc | 7 | ||||
-rw-r--r-- | ice40/pack.cc | 75 | ||||
-rw-r--r-- | ice40/pcf.cc | 8 |
17 files changed, 158 insertions, 129 deletions
diff --git a/3rdparty/QtPropertyBrowser/src/qtbuttonpropertybrowser.cpp b/3rdparty/QtPropertyBrowser/src/qtbuttonpropertybrowser.cpp index 58cfc510..c39c8667 100644 --- a/3rdparty/QtPropertyBrowser/src/qtbuttonpropertybrowser.cpp +++ b/3rdparty/QtPropertyBrowser/src/qtbuttonpropertybrowser.cpp @@ -277,14 +277,14 @@ void QtButtonPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBr if (!parentItem->container) { m_recreateQueue.removeAll(parentItem); WidgetItem *grandParent = parentItem->parent; - QWidget *w = 0; + //QWidget *w = 0; QGridLayout *l = 0; const int oldRow = gridRow(parentItem); if (grandParent) { - w = grandParent->container; + //w = grandParent->container; l = grandParent->layout; } else { - w = q_ptr; + //w = q_ptr; l = m_mainLayout; } QFrame *container = new QFrame(); diff --git a/3rdparty/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp b/3rdparty/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp index caf074db..9979b3c0 100644 --- a/3rdparty/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp +++ b/3rdparty/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp @@ -312,15 +312,15 @@ void QtGroupBoxPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) removeRow(parentItem->layout, row); } else { WidgetItem *par = parentItem->parent; - QWidget *w = 0; + //QWidget *w = 0; QGridLayout *l = 0; int oldRow = -1; if (!par) { - w = q_ptr; + //w = q_ptr; l = m_mainLayout; oldRow = m_children.indexOf(parentItem); } else { - w = par->groupBox; + //w = par->groupBox; l = par->layout; oldRow = par->children.indexOf(parentItem); if (hasHeader(par)) diff --git a/3rdparty/QtPropertyBrowser/src/qtpropertybrowser.cpp b/3rdparty/QtPropertyBrowser/src/qtpropertybrowser.cpp index 2449fcb8..63260fe4 100644 --- a/3rdparty/QtPropertyBrowser/src/qtpropertybrowser.cpp +++ b/3rdparty/QtPropertyBrowser/src/qtpropertybrowser.cpp @@ -1874,14 +1874,14 @@ QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property, QList<QtProperty *> pendingList = properties(); int pos = 0; int newPos = 0; - QtProperty *properAfterProperty = 0; + //QtProperty *properAfterProperty = 0; while (pos < pendingList.count()) { QtProperty *prop = pendingList.at(pos); if (prop == property) return 0; if (prop == afterProperty) { newPos = pos + 1; - properAfterProperty = afterProperty; + //properAfterProperty = afterProperty; } pos++; } diff --git a/common/log.cc b/common/log.cc index 73c764a4..02c6fe9a 100644 --- a/common/log.cc +++ b/common/log.cc @@ -42,7 +42,7 @@ int log_verbose_level; std::string log_last_error; void (*log_error_atexit)() = NULL; -static bool next_print_log = false; +//static bool next_print_log = false; static int log_newline_count = 0; std::string vstringf(const char *fmt, va_list ap) diff --git a/common/place_sa.cc b/common/place_sa.cc index 7a876256..6743e0ce 100644 --- a/common/place_sa.cc +++ b/common/place_sa.cc @@ -46,7 +46,7 @@ typedef int64_t wirelen_t; class SAPlacer { public: - SAPlacer(Context *ctx) : ctx(ctx) + SAPlacer(Context *ctx, bool timing_driven) : ctx(ctx), timing_driven(timing_driven) { checker = new PlaceValidityChecker(ctx); int num_bel_types = 0; @@ -334,15 +334,17 @@ class SAPlacer CellInfo *load_cell = load.cell; if (load_cell->bel == BelId()) continue; + if (timing_driven) { + WireId user_wire = ctx->getWireBelPin( + load_cell->bel, ctx->portPinFromId(load.port)); + delay_t raw_wl = ctx->estimateDelay(drv_wire, user_wire); + float slack = + ctx->getDelayNS(load.budget) - ctx->getDelayNS(raw_wl); + if (slack < 0) + tns += slack; + worst_slack = std::min(slack, worst_slack); + } - WireId user_wire = ctx->getWireBelPin( - load_cell->bel, ctx->portPinFromId(load.port)); - delay_t raw_wl = ctx->estimateDelay(drv_wire, user_wire); - float slack = - ctx->getDelayNS(load.budget) - ctx->getDelayNS(raw_wl); - if (slack < 0) - tns += slack; - worst_slack = std::min(slack, worst_slack); int load_x, load_y; bool load_gb; ctx->estimatePosition(load_cell->bel, load_x, load_y, load_gb); @@ -353,9 +355,15 @@ class SAPlacer xmax = std::max(xmax, load_x); ymax = std::max(ymax, load_y); } - wirelength = - wirelen_t((((ymax - ymin) + (xmax - xmin)) * - std::min(5.0, (1.0 + std::exp(-worst_slack / 5))))); + if (timing_driven) { + wirelength = + wirelen_t((((ymax - ymin) + (xmax - xmin)) * + std::min(5.0, (1.0 + std::exp(-worst_slack / 5))))); + } else { + wirelength = + wirelen_t((ymax - ymin) + (xmax - xmin)); + } + return wirelength; } @@ -475,6 +483,7 @@ class SAPlacer float curr_tns = 0; float temp = 1000; bool improved = false; + bool timing_driven = true; int n_move, n_accept; int diameter = 35, max_x = 1, max_y = 1; std::unordered_map<BelType, int> bel_types; @@ -483,10 +492,10 @@ class SAPlacer PlaceValidityChecker *checker; }; -bool place_design_sa(Context *ctx) +bool place_design_sa(Context *ctx, bool timing_driven) { try { - SAPlacer placer(ctx); + SAPlacer placer(ctx, timing_driven); placer.place(); log_info("Checksum: 0x%08x\n", ctx->checksum()); return true; diff --git a/common/place_sa.h b/common/place_sa.h index 1fd8c712..e61d9375 100644 --- a/common/place_sa.h +++ b/common/place_sa.h @@ -23,7 +23,7 @@ NEXTPNR_NAMESPACE_BEGIN -extern bool place_design_sa(Context *ctx); +extern bool place_design_sa(Context *ctx, bool timing_driven = true); NEXTPNR_NAMESPACE_END diff --git a/gui/pythontab.cc b/gui/pythontab.cc index 531038a1..a11059b5 100644 --- a/gui/pythontab.cc +++ b/gui/pythontab.cc @@ -127,7 +127,7 @@ void PythonTab::editLineReturnPressed(QString text) {
std::string input = text.toStdString();
print(std::string(">>> " + input + "\n"));
- int error = executePython(input);
+ executePython(input);
}
void PythonTab::showContextMenu(const QPoint &pt)
diff --git a/ice40/arch.cc b/ice40/arch.cc index ce45b051..78d4c29c 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -168,6 +168,9 @@ Arch::Arch(ArchArgs args) : args(args) wire_to_net.resize(chip_info->num_wires); pip_to_net.resize(chip_info->num_pips); switches_locked.resize(chip_info->num_switches); + + // Initialise regularly used IDStrings for performance + id_glb_buf_out = id("GLOBAL_BUFFER_OUTPUT"); } // ----------------------------------------------------------------------- @@ -501,4 +504,11 @@ bool Arch::isClockPort(const CellInfo *cell, IdString port) const return false; } +bool Arch::isGlobalNet(const NetInfo *net) const +{ + if (net == nullptr) + return false; + return net->driver.cell != nullptr && net->driver.port == id_glb_buf_out; +} + NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 07c2582b..a6b70a69 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -800,6 +800,10 @@ struct Arch : BaseCtx IdString getPortClock(const CellInfo *cell, IdString port) const; // Return true if a port is a clock bool isClockPort(const CellInfo *cell, IdString port) const; + // Return true if a port is a net + bool isGlobalNet(const NetInfo *net) const; + + IdString id_glb_buf_out; }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 25044525..7b79e031 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -58,11 +58,11 @@ bool PlaceValidityChecker::logicCellsCompatible( clk = get_net_or_empty(cell, id_clk); sr = get_net_or_empty(cell, id_sr); - if (!is_global_net(ctx, cen) && cen != nullptr) + if (!ctx->isGlobalNet(cen) && cen != nullptr) locals_count++; - if (!is_global_net(ctx, clk) && clk != nullptr) + if (!ctx->isGlobalNet(clk) && clk != nullptr) locals_count++; - if (!is_global_net(ctx, sr) && sr != nullptr) + if (!ctx->isGlobalNet(sr) && sr != nullptr) locals_count++; if (bool_or_default(cell->params, id_neg_clk)) { @@ -139,8 +139,9 @@ bool PlaceValidityChecker::isValidBelForCell(CellInfo *cell, BelId bel) return ctx->getBelPackagePin(bel) != ""; } else if (cell->type == id_sb_gb) { bool is_reset = false, is_cen = false; - assert(cell->ports.at("GLOBAL_BUFFER_OUTPUT").net != nullptr); - for (auto user : cell->ports.at("GLOBAL_BUFFER_OUTPUT").net->users) { + assert(cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net != nullptr); + for (auto user : + cell->ports.at(ctx->id("GLOBAL_BUFFER_OUTPUT")).net->users) { if (is_reset_port(ctx, user)) is_reset = true; if (is_enable_port(ctx, user)) @@ -148,7 +149,7 @@ bool PlaceValidityChecker::isValidBelForCell(CellInfo *cell, BelId bel) } IdString glb_net = ctx->getWireName( ctx->getWireBelPin(bel, PIN_GLOBAL_BUFFER_OUTPUT)); - int glb_id = std::stoi(std::string("") + glb_net.str().back()); + int glb_id = std::stoi(std::string("") + glb_net.str(ctx).back()); if (is_reset && is_cen) return false; else if (is_reset) diff --git a/ice40/arch_place.h b/ice40/arch_place.h index 339bf485..e90f2874 100644 --- a/ice40/arch_place.h +++ b/ice40/arch_place.h @@ -41,11 +41,11 @@ class PlaceValidityChecker private: bool logicCellsCompatible(const Context *ctx, const std::vector<const CellInfo *> &cells); + Context *ctx; IdString id_icestorm_lc, id_sb_io, id_sb_gb; IdString id_cen, id_clk, id_sr; IdString id_i0, id_i1, id_i2, id_i3; IdString id_dff_en, id_neg_clk; - Context *ctx; }; NEXTPNR_NAMESPACE_END diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 8e34335c..c46776a6 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -348,30 +348,34 @@ void write_asc(const Context *ctx, std::ostream &out) // Weird UltraPlus bits if (tile == TILE_DSP0 || tile == TILE_DSP1 || tile == TILE_DSP2 || - tile == TILE_IPCON) { - for (int lc_idx = 0; lc_idx < 8; lc_idx++) { - static const std::vector<int> ip_dsp_lut_perm = { - 4, 14, 15, 5, 6, 16, 17, 7, - 3, 13, 12, 2, 1, 11, 10, 0, - }; - for (int i = 0; i < 16; i++) - set_config(ti, config.at(y).at(x), - "LC_" + std::to_string(lc_idx), - ((i % 8) >= 4), ip_dsp_lut_perm.at(i)); - if (tile == TILE_IPCON) - set_config(ti, config.at(y).at(x), - "Cascade.IPCON_LC0" + - std::to_string(lc_idx) + - "_inmux02_5", - true); - else - set_config( - ti, config.at(y).at(x), - "Cascade.MULT" + - std::to_string(int(tile - TILE_DSP0)) + - "_LC0" + std::to_string(lc_idx) + - "_inmux02_5", - true); + tile == TILE_DSP3 || tile == TILE_IPCON) { + if (ctx->args.type == ArchArgs::UP5K && x == 25 && y == 14) { + // Mystery bits not set in this one tile + } else { + for (int lc_idx = 0; lc_idx < 8; lc_idx++) { + static const std::vector<int> ip_dsp_lut_perm = { + 4, 14, 15, 5, 6, 16, 17, 7, + 3, 13, 12, 2, 1, 11, 10, 0, + }; + for (int i = 0; i < 16; i++) + set_config(ti, config.at(y).at(x), + "LC_" + std::to_string(lc_idx), + ((i % 8) >= 4), ip_dsp_lut_perm.at(i)); + if (tile == TILE_IPCON) + set_config(ti, config.at(y).at(x), + "Cascade.IPCON_LC0" + + std::to_string(lc_idx) + + "_inmux02_5", + true); + else + set_config(ti, config.at(y).at(x), + "Cascade.MULT" + + std::to_string( + int(tile - TILE_DSP0)) + + "_LC0" + std::to_string(lc_idx) + + "_inmux02_5", + true); + } } } } @@ -441,7 +445,7 @@ void write_asc(const Context *ctx, std::ostream &out) cell.second, ctx->id(std::string("INIT_") + get_hexdigit(w))); assert(init != ""); - for (int i = 0; i < init.size(); i++) { + for (size_t i = 0; i < init.size(); i++) { bool val = (init.at((init.size() - 1) - i) == '1'); bits.at(i) = val; } @@ -458,7 +462,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Write symbols - const bool write_symbols = 1; + // const bool write_symbols = 1; for (auto wire : ctx->getWires()) { IdString net = ctx->getWireNet(wire, false); if (net != IdString()) diff --git a/ice40/cells.cc b/ice40/cells.cc index 0ae25e12..f34b7511 100644 --- a/ice40/cells.cc +++ b/ice40/cells.cc @@ -36,8 +36,8 @@ CellInfo *create_ice_cell(Context *ctx, IdString type, std::string name) static int auto_idx = 0; CellInfo *new_cell = new CellInfo(); if (name.empty()) { - new_cell->name = IdString(ctx, "$nextpnr_" + type.str() + "_" + - std::to_string(auto_idx++)); + new_cell->name = ctx->id("$nextpnr_" + type.str(ctx) + "_" + + std::to_string(auto_idx++)); } else { new_cell->name = ctx->id(name); } @@ -132,13 +132,13 @@ CellInfo *create_ice_cell(Context *ctx, IdString type, std::string name) void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff) { - lc->params["LUT_INIT"] = lut->params["LUT_INIT"]; - replace_port(lut, "I0", lc, "I0"); - replace_port(lut, "I1", lc, "I1"); - replace_port(lut, "I2", lc, "I2"); - replace_port(lut, "I3", lc, "I3"); + lc->params[ctx->id("LUT_INIT")] = lut->params[ctx->id("LUT_INIT")]; + replace_port(lut, ctx->id("I0"), lc, ctx->id("I0")); + replace_port(lut, ctx->id("I1"), lc, ctx->id("I1")); + replace_port(lut, ctx->id("I2"), lc, ctx->id("I2")); + replace_port(lut, ctx->id("I3"), lc, ctx->id("I3")); if (no_dff) { - replace_port(lut, "O", lc, "O"); + replace_port(lut, ctx->id("O"), lc, ctx->id("O")); lc->params[ctx->id("DFF_ENABLE")] = "0"; } } @@ -149,7 +149,7 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, lc->params[ctx->id("DFF_ENABLE")] = "1"; std::string config = dff->type.str(ctx).substr(6); auto citer = config.begin(); - replace_port(dff, "C", lc, "CLK"); + replace_port(dff, ctx->id("C"), lc, ctx->id("CLK")); if (citer != config.end() && *citer == 'N') { lc->params[ctx->id("NEG_CLK")] = "1"; @@ -159,7 +159,7 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, } if (citer != config.end() && *citer == 'E') { - replace_port(dff, "E", lc, "CEN"); + replace_port(dff, ctx->id("E"), lc, ctx->id("CEN")); ++citer; } @@ -174,12 +174,12 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, if (*citer == 'S') { citer++; - replace_port(dff, "S", lc, "SR"); + replace_port(dff, ctx->id("S"), lc, ctx->id("SR")); lc->params[ctx->id("SET_NORESET")] = "1"; } else { assert(*citer == 'R'); citer++; - replace_port(dff, "R", lc, "SR"); + replace_port(dff, ctx->id("R"), lc, ctx->id("SR")); lc->params[ctx->id("SET_NORESET")] = "0"; } } @@ -188,28 +188,28 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, if (pass_thru_lut) { lc->params[ctx->id("LUT_INIT")] = "2"; - replace_port(dff, "D", lc, "I0"); + replace_port(dff, ctx->id("D"), lc, ctx->id("I0")); } - replace_port(dff, "Q", lc, "O"); + replace_port(dff, ctx->id("Q"), lc, ctx->id("O")); } void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio) { if (nxio->type == ctx->id("$nextpnr_ibuf")) { sbio->params[ctx->id("PIN_TYPE")] = "1"; - auto pu_attr = nxio->attrs.find("PULLUP"); + auto pu_attr = nxio->attrs.find(ctx->id("PULLUP")); if (pu_attr != nxio->attrs.end()) sbio->params[ctx->id("PULLUP")] = pu_attr->second; - replace_port(nxio, "O", sbio, "D_IN_0"); + replace_port(nxio, ctx->id("O"), sbio, ctx->id("D_IN_0")); } else if (nxio->type == ctx->id("$nextpnr_obuf")) { sbio->params[ctx->id("PIN_TYPE")] = "25"; - replace_port(nxio, "I", sbio, "D_OUT_0"); + replace_port(nxio, ctx->id("I"), sbio, ctx->id("D_OUT_0")); } else if (nxio->type == ctx->id("$nextpnr_iobuf")) { // N.B. tristate will be dealt with below sbio->params[ctx->id("PIN_TYPE")] = "25"; - replace_port(nxio, "I", sbio, "D_OUT_0"); - replace_port(nxio, "O", sbio, "D_IN_0"); + replace_port(nxio, ctx->id("I"), sbio, ctx->id("D_OUT_0")); + replace_port(nxio, ctx->id("O"), sbio, ctx->id("D_IN_0")); } else { assert(false); } @@ -219,11 +219,11 @@ void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio) [](const Context *ctx, const CellInfo *cell) { return cell->type == ctx->id("$_TBUF_"); }, - "Y"); + ctx->id("Y")); if (tbuf) { sbio->params[ctx->id("PIN_TYPE")] = "41"; - replace_port(tbuf, "A", sbio, "D_OUT_0"); - replace_port(tbuf, "E", sbio, "OUTPUT_ENABLE"); + replace_port(tbuf, ctx->id("A"), sbio, ctx->id("D_OUT_0")); + replace_port(tbuf, ctx->id("E"), sbio, ctx->id("OUTPUT_ENABLE")); ctx->nets.erase(donet->name); if (!donet->users.empty()) log_error( @@ -269,10 +269,4 @@ bool is_enable_port(const Context *ctx, const PortRef &port) return false; } -bool is_global_net(const Context *ctx, const NetInfo *net) -{ - return bool( - net_driven_by(ctx, net, is_gbuf, ctx->id("GLOBAL_BUFFER_OUTPUT"))); -} - NEXTPNR_NAMESPACE_END diff --git a/ice40/cells.h b/ice40/cells.h index 3e5f6ebd..29331445 100644 --- a/ice40/cells.h +++ b/ice40/cells.h @@ -117,9 +117,6 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, // Convert a nextpnr IO buffer to a SB_IO void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio); -// Return true if a net is a global net -bool is_global_net(const Context *ctx, const NetInfo *net); - // Return true if a port is a clock port bool is_clock_port(const Context *ctx, const PortRef &port); diff --git a/ice40/main.cc b/ice40/main.cc index ae8c7705..e60ce442 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -101,6 +101,7 @@ int main(int argc, char *argv[]) options.add_options()("up5k", "set device type to iCE40UP5K"); options.add_options()("freq", po::value<double>(), "set target frequency for design in MHz"); + options.add_options()("no-tmdriv", "disable timing-driven placement"); options.add_options()("package", po::value<std::string>(), "set device package"); po::positional_options_description pos; @@ -308,9 +309,11 @@ int main(int argc, char *argv[]) freq = vm["freq"].as<double>() * 1e6; assign_budget(&ctx, freq); print_utilisation(&ctx); - + bool timing_driven = true; + if (vm.count("no-tmdriv")) + timing_driven = false; if (!vm.count("pack-only")) { - if (!place_design_sa(&ctx) && !ctx.force) + if (!place_design_sa(&ctx, timing_driven) && !ctx.force) log_error("Placing design failed.\n"); if (!route_design(&ctx) && !ctx.force) log_error("Routing design failed.\n"); diff --git a/ice40/pack.cc b/ice40/pack.cc index 5022fc59..e6be502f 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -41,7 +41,7 @@ static void pack_lut_lutffs(Context *ctx) log_info("cell '%s' is of type '%s'\n", ci->name.c_str(ctx), ci->type.c_str(ctx)); if (is_lut(ctx, ci)) { - CellInfo *packed = create_ice_cell(ctx, "ICESTORM_LC", + CellInfo *packed = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "_LC"); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(packed->attrs, packed->attrs.begin())); @@ -53,7 +53,7 @@ static void pack_lut_lutffs(Context *ctx) // See if we can pack into a DFF // TODO: LUT cascade NetInfo *o = ci->ports.at(ctx->id("O")).net; - CellInfo *dff = net_only_drives(ctx, o, is_ff, "D", true); + CellInfo *dff = net_only_drives(ctx, o, is_ff, ctx->id("D"), true); auto lut_bel = ci->attrs.find(ctx->id("BEL")); bool packed_dff = false; if (dff) { @@ -100,7 +100,7 @@ static void pack_nonlut_ffs(Context *ctx) for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (is_ff(ctx, ci)) { - CellInfo *packed = create_ice_cell(ctx, "ICESTORM_LC", + CellInfo *packed = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "_DFFLC"); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(packed->attrs, packed->attrs.begin())); @@ -131,18 +131,19 @@ static void pack_carries(Context *ctx) CellInfo *ci = cell.second; if (is_carry(ctx, ci)) { packed_cells.insert(cell.first); - CellInfo *carry_ci_lc = net_only_drives(ctx, ci->ports.at("CI").net, - is_lc, "I3", false); - if (!ci->ports.at("I0").net) + CellInfo *carry_ci_lc = + net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, is_lc, + ctx->id("I3"), false); + if (!ci->ports.at(ctx->id("I0")).net) log_error("SB_CARRY '%s' has disconnected port I0\n", cell.first.c_str(ctx)); - if (!ci->ports.at("I1").net) + if (!ci->ports.at(ctx->id("I1")).net) log_error("SB_CARRY '%s' has disconnected port I1\n", cell.first.c_str(ctx)); std::unordered_set<IdString> i0_matches, i1_matches; - auto &i0_usrs = ci->ports.at("I0").net->users; - auto &i1_usrs = ci->ports.at("I1").net->users; + auto &i0_usrs = ci->ports.at(ctx->id("I0")).net->users; + auto &i1_usrs = ci->ports.at(ctx->id("I1")).net->users; // Find logic cells connected to both I0 and I1 for (auto usr : i0_usrs) { if (is_lc(ctx, usr.cell) && usr.port == ctx->id("I1")) @@ -173,8 +174,8 @@ static void pack_carries(Context *ctx) carry_lc = ctx->cells.at(*carry_lcs.begin()); } carry_lc->attrs[ctx->id("CARRY_ENABLE")] = "1"; - replace_port(ci, "CI", carry_lc, "CIN"); - replace_port(ci, "CO", carry_lc, "COUT"); + replace_port(ci, ctx->id("CI"), carry_lc, ctx->id("CIN")); + replace_port(ci, ctx->id("CO"), carry_lc, ctx->id("COUT")); i0_usrs.erase(std::remove_if(i0_usrs.begin(), i0_usrs.end(), [ci, ctx](const PortRef &pr) { @@ -205,29 +206,30 @@ static void pack_ram(Context *ctx) for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (is_ram(ctx, ci)) { - CellInfo *packed = create_ice_cell(ctx, "ICESTORM_RAM", + CellInfo *packed = create_ice_cell(ctx, ctx->id("ICESTORM_RAM"), ci->name.str(ctx) + "_RAM"); packed_cells.insert(ci->name); new_cells.push_back(packed); for (auto param : ci->params) packed->params[param.first] = param.second; - packed->params["NEG_CLK_W"] = + packed->params[ctx->id("NEG_CLK_W")] = std::to_string(ci->type == ctx->id("SB_RAM40_4KNW") || ci->type == ctx->id("SB_RAM40_4KNRNW")); - packed->params["NEG_CLK_R"] = + packed->params[ctx->id("NEG_CLK_R")] = std::to_string(ci->type == ctx->id("SB_RAM40_4KNR") || ci->type == ctx->id("SB_RAM40_4KNRNW")); packed->type = ctx->id("ICESTORM_RAM"); for (auto port : ci->ports) { PortInfo &pi = port.second; - std::string newname = pi.name; + std::string newname = pi.name.str(ctx); size_t bpos = newname.find('['); if (bpos != std::string::npos) { newname = newname.substr(0, bpos) + "_" + newname.substr(bpos + 1, (newname.size() - bpos) - 2); } - replace_port(ci, pi.name, packed, newname); + replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed, + ctx->id(newname)); } } } @@ -268,14 +270,16 @@ static void pack_constants(Context *ctx) { log_info("Packing constants..\n"); - CellInfo *gnd_cell = create_ice_cell(ctx, "ICESTORM_LC", "$PACKER_GND"); + CellInfo *gnd_cell = + create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_GND"); gnd_cell->params[ctx->id("LUT_INIT")] = "0"; NetInfo *gnd_net = new NetInfo; - gnd_net->name = "$PACKER_GND_NET"; + gnd_net->name = ctx->id("$PACKER_GND_NET"); gnd_net->driver.cell = gnd_cell; gnd_net->driver.port = ctx->id("O"); - CellInfo *vcc_cell = create_ice_cell(ctx, "ICESTORM_LC", "$PACKER_VCC"); + CellInfo *vcc_cell = + create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC"); vcc_cell->params[ctx->id("LUT_INIT")] = "1"; NetInfo *vcc_net = new NetInfo; vcc_net->name = ctx->id("$PACKER_VCC_NET"); @@ -336,12 +340,14 @@ static void pack_io(Context *ctx) CellInfo *sb = nullptr; if (ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_iobuf")) { - sb = net_only_drives(ctx, ci->ports.at("O").net, is_sb_io, - "PACKAGE_PIN", true, ci); + sb = net_only_drives(ctx, ci->ports.at(ctx->id("O")).net, + is_sb_io, ctx->id("PACKAGE_PIN"), true, + ci); } else if (ci->type == ctx->id("$nextpnr_obuf")) { - sb = net_only_drives(ctx, ci->ports.at("I").net, is_sb_io, - "PACKAGE_PIN", true, ci); + sb = net_only_drives(ctx, ci->ports.at(ctx->id("I")).net, + is_sb_io, ctx->id("PACKAGE_PIN"), true, + ci); } if (sb != nullptr) { // Trivial case, SB_IO used. Just destroy the net and the @@ -349,14 +355,14 @@ static void pack_io(Context *ctx) log_info("%s feeds SB_IO %s, removing %s %s.\n", ci->name.c_str(ctx), sb->name.c_str(ctx), ci->type.c_str(ctx), ci->name.c_str(ctx)); - NetInfo *net = sb->ports.at("PACKAGE_PIN").net; + NetInfo *net = sb->ports.at(ctx->id("PACKAGE_PIN")).net; if (net != nullptr) { ctx->nets.erase(net->name); - sb->ports.at("PACKAGE_PIN").net = nullptr; + sb->ports.at(ctx->id("PACKAGE_PIN")).net = nullptr; } } else { // Create a SB_IO buffer - sb = create_ice_cell(ctx, "SB_IO", + sb = create_ice_cell(ctx, ctx->id("SB_IO"), ci->name.str(ctx) + "$sb_io"); nxio_to_sb(ctx, ci, sb); new_cells.push_back(sb); @@ -379,7 +385,7 @@ static void insert_global(Context *ctx, NetInfo *net, bool is_reset, { std::string glb_name = net->name.str(ctx) + std::string("_$glb_") + (is_reset ? "sr" : (is_cen ? "ce" : "clk")); - CellInfo *gb = create_ice_cell(ctx, "SB_GB", "$gbuf_" + glb_name); + CellInfo *gb = create_ice_cell(ctx, ctx->id("SB_GB"), "$gbuf_" + glb_name); gb->ports[ctx->id("USER_SIGNAL_TO_GLOBAL_BUFFER")].net = net; PortRef pr; pr.cell = gb; @@ -416,7 +422,7 @@ static void promote_globals(Context *ctx) std::map<IdString, int> clock_count, reset_count, cen_count; for (auto net : sorted(ctx->nets)) { NetInfo *ni = net.second; - if (ni->driver.cell != nullptr && !is_global_net(ctx, ni)) { + if (ni->driver.cell != nullptr && !ctx->isGlobalNet(ni)) { clock_count[net.first] = 0; reset_count[net.first] = 0; cen_count[net.first] = 0; @@ -496,16 +502,17 @@ static void pack_intosc(Context *ctx) for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (is_sb_lfosc(ctx, ci)) { - CellInfo *packed = create_ice_cell(ctx, "ICESTORM_LFOSC", + CellInfo *packed = create_ice_cell(ctx, ctx->id("ICESTORM_LFOSC"), ci->name.str(ctx) + "_OSC"); packed_cells.insert(ci->name); new_cells.push_back(packed); - replace_port(ci, "CLKLFEN", packed, "CLKLFEN"); - replace_port(ci, "CLKLFPU", packed, "CLKLFPU"); - if (bool_or_default(ci->attrs, "ROUTE_THROUGH_FABRIC")) { - replace_port(ci, "CLKLF", packed, "CLKLF_FABRIC"); + replace_port(ci, ctx->id("CLKLFEN"), packed, ctx->id("CLKLFEN")); + replace_port(ci, ctx->id("CLKLFPU"), packed, ctx->id("CLKLFPU")); + if (bool_or_default(ci->attrs, ctx->id("ROUTE_THROUGH_FABRIC"))) { + replace_port(ci, ctx->id("CLKLF"), packed, + ctx->id("CLKLF_FABRIC")); } else { - replace_port(ci, "CLKLF", packed, "CLKLF"); + replace_port(ci, ctx->id("CLKLF"), packed, ctx->id("CLKLF")); } } } diff --git a/ice40/pcf.cc b/ice40/pcf.cc index 13fe199e..51f67364 100644 --- a/ice40/pcf.cc +++ b/ice40/pcf.cc @@ -52,7 +52,7 @@ bool apply_pcf(Context *ctx, std::istream &in) args_end++; std::string cell = words.at(args_end); std::string pin = words.at(args_end + 1); - auto fnd_cell = ctx->cells.find(cell); + auto fnd_cell = ctx->cells.find(ctx->id(cell)); if (fnd_cell == ctx->cells.end()) { log_warning("unmatched pcf constraint %s\n", cell.c_str()); } else { @@ -60,10 +60,10 @@ bool apply_pcf(Context *ctx, std::istream &in) if (pin_bel == BelId()) log_error("package does not have a pin named %s\n", pin.c_str()); - fnd_cell->second->attrs["BEL"] = - ctx->getBelName(pin_bel).str(); + fnd_cell->second->attrs[ctx->id("BEL")] = + ctx->getBelName(pin_bel).str(ctx); log_info("constrained '%s' to bel '%s'\n", cell.c_str(), - fnd_cell->second->attrs["BEL"].c_str()); + fnd_cell->second->attrs[ctx->id("BEL")].c_str()); } } else { log_error("unsupported pcf command '%s'\n", cmd.c_str()); |