aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/nextpnr.h3
-rw-r--r--ecp5/arch.cc2
-rw-r--r--ecp5/pack.cc1
-rw-r--r--generic/arch.cc12
-rw-r--r--generic/pack.cc1
-rw-r--r--ice40/arch.cc2
-rw-r--r--ice40/pack.cc1
-rw-r--r--json/jsonparse.cc30
-rw-r--r--json/jsonwrite.cc8
9 files changed, 55 insertions, 5 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h
index 8e47dcda..3b17920d 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -550,6 +550,9 @@ struct BaseCtx
// Floorplanning regions
std::unordered_map<IdString, std::unique_ptr<Region>> region;
+ // Context meta data
+ std::unordered_map<IdString, Property> attrs;
+
BaseCtx()
{
idstring_str_to_idx = new std::unordered_map<std::string, int>;
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index e796c9db..2061bf4a 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -524,6 +524,7 @@ bool Arch::place()
}
permute_luts();
+ getCtx()->attrs[getCtx()->id("step")] = "place";
archInfoToAttributes();
return true;
}
@@ -560,6 +561,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
+ getCtx()->attrs[getCtx()->id("step")] = "route";
archInfoToAttributes();
return result;
}
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 20130aad..4077bfed 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -2429,6 +2429,7 @@ bool Arch::pack()
Ecp5Packer(ctx).pack();
log_info("Checksum: 0x%08x\n", ctx->checksum());
assignArchInfo();
+ ctx->attrs[ctx->id("step")] = "pack";
archInfoToAttributes();
return true;
} catch (log_execution_error_exception) {
diff --git a/generic/arch.cc b/generic/arch.cc
index 5617fa63..f6f7ff87 100644
--- a/generic/arch.cc
+++ b/generic/arch.cc
@@ -496,13 +496,21 @@ bool Arch::place()
std::string placer = str_or_default(settings, id("placer"), defaultPlacer);
// FIXME: No HeAP because it needs a list of IO buffers
if (placer == "sa") {
- return placer1(getCtx(), Placer1Cfg(getCtx()));
+ bool retVal = placer1(getCtx(), Placer1Cfg(getCtx()));
+ getCtx()->attrs[getCtx()->id("step")] = "place";
+ archInfoToAttributes();
+ return retVal;
} else {
log_error("Generic architecture does not support placer '%s'\n", placer.c_str());
}
}
-bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
+bool Arch::route() {
+ bool retVal = router1(getCtx(), Router1Cfg(getCtx()));
+ getCtx()->attrs[getCtx()->id("step")] = "route";
+ archInfoToAttributes();
+ return retVal;
+}
// ---------------------------------------------------------------
diff --git a/generic/pack.cc b/generic/pack.cc
index 26ae9182..0d47ea19 100644
--- a/generic/pack.cc
+++ b/generic/pack.cc
@@ -282,6 +282,7 @@ bool Arch::pack()
pack_io(ctx);
pack_lut_lutffs(ctx);
pack_nonlut_ffs(ctx);
+ ctx->attrs[ctx->id("step")] = "pack";
ctx->assignArchInfo();
log_info("Checksum: 0x%08x\n", ctx->checksum());
return true;
diff --git a/ice40/arch.cc b/ice40/arch.cc
index b7207ca9..4945f5b3 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -689,12 +689,14 @@ bool Arch::place()
tocfg.cellTypes.insert(id_ICESTORM_LC);
retVal = timing_opt(getCtx(), tocfg);
}
+ getCtx()->attrs[getCtx()->id("step")] = "place";
archInfoToAttributes();
return retVal;
}
bool Arch::route() {
bool retVal = router1(getCtx(), Router1Cfg(getCtx()));
+ getCtx()->attrs[getCtx()->id("step")] = "route";
archInfoToAttributes();
return retVal;
}
diff --git a/ice40/pack.cc b/ice40/pack.cc
index 0a62a5ca..ce39c903 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -1421,6 +1421,7 @@ bool Arch::pack()
ctx->assignArchInfo();
constrain_chains(ctx);
ctx->assignArchInfo();
+ ctx->attrs[ctx->id("step")] = "pack";
archInfoToAttributes();
log_info("Checksum: 0x%08x\n", ctx->checksum());
return true;
diff --git a/json/jsonparse.cc b/json/jsonparse.cc
index 1ff4f5af..a36f891d 100644
--- a/json/jsonparse.cc
+++ b/json/jsonparse.cc
@@ -355,6 +355,27 @@ void json_import_net_attrib(Context *ctx, string &modname, NetInfo *net, JsonNod
pId.c_str(ctx), net->attrs[pId].c_str(), net->name.c_str(ctx), modname.c_str());
}
+void json_import_top_attrib(Context *ctx, string &modname, JsonNode *param_node,
+ std::unordered_map<IdString, Property> *dest, int param_id)
+{
+ //
+ JsonNode *param;
+ IdString pId;
+ //
+ param = param_node->data_dict.at(param_node->data_dict_keys[param_id]);
+
+ pId = ctx->id(param_node->data_dict_keys[param_id]);
+ if (param->type == 'N') {
+ (*dest)[pId].setNumber(param->data_number);
+ } else if (param->type == 'S')
+ (*dest)[pId].setString(param->data_string);
+ else
+ log_error("JSON parameter type of \"%s\' of module not supported\n", pId.c_str(ctx));
+ if (json_debug)
+ log_info(" Added parameter \'%s\'=%s module \'%s\'\n",
+ pId.c_str(ctx), (*dest)[pId].c_str(), modname.c_str());
+}
+
static int const_net_idx = 0;
template <typename F>
@@ -714,7 +735,14 @@ void json_import(Context *ctx, string modname, JsonNode *node)
return;
log_info("Importing module %s\n", modname.c_str());
-
+ ctx->attrs[ctx->id("module")] = modname;
+ JsonNode *attr_node = node->data_dict.at("attributes");
+ for (int attrid = 0; attrid < GetSize(attr_node->data_dict_keys); attrid++) {
+ json_import_top_attrib(ctx, modname, attr_node, &ctx->attrs, attrid);
+ }
+ if (ctx->attrs.find(ctx->id("step")) == ctx->attrs.end())
+ ctx->attrs[ctx->id("step")] = "synth";
+
JsonNode *ports_parent = nullptr;
if (node->data_dict.count("ports") > 0)
ports_parent = node->data_dict.at("ports");
diff --git a/json/jsonwrite.cc b/json/jsonwrite.cc
index 811a2eec..19c43d7c 100644
--- a/json/jsonwrite.cc
+++ b/json/jsonwrite.cc
@@ -64,13 +64,17 @@ void write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<Id
void write_module(std::ostream &f, Context *ctx)
{
- f << stringf(" %s: {\n", get_string("top").c_str());
+ auto val = ctx->attrs.find(ctx->id("module"));
+ if (val != ctx->attrs.end())
+ f << stringf(" %s: {\n", get_string(val->second.str).c_str());
+ else
+ f << stringf(" %s: {\n", get_string("top").c_str());
// TODO: check if this is better to be separate
/*f << stringf(" \"settings\": {");
write_parameters(f, ctx, ctx->settings, true);
f << stringf("\n },\n");*/
f << stringf(" \"attributes\": {");
- // TODO: Top level attributes
+ write_parameters(f, ctx, ctx->attrs, true);
f << stringf("\n },\n");
f << stringf(" \"ports\": {");
// TODO: Top level ports