From d9b0bac248a12466cd2b62d02ec11b2e60d25019 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 7 Jun 2019 16:11:11 +0200 Subject: Save top level attrs and store current step --- common/nextpnr.h | 3 +++ ecp5/arch.cc | 2 ++ ecp5/pack.cc | 1 + generic/arch.cc | 12 ++++++++++-- generic/pack.cc | 1 + ice40/arch.cc | 2 ++ ice40/pack.cc | 1 + json/jsonparse.cc | 30 +++++++++++++++++++++++++++++- json/jsonwrite.cc | 8 ++++++-- 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> region; + // Context meta data + std::unordered_map attrs; + BaseCtx() { idstring_str_to_idx = new std::unordered_map; 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 *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 @@ -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_mapattrs.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 -- cgit v1.2.3