summaryrefslogtreecommitdiffstats
path: root/src/base/abci/abcAttach.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2005-09-04 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2005-09-04 08:01:00 -0700
commit33012d9530c40817e1fc5230b3e663f7690b2e94 (patch)
tree4b782c372b9647ad8490103ee98d0affa54a3952 /src/base/abci/abcAttach.c
parentdce73ade2fa0c7a01b58d4a6c592e0e07cbb5499 (diff)
downloadabc-33012d9530c40817e1fc5230b3e663f7690b2e94.tar.gz
abc-33012d9530c40817e1fc5230b3e663f7690b2e94.tar.bz2
abc-33012d9530c40817e1fc5230b3e663f7690b2e94.zip
Version abc50904
Diffstat (limited to 'src/base/abci/abcAttach.c')
-rw-r--r--src/base/abci/abcAttach.c405
1 files changed, 405 insertions, 0 deletions
diff --git a/src/base/abci/abcAttach.c b/src/base/abci/abcAttach.c
new file mode 100644
index 00000000..a8e06555
--- /dev/null
+++ b/src/base/abci/abcAttach.c
@@ -0,0 +1,405 @@
+/**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 DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Attaches gates from the current library to the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkAttach( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ 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(Abc_FrameGetGlobalFrame());
+ 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, 0 );
+ pNtk->pManFunc = pGenlib;
+
+ printf( "Library gates are successfully attached to the nodes.\n" );
+
+ // make sure that everything is okay
+ if ( fCheck && !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]].iFan = 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/32] & (1 << (iMint%32))) == 0 )
+ continue;
+ iMintPerm = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( iMint & (1 << v) )
+ iMintPerm |= (1 << pPerm[v]);
+ uTruthPerm[iMintPerm/32] |= (1 << (iMintPerm%32));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+