Difference between revisions of "Fanout cone and grouping"
From Verific Design Automation FAQ
(Created page with "C++ code: <nowiki> →This application example collects instances in the fanout cone of a signal, and groups those instances into a new netlist: #include "Set.h" #include...") |
|||
| Line 68: | Line 68: | ||
} | } | ||
| − | // Now, let group the fan-out into a new netlist | + | // Now, let's group the fan-out into a new netlist |
// Netlist::Group(const Set &instances, const char *inst_name, const char *cell_name, const char *netlist_name) | // Netlist::Group(const Set &instances, const char *inst_name, const char *cell_name, const char *netlist_name) | ||
top->Group(group, "new_instance", "new_cell", ""); | top->Group(group, "new_instance", "new_cell", ""); | ||
Latest revision as of 19:34, 18 April 2021
C++ code:
/* This application example collects instances in the fanout cone of a signal,
and groups those instances into a new netlist */
#include "Set.h"
#include "Array.h"
#include "Message.h"
#include "veri_file.h"
#include "DataBase.h"
#include "VeriWrite.h"
#ifdef VERIFIC_NAMESPACE
using namespace Verific ;
#endif
int main()
{
const char *file_name = "prep2.v";
const char *net_name = "compare_output";
Array files(1) ;
files.Insert(file_name) ;
if (!veri_file::AnalyzeMultipleFiles(&files, veri_file::VERILOG_2K)) {
return 1 ;
}
const char *name = veri_file::TopModule() ;
if (!veri_file::Elaborate(name /*module_name*/, "work" /*work_lib*/, 0 /*parameter_values_map*/)) return 4 ;
// After elaboration, we can now delete the parse-trees (to conserve memory) since
// we don't need them anymore.
veri_file::RemoveAllModules() ;
Netlist *top = Netlist::PresentDesign() ;
if (!top) {
Message::PrintLine("Cannot find any handle to the top-level netlist") ;
return 5 ;
}
Message::Msg(VERIFIC_INFO, 0, top->Linefile(), "last elaborated design is %s(%s)",
top->Owner()->Name(), top->Name()) ;
VeriWrite veriWriter;
veriWriter.WriteFile("netlist_out1.v", top);
const Net *net = top->GetNet(net_name);
if (!net) {
Message::Msg(VERIFIC_ERROR, 0, 0, "can't find net '%s'", net_name);
return 1 ;
}
Set fanout(POINTER_HASH) ;
top->LabelFanOut (net, fanout, 0, 0, 0);
SetIter si;
DesignObj *designobj;
Set group(POINTER_HASH) ;
FOREACH_SET_ITEM (&fanout, si, &designobj) {
if (designobj->IsInstance()) {
Message::Msg(VERIFIC_INFO, 0, 0, ">> instance '%s'", designobj->Name());
// Insert it in the set that is used for grouping later
group.Insert(designobj);
} else { // Not an Instance, must be a Net
Message::Msg(VERIFIC_INFO, 0, 0, ">> net '%s'", designobj->Name());
}
}
// Now, let's group the fan-out into a new netlist
// Netlist::Group(const Set &instances, const char *inst_name, const char *cell_name, const char *netlist_name)
top->Group(group, "new_instance", "new_cell", "");
veriWriter.WriteFile("netlist_out2.v", top);
return 0 ;
}
Perl script:
#!/usr/bin/perl
# This application example collects instances in the fanout cone of a signal,
# and groups those instances into a new netlist.
push (@INC,"../../../perlmain/install");
require "Verific.pm";
$file_name = "prep2.v";
$net_name = "compare_output";
if (!Verific::veri_file::Analyze($file_name, $Verific::veri_file::VERILOG_2K)) {
exit(1) ;
}
# Ok now let's elaborate this module. In case of failure return.
if (!Verific::veri_file::ElaborateAll()) {
exit(1) ;
}
# After elaboration, we can now delete the parse-trees (to conserve memory) since
# we don't need them anymore.
Verific::veri_file::RemoveAllModules() ;
# Get a handle to the top-level netlist
$top = Verific::Netlist::PresentDesign() ;
if (!$top) {
print "Cannot find any handle to the top-level netlist\n";
exit(1) ;
}
# Print out module that we have handle to
vfcprintf("INFO: last elaborated design is %s(%s)",$top->Linefile(),$top->Owner()->Name(), $top->Name());
$veriWriter = Verific::VeriWrite->new();
$veriWriter->WriteFile("netlist1.v", $top) ;
my $net = $top->GetNet($net_name);
if (!$net) {
print "Cannot find net $net_name";
exit(1) ;
}
my $fanout = Verific::Set::New();
$top->LabelFanOut($net, $fanout, 0, 0, 0);
my $group = Verific::Set::New();
$fanout_iter = new Verific::DesignObjSetIter($fanout);
if ($fanout_iter) {
for ($designobj = $fanout_iter->First(); $fanout_iter->GetIndex() < $fanout_iter->Size(); $designobj = $fanout_iter->Next()) {
if ($designobj->IsInstance()) {
vfcprintf("INFO: instance %s", undef, $designobj->Name());
# insert the instance in a set that will be used later to create a new level of hierarchy
$group->Insert($designobj);
} else {
vfcprintf("INFO: net %s", undef, $designobj->Name());
}
}
}
# Group the fanout into a new level of hierarchy
$top->Group($group, "new_instance", "new_cell", "");
$veriWriter->WriteFile("netlist2.v", $top) ;
exit(0) ;
# 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;
}
Verilog testcase, prep2.v:
// PREP Benchmark 2, Timer/Counter /* PREP2 contains 8 bit registers, a mux, counter and comparator Copyright (c) 1994 Synplicity, Inc. You may distribute freely, as long as this header remains attached. */ module prep2(DATA0, CLK, RST, SEL, LDCOMP, LDPRE, DATA1, DATA2); output [7:0] DATA0; input CLK, RST, SEL, LDCOMP, LDPRE; input [7:0] DATA1, DATA2; reg [7:0] DATA0; reg [7:0] highreg_output, lowreg_output; // internal registers wire compare_output = DATA0 == lowreg_output; // comparator wire [7:0] mux_output = SEL ? DATA1 : highreg_output; // mux // registers always @ (posedge CLK or posedge RST) begin if (RST) begin highreg_output = 0; lowreg_output = 0; end else begin if (LDPRE) highreg_output = DATA2; if (LDCOMP) lowreg_output = DATA2; end end // counter always @(posedge CLK or posedge RST) begin if (RST) DATA0 = 0; else if (compare_output) // load DATA0 = mux_output; else DATA0 = DATA0 + 1; end endmodule <./nowiki>