aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/command.cc51
-rw-r--r--common/nextpnr.cc66
-rw-r--r--common/nextpnr.h3
-rw-r--r--ecp5/arch.cc17
-rw-r--r--ecp5/arch.h2
-rw-r--r--ecp5/pack.cc1
-rw-r--r--generic/arch.cc11
-rw-r--r--generic/arch.h2
-rw-r--r--ice40/arch.cc24
-rw-r--r--ice40/arch.h2
-rw-r--r--ice40/pack.cc1
-rw-r--r--json/jsonparse.cc6
-rw-r--r--json/jsonwrite.cc74
13 files changed, 130 insertions, 130 deletions
diff --git a/common/command.cc b/common/command.cc
index d700f4ee..96008d2b 100644
--- a/common/command.cc
+++ b/common/command.cc
@@ -311,46 +311,7 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
run_script_hook("pre-pack");
if (!ctx->pack() && !ctx->force)
log_error("Packing design failed.\n");
- } else {
- for (auto &pair : ctx->cells) {
- auto &c = pair.second;
- auto constr_main = c->attrs.find(ctx->id("NEXTPNR_CONSTRAINT"));
- auto constr_child = c->attrs.find(ctx->id("NEXTPNR_CONSTR_CHILDREN"));
- if (constr_main!=c->attrs.end())
- {
- std::vector<std::string> val;
- boost::split(val,constr_main->second.str,boost::is_any_of(";"));
- c->constr_x = std::stoi(val[0]);
- c->constr_y = std::stoi(val[1]);
- c->constr_z = std::stoi(val[2]);
- c->constr_abs_z = val[3]=="1";
- c->constr_parent = nullptr;
- if (!val[4].empty())
- c->constr_parent = ctx->cells.find(ctx->id(val[4].c_str()))->second.get();
- #ifdef ARCH_ECP5
- c->sliceInfo.using_dff = val[5]=="1";
- c->sliceInfo.has_l6mux = val[6]=="1";
- c->sliceInfo.is_carry = val[7]=="1";
- c->sliceInfo.clk_sig = ctx->id(val[8]);
- c->sliceInfo.lsr_sig = ctx->id(val[9]);
- c->sliceInfo.clkmux = ctx->id(val[10]);
- c->sliceInfo.lsrmux = ctx->id(val[11]);
- c->sliceInfo.srmode = ctx->id(val[12]);
- c->sliceInfo.sd0 = std::stoi(val[13]);
- c->sliceInfo.sd1 = std::stoi(val[14]);
- #endif
- }
- if (constr_child!=c->attrs.end())
- {
- for(auto val : split(constr_child->second.str.c_str(),";"))
- {
- c->constr_children.push_back(ctx->cells.find(ctx->id(val.c_str()))->second.get());
- }
- }
- }
- ctx->assignArchInfo();
- }
-
+ }
assign_budget(ctx.get());
ctx->check();
print_utilisation(ctx.get());
@@ -360,16 +321,6 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
if (!ctx->place() && !ctx->force)
log_error("Placing design failed.\n");
ctx->check();
- } else {
- for (auto &pair : ctx->cells) {
- auto &c = pair.second;
- auto bel = c->attrs.find(ctx->id("NEXTPNR_BEL"));
- if (bel!=c->attrs.end())
- {
- BelId b = ctx->getBelByName(ctx->id(bel->second.c_str()));
- ctx->bindBel(b, c.get(), STRENGTH_USER);
- }
- }
}
if (do_route) {
diff --git a/common/nextpnr.cc b/common/nextpnr.cc
index daaadf28..89b6ed6c 100644
--- a/common/nextpnr.cc
+++ b/common/nextpnr.cc
@@ -453,4 +453,70 @@ DecalXY BaseCtx::constructDecalXY(DecalId decal, float x, float y)
return dxy;
}
+void BaseCtx::commonInfoToAttributes()
+{
+ for (auto &cell : cells) {
+ auto ci = cell.second.get();
+ if (ci->bel != BelId()) {
+ ci->attrs[id("NEXTPNR_BEL")] = getCtx()->getBelName(ci->bel).c_str(this);
+ ci->attrs[id("BEL_STRENGTH")] = std::to_string((int)ci->belStrength);
+ }
+ if (ci->constr_x!= ci->UNCONSTR)
+ ci->attrs[id("CONSTR_X")] = std::to_string(ci->constr_x);
+ if (ci->constr_y!= ci->UNCONSTR)
+ ci->attrs[id("CONSTR_Y")] = std::to_string(ci->constr_y);
+ if (ci->constr_z!= ci->UNCONSTR)
+ ci->attrs[id("CONSTR_Z")] = std::to_string(ci->constr_z);
+ if (ci->constr_parent!= nullptr)
+ ci->attrs[id("CONSTR_PARENT")] = ci->constr_parent->name.c_str(this);
+ }
+ for (auto &net : getCtx()->nets) {
+ auto ni = net.second.get();
+ std::string routing;
+ for (auto &item : ni->wires) {
+ routing += getCtx()->getWireName(item.first).c_str(this);
+ routing += ",";
+ if (item.second.pip != PipId())
+ routing += getCtx()->getPipName(item.second.pip).c_str(this);
+ }
+ ni->attrs[id("ROUTING")] = routing;
+ }
+}
+
+void BaseCtx::attributesToCommonInfo()
+{
+ for (auto &cell : cells) {
+ auto ci = cell.second.get();
+ auto val = ci->attrs.find(id("NEXTPNR_BEL"));
+ if (val != ci->attrs.end()) {
+ auto str = ci->attrs.find(id("BEL_STRENGTH"));
+ PlaceStrength strength = PlaceStrength::STRENGTH_USER;
+ if (str != ci->attrs.end())
+ strength = (PlaceStrength)std::stoi(str->second.str);
+
+ BelId b = getCtx()->getBelByName(id(val->second.str));
+ getCtx()->bindBel(b, ci, strength);
+ }
+ val = ci->attrs.find(id("CONSTR_X"));
+ if (val != ci->attrs.end())
+ ci->constr_x = std::stoi(val->second.str);
+
+ val = ci->attrs.find(id("CONSTR_Y"));
+ if (val != ci->attrs.end())
+ ci->constr_y = std::stoi(val->second.str);
+
+ val = ci->attrs.find(id("CONSTR_Z"));
+ if (val != ci->attrs.end()) {
+ ci->constr_z = std::stoi(val->second.str);
+ ci->constr_abs_z = (ci->constr_z == 0);
+ }
+ val = ci->attrs.find(id("CONSTR_PARENT"));
+ if (val != ci->attrs.end()) {
+ auto parent = cells.find(id(val->second.str));
+ if (parent != cells.end())
+ ci->constr_parent = parent->second.get();
+ }
+ }
+}
+
NEXTPNR_NAMESPACE_END
diff --git a/common/nextpnr.h b/common/nextpnr.h
index 02201463..f7f135fb 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -681,6 +681,9 @@ struct BaseCtx
// Workaround for lack of wrappable constructors
DecalXY constructDecalXY(DecalId decal, float x, float y);
+
+ void commonInfoToAttributes();
+ void attributesToCommonInfo();
};
NEXTPNR_NAMESPACE_END
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 9da8abdf..b5ffa5dc 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -524,6 +524,7 @@ bool Arch::place()
}
permute_luts();
+ archInfoToAttributes();
return true;
}
@@ -558,6 +559,7 @@ bool Arch::route()
log_info(" base %d adder %d\n", speed_grade->pip_classes[locInfo(slowest_pip)->pip_data[slowest_pip.index].timing_class].max_base_delay,
speed_grade->pip_classes[locInfo(slowest_pip)->pip_data[slowest_pip.index].timing_class].max_fanout_adder);
#endif
+ archInfoToAttributes();
return result;
}
@@ -986,6 +988,21 @@ WireId Arch::getBankECLK(int bank, int eclk)
return getWireByLocAndBasename(Location(0, 0), "G_BANK" + std::to_string(bank) + "ECLK" + std::to_string(eclk));
}
+void Arch::archInfoToAttributes()
+{
+ commonInfoToAttributes();
+ for (auto &net : getCtx()->nets) {
+ auto ni = net.second.get();
+ ni->attrs[id("IS_GLOBAL")] = ni->is_global ? "1" : "0";
+ }
+}
+
+void Arch::attributesToArchInfo()
+{
+ attributesToCommonInfo();
+ assignArchInfo();
+}
+
#ifdef WITH_HEAP
const std::string Arch::defaultPlacer = "heap";
#else
diff --git a/ecp5/arch.h b/ecp5/arch.h
index 3de06a42..23a264ec 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -994,6 +994,8 @@ struct Arch : BaseCtx
bool slicesCompatible(const std::vector<const CellInfo *> &cells) const;
void assignArchInfo();
+ void archInfoToAttributes();
+ void attributesToArchInfo();
void permute_luts();
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 548c38d8..5b924759 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -2428,6 +2428,7 @@ bool Arch::pack()
Ecp5Packer(ctx).pack();
log_info("Checksum: 0x%08x\n", ctx->checksum());
assignArchInfo();
+ archInfoToAttributes();
return true;
} catch (log_execution_error_exception) {
assignArchInfo();
diff --git a/generic/arch.cc b/generic/arch.cc
index 5617fa63..674f7af7 100644
--- a/generic/arch.cc
+++ b/generic/arch.cc
@@ -604,6 +604,17 @@ void Arch::assignArchInfo()
}
}
+void Arch::archInfoToAttributes()
+{
+ commonInfoToAttributes();
+}
+
+void Arch::attributesToArchInfo()
+{
+ attributesToCommonInfo();
+ assignArchInfo();
+}
+
bool Arch::cellsCompatible(const CellInfo **cells, int count) const
{
const NetInfo *clk = nullptr;
diff --git a/generic/arch.h b/generic/arch.h
index e9d3593c..f553c613 100644
--- a/generic/arch.h
+++ b/generic/arch.h
@@ -288,6 +288,8 @@ struct Arch : BaseCtx
// Internal usage
void assignArchInfo();
bool cellsCompatible(const CellInfo **cells, int count) const;
+ void archInfoToAttributes();
+ void attributesToArchInfo();
};
NEXTPNR_NAMESPACE_END
diff --git a/ice40/arch.cc b/ice40/arch.cc
index d536ad35..659717f8 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -683,16 +683,21 @@ bool Arch::place()
} else {
log_error("iCE40 architecture does not support placer '%s'\n", placer.c_str());
}
+ bool retVal = true;
if (bool_or_default(settings, id("opt_timing"), false)) {
TimingOptCfg tocfg(getCtx());
tocfg.cellTypes.insert(id_ICESTORM_LC);
- return timing_opt(getCtx(), tocfg);
- } else {
- return true;
+ retVal = timing_opt(getCtx(), tocfg);
}
+ archInfoToAttributes();
+ return retVal;
}
-bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
+bool Arch::route() {
+ bool retVal = router1(getCtx(), Router1Cfg(getCtx()));
+ archInfoToAttributes();
+ return retVal;
+}
// -----------------------------------------------------------------------
@@ -1229,6 +1234,17 @@ void Arch::assignCellInfo(CellInfo *cell)
}
}
+void Arch::archInfoToAttributes()
+{
+ commonInfoToAttributes();
+}
+
+void Arch::attributesToArchInfo()
+{
+ attributesToCommonInfo();
+ assignArchInfo();
+}
+
const std::string Arch::defaultPlacer = "sa";
const std::vector<std::string> Arch::availablePlacers = {"sa",
diff --git a/ice40/arch.h b/ice40/arch.h
index ea29f4f1..8b6942cb 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -878,6 +878,8 @@ struct Arch : BaseCtx
// netlist modifications, and validity checks
void assignArchInfo();
void assignCellInfo(CellInfo *cell);
+ void archInfoToAttributes();
+ void attributesToArchInfo();
// -------------------------------------------------
BelPin getIOBSharingPLLPin(BelId pll, IdString pll_pin) const
diff --git a/ice40/pack.cc b/ice40/pack.cc
index 4cb76add..bc57e7d0 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -1406,6 +1406,7 @@ bool Arch::pack()
ctx->assignArchInfo();
constrain_chains(ctx);
ctx->assignArchInfo();
+ archInfoToAttributes();
log_info("Checksum: 0x%08x\n", ctx->checksum());
return true;
} catch (log_execution_error_exception) {
diff --git a/json/jsonparse.cc b/json/jsonparse.cc
index 7d11cd03..41d54188 100644
--- a/json/jsonparse.cc
+++ b/json/jsonparse.cc
@@ -349,11 +349,6 @@ void json_import_net_attrib(Context *ctx, string &modname, NetInfo *net, JsonNod
else
log_error("JSON parameter type of \"%s\' of net \'%s\' not supported\n", pId.c_str(ctx),
net->name.c_str(ctx));
-#ifdef ARCH_ECP5
- if (param_node->data_dict_keys[param_id]== "NEXTPNR_IS_GLOBAL") {
- net->is_global = (*dest)[pId].num;
- }
-#endif
if (json_debug)
log_info(" Added parameter \'%s\'=%s to net \'%s\' "
"of module \'%s\'\n",
@@ -885,6 +880,7 @@ bool parse_json_file(std::istream &f, std::string &filename, Context *ctx)
log_info("Checksum: 0x%08x\n", ctx->checksum());
log_break();
ctx->settings.emplace(ctx->id("input/json"), filename);
+ ctx->attributesToCommonInfo();
return true;
} catch (log_execution_error_exception) {
return false;
diff --git a/json/jsonwrite.cc b/json/jsonwrite.cc
index 2aaba756..811a2eec 100644
--- a/json/jsonwrite.cc
+++ b/json/jsonwrite.cc
@@ -48,7 +48,7 @@ std::string get_name(IdString name, Context *ctx)
return get_string(name.c_str(ctx));
}
-bool write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<IdString, Property> &parameters, bool for_module=false)
+void write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<IdString, Property> &parameters, bool for_module=false)
{
bool first = true;
for (auto &param : parameters) {
@@ -60,72 +60,6 @@ bool write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<Id
f << param.second.num;
first = false;
}
- return first;
-}
-
-void write_routing(std::ostream &f, Context *ctx, NetInfo *net, bool first)
-{
- std::string routing;
- bool first2 = true;
- for (auto &item : net->wires) {
- routing += first2 ? "" : ";";
- routing += ctx->getWireName(item.first).c_str(ctx);
- routing += ",";
- if (item.second.pip != PipId())
- routing += ctx->getPipName(item.second.pip).c_str(ctx);
- first2 = false;
- }
-
- f << stringf("%s\n", first ? "" : ",");
- f << stringf(" \"NEXTPNR_ROUTING\": ");
- f << get_string(routing);
-#ifdef ARCH_ECP5
- f << stringf(",\n");
- f << stringf(" \"NEXTPNR_IS_GLOBAL\": ");
- f << std::to_string(net->is_global ? 1:0);
-#endif
-}
-
-void write_constraints(std::ostream &f, Context *ctx, CellInfo *cell, bool first)
-{
- std::string constr;
- constr += std::to_string(cell->constr_x) + ";";
- constr += std::to_string(cell->constr_y) + ";";
- constr += std::to_string(cell->constr_z) + ";";
- constr += std::to_string(cell->constr_abs_z ? 1:0) + ";";
- constr += cell->constr_parent!=nullptr ? cell->constr_parent->name.c_str(ctx) : "";
-#ifdef ARCH_ECP5
- constr += ";";
- constr += std::to_string(cell->sliceInfo.using_dff ? 1:0) + ";";
- constr += std::to_string(cell->sliceInfo.has_l6mux ? 1:0) + ";";
- constr += std::to_string(cell->sliceInfo.is_carry ? 1:0) + ";";
- constr += std::string(cell->sliceInfo.clk_sig.c_str(ctx)) + ";";
- constr += std::string(cell->sliceInfo.lsr_sig.c_str(ctx)) + ";";
- constr += std::string(cell->sliceInfo.clkmux.c_str(ctx)) + ";";
- constr += std::string(cell->sliceInfo.lsrmux.c_str(ctx)) + ";";
- constr += std::string(cell->sliceInfo.srmode.c_str(ctx)) + ";";
- constr += std::to_string(cell->sliceInfo.sd0) + ";";
- constr += std::to_string(cell->sliceInfo.sd1) + ";";
-#endif
- f << stringf("%s\n", first ? "" : ",");
- f << stringf(" \"NEXTPNR_CONSTRAINT\": ");
- f << get_string(constr);
-
- constr = "";
- for(auto &item : cell->constr_children)
- {
- if (!constr.empty()) constr += std::string(";");
- constr += item->name.c_str(ctx);
- }
- f << stringf(",\n");
- f << stringf(" \"NEXTPNR_CONSTR_CHILDREN\": ");
- f << get_string(constr);
- if (cell->bel != BelId()) {
- f << stringf(",\n");
- f << stringf(" \"NEXTPNR_BEL\": ");
- f << get_string(ctx->getBelName(cell->bel).c_str(ctx));
- }
-
}
void write_module(std::ostream &f, Context *ctx)
@@ -154,8 +88,7 @@ void write_module(std::ostream &f, Context *ctx)
write_parameters(f, ctx, c->params);
f << stringf("\n },\n");
f << stringf(" \"attributes\": {");
- bool first3 = write_parameters(f, ctx, c->attrs);
- write_constraints(f, ctx, c.get(), first3);
+ write_parameters(f, ctx, c->attrs);
f << stringf("\n },\n");
f << stringf(" \"port_directions\": {");
bool first2 = true;
@@ -196,8 +129,7 @@ void write_module(std::ostream &f, Context *ctx)
f << stringf(" \"hide_name\": %s,\n", w->name.c_str(ctx)[0] == '$' ? "1" : "0");
f << stringf(" \"bits\": [ %d ] ,\n", pair.first.index);
f << stringf(" \"attributes\": {");
- bool first2 = write_parameters(f, ctx, w->attrs);
- write_routing(f, ctx, w.get(), first2);
+ write_parameters(f, ctx, w->attrs);
f << stringf("\n }\n");
f << stringf(" }");
first = false;