3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-23 06:13:41 +00:00

Merge pull request #20 from alaindargelas/diagnostics_and_fencing

Prevent crashes and diagnostics
This commit is contained in:
Akash Levy 2024-11-14 16:37:03 -08:00 committed by GitHub
commit c3bcd0b643
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 119 additions and 66 deletions

View file

@ -84,7 +84,7 @@ struct ActivityProp {
DutyMap.emplace(bit, duties[i]); DutyMap.emplace(bit, duties[i]);
nbBitsWithActivity++; nbBitsWithActivity++;
} else { } else {
log_warning("Zeroing out activity for module: %s, wire: %s, wire_size: %d, activ_size: %ld", log_warning("Zeroing out activity for module: %s, wire: %s, wire_size: %d, activ_size: %ld\n",
module->name.c_str(), wire->name.c_str(), GetSize(sig), activities.size()); module->name.c_str(), wire->name.c_str(), GetSize(sig), activities.size());
ActivityMap.emplace(bit, "0.0"); ActivityMap.emplace(bit, "0.0");
DutyMap.emplace(bit, "0.0"); DutyMap.emplace(bit, "0.0");
@ -107,7 +107,7 @@ struct ActivityProp {
} else { } else {
RTLIL::SigSpec sigspec(bit); RTLIL::SigSpec sigspec(bit);
if (!sigspec.is_fully_const()) { if (!sigspec.is_fully_const()) {
log_warning("No activity found for : %s/%s/%s", module->name.c_str(), cell->name.c_str(), port_name.c_str()); log_warning("No activity found for : %s/%s/%s\n", module->name.c_str(), cell->name.c_str(), port_name.c_str());
} }
// constants have no activity // constants have no activity
cell_ports_activity += port_name + "=" + "0.0 "; cell_ports_activity += port_name + "=" + "0.0 ";
@ -120,7 +120,7 @@ struct ActivityProp {
} else { } else {
RTLIL::SigSpec sigspec(bit); RTLIL::SigSpec sigspec(bit);
if (!sigspec.is_fully_const()) { if (!sigspec.is_fully_const()) {
log_warning("No dutycycle found for : %s/%s/%s", module->name.c_str(), cell->name.c_str(), port_name.c_str()); log_warning("No dutycycle found for : %s/%s/%s\n", module->name.c_str(), cell->name.c_str(), port_name.c_str());
} }
// constant 1 has duty cycle 1, constant 0 has duty cycle 0 // constant 1 has duty cycle 1, constant 0 has duty cycle 0
cell_ports_duty += port_name + "=" + (sigspec.as_bool() ? "1.0" : "0.0") + " "; cell_ports_duty += port_name + "=" + (sigspec.as_bool() ? "1.0" : "0.0") + " ";

View file

@ -6,9 +6,14 @@ USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
struct ReconstructBusses : public ScriptPass { struct ReconstructBusses : public ScriptPass {
ReconstructBusses() : ScriptPass("reconstructbusses", "Reconstruct busses from wires with the same prefix following the convention: <prefix>_<index>_") {} ReconstructBusses()
: ScriptPass("reconstructbusses", "Reconstruct busses from wires with the same prefix following the convention: <prefix>_<index>_")
{
}
void script() override {} void script() override {}
bool is_digits(const std::string &str) { return std::all_of(str.begin(), str.end(), ::isdigit); }
void execute(std::vector<std::string>, RTLIL::Design *design) override void execute(std::vector<std::string>, RTLIL::Design *design) override
{ {
if (design == nullptr) { if (design == nullptr) {
@ -17,6 +22,8 @@ struct ReconstructBusses : public ScriptPass {
} }
log("Running reconstructbusses pass\n"); log("Running reconstructbusses pass\n");
log_flush(); log_flush();
log("Creating bus groups\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;
@ -32,7 +39,21 @@ struct ReconstructBusses : public ScriptPass {
// Result: "add_Y" // Result: "add_Y"
std::string::iterator end = prefix.end() - 1; std::string::iterator end = prefix.end() - 1;
if ((*end) == '_') { if ((*end) == '_') {
// Last character is an _, it is a bit blasted index // Last character is an _, check that it is a bit blasted index:
bool valid_index = false;
std::string ch_name = prefix.substr(0, prefix.size() - 1);
if (ch_name.find("_") != std::string::npos) {
std::string ch_index_str = ch_name.substr(ch_name.find_last_of('_') + 1);
if ((!ch_index_str.empty() && is_digits(ch_index_str))) {
valid_index = true;
}
}
if (!valid_index) {
log_warning("Invalid net name %s\n", prefix.c_str());
log_flush();
continue;
}
end--; end--;
for (; end != prefix.begin(); end--) { for (; end != prefix.begin(); end--) {
if ((*end) != '_') { if ((*end) != '_') {
@ -43,12 +64,20 @@ struct ReconstructBusses : public ScriptPass {
break; break;
} }
} }
if (end == prefix.begin()) {
// Last _ didn't mean there was another _
log_warning("Invalid net name %s\n", prefix.c_str());
log_flush();
continue;
}
std::string no_bitblast_prefix; std::string no_bitblast_prefix;
std::copy(prefix.begin(), end, std::back_inserter(no_bitblast_prefix)); std::copy(prefix.begin(), end, std::back_inserter(no_bitblast_prefix));
wire_groups[no_bitblast_prefix].push_back(wire); wire_groups[no_bitblast_prefix].push_back(wire);
} }
} }
log("Found %ld groups\n", wire_groups.size());
log("Creating busses\n");
log_flush();
std::map<std::string, RTLIL::Wire *> wirenames_to_remove; std::map<std::string, RTLIL::Wire *> wirenames_to_remove;
pool<RTLIL::Wire *> wires_to_remove; pool<RTLIL::Wire *> wires_to_remove;
// Reconstruct vectors // Reconstruct vectors
@ -56,25 +85,6 @@ struct ReconstructBusses : public ScriptPass {
std::string prefix = it.first; std::string prefix = it.first;
std::vector<RTLIL::Wire *> &wires = it.second; std::vector<RTLIL::Wire *> &wires = it.second;
// Sort wires by their bit index (assuming the suffix is _<index>_)
std::sort(wires.begin(), wires.end(), [](RTLIL::Wire *a, RTLIL::Wire *b) {
std::string a_name = a->name.str();
std::string b_name = b->name.str();
std::string::iterator a_end = a_name.end() - 1;
std::string::iterator b_end = b_name.end() - 1;
if (((*a_end) == '_') && ((*b_end) == '_')) {
a_name = a_name.substr(0, a_name.size() - 1);
b_name = b_name.substr(0, b_name.size() - 1);
std::string a_index_str = a_name.substr(a_name.find_last_of('_') + 1);
std::string b_index_str = b_name.substr(b_name.find_last_of('_') + 1);
int a_index = std::stoi(a_index_str);
int b_index = std::stoi(b_index_str);
return a_index > b_index; // Descending order for correct concatenation
} else {
return false;
}
});
// Create a new vector wire // Create a new vector wire
int width = wires.size(); int width = wires.size();
RTLIL::Wire *new_wire = module->addWire(prefix, width); RTLIL::Wire *new_wire = module->addWire(prefix, width);
@ -93,7 +103,8 @@ struct ReconstructBusses : public ScriptPass {
wires_to_remove.insert(wire); wires_to_remove.insert(wire);
} }
} }
log("Reconnecting cells\n");
log_flush();
// Reconnect cells // Reconnect cells
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
for (auto &conn : cell->connections_) { for (auto &conn : cell->connections_) {
@ -104,20 +115,26 @@ struct ReconstructBusses : public ScriptPass {
// 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
std::string lhs_name = chunk.wire->name.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); std::map<std::string, RTLIL::Wire *>::iterator itr = wirenames_to_remove.find(lhs_name);
if (itr != wirenames_to_remove.end()) { 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; if (!ch_name.empty()) {
if ((*ch_end) == '_') { std::string::iterator ch_end = ch_name.end() - 1;
ch_name = ch_name.substr(0, ch_name.size() - 1); if ((*ch_end) == '_') {
std::string ch_index_str = ch_name.substr(ch_name.find_last_of('_') + 1); ch_name = ch_name.substr(0, ch_name.size() - 1);
// std::cout << "ch_name: " << ch_name << std::endl; if (ch_name.find("_") != std::string::npos) {
if (!ch_index_str.empty()) { std::string ch_index_str =
// Create a new connection sigspec that matches the previous bit index ch_name.substr(ch_name.find_last_of('_') + 1);
int ch_index = std::stoi(ch_index_str); // std::cout << "ch_name: " << ch_name << std::endl;
RTLIL::SigSpec bit = RTLIL::SigSpec(itr->second, ch_index, 1); if ((!ch_index_str.empty() && is_digits(ch_index_str))) {
new_sig.append(bit); // Create a new connection sigspec that matches the previous
modified = true; // bit index
int ch_index = std::stoi(ch_index_str);
RTLIL::SigSpec bit = RTLIL::SigSpec(itr->second, ch_index, 1);
new_sig.append(bit);
modified = true;
}
}
} }
} }
} else { } else {
@ -130,9 +147,9 @@ struct ReconstructBusses : public ScriptPass {
conn.second = new_sig; conn.second = new_sig;
} }
} }
log("Reconnecting top connections\n");
log_flush();
// Reconnect top connections before removing the old wires // Reconnect top connections before removing the old wires
// 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;
RTLIL::SigSpec rhs = conn.second; RTLIL::SigSpec rhs = conn.second;
@ -146,31 +163,38 @@ struct ReconstructBusses : public ScriptPass {
while (lit != lhs.chunks().rend()) { while (lit != lhs.chunks().rend()) {
RTLIL::SigChunk sub_lhs = *lit; RTLIL::SigChunk sub_lhs = *lit;
std::string conn_lhs = sub_lhs.wire->name.c_str(); std::string conn_lhs = sub_lhs.wire->name.c_str();
std::string conn_rhs = sub_rhs.wire->name.c_str(); if (!conn_lhs.empty()) {
// The connection LHS matches a wire that is replaced by a bus // std::cout << "Conn LHS: " << conn_lhs << std::endl;
// std::cout << "Conn: " << conn_lhs << " to: " << conn_rhs << std::endl; // std::string conn_rhs = sub_rhs.wire->name.c_str();
std::map<std::string, RTLIL::Wire *>::iterator itr = wirenames_to_remove.find(conn_lhs); // std::cout << "Conn RHS: " << conn_rhs << std::endl;
if (itr != wirenames_to_remove.end()) {
std::string::iterator conn_lhs_end = conn_lhs.end() - 1; std::map<std::string, RTLIL::Wire *>::iterator itr = wirenames_to_remove.find(conn_lhs);
if ((*conn_lhs_end) == '_') { if (itr != wirenames_to_remove.end()) {
conn_lhs = conn_lhs.substr(0, conn_lhs.size() - 1); std::string::iterator conn_lhs_end = conn_lhs.end() - 1;
std::string ch_index_str = conn_lhs.substr(conn_lhs.find_last_of('_') + 1); if ((*conn_lhs_end) == '_') {
if (!ch_index_str.empty()) { conn_lhs = conn_lhs.substr(0, conn_lhs.size() - 1);
// std::cout << "Conn LHS: " << conn_lhs << std::endl; if (conn_lhs.find("_") != std::string::npos) {
// std::string conn_rhs = sub_rhs.wire->name.c_str(); std::string ch_index_str = conn_lhs.substr(conn_lhs.find_last_of('_') + 1);
// std::cout << "Conn RHS: " << conn_rhs << std::endl; if (!ch_index_str.empty() && is_digits(ch_index_str)) {
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(itr->second, 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 // If RHS has width > 1, replace with the bitblasted RHS
// connected bit // corresponding to the connected bit
RTLIL::SigSpec rhs_bit = RTLIL::SigSpec(sub_rhs.wire, ch_index, 1); RTLIL::SigSpec rhs_bit =
// And connect it RTLIL::SigSpec(sub_rhs.wire, ch_index, 1);
module->connect(bit, rhs_bit); // And connect it
} else { module->connect(bit, rhs_bit);
// Else, directly connect } else {
module->connect(bit, sub_rhs); // Else, directly connect
module->connect(bit, sub_rhs);
}
} else {
// Else, directly connect
RTLIL::SigSpec bit = RTLIL::SigSpec(itr->second, 0, 1);
module->connect(bit, sub_rhs);
}
} }
} }
} }
@ -180,12 +204,17 @@ struct ReconstructBusses : public ScriptPass {
rit++; rit++;
} }
} }
// Remove old wires // Remove old wires
log("Removing old wires\n");
log_flush();
module->remove(wires_to_remove); module->remove(wires_to_remove);
// Update module port list // Update module port list
log("Re-creating ports\n");
log_flush();
module->fixup_ports(); module->fixup_ports();
} }
log("End reconstructbusses pass\n");
log_flush();
} }
} ReconstructBusses; } ReconstructBusses;

View file

@ -51,6 +51,10 @@ void recordTransFanin(RTLIL::SigSpec &sig, dict<RTLIL::SigSpec, std::set<Cell *>
// Signal cell driver(s), precompute a cell output signal to a cell map // Signal cell driver(s), precompute a cell output signal to a cell map
void sigCellDrivers(RTLIL::Design *design, dict<RTLIL::SigSpec, std::set<Cell *> *> &sig2CellsInFanin) void sigCellDrivers(RTLIL::Design *design, dict<RTLIL::SigSpec, std::set<Cell *> *> &sig2CellsInFanin)
{ {
if (!design->top_module())
return;
if (design->top_module()->cells().size() == 0)
return;
for (auto cell : design->top_module()->cells()) { for (auto cell : design->top_module()->cells()) {
for (auto &conn : cell->connections()) { for (auto &conn : cell->connections()) {
IdString portName = conn.first; IdString portName = conn.first;
@ -95,6 +99,10 @@ void sigCellDrivers(RTLIL::Design *design, dict<RTLIL::SigSpec, std::set<Cell *>
// Assign statements fanin, traces the lhs to rhs sigspecs and precompute a map // Assign statements fanin, traces the lhs to rhs sigspecs and precompute a map
void lhs2rhs(RTLIL::Design *design, dict<RTLIL::SigSpec, RTLIL::SigSpec> &lhsSig2rhsSig) void lhs2rhs(RTLIL::Design *design, dict<RTLIL::SigSpec, RTLIL::SigSpec> &lhsSig2rhsSig)
{ {
if (!design->top_module())
return;
if (design->top_module()->connections().size() == 0)
return;
for (auto it = design->top_module()->connections().begin(); it != design->top_module()->connections().end(); ++it) { for (auto it = design->top_module()->connections().begin(); it != design->top_module()->connections().end(); ++it) {
RTLIL::SigSpec lhs = it->first; RTLIL::SigSpec lhs = it->first;
RTLIL::SigSpec rhs = it->second; RTLIL::SigSpec rhs = it->second;
@ -145,9 +153,15 @@ struct SplitNetlist : public ScriptPass {
log_error("No design object"); log_error("No design object");
return; return;
} }
log("Running splitnetlist pass\n");
log_flush();
log("Mapping signals to cells\n");
log_flush();
// Precompute cell output sigspec to cell map // Precompute cell output sigspec to cell map
dict<RTLIL::SigSpec, std::set<Cell *> *> sig2CellsInFanin; dict<RTLIL::SigSpec, std::set<Cell *> *> sig2CellsInFanin;
sigCellDrivers(design, sig2CellsInFanin); sigCellDrivers(design, sig2CellsInFanin);
log("Mapping assignments\n");
log_flush();
// Precompute lhs to rhs sigspec map // Precompute lhs to rhs sigspec map
dict<RTLIL::SigSpec, RTLIL::SigSpec> lhsSig2RhsSig; dict<RTLIL::SigSpec, RTLIL::SigSpec> lhsSig2RhsSig;
lhs2rhs(design, lhsSig2RhsSig); lhs2rhs(design, lhsSig2RhsSig);
@ -160,6 +174,12 @@ struct SplitNetlist : public ScriptPass {
typedef std::map<std::string, CellsAndSigs> CellName_ObjectMap; typedef std::map<std::string, CellsAndSigs> CellName_ObjectMap;
CellName_ObjectMap cellName_ObjectMap; CellName_ObjectMap cellName_ObjectMap;
// Record logic cone by output sharing the same prefix // Record logic cone by output sharing the same prefix
if (!design->top_module())
return;
if (design->top_module()->wires().size() == 0)
return;
log("Cells grouping\n");
log_flush();
for (auto wire : design->top_module()->wires()) { for (auto wire : design->top_module()->wires()) {
if (!wire->port_output) if (!wire->port_output)
continue; continue;
@ -219,6 +239,8 @@ struct SplitNetlist : public ScriptPass {
} }
} }
// Create submod attributes for the submod command // Create submod attributes for the submod command
log("Creating submods\n");
log_flush();
for (CellName_ObjectMap::iterator itr = cellName_ObjectMap.begin(); itr != cellName_ObjectMap.end(); itr++) { for (CellName_ObjectMap::iterator itr = cellName_ObjectMap.begin(); itr != cellName_ObjectMap.end(); itr++) {
// std::cout << "Cluster name: " << itr->first << std::endl; // std::cout << "Cluster name: " << itr->first << std::endl;
CellsAndSigs &components = itr->second; CellsAndSigs &components = itr->second;
@ -233,6 +255,8 @@ struct SplitNetlist : public ScriptPass {
} }
// Execute the submod command // Execute the submod command
Pass::call(design, "submod -copy"); Pass::call(design, "submod -copy");
log("End splitnetlist pass\n");
log_flush();
} }
} SplitNetlist; } SplitNetlist;