WIP saving/loading attributes

This commit is contained in:
Miodrag Milanovic 2019-06-07 11:48:15 +02:00
parent 3ae50f85b1
commit 1093d7e122
13 changed files with 130 additions and 130 deletions

View File

@ -311,46 +311,7 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
run_script_hook("pre-pack"); run_script_hook("pre-pack");
if (!ctx->pack() && !ctx->force) if (!ctx->pack() && !ctx->force)
log_error("Packing design failed.\n"); 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()); assign_budget(ctx.get());
ctx->check(); ctx->check();
print_utilisation(ctx.get()); print_utilisation(ctx.get());
@ -360,16 +321,6 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
if (!ctx->place() && !ctx->force) if (!ctx->place() && !ctx->force)
log_error("Placing design failed.\n"); log_error("Placing design failed.\n");
ctx->check(); 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) { if (do_route) {

View File

@ -453,4 +453,70 @@ DecalXY BaseCtx::constructDecalXY(DecalId decal, float x, float y)
return dxy; 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 NEXTPNR_NAMESPACE_END

View File

@ -681,6 +681,9 @@ struct BaseCtx
// Workaround for lack of wrappable constructors // Workaround for lack of wrappable constructors
DecalXY constructDecalXY(DecalId decal, float x, float y); DecalXY constructDecalXY(DecalId decal, float x, float y);
void commonInfoToAttributes();
void attributesToCommonInfo();
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -524,6 +524,7 @@ bool Arch::place()
} }
permute_luts(); permute_luts();
archInfoToAttributes();
return true; 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, 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); speed_grade->pip_classes[locInfo(slowest_pip)->pip_data[slowest_pip.index].timing_class].max_fanout_adder);
#endif #endif
archInfoToAttributes();
return result; 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)); 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 #ifdef WITH_HEAP
const std::string Arch::defaultPlacer = "heap"; const std::string Arch::defaultPlacer = "heap";
#else #else

View File

@ -994,6 +994,8 @@ struct Arch : BaseCtx
bool slicesCompatible(const std::vector<const CellInfo *> &cells) const; bool slicesCompatible(const std::vector<const CellInfo *> &cells) const;
void assignArchInfo(); void assignArchInfo();
void archInfoToAttributes();
void attributesToArchInfo();
void permute_luts(); void permute_luts();

View File

@ -2428,6 +2428,7 @@ bool Arch::pack()
Ecp5Packer(ctx).pack(); Ecp5Packer(ctx).pack();
log_info("Checksum: 0x%08x\n", ctx->checksum()); log_info("Checksum: 0x%08x\n", ctx->checksum());
assignArchInfo(); assignArchInfo();
archInfoToAttributes();
return true; return true;
} catch (log_execution_error_exception) { } catch (log_execution_error_exception) {
assignArchInfo(); assignArchInfo();

View File

@ -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 bool Arch::cellsCompatible(const CellInfo **cells, int count) const
{ {
const NetInfo *clk = nullptr; const NetInfo *clk = nullptr;

View File

@ -288,6 +288,8 @@ struct Arch : BaseCtx
// Internal usage // Internal usage
void assignArchInfo(); void assignArchInfo();
bool cellsCompatible(const CellInfo **cells, int count) const; bool cellsCompatible(const CellInfo **cells, int count) const;
void archInfoToAttributes();
void attributesToArchInfo();
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -683,16 +683,21 @@ bool Arch::place()
} else { } else {
log_error("iCE40 architecture does not support placer '%s'\n", placer.c_str()); 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)) { if (bool_or_default(settings, id("opt_timing"), false)) {
TimingOptCfg tocfg(getCtx()); TimingOptCfg tocfg(getCtx());
tocfg.cellTypes.insert(id_ICESTORM_LC); tocfg.cellTypes.insert(id_ICESTORM_LC);
return timing_opt(getCtx(), tocfg); retVal = timing_opt(getCtx(), tocfg);
} else {
return true;
} }
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::string Arch::defaultPlacer = "sa";
const std::vector<std::string> Arch::availablePlacers = {"sa", const std::vector<std::string> Arch::availablePlacers = {"sa",

View File

@ -878,6 +878,8 @@ struct Arch : BaseCtx
// netlist modifications, and validity checks // netlist modifications, and validity checks
void assignArchInfo(); void assignArchInfo();
void assignCellInfo(CellInfo *cell); void assignCellInfo(CellInfo *cell);
void archInfoToAttributes();
void attributesToArchInfo();
// ------------------------------------------------- // -------------------------------------------------
BelPin getIOBSharingPLLPin(BelId pll, IdString pll_pin) const BelPin getIOBSharingPLLPin(BelId pll, IdString pll_pin) const

View File

@ -1406,6 +1406,7 @@ bool Arch::pack()
ctx->assignArchInfo(); ctx->assignArchInfo();
constrain_chains(ctx); constrain_chains(ctx);
ctx->assignArchInfo(); ctx->assignArchInfo();
archInfoToAttributes();
log_info("Checksum: 0x%08x\n", ctx->checksum()); log_info("Checksum: 0x%08x\n", ctx->checksum());
return true; return true;
} catch (log_execution_error_exception) { } catch (log_execution_error_exception) {

View File

@ -349,11 +349,6 @@ void json_import_net_attrib(Context *ctx, string &modname, NetInfo *net, JsonNod
else else
log_error("JSON parameter type of \"%s\' of net \'%s\' not supported\n", pId.c_str(ctx), log_error("JSON parameter type of \"%s\' of net \'%s\' not supported\n", pId.c_str(ctx),
net->name.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) if (json_debug)
log_info(" Added parameter \'%s\'=%s to net \'%s\' " log_info(" Added parameter \'%s\'=%s to net \'%s\' "
"of module \'%s\'\n", "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_info("Checksum: 0x%08x\n", ctx->checksum());
log_break(); log_break();
ctx->settings.emplace(ctx->id("input/json"), filename); ctx->settings.emplace(ctx->id("input/json"), filename);
ctx->attributesToCommonInfo();
return true; return true;
} catch (log_execution_error_exception) { } catch (log_execution_error_exception) {
return false; return false;

View File

@ -48,7 +48,7 @@ std::string get_name(IdString name, Context *ctx)
return get_string(name.c_str(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; bool first = true;
for (auto &param : parameters) { 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; f << param.second.num;
first = false; 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) 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); write_parameters(f, ctx, c->params);
f << stringf("\n },\n"); f << stringf("\n },\n");
f << stringf(" \"attributes\": {"); f << stringf(" \"attributes\": {");
bool first3 = write_parameters(f, ctx, c->attrs); write_parameters(f, ctx, c->attrs);
write_constraints(f, ctx, c.get(), first3);
f << stringf("\n },\n"); f << stringf("\n },\n");
f << stringf(" \"port_directions\": {"); f << stringf(" \"port_directions\": {");
bool first2 = true; 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(" \"hide_name\": %s,\n", w->name.c_str(ctx)[0] == '$' ? "1" : "0");
f << stringf(" \"bits\": [ %d ] ,\n", pair.first.index); f << stringf(" \"bits\": [ %d ] ,\n", pair.first.index);
f << stringf(" \"attributes\": {"); f << stringf(" \"attributes\": {");
bool first2 = write_parameters(f, ctx, w->attrs); write_parameters(f, ctx, w->attrs);
write_routing(f, ctx, w.get(), first2);
f << stringf("\n }\n"); f << stringf("\n }\n");
f << stringf(" }"); f << stringf(" }");
first = false; first = false;