abc/src/base/seq/seqFpgaCore.c

580 lines
20 KiB
C
Raw Normal View History

2005-11-14 17:01:00 +01:00
/**CFile****************************************************************
FileName [seqFpgaCore.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 FPGA 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: seqFpgaCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
2005-11-20 17:01:00 +01:00
static Abc_Ntk_t * Seq_NtkFpgaDup( Abc_Ntk_t * pNtk );
2005-11-21 17:01:00 +01:00
static int Seq_NtkFpgaInitCompatible( Abc_Ntk_t * pNtk, int fVerbose );
2005-11-20 17:01:00 +01:00
static Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew );
static int Seq_FpgaMappingCount( Abc_Ntk_t * pNtk );
static int Seq_FpgaMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves );
static DdNode * Seq_FpgaMappingBdd_rec( DdManager * dd, Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves );
static void Seq_FpgaMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, Vec_Ptr_t * vLeaves, Vec_Vec_t * vMapEdges );
2005-11-21 17:01:00 +01:00
static Abc_Obj_t * Seq_FpgaMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsigned SeqEdge, int fTop, int LagCut, Vec_Ptr_t * vLeaves );
2005-11-14 17:01:00 +01:00
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs FPGA mapping and retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2005-11-20 17:01:00 +01:00
Abc_Ntk_t * Seq_NtkFpgaMapRetime( Abc_Ntk_t * pNtk, int fVerbose )
2005-11-14 17:01:00 +01:00
{
Abc_Ntk_t * pNtkNew;
Abc_Ntk_t * pNtkMap;
int RetValue;
2005-11-20 17:01:00 +01:00
// find the best mapping and retiming for all nodes (p->vLValues, p->vBestCuts, p->vLags)
Seq_FpgaMappingDelays( pNtk, fVerbose );
2005-11-14 17:01:00 +01:00
// duplicate the nodes contained in multiple cuts
2005-11-20 17:01:00 +01:00
pNtkNew = Seq_NtkFpgaDup( pNtk );
2005-11-21 17:01:00 +01:00
// return pNtkNew;
2005-11-20 17:01:00 +01:00
// implement the retiming
RetValue = Seq_NtkImplementRetiming( pNtkNew, ((Abc_Seq_t *)pNtkNew->pManFunc)->vLags, fVerbose );
2005-11-14 17:01:00 +01:00
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
2005-11-21 17:01:00 +01:00
// return pNtkNew;
2005-11-20 17:01:00 +01:00
// check the compatibility of initial states computed
2005-11-21 17:01:00 +01:00
if ( RetValue = Seq_NtkFpgaInitCompatible( pNtkNew, fVerbose ) )
2005-11-20 17:01:00 +01:00
{
printf( "The number of LUTs with incompatible edges = %d.\n", RetValue );
Abc_NtkDelete( pNtkNew );
return NULL;
}
2005-11-14 17:01:00 +01:00
// create the final mapped network
2005-11-20 17:01:00 +01:00
pNtkMap = Seq_NtkSeqFpgaMapped( pNtkNew );
2005-11-14 17:01:00 +01:00
Abc_NtkDelete( pNtkNew );
return pNtkMap;
}
/**Function*************************************************************
Synopsis [Derives the network by duplicating some of the nodes.]
2005-11-20 17:01:00 +01:00
Description [Information about mapping is given as mapping nodes (p->vMapAnds)
and best cuts for each node (p->vMapCuts).]
2005-11-14 17:01:00 +01:00
SideEffects []
SeeAlso []
***********************************************************************/
2005-11-20 17:01:00 +01:00
Abc_Ntk_t * Seq_NtkFpgaDup( Abc_Ntk_t * pNtk )
2005-11-14 17:01:00 +01:00
{
2005-11-20 17:01:00 +01:00
Abc_Seq_t * pNew, * p = pNtk->pManFunc;
2005-11-14 17:01:00 +01:00
Abc_Ntk_t * pNtkNew;
2005-11-20 17:01:00 +01:00
Abc_Obj_t * pObj, * pLeaf;
Vec_Ptr_t * vLeaves;
unsigned SeqEdge;
2005-11-21 17:01:00 +01:00
int i, k, nObjsNew, Lag;
2005-11-14 17:01:00 +01:00
assert( Abc_NtkIsSeq(pNtk) );
2005-11-20 17:01:00 +01:00
// start the expanded network
2005-11-14 17:01:00 +01:00
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// start the new sequential AIG manager
2005-11-20 17:01:00 +01:00
nObjsNew = 1 + Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Seq_FpgaMappingCount(pNtk);
Seq_Resize( pNtkNew->pManFunc, nObjsNew );
2005-11-14 17:01:00 +01:00
2005-11-20 17:01:00 +01:00
// duplicate the nodes in the mapping
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj );
// recursively construct the internals of each node
2005-11-14 17:01:00 +01:00
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
{
vLeaves = Vec_VecEntry( p->vMapCuts, i );
2005-11-21 17:01:00 +01:00
Seq_FpgaMappingBuild_rec( pNtkNew, pNtk, pObj->Id << 8, 1, Seq_NodeGetLag(pObj), vLeaves );
2005-11-14 17:01:00 +01:00
}
2005-11-20 17:01:00 +01:00
assert( nObjsNew == pNtkNew->nObjs );
2005-11-14 17:01:00 +01:00
// set the POs
2005-11-20 17:01:00 +01:00
Abc_NtkFinalize( pNtk, pNtkNew );
2005-11-21 17:01:00 +01:00
// duplicate the latches on the PO edges
Abc_NtkForEachPo( pNtk, pObj, i )
Seq_NodeDupLats( pObj->pCopy, pObj, 0 );
2005-11-20 17:01:00 +01:00
//Abc_NtkShowAig( pNtkNew );
// transfer the mapping info to the new manager
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
2005-11-14 17:01:00 +01:00
{
2005-11-20 17:01:00 +01:00
// convert the root node
Vec_PtrWriteEntry( p->vMapAnds, i, pObj->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 );
2005-11-21 17:01:00 +01:00
// Lag = (SeqEdge & 255);// + Seq_NodeGetLag(pObj) - Seq_NodeGetLag(pLeaf);
Lag = (SeqEdge & 255) + Seq_NodeGetLag(pObj) - Seq_NodeGetLag(pLeaf);
assert( Lag >= 0 );
2005-11-20 17:01:00 +01:00
// translate the old leaf into the leaf in the new network
2005-11-21 17:01:00 +01:00
Vec_PtrWriteEntry( vLeaves, k, (void *)((pLeaf->pCopy->Id << 8) | Lag) );
2005-11-20 17:01:00 +01:00
// printf( "%d -> %d\n", pLeaf->Id, pLeaf->pCopy->Id );
}
2005-11-14 17:01:00 +01:00
}
2005-11-20 17:01:00 +01:00
pNew = pNtkNew->pManFunc;
pNew->nVarsMax = p->nVarsMax;
pNew->vMapAnds = p->vMapAnds; p->vMapAnds = NULL;
pNew->vMapCuts = p->vMapCuts; p->vMapCuts = NULL;
2005-11-14 17:01:00 +01:00
if ( !Abc_NtkCheck( pNtkNew ) )
2005-11-20 17:01:00 +01:00
fprintf( stdout, "Seq_NtkFpgaDup(): Network check has failed.\n" );
2005-11-14 17:01:00 +01:00
return pNtkNew;
}
2005-11-20 17:01:00 +01:00
/**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 []
***********************************************************************/
2005-11-21 17:01:00 +01:00
int Seq_NtkFpgaInitCompatible( Abc_Ntk_t * pNtk, int fVerbose )
2005-11-20 17:01:00 +01:00
{
Abc_Seq_t * p = pNtk->pManFunc;
Abc_Obj_t * pAnd, * pLeaf, * pFanout0, * pFanout1;
Vec_Vec_t * vTotalEdges;
Vec_Ptr_t * vLeaves, * vEdges;
2005-11-21 17:01:00 +01:00
int i, k, m, Edge0, Edge1, nLatchAfter, nLatches1, nLatches2;
2005-11-20 17:01:00 +01:00
unsigned SeqEdge;
2005-11-21 17:01:00 +01:00
int CountBad = 0, CountAll = 0;
2005-11-20 17:01:00 +01:00
vTotalEdges = Vec_VecStart( p->nVarsMax );
// go through all the nodes (cuts) used in the mapping
Vec_PtrForEachEntry( p->vMapAnds, pAnd, i )
{
// printf( "*** Node %d.\n", pAnd->Id );
// get the cut of this gate
vLeaves = Vec_VecEntry( p->vMapCuts, i );
// get the edges pointing to the leaves
Vec_VecClear( vTotalEdges );
Seq_FpgaMappingEdges_rec( pNtk, pAnd->Id << 8, NULL, vLeaves, vTotalEdges );
// for each leaf, consider its edges
Vec_PtrForEachEntry( vLeaves, pLeaf, k )
{
SeqEdge = (unsigned)pLeaf;
pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
2005-11-21 17:01:00 +01:00
nLatchAfter = SeqEdge & 255;
2005-11-20 17:01:00 +01:00
if ( nLatchAfter == 0 )
continue;
// go through the edges
vEdges = Vec_VecEntry( vTotalEdges, k );
pFanout0 = NULL;
Vec_PtrForEachEntry( vEdges, pFanout1, m )
{
Edge1 = Abc_ObjIsComplement(pFanout1);
pFanout1 = Abc_ObjRegular(pFanout1);
//printf( "Fanin = %d. Fanout = %d.\n", pLeaf->Id, pFanout1->Id );
// make sure this is the same fanin
if ( Edge1 )
assert( pLeaf == Abc_ObjFanin1(pFanout1) );
else
assert( pLeaf == Abc_ObjFanin0(pFanout1) );
// save the first one
if ( pFanout0 == NULL )
{
pFanout0 = pFanout1;
Edge0 = Edge1;
continue;
}
// compare the rings
// if they have different number of latches, this is the bug
nLatches1 = Seq_NodeCountLats(pFanout0, Edge0);
nLatches2 = Seq_NodeCountLats(pFanout1, Edge1);
assert( nLatches1 == nLatches2 );
2005-11-21 17:01:00 +01:00
assert( nLatches1 == nLatchAfter );
2005-11-20 17:01:00 +01:00
assert( nLatches1 > 0 );
// if they have different initial states, this is the problem
if ( !Seq_NodeCompareLats(pFanout0, Edge0, pFanout1, Edge1) )
{
CountBad++;
break;
}
2005-11-21 17:01:00 +01:00
CountAll++;
2005-11-20 17:01:00 +01:00
}
}
}
2005-11-21 17:01:00 +01:00
if ( fVerbose )
printf( "The number of pairs of edges checked = %d.\n", CountAll );
2005-11-20 17:01:00 +01:00
Vec_VecFree( vTotalEdges );
return CountBad;
}
2005-11-14 17:01:00 +01:00
/**Function*************************************************************
Synopsis [Derives the final mapped network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2005-11-20 17:01:00 +01:00
Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtk )
2005-11-14 17:01:00 +01:00
{
2005-11-20 17:01:00 +01:00
Abc_Seq_t * p = pNtk->pManFunc;
Seq_Lat_t * pLat, * pRing;
2005-11-14 17:01:00 +01:00
Abc_Ntk_t * pNtkMap;
2005-11-20 17:01:00 +01:00
Vec_Vec_t * vTotalEdges;
Vec_Ptr_t * vLeaves, * vMapEdges;
Abc_Obj_t * pObj, * pAnd, * pLeaf, * pFanout, * pFanin, * pLatch;
2005-11-21 17:01:00 +01:00
int i, k, m, Edge, nLatches, nLatchAfter;
2005-11-20 17:01:00 +01:00
unsigned SeqEdge;
assert( Abc_NtkIsSeq(pNtk) );
// start the network
pNtkMap = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
// duplicate the nodes used in the mapping
Vec_PtrForEachEntry( p->vMapAnds, pAnd, i )
{
pAnd->pCopy = Abc_NtkCreateNode( pNtkMap );
// get the leaves of this gate
vLeaves = Vec_VecEntry( p->vMapCuts, i );
// get the BDD of the node
pAnd->pCopy->pData = Seq_FpgaMappingBdd_rec( pNtkMap->pManFunc, pNtk, pAnd->Id << 8, vLeaves );
Cudd_Ref( pAnd->pCopy->pData );
}
// construct nodes in the mapped network
vTotalEdges = Vec_VecStart( p->nVarsMax );
Vec_PtrForEachEntry( p->vMapAnds, pAnd, i )
{
// get the leaves of this gate
vLeaves = Vec_VecEntry( p->vMapCuts, i );
// get the edges pointing to the leaves
Vec_VecClear( vTotalEdges );
Seq_FpgaMappingEdges_rec( pNtk, pAnd->Id << 8, NULL, vLeaves, vTotalEdges );
// for each leaf, consider its edges
Vec_PtrForEachEntry( vLeaves, pLeaf, k )
{
SeqEdge = (unsigned)pLeaf;
pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
2005-11-21 17:01:00 +01:00
nLatchAfter = SeqEdge & 255;
2005-11-20 17:01:00 +01:00
if ( nLatchAfter == 0 )
{
// add the fanin
Abc_ObjAddFanin( pAnd->pCopy, pLeaf->pCopy );
continue;
}
// get the first edge
vMapEdges = Vec_VecEntry( vTotalEdges, k );
pFanout = Vec_PtrEntry( vMapEdges, 0 );
Edge = Abc_ObjIsComplement(pFanout);
pFanout = Abc_ObjRegular(pFanout);
// make sure this is the same fanin
if ( Edge )
assert( pLeaf == Abc_ObjFanin1(pFanout) );
else
assert( pLeaf == Abc_ObjFanin0(pFanout) );
nLatches = Seq_NodeCountLats(pFanout, Edge);
2005-11-21 17:01:00 +01:00
assert( nLatches == nLatchAfter );
2005-11-20 17:01:00 +01:00
assert( nLatches > 0 );
// for each implicit latch add the real latch
pFanin = pLeaf->pCopy;
pRing = Seq_NodeGetRing(pFanout, Edge);
for ( m = 0, pLat = Seq_LatPrev(pRing); m < nLatches; m++, pLat = Seq_LatPrev(pLat) )
{
pLatch = Abc_NtkCreateLatch( pNtkMap );
pLatch->pData = (void *)Seq_LatInit(pLat);
Abc_ObjAddFanin( pLatch, pFanin );
pFanin = pLatch;
}
// finally connect to the latch
Abc_ObjAddFanin( pAnd->pCopy, pFanin );
}
}
Vec_VecFree( vTotalEdges );
// set the POs
Abc_NtkForEachPo( pNtk, pObj, i )
{
pFanin = Abc_ObjFanin0(pObj)->pCopy;
2005-11-21 17:01:00 +01:00
nLatches = Seq_NodeCountLats(pObj, 0);
assert( nLatches == Seq_ObjFaninL0(pObj) );
if ( nLatches > 0 )
2005-11-20 17:01:00 +01:00
{
pRing = Seq_NodeGetRing(pObj, 0);
for ( m = 0, pLat = Seq_LatPrev(pRing); m < nLatches; m++, pLat = Seq_LatPrev(pLat) )
{
pLatch = Abc_NtkCreateLatch( pNtkMap );
pLatch->pData = (void *)Seq_LatInit(pLat);
Abc_ObjAddFanin( pLatch, pFanin );
pFanin = pLatch;
}
}
pFanin = Abc_ObjNotCond(pFanin, Abc_ObjFaninC0(pObj));
Abc_ObjAddFanin( pObj->pCopy, pFanin );
}
// add the latches and their names
Abc_NtkAddDummyLatchNames( pNtkMap );
Abc_NtkForEachLatch( pNtkMap, pLatch, i )
{
Vec_PtrPush( pNtkMap->vCis, pLatch );
Vec_PtrPush( pNtkMap->vCos, pLatch );
}
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkMap, 1 );
2005-11-14 17:01:00 +01:00
if ( !Abc_NtkCheck( pNtkMap ) )
fprintf( stdout, "Seq_NtkSeqFpgaMapped(): Network check has failed.\n" );
return pNtkMap;
}
2005-11-20 17:01:00 +01:00
/**Function*************************************************************
Synopsis [Counts the number of nodes in the bag.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_FpgaMappingCount( 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_FpgaMappingCount_rec( pNtk, pAnd->Id << 8, vLeaves );
}
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of nodes in the bag.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_FpgaMappingCount_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
2005-11-21 17:01:00 +01:00
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);
2005-11-20 17:01:00 +01:00
// call for the children
return 1 + Seq_FpgaMappingCount_rec( pNtk, SeqEdge0, vLeaves ) +
Seq_FpgaMappingCount_rec( pNtk, SeqEdge1, vLeaves );
}
/**Function*************************************************************
Synopsis [Derives the BDD of the selected cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode * Seq_FpgaMappingBdd_rec( DdManager * dd, Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves )
{
Abc_Obj_t * pObj, * pLeaf;
DdNode * bFunc0, * bFunc1, * bFunc;
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 Cudd_bddIthVar( dd, i );
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
// get new sequential edges
2005-11-21 17:01:00 +01:00
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);
2005-11-20 17:01:00 +01:00
// call for the children
bFunc0 = Seq_FpgaMappingBdd_rec( dd, pNtk, SeqEdge0, vLeaves ); Cudd_Ref( bFunc0 );
bFunc1 = Seq_FpgaMappingBdd_rec( dd, pNtk, SeqEdge1, vLeaves ); Cudd_Ref( bFunc1 );
2005-11-21 17:01:00 +01:00
bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pObj) );
bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pObj) );
2005-11-20 17:01:00 +01:00
// get the BDD of the node
2005-11-21 17:01:00 +01:00
bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc );
2005-11-20 17:01:00 +01:00
Cudd_RecursiveDeref( dd, bFunc0 );
Cudd_RecursiveDeref( dd, bFunc1 );
2005-11-21 17:01:00 +01:00
// complement the function if the node is created from the complimented cut
// ...
2005-11-20 17:01:00 +01:00
// return the BDD
Cudd_Deref( bFunc );
return bFunc;
}
/**Function*************************************************************
Synopsis [Collects the edges pointing to the leaves of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_FpgaMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, Vec_Ptr_t * vLeaves, Vec_Vec_t * vMapEdges )
{
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 )
{
assert( pPrev != NULL );
Vec_VecPush( vMapEdges, i, pPrev );
return;
}
}
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
// get new sequential edges
2005-11-21 17:01:00 +01:00
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);
2005-11-20 17:01:00 +01:00
// call for the children
Seq_FpgaMappingEdges_rec( pNtk, SeqEdge0, pObj , vLeaves, vMapEdges );
Seq_FpgaMappingEdges_rec( pNtk, SeqEdge1, Abc_ObjNot(pObj), vLeaves, vMapEdges );
}
/**Function*************************************************************
Synopsis [Collects the edges pointing to the leaves of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2005-11-21 17:01:00 +01:00
Abc_Obj_t * Seq_FpgaMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsigned SeqEdge, int fTop, int LagCut, Vec_Ptr_t * vLeaves )
2005-11-20 17:01:00 +01:00
{
Abc_Obj_t * pObj, * pObjNew, * pLeaf, * pFaninNew0, * pFaninNew1;
unsigned SeqEdge0, SeqEdge1;
2005-11-21 17:01:00 +01:00
int Lag, i;
2005-11-20 17:01:00 +01:00
// 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
2005-11-21 17:01:00 +01:00
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);
2005-11-20 17:01:00 +01:00
// call for the children
pObjNew = fTop? pObj->pCopy : Abc_NtkCreateNode( pNtkNew );
// solve subproblems
2005-11-21 17:01:00 +01:00
pFaninNew0 = Seq_FpgaMappingBuild_rec( pNtkNew, pNtk, SeqEdge0, 0, LagCut, vLeaves );
pFaninNew1 = Seq_FpgaMappingBuild_rec( pNtkNew, pNtk, SeqEdge1, 0, LagCut, vLeaves );
2005-11-20 17:01:00 +01:00
// 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
2005-11-21 17:01:00 +01:00
Seq_NodeSetLag( pObjNew, (char)(Lag + LagCut) );
// Seq_NodeSetLag( pObjNew, (char)(Lag) );
2005-11-20 17:01:00 +01:00
return pObjNew;
}
2005-11-14 17:01:00 +01:00
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////