1 /**CFile****************************************************************
2
3 FileName [mioUtils.c]
4
5 PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
6
7 Synopsis [File reading/writing for technology mapping.]
8
9 Author [MVSIS Group]
10
11 Affiliation [UC Berkeley]
12
13 Date [Ver. 1.0. Started - September 8, 2003.]
14
15 Revision [$Id: mioUtils.c,v 1.6 2004/09/03 18:02:20 satrajit Exp $]
16
17 ***********************************************************************/
18
19 #include <math.h>
20 #include "mioInt.h"
21 #include "base/main/main.h"
22 #include "exp.h"
23 #include "misc/util/utilTruth.h"
24 #include "opt/dau/dau.h"
25 #include "misc/util/utilNam.h"
26 #include "map/scl/sclLib.h"
27 #include "map/scl/sclCon.h"
28
29 ABC_NAMESPACE_IMPL_START
30
31
32 ////////////////////////////////////////////////////////////////////////
33 /// DECLARATIONS ///
34 ////////////////////////////////////////////////////////////////////////
35
36 ////////////////////////////////////////////////////////////////////////
37 /// FUNCTION DEFINITIONS ///
38 ////////////////////////////////////////////////////////////////////////
39
40 /**Function*************************************************************
41
42 Synopsis []
43
44 Description []
45
46 SideEffects []
47
48 SeeAlso []
49
50 ***********************************************************************/
Mio_LibraryDelete(Mio_Library_t * pLib)51 void Mio_LibraryDelete( Mio_Library_t * pLib )
52 {
53 Mio_Gate_t * pGate, * pGate2;
54 if ( pLib == NULL )
55 return;
56 Mio_LibraryMatchesStop( pLib );
57 Mio_LibraryMatches2Stop( pLib );
58 // free the bindings of nodes to gates from this library for all networks
59 Abc_FrameUnmapAllNetworks( Abc_FrameGetGlobalFrame() );
60 // free the library
61 ABC_FREE( pLib->pName );
62 Mio_LibraryForEachGateSafe( pLib, pGate, pGate2 )
63 Mio_GateDelete( pGate );
64 Mem_FlexStop( pLib->pMmFlex, 0 );
65 Vec_StrFree( pLib->vCube );
66 if ( pLib->tName2Gate )
67 st__free_table( pLib->tName2Gate );
68 // if ( pLib->dd )
69 // Cudd_Quit( pLib->dd );
70 ABC_FREE( pLib->ppGates0 );
71 ABC_FREE( pLib->ppGatesName );
72 ABC_FREE( pLib );
73 }
74
75 /**Function*************************************************************
76
77 Synopsis []
78
79 Description []
80
81 SideEffects []
82
83 SeeAlso []
84
85 ***********************************************************************/
Mio_GateDelete(Mio_Gate_t * pGate)86 void Mio_GateDelete( Mio_Gate_t * pGate )
87 {
88 Mio_Pin_t * pPin, * pPin2;
89 if ( pGate->nInputs > 6 )
90 ABC_FREE( pGate->pTruth );
91 Vec_IntFreeP( &pGate->vExpr );
92 ABC_FREE( pGate->pOutName );
93 ABC_FREE( pGate->pName );
94 ABC_FREE( pGate->pForm );
95 // if ( pGate->bFunc )
96 // Cudd_RecursiveDeref( pGate->pLib->dd, pGate->bFunc );
97 Mio_GateForEachPinSafe( pGate, pPin, pPin2 )
98 Mio_PinDelete( pPin );
99 ABC_FREE( pGate );
100 }
101
102 /**Function*************************************************************
103
104 Synopsis []
105
106 Description []
107
108 SideEffects []
109
110 SeeAlso []
111
112 ***********************************************************************/
Mio_PinDelete(Mio_Pin_t * pPin)113 void Mio_PinDelete( Mio_Pin_t * pPin )
114 {
115 ABC_FREE( pPin->pName );
116 ABC_FREE( pPin );
117 }
118
119 /**Function*************************************************************
120
121 Synopsis []
122
123 Description []
124
125 SideEffects []
126
127 SeeAlso []
128
129 ***********************************************************************/
Mio_PinDup(Mio_Pin_t * pPin)130 Mio_Pin_t * Mio_PinDup( Mio_Pin_t * pPin )
131 {
132 Mio_Pin_t * pPinNew;
133
134 pPinNew = ABC_ALLOC( Mio_Pin_t, 1 );
135 *pPinNew = *pPin;
136 pPinNew->pName = (pPinNew->pName ? Abc_UtilStrsav(pPinNew->pName) : NULL);
137 pPinNew->pNext = NULL;
138
139 return pPinNew;
140 }
141
142
143
144
145 /**Function*************************************************************
146
147 Synopsis [Check if pin characteristics are the same.]
148
149 Description []
150
151 SideEffects []
152
153 SeeAlso []
154
155 ***********************************************************************/
Mio_CheckPins(Mio_Pin_t * pPin1,Mio_Pin_t * pPin2)156 int Mio_CheckPins( Mio_Pin_t * pPin1, Mio_Pin_t * pPin2 )
157 {
158 if ( pPin1 == NULL || pPin2 == NULL )
159 return 1;
160 if ( pPin1->dLoadInput != pPin2->dLoadInput )
161 return 0;
162 if ( pPin1->dLoadMax != pPin2->dLoadMax )
163 return 0;
164 if ( pPin1->dDelayBlockRise != pPin2->dDelayBlockRise )
165 return 0;
166 if ( pPin1->dDelayFanoutRise != pPin2->dDelayFanoutRise )
167 return 0;
168 if ( pPin1->dDelayBlockFall != pPin2->dDelayBlockFall )
169 return 0;
170 if ( pPin1->dDelayFanoutFall != pPin2->dDelayFanoutFall )
171 return 0;
172 return 1;
173 }
Mio_CheckGates(Mio_Library_t * pLib)174 int Mio_CheckGates( Mio_Library_t * pLib )
175 {
176 Mio_Gate_t * pGate;
177 Mio_Pin_t * pPin0 = NULL, * pPin = NULL;
178 Mio_LibraryForEachGate( pLib, pGate )
179 Mio_GateForEachPin( pGate, pPin )
180 if ( Mio_CheckPins( pPin0, pPin ) )
181 pPin0 = pPin;
182 else
183 return 0;
184 return 1;
185 }
186
187 /**Function*************************************************************
188
189 Synopsis []
190
191 Description []
192
193 SideEffects []
194
195 SeeAlso []
196
197 ***********************************************************************/
Mio_WritePin(FILE * pFile,Mio_Pin_t * pPin,int NameLen,int fAllPins)198 void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin, int NameLen, int fAllPins )
199 {
200 char * pPhaseNames[10] = { "UNKNOWN", "INV", "NONINV" };
201 if ( fAllPins )
202 fprintf( pFile, "PIN * " );
203 else
204 fprintf( pFile, "\n PIN %*s ", NameLen, pPin->pName );
205 fprintf( pFile, "%7s ", pPhaseNames[pPin->Phase] );
206 fprintf( pFile, "%3d ", (int)pPin->dLoadInput );
207 fprintf( pFile, "%3d ", (int)pPin->dLoadMax );
208 fprintf( pFile, "%8.2f ", pPin->dDelayBlockRise );
209 fprintf( pFile, "%8.2f ", pPin->dDelayFanoutRise );
210 fprintf( pFile, "%8.2f ", pPin->dDelayBlockFall );
211 fprintf( pFile, "%8.2f", pPin->dDelayFanoutFall );
212 }
213
214 /**Function*************************************************************
215
216 Synopsis []
217
218 Description []
219
220 SideEffects []
221
222 SeeAlso []
223
224 ***********************************************************************/
Mio_WriteGate(FILE * pFile,Mio_Gate_t * pGate,int GateLen,int NameLen,int FormLen,int fPrintSops,int fAllPins)225 void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen, int FormLen, int fPrintSops, int fAllPins )
226 {
227 char Buffer[5000];
228 Mio_Pin_t * pPin;
229 assert( NameLen+FormLen+2 < 5000 );
230 sprintf( Buffer, "%s=%s;", pGate->pOutName, pGate->pForm );
231 fprintf( pFile, "GATE %-*s ", GateLen, pGate->pName );
232 fprintf( pFile, "%8.2f ", pGate->dArea );
233 fprintf( pFile, "%-*s ", Abc_MinInt(NameLen+FormLen+2, 60), Buffer );
234 // print the pins
235 if ( fPrintSops )
236 fprintf( pFile, "%s", pGate->pSop? pGate->pSop : "unspecified\n" );
237 if ( fAllPins && pGate->pPins ) // equal pins
238 Mio_WritePin( pFile, pGate->pPins, NameLen, 1 );
239 else // different pins
240 Mio_GateForEachPin( pGate, pPin )
241 Mio_WritePin( pFile, pPin, NameLen, 0 );
242 fprintf( pFile, "\n" );
243 }
244
245 /**Function*************************************************************
246
247 Synopsis []
248
249 Description []
250
251 SideEffects []
252
253 SeeAlso []
254
255 ***********************************************************************/
Mio_WriteLibrary(FILE * pFile,Mio_Library_t * pLib,int fPrintSops,int fShort,int fSelected)256 void Mio_WriteLibrary( FILE * pFile, Mio_Library_t * pLib, int fPrintSops, int fShort, int fSelected )
257 {
258 Mio_Gate_t * pGate;
259 Mio_Pin_t * pPin;
260 Vec_Ptr_t * vGates = Vec_PtrAlloc( 1000 );
261 int i, nCells, GateLen = 0, NameLen = 0, FormLen = 0;
262 int fAllPins = fShort || Mio_CheckGates( pLib );
263 if ( fSelected )
264 {
265 Mio_Cell2_t * pCells = Mio_CollectRootsNewDefault2( 6, &nCells, 0 );
266 for ( i = 0; i < nCells; i++ )
267 Vec_PtrPush( vGates, pCells[i].pMioGate );
268 ABC_FREE( pCells );
269 }
270 else
271 {
272 for ( i = 0; i < pLib->nGates; i++ )
273 Vec_PtrPush( vGates, pLib->ppGates0[i] );
274 }
275 Vec_PtrForEachEntry( Mio_Gate_t *, vGates, pGate, i )
276 {
277 GateLen = Abc_MaxInt( GateLen, strlen(pGate->pName) );
278 NameLen = Abc_MaxInt( NameLen, strlen(pGate->pOutName) );
279 FormLen = Abc_MaxInt( FormLen, strlen(pGate->pForm) );
280 Mio_GateForEachPin( pGate, pPin )
281 NameLen = Abc_MaxInt( NameLen, strlen(pPin->pName) );
282 }
283 fprintf( pFile, "# The genlib library \"%s\" with %d gates written by ABC on %s\n", pLib->pName, Vec_PtrSize(vGates), Extra_TimeStamp() );
284 Vec_PtrForEachEntry( Mio_Gate_t *, vGates, pGate, i )
285 Mio_WriteGate( pFile, pGate, GateLen, NameLen, FormLen, fPrintSops, fAllPins );
286 Vec_PtrFree( vGates );
287 }
288
289 /**Function*************************************************************
290
291 Synopsis [Compares the max delay of two gates.]
292
293 Description []
294
295 SideEffects []
296
297 SeeAlso []
298
299 ***********************************************************************/
Mio_DelayCompare(Mio_Gate_t ** ppG1,Mio_Gate_t ** ppG2)300 int Mio_DelayCompare( Mio_Gate_t ** ppG1, Mio_Gate_t ** ppG2 )
301 {
302 int Comp;
303 float Eps = (float)0.0094636;
304 if ( (*ppG1)->dDelayMax < (*ppG2)->dDelayMax - Eps )
305 return -1;
306 if ( (*ppG1)->dDelayMax > (*ppG2)->dDelayMax + Eps )
307 return 1;
308 // compare names
309 Comp = strcmp( (*ppG1)->pName, (*ppG2)->pName );
310 if ( Comp < 0 )
311 return -1;
312 if ( Comp > 0 )
313 return 1;
314 assert( 0 );
315 return 0;
316 }
Mio_AreaCompare(Mio_Cell_t * pG1,Mio_Cell_t * pG2)317 int Mio_AreaCompare( Mio_Cell_t * pG1, Mio_Cell_t * pG2 )
318 {
319 int Comp;
320 float Eps = (float)0.0094636;
321 if ( pG1->nFanins < pG2->nFanins )
322 return -1;
323 if ( pG1->nFanins > pG2->nFanins )
324 return 1;
325 if ( pG1->Area < pG2->Area - Eps )
326 return -1;
327 if ( pG1->Area > pG2->Area + Eps )
328 return 1;
329 // compare names
330 Comp = strcmp( pG1->pName, pG2->pName );
331 if ( Comp < 0 )
332 return -1;
333 if ( Comp > 0 )
334 return 1;
335 assert( 0 );
336 return 0;
337 }
Mio_AreaCompare2(Mio_Cell2_t * pG1,Mio_Cell2_t * pG2)338 int Mio_AreaCompare2( Mio_Cell2_t * pG1, Mio_Cell2_t * pG2 )
339 {
340 int Comp;
341 if ( pG1->nFanins < pG2->nFanins )
342 return -1;
343 if ( pG1->nFanins > pG2->nFanins )
344 return 1;
345 if ( pG1->AreaW < pG2->AreaW )
346 return -1;
347 if ( pG1->AreaW > pG2->AreaW )
348 return 1;
349 // compare names
350 Comp = strcmp( pG1->pName, pG2->pName );
351 if ( Comp < 0 )
352 return -1;
353 if ( Comp > 0 )
354 return 1;
355 assert( 0 );
356 return 0;
357 }
358
359 /**Function*************************************************************
360
361 Synopsis [Collects the set of root gates.]
362
363 Description [Only collects the gates with unique functionality,
364 which have fewer inputs and shorter delay than the given limits.]
365
366 SideEffects []
367
368 SeeAlso []
369
370 ***********************************************************************/
Mio_CellDelayAve(Mio_Cell_t * pCell)371 static inline float Mio_CellDelayAve( Mio_Cell_t * pCell )
372 {
373 float CellDelay = 0; int k;
374 for ( k = 0; k < (int)pCell->nFanins; k++ )
375 CellDelay += pCell->Delays[k];
376 if ( pCell->nFanins )
377 CellDelay /= pCell->nFanins;
378 return CellDelay;
379 }
Mio_GateDelayAve(Mio_Gate_t * pGate)380 static inline float Mio_GateDelayAve( Mio_Gate_t * pGate )
381 {
382 float GateDelay = 0;
383 Mio_Pin_t * pPin;
384 Mio_GateForEachPin( pGate, pPin )
385 GateDelay += (float)(0.5 * pPin->dDelayBlockRise + 0.5 * pPin->dDelayBlockFall);
386 if ( pGate->nInputs )
387 GateDelay /= pGate->nInputs;
388 return GateDelay;
389 }
Mio_CompareTwoGates(Mio_Gate_t * pCell,Mio_Gate_t * pGate)390 static inline int Mio_CompareTwoGates( Mio_Gate_t * pCell, Mio_Gate_t * pGate )
391 {
392 int Comp;
393 float Eps = (float)0.0094636;
394 float CellDelay, GateDelay;
395 // compare areas
396 if ( pCell->dArea > (float)pGate->dArea + Eps )
397 return 1;
398 if ( pCell->dArea < (float)pGate->dArea - Eps )
399 return 0;
400 // compare delays
401 CellDelay = Mio_GateDelayAve( pCell );
402 GateDelay = Mio_GateDelayAve( pGate );
403 if ( CellDelay > GateDelay + Eps )
404 return 1;
405 if ( CellDelay < GateDelay - Eps )
406 return 0;
407 // compare names
408 Comp = strcmp( pCell->pName, pGate->pName );
409 if ( Comp > 0 )
410 return 1;
411 if ( Comp < 0 )
412 return 0;
413 assert( 0 );
414 return 0;
415 }
Mio_CollectRoots(Mio_Library_t * pLib,int nInputs,float tDelay,int fSkipInv,int * pnGates,int fVerbose)416 Mio_Gate_t ** Mio_CollectRoots( Mio_Library_t * pLib, int nInputs, float tDelay, int fSkipInv, int * pnGates, int fVerbose )
417 {
418 Mio_Gate_t * pGate;
419 Mio_Gate_t ** ppGates;
420 int i, nGates, iGate, fProfile;
421 nGates = Mio_LibraryReadGateNum( pLib );
422 ppGates = ABC_ALLOC( Mio_Gate_t *, nGates );
423 iGate = 0;
424 // check if profile is entered
425 fProfile = Mio_LibraryHasProfile( pLib );
426 if ( fProfile )
427 printf( "Mio_CollectRoots(): Using gate profile to select gates for mapping.\n" );
428 // for each functionality, select gate with the smallest area
429 // if equal areas, select gate with lexicographically smaller name
430 Mio_LibraryForEachGate( pLib, pGate )
431 {
432 if ( pGate->nInputs > nInputs )
433 continue;
434 if ( fProfile && Mio_GateReadProfile(pGate) == 0 && pGate->nInputs > 1 )
435 continue;
436 if ( tDelay > 0.0 && pGate->dDelayMax > (double)tDelay )
437 continue;
438 if ( pGate->uTruth == 0 || pGate->uTruth == ~(word)0 )
439 continue;
440 if ( pGate->uTruth == ABC_CONST(0xAAAAAAAAAAAAAAAA) )
441 continue;
442 if ( pGate->uTruth == ~ABC_CONST(0xAAAAAAAAAAAAAAAA) && fSkipInv )
443 continue;
444 if ( pGate->pTwin ) // skip multi-output gates for now
445 continue;
446 // check if the gate with this functionality already exists
447 for ( i = 0; i < iGate; i++ )
448 if ( ppGates[i]->uTruth == pGate->uTruth )
449 {
450 if ( Mio_CompareTwoGates(ppGates[i], pGate) )
451 ppGates[i] = pGate;
452 break;
453 }
454 if ( i < iGate )
455 continue;
456 assert( iGate < nGates );
457 ppGates[ iGate++ ] = pGate;
458 if ( fVerbose )
459 printf( "Selected gate %3d: %-20s A = %7.2f D = %7.2f %3s = %-s\n",
460 iGate+1, pGate->pName, pGate->dArea, pGate->dDelayMax, pGate->pOutName, pGate->pForm );
461 }
462 // sort by delay
463 if ( iGate > 0 )
464 {
465 qsort( (void *)ppGates, (size_t)iGate, sizeof(Mio_Gate_t *),
466 (int (*)(const void *, const void *)) Mio_DelayCompare );
467 assert( Mio_DelayCompare( ppGates, ppGates + iGate - 1 ) <= 0 );
468 }
469 if ( pnGates )
470 *pnGates = iGate;
471 return ppGates;
472 }
473
474
475 /**Function*************************************************************
476
477 Synopsis [Collects the set of root gates.]
478
479 Description [Only collects the gates with unique functionality,
480 which have fewer inputs and shorter delay than the given limits.]
481
482 SideEffects []
483
484 SeeAlso []
485
486 ***********************************************************************/
Mio_CompareTwo(Mio_Cell_t * pCell,Mio_Gate_t * pGate)487 static inline int Mio_CompareTwo( Mio_Cell_t * pCell, Mio_Gate_t * pGate )
488 {
489 int Comp;
490 float Eps = (float)0.0094636;
491 float CellDelay, GateDelay;
492 // compare areas
493 if ( pCell->Area > (float)pGate->dArea + Eps )
494 return 1;
495 if ( pCell->Area < (float)pGate->dArea - Eps )
496 return 0;
497 // compare delays
498 CellDelay = Mio_CellDelayAve( pCell );
499 GateDelay = Mio_GateDelayAve( pGate );
500 if ( CellDelay > GateDelay + Eps )
501 return 1;
502 if ( CellDelay < GateDelay - Eps )
503 return 0;
504 // compare names
505 Comp = strcmp( pCell->pName, pGate->pName );
506 if ( Comp > 0 )
507 return 1;
508 if ( Comp < 0 )
509 return 0;
510 assert( 0 );
511 return 0;
512 }
Mio_CollectCopy(Mio_Cell_t * pCell,Mio_Gate_t * pGate)513 static inline void Mio_CollectCopy( Mio_Cell_t * pCell, Mio_Gate_t * pGate )
514 {
515 Mio_Pin_t * pPin; int k;
516 pCell->pName = pGate->pName;
517 pCell->uTruth = pGate->uTruth;
518 pCell->Area = (float)pGate->dArea;
519 pCell->nFanins = pGate->nInputs;
520 for ( k = 0, pPin = pGate->pPins; pPin; pPin = pPin->pNext, k++ )
521 pCell->Delays[k] = (float)(0.5 * pPin->dDelayBlockRise + 0.5 * pPin->dDelayBlockFall);
522 }
523
Mio_CollectRootsNew(Mio_Library_t * pLib,int nInputs,int * pnGates,int fVerbose)524 Mio_Cell_t * Mio_CollectRootsNew( Mio_Library_t * pLib, int nInputs, int * pnGates, int fVerbose )
525 {
526 Mio_Gate_t * pGate;
527 Mio_Cell_t * ppCells;
528 int i, nGates, iCell = 4;
529 nGates = Mio_LibraryReadGateNum( pLib );
530 ppCells = ABC_CALLOC( Mio_Cell_t, nGates + 4 );
531 // for each functionality, select gate with the smallest area
532 // if equal areas, select gate with smaller average pin delay
533 // if these are also equal, select lexicographically smaller name
534 Mio_LibraryForEachGate( pLib, pGate )
535 {
536 if ( pGate->nInputs > nInputs || pGate->pTwin ) // skip large and multi-output
537 continue;
538 // check if the gate with this functionality already exists
539 for ( i = 0; i < iCell; i++ )
540 if ( ppCells[i].pName && ppCells[i].uTruth == pGate->uTruth )
541 {
542 if ( Mio_CompareTwo( ppCells + i, pGate ) )
543 Mio_CollectCopy( ppCells + i, pGate );
544 break;
545 }
546 if ( i < iCell )
547 continue;
548 if ( pGate->uTruth == 0 || pGate->uTruth == ~(word)0 )
549 {
550 int Idx = (int)(pGate->uTruth == ~(word)0);
551 assert( pGate->nInputs == 0 );
552 Mio_CollectCopy( ppCells + Idx, pGate );
553 continue;
554 }
555 if ( pGate->uTruth == ABC_CONST(0xAAAAAAAAAAAAAAAA) || pGate->uTruth == ~ABC_CONST(0xAAAAAAAAAAAAAAAA) )
556 {
557 int Idx = 2 + (int)(pGate->uTruth == ~ABC_CONST(0xAAAAAAAAAAAAAAAA));
558 assert( pGate->nInputs == 1 );
559 Mio_CollectCopy( ppCells + Idx, pGate );
560 continue;
561 }
562 Mio_CollectCopy( ppCells + iCell++, pGate );
563 }
564 if ( ppCells[0].pName == NULL )
565 { printf( "Error: Cannot find constant 0 gate in the library.\n" ); return NULL; }
566 if ( ppCells[1].pName == NULL )
567 { printf( "Error: Cannot find constant 1 gate in the library.\n" ); return NULL; }
568 if ( ppCells[2].pName == NULL )
569 { printf( "Error: Cannot find buffer gate in the library.\n" ); return NULL; }
570 if ( ppCells[3].pName == NULL )
571 { printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; }
572 // sort by delay
573 if ( iCell > 5 )
574 {
575 qsort( (void *)(ppCells + 4), (size_t)(iCell - 4), sizeof(Mio_Cell_t),
576 (int (*)(const void *, const void *)) Mio_AreaCompare );
577 assert( Mio_AreaCompare( ppCells + 4, ppCells + iCell - 1 ) <= 0 );
578 }
579 // assign IDs
580 for ( i = 0; i < iCell; i++ )
581 ppCells[i].Id = ppCells[i].pName ? i : -1;
582
583 // report
584 if ( fVerbose )
585 {
586 // count gates
587 int * pCounts = ABC_CALLOC( int, nGates + 4 );
588 Mio_LibraryForEachGate( pLib, pGate )
589 {
590 if ( pGate->nInputs > nInputs || pGate->pTwin ) // skip large and multi-output
591 continue;
592 for ( i = 0; i < iCell; i++ )
593 if ( ppCells[i].pName && ppCells[i].uTruth == pGate->uTruth )
594 {
595 pCounts[i]++;
596 break;
597 }
598 assert( i < iCell );
599 }
600 for ( i = 0; i < iCell; i++ )
601 {
602 Mio_Cell_t * pCell = ppCells + i;
603 printf( "%4d : ", i );
604 if ( pCell->pName == NULL )
605 printf( "None\n" );
606 else
607 printf( "%-20s In = %d N = %3d A = %12.6f D = %12.6f\n",
608 pCell->pName, pCell->nFanins, pCounts[i], pCell->Area, Mio_CellDelayAve(pCell) );
609 }
610 ABC_FREE( pCounts );
611 }
612 if ( pnGates )
613 *pnGates = iCell;
614 return ppCells;
615 }
Mio_CollectRootsNewDefault(int nInputs,int * pnGates,int fVerbose)616 Mio_Cell_t * Mio_CollectRootsNewDefault( int nInputs, int * pnGates, int fVerbose )
617 {
618 return Mio_CollectRootsNew( (Mio_Library_t *)Abc_FrameReadLibGen(), nInputs, pnGates, fVerbose );
619 }
620
621 /**Function*************************************************************
622
623 Synopsis [Collects the set of root gates.]
624
625 Description [Only collects the gates with unique functionality,
626 which have fewer inputs and shorter delay than the given limits.]
627
628 SideEffects []
629
630 SeeAlso []
631
632 ***********************************************************************/
Mio_CompareTwo2(Mio_Cell2_t * pCell1,Mio_Cell2_t * pCell2)633 static inline int Mio_CompareTwo2( Mio_Cell2_t * pCell1, Mio_Cell2_t * pCell2 )
634 {
635 int Comp;
636 // compare areas
637 if ( pCell1->AreaW > pCell2->AreaW )
638 return 1;
639 if ( pCell1->AreaW < pCell2->AreaW )
640 return 0;
641 // compare delays
642 if ( pCell1->iDelayAve > pCell2->iDelayAve )
643 return 1;
644 if ( pCell1->iDelayAve < pCell2->iDelayAve )
645 return 0;
646 // compare names
647 Comp = strcmp( pCell1->pName, pCell2->pName );
648 if ( Comp > 0 )
649 return 1;
650 if ( Comp < 0 )
651 return 0;
652 assert( 0 );
653 return 0;
654 }
Mio_CollectCopy2(Mio_Cell2_t * pCell,Mio_Gate_t * pGate)655 static inline void Mio_CollectCopy2( Mio_Cell2_t * pCell, Mio_Gate_t * pGate )
656 {
657 Mio_Pin_t * pPin; int k;
658 pCell->pName = pGate->pName;
659 pCell->vExpr = pGate->vExpr;
660 pCell->uTruth = pGate->uTruth;
661 pCell->AreaF = pGate->dArea;
662 pCell->AreaW = (word)(SCL_NUM * pGate->dArea);
663 pCell->nFanins = pGate->nInputs;
664 pCell->pMioGate = pGate;
665 pCell->iDelayAve = 0;
666 for ( k = 0, pPin = pGate->pPins; pPin; pPin = pPin->pNext, k++ )
667 {
668 pCell->iDelays[k] = (int)(SCL_NUM/2 * pPin->dDelayBlockRise + SCL_NUM/2 * pPin->dDelayBlockFall);
669 pCell->iDelayAve += pCell->iDelays[k];
670 }
671 if ( pCell->nFanins )
672 pCell->iDelayAve /= pCell->nFanins;
673 }
674
Mio_CollectRootsNew2(Mio_Library_t * pLib,int nInputs,int * pnGates,int fVerbose)675 Mio_Cell2_t * Mio_CollectRootsNew2( Mio_Library_t * pLib, int nInputs, int * pnGates, int fVerbose )
676 {
677 Mio_Gate_t * pGate0;
678 Mio_Cell2_t * ppCells0, * ppCells, * pCell;
679 int i, nGates, iCell0 = 0, iCell = 4;
680 // create space for new cells
681 nGates = Mio_LibraryReadGateNum( pLib );
682 ppCells = ABC_CALLOC( Mio_Cell2_t, nGates + 4 );
683 // copy all gates first
684 ppCells0 = ABC_CALLOC( Mio_Cell2_t, nGates );
685 Mio_LibraryForEachGate( pLib, pGate0 )
686 if ( !(pGate0->nInputs > nInputs || pGate0->pTwin) ) // skip large and multi-output
687 Mio_CollectCopy2( ppCells0 + iCell0++, pGate0 );
688 assert( iCell0 <= nGates );
689 // for each functionality, select gate with the smallest area
690 // if equal areas, select gate with smaller average pin delay
691 // if these are also equal, select lexicographically smaller name
692 for ( pCell = ppCells0; pCell < ppCells0 + iCell0; pCell++ )
693 {
694 // check if the gate with this functionality already exists
695 for ( i = 0; i < iCell; i++ )
696 if ( ppCells[i].pName && ppCells[i].uTruth == pCell->uTruth )
697 {
698 if ( Mio_CompareTwo2( ppCells + i, pCell ) )
699 ppCells[i] = *pCell;
700 break;
701 }
702 if ( i < iCell )
703 continue;
704 if ( pCell->uTruth == 0 || pCell->uTruth == ~(word)0 )
705 {
706 int Idx = (int)(pCell->uTruth == ~(word)0);
707 assert( pCell->nFanins == 0 );
708 ppCells[Idx] = *pCell;
709 continue;
710 }
711 if ( pCell->uTruth == ABC_CONST(0xAAAAAAAAAAAAAAAA) || pCell->uTruth == ~ABC_CONST(0xAAAAAAAAAAAAAAAA) )
712 {
713 int Idx = 2 + (int)(pCell->uTruth == ~ABC_CONST(0xAAAAAAAAAAAAAAAA));
714 assert( pCell->nFanins == 1 );
715 ppCells[Idx] = *pCell;
716 continue;
717 }
718 ppCells[iCell++] = *pCell;
719 }
720 ABC_FREE( ppCells0 );
721 if ( ppCells[0].pName == NULL )
722 { printf( "Error: Cannot find constant 0 gate in the library.\n" ); return NULL; }
723 if ( ppCells[1].pName == NULL )
724 { printf( "Error: Cannot find constant 1 gate in the library.\n" ); return NULL; }
725 if ( ppCells[2].pName == NULL )
726 { printf( "Error: Cannot find buffer gate in the library.\n" ); return NULL; }
727 if ( ppCells[3].pName == NULL )
728 { printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; }
729 // sort by delay
730 if ( iCell > 5 )
731 {
732 qsort( (void *)(ppCells + 4), (size_t)(iCell - 4), sizeof(Mio_Cell2_t),
733 (int (*)(const void *, const void *)) Mio_AreaCompare2 );
734 assert( Mio_AreaCompare2( ppCells + 4, ppCells + iCell - 1 ) <= 0 );
735 }
736 // assign IDs
737 Mio_LibraryForEachGate( pLib, pGate0 )
738 Mio_GateSetCell( pGate0, -1 );
739 for ( i = 0; i < iCell; i++ )
740 {
741 ppCells[i].Id = ppCells[i].pName ? i : -1;
742 Mio_GateSetCell( (Mio_Gate_t *)ppCells[i].pMioGate, i );
743 }
744
745 // report
746 if ( fVerbose )
747 {
748 // count gates
749 int * pCounts = ABC_CALLOC( int, nGates + 4 );
750 Mio_LibraryForEachGate( pLib, pGate0 )
751 {
752 if ( pGate0->nInputs > nInputs || pGate0->pTwin ) // skip large and multi-output
753 continue;
754 for ( i = 0; i < iCell; i++ )
755 if ( ppCells[i].pName && ppCells[i].uTruth == pGate0->uTruth )
756 {
757 pCounts[i]++;
758 break;
759 }
760 assert( i < iCell );
761 }
762 for ( i = 0; i < iCell; i++ )
763 {
764 Mio_Cell2_t * pCell = ppCells + i;
765 printf( "%4d : ", i );
766 if ( pCell->pName == NULL )
767 printf( "None\n" );
768 else
769 printf( "%-20s In = %d N = %3d A = %12.6f D = %12.6f\n",
770 pCell->pName, pCell->nFanins, pCounts[i], pCell->AreaF, Scl_Int2Flt(pCell->iDelayAve) );
771 }
772 ABC_FREE( pCounts );
773 }
774 if ( pnGates )
775 *pnGates = iCell;
776 return ppCells;
777 }
Mio_CollectRootsNewDefault2(int nInputs,int * pnGates,int fVerbose)778 Mio_Cell2_t * Mio_CollectRootsNewDefault2( int nInputs, int * pnGates, int fVerbose )
779 {
780 return Mio_CollectRootsNew2( (Mio_Library_t *)Abc_FrameReadLibGen(), nInputs, pnGates, fVerbose );
781 }
782
783 /**Function*************************************************************
784
785 Synopsis [Derives the truth table of the gate.]
786
787 Description []
788
789 SideEffects []
790
791 SeeAlso []
792
793 ***********************************************************************/
Mio_CollectRootsNewDefault3(int nInputs,Vec_Ptr_t ** pvNames,Vec_Wrd_t ** pvTruths)794 int Mio_CollectRootsNewDefault3( int nInputs, Vec_Ptr_t ** pvNames, Vec_Wrd_t ** pvTruths )
795 {
796 Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
797 int i, iGate = 0, nGates = pLib ? Mio_LibraryReadGateNum( pLib ) : 0;
798 Mio_Gate_t * pGate0, ** ppGates; word * pTruth;
799 if ( pLib == NULL )
800 return 0;
801 ppGates = ABC_CALLOC( Mio_Gate_t *, nGates );
802 Mio_LibraryForEachGate( pLib, pGate0 )
803 ppGates[pGate0->Cell] = pGate0;
804 *pvNames = Vec_PtrAlloc( nGates );
805 *pvTruths = Vec_WrdStart( nGates * 4 );
806 for ( i = 0; i < nGates; i++ )
807 {
808 pGate0 = ppGates[i];
809 if ( pGate0->nInputs > nInputs || pGate0->pTwin ) // skip large and multi-output
810 continue;
811 Vec_PtrPush( *pvNames, pGate0->pName );
812 pTruth = Vec_WrdEntryP( *pvTruths, iGate++*4 );
813 if ( pGate0->nInputs <= 6 )
814 pTruth[0] = pTruth[1] = pTruth[2] = pTruth[3] = pGate0->uTruth;
815 else if ( pGate0->nInputs == 7 )
816 {
817 pTruth[0] = pTruth[2] = pGate0->pTruth[0];
818 pTruth[1] = pTruth[3] = pGate0->pTruth[1];
819 }
820 else if ( pGate0->nInputs == 8 )
821 memcpy( pTruth, pGate0->pTruth, (size_t)(4*sizeof(word)) );
822 }
823 assert( iGate == nGates );
824 assert( Vec_WrdEntry(*pvTruths, 0) == 0 );
825 assert( Vec_WrdEntry(*pvTruths, 4) == ~(word)0 );
826 assert( Vec_WrdEntry(*pvTruths, 8) == s_Truths6[0] );
827 assert( Vec_WrdEntry(*pvTruths, 12) == ~s_Truths6[0] );
828 ABC_FREE( ppGates );
829 return nGates;
830 }
831
832 /**Function*************************************************************
833
834 Synopsis [Derives the truth table of the gate.]
835
836 Description []
837
838 SideEffects []
839
840 SeeAlso []
841
842 ***********************************************************************/
Mio_DeriveTruthTable6(Mio_Gate_t * pGate)843 word Mio_DeriveTruthTable6( Mio_Gate_t * pGate )
844 {
845 static unsigned uTruths6[6][2] = {
846 { 0xAAAAAAAA, 0xAAAAAAAA },
847 { 0xCCCCCCCC, 0xCCCCCCCC },
848 { 0xF0F0F0F0, 0xF0F0F0F0 },
849 { 0xFF00FF00, 0xFF00FF00 },
850 { 0xFFFF0000, 0xFFFF0000 },
851 { 0x00000000, 0xFFFFFFFF }
852 };
853 union {
854 unsigned u[2];
855 word w;
856 } uTruthRes;
857 assert( pGate->nInputs <= 6 );
858 Mio_DeriveTruthTable( pGate, uTruths6, pGate->nInputs, 6, uTruthRes.u );
859 return uTruthRes.w;
860 }
861
862 #if 0
863
864 /**Function*************************************************************
865
866 Synopsis [Recursively derives the truth table of the gate.]
867
868 Description []
869
870 SideEffects []
871
872 SeeAlso []
873
874 ***********************************************************************/
875 void Mio_DeriveTruthTable_rec( DdNode * bFunc, unsigned uTruthsIn[][2], unsigned uTruthRes[] )
876 {
877 unsigned uTruthsCof0[2];
878 unsigned uTruthsCof1[2];
879
880 // complement the resulting truth table, if the function is complemented
881 if ( Cudd_IsComplement(bFunc) )
882 {
883 Mio_DeriveTruthTable_rec( Cudd_Not(bFunc), uTruthsIn, uTruthRes );
884 uTruthRes[0] = ~uTruthRes[0];
885 uTruthRes[1] = ~uTruthRes[1];
886 return;
887 }
888
889 // if the function is constant 1, return the constant 1 truth table
890 if ( bFunc->index == CUDD_CONST_INDEX )
891 {
892 uTruthRes[0] = MIO_FULL;
893 uTruthRes[1] = MIO_FULL;
894 return;
895 }
896
897 // solve the problem for both cofactors
898 Mio_DeriveTruthTable_rec( cuddE(bFunc), uTruthsIn, uTruthsCof0 );
899 Mio_DeriveTruthTable_rec( cuddT(bFunc), uTruthsIn, uTruthsCof1 );
900
901 // derive the resulting truth table using the input truth tables
902 uTruthRes[0] = (uTruthsCof0[0] & ~uTruthsIn[bFunc->index][0]) |
903 (uTruthsCof1[0] & uTruthsIn[bFunc->index][0]);
904 uTruthRes[1] = (uTruthsCof0[1] & ~uTruthsIn[bFunc->index][1]) |
905 (uTruthsCof1[1] & uTruthsIn[bFunc->index][1]);
906 }
907
908 /**Function*************************************************************
909
910 Synopsis [Derives the truth table of the gate.]
911
912 Description []
913
914 SideEffects []
915
916 SeeAlso []
917
918 ***********************************************************************/
919 void Mio_DeriveTruthTable( Mio_Gate_t * pGate, unsigned uTruthsIn[][2], int nSigns, int nInputs, unsigned uTruthRes[] )
920 {
921 Mio_DeriveTruthTable_rec( pGate->bFunc, uTruthsIn, uTruthRes );
922 }
923
924 #endif
925
926 /**Function*************************************************************
927
928 Synopsis [Derives the truth table of the gate.]
929
930 Description []
931
932 SideEffects []
933
934 SeeAlso []
935
936 ***********************************************************************/
Mio_DeriveTruthTable(Mio_Gate_t * pGate,unsigned uTruthsIn[][2],int nSigns,int nInputs,unsigned uTruthRes[])937 void Mio_DeriveTruthTable( Mio_Gate_t * pGate, unsigned uTruthsIn[][2], int nSigns, int nInputs, unsigned uTruthRes[] )
938 {
939 word uRes, uFanins[6];
940 int i;
941 assert( pGate->nInputs == nSigns );
942 for ( i = 0; i < nSigns; i++ )
943 uFanins[i] = (((word)uTruthsIn[i][1]) << 32) | (word)uTruthsIn[i][0];
944 uRes = Exp_Truth6( nSigns, pGate->vExpr, (word *)uFanins );
945 uTruthRes[0] = uRes & 0xFFFFFFFF;
946 uTruthRes[1] = uRes >> 32;
947 }
948
949 /**Function*************************************************************
950
951 Synopsis [Reads the number of variables in the cover.]
952
953 Description []
954
955 SideEffects []
956
957 SeeAlso []
958
959 ***********************************************************************/
Mio_SopGetVarNum(char * pSop)960 int Mio_SopGetVarNum( char * pSop )
961 {
962 char * pCur;
963 for ( pCur = pSop; *pCur != '\n'; pCur++ )
964 if ( *pCur == 0 )
965 return -1;
966 return pCur - pSop - 2;
967 }
968
969 /**Function*************************************************************
970
971 Synopsis [Derives the truth table of the root of the gate.]
972
973 Description [Given the truth tables of the leaves of the gate,
974 this procedure derives the truth table of the root.]
975
976 SideEffects []
977
978 SeeAlso []
979
980 ***********************************************************************/
Mio_DeriveTruthTable2(Mio_Gate_t * pGate,unsigned uTruthsIn[][2],int nTruths,int nInputs,unsigned uTruthRes[])981 void Mio_DeriveTruthTable2( Mio_Gate_t * pGate, unsigned uTruthsIn[][2], int nTruths, int nInputs, unsigned uTruthRes[] )
982 {
983 unsigned uSignCube[2];
984 int i, nFanins;
985 char * pCube;
986
987 // make sure that the number of input truth tables in equal to the number of gate inputs
988 assert( pGate->nInputs == nTruths );
989 assert( nInputs < 7 );
990
991 nFanins = Mio_SopGetVarNum( pGate->pSop );
992 assert( nFanins == nInputs );
993
994 // clean the resulting truth table
995 uTruthRes[0] = 0;
996 uTruthRes[1] = 0;
997 if ( nInputs < 6 )
998 {
999 // Abc_SopForEachCube( pGate->pSop, nFanins, pCube )
1000 for ( pCube = pGate->pSop; *pCube; pCube += (nFanins) + 3 )
1001 {
1002 // add the clause
1003 uSignCube[0] = MIO_FULL;
1004 for ( i = 0; i < nFanins; i++ )
1005 {
1006 if ( pCube[i] == '0' )
1007 uSignCube[0] &= ~uTruthsIn[i][0];
1008 else if ( pCube[i] == '1' )
1009 uSignCube[0] &= uTruthsIn[i][0];
1010 }
1011 }
1012 if ( nInputs < 5 )
1013 uTruthRes[0] &= MIO_MASK(1<<nInputs);
1014 }
1015 else
1016 {
1017 // consider the case when two unsigneds should be used
1018 // Abc_SopForEachCube( pGate->pSop, nFanins, pCube )
1019 for ( pCube = pGate->pSop; *pCube; pCube += (nFanins) + 3 )
1020 {
1021 uSignCube[0] = MIO_FULL;
1022 uSignCube[1] = MIO_FULL;
1023 for ( i = 0; i < nFanins; i++ )
1024 {
1025 if ( pCube[i] == '0' )
1026 {
1027 uSignCube[0] &= ~uTruthsIn[i][0];
1028 uSignCube[1] &= ~uTruthsIn[i][1];
1029 }
1030 else if ( pCube[i] == '1' )
1031 {
1032 uSignCube[0] &= uTruthsIn[i][0];
1033 uSignCube[1] &= uTruthsIn[i][1];
1034 }
1035 }
1036 uTruthRes[0] |= uSignCube[0];
1037 uTruthRes[1] |= uSignCube[1];
1038 }
1039 }
1040 }
1041
1042 /**Function*************************************************************
1043
1044 Synopsis [Derives the area and delay of the root of the gate.]
1045
1046 Description [Array of the resulting delays should be initialized
1047 to the (negative) SUPER_NO_VAR value.]
1048
1049 SideEffects []
1050
1051 SeeAlso []
1052
1053 ***********************************************************************/
Mio_DeriveGateDelays(Mio_Gate_t * pGate,float ** ptPinDelays,int nPins,int nInputs,float tDelayZero,float * ptDelaysRes,float * ptPinDelayMax)1054 void Mio_DeriveGateDelays( Mio_Gate_t * pGate,
1055 float ** ptPinDelays, int nPins, int nInputs, float tDelayZero,
1056 float * ptDelaysRes, float * ptPinDelayMax )
1057 {
1058 Mio_Pin_t * pPin;
1059 float Delay, DelayMax;
1060 int i, k;
1061 assert( pGate->nInputs == nPins );
1062 // set all the delays to the unused delay
1063 for ( i = 0; i < nInputs; i++ )
1064 ptDelaysRes[i] = tDelayZero;
1065 // compute the delays for each input and the max delay at the same time
1066 DelayMax = 0;
1067 for ( i = 0; i < nInputs; i++ )
1068 {
1069 for ( k = 0, pPin = pGate->pPins; pPin; pPin = pPin->pNext, k++ )
1070 {
1071 if ( ptPinDelays[k][i] < 0 )
1072 continue;
1073 Delay = ptPinDelays[k][i] + (float)pPin->dDelayBlockMax;
1074 if ( ptDelaysRes[i] < Delay )
1075 ptDelaysRes[i] = Delay;
1076 }
1077 if ( k != nPins )
1078 {
1079 printf ("DEBUG: problem gate is %s\n", Mio_GateReadName( pGate ));
1080 }
1081 assert( k == nPins );
1082 if ( DelayMax < ptDelaysRes[i] )
1083 DelayMax = ptDelaysRes[i];
1084 }
1085 *ptPinDelayMax = DelayMax;
1086 }
1087
1088
1089 /**Function*************************************************************
1090
1091 Synopsis [Creates a pseudo-gate.]
1092
1093 Description [The pseudo-gate is a N-input gate with all info set to 0.]
1094
1095 SideEffects []
1096
1097 SeeAlso []
1098
1099 ***********************************************************************/
Mio_GateCreatePseudo(int nInputs)1100 Mio_Gate_t * Mio_GateCreatePseudo( int nInputs )
1101 {
1102 Mio_Gate_t * pGate;
1103 Mio_Pin_t * pPin;
1104 int i;
1105 // allocate the gate structure
1106 pGate = ABC_ALLOC( Mio_Gate_t, 1 );
1107 memset( pGate, 0, sizeof(Mio_Gate_t) );
1108 pGate->nInputs = nInputs;
1109 // create pins
1110 for ( i = 0; i < nInputs; i++ )
1111 {
1112 pPin = ABC_ALLOC( Mio_Pin_t, 1 );
1113 memset( pPin, 0, sizeof(Mio_Pin_t) );
1114 pPin->pNext = pGate->pPins;
1115 pGate->pPins = pPin;
1116 }
1117 return pGate;
1118 }
1119
1120 /**Function*************************************************************
1121
1122 Synopsis [Adds constant value to all delay values.]
1123
1124 Description [The pseudo-gate is a N-input gate with all info set to 0.]
1125
1126 SideEffects []
1127
1128 SeeAlso []
1129
1130 ***********************************************************************/
Mio_LibraryShiftDelay(Mio_Library_t * pLib,double Shift)1131 void Mio_LibraryShiftDelay( Mio_Library_t * pLib, double Shift )
1132 {
1133 Mio_Gate_t * pGate;
1134 Mio_Pin_t * pPin;
1135 Mio_LibraryForEachGate( pLib, pGate )
1136 {
1137 pGate->dDelayMax += Shift;
1138 Mio_GateForEachPin( pGate, pPin )
1139 {
1140 pPin->dDelayBlockRise += Shift;
1141 pPin->dDelayBlockFall += Shift;
1142 pPin->dDelayBlockMax += Shift;
1143 }
1144 }
1145 }
1146
1147 /**Function*************************************************************
1148
1149 Synopsis [Multiply areas/delays by values proportional to fanin count.]
1150
1151 Description []
1152
1153 SideEffects []
1154
1155 SeeAlso []
1156
1157 ***********************************************************************/
Mio_LibraryMultiArea(Mio_Library_t * pLib,double Multi)1158 void Mio_LibraryMultiArea( Mio_Library_t * pLib, double Multi )
1159 {
1160 Mio_Gate_t * pGate;
1161 Mio_LibraryForEachGate( pLib, pGate )
1162 {
1163 if ( pGate->nInputs < 2 )
1164 continue;
1165 // printf( "Before %8.3f ", pGate->dArea );
1166 pGate->dArea *= pow( pGate->nInputs, Multi );
1167 // printf( "After %8.3f Inputs = %d. Factor = %8.3f\n", pGate->dArea, pGate->nInputs, pow( pGate->nInputs, Multi ) );
1168 }
1169 }
Mio_LibraryMultiDelay(Mio_Library_t * pLib,double Multi)1170 void Mio_LibraryMultiDelay( Mio_Library_t * pLib, double Multi )
1171 {
1172 Mio_Gate_t * pGate;
1173 Mio_Pin_t * pPin;
1174 Mio_LibraryForEachGate( pLib, pGate )
1175 {
1176 if ( pGate->nInputs < 2 )
1177 continue;
1178 // printf( "Before %8.3f ", pGate->dDelayMax );
1179 pGate->dDelayMax *= pow( pGate->nInputs, Multi );
1180 // printf( "After %8.3f Inputs = %d. Factor = %8.3f\n", pGate->dDelayMax, pGate->nInputs, pow( pGate->nInputs, Multi ) );
1181 Mio_GateForEachPin( pGate, pPin )
1182 {
1183 pPin->dDelayBlockRise *= pow( pGate->nInputs, Multi );
1184 pPin->dDelayBlockFall *= pow( pGate->nInputs, Multi );
1185 pPin->dDelayBlockMax *= pow( pGate->nInputs, Multi );
1186 }
1187 }
1188 }
1189
1190 /**Function*************************************************************
1191
1192 Synopsis [Transfers delays from the second to the first.]
1193
1194 Description []
1195
1196 SideEffects []
1197
1198 SeeAlso []
1199
1200 ***********************************************************************/
Mio_LibraryTransferDelays(Mio_Library_t * pLibD,Mio_Library_t * pLibS)1201 void Mio_LibraryTransferDelays( Mio_Library_t * pLibD, Mio_Library_t * pLibS )
1202 {
1203 Mio_Gate_t * pGateD, * pGateS;
1204 Mio_Pin_t * pPinD, * pPinS;
1205 Mio_LibraryForEachGate( pLibS, pGateS )
1206 {
1207 Mio_LibraryForEachGate( pLibD, pGateD )
1208 {
1209 if ( pGateD->uTruth != pGateS->uTruth )
1210 continue;
1211 pPinS = Mio_GateReadPins( pGateS );
1212 Mio_GateForEachPin( pGateD, pPinD )
1213 {
1214 if (pPinS)
1215 {
1216 pPinD->dDelayBlockRise = pPinS->dDelayBlockRise;
1217 pPinD->dDelayBlockFall = pPinS->dDelayBlockFall;
1218 pPinD->dDelayBlockMax = pPinS->dDelayBlockMax;
1219 pPinS = Mio_PinReadNext(pPinS);
1220 }
1221 else
1222 {
1223 pPinD->dDelayBlockRise = 0;
1224 pPinD->dDelayBlockFall = 0;
1225 pPinD->dDelayBlockMax = 0;
1226 }
1227 }
1228 }
1229 }
1230 }
1231
1232 /**Function*************************************************************
1233
1234 Synopsis []
1235
1236 Description []
1237
1238 SideEffects []
1239
1240 SeeAlso []
1241
1242 ***********************************************************************/
Nf_ManPrepareGate(int nVars,word uTruth,int * pComp,int * pPerm,Vec_Wrd_t * vResult)1243 void Nf_ManPrepareGate( int nVars, word uTruth, int * pComp, int * pPerm, Vec_Wrd_t * vResult )
1244 {
1245 int nPerms = Extra_Factorial( nVars );
1246 int nMints = (1 << nVars);
1247 word tCur, tTemp1, tTemp2;
1248 int i, p, c;
1249 Vec_WrdClear( vResult );
1250 for ( i = 0; i < 2; i++ )
1251 {
1252 tCur = i ? ~uTruth : uTruth;
1253 tTemp1 = tCur;
1254 for ( p = 0; p < nPerms; p++ )
1255 {
1256 tTemp2 = tCur;
1257 for ( c = 0; c < nMints; c++ )
1258 {
1259 Vec_WrdPush( vResult, tCur );
1260 tCur = Abc_Tt6Flip( tCur, pComp[c] );
1261 }
1262 assert( tTemp2 == tCur );
1263 tCur = Abc_Tt6SwapAdjacent( tCur, pPerm[p] );
1264 }
1265 assert( tTemp1 == tCur );
1266 }
1267 }
Nf_ManPreparePrint(int nVars,int * pComp,int * pPerm,char Line[2* 720* 64][8])1268 void Nf_ManPreparePrint( int nVars, int * pComp, int * pPerm, char Line[2*720*64][8] )
1269 {
1270 int nPerms = Extra_Factorial( nVars );
1271 int nMints = (1 << nVars);
1272 char * pChar, * pChar2;
1273 int i, p, c, n = 0;
1274 for ( i = 0; i < nVars; i++ )
1275 Line[0][i] = 'A' + nVars - 1 - i;
1276 Line[0][nVars] = '+';
1277 Line[0][nVars+1] = 0;
1278 for ( i = 0; i < 2; i++ )
1279 {
1280 Line[n][nVars] = i ? '-' : '+';
1281 for ( p = 0; p < nPerms; p++ )
1282 {
1283 for ( c = 0; c < nMints; c++ )
1284 {
1285 strcpy( Line[n+1], Line[n] ); n++;
1286 pChar = &Line[n][pComp[c]];
1287 if ( *pChar >= 'A' && *pChar <= 'Z' )
1288 *pChar += 'a' - 'A';
1289 else if ( *pChar >= 'a' && *pChar <= 'z' )
1290 *pChar -= 'a' - 'A';
1291 }
1292 pChar = &Line[n][pPerm[p]];
1293 pChar2 = pChar + 1;
1294 ABC_SWAP( char, *pChar, *pChar2 );
1295 }
1296 }
1297 assert( n == 2*nPerms*nMints );
1298 n = 0;
1299 for ( i = 0; i < 2; i++ )
1300 for ( p = 0; p < nPerms; p++ )
1301 for ( c = 0; c < nMints; c++ )
1302 printf("%8d : %d %3d %2d : %s\n", n, i, p, c, Line[n]), n++;
1303 }
1304
Nf_ManPrepareLibrary(Mio_Library_t * pLib)1305 void Nf_ManPrepareLibrary( Mio_Library_t * pLib )
1306 {
1307 // char Lines[2*720*64][8];
1308 // Nf_ManPreparePrint( 6, pComp, pPerm, Lines );
1309 int * pComp[7];
1310 int * pPerm[7];
1311 Mio_Gate_t ** ppGates;
1312 Vec_Wrd_t * vResult;
1313 word * pTruths;
1314 int * pSizes;
1315 int nGates, i, nClasses = 0, nTotal;
1316 abctime clk = Abc_Clock();
1317
1318 for ( i = 2; i <= 6; i++ )
1319 pComp[i] = Extra_GreyCodeSchedule( i );
1320 for ( i = 2; i <= 6; i++ )
1321 pPerm[i] = Extra_PermSchedule( i );
1322
1323 // collect truth tables
1324 ppGates = Mio_CollectRoots( pLib, 6, (float)1.0e+20, 1, &nGates, 0 );
1325 pSizes = ABC_CALLOC( int, nGates );
1326 pTruths = ABC_CALLOC( word, nGates );
1327 vResult = Vec_WrdAlloc( 2 * 720 * 64 );
1328 for ( i = 0; i < nGates; i++ )
1329 {
1330 pSizes[i] = Mio_GateReadPinNum( ppGates[i] );
1331 assert( pSizes[i] > 1 && pSizes[i] <= 6 );
1332 pTruths[i] = Mio_GateReadTruth( ppGates[i] );
1333
1334 Nf_ManPrepareGate( pSizes[i], pTruths[i], pComp[pSizes[i]], pPerm[pSizes[i]], vResult );
1335 Vec_WrdUniqify(vResult);
1336 nClasses += Vec_WrdSize(vResult);
1337 nTotal = (1 << (pSizes[i]+1)) * Extra_Factorial(pSizes[i]);
1338
1339 printf( "%6d : ", i );
1340 printf( "%16s : ", Mio_GateReadName( ppGates[i] ) );
1341 printf( "%48s : ", Mio_GateReadForm( ppGates[i] ) );
1342 printf( "Inputs = %2d ", pSizes[i] );
1343 printf( "Total = %6d ", nTotal );
1344 printf( "Classes = %6d ", Vec_WrdSize(vResult) );
1345 printf( "Configs = %8.2f ", 1.0*nTotal/Vec_WrdSize(vResult) );
1346 printf( "%6.2f %% ", 100.0*Vec_WrdSize(vResult)/nTotal );
1347 Dau_DsdPrintFromTruth( &pTruths[i], pSizes[i] );
1348 // printf( "\n" );
1349 }
1350 Vec_WrdFree( vResult );
1351 ABC_FREE( ppGates );
1352 ABC_FREE( pSizes );
1353 ABC_FREE( pTruths );
1354
1355 for ( i = 2; i <= 6; i++ )
1356 ABC_FREE( pComp[i] );
1357 for ( i = 2; i <= 6; i++ )
1358 ABC_FREE( pPerm[i] );
1359
1360 printf( "Classes = %d. ", nClasses );
1361 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
1362 }
1363
Nf_ManPrepareLibraryTest2()1364 void Nf_ManPrepareLibraryTest2()
1365 {
1366 Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
1367 if ( pLib != NULL )
1368 Nf_ManPrepareLibrary( pLib );
1369 else
1370 printf( "Standard cell library is not available.\n" );
1371
1372 }
1373
1374 /**Function*************************************************************
1375
1376 Synopsis [Install library.]
1377
1378 Description []
1379
1380 SideEffects []
1381
1382 SeeAlso []
1383
1384 ***********************************************************************/
Mio_LibraryTransferCellIds()1385 void Mio_LibraryTransferCellIds()
1386 {
1387 Mio_Gate_t * pGate;
1388 Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
1389 SC_Lib * pScl = (SC_Lib *)Abc_FrameReadLibScl();
1390 int CellId;
1391 if ( pScl == NULL )
1392 {
1393 printf( "SC library cannot be found.\n" );
1394 return;
1395 }
1396 if ( pLib == NULL )
1397 {
1398 printf( "Genlib library cannot be found.\n" );
1399 return;
1400 }
1401 Mio_LibraryForEachGate( pLib, pGate )
1402 {
1403 if ( Mio_GateReadPinNum(pGate) == 0 )
1404 continue;
1405 CellId = Abc_SclCellFind( pScl, Mio_GateReadName(pGate) );
1406 if ( CellId < 0 )
1407 printf( "Cannot find cell ID of gate %s.\n", Mio_GateReadName(pGate) );
1408 else
1409 Mio_GateSetCell( pGate, CellId );
1410 }
1411 }
1412
1413 /**Function*************************************************************
1414
1415 Synopsis []
1416
1417 Description []
1418
1419 SideEffects []
1420
1421 SeeAlso []
1422
1423 ***********************************************************************/
Mio_LibraryReadProfile(FILE * pFile,Mio_Library_t * pLib)1424 void Mio_LibraryReadProfile( FILE * pFile, Mio_Library_t * pLib )
1425 {
1426 Mio_Gate_t * pGate;
1427 char pBuffer[1000];
1428 while ( fgets( pBuffer, 1000, pFile ) != NULL )
1429 {
1430 char * pToken = strtok( pBuffer, " \t\n" );
1431 if ( pToken == NULL )
1432 continue;
1433 if ( pToken[0] == '#' )
1434 continue;
1435 // read gate
1436 pGate = Mio_LibraryReadGateByName( pLib, pToken, NULL );
1437 if ( pGate == NULL )
1438 {
1439 printf( "Cannot find gate \"%s\" in library \"%s\".\n", pToken, Mio_LibraryReadName(pLib) );
1440 continue;
1441 }
1442 // read profile
1443 pToken = strtok( NULL, " \t\n" );
1444 Mio_GateSetProfile( pGate, atoi(pToken) );
1445 }
1446 }
1447
Mio_LibraryWriteProfile(FILE * pFile,Mio_Library_t * pLib)1448 void Mio_LibraryWriteProfile( FILE * pFile, Mio_Library_t * pLib )
1449 {
1450 Mio_Gate_t * pGate;
1451 Mio_LibraryForEachGate( pLib, pGate )
1452 if ( Mio_GateReadProfile(pGate) > 0 )
1453 fprintf( pFile, "%-24s %6d\n", Mio_GateReadName(pGate), Mio_GateReadProfile(pGate) );
1454 }
1455
Mio_LibraryHasProfile(Mio_Library_t * pLib)1456 int Mio_LibraryHasProfile( Mio_Library_t * pLib )
1457 {
1458 Mio_Gate_t * pGate;
1459 Mio_LibraryForEachGate( pLib, pGate )
1460 if ( Mio_GateReadProfile(pGate) > 0 )
1461 return 1;
1462 return 0;
1463 }
1464
1465
Mio_LibraryTransferProfile(Mio_Library_t * pLibDst,Mio_Library_t * pLibSrc)1466 void Mio_LibraryTransferProfile( Mio_Library_t * pLibDst, Mio_Library_t * pLibSrc )
1467 {
1468 Mio_Gate_t * pGateSrc, * pGateDst;
1469 Mio_LibraryForEachGate( pLibDst, pGateDst )
1470 Mio_GateSetProfile( pGateDst, 0 );
1471 Mio_LibraryForEachGate( pLibSrc, pGateSrc )
1472 if ( Mio_GateReadProfile(pGateSrc) > 0 )
1473 {
1474 // find gate by name
1475 pGateDst = Mio_LibraryReadGateByName( pLibDst, Mio_GateReadName(pGateSrc), NULL );
1476 if ( pGateDst == NULL )
1477 {
1478 // find gate by function
1479 Mio_LibraryForEachGate( pLibDst, pGateDst )
1480 if ( pGateDst->uTruth == pGateSrc->uTruth )
1481 break;
1482 if ( pGateDst == NULL )
1483 {
1484 printf( "Cannot find gate \"%s\" in library \"%s\".\n", Mio_GateReadName(pGateSrc), Mio_LibraryReadName(pLibDst) );
1485 continue;
1486 }
1487 }
1488 Mio_GateAddToProfile( pGateDst, Mio_GateReadProfile(pGateSrc) );
1489 }
1490 }
Mio_LibraryTransferProfile2(Mio_Library_t * pLibDst,Mio_Library_t * pLibSrc)1491 void Mio_LibraryTransferProfile2( Mio_Library_t * pLibDst, Mio_Library_t * pLibSrc )
1492 {
1493 Mio_Gate_t * pGateSrc, * pGateDst;
1494 Mio_LibraryForEachGate( pLibDst, pGateDst )
1495 Mio_GateSetProfile2( pGateDst, 0 );
1496 Mio_LibraryForEachGate( pLibSrc, pGateSrc )
1497 if ( Mio_GateReadProfile2(pGateSrc) > 0 )
1498 {
1499 // find gate by name
1500 pGateDst = Mio_LibraryReadGateByName( pLibDst, Mio_GateReadName(pGateSrc), NULL );
1501 if ( pGateDst == NULL )
1502 {
1503 // find gate by function
1504 Mio_LibraryForEachGate( pLibDst, pGateDst )
1505 if ( pGateDst->uTruth == pGateSrc->uTruth )
1506 break;
1507 if ( pGateDst == NULL )
1508 {
1509 printf( "Cannot find gate \"%s\" in library \"%s\".\n", Mio_GateReadName(pGateSrc), Mio_LibraryReadName(pLibDst) );
1510 continue;
1511 }
1512 }
1513 Mio_GateAddToProfile2( pGateDst, Mio_GateReadProfile2(pGateSrc) );
1514 }
1515 }
1516
Mio_LibraryCleanProfile2(Mio_Library_t * pLib)1517 void Mio_LibraryCleanProfile2( Mio_Library_t * pLib )
1518 {
1519 Mio_Gate_t * pGate;
1520 Mio_LibraryForEachGate( pLib, pGate )
1521 Mio_GateSetProfile2( pGate, 0 );
1522 }
1523
1524 /**Function*************************************************************
1525
1526 Synopsis []
1527
1528 Description []
1529
1530 SideEffects []
1531
1532 SeeAlso []
1533
1534 ***********************************************************************/
Mio_LibraryHashGates(Mio_Library_t * pLib)1535 void Mio_LibraryHashGates( Mio_Library_t * pLib )
1536 {
1537 Mio_Gate_t * pGate;
1538 Mio_LibraryForEachGate( pLib, pGate )
1539 if ( pGate->pTwin )
1540 {
1541 printf( "Gates with multiple outputs are not supported.\n" );
1542 return;
1543 }
1544 if ( pLib->tName2Gate )
1545 st__free_table( pLib->tName2Gate );
1546 pLib->tName2Gate = st__init_table(strcmp, st__strhash);
1547 Mio_LibraryForEachGate( pLib, pGate )
1548 st__insert( pLib->tName2Gate, pGate->pName, (char *)pGate );
1549 }
1550
1551 /**Function*************************************************************
1552
1553 Synopsis []
1554
1555 Description []
1556
1557 SideEffects []
1558
1559 SeeAlso []
1560
1561 ***********************************************************************/
Abc_SclIsChar(char c)1562 static inline int Abc_SclIsChar( char c )
1563 {
1564 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
1565 }
Abc_SclIsName(char c)1566 static inline int Abc_SclIsName( char c )
1567 {
1568 return Abc_SclIsChar(c) || (c >= '0' && c <= '9');
1569 }
Abc_SclFindLimit(char * pName)1570 static inline char * Abc_SclFindLimit( char * pName )
1571 {
1572 assert( Abc_SclIsChar(*pName) );
1573 while ( Abc_SclIsName(*pName) )
1574 pName++;
1575 return pName;
1576 }
Abc_SclAreEqual(char * pBase,char * pName,char * pLimit)1577 static inline int Abc_SclAreEqual( char * pBase, char * pName, char * pLimit )
1578 {
1579 return !strncmp( pBase, pName, pLimit - pName );
1580 }
Mio_LibraryShortFormula(Mio_Gate_t * pCell,char * pForm,char * pBuffer)1581 void Mio_LibraryShortFormula( Mio_Gate_t * pCell, char * pForm, char * pBuffer )
1582 {
1583 Mio_Pin_t * pPin;
1584 char * pTemp, * pLimit; int i;
1585 if ( !strncmp(pForm, "CONST", 5) )
1586 {
1587 sprintf( pBuffer, "%s", pForm );
1588 return;
1589 }
1590 for ( pTemp = pForm; *pTemp; )
1591 {
1592 if ( !Abc_SclIsChar(*pTemp) )
1593 {
1594 *pBuffer++ = *pTemp++;
1595 continue;
1596 }
1597 pLimit = Abc_SclFindLimit( pTemp );
1598 i = 0;
1599 Mio_GateForEachPin( pCell, pPin )
1600 {
1601 if ( Abc_SclAreEqual( pPin->pName, pTemp, pLimit ) )
1602 {
1603 *pBuffer++ = 'a' + i;
1604 break;
1605 }
1606 i++;
1607 }
1608 pTemp = pLimit;
1609 }
1610 *pBuffer++ = 0;
1611 }
Mio_LibraryShortNames(Mio_Library_t * pLib)1612 void Mio_LibraryShortNames( Mio_Library_t * pLib )
1613 {
1614 char Buffer[10000];
1615 Mio_Gate_t * pGate; Mio_Pin_t * pPin;
1616 int c = 0, i, nDigits = Abc_Base10Log( Mio_LibraryReadGateNum(pLib) );
1617 // itereate through classes
1618 Mio_LibraryForEachGate( pLib, pGate )
1619 {
1620 ABC_FREE( pGate->pName );
1621 sprintf( Buffer, "g%0*d", nDigits, ++c );
1622 pGate->pName = Abc_UtilStrsav( Buffer );
1623 // update formula
1624 Mio_LibraryShortFormula( pGate, pGate->pForm, Buffer );
1625 ABC_FREE( pGate->pForm );
1626 pGate->pForm = Abc_UtilStrsav( Buffer );
1627 // pin names
1628 i = 0;
1629 Mio_GateForEachPin( pGate, pPin )
1630 {
1631 ABC_FREE( pPin->pName );
1632 sprintf( Buffer, "%c", 'a'+i );
1633 pPin->pName = Abc_UtilStrsav( Buffer );
1634 i++;
1635 }
1636 // output pin
1637 ABC_FREE( pGate->pOutName );
1638 sprintf( Buffer, "z" );
1639 pGate->pOutName = Abc_UtilStrsav( Buffer );
1640 }
1641 Mio_LibraryHashGates( pLib );
1642 // update library name
1643 printf( "Renaming library \"%s\" into \"%s%d\".\n", pLib->pName, "lib", Mio_LibraryReadGateNum(pLib) );
1644 ABC_FREE( pLib->pName );
1645 sprintf( Buffer, "lib%d", Mio_LibraryReadGateNum(pLib) );
1646 pLib->pName = Abc_UtilStrsav( Buffer );
1647 }
1648
1649 /**Function*************************************************************
1650
1651 Synopsis []
1652
1653 Description []
1654
1655 SideEffects []
1656
1657 SeeAlso []
1658
1659 ***********************************************************************/
Mio_LibraryMatchesStop(Mio_Library_t * pLib)1660 void Mio_LibraryMatchesStop( Mio_Library_t * pLib )
1661 {
1662 if ( !pLib->vTtMem )
1663 return;
1664 Vec_WecFree( pLib->vTt2Match );
1665 Vec_MemHashFree( pLib->vTtMem );
1666 Vec_MemFree( pLib->vTtMem );
1667 ABC_FREE( pLib->pCells );
1668 }
Mio_LibraryMatchesStart(Mio_Library_t * pLib,int fPinFilter,int fPinPerm,int fPinQuick)1669 void Mio_LibraryMatchesStart( Mio_Library_t * pLib, int fPinFilter, int fPinPerm, int fPinQuick )
1670 {
1671 extern Mio_Cell2_t * Nf_StoDeriveMatches( Vec_Mem_t * vTtMem, Vec_Wec_t * vTt2Match, int * pnCells, int fPinFilter, int fPinPerm, int fPinQuick );
1672 if ( pLib->vTtMem && pLib->fPinFilter == fPinFilter && pLib->fPinPerm == fPinPerm && pLib->fPinQuick == fPinQuick )
1673 return;
1674 if ( pLib->vTtMem )
1675 Mio_LibraryMatchesStop( pLib );
1676 pLib->fPinFilter = fPinFilter; // pin filtering
1677 pLib->fPinPerm = fPinPerm; // pin permutation
1678 pLib->fPinQuick = fPinQuick; // pin permutation
1679 pLib->vTtMem = Vec_MemAllocForTT( 6, 0 );
1680 pLib->vTt2Match = Vec_WecAlloc( 1000 );
1681 Vec_WecPushLevel( pLib->vTt2Match );
1682 Vec_WecPushLevel( pLib->vTt2Match );
1683 assert( Vec_WecSize(pLib->vTt2Match) == Vec_MemEntryNum(pLib->vTtMem) );
1684 pLib->pCells = Nf_StoDeriveMatches( pLib->vTtMem, pLib->vTt2Match, &pLib->nCells, fPinFilter, fPinPerm, fPinQuick );
1685 }
Mio_LibraryMatchesFetch(Mio_Library_t * pLib,Vec_Mem_t ** pvTtMem,Vec_Wec_t ** pvTt2Match,Mio_Cell2_t ** ppCells,int * pnCells,int fPinFilter,int fPinPerm,int fPinQuick)1686 void Mio_LibraryMatchesFetch( Mio_Library_t * pLib, Vec_Mem_t ** pvTtMem, Vec_Wec_t ** pvTt2Match, Mio_Cell2_t ** ppCells, int * pnCells, int fPinFilter, int fPinPerm, int fPinQuick )
1687 {
1688 Mio_LibraryMatchesStart( pLib, fPinFilter, fPinPerm, fPinQuick );
1689 *pvTtMem = pLib->vTtMem; // truth tables
1690 *pvTt2Match = pLib->vTt2Match; // matches for truth tables
1691 *ppCells = pLib->pCells; // library gates
1692 *pnCells = pLib->nCells; // library gate count
1693 }
1694
1695 /**Function*************************************************************
1696
1697 Synopsis []
1698
1699 Description []
1700
1701 SideEffects []
1702
1703 SeeAlso []
1704
1705 ***********************************************************************/
Mio_LibraryMatches2Stop(Mio_Library_t * pLib)1706 void Mio_LibraryMatches2Stop( Mio_Library_t * pLib )
1707 {
1708 int i;
1709 if ( !pLib->vNames )
1710 return;
1711 Vec_PtrFree( pLib->vNames );
1712 Vec_WrdFree( pLib->vTruths );
1713 Vec_IntFree( pLib->vTt2Match4 );
1714 Vec_IntFree( pLib->vConfigs );
1715 for ( i = 0; i < 3; i++ )
1716 {
1717 Vec_MemHashFree( pLib->vTtMem2[i] );
1718 Vec_MemFree( pLib->vTtMem2[i] );
1719 Vec_IntFree( pLib->vTt2Match2[i] );
1720 }
1721 }
Mio_LibraryMatches2Start(Mio_Library_t * pLib)1722 void Mio_LibraryMatches2Start( Mio_Library_t * pLib )
1723 {
1724 extern int Gia_ManDeriveMatches( Vec_Ptr_t ** pvNames, Vec_Wrd_t ** pvTruths, Vec_Int_t ** pvTt2Match4, Vec_Int_t ** pvConfigs, Vec_Mem_t * pvTtMem2[3], Vec_Int_t * pvTt2Match2[3] );
1725 if ( pLib->vNames )
1726 return;
1727 if ( pLib->vTtMem )
1728 Mio_LibraryMatches2Stop( pLib );
1729 Gia_ManDeriveMatches( &pLib->vNames, &pLib->vTruths, &pLib->vTt2Match4, &pLib->vConfigs, pLib->vTtMem2, pLib->vTt2Match2 );
1730 }
Mio_LibraryMatches2Fetch(Mio_Library_t * pLib,Vec_Ptr_t ** pvNames,Vec_Wrd_t ** pvTruths,Vec_Int_t ** pvTt2Match4,Vec_Int_t ** pvConfigs,Vec_Mem_t * pvTtMem2[3],Vec_Int_t * pvTt2Match2[3])1731 void Mio_LibraryMatches2Fetch( Mio_Library_t * pLib, Vec_Ptr_t ** pvNames, Vec_Wrd_t ** pvTruths, Vec_Int_t ** pvTt2Match4, Vec_Int_t ** pvConfigs, Vec_Mem_t * pvTtMem2[3], Vec_Int_t * pvTt2Match2[3] )
1732 {
1733 int i;
1734 Mio_LibraryMatches2Start( pLib );
1735 *pvNames = pLib->vNames;
1736 *pvTruths = pLib->vTruths;
1737 *pvTt2Match4 = pLib->vTt2Match4;
1738 *pvConfigs = pLib->vConfigs;
1739 for ( i = 0; i < 3; i++ )
1740 {
1741 pvTtMem2[i] = pLib->vTtMem2[i];
1742 pvTt2Match2[i] = pLib->vTt2Match2[i];
1743 }
1744 }
1745
1746 ////////////////////////////////////////////////////////////////////////
1747 /// END OF FILE ///
1748 ////////////////////////////////////////////////////////////////////////
1749
1750
1751 ABC_NAMESPACE_IMPL_END
1752
1753