diff options
author | Clifford Wolf <clifford@clifford.at> | 2013-03-07 18:51:17 +0100 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2013-03-07 18:51:17 +0100 |
commit | bf3a3b9589b089d3f31f4e994b80566b741006bd (patch) | |
tree | 6778b8bd1c3ce7062be718872dab6f07461581c2 | |
parent | ed1ddea83b13127afe99ec3d8dbf3ecf445cca6c (diff) | |
download | yosys-bf3a3b9589b089d3f31f4e994b80566b741006bd.tar.gz yosys-bf3a3b9589b089d3f31f4e994b80566b741006bd.tar.bz2 yosys-bf3a3b9589b089d3f31f4e994b80566b741006bd.zip |
Added support for attribute matching in extract pass
-rw-r--r-- | passes/extract/extract.cc | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/passes/extract/extract.cc b/passes/extract/extract.cc index 320f812ea..4909126a7 100644 --- a/passes/extract/extract.cc +++ b/passes/extract/extract.cc @@ -31,6 +31,58 @@ using RTLIL::id2cstr; namespace { + class SubCircuitSolver : public SubCircuit::Solver + { + public: + std::set<RTLIL::IdString> attr_compare; + + bool compareAttributes(const std::map<RTLIL::IdString, RTLIL::Const> &needleAttr, const std::map<RTLIL::IdString, RTLIL::Const> &haystackAttr) + { + for (auto &it : attr_compare) { + size_t nc = needleAttr.count(it), hc = haystackAttr.count(it); + if (nc != hc || (nc > 0 && needleAttr.at(it) != haystackAttr.at(it))) + return false; + } + return true; + } + + virtual bool userCompareNodes(const std::string &, const std::string &, void *needleUserData, + const std::string &, const std::string &, void *haystackUserData, const std::map<std::string, std::string> &portMapping) + { + if (attr_compare.size() == 0) + return true; + + RTLIL::Cell *needleCell = (RTLIL::Cell*) needleUserData; + RTLIL::Cell *haystackCell = (RTLIL::Cell*) haystackUserData; + + if (!compareAttributes(needleCell->attributes, haystackCell->attributes)) + return false; + + RTLIL::Wire *lastNeedleWire = NULL; + RTLIL::Wire *lastHaystackWire = NULL; + std::map<RTLIL::IdString, RTLIL::Const> emptyAttr; + + for (auto &conn : needleCell->connections) + { + RTLIL::SigSpec needleSig = conn.second; + RTLIL::SigSpec haystackSig = haystackCell->connections.at(portMapping.at(conn.first)); + + needleSig.expand(); + haystackSig.expand(); + + for (int i = 0; i < std::min(needleSig.width, haystackSig.width); i++) { + RTLIL::Wire *needleWire = needleSig.chunks.at(i).wire, *haystackWire = haystackSig.chunks.at(i).wire; + if (needleWire != lastNeedleWire || haystackWire != lastHaystackWire) + if (!compareAttributes(needleWire ? needleWire->attributes : emptyAttr, haystackWire ? haystackWire->attributes : emptyAttr)) + return false; + lastNeedleWire = needleWire, lastHaystackWire = haystackWire; + } + } + + return true; + } + }; + struct bit_ref_t { std::string cell, port; int bit; @@ -288,6 +340,9 @@ struct ExtractPass : public Pass { log(" Register a valid permutation of swapable ports for a needle\n"); log(" cell type. This option can be used multiple times.\n"); log("\n"); + log(" -attr <attribute_name>\n"); + log(" Attributes with the given name must match (cells and wires).\n"); + log("\n"); log("This pass does not operate on modules with uprocessed processes in it.\n"); log("(I.e. the 'proc' pass should be used first to convert processes to netlists.)\n"); log("\n"); @@ -324,7 +379,7 @@ struct ExtractPass : public Pass { log_header("Executing EXTRACT pass (map subcircuits to cells).\n"); log_push(); - SubCircuit::Solver solver; + SubCircuitSolver solver; std::string filename; bool constports = false; @@ -422,6 +477,10 @@ struct ExtractPass : public Pass { solver.addSwappablePortsPermutation(type, map); continue; } + if (args[argidx] == "-attr" && argidx+1 < args.size()) { + solver.attr_compare.insert(RTLIL::escape_id(args[++argidx])); + continue; + } break; } extra_args(args, argidx, design); |