mirror of https://github.com/YosysHQ/abc.git
410 lines
12 KiB
C
410 lines
12 KiB
C
/**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
|
|
|