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]); } } });