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