diff options
Diffstat (limited to 'src/base/abci/abcAttach.c')
-rw-r--r-- | src/base/abci/abcAttach.c | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/src/base/abci/abcAttach.c b/src/base/abci/abcAttach.c new file mode 100644 index 00000000..d5d2aa16 --- /dev/null +++ b/src/base/abci/abcAttach.c @@ -0,0 +1,404 @@ +/**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 "abc.h" +#include "main.h" +#include "mio.h" + +//////////////////////////////////////////////////////////////////////// +/// 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 = 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 ); + + // derive the gate truth tables + puTruthGates = ALLOC( unsigned *, nGates ); + puTruthGates[0] = 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_GateReadInputs(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(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(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) ); + free( puTruthGates[0] ); + free( puTruthGates ); + 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) ); + free( puTruthGates[0] ); + free( puTruthGates ); + free( ppGates ); + return 0; + } + } + free( puTruthGates[0] ); + free( puTruthGates ); + free( ppGates ); + 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( 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( 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<<nInputs); + } + else + { + // consider the case when two unsigneds should be used +// Mvc_CoverForEachCube( pCover, pCube ) + Abc_SopForEachCube( pSop, nFanins, pCube ) + { + uSignCube[0] = ATTACH_FULL; + uSignCube[1] = ATTACH_FULL; +// Mvc_CubeForEachVarValue( pCover, pCube, Var, Value ) + Abc_CubeForEachVar( pCube, Value, k ) + { + if ( Value == '0' ) + { + uSignCube[0] &= ~uTruthsIn[k][0]; + uSignCube[1] &= ~uTruthsIn[k][1]; + } + else if ( Value == '1' ) + { + uSignCube[0] &= uTruthsIn[k][0]; + uSignCube[1] &= uTruthsIn[k][1]; + } + } + uTruthRes[0] |= uSignCube[0]; + uTruthRes[1] |= uSignCube[1]; + } + + // complement if the SOP is complemented + if ( Abc_SopGetPhase(pSop) == 0 ) + { + uTruthRes[0] = ~uTruthRes[0]; + uTruthRes[1] = ~uTruthRes[1]; + } + } +} + +/**Function************************************************************* + + Synopsis [Find the gate by truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm ) +{ + unsigned uTruthPerm[2]; + int i, v, iNum; + + // try the gates without permutation + if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthNode )) >= 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 /// +//////////////////////////////////////////////////////////////////////// + + |