3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-17 19:36:18 +00:00

Reduced complexity: NxM -> N log(M)

This commit is contained in:
Alain Dargelas 2024-11-12 19:55:10 -08:00
parent ad48ce3da5
commit 61b37bebb6

View file

@ -15,6 +15,8 @@ struct ReconstructBusses : public ScriptPass {
log_error("No design object"); log_error("No design object");
return; return;
} }
log("Running reconstructbusses pass\n");
log_flush();
for (auto module : design->modules()) { for (auto module : design->modules()) {
// Collect all wires with a common prefix // Collect all wires with a common prefix
dict<std::string, std::vector<RTLIL::Wire *>> wire_groups; dict<std::string, std::vector<RTLIL::Wire *>> wire_groups;
@ -47,7 +49,8 @@ struct ReconstructBusses : public ScriptPass {
wire_groups[no_bitblast_prefix].push_back(wire); wire_groups[no_bitblast_prefix].push_back(wire);
} }
} }
std::map<std::string, RTLIL::Wire *> wirenames_to_remove;
pool<RTLIL::Wire *> wires_to_remove;
// Reconstruct vectors // Reconstruct vectors
for (auto &it : wire_groups) { for (auto &it : wire_groups) {
std::string prefix = it.first; std::string prefix = it.first;
@ -83,7 +86,14 @@ struct ReconstructBusses : public ScriptPass {
new_wire->port_output = 1; new_wire->port_output = 1;
break; break;
} }
RTLIL::SigSpec new_wire_s(new_wire);
for (auto wire : wires) {
std::string wire_name = wire->name.c_str();
wirenames_to_remove.emplace(wire_name, new_wire);
wires_to_remove.insert(wire);
}
}
// Reconnect cells // Reconnect cells
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
for (auto &conn : cell->connections_) { for (auto &conn : cell->connections_) {
@ -93,7 +103,9 @@ struct ReconstructBusses : public ScriptPass {
// std::cout << "Port:" << conn.first.c_str() << std::endl; // std::cout << "Port:" << conn.first.c_str() << std::endl;
// std::cout << "Conn:" << chunk.wire->name.c_str() << std::endl; // std::cout << "Conn:" << chunk.wire->name.c_str() << std::endl;
// Find the connections that match the wire group prefix // Find the connections that match the wire group prefix
if (chunk.wire->name.begins_with((prefix + "_").c_str())) { std::string lhs_name = chunk.wire->name.c_str();
std::map<std::string, RTLIL::Wire *>::iterator itr = wirenames_to_remove.find(lhs_name);
if (itr != wirenames_to_remove.end()) {
std::string ch_name = chunk.wire->name.c_str(); std::string ch_name = chunk.wire->name.c_str();
std::string::iterator ch_end = ch_name.end() - 1; std::string::iterator ch_end = ch_name.end() - 1;
if ((*ch_end) == '_') { if ((*ch_end) == '_') {
@ -103,7 +115,7 @@ struct ReconstructBusses : public ScriptPass {
if (!ch_index_str.empty()) { if (!ch_index_str.empty()) {
// Create a new connection sigspec that matches the previous bit index // Create a new connection sigspec that matches the previous bit index
int ch_index = std::stoi(ch_index_str); int ch_index = std::stoi(ch_index_str);
RTLIL::SigSpec bit = RTLIL::SigSpec(new_wire, ch_index, 1); RTLIL::SigSpec bit = RTLIL::SigSpec(itr->second, ch_index, 1);
new_sig.append(bit); new_sig.append(bit);
modified = true; modified = true;
} }
@ -120,8 +132,6 @@ struct ReconstructBusses : public ScriptPass {
} }
// Reconnect top connections before removing the old wires // Reconnect top connections before removing the old wires
for (auto wire : wires) {
std::string wire_name = wire->name.c_str();
// std::cout << "Wire to remove: " << wire_name << std::endl; // std::cout << "Wire to remove: " << wire_name << std::endl;
for (auto &conn : module->connections()) { for (auto &conn : module->connections()) {
RTLIL::SigSpec lhs = conn.first; RTLIL::SigSpec lhs = conn.first;
@ -139,7 +149,8 @@ struct ReconstructBusses : public ScriptPass {
std::string conn_rhs = sub_rhs.wire->name.c_str(); std::string conn_rhs = sub_rhs.wire->name.c_str();
// The connection LHS matches a wire that is replaced by a bus // The connection LHS matches a wire that is replaced by a bus
// std::cout << "Conn: " << conn_lhs << " to: " << conn_rhs << std::endl; // std::cout << "Conn: " << conn_lhs << " to: " << conn_rhs << std::endl;
if (wire_name == conn_lhs) { std::map<std::string, RTLIL::Wire *>::iterator itr = wirenames_to_remove.find(conn_lhs);
if (itr != wirenames_to_remove.end()) {
std::string::iterator conn_lhs_end = conn_lhs.end() - 1; std::string::iterator conn_lhs_end = conn_lhs.end() - 1;
if ((*conn_lhs_end) == '_') { if ((*conn_lhs_end) == '_') {
conn_lhs = conn_lhs.substr(0, conn_lhs.size() - 1); conn_lhs = conn_lhs.substr(0, conn_lhs.size() - 1);
@ -150,11 +161,11 @@ struct ReconstructBusses : public ScriptPass {
// std::cout << "Conn RHS: " << conn_rhs << std::endl; // std::cout << "Conn RHS: " << conn_rhs << std::endl;
int ch_index = std::stoi(ch_index_str); int ch_index = std::stoi(ch_index_str);
// Create the LHS sigspec of the desired bit // Create the LHS sigspec of the desired bit
RTLIL::SigSpec bit = RTLIL::SigSpec(new_wire, ch_index, 1); RTLIL::SigSpec bit = RTLIL::SigSpec(itr->second, ch_index, 1);
if (sub_rhs.size() > 1) { if (sub_rhs.size() > 1) {
// If RHS has width > 1, replace with the bitblasted RHS corresponding to the connected bit // If RHS has width > 1, replace with the bitblasted RHS corresponding to the
RTLIL::SigSpec rhs_bit = // connected bit
RTLIL::SigSpec(sub_rhs.wire, ch_index, 1); RTLIL::SigSpec rhs_bit = RTLIL::SigSpec(sub_rhs.wire, ch_index, 1);
// And connect it // And connect it
module->connect(bit, rhs_bit); module->connect(bit, rhs_bit);
} else { } else {
@ -169,14 +180,9 @@ struct ReconstructBusses : public ScriptPass {
rit++; rit++;
} }
} }
}
// Remove old wires // Remove old wires
pool<RTLIL::Wire *> wires_to_remove;
for (auto wire : wires) {
wires_to_remove.insert(wire);
}
module->remove(wires_to_remove); module->remove(wires_to_remove);
}
// Update module port list // Update module port list
module->fixup_ports(); module->fixup_ports();
} }