/**Function************************************************************* Synopsis [Inserts a new entry into the library.] Description [This function inserts the new gate (pGate), which will be accessible through its unfolded function (uTruth).] SideEffects [] SeeAlso [] ***********************************************************************/ int Map_SuperTableInsert( Map_HashTable_t * p, unsigned uTruth[], Map_Super_t * pGate, unsigned uPhase ) { Map_HashEntry_t * pEnt; unsigned Key; // resize the table if ( p->nEntries >= 2 * p->nBins ) Map_SuperTableResize( p ); // check if this entry already exists Key = MAP_TABLE_HASH( uTruth[0], uTruth[1], p->nBins ); for ( pEnt = p->pBins[Key]; pEnt; pEnt = pEnt->pNext ) if ( pEnt->uTruth[0] == uTruth[0] && pEnt->uTruth[1] == uTruth[1] ) return 1; // add the new hash table entry to the table pEnt = (Map_HashEntry_t *)Extra_MmFixedEntryFetch( p->mmMan ); memset( pEnt, 0, sizeof(Map_HashEntry_t) ); pEnt->uTruth[0] = uTruth[0]; pEnt->uTruth[1] = uTruth[1]; pEnt->pGates = pGate; pEnt->uPhase = uPhase; // add the hash table to the corresponding linked list in the table pEnt->pNext = p->pBins[Key]; p->pBins[Key] = pEnt; p->nEntries++; /* printf( "Adding gate: %10u ", Key ); Map_LibraryPrintSupergate( pGate ); Extra_PrintBinary( stdout, uTruth, 32 ); printf( "\n" ); */ return 0; }
/**Function************************************************************* Synopsis [Allocates the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Fpga_Cut_t * Fpga_CutAlloc( Fpga_Man_t * p ) { Fpga_Cut_t * pCut; pCut = (Fpga_Cut_t *)Extra_MmFixedEntryFetch( p->mmCuts ); memset( pCut, 0, sizeof(Fpga_Cut_t) ); return pCut; }
/**Function************************************************************* Synopsis [Inserts a new entry into the hash table.] Description [This function inserts the new gate (pGate), which will be accessible through its canonical form (uTruthC).] SideEffects [] SeeAlso [] ***********************************************************************/ int Map_SuperTableInsertC( Map_HashTable_t * p, unsigned uTruthC[], Map_Super_t * pGate ) { Map_HashEntry_t * pEnt; unsigned Key; // resize the table if ( p->nEntries >= 2 * p->nBins ) Map_SuperTableResize( p ); // check if another supergate with the same canonical form exists Key = MAP_TABLE_HASH( uTruthC[0], uTruthC[1], p->nBins ); for ( pEnt = p->pBins[Key]; pEnt; pEnt = pEnt->pNext ) if ( pEnt->uTruth[0] == uTruthC[0] && pEnt->uTruth[1] == uTruthC[1] ) break; // create a new entry if it does not exist if ( pEnt == NULL ) { // add the new entry to the table pEnt = (Map_HashEntry_t *)Extra_MmFixedEntryFetch( p->mmMan ); memset( pEnt, 0, sizeof(Map_HashEntry_t) ); pEnt->uTruth[0] = uTruthC[0]; pEnt->uTruth[1] = uTruthC[1]; // add the hash table entry to the corresponding linked list in the table pEnt->pNext = p->pBins[Key]; p->pBins[Key] = pEnt; p->nEntries++; } // add the supergate to the entry pGate->pNext = pEnt->pGates; pEnt->pGates = pGate; return 0; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Map_Super_t * Map_LibraryReadGate( Map_SuperLib_t * pLib, char * pBuffer, int nVars ) { Map_Super_t * pGate; char * pTemp; int i; // start and clean the gate pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers ); memset( pGate, 0, sizeof(Map_Super_t) ); // read the number pTemp = strtok( pBuffer, " " ); pGate->Num = atoi(pTemp); // read the signature pTemp = strtok( NULL, " " ); if ( pLib->nVarsMax < 6 ) { pGate->uTruth[0] = Extra_ReadBinary(pTemp); pGate->uTruth[1] = 0; } else { pGate->uTruth[0] = Extra_ReadBinary(pTemp+32); pTemp[32] = 0; pGate->uTruth[1] = Extra_ReadBinary(pTemp); } // read the max delay pTemp = strtok( NULL, " " ); pGate->tDelayMax.Rise = (float)atof(pTemp); pGate->tDelayMax.Fall = pGate->tDelayMax.Rise; // read the pin-to-pin delay for ( i = 0; i < nVars; i++ ) { pTemp = strtok( NULL, " " ); pGate->tDelaysR[i].Rise = (float)atof(pTemp); pGate->tDelaysF[i].Fall = pGate->tDelaysR[i].Rise; } // read the area pTemp = strtok( NULL, " " ); pGate->Area = (float)atof(pTemp); // the rest is the gate name pTemp = strtok( NULL, " \r\n" ); if ( strlen(pTemp) == 0 ) printf( "A gate name is empty.\n" ); // save the gate name pGate->pFormula = Extra_MmFlexEntryFetch( pLib->mmForms, strlen(pTemp) + 1 ); strcpy( pGate->pFormula, pTemp ); // the rest is the gate name pTemp = strtok( NULL, " \n\0" ); if ( pTemp != NULL ) printf( "The following trailing symbols found \"%s\".\n", pTemp ); return pGate; }
/**Function************************************************************* Synopsis [Adds one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Rwr_Node_t * Rwr_ManAddNode( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_Node_t * p1, int fExor, int Level, int Volume ) { Rwr_Node_t * pNew; unsigned uTruth; // compute truth table, leve, volume p->nConsidered++; if ( fExor ) uTruth = (p0->uTruth ^ p1->uTruth); else uTruth = (Rwr_IsComplement(p0)? ~Rwr_Regular(p0)->uTruth : Rwr_Regular(p0)->uTruth) & (Rwr_IsComplement(p1)? ~Rwr_Regular(p1)->uTruth : Rwr_Regular(p1)->uTruth) & 0xFFFF; // create the new node pNew = (Rwr_Node_t *)Extra_MmFixedEntryFetch( p->pMmNode ); pNew->Id = p->vForest->nSize; pNew->TravId = 0; pNew->uTruth = uTruth; pNew->Level = Level; pNew->Volume = Volume; pNew->fUsed = 0; pNew->fExor = fExor; pNew->p0 = p0; pNew->p1 = p1; pNew->pNext = NULL; Vec_PtrPush( p->vForest, pNew ); // do not add if the node is not essential if ( uTruth != p->puCanons[uTruth] ) return pNew; // add to the list p->nAdded++; if ( p->pTable[uTruth] == NULL ) p->nClasses++; Rwr_ListAddToTail( p->pTable + uTruth, pNew ); return pNew; }
/**Function************************************************************* Synopsis [Adds one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Rwr_Node_t * Rwr_ManTryNode( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_Node_t * p1, int fExor, int Level, int Volume ) { Rwr_Node_t * pOld, * pNew, ** ppPlace; unsigned uTruth; // compute truth table, level, volume p->nConsidered++; if ( fExor ) { // printf( "Considering EXOR of %d and %d.\n", p0->Id, p1->Id ); uTruth = (p0->uTruth ^ p1->uTruth); } else uTruth = (Rwr_IsComplement(p0)? ~Rwr_Regular(p0)->uTruth : Rwr_Regular(p0)->uTruth) & (Rwr_IsComplement(p1)? ~Rwr_Regular(p1)->uTruth : Rwr_Regular(p1)->uTruth) & 0xFFFF; // skip non-practical classes if ( Level > 2 && !p->pPractical[p->puCanons[uTruth]] ) return NULL; // enumerate through the nodes with the same canonical form ppPlace = p->pTable + uTruth; for ( pOld = *ppPlace; pOld; ppPlace = &pOld->pNext, pOld = pOld->pNext ) { if ( pOld->Level < (unsigned)Level && pOld->Volume < (unsigned)Volume ) return NULL; if ( pOld->Level == (unsigned)Level && pOld->Volume < (unsigned)Volume ) return NULL; // if ( pOld->Level < (unsigned)Level && pOld->Volume == (unsigned)Volume ) // return NULL; } /* // enumerate through the nodes with the opposite polarity for ( pOld = p->pTable[~uTruth & 0xFFFF]; pOld; pOld = pOld->pNext ) { if ( pOld->Level < (unsigned)Level && pOld->Volume < (unsigned)Volume ) return NULL; if ( pOld->Level == (unsigned)Level && pOld->Volume < (unsigned)Volume ) return NULL; // if ( pOld->Level < (unsigned)Level && pOld->Volume == (unsigned)Volume ) // return NULL; } */ // count the classes if ( p->pTable[uTruth] == NULL && p->puCanons[uTruth] == uTruth ) p->nClasses++; // create the new node pNew = (Rwr_Node_t *)Extra_MmFixedEntryFetch( p->pMmNode ); pNew->Id = p->vForest->nSize; pNew->TravId = 0; pNew->uTruth = uTruth; pNew->Level = Level; pNew->Volume = Volume; pNew->fUsed = 0; pNew->fExor = fExor; pNew->p0 = p0; pNew->p1 = p1; pNew->pNext = NULL; Vec_PtrPush( p->vForest, pNew ); *ppPlace = pNew; return pNew; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes ) { s_MemoryTotal += nBytes; if ( s_MemoryPeak < s_MemoryTotal ) s_MemoryPeak = s_MemoryTotal; // return ABC_ALLOC( char, nBytes ); return Extra_MmFixedEntryFetch( p->pMemMan ); }
/**Function************************************************************* Synopsis [Returns one simulation pattern.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p ) { Sim_Pat_t * pPat; pPat = (Sim_Pat_t *)Extra_MmFixedEntryFetch( p->pMmPat ); pPat->Output = -1; pPat->pData = (unsigned *)((char *)pPat + sizeof(Sim_Pat_t)); memset( pPat->pData, 0, p->nSuppWords * sizeof(unsigned) ); return pPat; }
/**Function************************************************************* Synopsis [Creates a new node.] Description [This procedure should be called to create the constant node and the PI nodes first.] SideEffects [] SeeAlso [] ***********************************************************************/ Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 ) { Map_Node_t * pNode; // create the node pNode = (Map_Node_t *)Extra_MmFixedEntryFetch( p->mmNodes ); memset( pNode, 0, sizeof(Map_Node_t) ); pNode->tRequired[0].Rise = pNode->tRequired[0].Fall = pNode->tRequired[0].Worst = MAP_FLOAT_LARGE; pNode->tRequired[1].Rise = pNode->tRequired[1].Fall = pNode->tRequired[1].Worst = MAP_FLOAT_LARGE; pNode->p1 = p1; pNode->p2 = p2; pNode->p = p; // set the number of this node pNode->Num = p->nNodes++; // place to store the fanouts // pNode->vFanouts = Map_NodeVecAlloc( 5 ); // store this node in the internal array if ( pNode->Num >= 0 ) Map_NodeVecPush( p->vMapObjs, pNode ); else pNode->fInv = 1; // set the level of this node if ( p1 ) { #ifdef MAP_ALLOCATE_FANOUT // create the fanout info Map_NodeAddFaninFanout( Map_Regular(p1), pNode ); if ( p2 ) Map_NodeAddFaninFanout( Map_Regular(p2), pNode ); #endif if ( p2 ) { pNode->Level = 1 + MAP_MAX(Map_Regular(pNode->p1)->Level, Map_Regular(pNode->p2)->Level); pNode->fInv = Map_NodeIsSimComplement(p1) & Map_NodeIsSimComplement(p2); } else { pNode->Level = Map_Regular(pNode->p1)->Level; pNode->fInv = Map_NodeIsSimComplement(p1); } } // reference the inputs (will be used to compute the number of fanouts) if ( p1 ) Map_NodeRef(p1); if ( p2 ) Map_NodeRef(p2); pNode->nRefEst[0] = pNode->nRefEst[1] = -1; return pNode; }
/**Function************************************************************* Synopsis [Adds one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Rwr_Node_t * Rwr_ManAddVar( Rwr_Man_t * p, unsigned uTruth, int fPrecompute ) { Rwr_Node_t * pNew; pNew = (Rwr_Node_t *)Extra_MmFixedEntryFetch( p->pMmNode ); pNew->Id = p->vForest->nSize; pNew->TravId = 0; pNew->uTruth = uTruth; pNew->Level = 0; pNew->Volume = 0; pNew->fUsed = 1; pNew->fExor = 0; pNew->p0 = NULL; pNew->p1 = NULL; pNew->pNext = NULL; Vec_PtrPush( p->vForest, pNew ); if ( fPrecompute ) Rwr_ListAddToTail( p->pTable + uTruth, pNew ); return pNew; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Mvc_Cover_t * Mvc_CoverClone( Mvc_Cover_t * p ) { Mvc_Cover_t * pCover; #ifdef USE_SYSTEM_MEMORY_MANAGEMENT pCover = (Mvc_Cover_t *)malloc( sizeof(Mvc_Cover_t) ); #else pCover = (Mvc_Cover_t *)Extra_MmFixedEntryFetch( p->pMem->pManC ); #endif pCover->pMem = p->pMem; pCover->nBits = p->nBits; pCover->nWords = p->nWords; pCover->nUnused = p->nUnused; pCover->lCubes.nItems = 0; pCover->lCubes.pHead = NULL; pCover->lCubes.pTail = NULL; pCover->nCubesAlloc = 0; pCover->pCubes = NULL; pCover->pMask = NULL; pCover->pLits = NULL; return pCover; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Mvc_Cover_t * Mvc_CoverAlloc( Mvc_Manager_t * pMem, int nBits ) { Mvc_Cover_t * p; int nBitsInUnsigned; nBitsInUnsigned = 8 * sizeof(Mvc_CubeWord_t); #ifdef USE_SYSTEM_MEMORY_MANAGEMENT p = (Mvc_Cover_t *)malloc( sizeof(Mvc_Cover_t) ); #else p = (Mvc_Cover_t *)Extra_MmFixedEntryFetch( pMem->pManC ); #endif p->pMem = pMem; p->nBits = nBits; p->nWords = nBits / nBitsInUnsigned + (int)(nBits % nBitsInUnsigned > 0); p->nUnused = p->nWords * nBitsInUnsigned - p->nBits; p->lCubes.nItems = 0; p->lCubes.pHead = NULL; p->lCubes.pTail = NULL; p->nCubesAlloc = 0; p->pCubes = NULL; p->pMask = NULL; p->pLits = NULL; return p; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Reads in the supergate library and prepares it for use.] Description [The supergates library comes in a .super file. This file contains descriptions of supergates along with some relevant information. This procedure reads the supergate file, canonicizes the supergates, and constructs an additional lookup table, which can be used to map truth tables of the cuts into the pair (phase, supergate). The phase indicates how the current truth table should be phase assigned to match the canonical form of the supergate. The resulting phase is the bitwise EXOR of the phase needed to canonicize the supergate and the phase needed to transform the truth table into its canonical form.] SideEffects [] SeeAlso [] ***********************************************************************/ Map_SuperLib_t * Map_SuperLibCreate( char * pFileName, char * pExcludeFile, int fAlgorithm, int fVerbose ) { Map_SuperLib_t * p; clock_t clk; // start the supergate library p = ABC_ALLOC( Map_SuperLib_t, 1 ); memset( p, 0, sizeof(Map_SuperLib_t) ); p->pName = pFileName; p->fVerbose = fVerbose; p->mmSupers = Extra_MmFixedStart( sizeof(Map_Super_t) ); p->mmEntries = Extra_MmFixedStart( sizeof(Map_HashEntry_t) ); p->mmForms = Extra_MmFlexStart(); Map_MappingSetupTruthTables( p->uTruths ); // start the hash table p->tTableC = Map_SuperTableCreate( p ); p->tTable = Map_SuperTableCreate( p ); // read the supergate library from file clk = clock(); if ( fAlgorithm ) { if ( !Map_LibraryReadTree( p, pFileName, pExcludeFile ) ) { Map_SuperLibFree( p ); return NULL; } } else { if ( pExcludeFile != 0 ) { Map_SuperLibFree( p ); printf ("Error: Exclude file support not present for old format. Stop.\n"); return NULL; } if ( !Map_LibraryRead( p, pFileName ) ) { Map_SuperLibFree( p ); return NULL; } } assert( p->nVarsMax > 0 ); // report the stats if ( fVerbose ) { printf( "Loaded %d unique %d-input supergates from \"%s\". ", p->nSupersReal, p->nVarsMax, pFileName ); ABC_PRT( "Time", clock() - clk ); } // assign the interver parameters p->pGateInv = Mio_LibraryReadInv( p->pGenlib ); p->tDelayInv.Rise = Mio_LibraryReadDelayInvRise( p->pGenlib ); p->tDelayInv.Fall = Mio_LibraryReadDelayInvFall( p->pGenlib ); p->tDelayInv.Worst = MAP_MAX( p->tDelayInv.Rise, p->tDelayInv.Fall ); p->AreaInv = Mio_LibraryReadAreaInv( p->pGenlib ); p->AreaBuf = Mio_LibraryReadAreaBuf( p->pGenlib ); // assign the interver supergate p->pSuperInv = (Map_Super_t *)Extra_MmFixedEntryFetch( p->mmSupers ); memset( p->pSuperInv, 0, sizeof(Map_Super_t) ); p->pSuperInv->Num = -1; p->pSuperInv->nGates = 1; p->pSuperInv->nFanins = 1; p->pSuperInv->nFanLimit = 10; p->pSuperInv->pFanins[0] = p->ppSupers[0]; p->pSuperInv->pRoot = p->pGateInv; p->pSuperInv->Area = p->AreaInv; p->pSuperInv->tDelayMax = p->tDelayInv; p->pSuperInv->tDelaysR[0].Rise = MAP_NO_VAR; p->pSuperInv->tDelaysR[0].Fall = p->tDelayInv.Rise; p->pSuperInv->tDelaysF[0].Rise = p->tDelayInv.Fall; p->pSuperInv->tDelaysF[0].Fall = MAP_NO_VAR; return p; }