blob: f24e1a72d9263a0f0ced830751418f3b8ff4ddf6 [file] [log] [blame]
/**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<<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 ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END