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