abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ioWriteDot.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [ioWriteDot.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Command processing package.]
8 
9  Synopsis [Procedures to write the graph structure of AIG in DOT.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: ioWriteDot.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "ioAbc.h"
22 #include "base/main/main.h"
23 #include "map/mio/mio.h"
24 
26 
27 
28 ////////////////////////////////////////////////////////////////////////
29 /// DECLARATIONS ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 static char * Abc_NtkPrintSop( char * pSop );
33 static int Abc_NtkCountLogicNodes( Vec_Ptr_t * vNodes );
34 
35 ////////////////////////////////////////////////////////////////////////
36 /// FUNCTION DEFINITIONS ///
37 ////////////////////////////////////////////////////////////////////////
38 
39 /**Function*************************************************************
40 
41  Synopsis [Writes the graph structure of network for DOT.]
42 
43  Description [Useful for graph visualization using tools such as GraphViz:
44  http://www.graphviz.org/]
45 
46  SideEffects []
47 
48  SeeAlso []
49 
50 ***********************************************************************/
51 void Io_WriteDot( Abc_Ntk_t * pNtk, char * FileName )
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 }
58 
59 /**Function*************************************************************
60 
61  Synopsis [Writes the graph structure of network for DOT.]
62 
63  Description [Useful for graph visualization using tools such as GraphViz:
64  http://www.graphviz.org/]
65 
66  SideEffects []
67 
68  SeeAlso []
69 
70 ***********************************************************************/
71 void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse )
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 }
420 
421 
422 /**Function*************************************************************
423 
424  Synopsis [Writes the graph structure of network for DOT.]
425 
426  Description [Useful for graph visualization using tools such as GraphViz:
427  http://www.graphviz.org/]
428 
429  SideEffects []
430 
431  SeeAlso []
432 
433 ***********************************************************************/
434 void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse )
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 }
790 
791 
792 /**Function*************************************************************
793 
794  Synopsis [Computes the printable SOP form.]
795 
796  Description []
797 
798  SideEffects []
799 
800  SeeAlso []
801 
802 ***********************************************************************/
803 char * Abc_NtkPrintSop( char * pSop )
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 }
821 
822 /**Function*************************************************************
823 
824  Synopsis [Computes the printable SOP form.]
825 
826  Description []
827 
828  SideEffects []
829 
830  SeeAlso []
831 
832 ***********************************************************************/
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 }
847 
848 ////////////////////////////////////////////////////////////////////////
849 /// END OF FILE ///
850 ////////////////////////////////////////////////////////////////////////
851 
852 
854 
static int Abc_NtkIsStrash(Abc_Ntk_t *pNtk)
Definition: abc.h:251
static int Abc_NtkIsLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:250
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
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 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
unsigned Level
Definition: abc.h:142
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 Vec_Ptr_t * Abc_NtkCollectObjects(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1725
ABC_DLL int Abc_NtkSopToBdd(Abc_Ntk_t *pNtk)
Definition: abcFunc.c:113
unsigned fMarkC
Definition: abc.h:136
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static int Counter
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition: abc.h:461
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static int Abc_ObjFaninC(Abc_Obj_t *pObj, int i)
Definition: abc.h:379
Abc_Ntk_t * pNtk
Definition: abc.h:130
unsigned fMarkB
Definition: abc.h:135
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
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 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()
void Io_WriteDotSeq(Abc_Ntk_t *pNtk, Vec_Ptr_t *vNodes, Vec_Ptr_t *vNodesShow, char *pFileName, int fGateNames, int fUseReverse)
Definition: ioWriteDot.c:434
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
void * pData
Definition: abc.h:145
#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
char * pName
Definition: abc.h:158
void Io_WriteDot(Abc_Ntk_t *pNtk, char *FileName)
FUNCTION DEFINITIONS ///.
Definition: ioWriteDot.c:51
static Abc_Obj_t * Abc_ObjFanout0(Abc_Obj_t *pObj)
Definition: abc.h:371
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223