aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--3rdparty/QtPropertyBrowser/src/qtbuttonpropertybrowser.cpp6
-rw-r--r--3rdparty/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp6
-rw-r--r--3rdparty/QtPropertyBrowser/src/qtpropertybrowser.cpp4
-rw-r--r--common/log.cc2
-rw-r--r--common/place_sa.cc37
-rw-r--r--common/place_sa.h2
-rw-r--r--gui/pythontab.cc2
-rw-r--r--ice40/arch.cc10
-rw-r--r--ice40/arch.h4
-rw-r--r--ice40/arch_place.cc13
-rw-r--r--ice40/arch_place.h2
-rw-r--r--ice40/bitstream.cc56
-rw-r--r--ice40/cells.cc50
-rw-r--r--ice40/cells.h3
-rw-r--r--ice40/main.cc7
-rw-r--r--ice40/pack.cc75
-rw-r--r--ice40/pcf.cc8
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());