2008-01-31 05:01:00 +01:00
|
|
|
/**CFile****************************************************************
|
|
|
|
|
|
|
|
|
|
FileName [ntlMap.c]
|
|
|
|
|
|
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
|
|
|
|
|
|
PackageName [Netlist representation.]
|
|
|
|
|
|
|
|
|
|
Synopsis [Derives mapped network from AIG.]
|
|
|
|
|
|
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
|
|
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
|
|
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
|
|
|
|
|
|
Revision [$Id: ntlMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "ntl.h"
|
|
|
|
|
#include "kit.h"
|
2008-03-26 16:01:00 +01:00
|
|
|
#include "if.h"
|
2008-01-31 05:01:00 +01:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// DECLARATIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// FUNCTION DEFINITIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Allocates mapping for the given AIG.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Vec_Ptr_t * Ntl_MappingAlloc( int nLuts, int nVars )
|
|
|
|
|
{
|
|
|
|
|
char * pMemory;
|
|
|
|
|
Ntl_Lut_t ** pArray;
|
|
|
|
|
int nEntrySize, i;
|
|
|
|
|
nEntrySize = sizeof(Ntl_Lut_t) + sizeof(int) * nVars + sizeof(unsigned) * Aig_TruthWordNum(nVars);
|
|
|
|
|
pArray = (Ntl_Lut_t **)malloc( (sizeof(Ntl_Lut_t *) + nEntrySize) * nLuts );
|
|
|
|
|
pMemory = (char *)(pArray + nLuts);
|
|
|
|
|
memset( pMemory, 0, nEntrySize * nLuts );
|
|
|
|
|
for ( i = 0; i < nLuts; i++ )
|
|
|
|
|
{
|
|
|
|
|
pArray[i] = (Ntl_Lut_t *)pMemory;
|
|
|
|
|
pArray[i]->pFanins = (int *)(pMemory + sizeof(Ntl_Lut_t));
|
|
|
|
|
pArray[i]->pTruth = (unsigned *)(pMemory + sizeof(Ntl_Lut_t) + sizeof(int) * nVars);
|
|
|
|
|
pMemory += nEntrySize;
|
|
|
|
|
}
|
|
|
|
|
return Vec_PtrAllocArray( (void **)pArray, nLuts );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Derives trivial mapping from the AIG.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Vec_Ptr_t * Ntl_MappingFromAig( Aig_Man_t * p )
|
|
|
|
|
{
|
|
|
|
|
Vec_Ptr_t * vMapping;
|
|
|
|
|
Ntl_Lut_t * pLut;
|
|
|
|
|
Aig_Obj_t * pObj;
|
|
|
|
|
int i, k = 0, nBytes = 4;
|
|
|
|
|
vMapping = Ntl_MappingAlloc( Aig_ManAndNum(p) + (int)(Aig_ManConst1(p)->nRefs > 0), 2 );
|
|
|
|
|
if ( Aig_ManConst1(p)->nRefs > 0 )
|
|
|
|
|
{
|
|
|
|
|
pLut = Vec_PtrEntry( vMapping, k++ );
|
|
|
|
|
pLut->Id = 0;
|
|
|
|
|
pLut->nFanins = 0;
|
|
|
|
|
memset( pLut->pTruth, 0xFF, nBytes );
|
|
|
|
|
}
|
|
|
|
|
Aig_ManForEachNode( p, pObj, i )
|
|
|
|
|
{
|
|
|
|
|
pLut = Vec_PtrEntry( vMapping, k++ );
|
|
|
|
|
pLut->Id = pObj->Id;
|
|
|
|
|
pLut->nFanins = 2;
|
|
|
|
|
pLut->pFanins[0] = Aig_ObjFaninId0(pObj);
|
|
|
|
|
pLut->pFanins[1] = Aig_ObjFaninId1(pObj);
|
|
|
|
|
if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) )
|
|
|
|
|
memset( pLut->pTruth, 0x11, nBytes );
|
|
|
|
|
else if ( !Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) )
|
|
|
|
|
memset( pLut->pTruth, 0x22, nBytes );
|
|
|
|
|
else if ( Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) )
|
|
|
|
|
memset( pLut->pTruth, 0x44, nBytes );
|
|
|
|
|
else if ( !Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) )
|
|
|
|
|
memset( pLut->pTruth, 0x88, nBytes );
|
|
|
|
|
}
|
|
|
|
|
assert( k == Vec_PtrSize(vMapping) );
|
|
|
|
|
return vMapping;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Load the network into FPGA manager.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
void Ntk_ManSetIfParsDefault( If_Par_t * pPars )
|
|
|
|
|
{
|
|
|
|
|
// extern void * Abc_FrameReadLibLut();
|
|
|
|
|
// set defaults
|
|
|
|
|
memset( pPars, 0, sizeof(If_Par_t) );
|
|
|
|
|
// user-controlable paramters
|
|
|
|
|
// pPars->nLutSize = -1;
|
|
|
|
|
pPars->nLutSize = 6;
|
|
|
|
|
pPars->nCutsMax = 8;
|
|
|
|
|
pPars->nFlowIters = 1;
|
|
|
|
|
pPars->nAreaIters = 2;
|
|
|
|
|
pPars->DelayTarget = -1;
|
2008-03-26 16:01:00 +01:00
|
|
|
pPars->Epsilon = (float)0.001;
|
2008-01-31 05:01:00 +01:00
|
|
|
pPars->fPreprocess = 1;
|
|
|
|
|
pPars->fArea = 0;
|
|
|
|
|
pPars->fFancy = 0;
|
|
|
|
|
pPars->fExpRed = 0;
|
|
|
|
|
pPars->fLatchPaths = 0;
|
|
|
|
|
pPars->fEdge = 1;
|
|
|
|
|
pPars->fCutMin = 1;
|
|
|
|
|
pPars->fSeqMap = 0;
|
|
|
|
|
pPars->fVerbose = 1;
|
|
|
|
|
// internal parameters
|
|
|
|
|
pPars->fTruth = 1;
|
|
|
|
|
pPars->nLatches = 0;
|
|
|
|
|
pPars->fLiftLeaves = 0;
|
|
|
|
|
// pPars->pLutLib = Abc_FrameReadLibLut();
|
|
|
|
|
pPars->pLutLib = NULL;
|
|
|
|
|
pPars->pTimesArr = NULL;
|
|
|
|
|
pPars->pTimesArr = NULL;
|
|
|
|
|
pPars->pFuncCost = NULL;
|
|
|
|
|
/*
|
|
|
|
|
if ( pPars->nLutSize == -1 )
|
|
|
|
|
{
|
|
|
|
|
if ( pPars->pLutLib == NULL )
|
|
|
|
|
{
|
|
|
|
|
printf( "The LUT library is not given.\n" );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// get LUT size from the library
|
|
|
|
|
pPars->nLutSize = pPars->pLutLib->LutMax;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Load the network into FPGA manager.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
If_Man_t * Ntk_ManToIf_old( Aig_Man_t * p, If_Par_t * pPars )
|
|
|
|
|
{
|
|
|
|
|
If_Man_t * pIfMan;
|
|
|
|
|
Aig_Obj_t * pNode;//, * pFanin, * pPrev;
|
|
|
|
|
Vec_Ptr_t * vNodes;
|
|
|
|
|
int i;
|
|
|
|
|
// start the mapping manager and set its parameters
|
|
|
|
|
pIfMan = If_ManStart( pPars );
|
|
|
|
|
// print warning about excessive memory usage
|
|
|
|
|
if ( 1.0 * Aig_ManObjNum(p) * pIfMan->nObjBytes / (1<<30) > 1.0 )
|
|
|
|
|
printf( "Warning: The mapper will allocate %.1f Gb for to represent the subject graph with %d AIG nodes.\n",
|
|
|
|
|
1.0 * Aig_ManObjNum(p) * pIfMan->nObjBytes / (1<<30), Aig_ManObjNum(p) );
|
|
|
|
|
// load the AIG into the mapper
|
|
|
|
|
vNodes = Aig_ManDfsPio( p );
|
|
|
|
|
Vec_PtrForEachEntry( vNodes, pNode, i )
|
|
|
|
|
{
|
|
|
|
|
if ( Aig_ObjIsAnd(pNode) )
|
|
|
|
|
pNode->pData = (Aig_Obj_t *)If_ManCreateAnd( pIfMan,
|
|
|
|
|
If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ),
|
|
|
|
|
If_NotCond( (If_Obj_t *)Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) );
|
|
|
|
|
else if ( Aig_ObjIsPi(pNode) )
|
|
|
|
|
pNode->pData = If_ManCreateCi( pIfMan );
|
|
|
|
|
else if ( Aig_ObjIsPo(pNode) )
|
|
|
|
|
If_ManCreateCo( pIfMan, If_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) );
|
|
|
|
|
else if ( Aig_ObjIsConst1(pNode) )
|
|
|
|
|
Aig_ManConst1(p)->pData = If_ManConst1( pIfMan );
|
|
|
|
|
else // add the node to the mapper
|
|
|
|
|
assert( 0 );
|
|
|
|
|
// set up the choice node
|
|
|
|
|
// if ( Aig_AigNodeIsChoice( pNode ) )
|
|
|
|
|
// {
|
|
|
|
|
// pIfMan->nChoices++;
|
|
|
|
|
// for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
|
|
|
|
|
// If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData );
|
|
|
|
|
// If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData );
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
Vec_PtrFree( vNodes );
|
|
|
|
|
return pIfMan;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Load the network into FPGA manager.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
If_Man_t * Ntk_ManToIf( Aig_Man_t * p, If_Par_t * pPars )
|
|
|
|
|
{
|
|
|
|
|
If_Man_t * pIfMan;
|
|
|
|
|
Aig_Obj_t * pNode;//, * pFanin, * pPrev;
|
|
|
|
|
int i;
|
|
|
|
|
// start the mapping manager and set its parameters
|
|
|
|
|
pIfMan = If_ManStart( pPars );
|
|
|
|
|
// print warning about excessive memory usage
|
|
|
|
|
if ( 1.0 * Aig_ManObjNum(p) * pIfMan->nObjBytes / (1<<30) > 1.0 )
|
|
|
|
|
printf( "Warning: The mapper will allocate %.1f Gb for to represent the subject graph with %d AIG nodes.\n",
|
|
|
|
|
1.0 * Aig_ManObjNum(p) * pIfMan->nObjBytes / (1<<30), Aig_ManObjNum(p) );
|
|
|
|
|
// load the AIG into the mapper
|
|
|
|
|
Aig_ManForEachObj( p, pNode, i )
|
|
|
|
|
{
|
|
|
|
|
if ( Aig_ObjIsAnd(pNode) )
|
|
|
|
|
pNode->pData = (Aig_Obj_t *)If_ManCreateAnd( pIfMan,
|
|
|
|
|
If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ),
|
|
|
|
|
If_NotCond( (If_Obj_t *)Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) );
|
|
|
|
|
else if ( Aig_ObjIsPi(pNode) )
|
|
|
|
|
{
|
|
|
|
|
pNode->pData = If_ManCreateCi( pIfMan );
|
|
|
|
|
((If_Obj_t *)pNode->pData)->Level = pNode->Level;
|
2008-03-26 16:01:00 +01:00
|
|
|
if ( pIfMan->nLevelMax < (int)pNode->Level )
|
|
|
|
|
pIfMan->nLevelMax = (int)pNode->Level;
|
2008-01-31 05:01:00 +01:00
|
|
|
}
|
|
|
|
|
else if ( Aig_ObjIsPo(pNode) )
|
|
|
|
|
If_ManCreateCo( pIfMan, If_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) );
|
|
|
|
|
else if ( Aig_ObjIsConst1(pNode) )
|
|
|
|
|
Aig_ManConst1(p)->pData = If_ManConst1( pIfMan );
|
|
|
|
|
else // add the node to the mapper
|
|
|
|
|
assert( 0 );
|
|
|
|
|
// set up the choice node
|
|
|
|
|
// if ( Aig_AigNodeIsChoice( pNode ) )
|
|
|
|
|
// {
|
|
|
|
|
// pIfMan->nChoices++;
|
|
|
|
|
// for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
|
|
|
|
|
// If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData );
|
|
|
|
|
// If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData );
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
return pIfMan;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Creates the mapped network.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Vec_Ptr_t * Ntk_ManFromIf( Aig_Man_t * p, If_Man_t * pMan )
|
|
|
|
|
{
|
|
|
|
|
Vec_Ptr_t * vIfMap;
|
|
|
|
|
If_Obj_t * pNode, * pLeaf;
|
|
|
|
|
If_Cut_t * pCutBest;
|
|
|
|
|
Vec_Ptr_t * vMapping;
|
|
|
|
|
Vec_Int_t * vIfToAig;
|
|
|
|
|
Aig_Obj_t * pObj;
|
|
|
|
|
Ntl_Lut_t * pLut;
|
|
|
|
|
int * ppLeaves;
|
|
|
|
|
int i, k, nLuts, nLeaves, nWords, nVarsMax;
|
|
|
|
|
// create mapping of If nodes into AIG nodes
|
|
|
|
|
vIfToAig = Vec_IntStart( Aig_ManObjNumMax(p) );
|
|
|
|
|
Vec_IntFill( vIfToAig, Aig_ManObjNumMax(p), -1 );
|
|
|
|
|
Aig_ManForEachObj( p, pObj, i )
|
|
|
|
|
{
|
|
|
|
|
if ( Aig_ObjIsPo(pObj) )
|
|
|
|
|
continue;
|
|
|
|
|
if ( Aig_ObjIsConst1(pObj) && pObj->pData == NULL )
|
|
|
|
|
continue;
|
|
|
|
|
if ( Aig_ObjIsPi(pObj) && pObj->pData == NULL )
|
|
|
|
|
continue;
|
|
|
|
|
pNode = pObj->pData;
|
|
|
|
|
assert( pNode != NULL );
|
|
|
|
|
Vec_IntWriteEntry( vIfToAig, pNode->Id, pObj->Id );
|
|
|
|
|
}
|
|
|
|
|
// create the mapping
|
|
|
|
|
vIfMap = If_ManCollectMappingDirect( pMan );
|
|
|
|
|
nVarsMax = pMan->pPars->nLutSize;
|
|
|
|
|
nWords = Aig_TruthWordNum( nVarsMax );
|
|
|
|
|
vMapping = Ntl_MappingAlloc( Vec_PtrSize(vIfMap) + (int)(Aig_ManConst1(p)->nRefs > 0), nVarsMax );
|
|
|
|
|
nLuts = 0;
|
|
|
|
|
if ( Aig_ManConst1(p)->nRefs > 0 )
|
|
|
|
|
{
|
|
|
|
|
pLut = Vec_PtrEntry( vMapping, nLuts++ );
|
|
|
|
|
pLut->Id = 0;
|
|
|
|
|
pLut->nFanins = 0;
|
|
|
|
|
memset( pLut->pTruth, 0xFF, 4 * nWords );
|
|
|
|
|
}
|
|
|
|
|
Vec_PtrForEachEntry( vIfMap, pNode, i )
|
|
|
|
|
{
|
|
|
|
|
// get the best cut
|
|
|
|
|
pCutBest = If_ObjCutBest(pNode);
|
|
|
|
|
nLeaves = If_CutLeaveNum( pCutBest );
|
|
|
|
|
ppLeaves = If_CutLeaves( pCutBest );
|
|
|
|
|
// fill the LUT
|
|
|
|
|
pLut = Vec_PtrEntry( vMapping, nLuts++ );
|
|
|
|
|
pLut->Id = Vec_IntEntry( vIfToAig, pNode->Id );
|
|
|
|
|
pLut->nFanins = nLeaves;
|
|
|
|
|
If_CutForEachLeaf( pMan, pCutBest, pLeaf, k )
|
|
|
|
|
pLut->pFanins[k] = Vec_IntEntry( vIfToAig, pLeaf->Id );
|
|
|
|
|
// compute the truth table
|
|
|
|
|
memcpy( pLut->pTruth, If_CutTruth(pCutBest), 4 * nWords );
|
|
|
|
|
}
|
|
|
|
|
assert( nLuts == Vec_PtrSize(vMapping) );
|
|
|
|
|
Vec_IntFree( vIfToAig );
|
|
|
|
|
Vec_PtrFree( vIfMap );
|
|
|
|
|
return vMapping;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Interface with the FPGA mapping package.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Vec_Ptr_t * Ntl_MappingIf( Ntl_Man_t * pMan, Aig_Man_t * p )
|
|
|
|
|
{
|
|
|
|
|
Vec_Ptr_t * vMapping;
|
|
|
|
|
If_Par_t Pars, * pPars = &Pars;
|
|
|
|
|
If_Man_t * pIfMan;
|
|
|
|
|
// perform FPGA mapping
|
|
|
|
|
Ntk_ManSetIfParsDefault( pPars );
|
|
|
|
|
// set the arrival times
|
|
|
|
|
pPars->pTimesArr = ALLOC( float, Aig_ManPiNum(p) );
|
|
|
|
|
memset( pPars->pTimesArr, 0, sizeof(float) * Aig_ManPiNum(p) );
|
|
|
|
|
// translate into the mapper
|
|
|
|
|
pIfMan = Ntk_ManToIf( p, pPars );
|
|
|
|
|
if ( pIfMan == NULL )
|
|
|
|
|
return NULL;
|
2008-03-26 16:01:00 +01:00
|
|
|
pIfMan->pManTim = Tim_ManDup( pMan->pManTime, 0 );
|
2008-01-31 05:01:00 +01:00
|
|
|
if ( !If_ManPerformMapping( pIfMan ) )
|
|
|
|
|
{
|
|
|
|
|
If_ManStop( pIfMan );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
// transform the result of mapping into the new network
|
|
|
|
|
vMapping = Ntk_ManFromIf( p, pIfMan );
|
|
|
|
|
If_ManStop( pIfMan );
|
|
|
|
|
if ( vMapping == NULL )
|
|
|
|
|
return NULL;
|
|
|
|
|
return vMapping;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// END OF FILE ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|