abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ioWriteDot.c File Reference
#include "ioAbc.h"
#include "base/main/main.h"
#include "map/mio/mio.h"

Go to the source code of this file.

Functions

static
ABC_NAMESPACE_IMPL_START char * 
Abc_NtkPrintSop (char *pSop)
 DECLARATIONS ///. More...
 
static int Abc_NtkCountLogicNodes (Vec_Ptr_t *vNodes)
 
void Io_WriteDot (Abc_Ntk_t *pNtk, char *FileName)
 FUNCTION DEFINITIONS ///. More...
 
void Io_WriteDotNtk (Abc_Ntk_t *pNtk, Vec_Ptr_t *vNodes, Vec_Ptr_t *vNodesShow, char *pFileName, int fGateNames, int fUseReverse)
 
void Io_WriteDotSeq (Abc_Ntk_t *pNtk, Vec_Ptr_t *vNodes, Vec_Ptr_t *vNodesShow, char *pFileName, int fGateNames, int fUseReverse)
 

Function Documentation

int Abc_NtkCountLogicNodes ( Vec_Ptr_t vNodes)
static

Function*************************************************************

Synopsis [Computes the printable SOP form.]

Description []

SideEffects []

SeeAlso []

Definition at line 833 of file ioWriteDot.c.

834 {
835  Abc_Obj_t * pObj;
836  int i, Counter = 0;
837  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
838  {
839  if ( !Abc_ObjIsNode(pObj) )
840  continue;
841  if ( Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 )
842  continue;
843  Counter ++;
844  }
845  return Counter;
846 }
static int Abc_ObjFanoutNum(Abc_Obj_t *pObj)
Definition: abc.h:365
static int Abc_ObjFaninNum(Abc_Obj_t *pObj)
Definition: abc.h:364
static int Abc_ObjIsNode(Abc_Obj_t *pObj)
Definition: abc.h:355
static int Counter
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
char * Abc_NtkPrintSop ( char *  pSop)
static

DECLARATIONS ///.

CFile****************************************************************

FileName [ioWriteDot.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [Command processing package.]

Synopsis [Procedures to write the graph structure of AIG in DOT.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - June 20, 2005.]

Revision [

Id:
ioWriteDot.c,v 1.00 2005/06/20 00:00:00 alanmi Exp

]

Function*************************************************************

Synopsis [Computes the printable SOP form.]

Description []

SideEffects []

SeeAlso []

Definition at line 803 of file ioWriteDot.c.

804 {
805  static char Buffer[1000];
806  char * pGet, * pSet;
807  pSet = Buffer;
808  for ( pGet = pSop; *pGet; pGet++ )
809  {
810  if ( *pGet == '\n' )
811  {
812  *pSet++ = '\\';
813  *pSet++ = 'n';
814  }
815  else
816  *pSet++ = *pGet;
817  }
818  *(pSet-2) = 0;
819  return Buffer;
820 }
void Io_WriteDot ( Abc_Ntk_t pNtk,
char *  FileName 
)

FUNCTION DEFINITIONS ///.

Function*************************************************************

Synopsis [Writes the graph structure of network for DOT.]

Description [Useful for graph visualization using tools such as GraphViz: http://www.graphviz.org/]

SideEffects []

SeeAlso []

Definition at line 51 of file ioWriteDot.c.

52 {
53  Vec_Ptr_t * vNodes;
54  vNodes = Abc_NtkCollectObjects( pNtk );
55  Io_WriteDotNtk( pNtk, vNodes, NULL, FileName, 0, 0 );
56  Vec_PtrFree( vNodes );
57 }
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
ABC_DLL Vec_Ptr_t * Abc_NtkCollectObjects(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1725
void Io_WriteDotNtk(Abc_Ntk_t *pNtk, Vec_Ptr_t *vNodes, Vec_Ptr_t *vNodesShow, char *pFileName, int fGateNames, int fUseReverse)
Definition: ioWriteDot.c:71
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223
void Io_WriteDotNtk ( Abc_Ntk_t pNtk,
Vec_Ptr_t vNodes,
Vec_Ptr_t vNodesShow,
char *  pFileName,
int  fGateNames,
int  fUseReverse 
)

Function*************************************************************

Synopsis [Writes the graph structure of network for DOT.]

Description [Useful for graph visualization using tools such as GraphViz: http://www.graphviz.org/]

SideEffects []

SeeAlso []

Definition at line 71 of file ioWriteDot.c.

72 {
73  FILE * pFile;
74  Abc_Obj_t * pNode, * pFanin;
75  char * pSopString;
76  int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl, Prev;
77  int Limit = 300;
78 
79  assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
80 
81  if ( vNodes->nSize < 1 )
82  {
83  printf( "The set has no nodes. DOT file is not written.\n" );
84  return;
85  }
86 
87  if ( vNodes->nSize > Limit )
88  {
89  printf( "The set has more than %d nodes. DOT file is not written.\n", Limit );
90  return;
91  }
92 
93  // start the stream
94  if ( (pFile = fopen( pFileName, "w" )) == NULL )
95  {
96  fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
97  return;
98  }
99 
100  // transform logic functions from BDD to SOP
101  if ( (fHasBdds = Abc_NtkIsBddLogic(pNtk)) )
102  {
103  if ( !Abc_NtkBddToSop(pNtk, 0) )
104  {
105  printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
106  return;
107  }
108  }
109 
110  // mark the nodes from the set
111  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
112  pNode->fMarkC = 1;
113  if ( vNodesShow )
114  Vec_PtrForEachEntry( Abc_Obj_t *, vNodesShow, pNode, i )
115  pNode->fMarkB = 1;
116 
117  // get the levels of nodes
118  LevelMax = Abc_NtkLevel( pNtk );
119  if ( fUseReverse )
120  {
121  LevelMin = Abc_NtkLevelReverse( pNtk );
122  assert( LevelMax == LevelMin );
123  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
124  if ( Abc_ObjIsNode(pNode) )
125  pNode->Level = LevelMax - pNode->Level + 1;
126  }
127 
128  // find the largest and the smallest levels
129  LevelMin = 10000;
130  LevelMax = -1;
131  fHasCos = 0;
132  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
133  {
134  if ( Abc_ObjIsCo(pNode) )
135  {
136  fHasCos = 1;
137  continue;
138  }
139  if ( LevelMin > (int)pNode->Level )
140  LevelMin = pNode->Level;
141  if ( LevelMax < (int)pNode->Level )
142  LevelMax = pNode->Level;
143  }
144 
145  // set the level of the CO nodes
146  if ( fHasCos )
147  {
148  LevelMax++;
149  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
150  {
151  if ( Abc_ObjIsCo(pNode) )
152  pNode->Level = LevelMax;
153  }
154  }
155 
156  // write the DOT header
157  fprintf( pFile, "# %s\n", "Network structure generated by ABC" );
158  fprintf( pFile, "\n" );
159  fprintf( pFile, "digraph network {\n" );
160  fprintf( pFile, "size = \"7.5,10\";\n" );
161 // fprintf( pFile, "size = \"10,8.5\";\n" );
162 // fprintf( pFile, "size = \"14,11\";\n" );
163 // fprintf( pFile, "page = \"8,11\";\n" );
164 // fprintf( pFile, "ranksep = 0.5;\n" );
165 // fprintf( pFile, "nodesep = 0.5;\n" );
166  fprintf( pFile, "center = true;\n" );
167 // fprintf( pFile, "orientation = landscape;\n" );
168 // fprintf( pFile, "edge [fontsize = 10];\n" );
169 // fprintf( pFile, "edge [dir = none];\n" );
170  fprintf( pFile, "edge [dir = back];\n" );
171  fprintf( pFile, "\n" );
172 
173  // labels on the left of the picture
174  fprintf( pFile, "{\n" );
175  fprintf( pFile, " node [shape = plaintext];\n" );
176  fprintf( pFile, " edge [style = invis];\n" );
177  fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
178  fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
179  // generate node names with labels
180  for ( Level = LevelMax; Level >= LevelMin; Level-- )
181  {
182  // the visible node name
183  fprintf( pFile, " Level%d", Level );
184  fprintf( pFile, " [label = " );
185  // label name
186  fprintf( pFile, "\"" );
187  fprintf( pFile, "\"" );
188  fprintf( pFile, "];\n" );
189  }
190 
191  // genetate the sequence of visible/invisible nodes to mark levels
192  fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
193  for ( Level = LevelMax; Level >= LevelMin; Level-- )
194  {
195  // the visible node name
196  fprintf( pFile, " Level%d", Level );
197  // the connector
198  if ( Level != LevelMin )
199  fprintf( pFile, " ->" );
200  else
201  fprintf( pFile, ";" );
202  }
203  fprintf( pFile, "\n" );
204  fprintf( pFile, "}" );
205  fprintf( pFile, "\n" );
206  fprintf( pFile, "\n" );
207 
208  // generate title box on top
209  fprintf( pFile, "{\n" );
210  fprintf( pFile, " rank = same;\n" );
211  fprintf( pFile, " LevelTitle1;\n" );
212  fprintf( pFile, " title1 [shape=plaintext,\n" );
213  fprintf( pFile, " fontsize=20,\n" );
214  fprintf( pFile, " fontname = \"Times-Roman\",\n" );
215  fprintf( pFile, " label=\"" );
216  fprintf( pFile, "%s", "Network structure visualized by ABC" );
217  fprintf( pFile, "\\n" );
218  fprintf( pFile, "Benchmark \\\"%s\\\". ", pNtk->pName );
219  fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
220  fprintf( pFile, "\"\n" );
221  fprintf( pFile, " ];\n" );
222  fprintf( pFile, "}" );
223  fprintf( pFile, "\n" );
224  fprintf( pFile, "\n" );
225 
226  // generate statistics box
227  fprintf( pFile, "{\n" );
228  fprintf( pFile, " rank = same;\n" );
229  fprintf( pFile, " LevelTitle2;\n" );
230  fprintf( pFile, " title2 [shape=plaintext,\n" );
231  fprintf( pFile, " fontsize=18,\n" );
232  fprintf( pFile, " fontname = \"Times-Roman\",\n" );
233  fprintf( pFile, " label=\"" );
234  if ( Abc_NtkObjNum(pNtk) == Vec_PtrSize(vNodes) )
235  fprintf( pFile, "The network contains %d logic nodes and %d latches.", Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk) );
236  else
237  fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 );
238  fprintf( pFile, "\\n" );
239  fprintf( pFile, "\"\n" );
240  fprintf( pFile, " ];\n" );
241  fprintf( pFile, "}" );
242  fprintf( pFile, "\n" );
243  fprintf( pFile, "\n" );
244 
245  // generate the POs
246  if ( fHasCos )
247  {
248  fprintf( pFile, "{\n" );
249  fprintf( pFile, " rank = same;\n" );
250  // the labeling node of this level
251  fprintf( pFile, " Level%d;\n", LevelMax );
252  // generate the PO nodes
253  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
254  {
255  if ( !Abc_ObjIsCo(pNode) )
256  continue;
257  fprintf( pFile, " Node%d [label = \"%s%s\"",
258  pNode->Id,
259  (Abc_ObjIsBi(pNode)? Abc_ObjName(Abc_ObjFanout0(pNode)):Abc_ObjName(pNode)),
260  (Abc_ObjIsBi(pNode)? "_in":"") );
261  fprintf( pFile, ", shape = %s", (Abc_ObjIsBi(pNode)? "box":"invtriangle") );
262  if ( pNode->fMarkB )
263  fprintf( pFile, ", style = filled" );
264  fprintf( pFile, ", color = coral, fillcolor = coral" );
265  fprintf( pFile, "];\n" );
266  }
267  fprintf( pFile, "}" );
268  fprintf( pFile, "\n" );
269  fprintf( pFile, "\n" );
270  }
271 
272  // generate nodes of each rank
273  for ( Level = LevelMax - fHasCos; Level >= LevelMin && Level > 0; Level-- )
274  {
275  fprintf( pFile, "{\n" );
276  fprintf( pFile, " rank = same;\n" );
277  // the labeling node of this level
278  fprintf( pFile, " Level%d;\n", Level );
279  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
280  {
281  if ( (int)pNode->Level != Level )
282  continue;
283  if ( Abc_ObjFaninNum(pNode) == 0 )
284  continue;
285 
286 /*
287  int SuppSize;
288  Vec_Ptr_t * vSupp;
289  if ( (int)pNode->Level != Level )
290  continue;
291  if ( Abc_ObjFaninNum(pNode) == 0 )
292  continue;
293  vSupp = Abc_NtkNodeSupport( pNtk, &pNode, 1 );
294  SuppSize = Vec_PtrSize( vSupp );
295  Vec_PtrFree( vSupp );
296 */
297 
298 // fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id );
299  if ( Abc_NtkIsStrash(pNtk) )
300  pSopString = "";
301  else if ( Abc_NtkHasMapping(pNtk) && fGateNames )
302  pSopString = Mio_GateReadName((Mio_Gate_t *)pNode->pData);
303  else if ( Abc_NtkHasMapping(pNtk) )
304  pSopString = Abc_NtkPrintSop(Mio_GateReadSop((Mio_Gate_t *)pNode->pData));
305  else
306  pSopString = Abc_NtkPrintSop((char *)pNode->pData);
307  fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString );
308 // fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id,
309 // SuppSize,
310 // pSopString );
311 
312  fprintf( pFile, ", shape = ellipse" );
313  if ( pNode->fMarkB )
314  fprintf( pFile, ", style = filled" );
315  fprintf( pFile, "];\n" );
316  }
317  fprintf( pFile, "}" );
318  fprintf( pFile, "\n" );
319  fprintf( pFile, "\n" );
320  }
321 
322  // generate the PI nodes if any
323  if ( LevelMin == 0 )
324  {
325  fprintf( pFile, "{\n" );
326  fprintf( pFile, " rank = same;\n" );
327  // the labeling node of this level
328  fprintf( pFile, " Level%d;\n", LevelMin );
329  // generate the PO nodes
330  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
331  {
332  if ( !Abc_ObjIsCi(pNode) )
333  {
334  // check if the costant node is present
335  if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 )
336  {
337  fprintf( pFile, " Node%d [label = \"Const%d\"", pNode->Id, Abc_NtkIsStrash(pNode->pNtk) || Abc_NodeIsConst1(pNode) );
338  fprintf( pFile, ", shape = ellipse" );
339  if ( pNode->fMarkB )
340  fprintf( pFile, ", style = filled" );
341  fprintf( pFile, ", color = coral, fillcolor = coral" );
342  fprintf( pFile, "];\n" );
343  }
344  continue;
345  }
346  fprintf( pFile, " Node%d [label = \"%s\"",
347  pNode->Id,
348  (Abc_ObjIsBo(pNode)? Abc_ObjName(Abc_ObjFanin0(pNode)):Abc_ObjName(pNode)) );
349  fprintf( pFile, ", shape = %s", (Abc_ObjIsBo(pNode)? "box":"triangle") );
350  if ( pNode->fMarkB )
351  fprintf( pFile, ", style = filled" );
352  fprintf( pFile, ", color = coral, fillcolor = coral" );
353  fprintf( pFile, "];\n" );
354  }
355  fprintf( pFile, "}" );
356  fprintf( pFile, "\n" );
357  fprintf( pFile, "\n" );
358  }
359 
360  // generate invisible edges from the square down
361  fprintf( pFile, "title1 -> title2 [style = invis];\n" );
362  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
363  {
364  if ( (int)pNode->Level != LevelMax )
365  continue;
366  fprintf( pFile, "title2 -> Node%d [style = invis];\n", pNode->Id );
367  }
368  // generate invisible edges among the COs
369  Prev = -1;
370  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
371  {
372  if ( (int)pNode->Level != LevelMax )
373  continue;
374  if ( !Abc_ObjIsPo(pNode) )
375  continue;
376  if ( Prev >= 0 )
377  fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, pNode->Id );
378  Prev = pNode->Id;
379  }
380 
381  // generate edges
382  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
383  {
384  if ( Abc_ObjIsLatch(pNode) )
385  continue;
386  Abc_ObjForEachFanin( pNode, pFanin, k )
387  {
388  if ( Abc_ObjIsLatch(pFanin) )
389  continue;
390  fCompl = 0;
391  if ( Abc_NtkIsStrash(pNtk) )
392  fCompl = Abc_ObjFaninC(pNode, k);
393  // generate the edge from this node to the next
394  fprintf( pFile, "Node%d", pNode->Id );
395  fprintf( pFile, " -> " );
396  fprintf( pFile, "Node%d", pFanin->Id );
397  fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
398 // fprintf( pFile, ", label = \"%c\"", 'a' + k );
399  fprintf( pFile, "]" );
400  fprintf( pFile, ";\n" );
401  }
402  }
403 
404  fprintf( pFile, "}" );
405  fprintf( pFile, "\n" );
406  fprintf( pFile, "\n" );
407  fclose( pFile );
408 
409  // unmark the nodes from the set
410  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
411  pNode->fMarkC = 0;
412  if ( vNodesShow )
413  Vec_PtrForEachEntry( Abc_Obj_t *, vNodesShow, pNode, i )
414  pNode->fMarkB = 0;
415 
416  // convert the network back into BDDs if this is how it was
417  if ( fHasBdds )
418  Abc_NtkSopToBdd(pNtk);
419 }
static int Abc_NtkIsStrash(Abc_Ntk_t *pNtk)
Definition: abc.h:251
static int Abc_NtkIsLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:250
static int Abc_ObjIsCi(Abc_Obj_t *pObj)
Definition: abc.h:351
static int Abc_ObjIsBo(Abc_Obj_t *pObj)
Definition: abc.h:350
static int Abc_ObjIsLatch(Abc_Obj_t *pObj)
Definition: abc.h:356
static int Abc_ObjFanoutNum(Abc_Obj_t *pObj)
Definition: abc.h:365
static int Abc_ObjFaninNum(Abc_Obj_t *pObj)
Definition: abc.h:364
static int Abc_NtkHasMapping(Abc_Ntk_t *pNtk)
Definition: abc.h:256
static int Abc_NtkLatchNum(Abc_Ntk_t *pNtk)
Definition: abc.h:294
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
ABC_DLL int Abc_NtkLevelReverse(Abc_Ntk_t *pNtk)
Definition: abcDfs.c:1315
static Abc_Obj_t * Abc_ObjFanin0(Abc_Obj_t *pObj)
Definition: abc.h:373
static int Abc_ObjIsCo(Abc_Obj_t *pObj)
Definition: abc.h:352
static ABC_NAMESPACE_IMPL_START char * Abc_NtkPrintSop(char *pSop)
DECLARATIONS ///.
Definition: ioWriteDot.c:803
static int Abc_ObjIsNode(Abc_Obj_t *pObj)
Definition: abc.h:355
static int Abc_NtkNodeNum(Abc_Ntk_t *pNtk)
Definition: abc.h:293
ABC_DLL int Abc_NtkSopToBdd(Abc_Ntk_t *pNtk)
Definition: abcFunc.c:113
if(last==0)
Definition: sparse_int.h:34
static int Abc_ObjFaninC(Abc_Obj_t *pObj, int i)
Definition: abc.h:379
static int Abc_ObjIsBi(Abc_Obj_t *pObj)
Definition: abc.h:349
ABC_DLL int Abc_NtkBddToSop(Abc_Ntk_t *pNtk, int fDirect)
Definition: abcFunc.c:359
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition: abc.h:524
static int Abc_NtkIsBddLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:265
int Id
Definition: abc.h:132
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition: abcNames.c:48
char * Extra_TimeStamp()
static int Abc_ObjIsPo(Abc_Obj_t *pObj)
Definition: abc.h:348
ABC_DLL int Abc_NodeIsConst1(Abc_Obj_t *pNode)
Definition: abcObj.c:890
#define assert(ex)
Definition: util_old.h:213
static int Abc_NtkCountLogicNodes(Vec_Ptr_t *vNodes)
Definition: ioWriteDot.c:833
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
static int Abc_NtkObjNum(Abc_Ntk_t *pNtk)
Definition: abc.h:283
ABC_DLL int Abc_NtkLevel(Abc_Ntk_t *pNtk)
Definition: abcDfs.c:1265
char * Mio_GateReadName(Mio_Gate_t *pGate)
Definition: mioApi.c:143
char * Mio_GateReadSop(Mio_Gate_t *pGate)
Definition: mioApi.c:153
static Abc_Obj_t * Abc_ObjFanout0(Abc_Obj_t *pObj)
Definition: abc.h:371
void Io_WriteDotSeq ( Abc_Ntk_t pNtk,
Vec_Ptr_t vNodes,
Vec_Ptr_t vNodesShow,
char *  pFileName,
int  fGateNames,
int  fUseReverse 
)

Function*************************************************************

Synopsis [Writes the graph structure of network for DOT.]

Description [Useful for graph visualization using tools such as GraphViz: http://www.graphviz.org/]

SideEffects []

SeeAlso []

Definition at line 434 of file ioWriteDot.c.

435 {
436  FILE * pFile;
437  Abc_Obj_t * pNode, * pFanin;
438  char * pSopString;
439  int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl, Prev;
440  int Limit = 300;
441 
442  assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
443 
444  if ( vNodes->nSize < 1 )
445  {
446  printf( "The set has no nodes. DOT file is not written.\n" );
447  return;
448  }
449 
450  if ( vNodes->nSize > Limit )
451  {
452  printf( "The set has more than %d nodes. DOT file is not written.\n", Limit );
453  return;
454  }
455 
456  // start the stream
457  if ( (pFile = fopen( pFileName, "w" )) == NULL )
458  {
459  fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
460  return;
461  }
462 
463  // transform logic functions from BDD to SOP
464  if ( (fHasBdds = Abc_NtkIsBddLogic(pNtk)) )
465  {
466  if ( !Abc_NtkBddToSop(pNtk, 0) )
467  {
468  printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
469  return;
470  }
471  }
472 
473  // mark the nodes from the set
474  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
475  pNode->fMarkC = 1;
476  if ( vNodesShow )
477  Vec_PtrForEachEntry( Abc_Obj_t *, vNodesShow, pNode, i )
478  pNode->fMarkB = 1;
479 
480  // get the levels of nodes
481  LevelMax = Abc_NtkLevel( pNtk );
482  if ( fUseReverse )
483  {
484  LevelMin = Abc_NtkLevelReverse( pNtk );
485  assert( LevelMax == LevelMin );
486  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
487  if ( Abc_ObjIsNode(pNode) )
488  pNode->Level = LevelMax - pNode->Level + 1;
489  }
490 
491  // find the largest and the smallest levels
492  LevelMin = 10000;
493  LevelMax = -1;
494  fHasCos = 0;
495  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
496  {
497  if ( Abc_ObjIsCo(pNode) )
498  {
499  fHasCos = 1;
500  continue;
501  }
502  if ( LevelMin > (int)pNode->Level )
503  LevelMin = pNode->Level;
504  if ( LevelMax < (int)pNode->Level )
505  LevelMax = pNode->Level;
506  }
507 
508  // set the level of the CO nodes
509  if ( fHasCos )
510  {
511  LevelMax++;
512  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
513  {
514  if ( Abc_ObjIsCo(pNode) )
515  pNode->Level = LevelMax;
516  }
517  }
518 
519  // write the DOT header
520  fprintf( pFile, "# %s\n", "Network structure generated by ABC" );
521  fprintf( pFile, "\n" );
522  fprintf( pFile, "digraph network {\n" );
523  fprintf( pFile, "size = \"7.5,10\";\n" );
524 // fprintf( pFile, "size = \"10,8.5\";\n" );
525 // fprintf( pFile, "size = \"14,11\";\n" );
526 // fprintf( pFile, "page = \"8,11\";\n" );
527 // fprintf( pFile, "ranksep = 0.5;\n" );
528 // fprintf( pFile, "nodesep = 0.5;\n" );
529  fprintf( pFile, "center = true;\n" );
530 // fprintf( pFile, "orientation = landscape;\n" );
531 // fprintf( pFile, "edge [fontsize = 10];\n" );
532 // fprintf( pFile, "edge [dir = none];\n" );
533  fprintf( pFile, "edge [dir = back];\n" );
534  fprintf( pFile, "\n" );
535 
536  // labels on the left of the picture
537  fprintf( pFile, "{\n" );
538  fprintf( pFile, " node [shape = plaintext];\n" );
539  fprintf( pFile, " edge [style = invis];\n" );
540  fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
541  fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
542  // generate node names with labels
543  for ( Level = LevelMax; Level >= LevelMin; Level-- )
544  {
545  // the visible node name
546  fprintf( pFile, " Level%d", Level );
547  fprintf( pFile, " [label = " );
548  // label name
549  fprintf( pFile, "\"" );
550  fprintf( pFile, "\"" );
551  fprintf( pFile, "];\n" );
552  }
553 
554  // genetate the sequence of visible/invisible nodes to mark levels
555  fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
556  for ( Level = LevelMax; Level >= LevelMin; Level-- )
557  {
558  // the visible node name
559  fprintf( pFile, " Level%d", Level );
560  // the connector
561  if ( Level != LevelMin )
562  fprintf( pFile, " ->" );
563  else
564  fprintf( pFile, ";" );
565  }
566  fprintf( pFile, "\n" );
567  fprintf( pFile, "}" );
568  fprintf( pFile, "\n" );
569  fprintf( pFile, "\n" );
570 
571  // generate title box on top
572  fprintf( pFile, "{\n" );
573  fprintf( pFile, " rank = same;\n" );
574  fprintf( pFile, " LevelTitle1;\n" );
575  fprintf( pFile, " title1 [shape=plaintext,\n" );
576  fprintf( pFile, " fontsize=20,\n" );
577  fprintf( pFile, " fontname = \"Times-Roman\",\n" );
578  fprintf( pFile, " label=\"" );
579  fprintf( pFile, "%s", "Network structure visualized by ABC" );
580  fprintf( pFile, "\\n" );
581  fprintf( pFile, "Benchmark \\\"%s\\\". ", pNtk->pName );
582  fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
583  fprintf( pFile, "\"\n" );
584  fprintf( pFile, " ];\n" );
585  fprintf( pFile, "}" );
586  fprintf( pFile, "\n" );
587  fprintf( pFile, "\n" );
588 
589  // generate statistics box
590  fprintf( pFile, "{\n" );
591  fprintf( pFile, " rank = same;\n" );
592  fprintf( pFile, " LevelTitle2;\n" );
593  fprintf( pFile, " title2 [shape=plaintext,\n" );
594  fprintf( pFile, " fontsize=18,\n" );
595  fprintf( pFile, " fontname = \"Times-Roman\",\n" );
596  fprintf( pFile, " label=\"" );
597  if ( Abc_NtkObjNum(pNtk) == Vec_PtrSize(vNodes) )
598  fprintf( pFile, "The network contains %d logic nodes and %d latches.", Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk) );
599  else
600  fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 );
601  fprintf( pFile, "\\n" );
602  fprintf( pFile, "\"\n" );
603  fprintf( pFile, " ];\n" );
604  fprintf( pFile, "}" );
605  fprintf( pFile, "\n" );
606  fprintf( pFile, "\n" );
607 
608  // generate the POs
609  if ( fHasCos )
610  {
611  fprintf( pFile, "{\n" );
612  fprintf( pFile, " rank = same;\n" );
613  // the labeling node of this level
614  fprintf( pFile, " Level%d;\n", LevelMax );
615  // generate the PO nodes
616  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
617  {
618  if ( !Abc_ObjIsPo(pNode) )
619  continue;
620  fprintf( pFile, " Node%d [label = \"%s\"", pNode->Id, Abc_ObjName(pNode) );
621  fprintf( pFile, ", shape = %s", "invtriangle" );
622  if ( pNode->fMarkB )
623  fprintf( pFile, ", style = filled" );
624  fprintf( pFile, ", color = coral, fillcolor = coral" );
625  fprintf( pFile, "];\n" );
626  }
627  fprintf( pFile, "}" );
628  fprintf( pFile, "\n" );
629  fprintf( pFile, "\n" );
630  }
631 
632  // generate nodes of each rank
633  for ( Level = LevelMax - fHasCos; Level >= LevelMin && Level > 0; Level-- )
634  {
635  fprintf( pFile, "{\n" );
636  fprintf( pFile, " rank = same;\n" );
637  // the labeling node of this level
638  fprintf( pFile, " Level%d;\n", Level );
639  Abc_NtkForEachNode( pNtk, pNode, i )
640  {
641  if ( (int)pNode->Level != Level )
642  continue;
643 // fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id );
644  if ( Abc_NtkIsStrash(pNtk) )
645  pSopString = "";
646  else if ( Abc_NtkHasMapping(pNtk) && fGateNames )
647  pSopString = Mio_GateReadName((Mio_Gate_t *)pNode->pData);
648  else if ( Abc_NtkHasMapping(pNtk) )
649  pSopString = Abc_NtkPrintSop(Mio_GateReadSop((Mio_Gate_t *)pNode->pData));
650  else
651  pSopString = Abc_NtkPrintSop((char *)pNode->pData);
652  fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString );
653 
654  fprintf( pFile, ", shape = ellipse" );
655  if ( pNode->fMarkB )
656  fprintf( pFile, ", style = filled" );
657  fprintf( pFile, "];\n" );
658  }
659  fprintf( pFile, "}" );
660  fprintf( pFile, "\n" );
661  fprintf( pFile, "\n" );
662  }
663 
664  // generate the PI nodes if any
665  if ( LevelMin == 0 )
666  {
667  fprintf( pFile, "{\n" );
668  fprintf( pFile, " rank = same;\n" );
669  // the labeling node of this level
670  fprintf( pFile, " Level%d;\n", LevelMin );
671  // generate the PO nodes
672  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
673  {
674  if ( pNode->Level > 0 )
675  continue;
676  if ( !Abc_ObjIsPi(pNode) )
677  {
678  // check if the costant node is present
679  if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 )
680  {
681  fprintf( pFile, " Node%d [label = \"Const1\"", pNode->Id );
682  fprintf( pFile, ", shape = ellipse" );
683  if ( pNode->fMarkB )
684  fprintf( pFile, ", style = filled" );
685  fprintf( pFile, ", color = coral, fillcolor = coral" );
686  fprintf( pFile, "];\n" );
687  }
688  continue;
689  }
690  fprintf( pFile, " Node%d [label = \"%s\"", pNode->Id, Abc_ObjName(pNode) );
691  fprintf( pFile, ", shape = %s", "triangle" );
692  if ( pNode->fMarkB )
693  fprintf( pFile, ", style = filled" );
694  fprintf( pFile, ", color = coral, fillcolor = coral" );
695  fprintf( pFile, "];\n" );
696  }
697  fprintf( pFile, "}" );
698  fprintf( pFile, "\n" );
699  fprintf( pFile, "\n" );
700  }
701 
702 // fprintf( pFile, "{\n" );
703  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
704  {
705  if ( !Abc_ObjIsLatch(pNode) )
706  continue;
707  fprintf( pFile, "Node%d [label = \"%s\"", pNode->Id, Abc_ObjName(pNode) );
708  fprintf( pFile, ", shape = box" );
709  if ( pNode->fMarkB )
710  fprintf( pFile, ", style = filled" );
711  fprintf( pFile, ", color = coral, fillcolor = coral" );
712  fprintf( pFile, "];\n" );
713  }
714 // fprintf( pFile, "}" );
715 // fprintf( pFile, "\n" );
716  fprintf( pFile, "\n" );
717 
718  // generate invisible edges from the square down
719  fprintf( pFile, "title1 -> title2 [style = invis];\n" );
720  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
721  {
722  if ( (int)pNode->Level != LevelMax )
723  continue;
724  if ( !Abc_ObjIsPo(pNode) )
725  continue;
726  fprintf( pFile, "title2 -> Node%d [style = invis];\n", pNode->Id );
727  }
728  // generate invisible edges among the COs
729  Prev = -1;
730  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
731  {
732  if ( (int)pNode->Level != LevelMax )
733  continue;
734  if ( !Abc_ObjIsPo(pNode) )
735  continue;
736  if ( Prev >= 0 )
737  fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, pNode->Id );
738  Prev = pNode->Id;
739  }
740 
741  // generate edges
742  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
743  {
744  if ( Abc_ObjIsBi(pNode) || Abc_ObjIsBo(pNode) )
745  continue;
746  Abc_ObjForEachFanin( pNode, pFanin, k )
747  {
748  fCompl = 0;
749  if ( Abc_NtkIsStrash(pNtk) )
750  {
751  if ( Abc_ObjIsBi(pFanin) )
752  fCompl = Abc_ObjFaninC(pFanin, k);
753  else
754  fCompl = Abc_ObjFaninC(pNode, k);
755  }
756  if ( Abc_ObjIsBi(pFanin) || Abc_ObjIsBo(pFanin) )
757  pFanin = Abc_ObjFanin0(pFanin);
758  if ( Abc_ObjIsBi(pFanin) || Abc_ObjIsBo(pFanin) )
759  pFanin = Abc_ObjFanin0(pFanin);
760  if ( !pFanin->fMarkC )
761  continue;
762 
763  // generate the edge from this node to the next
764  fprintf( pFile, "Node%d", pNode->Id );
765  fprintf( pFile, " -> " );
766  fprintf( pFile, "Node%d", pFanin->Id );
767  fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
768 // fprintf( pFile, ", label = \"%c\"", 'a' + k );
769  fprintf( pFile, "]" );
770  fprintf( pFile, ";\n" );
771  }
772  }
773 
774  fprintf( pFile, "}" );
775  fprintf( pFile, "\n" );
776  fprintf( pFile, "\n" );
777  fclose( pFile );
778 
779  // unmark the nodes from the set
780  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
781  pNode->fMarkC = 0;
782  if ( vNodesShow )
783  Vec_PtrForEachEntry( Abc_Obj_t *, vNodesShow, pNode, i )
784  pNode->fMarkB = 0;
785 
786  // convert the network back into BDDs if this is how it was
787  if ( fHasBdds )
788  Abc_NtkSopToBdd(pNtk);
789 }
static int Abc_NtkIsStrash(Abc_Ntk_t *pNtk)
Definition: abc.h:251
static int Abc_NtkIsLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:250
static int Abc_ObjIsBo(Abc_Obj_t *pObj)
Definition: abc.h:350
static int Abc_ObjIsLatch(Abc_Obj_t *pObj)
Definition: abc.h:356
static int Abc_ObjFanoutNum(Abc_Obj_t *pObj)
Definition: abc.h:365
static int Abc_ObjFaninNum(Abc_Obj_t *pObj)
Definition: abc.h:364
static int Abc_NtkHasMapping(Abc_Ntk_t *pNtk)
Definition: abc.h:256
static int Abc_NtkLatchNum(Abc_Ntk_t *pNtk)
Definition: abc.h:294
static int Abc_ObjIsPi(Abc_Obj_t *pObj)
Definition: abc.h:347
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
ABC_DLL int Abc_NtkLevelReverse(Abc_Ntk_t *pNtk)
Definition: abcDfs.c:1315
static Abc_Obj_t * Abc_ObjFanin0(Abc_Obj_t *pObj)
Definition: abc.h:373
static int Abc_ObjIsCo(Abc_Obj_t *pObj)
Definition: abc.h:352
static ABC_NAMESPACE_IMPL_START char * Abc_NtkPrintSop(char *pSop)
DECLARATIONS ///.
Definition: ioWriteDot.c:803
static int Abc_ObjIsNode(Abc_Obj_t *pObj)
Definition: abc.h:355
static int Abc_NtkNodeNum(Abc_Ntk_t *pNtk)
Definition: abc.h:293
ABC_DLL int Abc_NtkSopToBdd(Abc_Ntk_t *pNtk)
Definition: abcFunc.c:113
unsigned fMarkC
Definition: abc.h:136
if(last==0)
Definition: sparse_int.h:34
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition: abc.h:461
static int Abc_ObjFaninC(Abc_Obj_t *pObj, int i)
Definition: abc.h:379
static int Abc_ObjIsBi(Abc_Obj_t *pObj)
Definition: abc.h:349
ABC_DLL int Abc_NtkBddToSop(Abc_Ntk_t *pNtk, int fDirect)
Definition: abcFunc.c:359
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition: abc.h:524
static int Abc_NtkIsBddLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:265
int Id
Definition: abc.h:132
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition: abcNames.c:48
char * Extra_TimeStamp()
static int Abc_ObjIsPo(Abc_Obj_t *pObj)
Definition: abc.h:348
#define assert(ex)
Definition: util_old.h:213
static int Abc_NtkCountLogicNodes(Vec_Ptr_t *vNodes)
Definition: ioWriteDot.c:833
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
static int Abc_NtkObjNum(Abc_Ntk_t *pNtk)
Definition: abc.h:283
ABC_DLL int Abc_NtkLevel(Abc_Ntk_t *pNtk)
Definition: abcDfs.c:1265
char * Mio_GateReadName(Mio_Gate_t *pGate)
Definition: mioApi.c:143
char * Mio_GateReadSop(Mio_Gate_t *pGate)
Definition: mioApi.c:153