1 /**CFile****************************************************************
2 
3   FileName    [ioWriteBook.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Command processing package.]
8 
9   Synopsis    [Procedures to write Bookshelf files.]
10 
11   Author      [Myungchul Kim]
12 
13   Affiliation [U of Michigan]
14 
15   Date        [Ver. 1.0. Started - October 25, 2008.]
16 
17   Revision    [$Id: ioWriteBook.c,v 1.00 2005/11/10 00:00:00 mckima Exp $]
18 
19 ***********************************************************************/
20 
21 #include <math.h>
22 
23 #include "base/main/main.h"
24 #include "map/mio/mio.h"
25 #include "ioAbc.h"
26 
27 ABC_NAMESPACE_IMPL_START
28 
29 #define    NODES       0
30 #define    PL       1
31 #define coreHeight 1
32 #define termWidth  1
33 #define termHeight 1
34 
35 ////////////////////////////////////////////////////////////////////////
36 ///                        DECLARATIONS                              ///
37 ////////////////////////////////////////////////////////////////////////
38 
39 static unsigned Io_NtkWriteNodes( FILE * pFile, Abc_Ntk_t * pNtk );
40 static void Io_NtkWritePiPoNodes( FILE * pFile, Abc_Ntk_t * pNtk );
41 static void Io_NtkWriteLatchNode( FILE * pFile, Abc_Obj_t * pLatch, int NodesOrPl );
42 static unsigned Io_NtkWriteIntNode( FILE * pFile, Abc_Obj_t * pNode, int NodesOrPl );
43 static unsigned Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode );
44 static void Io_NtkWriteNets( FILE * pFile, Abc_Ntk_t * pNtk );
45 static void Io_NtkWriteIntNet( FILE * pFile, Abc_Obj_t * pNode );
46 static void Io_NtkBuildLayout( FILE * pFile1, FILE *pFile2, Abc_Ntk_t * pNtk, double aspectRatio, double whiteSpace, unsigned coreCellArea );
47 static void Io_NtkWriteScl( FILE * pFile, unsigned numCoreRows, double layoutWidth );
48 static void Io_NtkWritePl( FILE * pFile, Abc_Ntk_t * pNtk, unsigned numTerms, double layoutHeight, double layoutWidth );
49 static Vec_Ptr_t * Io_NtkOrderingPads( Abc_Ntk_t * pNtk, Vec_Ptr_t * vTerms );
50 static Abc_Obj_t * Io_NtkBfsPads( Abc_Ntk_t * pNtk, Abc_Obj_t * pCurrEntry, unsigned numTerms, int * pOrdered );
51 static int Abc_NodeIsNand2( Abc_Obj_t * pNode );
52 static int Abc_NodeIsNor2( Abc_Obj_t * pNode );
53 static int Abc_NodeIsAnd2( Abc_Obj_t * pNode );
54 static int Abc_NodeIsOr2( Abc_Obj_t * pNode );
55 static int Abc_NodeIsXor2( Abc_Obj_t * pNode );
56 static int Abc_NodeIsXnor2( Abc_Obj_t * pNode );
57 
Abc_Rint(double x)58 static inline double Abc_Rint( double x )   { return (double)(int)x;  }
59 
60 ////////////////////////////////////////////////////////////////////////
61 ///                     FUNCTION DEFINITIONS                         ///
62 ////////////////////////////////////////////////////////////////////////
63 
64 /**Function*************************************************************
65 
66   Synopsis    [Write the network into a Bookshelf file with the given name.]
67 
68   Description []
69 
70   SideEffects []
71 
72   SeeAlso     []
73 
74 ***********************************************************************/
Io_WriteBookLogic(Abc_Ntk_t * pNtk,char * FileName)75 void Io_WriteBookLogic( Abc_Ntk_t * pNtk, char * FileName )
76 {
77     Abc_Ntk_t * pNtkTemp;
78     // derive the netlist
79     pNtkTemp = Abc_NtkToNetlist(pNtk);
80     if ( pNtkTemp == NULL )
81     {
82         fprintf( stdout, "Writing BOOK has failed.\n" );
83         return;
84     }
85     Io_WriteBook( pNtkTemp, FileName );
86     Abc_NtkDelete( pNtkTemp );
87 }
88 
89 /**Function*************************************************************
90 
91   Synopsis    [Write the network into a BOOK file with the given name.]
92 
93   Description []
94 
95   SideEffects []
96 
97   SeeAlso     []
98 
99 ***********************************************************************/
Io_WriteBook(Abc_Ntk_t * pNtk,char * FileName)100 void Io_WriteBook( Abc_Ntk_t * pNtk, char * FileName )
101 {
102 
103     FILE * pFileNodes, * pFileNets, * pFileAux;
104     FILE * pFileScl, * pFilePl, * pFileWts;
105     char * FileExt = ABC_CALLOC( char, strlen(FileName)+7 );
106     unsigned coreCellArea=0;
107     Abc_Ntk_t * pExdc, * pNtkTemp;
108     int i;
109 
110     assert( Abc_NtkIsNetlist(pNtk) );
111     // start writing the files
112     strcpy(FileExt, FileName);
113     pFileNodes = fopen( strcat(FileExt,".nodes"), "w" );
114     strcpy(FileExt, FileName);
115     pFileNets  = fopen( strcat(FileExt,".nets"), "w" );
116     strcpy(FileExt, FileName);
117     pFileAux   = fopen( strcat(FileExt,".aux"), "w" );
118 
119         // write the aux file
120     if ( (pFileNodes == NULL) || (pFileNets == NULL) || (pFileAux == NULL) )
121     {
122         fclose( pFileAux );
123         fprintf( stdout, "Io_WriteBook(): Cannot open the output files.\n" );
124         return;
125     }
126     fprintf( pFileAux, "RowBasedPlacement : %s.nodes %s.nets %s.scl %s.pl %s.wts",
127          FileName, FileName, FileName, FileName, FileName );
128     fclose( pFileAux );
129 
130     // write the master network
131     coreCellArea+=Io_NtkWriteNodes( pFileNodes, pNtk );
132     Io_NtkWriteNets( pFileNets, pNtk );
133 
134     // write EXDC network if it exists
135     pExdc = Abc_NtkExdc( pNtk );
136     if ( pExdc )
137     {
138     coreCellArea+=Io_NtkWriteNodes( pFileNodes, pNtk );
139         Io_NtkWriteNets( pFileNets, pNtk );
140     }
141 
142     // make sure there is no logic hierarchy
143     assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
144 
145     // write the hierarchy if present
146     if ( Abc_NtkBlackboxNum(pNtk) > 0 )
147     {
148         Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pNtkTemp, i )
149         {
150             if ( pNtkTemp == pNtk )
151                 continue;
152             coreCellArea+=Io_NtkWriteNodes( pFileNodes, pNtkTemp );
153             Io_NtkWriteNets( pFileNets, pNtkTemp );
154         }
155     }
156     fclose( pFileNodes );
157     fclose( pFileNets );
158 
159     strcpy(FileExt, FileName);
160     pFileScl = fopen( strcat(FileExt,".scl"), "w" );
161     strcpy(FileExt, FileName);
162     pFilePl  = fopen( strcat(FileExt,".pl"), "w" );
163     strcpy(FileExt, FileName);
164     pFileWts   = fopen( strcat(FileExt,".wts"), "w" );
165     ABC_FREE(FileExt);
166 
167     Io_NtkBuildLayout( pFileScl, pFilePl, pNtk, 1.0, 10, coreCellArea );
168     fclose( pFileScl );
169     fclose( pFilePl );
170     fclose( pFileWts );
171 }
172 
173 /**Function*************************************************************
174 
175   Synopsis    [Write the network into a BOOK file with the given name.]
176 
177   Description []
178 
179   SideEffects []
180 
181   SeeAlso     []
182 
183 ***********************************************************************/
Io_NtkWriteNodes(FILE * pFile,Abc_Ntk_t * pNtk)184 unsigned Io_NtkWriteNodes( FILE * pFile, Abc_Ntk_t * pNtk )
185 {
186     ProgressBar * pProgress;
187     Abc_Obj_t * pLatch, * pNode;
188     unsigned numTerms, numNodes, coreCellArea=0;
189     int i;
190 
191     assert( Abc_NtkIsNetlist(pNtk) );
192     // write the forehead
193     numTerms=Abc_NtkPiNum(pNtk)+Abc_NtkPoNum(pNtk);
194     numNodes=numTerms+Abc_NtkNodeNum(pNtk)+Abc_NtkLatchNum(pNtk);
195     printf("NumNodes : %d\t", numNodes );
196     printf("NumTerminals : %d\n", numTerms );
197     fprintf( pFile, "UCLA    nodes    1.0\n");
198     fprintf( pFile, "NumNodes : %d\n", numNodes );
199     fprintf( pFile, "NumTerminals : %d\n", numTerms );
200     // write the PI/POs
201     Io_NtkWritePiPoNodes( pFile, pNtk );
202     // write the latches
203     if ( !Abc_NtkIsComb(pNtk) )
204     {
205         Abc_NtkForEachLatch( pNtk, pLatch, i )
206         {
207             Io_NtkWriteLatchNode( pFile, pLatch, NODES );
208             coreCellArea+=6*coreHeight;
209         }
210     }
211     // write each internal node
212     pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
213     Abc_NtkForEachNode( pNtk, pNode, i )
214     {
215         Extra_ProgressBarUpdate( pProgress, i, NULL );
216         coreCellArea+=Io_NtkWriteIntNode( pFile, pNode, NODES );
217     }
218     Extra_ProgressBarStop( pProgress );
219     return coreCellArea;
220 }
221 
222 /**Function*************************************************************
223 
224   Synopsis    [Writes the primary input nodes into a file]
225 
226   Description []
227 
228   SideEffects []
229 
230   SeeAlso     []
231 
232 ***********************************************************************/
Io_NtkWritePiPoNodes(FILE * pFile,Abc_Ntk_t * pNtk)233 void Io_NtkWritePiPoNodes( FILE * pFile, Abc_Ntk_t * pNtk )
234 {
235     Abc_Obj_t * pTerm, * pNet;
236     int i;
237 
238     Abc_NtkForEachPi( pNtk, pTerm, i )
239     {
240         pNet = Abc_ObjFanout0(pTerm);
241     fprintf( pFile, "i%s_input\t", Abc_ObjName(pNet) );
242     fprintf( pFile, "terminal ");
243     fprintf( pFile, " %d %d\n", termWidth, termHeight );
244     }
245 
246     Abc_NtkForEachPo( pNtk, pTerm, i )
247     {
248     pNet = Abc_ObjFanin0(pTerm);
249     fprintf( pFile, "o%s_output\t", Abc_ObjName(pNet) );
250     fprintf( pFile, "terminal ");
251     fprintf( pFile, " %d %d\n", termWidth, termHeight );
252     }
253 }
254 
255 /**Function*************************************************************
256 
257   Synopsis    [Write the latch nodes into a file.]
258 
259   Description []
260 
261   SideEffects []
262 
263   SeeAlso     []
264 
265 ***********************************************************************/
Io_NtkWriteLatchNode(FILE * pFile,Abc_Obj_t * pLatch,int NodesOrPl)266 void Io_NtkWriteLatchNode( FILE * pFile, Abc_Obj_t * pLatch, int NodesOrPl )
267 {
268     Abc_Obj_t * pNetLi, * pNetLo;
269 
270     pNetLi = Abc_ObjFanin0( Abc_ObjFanin0(pLatch) );
271     pNetLo = Abc_ObjFanout0( Abc_ObjFanout0(pLatch) );
272     /// write the latch line
273     fprintf( pFile, "%s_%s_latch\t", Abc_ObjName(pNetLi), Abc_ObjName(pNetLo) );
274     if (NodesOrPl == NODES)
275         fprintf( pFile, " %d %d\n", 6, 1 );
276 }
277 
278 /**Function*************************************************************
279 
280   Synopsis    [Write the internal node into a file.]
281 
282   Description []
283 
284   SideEffects []
285 
286   SeeAlso     []
287 
288 ***********************************************************************/
Io_NtkWriteIntNode(FILE * pFile,Abc_Obj_t * pNode,int NodesOrPl)289 unsigned Io_NtkWriteIntNode( FILE * pFile, Abc_Obj_t * pNode, int NodesOrPl )
290 {
291     unsigned sizex=0, sizey=coreHeight, isize=0;
292     //double nx, ny, xstep, ystep;
293     Abc_Obj_t * pNeti, *pNeto;
294     int i;
295 
296     // write the network after mapping
297     if ( Abc_NtkHasMapping(pNode->pNtk) )
298         sizex=Io_NtkWriteNodeGate( pFile, pNode );
299     else
300     {
301     Abc_ObjForEachFanin( pNode, pNeti, i )
302         fprintf( pFile, "%s_", Abc_ObjName(pNeti) );
303     Abc_ObjForEachFanout( pNode, pNeto, i )
304         fprintf( pFile, "%s_", Abc_ObjName(pNeto) );
305     fprintf( pFile, "name\t" );
306 
307     if(NodesOrPl == NODES)
308     {
309         isize=Abc_ObjFaninNum(pNode);
310         if ( Abc_NodeIsConst0(pNode) || Abc_NodeIsConst1(pNode) )
311             sizex=0;
312         else if ( Abc_NodeIsInv(pNode) )
313             sizex=1;
314         else if ( Abc_NodeIsBuf(pNode) )
315             sizex=2;
316         else
317         {
318             assert( Abc_NtkHasSop(pNode->pNtk) );
319             if ( Abc_NodeIsNand2(pNode) || Abc_NodeIsNor2(pNode) )
320             sizex=2;
321         else if ( Abc_NodeIsAnd2(pNode) || Abc_NodeIsOr2(pNode) )
322             sizex=3;
323         else if ( Abc_NodeIsXor2(pNode) || Abc_NodeIsXnor2(pNode) )
324             sizex=5;
325         else
326         {
327             assert( isize > 2 );
328             sizex=isize+Abc_SopGetCubeNum((char *)pNode->pData);
329         }
330         }
331     }
332     }
333     if(NodesOrPl == NODES)
334     {
335     fprintf( pFile, " %d %d\n", sizex, sizey );
336 
337     // Equally place pins. Size pins needs /  isize+#output+1
338     isize= isize + Abc_ObjFanoutNum(pNode) + 1;
339     }
340     return sizex*sizey;
341     /*
342     xstep = sizex / isize;
343     ystep = sizey / isize;
344     nx= -0.5 * sizex;
345     ny= -0.5 * sizey;
346 
347     Abc_ObjForEachFanin( pNode, pFanin, i )
348     {
349             nx+= xstep;
350             ny+= ystep;
351             if (fabs(nx) < 0.001)
352                     nx= 0;
353             if (fabs(ny) < 0.001)
354                     ny= 0;
355     }
356     Abc_ObjForEachFanout( pNode, pFanout, i )
357     {
358             nx+= xstep;
359             ny+= ystep;
360             if (fabs(nx) < 0.001)
361                     nx= 0;
362             if (fabs(ny) < 0.001)
363                     ny= 0;
364     }
365     */
366 }
367 
368 /**Function*************************************************************
369 
370   Synopsis    [Writes the internal node after tech mapping.]
371 
372   Description []
373 
374   SideEffects []
375 
376   SeeAlso     []
377 
378 ***********************************************************************/
Io_NtkWriteNodeGate(FILE * pFile,Abc_Obj_t * pNode)379 unsigned Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode )
380 {
381     Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData;
382     Mio_Pin_t * pGatePin;
383     int i;
384     // write the node gate
385     for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
386         fprintf( pFile, "%s_", Abc_ObjName( Abc_ObjFanin(pNode,i) ) );
387     assert ( i == Abc_ObjFaninNum(pNode) );
388     fprintf( pFile, "%s_%s\t", Abc_ObjName( Abc_ObjFanout0(pNode) ), Mio_GateReadName(pGate) );
389     return Mio_GateReadArea(pGate);
390 }
391 
392 /**Function*************************************************************
393 
394   Synopsis    [Write the nets into a file.]
395 
396   Description []
397 
398   SideEffects []
399 
400   SeeAlso     []
401 
402 ***********************************************************************/
Io_NtkWriteNets(FILE * pFile,Abc_Ntk_t * pNtk)403 void Io_NtkWriteNets( FILE * pFile, Abc_Ntk_t * pNtk )
404 {
405     ProgressBar * pProgress;
406     Abc_Obj_t * pNet;
407     unsigned numPin=0;
408     int i;
409 
410     assert( Abc_NtkIsNetlist(pNtk) );
411     // write the head
412     Abc_NtkForEachNet( pNtk, pNet, i )
413     numPin+=Abc_ObjFaninNum(pNet)+Abc_ObjFanoutNum(pNet);
414     printf( "NumNets  : %d\t", Abc_NtkNetNum(pNtk) );
415     printf( "NumPins      : %d\n\n", numPin );
416     fprintf( pFile, "UCLA    nets    1.0\n");
417     fprintf( pFile, "NumNets : %d\n", Abc_NtkNetNum(pNtk) );
418     fprintf( pFile, "NumPins : %d\n", numPin );
419 
420     // write nets
421     pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNetNum(pNtk) );
422     Abc_NtkForEachNet( pNtk, pNet, i )
423     {
424         Extra_ProgressBarUpdate( pProgress, i, NULL );
425         Io_NtkWriteIntNet( pFile, pNet );
426     }
427     Extra_ProgressBarStop( pProgress );
428 }
429 
430 /**Function*************************************************************
431 
432   Synopsis    [Write the nets into a file.]
433 
434   Description []
435 
436   SideEffects []
437 
438   SeeAlso     []
439 
440 ***********************************************************************/
Io_NtkWriteIntNet(FILE * pFile,Abc_Obj_t * pNet)441 void Io_NtkWriteIntNet( FILE * pFile, Abc_Obj_t * pNet )
442 {
443     Abc_Obj_t * pFanin, * pFanout;
444     Abc_Obj_t * pNeti, * pNeto;
445     Abc_Obj_t * pNetLi, * pNetLo, * pLatch;
446     int i, j;
447     int NetDegree=Abc_ObjFaninNum(pNet)+Abc_ObjFanoutNum(pNet);
448 
449     fprintf( pFile, "NetDegree\t:\t\t%d\t\t%s\n", NetDegree, Abc_ObjName(Abc_ObjFanin0(pNet)) );
450 
451     pFanin=Abc_ObjFanin0(pNet);
452     if ( Abc_ObjIsPi(pFanin) )
453     fprintf( pFile, "i%s_input I\n", Abc_ObjName(pNet) );
454     else
455     {
456     if(!Abc_NtkIsComb(pNet->pNtk) && Abc_ObjFaninNum(pFanin) && Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
457     {
458         pLatch=Abc_ObjFanin0(pFanin);
459         pNetLi=Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
460         pNetLo=Abc_ObjFanout0(Abc_ObjFanout0(pLatch));
461         fprintf( pFile, "%s_%s_latch I : ", Abc_ObjName(pNetLi), Abc_ObjName(pNetLo) );
462     }
463     else
464     {
465         Abc_ObjForEachFanin( pFanin, pNeti, j )
466         fprintf( pFile, "%s_", Abc_ObjName(pNeti) );
467         Abc_ObjForEachFanout( pFanin, pNeto, j )
468         fprintf( pFile, "%s_", Abc_ObjName(pNeto) );
469         if ( Abc_NtkHasMapping(pNet->pNtk) )
470         fprintf( pFile, "%s : ", Mio_GateReadName((Mio_Gate_t *)pFanin->pData) );
471         else
472         fprintf( pFile, "name I : " );
473     }
474     // offsets are simlply 0.00 0.00 at the moment
475     fprintf( pFile, "%.2f %.2f\n", .0, .0 );
476     }
477 
478     Abc_ObjForEachFanout( pNet, pFanout, i )
479     {
480     if ( Abc_ObjIsPo(pFanout) )
481         fprintf( pFile, "o%s_output O\n", Abc_ObjName(pNet) );
482     else
483     {
484         if(!Abc_NtkIsComb(pNet->pNtk) && Abc_ObjFanoutNum(pFanout) && Abc_ObjIsLatch( Abc_ObjFanout0(pFanout) ) )
485         {
486         pLatch=Abc_ObjFanout0(pFanout);
487         pNetLi=Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
488         pNetLo=Abc_ObjFanout0(Abc_ObjFanout0(pLatch));
489         fprintf( pFile, "%s_%s_latch O : ", Abc_ObjName(pNetLi), Abc_ObjName(pNetLo) );
490         }
491         else
492         {
493         Abc_ObjForEachFanin( pFanout, pNeti, j )
494         fprintf( pFile, "%s_", Abc_ObjName(pNeti) );
495         Abc_ObjForEachFanout( pFanout, pNeto, j )
496         fprintf( pFile, "%s_", Abc_ObjName(pNeto) );
497         if ( Abc_NtkHasMapping(pNet->pNtk) )
498             fprintf( pFile, "%s : ", Mio_GateReadName((Mio_Gate_t *)pFanout->pData) );
499         else
500             fprintf( pFile, "name O : " );
501         }
502     // offsets are simlply 0.00 0.00 at the moment
503     fprintf( pFile, "%.2f %.2f\n", .0, .0 );
504     }
505     }
506 }
507 
508 /**Function*************************************************************
509 
510   Synopsis    [Write the network into a BOOK file with the given name.]
511 
512   Description []
513 
514   SideEffects []
515 
516   SeeAlso     []
517 
518 ***********************************************************************/
Io_NtkBuildLayout(FILE * pFileScl,FILE * pFilePl,Abc_Ntk_t * pNtk,double aspectRatio,double whiteSpace,unsigned coreCellArea)519 void Io_NtkBuildLayout( FILE * pFileScl, FILE * pFilePl, Abc_Ntk_t * pNtk, double aspectRatio, double whiteSpace, unsigned coreCellArea )
520 {
521     unsigned numCoreCells=Abc_NtkNodeNum(pNtk)+Abc_NtkLatchNum(pNtk);
522     double targetLayoutArea = coreCellArea/(1.0-(whiteSpace/100.0));
523     unsigned numCoreRows=(aspectRatio>0.0) ? (Abc_Rint(sqrt(targetLayoutArea/aspectRatio)/coreHeight)) : 0;
524     unsigned numTerms=Abc_NtkPiNum(pNtk)+Abc_NtkPoNum(pNtk);
525     unsigned totalWidth=coreCellArea/coreHeight;
526     double layoutHeight = numCoreRows * coreHeight;
527     double layoutWidth = Abc_Rint(targetLayoutArea/layoutHeight);
528     double actualLayoutArea = layoutWidth * layoutHeight;
529 
530     printf( "Core cell height(==site height) is %d\n", coreHeight );
531     printf( "Total core cell width is %d giving an ave width of %f\n", totalWidth, (double)(totalWidth/numCoreCells));
532     printf( "Target Dimensions:\n" );
533     printf( "  Area  :   %f\n", targetLayoutArea );
534     printf( "  WS%%   :   %f\n", whiteSpace );
535     printf( "  AR    :   %f\n", aspectRatio );
536     printf( "Actual Dimensions:\n" );
537     printf( "  Width :   %f\n", layoutWidth );
538     printf( "  Height:   %f (%d rows)\n", layoutHeight, numCoreRows);
539     printf( "  Area  :   %f\n", actualLayoutArea );
540     printf( "  WS%%   :   %f\n", 100*(actualLayoutArea-coreCellArea)/actualLayoutArea );
541     printf( "  AR    :   %f\n\n", layoutWidth/layoutHeight );
542 
543     Io_NtkWriteScl( pFileScl, numCoreRows, layoutWidth );
544     Io_NtkWritePl( pFilePl, pNtk, numTerms, layoutHeight, layoutWidth );
545 }
546 
547 /**Function*************************************************************
548 
549   Synopsis    [Write the network into a BOOK file with the given name.]
550 
551   Description []
552 
553   SideEffects []
554 
555   SeeAlso     []
556 
557 ***********************************************************************/
Io_NtkWriteScl(FILE * pFile,unsigned numCoreRows,double layoutWidth)558 void Io_NtkWriteScl( FILE * pFile, unsigned numCoreRows, double layoutWidth )
559 {
560     int origin_y=0;
561     char * rowOrients[2] = {"N", "FS"};
562     char symmetry='Y';
563     double sitewidth=1.0;
564     double spacing=1.0;
565 
566     unsigned rowId;
567     // write the forehead
568     fprintf( pFile, "UCLA    scl    1.0\n\n" );
569     fprintf( pFile, "Numrows : %d\n\n", numCoreRows );
570 
571     for( rowId=0 ; rowId<numCoreRows ; rowId++, origin_y += coreHeight )
572     {
573     fprintf( pFile, "CoreRow Horizontal\n" );
574     fprintf( pFile, " Coordinate   : \t%d\n", origin_y);
575     fprintf( pFile, " Height       : \t%d\n", coreHeight);
576     fprintf( pFile, " Sitewidth    : \t%d\n", (unsigned)sitewidth );
577     fprintf( pFile, " Sitespacing  : \t%d\n", (unsigned)spacing );
578     fprintf( pFile, " Siteorient   : \t%s\n", rowOrients[rowId%2] );
579     //if( coreRow[i].site.symmetry.rot90 || coreRow[i].site.symmetry.y || coreRow[i].site.symmetry.x )
580     fprintf( pFile, " Sitesymmetry : \t%c\n", symmetry );
581     //else fprintf( pFile, "Sitesymmetry            : \t\t\t1\n" );
582     fprintf( pFile, " SubrowOrigin : \t%d Numsites :    \t%d\n", 0, (unsigned)layoutWidth );
583     fprintf( pFile, "End\n" );
584     }
585 }
586 
587 /**Function*************************************************************
588 
589   Synopsis    [Write the network into a BOOK file with the given name.]
590 
591   Description []
592 
593   SideEffects []
594 
595   SeeAlso     []
596 
597 ***********************************************************************/
Io_NtkWritePl(FILE * pFile,Abc_Ntk_t * pNtk,unsigned numTerms,double layoutWidth,double layoutHeight)598 void Io_NtkWritePl( FILE * pFile, Abc_Ntk_t * pNtk, unsigned numTerms, double layoutWidth, double layoutHeight )
599 {
600     Abc_Obj_t * pTerm, * pLatch, * pNode;
601     Vec_Ptr_t * vTerms = Vec_PtrAlloc ( numTerms );
602     Vec_Ptr_t * vOrderedTerms = Vec_PtrAlloc ( numTerms );
603     double layoutPerim = 2*layoutWidth + 2*layoutHeight;
604     double nextLoc_x, nextLoc_y;
605     double delta;
606     unsigned termsOnTop, termsOnBottom, termsOnLeft, termsOnRight;
607     unsigned t;
608     int i;
609 
610     termsOnTop = termsOnBottom = (unsigned)(Abc_Rint(numTerms*(layoutWidth/layoutPerim)));
611     termsOnLeft = numTerms - (termsOnTop+termsOnBottom);
612     termsOnRight = (unsigned)(ceil(termsOnLeft/2.0));
613     termsOnLeft -= termsOnRight;
614 
615     Abc_NtkForEachPi( pNtk, pTerm, i )
616     Vec_PtrPush( vTerms, pTerm );
617     Abc_NtkForEachPo( pNtk, pTerm, i )
618     Vec_PtrPush( vTerms, pTerm );
619     // Ordering Pads
620     vOrderedTerms=Io_NtkOrderingPads( pNtk, vTerms );
621     assert( termsOnTop+termsOnBottom+termsOnLeft+termsOnRight == (unsigned)Vec_PtrSize(vOrderedTerms) );
622 
623     printf( "Done constructing layout region\n" );
624     printf( "Terminals: %d\n", numTerms );
625     printf( "  Top:     %d\n", termsOnTop );
626     printf( "  Bottom:  %d\n", termsOnBottom );
627     printf( "  Left:    %d\n", termsOnLeft );
628     printf( "  Right:   %d\n", termsOnRight );
629 
630     fprintf( pFile, "UCLA    pl    1.0\n\n" );
631 
632     nextLoc_x = floor(.0);
633     nextLoc_y = ceil(layoutHeight + 2*coreHeight);
634     delta   = layoutWidth / termsOnTop;
635     for(t = 0; t < termsOnTop; t++)
636     {
637     pTerm = (Abc_Obj_t *)Vec_PtrEntry( vOrderedTerms, t );
638     if( Abc_ObjIsPi(pTerm) )
639         fprintf( pFile, "i%s_input\t\t", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
640     else
641         fprintf( pFile, "o%s_output\t\t", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
642     if( t && Abc_Rint(nextLoc_x) < Abc_Rint(nextLoc_x-delta)+termWidth )
643         nextLoc_x++;
644     fprintf( pFile, "%d\t\t%d\t: %s /FIXED\n", (int)Abc_Rint(nextLoc_x), (int)Abc_Rint(nextLoc_y), "FS" );
645     nextLoc_x += delta;
646     }
647 
648     nextLoc_x = floor(.0);
649     nextLoc_y = floor(.0 - 2*coreHeight - termHeight);
650     delta   = layoutWidth / termsOnBottom;
651     for(;t < termsOnTop+termsOnBottom; t++)
652     {
653     pTerm = (Abc_Obj_t *)Vec_PtrEntry( vOrderedTerms, t );
654     if( Abc_ObjIsPi(pTerm) )
655         fprintf( pFile, "i%s_input\t\t", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
656     else
657         fprintf( pFile, "o%s_output\t\t", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
658     if( t!=termsOnTop && Abc_Rint(nextLoc_x) < Abc_Rint(nextLoc_x-delta)+termWidth )
659         nextLoc_x++;
660     fprintf( pFile, "%d\t\t%d\t: %s /FIXED\n", (int)Abc_Rint(nextLoc_x), (int)Abc_Rint(nextLoc_y), "N" );
661     nextLoc_x     += delta;
662     }
663 
664     nextLoc_x = floor(.0-2*coreHeight-termWidth);
665     nextLoc_y = floor(.0);
666     delta   = layoutHeight / termsOnLeft;
667     for(;t < termsOnTop+termsOnBottom+termsOnLeft; t++)
668     {
669     pTerm = (Abc_Obj_t *)Vec_PtrEntry( vOrderedTerms, t );
670     if( Abc_ObjIsPi(pTerm) )
671         fprintf( pFile, "i%s_input\t\t", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
672     else
673         fprintf( pFile, "o%s_output\t\t", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
674     if( Abc_Rint(nextLoc_y) < Abc_Rint(nextLoc_y-delta)+termHeight )
675         nextLoc_y++;
676     fprintf( pFile, "%d\t\t%d\t: %s /FIXED\n", (int)Abc_Rint(nextLoc_x), (int)Abc_Rint(nextLoc_y), "E" );
677     nextLoc_y     += delta;
678     }
679 
680     nextLoc_x = ceil(layoutWidth+2*coreHeight);
681     nextLoc_y = floor(.0);
682     delta   = layoutHeight / termsOnRight;
683     for(;t < termsOnTop+termsOnBottom+termsOnLeft+termsOnRight; t++)
684     {
685            pTerm = (Abc_Obj_t *)Vec_PtrEntry( vOrderedTerms, t );
686     if( Abc_ObjIsPi(pTerm) )
687         fprintf( pFile, "i%s_input\t\t", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
688     else
689         fprintf( pFile, "o%s_output\t\t", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
690     if( Abc_Rint(nextLoc_y) < Abc_Rint(nextLoc_y-delta)+termHeight )
691         nextLoc_y++;
692     fprintf( pFile, "%d\t\t%d\t: %s /FIXED\n", (int)Abc_Rint(nextLoc_x), (int)Abc_Rint(nextLoc_y), "FW" );
693     nextLoc_y     += delta;
694     }
695 
696     if( !Abc_NtkIsComb(pNtk) )
697     {
698     Abc_NtkForEachLatch( pNtk, pLatch, i )
699     {
700         Io_NtkWriteLatchNode( pFile, pLatch, PL );
701         fprintf( pFile, "\t%d\t\t%d\t: %s\n", 0, 0, "N" );
702     }
703     }
704 
705     Abc_NtkForEachNode( pNtk, pNode, i )
706     {
707     Io_NtkWriteIntNode( pFile, pNode, PL );
708     fprintf( pFile, "\t%d\t\t%d\t: %s\n", 0, 0, "N" );
709     }
710 }
711 
712 /**Function*************************************************************
713 
714   Synopsis    [Returns the closest I/O to a given I/O.]
715 
716   Description []
717 
718   SideEffects []
719 
720   SeeAlso     []
721 
722 ***********************************************************************/
Io_NtkOrderingPads(Abc_Ntk_t * pNtk,Vec_Ptr_t * vTerms)723 Vec_Ptr_t * Io_NtkOrderingPads( Abc_Ntk_t * pNtk, Vec_Ptr_t * vTerms )
724 {
725     ProgressBar * pProgress;
726     unsigned numTerms=Vec_PtrSize(vTerms);
727     unsigned termIdx=0, termCount=0;
728     int * pOrdered = ABC_ALLOC(int, numTerms);
729     int newNeighbor=1;
730     Vec_Ptr_t * vOrderedTerms = Vec_PtrAlloc ( numTerms );
731     Abc_Obj_t * pNeighbor = NULL, * pNextTerm;
732     unsigned i;
733 
734     for( i=0 ; i<numTerms ; i++ )
735     pOrdered[i]=0;
736 
737     pNextTerm = (Abc_Obj_t *)Vec_PtrEntry(vTerms, termIdx++);
738     pProgress = Extra_ProgressBarStart( stdout, numTerms );
739     while( termCount < numTerms && termIdx < numTerms )
740     {
741     if( pOrdered[Abc_ObjId(pNextTerm)] && !newNeighbor )
742     {
743         pNextTerm = (Abc_Obj_t *)Vec_PtrEntry( vTerms, termIdx++ );
744         continue;
745     }
746     if(!Vec_PtrPushUnique( vOrderedTerms, pNextTerm ))
747     {
748         pOrdered[Abc_ObjId(pNextTerm)]=1;
749         termCount++;
750     }
751     pNeighbor=Io_NtkBfsPads( pNtk, pNextTerm, numTerms, pOrdered );
752     if( (newNeighbor=!Vec_PtrPushUnique( vOrderedTerms, pNeighbor )) )
753     {
754        pOrdered[Abc_ObjId(pNeighbor)]=1;
755        termCount++;
756        pNextTerm=pNeighbor;
757     }
758     else if(termIdx < numTerms)
759         pNextTerm = (Abc_Obj_t *)Vec_PtrEntry( vTerms, termIdx++ );
760 
761     Extra_ProgressBarUpdate( pProgress, termCount, NULL );
762     }
763     Extra_ProgressBarStop( pProgress );
764     assert(termCount==numTerms);
765     return vOrderedTerms;
766 }
767 
768 /**Function*************************************************************
769 
770   Synopsis    [Returns the closest I/O to a given I/O.]
771 
772   Description []
773 
774   SideEffects []
775 
776   SeeAlso     []
777 
778 ***********************************************************************/
Io_NtkBfsPads(Abc_Ntk_t * pNtk,Abc_Obj_t * pTerm,unsigned numTerms,int * pOrdered)779 Abc_Obj_t * Io_NtkBfsPads( Abc_Ntk_t * pNtk, Abc_Obj_t * pTerm, unsigned numTerms, int * pOrdered )
780 {
781     Vec_Ptr_t * vNeighbors = Vec_PtrAlloc ( numTerms );
782     Abc_Obj_t * pNet, * pNode, * pNeighbor;
783     int foundNeighbor=0;
784     int i;
785 
786     assert(Abc_ObjIsPi(pTerm) || Abc_ObjIsPo(pTerm) );
787     Abc_NtkIncrementTravId ( pNtk );
788     Abc_NodeSetTravIdCurrent( pTerm );
789     if(Abc_ObjIsPi(pTerm))
790     {
791     pNet = Abc_ObjFanout0(pTerm);
792     Abc_ObjForEachFanout( pNet, pNode, i )
793         Vec_PtrPush( vNeighbors, pNode );
794     }
795     else
796     {
797     pNet = Abc_ObjFanin0(pTerm);
798     Abc_ObjForEachFanin( pNet, pNode, i )
799         Vec_PtrPush( vNeighbors, pNode );
800     }
801 
802     while ( Vec_PtrSize(vNeighbors) >0 )
803     {
804     pNeighbor = (Abc_Obj_t *)Vec_PtrEntry( vNeighbors, 0 );
805     assert( Abc_ObjIsNode(pNeighbor) || Abc_ObjIsTerm(pNeighbor) );
806     Vec_PtrRemove( vNeighbors, pNeighbor );
807 
808     if( Abc_NodeIsTravIdCurrent( pNeighbor ) )
809         continue;
810     Abc_NodeSetTravIdCurrent( pNeighbor );
811 
812     if( ((Abc_ObjIsPi(pNeighbor) || Abc_ObjIsPo(pNeighbor))) && !pOrdered[Abc_ObjId(pNeighbor)] )
813     {
814         foundNeighbor=1;
815         break;
816     }
817     if( Abc_ObjFanoutNum( pNeighbor ) )
818     {
819         pNet=Abc_ObjFanout0( pNeighbor );
820         if( !Abc_NtkIsComb(pNtk) && Abc_ObjIsLatch(pNet) )
821         pNet=Abc_ObjFanout0( Abc_ObjFanout0(pNet) );
822         Abc_ObjForEachFanout( pNet, pNode, i )
823         if( !Abc_NodeIsTravIdCurrent(pNode) )
824             Vec_PtrPush( vNeighbors, pNode );
825     }
826     if( Abc_ObjFaninNum( pNeighbor ) )
827     {
828         if( !Abc_NtkIsComb(pNtk) && Abc_ObjIsLatch(Abc_ObjFanin0(pNeighbor)) )
829         pNeighbor=Abc_ObjFanin0( Abc_ObjFanin0(pNeighbor) );
830         Abc_ObjForEachFanin( pNeighbor, pNet, i )
831         if( !Abc_NodeIsTravIdCurrent(pNode=Abc_ObjFanin0(pNet)) )
832             Vec_PtrPush( vNeighbors, pNode );
833     }
834     }
835     return ( foundNeighbor ) ? pNeighbor : pTerm;
836 }
837 
838 /**Function*************************************************************
839 
840   Synopsis    [Test is the node is nand2.]
841 
842   Description []
843 
844   SideEffects []
845 
846   SeeAlso     []
847 
848 ***********************************************************************/
Abc_NodeIsNand2(Abc_Obj_t * pNode)849 int Abc_NodeIsNand2( Abc_Obj_t * pNode )
850 {
851     Abc_Ntk_t * pNtk = pNode->pNtk;
852     assert( Abc_NtkIsNetlist(pNtk) );
853     assert( Abc_ObjIsNode(pNode) );
854     if ( Abc_ObjFaninNum(pNode) != 2 )
855         return 0;
856     if ( Abc_NtkHasSop(pNtk) )
857     return ( !strcmp(((char *)pNode->pData), "-0 1\n0- 1\n") ||
858          !strcmp(((char *)pNode->pData), "0- 1\n-0 1\n") ||
859          !strcmp(((char *)pNode->pData), "11 0\n") );
860     if ( Abc_NtkHasMapping(pNtk) )
861         return pNode->pData == (void *)Mio_LibraryReadNand2((Mio_Library_t *)Abc_FrameReadLibGen());
862     assert( 0 );
863     return 0;
864 }
865 
866 /**Function*************************************************************
867 
868   Synopsis    [Test is the node is nand2.]
869 
870   Description []
871 
872   SideEffects []
873 
874   SeeAlso     []
875 
876 ***********************************************************************/
Abc_NodeIsNor2(Abc_Obj_t * pNode)877 int Abc_NodeIsNor2( Abc_Obj_t * pNode )
878 {
879     Abc_Ntk_t * pNtk = pNode->pNtk;
880     assert( Abc_NtkIsNetlist(pNtk) );
881     assert( Abc_ObjIsNode(pNode) );
882     if ( Abc_ObjFaninNum(pNode) != 2 )
883         return 0;
884     if ( Abc_NtkHasSop(pNtk) )
885         return ( !strcmp(((char *)pNode->pData), "00 1\n") );
886     assert( 0 );
887     return 0;
888 }
889 
890 /**Function*************************************************************
891 
892   Synopsis    [Test is the node is and2.]
893 
894   Description []
895 
896   SideEffects []
897 
898   SeeAlso     []
899 
900 ***********************************************************************/
Abc_NodeIsAnd2(Abc_Obj_t * pNode)901 int Abc_NodeIsAnd2( Abc_Obj_t * pNode )
902 {
903     Abc_Ntk_t * pNtk = pNode->pNtk;
904     assert( Abc_NtkIsNetlist(pNtk) );
905     assert( Abc_ObjIsNode(pNode) );
906     if ( Abc_ObjFaninNum(pNode) != 2 )
907         return 0;
908     if ( Abc_NtkHasSop(pNtk) )
909     return Abc_SopIsAndType(((char *)pNode->pData));
910     if ( Abc_NtkHasMapping(pNtk) )
911         return pNode->pData == (void *)Mio_LibraryReadAnd2((Mio_Library_t *)Abc_FrameReadLibGen());
912     assert( 0 );
913     return 0;
914 }
915 
916 /**Function*************************************************************
917 
918   Synopsis    [Test is the node is or2.]
919 
920   Description []
921 
922   SideEffects []
923 
924   SeeAlso     []
925 
926 ***********************************************************************/
Abc_NodeIsOr2(Abc_Obj_t * pNode)927 int Abc_NodeIsOr2( Abc_Obj_t * pNode )
928 {
929     Abc_Ntk_t * pNtk = pNode->pNtk;
930     assert( Abc_NtkIsNetlist(pNtk) );
931     assert( Abc_ObjIsNode(pNode) );
932     if ( Abc_ObjFaninNum(pNode) != 2 )
933         return 0;
934     if ( Abc_NtkHasSop(pNtk) )
935     return ( Abc_SopIsOrType(((char *)pNode->pData))   ||
936          !strcmp(((char *)pNode->pData), "01 0\n") ||
937          !strcmp(((char *)pNode->pData), "10 0\n") ||
938          !strcmp(((char *)pNode->pData), "00 0\n") );
939          //off-sets, too
940     assert( 0 );
941     return 0;
942 }
943 
944 /**Function*************************************************************
945 
946   Synopsis    [Test is the node is xor2.]
947 
948   Description []
949 
950   SideEffects []
951 
952   SeeAlso     []
953 
954 ***********************************************************************/
Abc_NodeIsXor2(Abc_Obj_t * pNode)955 int Abc_NodeIsXor2( Abc_Obj_t * pNode )
956 {
957     Abc_Ntk_t * pNtk = pNode->pNtk;
958     assert( Abc_NtkIsNetlist(pNtk) );
959     assert( Abc_ObjIsNode(pNode) );
960     if ( Abc_ObjFaninNum(pNode) != 2 )
961         return 0;
962     if ( Abc_NtkHasSop(pNtk) )
963     return ( !strcmp(((char *)pNode->pData), "01 1\n10 1\n") || !strcmp(((char *)pNode->pData), "10 1\n01 1\n")  );
964     assert( 0 );
965     return 0;
966 }
967 
968 /**Function*************************************************************
969 
970   Synopsis    [Test is the node is xnor2.]
971 
972   Description []
973 
974   SideEffects []
975 
976   SeeAlso     []
977 
978 ***********************************************************************/
Abc_NodeIsXnor2(Abc_Obj_t * pNode)979 int Abc_NodeIsXnor2( Abc_Obj_t * pNode )
980 {
981     Abc_Ntk_t * pNtk = pNode->pNtk;
982     assert( Abc_NtkIsNetlist(pNtk) );
983     assert( Abc_ObjIsNode(pNode) );
984     if ( Abc_ObjFaninNum(pNode) != 2 )
985         return 0;
986     if ( Abc_NtkHasSop(pNtk) )
987     return ( !strcmp(((char *)pNode->pData), "11 1\n00 1\n") || !strcmp(((char *)pNode->pData), "00 1\n11 1\n") );
988     assert( 0 );
989     return 0;
990 }
991 
992 ////////////////////////////////////////////////////////////////////////
993 ///                       END OF FILE                                ///
994 ////////////////////////////////////////////////////////////////////////
995 
996 
997 ABC_NAMESPACE_IMPL_END
998 
999