/**CFile**************************************************************** FileName [abcAttach.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Network and node package.] Synopsis [Attaches the library gates to the current network.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: abcAttach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "base/abc/abc.h" #include "base/main/main.h" #include "map/mio/mio.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// #define ATTACH_FULL (~((unsigned)0)) #define ATTACH_MASK(n) ((~((unsigned)0)) >> (32-(n))) static void Abc_AttachSetupTruthTables( unsigned uTruths[][2] ); static void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthNode ); static Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm ); static int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode ); static int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] ); static void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm ); static char ** s_pPerms = NULL; static int s_nPerms; //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Attaches gates from the current library to the internal nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkAttach( Abc_Ntk_t * pNtk ) { Mio_Library_t * pGenlib; unsigned ** puTruthGates; unsigned uTruths[6][2]; Abc_Obj_t * pNode; Mio_Gate_t ** ppGates; int nGates, nFanins, i; assert( Abc_NtkIsSopLogic(pNtk) ); // check that the library is available pGenlib = (Mio_Library_t *)Abc_FrameReadLibGen(); if ( pGenlib == NULL ) { printf( "The current library is not available.\n" ); return 0; } // start the truth tables Abc_AttachSetupTruthTables( uTruths ); // collect all the gates ppGates = Mio_CollectRoots( pGenlib, 6, (float)1.0e+20, 1, &nGates, 0 ); // derive the gate truth tables puTruthGates = ABC_ALLOC( unsigned *, nGates ); puTruthGates[0] = ABC_ALLOC( unsigned, 2 * nGates ); for ( i = 1; i < nGates; i++ ) puTruthGates[i] = puTruthGates[i-1] + 2; for ( i = 0; i < nGates; i++ ) Mio_DeriveTruthTable( ppGates[i], uTruths, Mio_GateReadPinNum(ppGates[i]), 6, puTruthGates[i] ); // assign the gates to pNode->pCopy Abc_NtkCleanCopy( pNtk ); Abc_NtkForEachNode( pNtk, pNode, i ) { nFanins = Abc_ObjFaninNum(pNode); if ( nFanins == 0 ) { if ( Abc_SopIsConst1((char *)pNode->pData) ) pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst1(pGenlib); else pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst0(pGenlib); } else if ( nFanins == 1 ) { if ( Abc_SopIsBuf((char *)pNode->pData) ) pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadBuf(pGenlib); else pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadInv(pGenlib); } else if ( nFanins > 6 ) { printf( "Cannot attach gate with more than 6 inputs to node %s.\n", Abc_ObjName(pNode) ); ABC_FREE( puTruthGates[0] ); ABC_FREE( puTruthGates ); ABC_FREE( ppGates ); return 0; } else if ( !Abc_NodeAttach( pNode, ppGates, puTruthGates, nGates, uTruths ) ) { printf( "Could not attach the library gate to node %s.\n", Abc_ObjName(pNode) ); ABC_FREE( puTruthGates[0] ); ABC_FREE( puTruthGates ); ABC_FREE( ppGates ); return 0; } } ABC_FREE( puTruthGates[0] ); ABC_FREE( puTruthGates ); ABC_FREE( ppGates ); ABC_FREE( s_pPerms ); // perform the final transformation Abc_NtkForEachNode( pNtk, pNode, i ) { if ( pNode->pCopy == NULL ) { printf( "Some elementary gates (constant, buffer, or inverter) are missing in the library.\n" ); return 0; } } // replace SOP representation by the gate representation Abc_NtkForEachNode( pNtk, pNode, i ) pNode->pData = pNode->pCopy, pNode->pCopy = NULL; pNtk->ntkFunc = ABC_FUNC_MAP; Extra_MmFlexStop( (Extra_MmFlex_t *)pNtk->pManFunc ); pNtk->pManFunc = pGenlib; printf( "Library gates are successfully attached to the nodes.\n" ); // make sure that everything is okay if ( !Abc_NtkCheck( pNtk ) ) { printf( "Abc_NtkAttach: The network check has failed.\n" ); return 0; } return 1; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] ) { int Perm[10]; int pTempInts[10]; unsigned uTruthNode[2]; Abc_Obj_t * pFanin; Mio_Gate_t * pGate; int nFanins, i; // compute the node's truth table Abc_AttachComputeTruth( (char *)pNode->pData, uTruths, uTruthNode ); // find the matching gate and permutation pGate = Abc_AttachFind( ppGates, puTruthGates, nGates, uTruthNode, Perm ); if ( pGate == NULL ) return 0; // permute the fanins nFanins = Abc_ObjFaninNum(pNode); Abc_ObjForEachFanin( pNode, pFanin, i ) pTempInts[i] = pFanin->Id; for ( i = 0; i < nFanins; i++ ) pNode->vFanins.pArray[Perm[i]] = pTempInts[i]; // set the gate pNode->pCopy = (Abc_Obj_t *)pGate; return 1; } /**Function************************************************************* Synopsis [Sets up the truth tables.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_AttachSetupTruthTables( unsigned uTruths[][2] ) { int m, v; for ( v = 0; v < 5; v++ ) uTruths[v][0] = 0; // set up the truth tables for ( m = 0; m < 32; m++ ) for ( v = 0; v < 5; v++ ) if ( m & (1 << v) ) uTruths[v][0] |= (1 << m); // make adjustments for the case of 6 variables for ( v = 0; v < 5; v++ ) uTruths[v][1] = uTruths[v][0]; uTruths[5][0] = 0; uTruths[5][1] = ATTACH_FULL; } /**Function************************************************************* Synopsis [Compute the truth table of the node's cover.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthRes ) { // Mvc_Cube_t * pCube; unsigned uSignCube[2]; int Value; // int nInputs = pCover->nBits/2; int nInputs = 6; int nFanins = Abc_SopGetVarNum(pSop); char * pCube; int k; // make sure that the number of input truth tables in equal to the number of gate inputs assert( nInputs < 7 ); // clean the resulting truth table uTruthRes[0] = 0; uTruthRes[1] = 0; if ( nInputs < 6 ) { // consider the case when only one unsigned can be used // Mvc_CoverForEachCube( pCover, pCube ) Abc_SopForEachCube( pSop, nFanins, pCube ) { uSignCube[0] = ATTACH_FULL; // Mvc_CubeForEachVarValue( pCover, pCube, Var, Value ) Abc_CubeForEachVar( pCube, Value, k ) { if ( Value == '0' ) uSignCube[0] &= ~uTruthsIn[k][0]; else if ( Value == '1' ) uSignCube[0] &= uTruthsIn[k][0]; } uTruthRes[0] |= uSignCube[0]; } if ( Abc_SopGetPhase(pSop) == 0 ) uTruthRes[0] = ~uTruthRes[0]; if ( nInputs < 5 ) uTruthRes[0] &= ATTACH_MASK(1<= 0 ) { for ( v = 0; v < 6; v++ ) Perm[v] = v; return ppGates[iNum]; } // get permutations if ( s_pPerms == NULL ) { s_pPerms = Extra_Permutations( 6 ); s_nPerms = Extra_Factorial( 6 ); } // try permutations for ( i = 0; i < s_nPerms; i++ ) { Abc_TruthPermute( s_pPerms[i], 6, uTruthNode, uTruthPerm ); if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthPerm )) >= 0 ) { for ( v = 0; v < 6; v++ ) Perm[v] = (int)s_pPerms[i][v]; return ppGates[iNum]; } } return NULL; } /**Function************************************************************* Synopsis [Find the gate by truth table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode ) { int i; for ( i = 0; i < nGates; i++ ) if ( puTruthGates[i][0] == uTruthNode[0] && puTruthGates[i][1] == uTruthNode[1] ) return i; return -1; } /**Function************************************************************* Synopsis [Permutes the 6-input truth table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm ) { int nMints, iMintPerm, iMint, v; uTruthPerm[0] = uTruthPerm[1] = 0; nMints = (1 << nVars); for ( iMint = 0; iMint < nMints; iMint++ ) { if ( (uTruthNode[iMint>>5] & (1 << (iMint&31))) == 0 ) continue; iMintPerm = 0; for ( v = 0; v < nVars; v++ ) if ( iMint & (1 << v) ) iMintPerm |= (1 << pPerm[v]); uTruthPerm[iMintPerm>>5] |= (1 << (iMintPerm&31)); } } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END