diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc index 7aee18837..42f2f76e0 100644 --- a/kernel/fstdata.cc +++ b/kernel/fstdata.cc @@ -103,11 +103,11 @@ dict FstData::getMemoryHandles(std::string name) { return dict(); }; -dict FstData::getArrayHandles(std::string name) { +dict,fstHandle> FstData::getArrayHandles(std::string name) { if (array_to_handle.find(name) != array_to_handle.end()) return array_to_handle[name]; else - return dict(); + return dict,fstHandle>(); }; static std::string remove_spaces(std::string str) @@ -213,22 +213,41 @@ void FstData::extractVarNames() } } } else { - // Handle "signal [index][bitrange]" format + + // Handle "signal [i0][i1]...[iN][bitrange]" format std::string full_name = h->u.var.name; size_t space_pos = full_name.find(' '); if (space_pos != std::string::npos) { + + // Extract "[i0][i1]...[iN][bitrange]" suffix std::string suffix = full_name.substr(space_pos + 1); - // Parse first bracket pair for array index - if (!suffix.empty() && suffix[0] == '[') { - size_t close_bracket = suffix.find(']'); - if (close_bracket != std::string::npos) { - std::string index_str = suffix.substr(1, close_bracket - 1); + + // Parse arbitrary number of array indices + size_t open = 0; + std::vector array_indices; + while (open < suffix.length() && suffix[open] == '[') { + + size_t close = suffix.find(']', open); + if (close != std::string::npos) { + std::string index_str = suffix.substr(open + 1, close - open - 1); + // Check it's an array index (no colon), not a bit range if (index_str.find(':') == std::string::npos) { int array_index = std::stoi(index_str); - array_to_handle[var.scope+"."+clean_name][array_index] = var.id; + array_indices.push_back(array_index); } + } else { + log_warning("Error parsing array index in : %s\n", full_name.c_str()); + break; } + + // Move to next opening bracket + open = close + 1; + } + + // Add array indices to array_to_handle map if there are any + if (!array_indices.empty()) { + array_to_handle[var.scope+"."+clean_name][array_indices] = var.id; } } } diff --git a/kernel/fstdata.h b/kernel/fstdata.h index 87a7f3eb7..a7a269da6 100644 --- a/kernel/fstdata.h +++ b/kernel/fstdata.h @@ -55,7 +55,7 @@ class FstData std::string valueOf(fstHandle signal); fstHandle getHandle(std::string name); dict getMemoryHandles(std::string name); - dict getArrayHandles(std::string name); + dict,fstHandle> getArrayHandles(std::string name); double getTimescale() { return timescale; } const char *getTimescaleString() { return timescale_str.c_str(); } int getWidth(fstHandle signal); @@ -68,7 +68,7 @@ private: std::map handle_to_var; std::map name_to_handle; std::map> memory_to_handle; - std::map> array_to_handle; + std::map, fstHandle>> array_to_handle; std::map last_data; uint64_t last_time; std::map past_data; diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 65bddbe00..d0c6d8748 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -225,15 +225,15 @@ struct SimInstance dict> fst_memories; // For multi-dimensional arrays - dict> fst_array_handles; - dict> fst_array_inputs; + dict,fstHandle>> fst_array_handles; + dict,fstHandle>> fst_array_inputs; // Helper function to detect and retrieve array element handles // Returns non-empty dict if wire is a multi-dimensional array split in VCD - dict tryGetArrayHandles(FstData* fst, const std::string& scope, Wire* wire) + dict, fstHandle> tryGetArrayHandles(FstData* fst, const std::string& scope, Wire* wire) { std::string wire_name = scope + "." + RTLIL::unescape_id(wire->name); - dict array_handles = fst->getArrayHandles(wire_name); + dict, fstHandle> array_handles = fst->getArrayHandles(wire_name); if (!array_handles.empty()) { int total_width = 0; @@ -250,23 +250,24 @@ struct SimInstance log_warning("Array wire '%s' found in VCD (total width %d) but does not match Yosys wire width %d; skipping.\n", wire_name.c_str(), total_width, wire->width); } - return dict(); + return dict, fstHandle>(); } // Helper function to set wire state from array element handles // Concatenates values from array elements in descending index order - bool setStateFromArrayHandles(Wire* wire, dict& handles) + bool setStateFromArrayHandles(Wire* wire, dict, fstHandle>& handles) { - // Collect and sort indices in descending order (MSB = highest index) - std::vector indices; - for (auto &kv : handles) - indices.push_back(kv.first); - std::sort(indices.begin(), indices.end(), std::greater()); - + // Collect and sort indices in descending row-major order + std::vector, fstHandle>> sorted_elements; + for (auto &kv : handles) { + sorted_elements.push_back({kv.first, kv.second}); + } + std::sort(sorted_elements.begin(), sorted_elements.end(), std::greater<>()); + // Concatenate values in descending index order std::string concatenated = ""; - for (int idx : indices) { - concatenated += shared->fst->valueOf(handles[idx]); + for (auto &elem : sorted_elements) { + concatenated += shared->fst->valueOf(elem.second); } return set_state(wire, Const::from_string(concatenated)); } @@ -307,7 +308,7 @@ struct SimInstance fstHandle id = shared->fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name)); // Try to get array element handles if this is a multi-dimensional array - dict array_handles = tryGetArrayHandles(shared->fst, scope, wire); + dict, fstHandle> array_handles = tryGetArrayHandles(shared->fst, scope, wire); if (!array_handles.empty()) { // Must be an array, store in fst_array_handles fst_array_handles[wire] = array_handles; @@ -1590,7 +1591,7 @@ struct SimWorker : SimShared fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name)); // Try to get array element handles if this is a multi-dimensional array - dict array_handles = top->tryGetArrayHandles(fst, scope, wire); + dict, fstHandle> array_handles = top->tryGetArrayHandles(fst, scope, wire); if (!array_handles.empty()) { // Must be an array, store in fst_array_inputs top->fst_array_inputs[wire] = array_handles;