ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ioWriteDot.c File Reference
#include "ioAbc.h"
#include "base/main/main.h"
#include "map/mio/mio.h"
Include dependency graph for ioWriteDot.c:

Go to the source code of this file.

Functions

void Io_WriteDot (Abc_Ntk_t *pNtk, char *FileName)
 FUNCTION DEFINITIONS ///.
 
void Io_WriteDotNtk (Abc_Ntk_t *pNtk, Vec_Ptr_t *vNodes, Vec_Ptr_t *vNodesShow, char *pFileName, int fGateNames, int fUseReverse, int fAigIds)
 
void Io_WriteDotSeq (Abc_Ntk_t *pNtk, Vec_Ptr_t *vNodes, Vec_Ptr_t *vNodesShow, char *pFileName, int fGateNames, int fUseReverse)
 

Function Documentation

◆ Io_WriteDot()

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, 0 );
56 Vec_PtrFree( vNodes );
57}
ABC_DLL Vec_Ptr_t * Abc_NtkCollectObjects(Abc_Ntk_t *pNtk)
Definition abcUtil.c:1765
void Io_WriteDotNtk(Abc_Ntk_t *pNtk, Vec_Ptr_t *vNodes, Vec_Ptr_t *vNodesShow, char *pFileName, int fGateNames, int fUseReverse, int fAigIds)
Definition ioWriteDot.c:71
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Io_WriteDotNtk()

void Io_WriteDotNtk ( Abc_Ntk_t * pNtk,
Vec_Ptr_t * vNodes,
Vec_Ptr_t * vNodesShow,
char * pFileName,
int fGateNames,
int fUseReverse,
int fAigIds )

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, SopString[32];
76 int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl, Prev, AigNodeId;
77 int Limit = 500;
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, -1, ABC_INFINITY, 1) )
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 int nCubes = Abc_SopGetCubeNum((char *)pNode->pData);
307 if ( nCubes <= 16 )
308 pSopString = Abc_NtkPrintSop((char *)pNode->pData);
309 else {
310 sprintf( SopString, "%d cubes", nCubes );
311 pSopString = SopString;
312 }
313 }
314 //if ( pNtk->vOrigNodeIds )
315 // printf( "%d = %d \n", pNode->Id, Vec_IntEntry(pNtk->vOrigNodeIds, pNode->Id) )
316 AigNodeId = (fAigIds && pNtk->vOrigNodeIds) ? Vec_IntEntry(pNtk->vOrigNodeIds, pNode->Id) : -1;
317 if ( AigNodeId > 0 )
318 fprintf( pFile, " Node%d [label = \"%s%d\\n%s\"", pNode->Id, Abc_LitIsCompl(AigNodeId) ? "-":"+", Abc_Lit2Var(AigNodeId), pSopString );
319 else
320 fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id+1, pSopString );
321// fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id,
322// SuppSize,
323// pSopString );
324
325 fprintf( pFile, ", shape = ellipse" );
326 if ( pNode->fMarkB )
327 fprintf( pFile, ", style = filled" );
328 fprintf( pFile, "];\n" );
329 }
330 fprintf( pFile, "}" );
331 fprintf( pFile, "\n" );
332 fprintf( pFile, "\n" );
333 }
334
335 // generate the PI nodes if any
336 if ( LevelMin == 0 )
337 {
338 fprintf( pFile, "{\n" );
339 fprintf( pFile, " rank = same;\n" );
340 // the labeling node of this level
341 fprintf( pFile, " Level%d;\n", LevelMin );
342 // generate the PO nodes
343 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
344 {
345 if ( !Abc_ObjIsCi(pNode) )
346 {
347 // check if the costant node is present
348 if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 )
349 {
350 fprintf( pFile, " Node%d [label = \"Const%d\"", pNode->Id, Abc_NtkIsStrash(pNode->pNtk) || Abc_NodeIsConst1(pNode) );
351 fprintf( pFile, ", shape = ellipse" );
352 if ( pNode->fMarkB )
353 fprintf( pFile, ", style = filled" );
354 fprintf( pFile, ", color = coral, fillcolor = coral" );
355 fprintf( pFile, "];\n" );
356 }
357 continue;
358 }
359 fprintf( pFile, " Node%d [label = \"%s\"",
360 pNode->Id,
361 (Abc_ObjIsBo(pNode)? Abc_ObjName(Abc_ObjFanin0(pNode)):Abc_ObjName(pNode)) );
362 fprintf( pFile, ", shape = %s", (Abc_ObjIsBo(pNode)? "box":"triangle") );
363 if ( pNode->fMarkB )
364 fprintf( pFile, ", style = filled" );
365 fprintf( pFile, ", color = coral, fillcolor = coral" );
366 fprintf( pFile, "];\n" );
367 }
368 fprintf( pFile, "}" );
369 fprintf( pFile, "\n" );
370 fprintf( pFile, "\n" );
371 }
372
373 // generate invisible edges from the square down
374 fprintf( pFile, "title1 -> title2 [style = invis];\n" );
375 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
376 {
377 if ( (int)pNode->Level != LevelMax )
378 continue;
379 fprintf( pFile, "title2 -> Node%d [style = invis];\n", pNode->Id );
380 }
381 // generate invisible edges among the COs
382 Prev = -1;
383 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
384 {
385 if ( (int)pNode->Level != LevelMax )
386 continue;
387 if ( !Abc_ObjIsPo(pNode) )
388 continue;
389 if ( Prev >= 0 )
390 fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, pNode->Id );
391 Prev = pNode->Id;
392 }
393
394 // generate edges
395 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
396 {
397 if ( Abc_ObjIsLatch(pNode) )
398 continue;
399 Abc_ObjForEachFanin( pNode, pFanin, k )
400 {
401 if ( Abc_ObjIsLatch(pFanin) )
402 continue;
403 fCompl = 0;
404 if ( Abc_NtkIsStrash(pNtk) )
405 fCompl = Abc_ObjFaninC(pNode, k);
406 // generate the edge from this node to the next
407 fprintf( pFile, "Node%d", pNode->Id );
408 fprintf( pFile, " -> " );
409 fprintf( pFile, "Node%d", pFanin->Id );
410 fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" );
411// fprintf( pFile, ", label = \"%c\"", 'a' + k );
412 fprintf( pFile, "]" );
413 fprintf( pFile, ";\n" );
414 }
415 }
416
417 fprintf( pFile, "}" );
418 fprintf( pFile, "\n" );
419 fprintf( pFile, "\n" );
420 fclose( pFile );
421
422 // unmark the nodes from the set
423 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
424 pNode->fMarkC = 0;
425 if ( vNodesShow )
426 Vec_PtrForEachEntry( Abc_Obj_t *, vNodesShow, pNode, i )
427 pNode->fMarkB = 0;
428
429 // convert the network back into BDDs if this is how it was
430 if ( fHasBdds )
431 Abc_NtkSopToBdd(pNtk);
432}
void Abc_NtkPrintSop(FILE *pFile, Abc_Ntk_t *pNtk, int fUseRealNames)
Definition abcPrint.c:1200
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
ABC_DLL int Abc_NtkSopToBdd(Abc_Ntk_t *pNtk)
Definition abcFunc.c:865
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition abc.h:527
ABC_DLL int Abc_NtkLevelReverse(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1499
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
ABC_DLL int Abc_NtkLevel(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1449
ABC_DLL int Abc_SopGetCubeNum(char *pSop)
Definition abcSop.c:537
ABC_DLL int Abc_NtkBddToSop(Abc_Ntk_t *pNtk, int fMode, int nCubeLimit, int fCubeSort)
Definition abcFunc.c:866
ABC_DLL int Abc_NodeIsConst1(Abc_Obj_t *pNode)
Definition abcObj.c:916
#define ABC_INFINITY
MACRO DEFINITIONS ///.
Definition abc_global.h:250
char * Extra_TimeStamp()
char * Mio_GateReadSop(Mio_Gate_t *pGate)
Definition mioApi.c:179
char * Mio_GateReadName(Mio_Gate_t *pGate)
Definition mioApi.c:169
struct Mio_GateStruct_t_ Mio_Gate_t
Definition mio.h:43
char * pName
Definition abc.h:158
Vec_Int_t * vOrigNodeIds
Definition abc.h:217
void * pData
Definition abc.h:145
unsigned fMarkC
Definition abc.h:136
Abc_Ntk_t * pNtk
Definition abc.h:130
int Id
Definition abc.h:132
unsigned fMarkB
Definition abc.h:135
unsigned Level
Definition abc.h:142
#define assert(ex)
Definition util_old.h:213
char * sprintf()
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Io_WriteDotSeq()

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 447 of file ioWriteDot.c.

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