Difference between revisions of "Traverse instances in parsetree"
From Verific Design Automation FAQ
Line 213: | Line 213: | ||
[hoa@awing0 HD]$ | [hoa@awing0 HD]$ | ||
+ | </nowiki> | ||
+ | |||
+ | Python: | ||
+ | <nowiki> | ||
+ | #!/usr/bin/python | ||
+ | |||
+ | import sys | ||
+ | sys.path.append('../../pythonmain/install') | ||
+ | import Verific | ||
+ | |||
+ | def TraverseVhdl(unit, arch_name): | ||
+ | # Find the architecture of the unit: | ||
+ | if not unit: return | ||
+ | arch = unit.GetSecondaryUnit(arch_name) | ||
+ | if not arch: return | ||
+ | # Find the scope: | ||
+ | scope = arch.LocalScope() | ||
+ | if not scope: return | ||
+ | |||
+ | # Get the declared ids from that scope: | ||
+ | ids = Verific.VhdlIdDefMapIter(scope.DeclArea()) | ||
+ | id = ids.First() | ||
+ | while (id): | ||
+ | stmt = id.GetStatement() | ||
+ | if not stmt: | ||
+ | id = ids.Next() | ||
+ | continue | ||
+ | # Routine to print the hierarchy: | ||
+ | PrintDesignUnit(stmt) | ||
+ | id = ids.Next() | ||
+ | |||
+ | def PrintDesignUnit(stmt): | ||
+ | if not stmt: return | ||
+ | |||
+ | # Get the array of statements, for loop/block statements | ||
+ | # we get an array of statements and recursively go to the | ||
+ | # inner most statement and print the hierarchy. | ||
+ | stmts = Verific.VhdlStatementArrayIter(stmt.GetStatements()) | ||
+ | inner_stmt = stmts.First() | ||
+ | while (inner_stmt): | ||
+ | PrintDesignUnit(inner_stmt) | ||
+ | inner_stmt = stmts.Next() | ||
+ | |||
+ | inst_unit = stmt.GetInstantiatedUnit() # Get the instantiated unit id for instances only | ||
+ | if not inst_unit: return # Not an instance level | ||
+ | |||
+ | # Processing instance | ||
+ | id = stmt.GetLabel() | ||
+ | if not id: return | ||
+ | Verific.Message.PrintLine("Processing instance : ", id.Name()) | ||
+ | |||
+ | if inst_unit.IsComponent(): | ||
+ | Verific.Message.PrintLine("Component instance, name of component is ", inst_unit.Name()) | ||
+ | Verific.Message.PrintLine("\n") | ||
+ | |||
+ | prim_unit = inst_unit.GetPrimaryUnit() | ||
+ | if not prim_unit: return | ||
+ | |||
+ | if prim_unit.IsVerilogModule(): | ||
+ | # Get instantiated verilog module | ||
+ | veri_module = Verific.vhdl_file.GetVerilogModuleFromlib(inst_unit.GetContainingLibraryName(), inst_unit.Name()) | ||
+ | if not veri_module: return | ||
+ | Verific.Message.PrintLine("instantiated Verilog module : ", veri_module.Name()) | ||
+ | Verific.Message.PrintLine("\n") | ||
+ | else: | ||
+ | instantiated_unit_name = stmt.GetInstantiatedUnitNameNode() | ||
+ | if not instantiated_unit_name: return | ||
+ | # Find the architecture name and traverse the vhdl design | ||
+ | arch_name = instantiated_unit_name.ArchitectureNameAspect() | ||
+ | if not arch_name: return | ||
+ | Verific.Message.PrintLine("instantiated VHDL unit : ", prim_unit.Name()) | ||
+ | Verific.Message.PrintLine("architecture name : ", arch_name) | ||
+ | Verific.Message.PrintLine("\n") | ||
+ | TraverseVhdl(prim_unit, arch_name) # Traverse the VHDL unit | ||
+ | |||
+ | # Set default library path to auto-load standard packages | ||
+ | if not Verific.vhdl_file.SetDefaultLibraryPath("../../vhdl_packages/vdbs_1993"): | ||
+ | print ("Error during analysis, exiting") | ||
+ | sys.exit(1) | ||
+ | |||
+ | # Analyze the design | ||
+ | if not Verific.veri_file.Analyze("test.v", Verific.veri_file.SYSTEM_VERILOG, "work"): | ||
+ | print ("Analyze failure. Exiting") | ||
+ | sys.exit(2) | ||
+ | |||
+ | if not Verific.vhdl_file.Analyze("test.vhd", "work", Verific.vhdl_file.VHDL_93): | ||
+ | print ("Analyze failure. Exiting") | ||
+ | sys.exit(2) | ||
+ | |||
+ | # Get the library | ||
+ | lib = Verific.vhdl_file.GetLibrary("work") | ||
+ | if not lib: | ||
+ | print ("Can't get library 'work'") | ||
+ | sys.exit(3) | ||
+ | |||
+ | # Check all the primary units of the library | ||
+ | top_entity = lib.GetPrimUnit("comp") | ||
+ | if not top_entity: | ||
+ | sys.exit(4) | ||
+ | |||
+ | if not Verific.vhdl_file.Elaborate("comp", "work", None, None, 1): | ||
+ | sys.exit(5) | ||
+ | |||
+ | Verific.Message.PrintLine("\n") | ||
+ | top_entity.Info("Start hierarchy traversal here at VHDL top level unit '%s'", top_entity.Name()) | ||
+ | Verific.Message.PrintLine("\n") | ||
+ | TraverseVhdl(top_entity, None) | ||
</nowiki> | </nowiki> |
Revision as of 20:40, 22 July 2024
C++:
// Verific utilities #include "Array.h" // Make class Array available #include "Set.h" // Make class Set available #include "Message.h" // Make message handlers available #include "Strings.h" // Definition of class to manipulate, copy, concatenate, create etc... // Verific Verilog parser #include "VeriModule.h" #include "veri_file.h" // Verific VHDL parser #include "vhdl_file.h" #include "VhdlIdDef.h" #include "VhdlScope.h" #include "VhdlStatement.h" #include "VhdlName.h" // Definition of VhdlName #include "VhdlUnits.h" // Definition of VhdlLibrary #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif // Routines for traversing the entity instances in DFS order and print them. static void PrintDesignUnit(const VhdlStatement *stmt) ; static void TraverseVhdl(const VhdlPrimaryUnit *top, const char *arch_name) ; int main(int argc, const char **argv) { vhdl_file::SetDefaultLibraryPath("../vdbs") ; if (!veri_file::Analyze("test.v")) return 1 ; if (!vhdl_file::Analyze("test.vhd")) return 1 ; VhdlLibrary *lib = vhdl_file::GetLibrary("work") ; VhdlPrimaryUnit *top_entity = lib ? lib->GetPrimUnit("comp") : 0 ; // Get the top-level entity if (!top_entity) { return 1 ; } if (!vhdl_file::Elaborate("comp", "work", 0, 0, 1)) { return 2 ; } Message::PrintLine("\n") ; top_entity->Info("Start hierarchy traversal here at VHDL top level unit '%s'", top_entity->Name()) ; Message::PrintLine("\n") ; TraverseVhdl(top_entity, 0 /*architecture name*/) ; // Traverse top level unit and the hierarchy under it return 0 ; // all good } // Traverse an entity and the hierarchy under it: static void TraverseVhdl(const VhdlPrimaryUnit *unit, const char *arch_name) { // Find the architecture of the unit: VhdlSecondaryUnit *arch = unit? unit->GetSecondaryUnit(arch_name) : 0 ; // Find the scope: VhdlScope *scope = arch ? arch->LocalScope() : 0 ; // Get the declared ids from that scope: Map *ids = scope ? scope->DeclArea() : 0 ; MapIter mi ; VhdlIdDef *id ; FOREACH_MAP_ITEM(ids, mi, 0, &id) { if (!id) continue ; VhdlStatement *stmt = id->GetStatement() ; if (!stmt) continue ; // Routine to print the hierarchy: PrintDesignUnit(stmt) ; } } // Print the hierarchy static void PrintDesignUnit(const VhdlStatement *stmt) { if (!stmt) return ; // Get the array of statements, for loop/block statements // we get an array of statements and recursively go to the // inner most statement and print the hierarchy. Array *stmts = stmt->GetStatements() ; unsigned ai ; VhdlStatement *inner_stmt ; FOREACH_ARRAY_ITEM(stmts, ai, inner_stmt) { PrintDesignUnit(inner_stmt) ; } VhdlIdDef *inst_unit = stmt->GetInstantiatedUnit() ; // Get the instantiated unit id for instances only if (!inst_unit) return ; // Not an instance level // Processing instance VhdlIdDef *id = stmt->GetLabel() ; Message::PrintLine("Processing instance : ", id ? id->Name() : 0) ; if (inst_unit->IsComponent()) { // instance of component Message::PrintLine("Component instance, name of component is ", inst_unit->Name()) ; Message::PrintLine("\n") ; } VhdlPrimaryUnit *prim_unit = inst_unit ? inst_unit->GetPrimaryUnit() : 0 ; // Get the primary unit if (!prim_unit) return ; if (prim_unit->IsVerilogModule()) { // instance of Verilog module // Get instantiated verilog module VeriModule *veri_module = vhdl_file::GetVerilogModuleFromlib(inst_unit->GetContainingLibraryName(), inst_unit->Name()) ; if (!veri_module) return ; Message::PrintLine("instantiated Verilog module : ", veri_module->Name()) ; Message::PrintLine("\n") ; } else { // Instance of vhdl unit VhdlName *instantiated_unit_name = stmt->GetInstantiatedUnitNameNode() ; // Find the architecture name and traverse the vhdl design const char *arch_name = instantiated_unit_name ? instantiated_unit_name->ArchitectureNameAspect(): 0 ; Message::PrintLine("instantiated VHDL unit : ", prim_unit->Name()) ; Message::PrintLine("architecture name : ", arch_name ? arch_name : 0) ; Message::PrintLine("\n") ; TraverseVhdl(prim_unit, arch_name) ; // Traverse the VHDL unit } }
test.vhd:
entity child is -- instantiated in test module in Verilog design generic (p : integer := 3); port (S1, S2: out bit_vector (p downto 0); I1 : in bit_vector (p downto 0)); end ; architecture arch of child is begin S1 <= I1 ; S2 <= not I1 ; end ; entity comp is -- top-level unit port(X, Y: in BIT_VECTOR(3 DOWNTO 0); S1, S2: out bit_vector (3 DOWNTO 0); S3, S4: out bit_vector (3 DOWNTO 0); Sum, Carry: out BIT); end; architecture Structure of comp is component child is generic (p : integer) ; port (S1, S2: out BIT_VECTOR(p DOWNTO 0); I1 : in BIT_VECTOR(p downto 0)); end component; begin L1: entity work.xor_gate generic map (4) port map (X, Y, Sum); L2 : component child generic map (3) port map(S1, S2, X) ; blk : block begin L3 : entity work.child(arch) generic map (3) port map(S3, S4, X) ; end block ; end;
test.v:
module xor_gate (CompIn1, CompIn2, CompOut); // Instantiated in 'comp' entity in VHDL file test.vhd parameter p = 10 ; input [3:0]CompIn1; input [3:0]CompIn2; output CompOut; endmodule
Run:
[hoa@awing0 HD]$ test-linux -- Analyzing Verilog file 'test.v' (VERI-1482) -- Analyzing VHDL file 'test.vhd' (VHDL-1481) -- Restoring VHDL unit 'std.standard' from file '../vdbs/std/standard.vdb' (VHDL-1493) test.vhd(1): INFO: analyzing entity 'child' (VHDL-1012) test.vhd(7): INFO: analyzing architecture 'arch' (VHDL-1010) test.vhd(13): INFO: analyzing entity 'comp' (VHDL-1012) test.vhd(22): INFO: analyzing architecture 'structure' (VHDL-1010) -- Restoring VHDL unit 'vl.vl_types' from file '../vdbs/vl/vl_types.vdb' (VHDL-1493) test.vhd(13): INFO: processing 'comp(Structure)' (VHDL-1067) test.vhd(33): INFO: switching to Verilog mode to elaborate module 'xor_gate' (VHDL-1399) test.v(1): INFO: compiling module 'xor_gate(p=4)' (VERI-1018) test.vhd(33): INFO: returning to VHDL mode to continue with elaboration (VHDL-1400) test.vhd(1): INFO: processing 'child_default(arch)' (VHDL-1067) -- test.vhd(20): INFO: Start hierarchy traversal here at VHDL top level unit 'comp' -- -- Processing instance : l1 -- instantiated Verilog module : xor_gate(p=4) -- -- Processing instance : l2 -- instantiated VHDL unit : child_default -- architecture name : arch -- -- Processing instance : l3 -- instantiated VHDL unit : child_default -- architecture name : arch -- [hoa@awing0 HD]$
Python:
#!/usr/bin/python import sys sys.path.append('../../pythonmain/install') import Verific def TraverseVhdl(unit, arch_name): # Find the architecture of the unit: if not unit: return arch = unit.GetSecondaryUnit(arch_name) if not arch: return # Find the scope: scope = arch.LocalScope() if not scope: return # Get the declared ids from that scope: ids = Verific.VhdlIdDefMapIter(scope.DeclArea()) id = ids.First() while (id): stmt = id.GetStatement() if not stmt: id = ids.Next() continue # Routine to print the hierarchy: PrintDesignUnit(stmt) id = ids.Next() def PrintDesignUnit(stmt): if not stmt: return # Get the array of statements, for loop/block statements # we get an array of statements and recursively go to the # inner most statement and print the hierarchy. stmts = Verific.VhdlStatementArrayIter(stmt.GetStatements()) inner_stmt = stmts.First() while (inner_stmt): PrintDesignUnit(inner_stmt) inner_stmt = stmts.Next() inst_unit = stmt.GetInstantiatedUnit() # Get the instantiated unit id for instances only if not inst_unit: return # Not an instance level # Processing instance id = stmt.GetLabel() if not id: return Verific.Message.PrintLine("Processing instance : ", id.Name()) if inst_unit.IsComponent(): Verific.Message.PrintLine("Component instance, name of component is ", inst_unit.Name()) Verific.Message.PrintLine("\n") prim_unit = inst_unit.GetPrimaryUnit() if not prim_unit: return if prim_unit.IsVerilogModule(): # Get instantiated verilog module veri_module = Verific.vhdl_file.GetVerilogModuleFromlib(inst_unit.GetContainingLibraryName(), inst_unit.Name()) if not veri_module: return Verific.Message.PrintLine("instantiated Verilog module : ", veri_module.Name()) Verific.Message.PrintLine("\n") else: instantiated_unit_name = stmt.GetInstantiatedUnitNameNode() if not instantiated_unit_name: return # Find the architecture name and traverse the vhdl design arch_name = instantiated_unit_name.ArchitectureNameAspect() if not arch_name: return Verific.Message.PrintLine("instantiated VHDL unit : ", prim_unit.Name()) Verific.Message.PrintLine("architecture name : ", arch_name) Verific.Message.PrintLine("\n") TraverseVhdl(prim_unit, arch_name) # Traverse the VHDL unit # Set default library path to auto-load standard packages if not Verific.vhdl_file.SetDefaultLibraryPath("../../vhdl_packages/vdbs_1993"): print ("Error during analysis, exiting") sys.exit(1) # Analyze the design if not Verific.veri_file.Analyze("test.v", Verific.veri_file.SYSTEM_VERILOG, "work"): print ("Analyze failure. Exiting") sys.exit(2) if not Verific.vhdl_file.Analyze("test.vhd", "work", Verific.vhdl_file.VHDL_93): print ("Analyze failure. Exiting") sys.exit(2) # Get the library lib = Verific.vhdl_file.GetLibrary("work") if not lib: print ("Can't get library 'work'") sys.exit(3) # Check all the primary units of the library top_entity = lib.GetPrimUnit("comp") if not top_entity: sys.exit(4) if not Verific.vhdl_file.Elaborate("comp", "work", None, None, 1): sys.exit(5) Verific.Message.PrintLine("\n") top_entity.Info("Start hierarchy traversal here at VHDL top level unit '%s'", top_entity.Name()) Verific.Message.PrintLine("\n") TraverseVhdl(top_entity, None)