mirror of https://github.com/YosysHQ/yosys.git
N-dimensional regs
This commit is contained in:
parent
39b36fa5f5
commit
608ed37a6d
|
|
@ -103,13 +103,6 @@ dict<int,fstHandle> FstData::getMemoryHandles(std::string name) {
|
|||
return dict<int,fstHandle>();
|
||||
};
|
||||
|
||||
dict<std::vector<int>,fstHandle> FstData::getArrayHandles(std::string name) {
|
||||
if (array_to_handle.find(name) != array_to_handle.end())
|
||||
return array_to_handle[name];
|
||||
else
|
||||
return dict<std::vector<int>,fstHandle>();
|
||||
};
|
||||
|
||||
static std::string remove_spaces(std::string str)
|
||||
{
|
||||
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
|
||||
|
|
@ -144,63 +137,17 @@ void FstData::extractVarNames()
|
|||
if (!var.is_alias)
|
||||
handle_to_var[h->u.var.handle] = var;
|
||||
|
||||
std::string clean_name;
|
||||
bool has_space = false;
|
||||
for(size_t i=0;i<strlen(h->u.var.name);i++)
|
||||
{
|
||||
char c = h->u.var.name[i];
|
||||
if(c==' ') { has_space = true; break; }
|
||||
clean_name += c;
|
||||
}
|
||||
if (clean_name[0]=='\\')
|
||||
clean_name = clean_name.substr(1);
|
||||
std::string clean_name = var.name;
|
||||
if (!clean_name.empty() && clean_name[0] == '\\')
|
||||
clean_name = clean_name.substr(1);
|
||||
|
||||
// Strip bit ranges like [4:0] from the end (only if no space)
|
||||
if (!has_space) {
|
||||
size_t pos = clean_name.find_last_of("[");
|
||||
if (pos != std::string::npos) {
|
||||
std::string index_or_range = clean_name.substr(pos+1);
|
||||
if (index_or_range.find(":") != std::string::npos) {
|
||||
clean_name = clean_name.substr(0,pos);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// 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 arbitrary number of array indices
|
||||
size_t open = 0;
|
||||
std::vector<int> 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_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;
|
||||
}
|
||||
// Strip trailing bit range [N:M] if present
|
||||
if (!clean_name.empty() && clean_name.back() == ']') {
|
||||
size_t open = clean_name.rfind('[');
|
||||
if (open != std::string::npos) {
|
||||
std::string inner = clean_name.substr(open + 1, clean_name.size() - open - 2);
|
||||
if (inner.find(':') != std::string::npos)
|
||||
clean_name.erase(open);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ private:
|
|||
std::map<fstHandle, FstVar> handle_to_var;
|
||||
std::map<std::string, fstHandle> name_to_handle;
|
||||
std::map<std::string, dict<int, fstHandle>> memory_to_handle;
|
||||
std::map<std::string, dict<std::vector<int>, fstHandle>> array_to_handle;
|
||||
std::map<fstHandle, std::string> last_data;
|
||||
uint64_t last_time;
|
||||
std::map<fstHandle, std::string> past_data;
|
||||
|
|
|
|||
|
|
@ -225,35 +225,6 @@ struct SimInstance
|
|||
dict<Wire*, fstHandle> fst_inputs;
|
||||
dict<IdString, dict<int,fstHandle>> fst_memories;
|
||||
|
||||
// For multi-dimensional arrays
|
||||
dict<Wire*, dict<std::vector<int>,fstHandle>> fst_array_handles;
|
||||
dict<Wire*, dict<std::vector<int>,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<std::vector<int>, fstHandle> tryGetArrayHandles(FstData* fst, const std::string& scope, Wire* wire)
|
||||
{
|
||||
std::string wire_name = scope + "." + RTLIL::unescape_id(wire->name);
|
||||
dict<std::vector<int>, fstHandle> array_handles = fst->getArrayHandles(wire_name);
|
||||
|
||||
if (!array_handles.empty()) {
|
||||
int total_width = 0;
|
||||
for (auto &pair : array_handles) {
|
||||
total_width += fst->getWidth(pair.second);
|
||||
}
|
||||
if (total_width == wire->width) {
|
||||
if (shared->debug) {
|
||||
log("Found %zu array elements for wire %s, total width: %d\n",
|
||||
array_handles.size(), wire_name.c_str(), total_width);
|
||||
}
|
||||
return array_handles;
|
||||
}
|
||||
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<std::vector<int>, 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<std::vector<int>, fstHandle>& handles)
|
||||
|
|
@ -304,16 +275,11 @@ struct SimInstance
|
|||
}
|
||||
}
|
||||
|
||||
// Populate fst_handles and fst_array_handles for signal lookups
|
||||
// Populate fst_handles for signal lookups
|
||||
if ((shared->fst) && !(shared->hide_internal && wire->name[0] == '$')) {
|
||||
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<std::vector<int>, 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;
|
||||
} else if (id != 0) {
|
||||
if (id != 0) {
|
||||
// Case of a regular wire/reg
|
||||
fst_handles[wire] = id;
|
||||
if (shared->debug) {
|
||||
|
|
@ -1587,16 +1553,10 @@ struct SimWorker : SimShared
|
|||
|
||||
for (auto wire : topmod->wires()) {
|
||||
|
||||
// Populate fst_inputs and fst_array_inputs for input ports
|
||||
// Populate fst_inputs for input ports
|
||||
if (wire->port_input) {
|
||||
fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name));
|
||||
|
||||
// Try to get array element handles if this is a multi-dimensional array
|
||||
dict<std::vector<int>, 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;
|
||||
} else if (id != 0) {
|
||||
if (id != 0) {
|
||||
// Case of a regular wire/reg
|
||||
top->fst_inputs[wire] = id;
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue