Create a Netlist Database from scratch (not from RTL elaboration)

From Verific Design Automation FAQ
Jump to: navigation, search
#!/usr/bin/perl
use strict;

push (@INC,"../../../extra_tests/pm");
require "Verific.pm";

# The global Libset is already at the top of the netlist database.
# No need to create, just get a handle to it.
my $libset = Verific::Libset::Global();

# Add new library.  If RTL elaboration has been run, a library has been created
# already.  The default library is "work".
my $lib = Verific::Library->new("mylib");
$libset->Add($lib);

# Add cell to the library.  In the Verilog netlist output, the cell name is the
# same as the module name.
my $cell = Verific::Cell->new("mycell");
$lib->Add($cell);

# Add netlist to cell.  In the Verilog netlist output, the netlist name doesn't matter.
my $netlist = Verific::Netlist->new("mynetlist");
$cell->Add($netlist);

# Add ports to netlist
my $inport = Verific::Port->new("in", $Verific::DIR_IN);
$netlist->Add($inport);
my $outport = Verific::Port->new("out", $Verific::DIR_OUT);
$netlist->Add($outport);

# Add nets (Verilog: wire) to netlist
my $net1 = Verific::Net->new("in");
$netlist->Add($net1);
$net1->Connect($inport);

my $net2 = Verific::Net->new("out");
$netlist->Add($net2);
$net2->Connect($outport);

my $net3 = Verific::Net->new("n1");
$netlist->Add($net3);

# Add new library
my $primlib = Verific::Library->new("myprimitives");
$libset->Add($primlib);
# Create primitive inv
my $invcell = Verific::Cell->new("inv");
$primlib->Add($invcell);
my $invnetlist = Verific::Netlist->new("primitive");
$invcell->Add($invnetlist);
my $Ainport = Verific::Port->new("A", $Verific::DIR_IN);
$invnetlist->Add($Ainport);
my $Zoutport = Verific::Port->new("Z", $Verific::DIR_OUT);
$invnetlist->Add($Zoutport);
# Create primitive buff
my $buffcell = Verific::Cell->new("buff");
$primlib->Add($buffcell);
my $buffnetlist = Verific::Netlist->new("primitive");
$buffcell->Add($buffnetlist);
$Ainport = Verific::Port->new("A", $Verific::DIR_IN);
$buffnetlist->Add($Ainport);
$Zoutport = Verific::Port->new("Z", $Verific::DIR_OUT);
$buffnetlist->Add($Zoutport);

# Instantiate inv in mynetlist
my $inst = $netlist->Add(Verific::Instance->new("inv1", $invnetlist));
if ($inst) {
    my $port = $invnetlist->GetPort("A");
    if ($port) {$net1->Connect($inst, $port);}
    $port = $invnetlist->GetPort("Z");
    if ($port) {$net3->Connect($inst, $port);}
}

# Instantiate buff in mynetlist
$inst = $netlist->Add(Verific::Instance->new("buff2", $buffnetlist));
if ($inst) {
    my $port = $buffnetlist->GetPort("A");
    if ($port) {$net3->Connect($inst, $port);}
    $port = $buffnetlist->GetPort("Z");
    if ($port) {$net2->Connect($inst, $port);}
}

# write netlist
my $veriWriter = Verific::VeriWrite->new();
$veriWriter->WriteFile(sprintf("%s.v",$netlist->Owner->Name()), $netlist);

exit(1);

# moved this to a subroutine to keep above code clean,
# this subroutine shows how to resolve linefile information
sub vfcprintf {
   my ($format) = (@_[0]);
   my ($lf) = (@_[1]);
   my @PARAMS;
   for (my $i = 2; $i < scalar(@_); $i++) {
       push(@PARAMS,"@_[$i]");
   }   
   my $lf_format = ""; 
   if (Verific::LineFile::GetFileName($lf) && Verific::LineFile::GetLineNo($lf)) {
       my $lf_format = sprintf("%s(%s)",Verific::LineFile::GetFileName($lf), Verific::LineFile::GetLineNo($lf));
       printf "%s: $format\n",$lf_format,@PARAMS;
   } else {
       printf "$format\n",@PARAMS;
   }   

   return 0;
}