summaryrefslogtreecommitdiffstats
path: root/src/base/wlc/wlcShow.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2017-01-26 15:17:02 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2017-01-26 15:17:02 -0800
commit7d82819d519595854c4e1b9dbf99d91e1d2ab9f9 (patch)
treec0f6482c15f4b83642e62d81c09f6b0e842ed43a /src/base/wlc/wlcShow.c
parent3c8c807ac16dbfc9b1960f77dd49fd244e3d718d (diff)
downloadabc-7d82819d519595854c4e1b9dbf99d91e1d2ab9f9.tar.gz
abc-7d82819d519595854c4e1b9dbf99d91e1d2ab9f9.tar.bz2
abc-7d82819d519595854c4e1b9dbf99d91e1d2ab9f9.zip
Adding visualization of word-level networks Wlc_Ntk_t.
Diffstat (limited to 'src/base/wlc/wlcShow.c')
-rw-r--r--src/base/wlc/wlcShow.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c
new file mode 100644
index 00000000..dd25c7a3
--- /dev/null
+++ b/src/base/wlc/wlcShow.c
@@ -0,0 +1,331 @@
+/**CFile****************************************************************
+
+ FileName [wlcShow.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Parses several flavors of word-level Verilog.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlcShow.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the graph structure of WLC for DOT.]
+
+ Description [Useful for graph visualization using tools such as GraphViz:
+ http://www.graphviz.org/]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold )
+{
+ FILE * pFile;
+ Wlc_Obj_t * pNode;
+ int LevelMax, Prev, Level, i;
+
+ if ( Wlc_NtkObjNum(p) > 500 )
+ {
+ fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 500 );
+ return;
+ }
+ if ( (pFile = fopen( pFileName, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // mark the nodes
+ if ( vBold )
+ Wlc_NtkForEachObjVec( vBold, p, pNode, i )
+ pNode->Mark = 1;
+
+ // compute levels
+ LevelMax = 1 + Wlc_NtkCreateLevelsRev( p );
+
+ // write the DOT header
+ fprintf( pFile, "# %s\n", "WLC structure generated by ABC" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "digraph WLC {\n" );
+ fprintf( pFile, "size = \"7.5,10\";\n" );
+// fprintf( pFile, "ranksep = 0.5;\n" );
+// fprintf( pFile, "nodesep = 0.5;\n" );
+ fprintf( pFile, "center = true;\n" );
+// fprintf( pFile, "orientation = landscape;\n" );
+// fprintf( pFile, "edge [fontsize = 10];\n" );
+// fprintf( pFile, "edge [dir = none];\n" );
+ fprintf( pFile, "edge [dir = back];\n" );
+ fprintf( pFile, "\n" );
+
+ // labels on the left of the picture
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " node [shape = plaintext];\n" );
+ fprintf( pFile, " edge [style = invis];\n" );
+ fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
+ fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
+ // generate node names with labels
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ fprintf( pFile, " [label = " );
+ // label name
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "];\n" );
+ }
+
+ // genetate the sequence of visible/invisible nodes to mark levels
+ fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ // the connector
+ if ( Level != 0 )
+ fprintf( pFile, " ->" );
+ else
+ fprintf( pFile, ";" );
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate title box on top
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle1;\n" );
+ fprintf( pFile, " title1 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=20,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "%s", "WLC structure generated by ABC" );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "Benchmark \\\"%s\\\". ", p->pName );
+// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate statistics box
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle2;\n" );
+ fprintf( pFile, " title2 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=18,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkPiNum(p)-Wlc_NtkPoNum(p)-Wlc_NtkFfNum(p), LevelMax-1 );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate the COs
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", LevelMax );
+ // generate the CO nodes
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ fprintf( pFile, " NodePo%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
+ fprintf( pFile, ", shape = %s", "invtriangle" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate nodes of each rank
+ for ( Level = LevelMax - 1; Level > 0; Level-- )
+ {
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", Level );
+ Wlc_NtkForEachObj( p, pNode, i )
+ {
+ if ( (int)Wlc_ObjLevel(p, pNode) != Level )
+ continue;
+
+ if ( pNode->Type == WLC_OBJ_CONST )
+ {
+ fprintf( pFile, " Node%d [label = \"0x", i );
+ Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 );
+ fprintf( pFile, "\"" );
+ }
+ else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_MUX )
+ fprintf( pFile, " Node%d [label = \"%d\"", i, Wlc_ObjRange(pNode) );
+ else if ( pNode->Type >= WLC_OBJ_LOGIC_NOT && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
+ fprintf( pFile, " Node%d [label = \"%s\"", i, Wlc_ObjTypeName(pNode) );
+ else
+ fprintf( pFile, " Node%d [label = \"%s %d\"", i, Wlc_ObjTypeName(pNode), Wlc_ObjRange(pNode) );
+
+ if ( pNode->Type == WLC_OBJ_ARI_MULTI )
+ fprintf( pFile, ", shape = doublecircle" );
+ else if ( pNode->Type >= WLC_OBJ_COMP_EQU && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
+ fprintf( pFile, ", shape = diamond" );
+ else if ( pNode->Type == WLC_OBJ_BIT_SELECT || pNode->Type == WLC_OBJ_BIT_CONCAT )
+ fprintf( pFile, ", shape = box" );
+ else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_BIT_ZEROPAD || pNode->Type == WLC_OBJ_BIT_SIGNEXT )
+ fprintf( pFile, ", shape = triangle" );
+ else if ( pNode->Type == WLC_OBJ_MUX )
+ fprintf( pFile, ", shape = trapezium" );
+ else
+ fprintf( pFile, ", shape = ellipse" );
+
+ if ( vBold ? pNode->Mark : ((pNode->Type >= WLC_OBJ_ARI_ADD && pNode->Type <= WLC_OBJ_ARI_SQUARE) || pNode->Type == WLC_OBJ_BIT_NOT) )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ }
+
+ // generate the CI nodes
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", 0 );
+ // generate the CI nodes
+ Wlc_NtkForEachCi( p, pNode, i )
+ {
+ fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
+ fprintf( pFile, ", shape = %s", "triangle" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate invisible edges from the square down
+ fprintf( pFile, "title1 -> title2 [style = invis];\n" );
+ Wlc_NtkForEachCo( p, pNode, i )
+ fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) );
+ // generate invisible edges among the COs
+ Prev = -1;
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ if ( i > 0 )
+ fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
+ Prev = Wlc_ObjId(p, pNode);
+ }
+ // generate invisible edges among the CIs
+ Prev = -1;
+ Wlc_NtkForEachCi( p, pNode, i )
+ {
+ if ( i > 0 )
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
+ Prev = Wlc_ObjId(p, pNode);
+ }
+
+ // generate edges
+ Wlc_NtkForEachObj( p, pNode, i )
+ {
+ int k, iFanin;
+ if ( Wlc_ObjIsCi(pNode) )
+ continue;
+ if ( Wlc_ObjIsCo(pNode) )
+ {
+ // generate the edge from this node to the next
+ fprintf( pFile, "NodePo%d", i );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", i );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "bold" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ // generate the edge from this node to the next
+ Wlc_ObjForEachFanin( pNode, iFanin, k )
+ {
+ fprintf( pFile, "Node%d", i );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", iFanin );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "bold" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+
+ // unmark nodes
+ if ( vBold )
+ Wlc_NtkCleanMarks( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold )
+{
+ extern void Abc_ShowFile( char * FileNameDot );
+ FILE * pFile;
+ char FileNameDot[200];
+ sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(p->pName, ".dot") );
+ // check that the file can be opened
+ if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
+ return;
+ }
+ fclose( pFile );
+ // generate the file
+ Wlc_NtkDumpDot( p, FileNameDot, vBold );
+ // visualize the file
+ Abc_ShowFile( FileNameDot );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+