In Verilog parsetree adding names to unnamed instances
From Verific Design Automation FAQ
Revision as of 12:58, 24 April 2023 by Hoa (Talk | contribs) (Created page with "In Verilog, each module instantiation should have a name. But name is optional for UDP instantiation and Verilog primitive instantiation. Verific issues a warning for unnamed...")
In Verilog, each module instantiation should have a name. But name is optional for UDP instantiation and Verilog primitive instantiation.
Verific issues a warning for unnamed module instantiation:
test.v(16): WARNING: instantiating unknown module 'foo' (VERI-1063)
The warning is issued during elaboration because in analysis, it is not known whether the instantiated construct is a module, a UDP, or a primitive.
This application adds a name to each unnamed module instantiation. Note that this application has facilities to keep track of the scope of the instantiation statement.
#include <iostream> #include "veri_file.h" #include "VeriModule.h" #include "VeriId.h" #include "VeriExpression.h" #include "VeriScope.h" #include "Map.h" using namespace std ; #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif class MyVisitor : public VeriVisitor { public: MyVisitor() : VeriVisitor(), _scope_stack(0) { } virtual ~MyVisitor() { } virtual void VERI_VISIT(VeriModuleInstantiation, node) { VeriScope *current_scope = GetCurrentScope() ; Array *inst_ids ; inst_ids = node.GetIds() ; unsigned i ; VeriInstId *inst_id ; FOREACH_ARRAY_ITEM(inst_ids, i, inst_id) { if (!inst_id) continue ; const char *inst_name = inst_id->InstName() ; char *allocated_inst_name = 0 ; if (!inst_name && current_scope) { VeriIdDef *scope_id = current_scope->GetOwner(); unsigned uniq_no = 0 ; char *suffix = Strings::itoa((int)(uniq_no)) ; char *prefix = (scope_id && scope_id->Name()) ? Strings::save("unnamed_inst_", scope_id->Name(), "_") : Strings::save("unnamed_inst_") ; allocated_inst_name = Strings::save(prefix, suffix) ; while (current_scope->FindLocal(allocated_inst_name) && (uniq_no < 1000)) { Strings::free(allocated_inst_name) ; Strings::free(suffix) ; suffix = Strings::itoa((int)(uniq_no)) ; allocated_inst_name = Strings::save(prefix, suffix) ; uniq_no++ ; } inst_id->SetName(allocated_inst_name) ; current_scope->Declare(inst_id, 0, 0) ; Strings::free(allocated_inst_name) ; Strings::free(suffix) ; Strings::free(prefix) ; } } } virtual void PreAction(VeriTreeNode &node) { // Push the scope of the current node into the stack: const VeriModuleItem *item = dynamic_cast<VeriModuleItem *>(&node) ; VeriScope *scope = (item) ? item->GetScope() : 0 ; if (scope) _scope_stack.InsertLast(scope) ; } virtual void PostAction(VeriTreeNode &node) { // Pop the scope of the current node from the stack: const VeriModuleItem *item = dynamic_cast<VeriModuleItem *>(&node) ; VeriScope *scope = (item) ? item->GetScope() : 0 ; if (scope) (void) _scope_stack.RemoveLast() ; } // Get the current/active scope for the parse tree we are visiting: VeriScope *GetCurrentScope() const { return (_scope_stack.Size()) ? (VeriScope *)_scope_stack.GetLast() : 0 ; } private: Array _scope_stack ; } ; int main() { if (!veri_file::Analyze("test.v", veri_file::SYSTEM_VERILOG)) return 1 ; veri_file::PrettyPrint ("pp_out_before.v.golden.new", 0) ; MyVisitor mv ; MapIter mi ; VeriModule *mod ; FOREACH_VERILOG_MODULE(mi, mod) { if (!mod) continue ; mod->Accept(mv) ; } veri_file::PrettyPrint ("pp_out_after.v.golden.new", 0) ; return 0 ; }