From 1093d7e1228272ca73114bbc4415c48d6cba76ed Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 7 Jun 2019 11:48:15 +0200 Subject: WIP saving/loading attributes --- common/command.cc | 51 +------------------------------------- common/nextpnr.cc | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ common/nextpnr.h | 3 +++ ecp5/arch.cc | 17 +++++++++++++ ecp5/arch.h | 2 ++ ecp5/pack.cc | 1 + generic/arch.cc | 11 +++++++++ generic/arch.h | 2 ++ ice40/arch.cc | 24 +++++++++++++++--- ice40/arch.h | 2 ++ ice40/pack.cc | 1 + json/jsonparse.cc | 6 +---- json/jsonwrite.cc | 74 +++---------------------------------------------------- 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 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 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 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 &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 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 ¶meters, bool for_module=false) +void write_parameters(std::ostream &f, Context *ctx, const std::unordered_map ¶meters, bool for_module=false) { bool first = true; for (auto ¶m : parameters) { @@ -60,72 +60,6 @@ bool write_parameters(std::ostream &f, Context *ctx, const std::unordered_mapwires) { - 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; -- cgit v1.2.3