systemverilog-plugin: Use current scope in check memories
Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 38c42a7..8d2527f 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -407,12 +407,16 @@
static void check_memories(AST::AstNode *module_node)
{
std::map<std::string, AST::AstNode *> memories;
+ std::string current_scope_str = "";
visitEachDescendant(module_node, [&](AST::AstNode *node) {
+ if (node->type == AST::AST_GENBLOCK) {
+ current_scope_str = "." + node->str;
+ }
if (node->str == "\\$readmemh") {
if (node->children.size() != 2 || node->children[1]->str.empty() || node->children[1]->type != AST::AST_IDENTIFIER) {
log_error("%s:%d: Wrong usage of '\\$readmemh'\n", node->filename.c_str(), node->location.first_line);
}
- if (memories[node->children[1]->str])
+ if (memories[current_scope_str + node->children[1]->str])
add_force_convert_attribute(memories[node->children[1]->str], 0);
}
if (node->type == AST::AST_WIRE) {
@@ -422,37 +426,54 @@
? node->attributes[UhdmAst::unpacked_ranges()]->children
: std::vector<AST::AstNode *>();
if (packed_ranges.size() == 1 && unpacked_ranges.size() == 1) {
- log_assert(!memories.count(node->str));
- memories[node->str] = node;
+ log_assert(!memories.count(current_scope_str + node->str));
+ memories[current_scope_str + node->str] = node;
}
}
- if (node->type == AST::AST_IDENTIFIER && memories.count(node->str)) {
- if (!memories[node->str]->attributes.count(UhdmAst::force_convert())) {
- bool force_convert = false;
- // convert memory to list of registers
- // in case of access to whole memory
- // or slice of memory
- // e.g.
- // logic [3:0] mem [8:0];
- // always_ff @ (posedge clk) begin
- // mem <= '{default:0};
- // mem[7:1] <= mem[6:0];
- // end
- // don't convert in case of accessing
- // memory using address, e.g.
- // mem[0] <= '{default:0}
- //
- // Access to whole memory
- if (node->children.size() == 0) {
- force_convert = true;
+ if (node->type == AST::AST_IDENTIFIER) {
+ std::string name = current_scope_str + node->str;
+ bool force_convert = false;
+ if (memories.count(name)) {
+ if (!memories[name]->attributes.count(UhdmAst::force_convert())) {
+ // convert memory to list of registers
+ // in case of access to whole memory
+ // or slice of memory
+ // e.g.
+ // logic [3:0] mem [8:0];
+ // always_ff @ (posedge clk) begin
+ // mem <= '{default:0};
+ // mem[7:1] <= mem[6:0];
+ // end
+ // don't convert in case of accessing
+ // memory using address, e.g.
+ // mem[0] <= '{default:0}
+ //
+ // Access to whole memory
+ if (node->children.size() == 0) {
+ force_convert = true;
+ }
+ // Access to slice of memory
+ if (node->children.size() == 1 && node->children[0]->children.size() != 1) {
+ force_convert = true;
+ }
}
- // Access to slice of memory
- if (node->children.size() == 1 && node->children[0]->children.size() != 1) {
- force_convert = true;
+ } else {
+ name = node->str;
+ if (memories.count(name)) {
+ if (!memories[name]->attributes.count(UhdmAst::force_convert())) {
+ // Access to whole memory
+ if (node->children.size() == 0) {
+ force_convert = true;
+ }
+ // Access to slice of memory
+ if (node->children.size() == 1 && node->children[0]->children.size() != 1) {
+ force_convert = true;
+ }
+ }
}
- if (force_convert) {
- add_force_convert_attribute(memories[node->str]);
- }
+ }
+ if (force_convert) {
+ add_force_convert_attribute(memories[name]);
}
}
});