445 log_header(
"Executing EXTRACT pass (map subcircuits to cells).\n");
450 std::vector<std::string> map_filenames;
451 std::string mine_outfile;
452 bool constports =
false;
453 bool nodefaultswaps =
false;
455 bool mine_mode =
false;
456 int mine_cells_min = 3;
457 int mine_cells_max = 5;
458 int mine_min_freq = 10;
459 int mine_limit_mod = -1;
460 int mine_max_fanout = -1;
461 std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> mine_split;
464 for (argidx = 1; argidx <
args.size(); argidx++) {
465 if (
args[argidx] ==
"-map" && argidx+1 <
args.size()) {
468 map_filenames.push_back(
args[++argidx]);
471 if (
args[argidx] ==
"-mine" && argidx+1 <
args.size()) {
472 if (!map_filenames.empty())
474 mine_outfile =
args[++argidx];
478 if (
args[argidx] ==
"-mine_cells_span" && argidx+2 <
args.size()) {
479 mine_cells_min = atoi(
args[++argidx].c_str());
480 mine_cells_max = atoi(
args[++argidx].c_str());
483 if (
args[argidx] ==
"-mine_min_freq" && argidx+1 <
args.size()) {
484 mine_min_freq = atoi(
args[++argidx].c_str());
487 if (
args[argidx] ==
"-mine_limit_matches_per_module" && argidx+1 <
args.size()) {
488 mine_limit_mod = atoi(
args[++argidx].c_str());
491 if (
args[argidx] ==
"-mine_split" && argidx+2 <
args.size()) {
496 if (
args[argidx] ==
"-mine_max_fanout" && argidx+1 <
args.size()) {
497 mine_max_fanout = atoi(
args[++argidx].c_str());
500 if (
args[argidx] ==
"-verbose") {
504 if (
args[argidx] ==
"-constports") {
508 if (
args[argidx] ==
"-nodefaultswaps") {
509 nodefaultswaps =
true;
512 if (
args[argidx] ==
"-compat" && argidx+2 <
args.size()) {
518 if (
args[argidx] ==
"-swap" && argidx+2 <
args.size()) {
520 std::set<std::string> ports;
521 std::string ports_str =
args[++argidx], p;
522 while (!(p =
next_token(ports_str,
",\t\r\n ")).empty())
527 if (
args[argidx] ==
"-perm" && argidx+3 <
args.size()) {
529 std::vector<std::string> map_left, map_right;
530 std::string left_str =
args[++argidx];
531 std::string right_str =
args[++argidx], p;
532 while (!(p =
next_token(left_str,
",\t\r\n ")).empty())
534 while (!(p =
next_token(right_str,
",\t\r\n ")).empty())
536 if (map_left.size() != map_right.size())
537 log_cmd_error(
"Arguments to -perm are not a valid permutation!\n");
538 std::map<std::string, std::string> map;
539 for (
size_t i = 0; i < map_left.size(); i++)
540 map[map_left[i]] = map_right[i];
541 std::sort(map_left.begin(), map_left.end());
542 std::sort(map_right.begin(), map_right.end());
543 if (map_left != map_right)
544 log_cmd_error(
"Arguments to -perm are not a valid permutation!\n");
548 if (
args[argidx] ==
"-cell_attr" && argidx+1 <
args.size()) {
552 if (
args[argidx] ==
"-wire_attr" && argidx+1 <
args.size()) {
556 if (
args[argidx] ==
"-ignore_parameters") {
560 if (
args[argidx] ==
"-ignore_param" && argidx+2 <
args.size()) {
569 if (!nodefaultswaps) {
587 if (map_filenames.empty() && mine_outfile.empty())
588 log_cmd_error(
"Missing option -map <verilog_or_ilang_file> or -mine <output_ilang_file>.\n");
595 for (
auto &filename : map_filenames)
597 if (filename.substr(0, 1) ==
"%")
601 log_cmd_error(
"Can't saved design `%s'.\n", filename.c_str()+1);
603 for (
auto mod :
saved_designs.at(filename.substr(1))->modules())
604 if (!map->
has(mod->name))
605 map->
add(mod->clone());
610 f.open(filename.c_str());
613 log_cmd_error(
"Can't open map file `%s'.\n", filename.c_str());
615 Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) ==
".il") ?
"ilang" :
"verilog");
618 if (filename.size() <= 3 || filename.substr(filename.size()-3) !=
".il") {
626 std::map<std::string, RTLIL::Module*> needle_map, haystack_map;
627 std::vector<RTLIL::Module*> needle_list;
629 log_header(
"Creating graphs for SubCircuit library.\n");
632 for (
auto &mod_it : map->
modules_) {
635 log(
"Creating needle graph %s.\n", graph_name.c_str());
636 if (
module2graph(mod_graph, mod_it.second, constports)) {
637 solver.
addGraph(graph_name, mod_graph);
638 needle_map[graph_name] = mod_it.second;
639 needle_list.push_back(mod_it.second);
643 for (
auto &mod_it : design->
modules_) {
646 log(
"Creating haystack graph %s.\n", graph_name.c_str());
647 if (
module2graph(mod_graph, mod_it.second, constports, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split :
NULL)) {
648 solver.
addGraph(graph_name, mod_graph);
649 haystack_map[graph_name] = mod_it.second;
655 std::vector<SubCircuit::Solver::Result> results;
656 log_header(
"Running solver from SubCircuit library.\n");
660 for (
auto needle : needle_list)
661 for (
auto &haystack_it : haystack_map) {
662 log(
"Solving for %s in %s.\n", (
"needle_" +
RTLIL::unescape_id(needle->name)).c_str(), haystack_it.first.c_str());
667 if (results.size() > 0)
669 log_header(
"Substitute SubCircuits with cells.\n");
671 for (
int i = 0; i < int(results.size()); i++) {
672 auto &result = results[i];
673 log(
"\nMatch #%d: (%s in %s)\n", i, result.needleGraphId.c_str(), result.haystackGraphId.c_str());
674 for (
const auto &it : result.mappings) {
675 log(
" %s -> %s", it.first.c_str(), it.second.haystackNodeId.c_str());
676 for (
const auto & it2 : it.second.portMapping)
677 log(
" %s:%s", it2.first.c_str(), it2.second.c_str());
680 RTLIL::Cell *new_cell =
replace(needle_map.at(result.needleGraphId), haystack_map.at(result.haystackGraphId), result);
681 design->
select(haystack_map.at(result.haystackGraphId), new_cell);
688 std::vector<SubCircuit::Solver::MineResult> results;
690 log_header(
"Running miner from SubCircuit library.\n");
691 solver.
mine(results, mine_cells_min, mine_cells_max, mine_min_freq, mine_limit_mod);
695 int needleCounter = 0;
696 for (
auto &result: results)
698 log(
"\nFrequent SubCircuit with %d nodes and %d matches:\n",
int(result.nodes.size()), result.totalMatchesAfterLimits);
699 log(
" primary match in %s:",
id2cstr(haystack_map.at(result.graphId)->name));
700 for (
auto &node : result.nodes)
703 for (
auto &it : result.matchesPerGraph)
704 log(
" matches in %s: %d\n",
id2cstr(haystack_map.at(it.first)->name), it.second);
707 std::set<RTLIL::Cell*> cells;
708 std::set<RTLIL::Wire*> wires;
712 for (
auto &node : result.nodes)
715 for (
auto cell : cells)
716 for (
auto &conn : cell->connections()) {
718 for (
auto &chunk : sig.
chunks())
719 if (chunk.wire != NULL)
720 wires.insert(chunk.wire);
724 newMod->
name =
stringf(
"\\needle%05d_%s_%dx", needleCounter++,
id2cstr(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits);
727 for (
auto wire : wires) {
735 for (
auto cell : cells) {
738 for (
auto &conn : cell->connections()) {
739 std::vector<RTLIL::SigChunk> chunks = sigmap(conn.second);
740 for (
auto &chunk : chunks)
741 if (chunk.wire != NULL)
742 chunk.wire = newMod->
wires_.at(chunk.wire->name);
743 newCell->
setPort(conn.first, chunks);
749 f.open(mine_outfile.c_str(), std::ofstream::trunc);
751 log_error(
"Can't open output file `%s'.\n", mine_outfile.c_str());
static std::string next_token(bool pass_newline=false)
std::set< RTLIL::IdString > wire_attr
std::string stringf(const char *fmt,...)
void sort(T *array, int size, LessThan lt)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void add(RTLIL::Module *module)
std::set< RTLIL::IdString > cell_attr
void log_header(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
static std::string unescape_id(std::string str)
static void frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::string command)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
void addSwappablePorts(std::string needleTypeId, std::string portId1, std::string portId2, std::string portId3=std::string(), std::string portId4=std::string())
void log_error(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Const > parameters
void select(T1 *module, T2 *member)
static std::string escape_id(std::string str)
void solve(std::vector< Result > &results, std::string needleGraphId, std::string haystackGraphId, bool allowOverlap=true, int maxSolutions=-1)
std::map< std::string, RTLIL::Design * > saved_designs
static void backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::string command)
void addGraph(std::string graphId, const Graph &graph)
int GetSize(RTLIL::Wire *wire)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
void addSwappablePortsPermutation(std::string needleTypeId, std::map< std::string, std::string > portMapping)
void mine(std::vector< MineResult > &results, int minNodes, int maxNodes, int minMatches, int limitMatchesPerGraph=-1)
static const char * id2cstr(const RTLIL::IdString &str)
void log_cmd_error(const char *format,...)
std::set< std::pair< RTLIL::IdString, RTLIL::IdString > > ignored_parameters
bool has(RTLIL::IdString id) const
std::map< RTLIL::IdString, RTLIL::Module * > modules_
void log(const char *format,...)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
static void call(RTLIL::Design *design, std::string command)
void addCompatibleTypes(std::string needleTypeId, std::string haystackTypeId)
const std::vector< RTLIL::SigChunk > & chunks() const