mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
Annotate logic depth
This commit is contained in:
parent
47aac95f64
commit
bf96f94267
3 changed files with 150 additions and 2 deletions
130
passes/cmds/annotate_logic_depth.cc
Normal file
130
passes/cmds/annotate_logic_depth.cc
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
*
|
||||
* 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 "kernel/celltypes.h"
|
||||
#include "kernel/sigtools.h"
|
||||
#include "kernel/utils.h"
|
||||
#include "kernel/yosys.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
typedef RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell> cell_ptr_cmp;
|
||||
|
||||
struct AnnotateLogicDepth : public ScriptPass {
|
||||
AnnotateLogicDepth() : ScriptPass("annotate_logic_depth", "Annotate logic depth per cells and modules") {}
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" annotate_logic_depth [-module] [-cell]\n");
|
||||
log("\n");
|
||||
}
|
||||
void script() override {}
|
||||
|
||||
// Adapted from the torder pass
|
||||
void toposorting(std::vector<Cell *> &cells, SigMap &sigmap,
|
||||
TopoSort<RTLIL::Cell *, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> &toposort)
|
||||
{
|
||||
dict<SigBit, pool<Cell *>> bit_drivers, bit_users;
|
||||
for (Cell *cell : cells) {
|
||||
for (auto conn : cell->connections()) {
|
||||
bool noautostop = false;
|
||||
if (!noautostop && yosys_celltypes.cell_known(cell->type)) {
|
||||
if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA))
|
||||
continue;
|
||||
if (cell->type.in(ID($memrd), ID($memrd_v2)) && conn.first == ID::DATA)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell->input(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
bit_users[bit].insert(cell);
|
||||
|
||||
if (cell->output(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
bit_drivers[bit].insert(cell);
|
||||
|
||||
toposort.node(cell);
|
||||
}
|
||||
}
|
||||
for (auto &it : bit_users)
|
||||
if (bit_drivers.count(it.first))
|
||||
for (auto driver_cell : bit_drivers.at(it.first))
|
||||
for (auto user_cell : it.second)
|
||||
toposort.edge(driver_cell, user_cell);
|
||||
|
||||
toposort.analyze_loops = false;
|
||||
toposort.sort();
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
if (design == nullptr) {
|
||||
log_error("No design object");
|
||||
return;
|
||||
}
|
||||
size_t argidx;
|
||||
bool annotate_modules = false;
|
||||
bool annotate_cells = false;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-module") {
|
||||
annotate_modules = true;
|
||||
} else if (args[argidx] == "-cell") {
|
||||
annotate_cells = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
int design_max_depth = 0;
|
||||
for (auto module : design->selected_modules()) {
|
||||
int module_max_depth = 0;
|
||||
SigMap sigmap(module);
|
||||
std::vector<Cell *> cells;
|
||||
std::map<RTLIL::Cell *, int> celllevel;
|
||||
for (auto cell : module->selected_cells()) {
|
||||
cells.push_back(cell);
|
||||
celllevel.emplace(cell, 0);
|
||||
}
|
||||
TopoSort<RTLIL::Cell *, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> toposort;
|
||||
toposorting(cells, sigmap, toposort);
|
||||
std::map<RTLIL::Cell *, std::set<RTLIL::Cell *, cell_ptr_cmp>, cell_ptr_cmp> topo_cell_drivers = toposort.get_database();
|
||||
for (auto cell : toposort.sorted) {
|
||||
int level = 0;
|
||||
auto itrAdj = topo_cell_drivers.find(cell);
|
||||
for (auto c : (*itrAdj).second) {
|
||||
level = std::max(level, celllevel[c]);
|
||||
}
|
||||
level++;
|
||||
celllevel[cell] = level;
|
||||
module_max_depth = std::max(module_max_depth, level);
|
||||
if (annotate_cells)
|
||||
cell->set_string_attribute("$DEPTH", std::to_string(level));
|
||||
}
|
||||
design_max_depth = std::max(design_max_depth, module_max_depth);
|
||||
if (annotate_modules)
|
||||
module->set_string_attribute("$MAX_DEPTH", std::to_string(module_max_depth));
|
||||
}
|
||||
design->top_module()->set_string_attribute("$DESIGN_MAX_DEPTH", std::to_string(design_max_depth));
|
||||
log("Max logic depth: %d\n", design_max_depth);
|
||||
}
|
||||
} AnnotateLogicDepth;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
|
@ -25,6 +25,8 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
typedef RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell> cell_ptr_cmp;
|
||||
|
||||
struct LongLoopSelect : public ScriptPass {
|
||||
LongLoopSelect()
|
||||
: ScriptPass("longloop_select", "Selects long for-loops (Creating logic above a certain logic depth) for further optimizations")
|
||||
|
@ -178,10 +180,26 @@ struct LongLoopSelect : public ScriptPass {
|
|||
}
|
||||
// For a given for-loop cell group, perform topological sorting to get the logic depth of the ending cell in
|
||||
// the group
|
||||
std::map<RTLIL::Cell *, int> celllevel;
|
||||
for (auto cell : itrCluster->second) {
|
||||
celllevel.emplace(cell, 0);
|
||||
}
|
||||
TopoSort<RTLIL::Cell *, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> toposort;
|
||||
toposorting(itrCluster->second, sigmap, toposort, debug);
|
||||
std::vector<Cell *>::reverse_iterator itrLastCell = toposort.sorted.rbegin();
|
||||
int logicdepth = toposort.node_to_index.find((*itrLastCell))->second;
|
||||
int logicdepth = 0;
|
||||
std::map<RTLIL::Cell *, std::set<RTLIL::Cell *, cell_ptr_cmp>, cell_ptr_cmp> topo_cell_drivers =
|
||||
toposort.get_database();
|
||||
for (auto cell : toposort.sorted) {
|
||||
int level = 0;
|
||||
auto itrAdj = topo_cell_drivers.find(cell);
|
||||
for (auto c : (*itrAdj).second) {
|
||||
level = std::max(level, celllevel[c]);
|
||||
}
|
||||
level++;
|
||||
celllevel[cell] = level;
|
||||
logicdepth = std::max(logicdepth, level);
|
||||
}
|
||||
if (debug) {
|
||||
log(" Logic depth: %d\n", logicdepth);
|
||||
log_flush();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue