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