mirror of https://github.com/YosysHQ/yosys.git
fstdata: Handle square/angle bracket replacemnt, change memory handling
When writing VCDs smtbmc replaces square brackets with angle brackets to avoid the issues with VCD readers misinterpreting such signal names. For memory addresses it also uses angle brackets and hexadecimal addresses, while other tools will use square brackets and decimal addresses. Previously the code handled both forms of memory addresses, assuming that any signal that looks like a memory address is a memory address. This is not the case when the user uses regular signals whose names include square brackets _or_ when the verific frontend generates such names to represent various constructs. With this change all angular brackets are turned into square brackets when reading the trace _and_ when performing a signal lookup. This means no matter which kind of brackets are used in the design or in the VCD signals will be matched. This will not handle multiple signals that are the same apart from replacing square/angle brackets, but this will cause issues during the VCD writing of smtbmc already. It still uses the distinction between square and angle brackets for memories to decide whether the address is hex or decimal, but even if something looks like a memory and is added to the `memory_to_handle` data, the plain signal added to `name_to_handle` is used as-is, without rewriting the address. This last change is needed to successfully match verific generated signal names that look like memory addresses while keeping memories working at the same time. It may cause regressions when VCD generation was done with a design that had memories but simulation is done with a design where the memories were mapped to registers. This seems like an unusual setup, but could be worked around with some further changes should this be required.
This commit is contained in:
parent
9470ef9efe
commit
3477f2d00b
|
@ -78,7 +78,18 @@ uint64_t FstData::getStartTime() { return fstReaderGetStartTime(ctx); }
|
||||||
|
|
||||||
uint64_t FstData::getEndTime() { return fstReaderGetEndTime(ctx); }
|
uint64_t FstData::getEndTime() { return fstReaderGetEndTime(ctx); }
|
||||||
|
|
||||||
|
static void normalize_brackets(std::string &str)
|
||||||
|
{
|
||||||
|
for (auto &c : str) {
|
||||||
|
if (c == '<')
|
||||||
|
c = '[';
|
||||||
|
else if (c == '>')
|
||||||
|
c = ']';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fstHandle FstData::getHandle(std::string name) {
|
fstHandle FstData::getHandle(std::string name) {
|
||||||
|
normalize_brackets(name);
|
||||||
if (name_to_handle.find(name) != name_to_handle.end())
|
if (name_to_handle.find(name) != name_to_handle.end())
|
||||||
return name_to_handle[name];
|
return name_to_handle[name];
|
||||||
else
|
else
|
||||||
|
@ -120,6 +131,7 @@ void FstData::extractVarNames()
|
||||||
var.is_reg = (fstVarType)h->u.var.typ == FST_VT_VCD_REG;
|
var.is_reg = (fstVarType)h->u.var.typ == FST_VT_VCD_REG;
|
||||||
var.name = remove_spaces(h->u.var.name);
|
var.name = remove_spaces(h->u.var.name);
|
||||||
var.scope = fst_scope_name;
|
var.scope = fst_scope_name;
|
||||||
|
normalize_brackets(var.scope);
|
||||||
var.width = h->u.var.length;
|
var.width = h->u.var.length;
|
||||||
vars.push_back(var);
|
vars.push_back(var);
|
||||||
if (!var.is_alias)
|
if (!var.is_alias)
|
||||||
|
@ -134,35 +146,34 @@ void FstData::extractVarNames()
|
||||||
if (clean_name[0]=='\\')
|
if (clean_name[0]=='\\')
|
||||||
clean_name = clean_name.substr(1);
|
clean_name = clean_name.substr(1);
|
||||||
size_t pos = clean_name.find_last_of("<");
|
size_t pos = clean_name.find_last_of("<");
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos && clean_name.back() == '>') {
|
||||||
std::string mem_cell = clean_name.substr(0, pos);
|
std::string mem_cell = clean_name.substr(0, pos);
|
||||||
|
normalize_brackets(mem_cell);
|
||||||
std::string addr = clean_name.substr(pos+1);
|
std::string addr = clean_name.substr(pos+1);
|
||||||
addr.pop_back(); // remove closing bracket
|
addr.pop_back(); // remove closing bracket
|
||||||
char *endptr;
|
char *endptr;
|
||||||
int mem_addr = strtol(addr.c_str(), &endptr, 16);
|
int mem_addr = strtol(addr.c_str(), &endptr, 16);
|
||||||
if (*endptr) {
|
if (*endptr) {
|
||||||
log_warning("Error parsing memory address in : %s\n", clean_name.c_str());
|
log_debug("Error parsing memory address in : %s\n", clean_name.c_str());
|
||||||
} else {
|
} else {
|
||||||
memory_to_handle[var.scope+"."+mem_cell][mem_addr] = var.id;
|
memory_to_handle[var.scope+"."+mem_cell][mem_addr] = var.id;
|
||||||
name_to_handle[stringf("%s.%s[%d]",var.scope.c_str(),mem_cell.c_str(),mem_addr)] = h->u.var.handle;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pos = clean_name.find_last_of("[");
|
pos = clean_name.find_last_of("[");
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos && clean_name.back() == ']') {
|
||||||
std::string mem_cell = clean_name.substr(0, pos);
|
std::string mem_cell = clean_name.substr(0, pos);
|
||||||
|
normalize_brackets(mem_cell);
|
||||||
std::string addr = clean_name.substr(pos+1);
|
std::string addr = clean_name.substr(pos+1);
|
||||||
addr.pop_back(); // remove closing bracket
|
addr.pop_back(); // remove closing bracket
|
||||||
char *endptr;
|
char *endptr;
|
||||||
int mem_addr = strtol(addr.c_str(), &endptr, 10);
|
int mem_addr = strtol(addr.c_str(), &endptr, 10);
|
||||||
if (*endptr) {
|
if (*endptr) {
|
||||||
log_warning("Error parsing memory address in : %s\n", clean_name.c_str());
|
log_debug("Error parsing memory address in : %s\n", clean_name.c_str());
|
||||||
} else {
|
} else {
|
||||||
memory_to_handle[var.scope+"."+mem_cell][mem_addr] = var.id;
|
memory_to_handle[var.scope+"."+mem_cell][mem_addr] = var.id;
|
||||||
name_to_handle[stringf("%s.%s[%d]",var.scope.c_str(),mem_cell.c_str(),mem_addr)] = h->u.var.handle;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
normalize_brackets(clean_name);
|
||||||
name_to_handle[var.scope+"."+clean_name] = h->u.var.handle;
|
name_to_handle[var.scope+"."+clean_name] = h->u.var.handle;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue