1 /**CFile****************************************************************
2
3 FileName [mapperCreate.c]
4
5 PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
6
7 Synopsis [Generic technology mapping engine.]
8
9 Author [MVSIS Group]
10
11 Affiliation [UC Berkeley]
12
13 Date [Ver. 2.0. Started - June 1, 2004.]
14
15 Revision [$Id: mapperCreate.c,v 1.15 2005/02/28 05:34:26 alanmi Exp $]
16
17 ***********************************************************************/
18
19 #include "mapperInt.h"
20
21 ABC_NAMESPACE_IMPL_START
22
23
24 ////////////////////////////////////////////////////////////////////////
25 /// DECLARATIONS ///
26 ////////////////////////////////////////////////////////////////////////
27
28 static void Map_TableCreate( Map_Man_t * p );
29 static void Map_TableResize( Map_Man_t * p );
30
31 // hash key for the structural hash table
Map_HashKey2(Map_Node_t * p0,Map_Node_t * p1,int TableSize)32 static inline unsigned Map_HashKey2( Map_Node_t * p0, Map_Node_t * p1, int TableSize ) { return (unsigned)(((ABC_PTRUINT_T)(p0) + (ABC_PTRUINT_T)(p1) * 12582917) % TableSize); }
33
34 ////////////////////////////////////////////////////////////////////////
35 /// FUNCTION DEFINITIONS ///
36 ////////////////////////////////////////////////////////////////////////
37
38 /**Function*************************************************************
39
40 Synopsis [Reads parameters from the mapping manager.]
41
42 Description []
43
44 SideEffects []
45
46 SeeAlso []
47
48 ***********************************************************************/
Map_ManReadInputNum(Map_Man_t * p)49 int Map_ManReadInputNum( Map_Man_t * p ) { return p->nInputs; }
Map_ManReadOutputNum(Map_Man_t * p)50 int Map_ManReadOutputNum( Map_Man_t * p ) { return p->nOutputs; }
Map_ManReadBufNum(Map_Man_t * p)51 int Map_ManReadBufNum( Map_Man_t * p ) { return Map_NodeVecReadSize(p->vMapBufs); }
Map_ManReadInputs(Map_Man_t * p)52 Map_Node_t ** Map_ManReadInputs ( Map_Man_t * p ) { return p->pInputs; }
Map_ManReadOutputs(Map_Man_t * p)53 Map_Node_t ** Map_ManReadOutputs( Map_Man_t * p ) { return p->pOutputs; }
Map_ManReadBufs(Map_Man_t * p)54 Map_Node_t ** Map_ManReadBufs( Map_Man_t * p ) { return Map_NodeVecReadArray(p->vMapBufs); }
Map_ManReadBufDriver(Map_Man_t * p,int i)55 Map_Node_t * Map_ManReadBufDriver( Map_Man_t * p, int i ) { return Map_ManReadBufs(p)[i]->p1; }
Map_ManReadConst1(Map_Man_t * p)56 Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p ) { return p->pConst1; }
Map_ManReadInputArrivals(Map_Man_t * p)57 Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p ) { return p->pInputArrivals; }
Map_ManReadOutputRequireds(Map_Man_t * p)58 Map_Time_t * Map_ManReadOutputRequireds( Map_Man_t * p ) { return p->pOutputRequireds; }
Map_ManReadGenLib(Map_Man_t * p)59 Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p ) { return p->pSuperLib->pGenlib; }
Map_ManReadVerbose(Map_Man_t * p)60 int Map_ManReadVerbose( Map_Man_t * p ) { return p->fVerbose; }
Map_ManReadAreaFinal(Map_Man_t * p)61 float Map_ManReadAreaFinal( Map_Man_t * p ) { return p->AreaFinal; }
Map_ManReadRequiredGlo(Map_Man_t * p)62 float Map_ManReadRequiredGlo( Map_Man_t * p ) { return p->fRequiredGlo; }
Map_ManSetOutputNames(Map_Man_t * p,char ** ppNames)63 void Map_ManSetOutputNames( Map_Man_t * p, char ** ppNames ) { p->ppOutputNames = ppNames;}
Map_ManSetAreaRecovery(Map_Man_t * p,int fAreaRecovery)64 void Map_ManSetAreaRecovery( Map_Man_t * p, int fAreaRecovery ) { p->fAreaRecovery = fAreaRecovery;}
Map_ManSetDelayTarget(Map_Man_t * p,float DelayTarget)65 void Map_ManSetDelayTarget( Map_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget;}
Map_ManSetInputArrivals(Map_Man_t * p,Map_Time_t * pArrivals)66 void Map_ManSetInputArrivals( Map_Man_t * p, Map_Time_t * pArrivals ) { p->pInputArrivals = pArrivals; }
Map_ManSetOutputRequireds(Map_Man_t * p,Map_Time_t * pRequireds)67 void Map_ManSetOutputRequireds( Map_Man_t * p, Map_Time_t * pRequireds ) { p->pOutputRequireds = pRequireds; }
Map_ManSetObeyFanoutLimits(Map_Man_t * p,int fObeyFanoutLimits)68 void Map_ManSetObeyFanoutLimits( Map_Man_t * p, int fObeyFanoutLimits ) { p->fObeyFanoutLimits = fObeyFanoutLimits; }
Map_ManSetNumIterations(Map_Man_t * p,int nIterations)69 void Map_ManSetNumIterations( Map_Man_t * p, int nIterations ) { p->nIterations = nIterations; }
Map_ManReadFanoutViolations(Map_Man_t * p)70 int Map_ManReadFanoutViolations( Map_Man_t * p ) { return p->nFanoutViolations; }
Map_ManSetFanoutViolations(Map_Man_t * p,int nVio)71 void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio ) { p->nFanoutViolations = nVio; }
Map_ManSetChoiceNodeNum(Map_Man_t * p,int nChoiceNodes)72 void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes ) { p->nChoiceNodes = nChoiceNodes; }
Map_ManSetChoiceNum(Map_Man_t * p,int nChoices)73 void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices ) { p->nChoices = nChoices; }
Map_ManSetVerbose(Map_Man_t * p,int fVerbose)74 void Map_ManSetVerbose( Map_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; }
Map_ManSetSwitching(Map_Man_t * p,int fSwitching)75 void Map_ManSetSwitching( Map_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; }
Map_ManSetSkipFanout(Map_Man_t * p,int fSkipFanout)76 void Map_ManSetSkipFanout( Map_Man_t * p, int fSkipFanout ) { p->fSkipFanout = fSkipFanout; }
Map_ManSetUseProfile(Map_Man_t * p)77 void Map_ManSetUseProfile( Map_Man_t * p ) { p->fUseProfile = 1; }
78
79 /**Function*************************************************************
80
81 Synopsis [Reads parameters from the mapping node.]
82
83 Description []
84
85 SideEffects []
86
87 SeeAlso []
88
89 ***********************************************************************/
Map_NodeReadMan(Map_Node_t * p)90 Map_Man_t * Map_NodeReadMan( Map_Node_t * p ) { return p->p; }
Map_NodeReadData(Map_Node_t * p,int fPhase)91 char * Map_NodeReadData( Map_Node_t * p, int fPhase ) { return fPhase? p->pData1 : p->pData0; }
Map_NodeReadNum(Map_Node_t * p)92 int Map_NodeReadNum( Map_Node_t * p ) { return p->Num; }
Map_NodeReadLevel(Map_Node_t * p)93 int Map_NodeReadLevel( Map_Node_t * p ) { return Map_Regular(p)->Level; }
Map_NodeReadCuts(Map_Node_t * p)94 Map_Cut_t * Map_NodeReadCuts( Map_Node_t * p ) { return p->pCuts; }
Map_NodeReadCutBest(Map_Node_t * p,int fPhase)95 Map_Cut_t * Map_NodeReadCutBest( Map_Node_t * p, int fPhase ) { return p->pCutBest[fPhase]; }
Map_NodeReadOne(Map_Node_t * p)96 Map_Node_t * Map_NodeReadOne( Map_Node_t * p ) { return p->p1; }
Map_NodeReadTwo(Map_Node_t * p)97 Map_Node_t * Map_NodeReadTwo( Map_Node_t * p ) { return p->p2; }
Map_NodeSetData(Map_Node_t * p,int fPhase,char * pData)98 void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData ) { if (fPhase) p->pData1 = pData; else p->pData0 = pData; }
Map_NodeSetNextE(Map_Node_t * p,Map_Node_t * pNextE)99 void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ) { p->pNextE = pNextE; }
Map_NodeSetRepr(Map_Node_t * p,Map_Node_t * pRepr)100 void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ) { p->pRepr = pRepr; }
Map_NodeSetSwitching(Map_Node_t * p,float Switching)101 void Map_NodeSetSwitching( Map_Node_t * p, float Switching ) { p->Switching = Switching; }
102
103 /**Function*************************************************************
104
105 Synopsis [Checks the type of the node.]
106
107 Description []
108
109 SideEffects []
110
111 SeeAlso []
112
113 ***********************************************************************/
Map_NodeIsConst(Map_Node_t * p)114 int Map_NodeIsConst( Map_Node_t * p ) { return (Map_Regular(p))->Num == -1; }
Map_NodeIsVar(Map_Node_t * p)115 int Map_NodeIsVar( Map_Node_t * p ) { return (Map_Regular(p))->p1 == NULL && (Map_Regular(p))->Num >= 0; }
Map_NodeIsBuf(Map_Node_t * p)116 int Map_NodeIsBuf( Map_Node_t * p ) { return (Map_Regular(p))->p1 != NULL && (Map_Regular(p))->p2 == NULL; }
Map_NodeIsAnd(Map_Node_t * p)117 int Map_NodeIsAnd( Map_Node_t * p ) { return (Map_Regular(p))->p1 != NULL && (Map_Regular(p))->p2 != NULL; }
Map_NodeComparePhase(Map_Node_t * p1,Map_Node_t * p2)118 int Map_NodeComparePhase( Map_Node_t * p1, Map_Node_t * p2 ) { assert( !Map_IsComplement(p1) ); assert( !Map_IsComplement(p2) ); return p1->fInv ^ p2->fInv; }
119
120 /**Function*************************************************************
121
122 Synopsis [Reads parameters from the cut.]
123
124 Description []
125
126 SideEffects []
127
128 SeeAlso []
129
130 ***********************************************************************/
Map_CutReadSuperBest(Map_Cut_t * p,int fPhase)131 Map_Super_t * Map_CutReadSuperBest( Map_Cut_t * p, int fPhase ) { return p->M[fPhase].pSuperBest;}
Map_CutReadSuper0(Map_Cut_t * p)132 Map_Super_t * Map_CutReadSuper0( Map_Cut_t * p ) { return p->M[0].pSuperBest;}
Map_CutReadSuper1(Map_Cut_t * p)133 Map_Super_t * Map_CutReadSuper1( Map_Cut_t * p ) { return p->M[1].pSuperBest;}
Map_CutReadLeavesNum(Map_Cut_t * p)134 int Map_CutReadLeavesNum( Map_Cut_t * p ) { return p->nLeaves; }
Map_CutReadLeaves(Map_Cut_t * p)135 Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p ) { return p->ppLeaves; }
Map_CutReadPhaseBest(Map_Cut_t * p,int fPhase)136 unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase ) { return p->M[fPhase].uPhaseBest;}
Map_CutReadPhase0(Map_Cut_t * p)137 unsigned Map_CutReadPhase0( Map_Cut_t * p ) { return p->M[0].uPhaseBest;}
Map_CutReadPhase1(Map_Cut_t * p)138 unsigned Map_CutReadPhase1( Map_Cut_t * p ) { return p->M[1].uPhaseBest;}
Map_CutReadNext(Map_Cut_t * p)139 Map_Cut_t * Map_CutReadNext( Map_Cut_t * p ) { return p->pNext; }
140
141 /**Function*************************************************************
142
143 Synopsis [Reads parameters from the supergate.]
144
145 Description []
146
147 SideEffects []
148
149 SeeAlso []
150
151 ***********************************************************************/
Map_SuperReadFormula(Map_Super_t * p)152 char * Map_SuperReadFormula( Map_Super_t * p ) { return p->pFormula; }
Map_SuperReadRoot(Map_Super_t * p)153 Mio_Gate_t * Map_SuperReadRoot( Map_Super_t * p ) { return p->pRoot; }
Map_SuperReadNum(Map_Super_t * p)154 int Map_SuperReadNum( Map_Super_t * p ) { return p->Num; }
Map_SuperReadFanins(Map_Super_t * p)155 Map_Super_t ** Map_SuperReadFanins( Map_Super_t * p ) { return p->pFanins; }
Map_SuperReadFaninNum(Map_Super_t * p)156 int Map_SuperReadFaninNum( Map_Super_t * p ) { return p->nFanins; }
Map_SuperReadNext(Map_Super_t * p)157 Map_Super_t * Map_SuperReadNext( Map_Super_t * p ) { return p->pNext; }
Map_SuperReadNumPhases(Map_Super_t * p)158 int Map_SuperReadNumPhases( Map_Super_t * p ) { return p->nPhases; }
Map_SuperReadPhases(Map_Super_t * p)159 unsigned char * Map_SuperReadPhases( Map_Super_t * p ) { return p->uPhases; }
Map_SuperReadFanoutLimit(Map_Super_t * p)160 int Map_SuperReadFanoutLimit( Map_Super_t * p ) { return p->nFanLimit;}
161
Map_SuperLibReadGenLib(Map_SuperLib_t * p)162 Mio_Library_t * Map_SuperLibReadGenLib( Map_SuperLib_t * p ) { return p->pGenlib; }
Map_SuperLibReadAreaInv(Map_SuperLib_t * p)163 float Map_SuperLibReadAreaInv( Map_SuperLib_t * p ) { return p->AreaInv; }
Map_SuperLibReadDelayInv(Map_SuperLib_t * p)164 Map_Time_t Map_SuperLibReadDelayInv( Map_SuperLib_t * p ) { return p->tDelayInv;}
Map_SuperLibReadVarsMax(Map_SuperLib_t * p)165 int Map_SuperLibReadVarsMax( Map_SuperLib_t * p ) { return p->nVarsMax; }
166
167
168 /**Function*************************************************************
169
170 Synopsis [Create the mapping manager.]
171
172 Description [The number of inputs and outputs is assumed to be
173 known is advance. It is much simpler to have them fixed upfront.
174 When it comes to representing the object graph in the form of
175 AIG, the resulting manager is similar to the regular AIG manager,
176 except that it does not use reference counting (and therefore
177 does not have garbage collections). It does have table resizing.
178 The data structure is more flexible to represent additional
179 information needed for mapping.]
180
181 SideEffects []
182
183 SeeAlso []
184
185 ***********************************************************************/
Map_ManCreate(int nInputs,int nOutputs,int fVerbose)186 Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
187 {
188 Map_Man_t * p;
189 int i;
190
191 // derive the supergate library
192 if ( Abc_FrameReadLibSuper() == NULL )
193 {
194 printf( "The supergate library is not specified. Use \"read_super\".\n" );
195 return NULL;
196 }
197
198 // start the manager
199 p = ABC_ALLOC( Map_Man_t, 1 );
200 memset( p, 0, sizeof(Map_Man_t) );
201 p->pSuperLib = (Map_SuperLib_t *)Abc_FrameReadLibSuper();
202 p->nVarsMax = p->pSuperLib->nVarsMax;
203 p->fVerbose = fVerbose;
204 p->fEpsilon = (float)0.001;
205 assert( p->nVarsMax > 0 );
206
207 if ( p->nVarsMax == 5 )
208 Extra_Truth4VarN( &p->uCanons, &p->uPhases, &p->pCounters, 8 );
209
210 // start various data structures
211 Map_TableCreate( p );
212 Map_MappingSetupTruthTables( p->uTruths );
213 Map_MappingSetupTruthTablesLarge( p->uTruthsLarge );
214 // printf( "Node = %d bytes. Cut = %d bytes. Super = %d bytes.\n", sizeof(Map_Node_t), sizeof(Map_Cut_t), sizeof(Map_Super_t) );
215 p->mmNodes = Extra_MmFixedStart( sizeof(Map_Node_t) );
216 p->mmCuts = Extra_MmFixedStart( sizeof(Map_Cut_t) );
217
218 // make sure the constant node will get index -1
219 p->nNodes = -1;
220 // create the constant node
221 p->pConst1 = Map_NodeCreate( p, NULL, NULL );
222 p->vMapObjs = Map_NodeVecAlloc( 100 );
223 p->vMapBufs = Map_NodeVecAlloc( 100 );
224 p->vVisited = Map_NodeVecAlloc( 100 );
225
226 // create the PI nodes
227 p->nInputs = nInputs;
228 p->pInputs = ABC_ALLOC( Map_Node_t *, nInputs );
229 for ( i = 0; i < nInputs; i++ )
230 p->pInputs[i] = Map_NodeCreate( p, NULL, NULL );
231
232 // create the place for the output nodes
233 p->nOutputs = nOutputs;
234 p->pOutputs = ABC_ALLOC( Map_Node_t *, nOutputs );
235 memset( p->pOutputs, 0, sizeof(Map_Node_t *) * nOutputs );
236 return p;
237 }
238
239 /**Function*************************************************************
240
241 Synopsis [Deallocates the mapping manager.]
242
243 Description []
244
245 SideEffects []
246
247 SeeAlso []
248
249 ***********************************************************************/
Map_ManFree(Map_Man_t * p)250 void Map_ManFree( Map_Man_t * p )
251 {
252 // int i;
253 // for ( i = 0; i < p->vMapObjs->nSize; i++ )
254 // Map_NodeVecFree( p->vMapObjs->pArray[i]->vFanouts );
255 // Map_NodeVecFree( p->pConst1->vFanouts );
256 Map_NodeVecFree( p->vMapObjs );
257 Map_NodeVecFree( p->vMapBufs );
258 Map_NodeVecFree( p->vVisited );
259 if ( p->uCanons ) ABC_FREE( p->uCanons );
260 if ( p->uPhases ) ABC_FREE( p->uPhases );
261 if ( p->pCounters ) ABC_FREE( p->pCounters );
262 Extra_MmFixedStop( p->mmNodes );
263 Extra_MmFixedStop( p->mmCuts );
264 ABC_FREE( p->pNodeDelays );
265 ABC_FREE( p->pInputArrivals );
266 ABC_FREE( p->pOutputRequireds );
267 ABC_FREE( p->pInputs );
268 ABC_FREE( p->pOutputs );
269 ABC_FREE( p->pBins );
270 ABC_FREE( p->ppOutputNames );
271 ABC_FREE( p );
272 }
273
274
275 /**Function*************************************************************
276
277 Synopsis [Creates node delays.]
278
279 Description []
280
281 SideEffects []
282
283 SeeAlso []
284
285 ***********************************************************************/
Map_ManCreateNodeDelays(Map_Man_t * p,int LogFan)286 void Map_ManCreateNodeDelays( Map_Man_t * p, int LogFan )
287 {
288 Map_Node_t * pNode;
289 int k;
290 assert( p->pNodeDelays == NULL );
291 p->pNodeDelays = ABC_CALLOC( float, p->vMapObjs->nSize );
292 for ( k = 0; k < p->vMapObjs->nSize; k++ )
293 {
294 pNode = p->vMapObjs->pArray[k];
295 if ( pNode->nRefs == 0 )
296 continue;
297 p->pNodeDelays[k] = 0.014426 * LogFan * p->pSuperLib->tDelayInv.Worst * log( (double)pNode->nRefs ); // 1.4426 = 1/ln(2)
298 // printf( "%d = %d (%.2f) ", k, pNode->nRefs, p->pNodeDelays[k] );
299 }
300 // printf( "\n" );
301 }
302
303
304 /**Function*************************************************************
305
306 Synopsis [Deallocates the mapping manager.]
307
308 Description []
309
310 SideEffects []
311
312 SeeAlso []
313
314 ***********************************************************************/
Map_ManPrintTimeStats(Map_Man_t * p)315 void Map_ManPrintTimeStats( Map_Man_t * p )
316 {
317 printf( "N-canonical = %d. Matchings = %d. Phases = %d. ", p->nCanons, p->nMatches, p->nPhases );
318 printf( "Choice nodes = %d. Choices = %d.\n", p->nChoiceNodes, p->nChoices );
319 ABC_PRT( "ToMap", p->timeToMap );
320 ABC_PRT( "Cuts ", p->timeCuts );
321 ABC_PRT( "Truth", p->timeTruth );
322 ABC_PRT( "Match", p->timeMatch );
323 ABC_PRT( "Area ", p->timeArea );
324 ABC_PRT( "Sweep", p->timeSweep );
325 ABC_PRT( "ToNet", p->timeToNet );
326 ABC_PRT( "TOTAL", p->timeTotal );
327 if ( p->time1 ) { ABC_PRT( "time1", p->time1 ); }
328 if ( p->time2 ) { ABC_PRT( "time2", p->time2 ); }
329 if ( p->time3 ) { ABC_PRT( "time3", p->time3 ); }
330 }
331
332 /**Function*************************************************************
333
334 Synopsis [Prints the mapping stats.]
335
336 Description []
337
338 SideEffects []
339
340 SeeAlso []
341
342 ***********************************************************************/
Map_ManPrintStatsToFile(char * pName,float Area,float Delay,abctime Time)343 void Map_ManPrintStatsToFile( char * pName, float Area, float Delay, abctime Time )
344 {
345 FILE * pTable;
346 pTable = fopen( "map_stats.txt", "a+" );
347 fprintf( pTable, "%s ", pName );
348 fprintf( pTable, "%4.2f ", Area );
349 fprintf( pTable, "%4.2f ", Delay );
350 fprintf( pTable, "%4.2f\n", (float)(Time)/(float)(CLOCKS_PER_SEC) );
351 fclose( pTable );
352 }
353
354 /**Function*************************************************************
355
356 Synopsis [Creates a new node.]
357
358 Description [This procedure should be called to create the constant
359 node and the PI nodes first.]
360
361 SideEffects []
362
363 SeeAlso []
364
365 ***********************************************************************/
Map_NodeCreate(Map_Man_t * p,Map_Node_t * p1,Map_Node_t * p2)366 Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
367 {
368 Map_Node_t * pNode;
369 // create the node
370 pNode = (Map_Node_t *)Extra_MmFixedEntryFetch( p->mmNodes );
371 memset( pNode, 0, sizeof(Map_Node_t) );
372 pNode->tRequired[0].Rise = pNode->tRequired[0].Fall = pNode->tRequired[0].Worst = MAP_FLOAT_LARGE;
373 pNode->tRequired[1].Rise = pNode->tRequired[1].Fall = pNode->tRequired[1].Worst = MAP_FLOAT_LARGE;
374 pNode->p1 = p1;
375 pNode->p2 = p2;
376 pNode->p = p;
377 // set the number of this node
378 pNode->Num = p->nNodes++;
379 // place to store the fanouts
380 // pNode->vFanouts = Map_NodeVecAlloc( 5 );
381 // store this node in the internal array
382 if ( pNode->Num >= 0 )
383 Map_NodeVecPush( p->vMapObjs, pNode );
384 else
385 pNode->fInv = 1;
386 // set the level of this node
387 if ( p1 )
388 {
389 #ifdef MAP_ALLOCATE_FANOUT
390 // create the fanout info
391 Map_NodeAddFaninFanout( Map_Regular(p1), pNode );
392 if ( p2 )
393 Map_NodeAddFaninFanout( Map_Regular(p2), pNode );
394 #endif
395
396 if ( p2 )
397 {
398 pNode->Level = 1 + MAP_MAX(Map_Regular(pNode->p1)->Level, Map_Regular(pNode->p2)->Level);
399 pNode->fInv = Map_NodeIsSimComplement(p1) & Map_NodeIsSimComplement(p2);
400 }
401 else
402 {
403 pNode->Level = Map_Regular(pNode->p1)->Level;
404 pNode->fInv = Map_NodeIsSimComplement(p1);
405 }
406 }
407 // reference the inputs (will be used to compute the number of fanouts)
408 if ( p1 ) Map_NodeRef(p1);
409 if ( p2 ) Map_NodeRef(p2);
410
411 pNode->nRefEst[0] = pNode->nRefEst[1] = -1;
412 return pNode;
413 }
414
415 /**Function*************************************************************
416
417 Synopsis [Create the unique table of AND gates.]
418
419 Description []
420
421 SideEffects []
422
423 SeeAlso []
424
425 ***********************************************************************/
Map_TableCreate(Map_Man_t * pMan)426 void Map_TableCreate( Map_Man_t * pMan )
427 {
428 assert( pMan->pBins == NULL );
429 pMan->nBins = Abc_PrimeCudd(5000);
430 pMan->pBins = ABC_ALLOC( Map_Node_t *, pMan->nBins );
431 memset( pMan->pBins, 0, sizeof(Map_Node_t *) * pMan->nBins );
432 pMan->nNodes = 0;
433 }
434
435 /**Function*************************************************************
436
437 Synopsis [Looks up the AND2 node in the unique table.]
438
439 Description [This procedure implements one-level hashing. All the nodes
440 are hashed by their children. If the node with the same children was already
441 created, it is returned by the call to this procedure. If it does not exist,
442 this procedure creates a new node with these children. ]
443
444 SideEffects []
445
446 SeeAlso []
447
448 ***********************************************************************/
Map_NodeAnd(Map_Man_t * pMan,Map_Node_t * p1,Map_Node_t * p2)449 Map_Node_t * Map_NodeAnd( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2 )
450 {
451 Map_Node_t * pEnt;
452 unsigned Key;
453
454 if ( p1 == p2 )
455 return p1;
456 if ( p1 == Map_Not(p2) )
457 return Map_Not(pMan->pConst1);
458 if ( Map_NodeIsConst(p1) )
459 {
460 if ( p1 == pMan->pConst1 )
461 return p2;
462 return Map_Not(pMan->pConst1);
463 }
464 if ( Map_NodeIsConst(p2) )
465 {
466 if ( p2 == pMan->pConst1 )
467 return p1;
468 return Map_Not(pMan->pConst1);
469 }
470
471 if ( Map_Regular(p1)->Num > Map_Regular(p2)->Num )
472 pEnt = p1, p1 = p2, p2 = pEnt;
473
474 Key = Map_HashKey2( p1, p2, pMan->nBins );
475 for ( pEnt = pMan->pBins[Key]; pEnt; pEnt = pEnt->pNext )
476 if ( pEnt->p1 == p1 && pEnt->p2 == p2 )
477 return pEnt;
478 // resize the table
479 if ( pMan->nNodes >= 2 * pMan->nBins )
480 {
481 Map_TableResize( pMan );
482 Key = Map_HashKey2( p1, p2, pMan->nBins );
483 }
484 // create the new node
485 pEnt = Map_NodeCreate( pMan, p1, p2 );
486 // add the node to the corresponding linked list in the table
487 pEnt->pNext = pMan->pBins[Key];
488 pMan->pBins[Key] = pEnt;
489 return pEnt;
490 }
491
492
493 /**Function*************************************************************
494
495 Synopsis [Resizes the table.]
496
497 Description []
498
499 SideEffects []
500
501 SeeAlso []
502
503 ***********************************************************************/
Map_TableResize(Map_Man_t * pMan)504 void Map_TableResize( Map_Man_t * pMan )
505 {
506 Map_Node_t ** pBinsNew;
507 Map_Node_t * pEnt, * pEnt2;
508 int nBinsNew, Counter, i;
509 abctime clk;
510 unsigned Key;
511
512 clk = Abc_Clock();
513 // get the new table size
514 nBinsNew = Abc_PrimeCudd(2 * pMan->nBins);
515 // allocate a new array
516 pBinsNew = ABC_ALLOC( Map_Node_t *, nBinsNew );
517 memset( pBinsNew, 0, sizeof(Map_Node_t *) * nBinsNew );
518 // rehash the entries from the old table
519 Counter = 0;
520 for ( i = 0; i < pMan->nBins; i++ )
521 for ( pEnt = pMan->pBins[i], pEnt2 = pEnt? pEnt->pNext: NULL; pEnt;
522 pEnt = pEnt2, pEnt2 = pEnt? pEnt->pNext: NULL )
523 {
524 Key = Map_HashKey2( pEnt->p1, pEnt->p2, nBinsNew );
525 pEnt->pNext = pBinsNew[Key];
526 pBinsNew[Key] = pEnt;
527 Counter++;
528 }
529 assert( Counter == pMan->nNodes - pMan->nInputs );
530 if ( pMan->fVerbose )
531 {
532 // printf( "Increasing the unique table size from %6d to %6d. ", pMan->nBins, nBinsNew );
533 // ABC_PRT( "Time", Abc_Clock() - clk );
534 }
535 // replace the table and the parameters
536 ABC_FREE( pMan->pBins );
537 pMan->pBins = pBinsNew;
538 pMan->nBins = nBinsNew;
539 }
540
541
542
543 /**Function*************************************************************
544
545 Synopsis []
546
547 Description []
548
549 SideEffects []
550
551 SeeAlso []
552
553 ***********************************************************************/
Map_NodeBuf(Map_Man_t * p,Map_Node_t * p1)554 Map_Node_t * Map_NodeBuf( Map_Man_t * p, Map_Node_t * p1 )
555 {
556 Map_Node_t * pNode = Map_NodeCreate( p, p1, NULL );
557 Map_NodeVecPush( p->vMapBufs, pNode );
558 return pNode;
559 }
560
561 /**Function*************************************************************
562
563 Synopsis [Sets the node to be equivalent to the given one.]
564
565 Description [This procedure is a work-around for the equivalence check.
566 Does not verify the equivalence. Use at the user's risk.]
567
568 SideEffects []
569
570 SeeAlso []
571
572 ***********************************************************************/
Map_NodeSetChoice(Map_Man_t * pMan,Map_Node_t * pNodeOld,Map_Node_t * pNodeNew)573 void Map_NodeSetChoice( Map_Man_t * pMan, Map_Node_t * pNodeOld, Map_Node_t * pNodeNew )
574 {
575 pNodeNew->pNextE = pNodeOld->pNextE;
576 pNodeOld->pNextE = pNodeNew;
577 pNodeNew->pRepr = pNodeOld;
578 }
579
580
581
582 ////////////////////////////////////////////////////////////////////////
583 /// END OF FILE ///
584 ////////////////////////////////////////////////////////////////////////
585
586 ABC_NAMESPACE_IMPL_END
587
588