WIP saving/loading attributes
This commit is contained in:
parent
3ae50f85b1
commit
1093d7e122
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
17
ecp5/arch.cc
17
ecp5/arch.cc
@ -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
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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> ¶meters, bool for_module=false)
|
void write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<IdString, Property> ¶meters, bool for_module=false)
|
||||||
{
|
{
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto ¶m : parameters) {
|
for (auto ¶m : 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;
|
||||||
|
Loading…
Reference in New Issue
Block a user