mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-18 06:39:03 +00:00
Merge 5c77c73888
into 733487e730
This commit is contained in:
commit
99be5df02b
|
@ -103,6 +103,8 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO: add an optional check to make sure the port-assignment is in one continous block, not in chunks
|
||||
|
||||
if (!ignore_parameters) {
|
||||
std::map<RTLIL::IdString, RTLIL::Const> needle_param, haystack_param;
|
||||
for (auto &it : needleCell->parameters)
|
||||
|
@ -148,7 +150,7 @@ struct bit_ref_t {
|
|||
int bit;
|
||||
};
|
||||
|
||||
bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, RTLIL::Design *sel = nullptr,
|
||||
bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, int min_port_width = -1, RTLIL::Design *sel = nullptr,
|
||||
int max_fanout = -1, std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> *split = nullptr)
|
||||
{
|
||||
SigMap sigmap(mod);
|
||||
|
@ -206,7 +208,7 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
|
|||
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
graph.createPort(cell->name.str(), conn.first.str(), conn.second.size());
|
||||
graph.createPort(cell->name.str(), conn.first.str(), conn.second.size(), min_port_width);
|
||||
|
||||
if (split && split->count(std::pair<RTLIL::IdString, RTLIL::IdString>(cell->type, conn.first)) > 0)
|
||||
continue;
|
||||
|
@ -286,7 +288,7 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
|
|||
return true;
|
||||
}
|
||||
|
||||
RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit::Solver::Result &match)
|
||||
RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit::Solver::Result &match, bool minimize_port_width=false)
|
||||
{
|
||||
SigMap sigmap(needle);
|
||||
SigSet<std::pair<RTLIL::IdString, int>> sig2port;
|
||||
|
@ -296,10 +298,12 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
|
|||
|
||||
// create cell ports
|
||||
for (auto wire : needle->wires()) {
|
||||
// for all ports in the needle module
|
||||
if (wire->port_id > 0) {
|
||||
cell->setPort(wire->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width));
|
||||
// remember all bits
|
||||
for (int i = 0; i < wire->width; i++)
|
||||
sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair<RTLIL::IdString, int>(wire->name, i));
|
||||
cell->setPort(wire->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,21 +318,60 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
|
|||
continue;
|
||||
|
||||
for (auto &conn : needle_cell->connections()) {
|
||||
RTLIL::SigSpec sig = sigmap(conn.second);
|
||||
if (mapping.portMapping.count(conn.first.str()) > 0 && sig2port.has(sigmap(sig))) {
|
||||
for (int i = 0; i < sig.size(); i++)
|
||||
for (auto &port : sig2port.find(sig[i])) {
|
||||
RTLIL::SigSpec bitsig = haystack_cell->getPort(mapping.portMapping[conn.first.str()]).extract(i, 1);
|
||||
RTLIL::SigSpec new_sig = cell->getPort(port.first);
|
||||
new_sig.replace(port.second, bitsig);
|
||||
cell->setPort(port.first, new_sig);
|
||||
RTLIL::SigSpec nsig = sigmap(conn.second);
|
||||
std::string nsig_name = conn.first.str();
|
||||
// if it is a mapped port and connects to a wire/port in the needle module
|
||||
if (mapping.portMapping.count(nsig_name) > 0 && sig2port.has(sigmap(nsig))) {
|
||||
RTLIL::IdString hport_name = mapping.portMapping[nsig_name];
|
||||
|
||||
// copy signed-ness from haystack to new needle cell
|
||||
RTLIL::IdString nconn_sgn = RTLIL::escape_id(nsig_name + "_SIGNED");
|
||||
if(haystack_cell->hasParam(RTLIL::escape_id(hport_name.str() + "_SIGNED"))) {
|
||||
cell->setParam(nconn_sgn, haystack_cell->getParam(RTLIL::escape_id(hport_name.str() + "_SIGNED")));
|
||||
} else {
|
||||
cell->setParam(nconn_sgn, 0);
|
||||
}
|
||||
// add and connect ports
|
||||
RTLIL::SigSpec hsig = haystack_cell->getPort(hport_name);
|
||||
|
||||
for (int i = 0; i < nsig.size() && i < hsig.size(); i++) { // for each bit
|
||||
// for each needle port connected to wire-bit
|
||||
for (auto &port : sig2port.find(nsig[i])) {
|
||||
RTLIL::SigSpec bitsig = hsig.extract(i, 1);
|
||||
RTLIL::SigSpec new_sig = cell->getPort(port.first);
|
||||
new_sig.replace(port.second, bitsig);
|
||||
cell->setPort(port.first, new_sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
haystack->remove(haystack_cell);
|
||||
}
|
||||
|
||||
// for all connections/port of the new cell
|
||||
for (auto &conn : cell->connections()) {
|
||||
// for all ports in the needle module
|
||||
RTLIL::IdString port_name = conn.first;
|
||||
RTLIL::SigSpec port = cell->getPort(conn.first);
|
||||
if(minimize_port_width) {
|
||||
// starting from the MSB, remove until first non-constant bit
|
||||
int msb = port.size()-1;
|
||||
for (; msb >= 0; msb--) {
|
||||
if(port[msb].is_wire())
|
||||
break;
|
||||
}
|
||||
if(msb > 0 && msb < port.size()-1) {
|
||||
log("removing in %s (width: %d) from bit %d-%d\n", port_name.c_str(), port.size(), port.size()-1, msb+1);
|
||||
log(" remove(%d, %d)\n", msb+1, port.size()-1-msb);
|
||||
port.remove(msb+1, port.size()-1-msb);
|
||||
log("removing in %s (width: %d) from bit %d-%d\n", port_name.c_str(), port.size(), port.size()-1, msb+1);
|
||||
}
|
||||
}
|
||||
|
||||
RTLIL::IdString port_width = RTLIL::escape_id(port_name.str() + "_WIDTH");
|
||||
cell->setParam(port_width, port.size());
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
@ -427,6 +470,11 @@ struct ExtractPass : public Pass {
|
|||
log(" -mine_max_fanout <num>\n");
|
||||
log(" don't consider internal signals with more than <num> connections\n");
|
||||
log("\n");
|
||||
log(" -min_port_width <num>\n");
|
||||
log(" match all subcircuits with port widths starting from <num>");
|
||||
log(" up to the needle port width defined in the map-design\n");
|
||||
log(" default: -1 (exact port width matching)\n");
|
||||
log("\n");
|
||||
log("The modules in the map file may have the attribute 'extract_order' set to an\n");
|
||||
log("integer value. Then this value is used to determine the order in which the pass\n");
|
||||
log("tries to map the modules to the design (ascending, default value is 0).\n");
|
||||
|
@ -452,6 +500,7 @@ struct ExtractPass : public Pass {
|
|||
int mine_min_freq = 10;
|
||||
int mine_limit_mod = -1;
|
||||
int mine_max_fanout = -1;
|
||||
int min_port_width = -1;
|
||||
std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> mine_split;
|
||||
|
||||
size_t argidx;
|
||||
|
@ -556,6 +605,10 @@ struct ExtractPass : public Pass {
|
|||
argidx += 2;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-min_port_width" && argidx+1 < args.size()) {
|
||||
min_port_width = atoi(args[++argidx].c_str());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
@ -628,7 +681,7 @@ struct ExtractPass : public Pass {
|
|||
SubCircuit::Graph mod_graph;
|
||||
std::string graph_name = "needle_" + RTLIL::unescape_id(module->name);
|
||||
log("Creating needle graph %s.\n", graph_name.c_str());
|
||||
if (module2graph(mod_graph, module, constports)) {
|
||||
if (module2graph(mod_graph, module, constports, min_port_width)) {
|
||||
solver.addGraph(graph_name, mod_graph);
|
||||
needle_map[graph_name] = module;
|
||||
needle_list.push_back(module);
|
||||
|
@ -639,7 +692,7 @@ struct ExtractPass : public Pass {
|
|||
SubCircuit::Graph mod_graph;
|
||||
std::string graph_name = "haystack_" + RTLIL::unescape_id(module->name);
|
||||
log("Creating haystack graph %s.\n", graph_name.c_str());
|
||||
if (module2graph(mod_graph, module, constports, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split : nullptr)) {
|
||||
if (module2graph(mod_graph, module, constports, -1, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split : nullptr)) {
|
||||
solver.addGraph(graph_name, mod_graph);
|
||||
haystack_map[graph_name] = module;
|
||||
}
|
||||
|
@ -672,7 +725,7 @@ struct ExtractPass : public Pass {
|
|||
log(" %s:%s", it2.first.c_str(), it2.second.c_str());
|
||||
log("\n");
|
||||
}
|
||||
RTLIL::Cell *new_cell = replace(needle_map.at(result.needleGraphId), haystack_map.at(result.haystackGraphId), result);
|
||||
RTLIL::Cell *new_cell = replace(needle_map.at(result.needleGraphId), haystack_map.at(result.haystackGraphId), result, (min_port_width >= 0));
|
||||
design->select(haystack_map.at(result.haystackGraphId), new_cell);
|
||||
log(" new cell: %s\n", log_id(new_cell->name));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue