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