1 /**CFile****************************************************************
2 
3   FileName    [abcShow.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Network and node package.]
8 
9   Synopsis    [Visualization procedures using DOT software and GSView.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: abcShow.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #ifdef WIN32
22 #include <process.h>
23 #else
24 #include <unistd.h>
25 #endif
26 
27 
28 #include "abc.h"
29 #include "base/main/main.h"
30 #include "base/io/ioAbc.h"
31 
32 #ifdef ABC_USE_CUDD
33 #include "bdd/extrab/extraBdd.h"
34 #endif
35 
36 ABC_NAMESPACE_IMPL_START
37 
38 
39 ////////////////////////////////////////////////////////////////////////
40 ///                        DECLARATIONS                              ///
41 ////////////////////////////////////////////////////////////////////////
42 
43 extern void Abc_ShowFile( char * FileNameDot );
44 static void Abc_ShowGetFileName( char * pName, char * pBuffer );
45 
46 ////////////////////////////////////////////////////////////////////////
47 ///                     FUNCTION DEFINITIONS                         ///
48 ////////////////////////////////////////////////////////////////////////
49 
50 #ifdef ABC_USE_CUDD
51 
52 /**Function*************************************************************
53 
54   Synopsis    [Visualizes BDD of the node.]
55 
56   Description []
57 
58   SideEffects []
59 
60   SeeAlso     []
61 
62 ***********************************************************************/
Abc_NodeShowBddOne(DdManager * dd,DdNode * bFunc)63 void Abc_NodeShowBddOne( DdManager * dd, DdNode * bFunc )
64 {
65     char * FileNameDot = "temp.dot";
66     FILE * pFile;
67     if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
68     {
69         fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
70         return;
71     }
72     Cudd_DumpDot( dd, 1, (DdNode **)&bFunc, NULL, NULL, pFile );
73     fclose( pFile );
74     Abc_ShowFile( FileNameDot );
75 }
76 
77 /**Function*************************************************************
78 
79   Synopsis    [Visualizes BDD of the node.]
80 
81   Description []
82 
83   SideEffects []
84 
85   SeeAlso     []
86 
87 ***********************************************************************/
Abc_NodeShowBdd(Abc_Obj_t * pNode,int fCompl)88 void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl )
89 {
90     FILE * pFile;
91     Vec_Ptr_t * vNamesIn;
92     char FileNameDot[200];
93     char * pNameOut;
94     DdManager * dd = (DdManager *)pNode->pNtk->pManFunc;
95 
96     assert( Abc_NtkIsBddLogic(pNode->pNtk) );
97     // create the file name
98     Abc_ShowGetFileName( Abc_ObjName(pNode), FileNameDot );
99     // check that the file can be opened
100     if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
101     {
102         fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
103         return;
104     }
105 
106     // set the node names
107     vNamesIn = Abc_NodeGetFaninNames( pNode );
108     pNameOut = Abc_ObjName(pNode);
109     if ( fCompl )
110         Cudd_DumpDot( dd, 1, (DdNode **)&pNode->pData, (char **)vNamesIn->pArray, &pNameOut, pFile );
111     else
112     {
113         DdNode * bAdd = Cudd_BddToAdd( dd, (DdNode *)pNode->pData ); Cudd_Ref( bAdd );
114         Cudd_DumpDot( dd, 1, (DdNode **)&bAdd, (char **)vNamesIn->pArray, &pNameOut, pFile );
115         Cudd_RecursiveDeref( dd, bAdd );
116     }
117     Abc_NodeFreeNames( vNamesIn );
118     Abc_NtkCleanCopy( pNode->pNtk );
119     fclose( pFile );
120 
121     // visualize the file
122     Abc_ShowFile( FileNameDot );
123 }
Abc_NtkShowBdd(Abc_Ntk_t * pNtk,int fCompl)124 void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl )
125 {
126     char FileNameDot[200];
127     char ** ppNamesIn, ** ppNamesOut;
128     DdManager * dd; DdNode * bFunc;
129     Vec_Ptr_t * vFuncsGlob;
130     Abc_Obj_t * pObj; int i;
131     FILE * pFile;
132 
133     assert( Abc_NtkIsStrash(pNtk) );
134     dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, 0 );
135     if ( dd == NULL )
136     {
137         printf( "Construction of global BDDs has failed.\n" );
138         return;
139     }
140     //printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
141 
142     // complement the global functions
143     vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
144     Abc_NtkForEachCo( pNtk, pObj, i )
145         Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) );
146 
147     // create the file name
148     Abc_ShowGetFileName( pNtk->pName, FileNameDot );
149     // check that the file can be opened
150     if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
151     {
152         fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
153         return;
154     }
155 
156     // set the node names
157     ppNamesIn = Abc_NtkCollectCioNames( pNtk, 0 );
158     ppNamesOut = Abc_NtkCollectCioNames( pNtk, 1 );
159     if ( fCompl )
160         Cudd_DumpDot( dd, Abc_NtkCoNum(pNtk), (DdNode **)Vec_PtrArray(vFuncsGlob), ppNamesIn, ppNamesOut, pFile );
161     else
162     {
163         DdNode ** pbAdds = ABC_ALLOC( DdNode *, Vec_PtrSize(vFuncsGlob) );
164         Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i )
165             { pbAdds[i] = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( pbAdds[i] ); }
166         Cudd_DumpDot( dd, Abc_NtkCoNum(pNtk), pbAdds, ppNamesIn, ppNamesOut, pFile );
167         Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i )
168             Cudd_RecursiveDeref( dd, pbAdds[i] );
169         ABC_FREE( pbAdds );
170     }
171     ABC_FREE( ppNamesIn );
172     ABC_FREE( ppNamesOut );
173     fclose( pFile );
174 
175     // cleanup
176     Abc_NtkFreeGlobalBdds( pNtk, 0 );
177     Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i )
178         Cudd_RecursiveDeref( dd, bFunc );
179     Vec_PtrFree( vFuncsGlob );
180     Extra_StopManager( dd );
181     Abc_NtkCleanCopy( pNtk );
182 
183     // visualize the file
184     Abc_ShowFile( FileNameDot );
185 }
186 
187 #else
Abc_NodeShowBdd(Abc_Obj_t * pNode,int fCompl)188 void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl ) {}
Abc_NtkShowBdd(Abc_Ntk_t * pNtk,int fCompl)189 void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl ) {}
190 #endif
191 
192 /**Function*************************************************************
193 
194   Synopsis    [Visualizes a reconvergence driven cut at the node.]
195 
196   Description []
197 
198   SideEffects []
199 
200   SeeAlso     []
201 
202 ***********************************************************************/
Abc_NodeShowCut(Abc_Obj_t * pNode,int nNodeSizeMax,int nConeSizeMax)203 void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax )
204 {
205     FILE * pFile;
206     char FileNameDot[200];
207     Abc_ManCut_t * p;
208     Vec_Ptr_t * vCutSmall;
209     Vec_Ptr_t * vCutLarge;
210     Vec_Ptr_t * vInside;
211     Vec_Ptr_t * vNodesTfo;
212     Abc_Obj_t * pTemp;
213     int i;
214 
215     assert( Abc_NtkIsStrash(pNode->pNtk) );
216 
217     // start the cut computation manager
218     p = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, ABC_INFINITY );
219     // get the recovergence driven cut
220     vCutSmall = Abc_NodeFindCut( p, pNode, 1 );
221     // get the containing cut
222     vCutLarge = Abc_NtkManCutReadCutLarge( p );
223     // get the array for the inside nodes
224     vInside = Abc_NtkManCutReadVisited( p );
225     // get the inside nodes of the containing cone
226     Abc_NodeConeCollect( &pNode, 1, vCutLarge, vInside, 1 );
227 
228     // add the nodes in the TFO
229     vNodesTfo = Abc_NodeCollectTfoCands( p, pNode, vCutSmall, ABC_INFINITY );
230     Vec_PtrForEachEntry( Abc_Obj_t *, vNodesTfo, pTemp, i )
231         Vec_PtrPushUnique( vInside, pTemp );
232 
233     // create the file name
234     Abc_ShowGetFileName( Abc_ObjName(pNode), FileNameDot );
235     // check that the file can be opened
236     if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
237     {
238         fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
239         return;
240     }
241     // add the root node to the cone (for visualization)
242     Vec_PtrPush( vCutSmall, pNode );
243     // write the DOT file
244     Io_WriteDotNtk( pNode->pNtk, vInside, vCutSmall, FileNameDot, 0, 0 );
245     // stop the cut computation manager
246     Abc_NtkManCutStop( p );
247 
248     // visualize the file
249     Abc_ShowFile( FileNameDot );
250 }
251 
252 /**Function*************************************************************
253 
254   Synopsis    [Visualizes AIG with choices.]
255 
256   Description []
257 
258   SideEffects []
259 
260   SeeAlso     []
261 
262 ***********************************************************************/
Abc_NtkShow(Abc_Ntk_t * pNtk0,int fGateNames,int fSeq,int fUseReverse)263 void Abc_NtkShow( Abc_Ntk_t * pNtk0, int fGateNames, int fSeq, int fUseReverse )
264 {
265     FILE * pFile;
266     Abc_Ntk_t * pNtk;
267     Abc_Obj_t * pNode;
268     Vec_Ptr_t * vNodes;
269     int nBarBufs;
270     char FileNameDot[200];
271     int i;
272 
273     assert( Abc_NtkIsStrash(pNtk0) || Abc_NtkIsLogic(pNtk0) );
274     if ( Abc_NtkIsStrash(pNtk0) && Abc_NtkGetChoiceNum(pNtk0) )
275     {
276         printf( "Temporarily visualization of AIGs with choice nodes is disabled.\n" );
277         return;
278     }
279     // create the file name
280     Abc_ShowGetFileName( pNtk0->pName, FileNameDot );
281     // check that the file can be opened
282     if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
283     {
284         fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
285         return;
286     }
287     fclose( pFile );
288 
289 
290     // convert to logic SOP
291     pNtk = Abc_NtkDup( pNtk0 );
292     if ( Abc_NtkIsLogic(pNtk) && !Abc_NtkHasMapping(pNtk) )
293         Abc_NtkToSop( pNtk, -1, ABC_INFINITY );
294 
295     // collect all nodes in the network
296     vNodes = Vec_PtrAlloc( 100 );
297     Abc_NtkForEachObj( pNtk, pNode, i )
298         Vec_PtrPush( vNodes, pNode );
299     // write the DOT file
300     nBarBufs = pNtk->nBarBufs;
301     pNtk->nBarBufs = 0;
302     if ( fSeq )
303         Io_WriteDotSeq( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse );
304     else
305         Io_WriteDotNtk( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse );
306     pNtk->nBarBufs = nBarBufs;
307     Vec_PtrFree( vNodes );
308 
309     // visualize the file
310     Abc_ShowFile( FileNameDot );
311     Abc_NtkDelete( pNtk );
312 }
313 
314 
315 /**Function*************************************************************
316 
317   Synopsis    [Shows the given DOT file.]
318 
319   Description []
320 
321   SideEffects []
322 
323   SeeAlso     []
324 
325 ***********************************************************************/
Abc_ShowFile(char * FileNameDot)326 void Abc_ShowFile( char * FileNameDot )
327 {
328     FILE * pFile;
329     char * FileGeneric;
330     char FileNamePs[200];
331     char CommandDot[1000];
332     char * pDotName;
333     char * pDotNameWin = "dot.exe";
334     char * pDotNameUnix = "dot";
335     char * pGsNameWin = "gsview32.exe";
336     char * pGsNameUnix = "gv";
337     int RetValue;
338 
339     // get DOT names from the resource file
340     if ( Abc_FrameReadFlag("dotwin") )
341         pDotNameWin = Abc_FrameReadFlag("dotwin");
342     if ( Abc_FrameReadFlag("dotunix") )
343         pDotNameUnix = Abc_FrameReadFlag("dotunix");
344 
345 #ifdef WIN32
346     pDotName = pDotNameWin;
347 #else
348     pDotName = pDotNameUnix;
349 #endif
350 
351     // check if the input DOT file is okay
352     if ( (pFile = fopen( FileNameDot, "r" )) == NULL )
353     {
354         fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
355         return;
356     }
357     fclose( pFile );
358 
359     // create the PostScript file name
360     FileGeneric = Extra_FileNameGeneric( FileNameDot );
361     sprintf( FileNamePs,  "%s.ps",  FileGeneric );
362     ABC_FREE( FileGeneric );
363 
364     // generate the PostScript file using DOT
365     sprintf( CommandDot,  "%s -Tps -o %s %s", pDotName, FileNamePs, FileNameDot );
366     RetValue = system( CommandDot );
367     if ( RetValue == -1 )
368     {
369         fprintf( stdout, "Command \"%s\" did not succeed.\n", CommandDot );
370         return;
371     }
372     // check that the input PostScript file is okay
373     if ( (pFile = fopen( FileNamePs, "r" )) == NULL )
374     {
375         fprintf( stdout, "Cannot open intermediate file \"%s\".\n", FileNamePs );
376         return;
377     }
378     fclose( pFile );
379 
380 
381     // get GSVIEW names from the resource file
382     if ( Abc_FrameReadFlag("gsviewwin") )
383         pGsNameWin = Abc_FrameReadFlag("gsviewwin");
384     if ( Abc_FrameReadFlag("gsviewunix") )
385         pGsNameUnix = Abc_FrameReadFlag("gsviewunix");
386 
387     // spawn the viewer
388 #ifdef WIN32
389     _unlink( FileNameDot );
390     if ( _spawnl( _P_NOWAIT, pGsNameWin, pGsNameWin, FileNamePs, NULL ) == -1 )
391         if ( _spawnl( _P_NOWAIT, "C:\\Program Files\\Ghostgum\\gsview\\gsview32.exe",
392             "C:\\Program Files\\Ghostgum\\gsview\\gsview32.exe", FileNamePs, NULL ) == -1 )
393             if ( _spawnl( _P_NOWAIT, "C:\\Program Files\\Ghostgum\\gsview\\gsview64.exe",
394                 "C:\\Program Files\\Ghostgum\\gsview\\gsview64.exe", FileNamePs, NULL ) == -1 )
395             {
396                 fprintf( stdout, "Cannot find \"%s\".\n", pGsNameWin );
397                 return;
398             }
399 #else
400     {
401         char CommandPs[1000];
402         unlink( FileNameDot );
403         sprintf( CommandPs,  "%s %s &", pGsNameUnix, FileNamePs );
404         if ( system( CommandPs ) == -1 )
405         {
406             fprintf( stdout, "Cannot execute \"%s\".\n", CommandPs );
407             return;
408         }
409     }
410 #endif
411 }
412 
413 /**Function*************************************************************
414 
415   Synopsis    [Derives the DOT file name.]
416 
417   Description []
418 
419   SideEffects []
420 
421   SeeAlso     []
422 
423 ***********************************************************************/
Abc_ShowGetFileName(char * pName,char * pBuffer)424 void Abc_ShowGetFileName( char * pName, char * pBuffer )
425 {
426     char * pCur;
427     // creat the file name
428     sprintf( pBuffer, "%s.dot", pName );
429     // get rid of not-alpha-numeric characters
430     for ( pCur = pBuffer; *pCur; pCur++ )
431         if ( !((*pCur >= '0' && *pCur <= '9') || (*pCur >= 'a' && *pCur <= 'z') ||
432                (*pCur >= 'A' && *pCur <= 'Z') || (*pCur == '.')) )
433             *pCur = '_';
434 }
435 
436 
437 /**Function*************************************************************
438 
439   Synopsis    []
440 
441   Description []
442 
443   SideEffects []
444 
445   SeeAlso     []
446 
447 ***********************************************************************/
Abc_NtkWriteFlopDependency(Abc_Ntk_t * pNtk,char * pFileName)448 void Abc_NtkWriteFlopDependency( Abc_Ntk_t * pNtk, char * pFileName )
449 {
450     FILE * pFile;
451     Vec_Ptr_t * vSupp;
452     Abc_Obj_t * pObj, * pTemp;
453     int i, k, Count;
454     pFile = fopen( pFileName, "w" );
455     if ( pFile == NULL )
456     {
457         printf( "Cannot open input file %s.\n", pFileName );
458         return;
459     }
460     fprintf( pFile, "# Flop dependency for \"%s\" generated by ABC on %s\n", Abc_NtkName(pNtk), Extra_TimeStamp() );
461     fprintf( pFile, "digraph G {\n" );
462     fprintf( pFile, "  graph [splines=true overlap=false];\n" );
463     fprintf( pFile, "  size = \"7.5,10\";\n" );
464     fprintf( pFile, "  center = true;\n" );
465 //    fprintf( pFile, "  edge [len=3,dir=forward];\n" );
466     fprintf( pFile, "  edge [dir=forward];\n" );
467     Abc_NtkForEachLatchInput( pNtk, pObj, i )
468     {
469         Abc_ObjFanout0( Abc_ObjFanout0(pObj) )->iTemp = i;
470         vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
471         Count = 0;
472         Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pTemp, k )
473             Count += Abc_ObjIsPi(pTemp);
474         Vec_PtrFree( vSupp );
475         fprintf( pFile, "  { rank = same; %d [label=\"%d(%d)\"]; }\n", i, i, Count );
476     }
477     Abc_NtkForEachLatchInput( pNtk, pObj, i )
478     {
479         vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
480         Count = 0;
481         Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pTemp, k )
482             if ( !Abc_ObjIsPi(pTemp) )
483                 fprintf( pFile, "  %4d -> %4d\n", pTemp->iTemp, i );
484         Vec_PtrFree( vSupp );
485     }
486     fprintf( pFile, "}\n" );
487     fclose( pFile );
488 }
489 
490 
491 /**Function*************************************************************
492 
493   Synopsis    [Visualizes AIG with choices.]
494 
495   Description []
496 
497   SideEffects []
498 
499   SeeAlso     []
500 
501 ***********************************************************************/
Abc_NtkShowFlopDependency(Abc_Ntk_t * pNtk)502 void Abc_NtkShowFlopDependency( Abc_Ntk_t * pNtk )
503 {
504     FILE * pFile;
505     char FileNameDot[200];
506     assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
507     // create the file name
508     Abc_ShowGetFileName( pNtk->pName, FileNameDot );
509     // check that the file can be opened
510     if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
511     {
512         fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
513         return;
514     }
515     fclose( pFile );
516     // write the DOT file
517     Abc_NtkWriteFlopDependency( pNtk, FileNameDot );
518     // visualize the file
519     Abc_ShowFile( FileNameDot );
520 }
521 
522 
523 ////////////////////////////////////////////////////////////////////////
524 ///                       END OF FILE                                ///
525 ////////////////////////////////////////////////////////////////////////
526 
527 
528 ABC_NAMESPACE_IMPL_END
529 
530