common: Add JSON timing and utilisation report
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
4ac00af6fa
commit
d2007a386c
@ -173,6 +173,9 @@ po::options_description CommandHandler::getGeneralOptions()
|
||||
general.add_options()("router2-heatmap", po::value<std::string>(),
|
||||
"prefix for router2 resource congestion heatmaps");
|
||||
|
||||
general.add_options()("report", po::value<std::string>(),
|
||||
"write timing and utilization report in JSON format to file");
|
||||
|
||||
general.add_options()("placed-svg", po::value<std::string>(), "write render of placement to SVG file");
|
||||
general.add_options()("routed-svg", po::value<std::string>(), "write render of routing to SVG file");
|
||||
|
||||
@ -424,6 +427,14 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
|
||||
ctx->writeSDF(f, vm.count("sdf-cvc"));
|
||||
}
|
||||
|
||||
if (vm.count("report")) {
|
||||
std::string filename = vm["report"].as<std::string>();
|
||||
std::ofstream f(filename);
|
||||
if (!f)
|
||||
log_error("Failed to open report file '%s' for writing.\n", filename.c_str());
|
||||
ctx->writeReport(f);
|
||||
}
|
||||
|
||||
#ifndef NO_PYTHON
|
||||
deinit_python();
|
||||
#endif
|
||||
|
@ -76,6 +76,10 @@ struct Context : Arch, DeterministicRNG
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// provided by report.cc
|
||||
void writeReport(std::ostream &out) const;
|
||||
// --------------------------------------------------------------
|
||||
|
||||
uint32_t checksum() const;
|
||||
|
||||
void check() const;
|
||||
|
68
common/report.cc
Normal file
68
common/report.cc
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* nextpnr -- Next Generation Place and Route
|
||||
*
|
||||
* Copyright (C) 2021 gatecat <gatecat@ds0.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "json11.hpp"
|
||||
#include "nextpnr.h"
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
using namespace json11;
|
||||
|
||||
namespace {
|
||||
dict<IdString, std::pair<int, int>> get_utilization(const Context *ctx)
|
||||
{
|
||||
// Sort by Bel type
|
||||
dict<IdString, std::pair<int, int>> result;
|
||||
for (auto &cell : ctx->cells) {
|
||||
result[ctx->getBelBucketName(ctx->getBelBucketForCellType(cell.second.get()->type))].first++;
|
||||
}
|
||||
for (auto bel : ctx->getBels()) {
|
||||
if (!ctx->getBelHidden(bel)) {
|
||||
result[ctx->getBelBucketName(ctx->getBelBucketForBel(bel))].second++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
void Context::writeReport(std::ostream &out) const
|
||||
{
|
||||
auto util = get_utilization(this);
|
||||
dict<std::string, Json> util_json;
|
||||
for (const auto &kv : util) {
|
||||
util_json[kv.first.str(this)] = Json::object{
|
||||
{"used", kv.second.first},
|
||||
{"available", kv.second.second},
|
||||
};
|
||||
}
|
||||
dict<std::string, Json> fmax_json;
|
||||
for (const auto &kv : timing_result.clock_fmax) {
|
||||
fmax_json[kv.first.str(this)] = Json::object{
|
||||
{"achieved", kv.second.achieved},
|
||||
{"constraint", kv.second.constraint},
|
||||
};
|
||||
}
|
||||
out << Json(Json::object{
|
||||
{"utilization", util_json},
|
||||
{"fmax", fmax_json},
|
||||
})
|
||||
.dump()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
22
docs/report.md
Normal file
22
docs/report.md
Normal file
@ -0,0 +1,22 @@
|
||||
# JSON Reports
|
||||
|
||||
nextpnr can write a JSON report using `--report` post-place-and-route for integration with other build systems. It contains information on post-pack utilization and maximum achieved frequency for each clock domain, and is of the following format:
|
||||
|
||||
```
|
||||
{
|
||||
"utilization": {
|
||||
<beltype>: {
|
||||
"used": <number of bels used in design>,
|
||||
"available": <total number of bels available in device>
|
||||
},
|
||||
...
|
||||
},
|
||||
"fmax": {
|
||||
<clock domain>: {
|
||||
"achieved": <computed Fmax of routed design for clock in MHz>,
|
||||
"constraint": <constraint for clock in MHz>
|
||||
},
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue
Block a user