Difference between revisions of "Traverse instances in parsetree"
From Verific Design Automation FAQ
| Line 122: | Line 122: | ||
</nowiki> | </nowiki> | ||
| − | + | Python script: | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | Python: | + | |
<nowiki> | <nowiki> | ||
#!/usr/bin/python | #!/usr/bin/python | ||
| Line 320: | Line 227: | ||
Verific.Message.PrintLine("\n") | Verific.Message.PrintLine("\n") | ||
TraverseVhdl(top_entity, None) | TraverseVhdl(top_entity, None) | ||
| + | </nowiki> | ||
| + | |||
| + | test.vhd: | ||
| + | <nowiki> | ||
| + | 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; | ||
| + | </nowiki> | ||
| + | |||
| + | test.v: | ||
| + | <nowiki> | ||
| + | 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 | ||
| + | </nowiki> | ||
| + | |||
| + | Run: | ||
| + | <nowiki> | ||
| + | [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]$ | ||
</nowiki> | </nowiki> | ||
Latest revision as of 20:44, 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
}
}
Python script:
#!/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)
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]$