2005-11-14 17:01:00 +01:00
|
|
|
/**CFile****************************************************************
|
|
|
|
|
|
|
|
|
|
FileName [seqMapCore.c]
|
|
|
|
|
|
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
|
|
|
|
|
|
PackageName [Construction and manipulation of sequential AIGs.]
|
|
|
|
|
|
2005-11-20 17:01:00 +01:00
|
|
|
Synopsis [The core of SC mapping/retiming package.]
|
2005-11-14 17:01:00 +01:00
|
|
|
|
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
|
|
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
|
|
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
|
|
|
|
|
|
Revision [$Id: seqMapCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "seqInt.h"
|
2005-11-26 17:01:00 +01:00
|
|
|
#include "main.h"
|
|
|
|
|
#include "mio.h"
|
|
|
|
|
#include "mapper.h"
|
2005-11-14 17:01:00 +01:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// DECLARATIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2005-11-26 17:01:00 +01:00
|
|
|
extern Abc_Ntk_t * Seq_NtkMapDup( Abc_Ntk_t * pNtk );
|
|
|
|
|
extern int Seq_NtkMapInitCompatible( Abc_Ntk_t * pNtk, int fVerbose );
|
|
|
|
|
extern Abc_Ntk_t * Seq_NtkSeqMapMapped( Abc_Ntk_t * pNtk );
|
|
|
|
|
|
|
|
|
|
static int Seq_MapMappingCount( Abc_Ntk_t * pNtk );
|
|
|
|
|
static int Seq_MapMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves );
|
|
|
|
|
static Abc_Obj_t * Seq_MapMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsigned SeqEdge, int fTop, int LagCut, Vec_Ptr_t * vLeaves );
|
|
|
|
|
static DdNode * Seq_MapMappingBdd_rec( DdManager * dd, Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves );
|
|
|
|
|
static void Seq_MapMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, Vec_Ptr_t * vLeaves, Vec_Vec_t * vMapEdges );
|
|
|
|
|
static void Seq_MapMappingConnect_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, int Edge, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves );
|
|
|
|
|
static DdNode * Seq_MapMappingConnectBdd_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, int Edge, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves );
|
|
|
|
|
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// FUNCTION DEFINITIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
2005-11-26 17:01:00 +01:00
|
|
|
Synopsis [Performs Map mapping and retiming.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Abc_Ntk_t * Seq_MapRetime( Abc_Ntk_t * pNtk, int nMaxIters, int fVerbose )
|
|
|
|
|
{
|
|
|
|
|
Abc_Seq_t * p = pNtk->pManFunc;
|
|
|
|
|
Abc_Ntk_t * pNtkNew;
|
|
|
|
|
Abc_Ntk_t * pNtkMap;
|
|
|
|
|
int RetValue;
|
|
|
|
|
|
|
|
|
|
// derive the supergate library
|
|
|
|
|
if ( Abc_FrameReadLibSuper() == NULL && Abc_FrameReadLibGen() )
|
|
|
|
|
{
|
|
|
|
|
printf( "A simple supergate library is derived from gate library \"%s\".\n",
|
|
|
|
|
Mio_LibraryReadName(Abc_FrameReadLibGen()) );
|
|
|
|
|
Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen() );
|
|
|
|
|
}
|
|
|
|
|
p->pSuperLib = Abc_FrameReadLibSuper();
|
|
|
|
|
p->nVarsMax = Map_SuperLibReadVarsMax(p->pSuperLib);
|
|
|
|
|
p->nMaxIters = nMaxIters;
|
|
|
|
|
p->fStandCells = 1;
|
|
|
|
|
|
|
|
|
|
// find the best mapping and retiming for all nodes (p->vLValues, p->vBestCuts, p->vLags)
|
|
|
|
|
Seq_MapRetimeDelayLags( pNtk, fVerbose );
|
|
|
|
|
if ( RetValue = Abc_NtkGetChoiceNum(pNtk) )
|
|
|
|
|
{
|
|
|
|
|
printf( "The network has %d choices. Deriving the resulting network is skipped.\n", RetValue );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
// duplicate the nodes contained in multiple cuts
|
|
|
|
|
pNtkNew = Seq_NtkMapDup( pNtk );
|
|
|
|
|
// return pNtkNew;
|
|
|
|
|
|
|
|
|
|
// implement the retiming
|
|
|
|
|
RetValue = Seq_NtkImplementRetiming( pNtkNew, ((Abc_Seq_t *)pNtkNew->pManFunc)->vLags, fVerbose );
|
|
|
|
|
if ( RetValue == 0 )
|
|
|
|
|
printf( "Retiming completed but initial state computation has failed.\n" );
|
|
|
|
|
// return pNtkNew;
|
|
|
|
|
|
|
|
|
|
// check the compatibility of initial states computed
|
|
|
|
|
if ( RetValue = Seq_NtkMapInitCompatible( pNtkNew, fVerbose ) )
|
|
|
|
|
{
|
|
|
|
|
printf( "The number of LUTs with incompatible edges = %d.\n", RetValue );
|
|
|
|
|
Abc_NtkDelete( pNtkNew );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create the final mapped network
|
|
|
|
|
pNtkMap = Seq_NtkSeqMapMapped( pNtkNew );
|
|
|
|
|
Abc_NtkDelete( pNtkNew );
|
|
|
|
|
return pNtkMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Derives the network by duplicating some of the nodes.]
|
|
|
|
|
|
|
|
|
|
Description [Information about mapping is given as mapping nodes (p->vMapAnds)
|
|
|
|
|
and best cuts for each node (p->vMapCuts).]
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Abc_Ntk_t * Seq_NtkMapDup( Abc_Ntk_t * pNtk )
|
|
|
|
|
{
|
|
|
|
|
Abc_Seq_t * pNew, * p = pNtk->pManFunc;
|
|
|
|
|
Seq_Match_t * pMatch;
|
|
|
|
|
Abc_Ntk_t * pNtkNew;
|
|
|
|
|
Abc_Obj_t * pObj, * pLeaf, * pDriver, * pDriverNew;
|
|
|
|
|
Vec_Ptr_t * vLeaves;
|
|
|
|
|
unsigned SeqEdge;
|
|
|
|
|
int i, k, nObjsNew, Lag;
|
|
|
|
|
|
|
|
|
|
assert( Abc_NtkIsSeq(pNtk) );
|
|
|
|
|
|
|
|
|
|
// start the expanded network
|
|
|
|
|
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
|
|
|
|
|
Abc_NtkCleanNext( pNtk );
|
|
|
|
|
|
|
|
|
|
// start the new sequential AIG manager
|
|
|
|
|
nObjsNew = 1 + Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Seq_MapMappingCount(pNtk);
|
|
|
|
|
Seq_Resize( pNtkNew->pManFunc, nObjsNew );
|
|
|
|
|
|
|
|
|
|
// duplicate the nodes in the mapping
|
|
|
|
|
Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
|
|
|
|
|
if ( pMatch->fCompl )
|
|
|
|
|
pMatch->pAnd->pNext = Abc_NtkCreateNode( pNtkNew );
|
|
|
|
|
else
|
|
|
|
|
pMatch->pAnd->pCopy = Abc_NtkCreateNode( pNtkNew );
|
|
|
|
|
|
|
|
|
|
// recursively construct the internals of each node
|
|
|
|
|
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
|
|
|
|
|
{
|
|
|
|
|
vLeaves = Vec_VecEntry( p->vMapCuts, i );
|
|
|
|
|
Seq_MapMappingBuild_rec( pNtkNew, pNtk, pObj->Id << 8, 1, Seq_NodeGetLag(pObj), vLeaves );
|
|
|
|
|
}
|
|
|
|
|
assert( nObjsNew == pNtkNew->nObjs );
|
|
|
|
|
|
|
|
|
|
// set the POs
|
|
|
|
|
Abc_NtkForEachCo( pNtk, pObj, i )
|
|
|
|
|
{
|
|
|
|
|
pDriver = Abc_ObjFanin0(pObj);
|
|
|
|
|
pDriverNew = Abc_ObjFaninC0(pObj)? pDriver->pNext : pDriver->pCopy;
|
|
|
|
|
Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// duplicate the latches on the PO edges
|
|
|
|
|
Abc_NtkForEachPo( pNtk, pObj, i )
|
|
|
|
|
Seq_NodeDupLats( pObj->pCopy, pObj, 0 );
|
|
|
|
|
|
|
|
|
|
// transfer the mapping info to the new manager
|
|
|
|
|
Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
|
|
|
|
|
{
|
|
|
|
|
// convert the root node
|
|
|
|
|
// Vec_PtrWriteEntry( p->vMapAnds, i, pObj->pCopy );
|
|
|
|
|
pMatch->pAnd = pMatch->pAnd->pCopy;
|
|
|
|
|
// get the leaves of the cut
|
|
|
|
|
vLeaves = Vec_VecEntry( p->vMapCuts, i );
|
|
|
|
|
// convert the leaf nodes
|
|
|
|
|
Vec_PtrForEachEntry( vLeaves, pLeaf, k )
|
|
|
|
|
{
|
|
|
|
|
SeqEdge = (unsigned)pLeaf;
|
|
|
|
|
pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
|
|
|
|
// Lag = (SeqEdge & 255);// + Seq_NodeGetLag(pObj) - Seq_NodeGetLag(pLeaf);
|
|
|
|
|
Lag = (SeqEdge & 255) + Seq_NodeGetLag(pObj) - Seq_NodeGetLag(pLeaf);
|
|
|
|
|
assert( Lag >= 0 );
|
|
|
|
|
// translate the old leaf into the leaf in the new network
|
|
|
|
|
Vec_PtrWriteEntry( vLeaves, k, (void *)((pLeaf->pCopy->Id << 8) | Lag) );
|
|
|
|
|
// printf( "%d -> %d\n", pLeaf->Id, pLeaf->pCopy->Id );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pNew = pNtkNew->pManFunc;
|
|
|
|
|
pNew->nVarsMax = p->nVarsMax;
|
|
|
|
|
pNew->vMapAnds = p->vMapAnds; p->vMapAnds = NULL;
|
|
|
|
|
pNew->vMapCuts = p->vMapCuts; p->vMapCuts = NULL;
|
|
|
|
|
|
|
|
|
|
if ( !Abc_NtkCheck( pNtkNew ) )
|
|
|
|
|
fprintf( stdout, "Seq_NtkMapDup(): Network check has failed.\n" );
|
|
|
|
|
return pNtkNew;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Checks if the initial states are compatible.]
|
|
|
|
|
|
|
|
|
|
Description [Checks of all the initial states on the fanins edges
|
|
|
|
|
of the cut have compatible number of latches and initial states.
|
|
|
|
|
If this is not true, then the mapped network with the does not have initial
|
|
|
|
|
state. Returns the number of LUTs with incompatible edges.]
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Seq_NtkMapInitCompatible( Abc_Ntk_t * pNtk, int fVerbose )
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Derives the final mapped network.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Abc_Ntk_t * Seq_NtkSeqMapMapped( Abc_Ntk_t * pNtk )
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Counts the number of nodes in the bag.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Seq_MapMappingCount( Abc_Ntk_t * pNtk )
|
|
|
|
|
{
|
|
|
|
|
Abc_Seq_t * p = pNtk->pManFunc;
|
|
|
|
|
Vec_Ptr_t * vLeaves;
|
|
|
|
|
Abc_Obj_t * pAnd;
|
|
|
|
|
int i, Counter = 0;
|
|
|
|
|
Vec_PtrForEachEntry( p->vMapAnds, pAnd, i )
|
|
|
|
|
{
|
|
|
|
|
vLeaves = Vec_VecEntry( p->vMapCuts, i );
|
|
|
|
|
Counter += Seq_MapMappingCount_rec( pNtk, pAnd->Id << 8, vLeaves );
|
|
|
|
|
}
|
|
|
|
|
return Counter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Counts the number of nodes in the bag.]
|
2005-11-14 17:01:00 +01:00
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2005-11-26 17:01:00 +01:00
|
|
|
int Seq_MapMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves )
|
|
|
|
|
{
|
|
|
|
|
Abc_Obj_t * pObj, * pLeaf;
|
|
|
|
|
unsigned SeqEdge0, SeqEdge1;
|
|
|
|
|
int Lag, i;
|
|
|
|
|
// get the object and the lag
|
|
|
|
|
pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
|
|
|
|
Lag = SeqEdge & 255;
|
|
|
|
|
// if the node is the fanin of the cut, return
|
|
|
|
|
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
|
|
|
|
|
if ( SeqEdge == (unsigned)pLeaf )
|
|
|
|
|
return 0;
|
|
|
|
|
// continue unfolding
|
|
|
|
|
assert( Abc_NodeIsAigAnd(pObj) );
|
|
|
|
|
// get new sequential edges
|
|
|
|
|
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
|
|
|
|
|
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
|
|
|
|
|
SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Seq_ObjFaninL0(pObj);
|
|
|
|
|
SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Seq_ObjFaninL1(pObj);
|
|
|
|
|
// call for the children
|
|
|
|
|
return 1 + Seq_MapMappingCount_rec( pNtk, SeqEdge0, vLeaves ) +
|
|
|
|
|
Seq_MapMappingCount_rec( pNtk, SeqEdge1, vLeaves );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Collects the edges pointing to the leaves of the cut.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Abc_Obj_t * Seq_MapMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsigned SeqEdge, int fTop, int LagCut, Vec_Ptr_t * vLeaves )
|
|
|
|
|
{
|
|
|
|
|
Abc_Obj_t * pObj, * pObjNew, * pLeaf, * pFaninNew0, * pFaninNew1;
|
|
|
|
|
unsigned SeqEdge0, SeqEdge1;
|
|
|
|
|
int Lag, i;
|
|
|
|
|
// get the object and the lag
|
|
|
|
|
pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
|
|
|
|
Lag = SeqEdge & 255;
|
|
|
|
|
// if the node is the fanin of the cut, return
|
|
|
|
|
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
|
|
|
|
|
if ( SeqEdge == (unsigned)pLeaf )
|
|
|
|
|
return pObj->pCopy;
|
|
|
|
|
// continue unfolding
|
|
|
|
|
assert( Abc_NodeIsAigAnd(pObj) );
|
|
|
|
|
// get new sequential edges
|
|
|
|
|
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
|
|
|
|
|
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
|
|
|
|
|
SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Seq_ObjFaninL0(pObj);
|
|
|
|
|
SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Seq_ObjFaninL1(pObj);
|
|
|
|
|
// call for the children
|
|
|
|
|
pObjNew = fTop? pObj->pCopy : Abc_NtkCreateNode( pNtkNew );
|
|
|
|
|
// solve subproblems
|
|
|
|
|
pFaninNew0 = Seq_MapMappingBuild_rec( pNtkNew, pNtk, SeqEdge0, 0, LagCut, vLeaves );
|
|
|
|
|
pFaninNew1 = Seq_MapMappingBuild_rec( pNtkNew, pNtk, SeqEdge1, 0, LagCut, vLeaves );
|
|
|
|
|
// add the fanins to the node
|
|
|
|
|
Abc_ObjAddFanin( pObjNew, Abc_ObjNotCond( pFaninNew0, Abc_ObjFaninC0(pObj) ) );
|
|
|
|
|
Abc_ObjAddFanin( pObjNew, Abc_ObjNotCond( pFaninNew1, Abc_ObjFaninC1(pObj) ) );
|
|
|
|
|
Seq_NodeDupLats( pObjNew, pObj, 0 );
|
|
|
|
|
Seq_NodeDupLats( pObjNew, pObj, 1 );
|
|
|
|
|
// set the lag of the new node equal to the internal lag plus mapping/retiming lag
|
|
|
|
|
Seq_NodeSetLag( pObjNew, (char)(Lag + LagCut) );
|
|
|
|
|
// Seq_NodeSetLag( pObjNew, (char)(Lag) );
|
|
|
|
|
return pObjNew;
|
|
|
|
|
}
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// END OF FILE ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|