2005-08-13 17:01:00 +02:00
|
|
|
/**CFile****************************************************************
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
FileName [seqCreate.c]
|
2005-08-13 17:01:00 +02:00
|
|
|
|
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
PackageName [Construction and manipulation of sequential AIGs.]
|
2005-08-13 17:01:00 +02:00
|
|
|
|
2005-11-20 17:01:00 +01:00
|
|
|
Synopsis [Transformations to and from the sequential AIG.]
|
2005-08-13 17:01:00 +02:00
|
|
|
|
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
|
|
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
|
|
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
Revision [$Id: seqCreate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
2005-08-13 17:01:00 +02:00
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
#include "seqInt.h"
|
2005-08-13 17:01:00 +02:00
|
|
|
|
|
|
|
|
/*
|
2005-09-11 17:01:00 +02:00
|
|
|
A sequential network is similar to AIG in that it contains only
|
|
|
|
|
AND gates. However, the AND-gates are currently not hashed.
|
2005-09-12 17:01:00 +02:00
|
|
|
|
|
|
|
|
When converting AIG into sequential AIG:
|
|
|
|
|
- Const1/PIs/POs remain the same as in the original AIG.
|
|
|
|
|
- Instead of the latches, a new cutset is added, which is currently
|
|
|
|
|
defined as a set of AND gates that have a latch among their fanouts.
|
|
|
|
|
- The edges of a sequential AIG are labeled with latch attributes
|
|
|
|
|
in addition to the complementation attibutes.
|
|
|
|
|
- The attributes contain information about the number of latches
|
2005-09-16 17:01:00 +02:00
|
|
|
and their initial states.
|
2005-09-12 17:01:00 +02:00
|
|
|
- The number of latches is stored directly on the edges. The initial
|
2005-11-14 17:01:00 +01:00
|
|
|
states are stored in the sequential AIG manager.
|
2005-09-12 17:01:00 +02:00
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
In the current version of the code, the sequential AIG is static
|
|
|
|
|
in the sense that the new AIG nodes are never created.
|
2005-09-11 17:01:00 +02:00
|
|
|
The retiming (or retiming/mapping) is performed by moving the
|
|
|
|
|
latches over the static nodes of the AIG.
|
2005-11-14 17:01:00 +01:00
|
|
|
The new initial state after backward retiming is computed
|
|
|
|
|
by setting up and solving a SAT problem.
|
2005-08-13 17:01:00 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// DECLARATIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
static Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge, Vec_Int_t * vInitValues );
|
|
|
|
|
static void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk );
|
|
|
|
|
static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, Seq_Lat_t * pRing, int nLatches );
|
2005-08-13 17:01:00 +02:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
2005-10-12 17:01:00 +02:00
|
|
|
/// FUNCTION DEFINITIONS ///
|
2005-08-13 17:01:00 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
|
2005-08-13 17:01:00 +02:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
2005-09-12 17:01:00 +02:00
|
|
|
Synopsis [Converts combinational AIG with latches into sequential AIG.]
|
2005-08-13 17:01:00 +02:00
|
|
|
|
2005-09-11 17:01:00 +02:00
|
|
|
Description [The const/PI/PO nodes are duplicated. The internal
|
|
|
|
|
nodes are duplicated in the topological order. The dangling nodes
|
2005-09-12 17:01:00 +02:00
|
|
|
are not duplicated. The choice nodes are duplicated.]
|
2005-08-13 17:01:00 +02:00
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk )
|
|
|
|
|
{
|
|
|
|
|
Abc_Ntk_t * pNtkNew;
|
2005-09-15 17:01:00 +02:00
|
|
|
Abc_Obj_t * pObj, * pFaninNew;
|
2005-11-14 17:01:00 +01:00
|
|
|
Vec_Int_t * vInitValues;
|
|
|
|
|
Abc_InitType_t Init;
|
|
|
|
|
int i, k;
|
|
|
|
|
|
2005-09-11 17:01:00 +02:00
|
|
|
// make sure it is an AIG without self-feeding latches
|
2005-08-29 17:01:00 +02:00
|
|
|
assert( Abc_NtkIsStrash(pNtk) );
|
2005-09-11 17:01:00 +02:00
|
|
|
assert( Abc_NtkCountSelfFeedLatches(pNtk) == 0 );
|
2005-11-14 17:01:00 +01:00
|
|
|
assert( Abc_NtkIsDfsOrdered(pNtk) );
|
|
|
|
|
|
2005-08-13 17:01:00 +02:00
|
|
|
// start the network
|
2005-09-13 17:01:00 +02:00
|
|
|
pNtkNew = Abc_NtkAlloc( ABC_NTK_SEQ, ABC_FUNC_AIG );
|
2005-09-11 17:01:00 +02:00
|
|
|
// duplicate the name and the spec
|
|
|
|
|
pNtkNew->pName = util_strsav(pNtk->pName);
|
|
|
|
|
pNtkNew->pSpec = util_strsav(pNtk->pSpec);
|
2005-11-14 17:01:00 +01:00
|
|
|
|
|
|
|
|
// map the constant nodes
|
|
|
|
|
Abc_NtkCleanCopy( pNtk );
|
|
|
|
|
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
|
|
|
|
|
|
|
|
|
|
// copy all objects, except the latches and constant
|
|
|
|
|
Vec_PtrFill( pNtkNew->vObjs, Abc_NtkObjNumMax(pNtk), NULL );
|
|
|
|
|
Vec_PtrWriteEntry( pNtkNew->vObjs, 0, Abc_NtkConst1(pNtk)->pCopy );
|
|
|
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
|
|
|
|
{
|
|
|
|
|
if ( i == 0 || Abc_ObjIsLatch(pObj) )
|
|
|
|
|
continue;
|
|
|
|
|
pObj->pCopy = Abc_ObjAlloc( pNtkNew, pObj->Type );
|
2005-11-20 17:01:00 +01:00
|
|
|
pObj->pCopy->Id = pObj->Id; // the ID is the same for both
|
|
|
|
|
pObj->pCopy->fPhase = pObj->fPhase; // used to work with choices
|
|
|
|
|
pObj->pCopy->Level = pObj->Level; // used for upper bound on clock cycle
|
2005-11-14 17:01:00 +01:00
|
|
|
Vec_PtrWriteEntry( pNtkNew->vObjs, pObj->pCopy->Id, pObj->pCopy );
|
|
|
|
|
pNtkNew->nObjs++;
|
|
|
|
|
}
|
|
|
|
|
pNtkNew->nNodes = pNtk->nNodes;
|
|
|
|
|
pNtkNew->nPis = pNtk->nPis;
|
|
|
|
|
pNtkNew->nPos = pNtk->nPos;
|
|
|
|
|
|
|
|
|
|
// create PI/PO and their names
|
2005-09-11 17:01:00 +02:00
|
|
|
Abc_NtkForEachPi( pNtk, pObj, i )
|
2005-11-14 17:01:00 +01:00
|
|
|
{
|
|
|
|
|
Vec_PtrPush( pNtkNew->vCis, pObj->pCopy );
|
|
|
|
|
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
|
|
|
|
|
}
|
2005-09-11 17:01:00 +02:00
|
|
|
Abc_NtkForEachPo( pNtk, pObj, i )
|
2005-09-12 17:01:00 +02:00
|
|
|
{
|
2005-11-14 17:01:00 +01:00
|
|
|
Vec_PtrPush( pNtkNew->vCos, pObj->pCopy );
|
|
|
|
|
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
|
2005-09-12 17:01:00 +02:00
|
|
|
}
|
2005-11-14 17:01:00 +01:00
|
|
|
|
2005-09-12 17:01:00 +02:00
|
|
|
// relink the choice nodes
|
2005-11-14 17:01:00 +01:00
|
|
|
Abc_AigForEachAnd( pNtk, pObj, i )
|
2005-09-12 17:01:00 +02:00
|
|
|
if ( pObj->pData )
|
|
|
|
|
pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
|
2005-11-14 17:01:00 +01:00
|
|
|
|
2005-09-11 17:01:00 +02:00
|
|
|
// start the storage for initial states
|
2005-11-14 17:01:00 +01:00
|
|
|
Seq_Resize( pNtkNew->pManFunc, Abc_NtkObjNumMax(pNtkNew) );
|
2005-09-11 17:01:00 +02:00
|
|
|
// reconnect the internal nodes
|
2005-11-14 17:01:00 +01:00
|
|
|
vInitValues = Vec_IntAlloc( 100 );
|
2005-09-12 17:01:00 +02:00
|
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
2005-08-14 17:01:00 +02:00
|
|
|
{
|
2005-11-14 17:01:00 +01:00
|
|
|
// skip constants, PIs, and latches
|
|
|
|
|
if ( Abc_ObjFaninNum(pObj) == 0 || Abc_ObjIsLatch(pObj) )
|
2005-09-15 17:01:00 +02:00
|
|
|
continue;
|
2005-09-12 17:01:00 +02:00
|
|
|
// process the first fanin
|
2005-11-14 17:01:00 +01:00
|
|
|
Vec_IntClear( vInitValues );
|
|
|
|
|
pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 0, vInitValues );
|
2005-09-15 17:01:00 +02:00
|
|
|
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
2005-11-14 17:01:00 +01:00
|
|
|
// store the initial values
|
|
|
|
|
Vec_IntForEachEntry( vInitValues, Init, k )
|
|
|
|
|
Seq_NodeInsertFirst( pObj->pCopy, 0, Init );
|
|
|
|
|
// skip single-input nodes
|
2005-09-12 17:01:00 +02:00
|
|
|
if ( Abc_ObjFaninNum(pObj) == 1 )
|
|
|
|
|
continue;
|
|
|
|
|
// process the second fanin
|
2005-11-14 17:01:00 +01:00
|
|
|
Vec_IntClear( vInitValues );
|
|
|
|
|
pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 1, vInitValues );
|
2005-09-15 17:01:00 +02:00
|
|
|
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
2005-11-14 17:01:00 +01:00
|
|
|
// store the initial values
|
|
|
|
|
Vec_IntForEachEntry( vInitValues, Init, k )
|
|
|
|
|
Seq_NodeInsertFirst( pObj->pCopy, 1, Init );
|
2005-08-14 17:01:00 +02:00
|
|
|
}
|
2005-11-14 17:01:00 +01:00
|
|
|
Vec_IntFree( vInitValues );
|
|
|
|
|
|
2005-09-11 17:01:00 +02:00
|
|
|
// set the cutset composed of latch drivers
|
2005-11-14 17:01:00 +01:00
|
|
|
Abc_NtkAigCutsetCopy( pNtk );
|
2005-11-21 17:01:00 +01:00
|
|
|
Seq_NtkLatchGetEqualFaninNum( pNtkNew );
|
2005-11-14 17:01:00 +01:00
|
|
|
|
2005-09-11 17:01:00 +02:00
|
|
|
// copy EXDC and check correctness
|
|
|
|
|
if ( pNtkNew->pExdc )
|
2005-11-14 17:01:00 +01:00
|
|
|
fprintf( stdout, "Warning: EXDC is not copied when converting to sequential AIG.\n" );
|
2005-09-05 17:01:00 +02:00
|
|
|
if ( !Abc_NtkCheck( pNtkNew ) )
|
2005-08-14 17:01:00 +02:00
|
|
|
fprintf( stdout, "Abc_NtkAigToSeq(): Network check has failed.\n" );
|
2005-08-13 17:01:00 +02:00
|
|
|
return pNtkNew;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
2005-09-11 17:01:00 +02:00
|
|
|
Synopsis [Determines the fanin that is transparent for latches.]
|
2005-08-13 17:01:00 +02:00
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2005-11-14 17:01:00 +01:00
|
|
|
Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge, Vec_Int_t * vInitValues )
|
2005-08-13 17:01:00 +02:00
|
|
|
{
|
2005-09-15 17:01:00 +02:00
|
|
|
Abc_Obj_t * pFanin, * pFaninNew;
|
2005-09-12 17:01:00 +02:00
|
|
|
Abc_InitType_t Init;
|
2005-09-11 17:01:00 +02:00
|
|
|
// get the given fanin of the node
|
2005-11-14 17:01:00 +01:00
|
|
|
pFanin = Abc_ObjFanin( pObj, Edge );
|
2005-09-15 17:01:00 +02:00
|
|
|
// if fanin is the internal node, return its copy in the corresponding polarity
|
2005-09-11 17:01:00 +02:00
|
|
|
if ( !Abc_ObjIsLatch(pFanin) )
|
2005-11-14 17:01:00 +01:00
|
|
|
return Abc_ObjNotCond( pFanin->pCopy, Abc_ObjFaninC(pObj, Edge) );
|
2005-09-15 17:01:00 +02:00
|
|
|
// fanin is a latch
|
|
|
|
|
// get the new fanins
|
2005-11-14 17:01:00 +01:00
|
|
|
pFaninNew = Abc_NodeAigToSeq( pObjNew, pFanin, 0, vInitValues );
|
2005-09-15 17:01:00 +02:00
|
|
|
// get the initial state
|
|
|
|
|
Init = Abc_LatchInit(pFanin);
|
2005-09-11 17:01:00 +02:00
|
|
|
// complement the initial state if the inv is retimed over the latch
|
2005-09-15 17:01:00 +02:00
|
|
|
if ( Abc_ObjIsComplement(pFaninNew) )
|
2005-09-12 17:01:00 +02:00
|
|
|
{
|
|
|
|
|
if ( Init == ABC_INIT_ZERO )
|
|
|
|
|
Init = ABC_INIT_ONE;
|
|
|
|
|
else if ( Init == ABC_INIT_ONE )
|
|
|
|
|
Init = ABC_INIT_ZERO;
|
|
|
|
|
else if ( Init != ABC_INIT_DC )
|
|
|
|
|
assert( 0 );
|
|
|
|
|
}
|
2005-11-14 17:01:00 +01:00
|
|
|
// record the initial state
|
|
|
|
|
Vec_IntPush( vInitValues, Init );
|
|
|
|
|
return Abc_ObjNotCond( pFaninNew, Abc_ObjFaninC(pObj, Edge) );
|
2005-08-13 17:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
/**Function*************************************************************
|
2005-08-13 17:01:00 +02:00
|
|
|
|
2005-11-14 17:01:00 +01:00
|
|
|
Synopsis [Collects the cut set nodes.]
|
|
|
|
|
|
|
|
|
|
Description [These are internal AND gates that have latch fanouts.]
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk )
|
|
|
|
|
{
|
|
|
|
|
Abc_Obj_t * pLatch, * pDriver, * pDriverNew;
|
|
|
|
|
int i;
|
|
|
|
|
Abc_NtkIncrementTravId(pNtk);
|
|
|
|
|
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
|
|
|
|
{
|
|
|
|
|
pDriver = Abc_ObjFanin0(pLatch);
|
|
|
|
|
if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_NodeIsAigAnd(pDriver) )
|
|
|
|
|
continue;
|
|
|
|
|
Abc_NodeSetTravIdCurrent(pDriver);
|
|
|
|
|
pDriverNew = pDriver->pCopy;
|
|
|
|
|
Vec_PtrPush( pDriverNew->pNtk->vCutSet, pDriverNew );
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-09-12 17:01:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Converts a sequential AIG into a logic SOP network.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
|
|
|
|
|
{
|
|
|
|
|
Abc_Ntk_t * pNtkNew;
|
2005-11-14 17:01:00 +01:00
|
|
|
Abc_Obj_t * pObj, * pObjNew, * pFaninNew;
|
|
|
|
|
int i;
|
2005-09-15 17:01:00 +02:00
|
|
|
|
2005-09-12 17:01:00 +02:00
|
|
|
assert( Abc_NtkIsSeq(pNtk) );
|
|
|
|
|
// start the network without latches
|
2005-09-13 17:01:00 +02:00
|
|
|
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
2005-09-15 17:01:00 +02:00
|
|
|
|
2005-09-12 17:01:00 +02:00
|
|
|
// duplicate the nodes, create node functions
|
|
|
|
|
Abc_NtkForEachNode( pNtk, pObj, i )
|
|
|
|
|
{
|
|
|
|
|
// skip the constant
|
|
|
|
|
if ( Abc_ObjFaninNum(pObj) == 0 )
|
|
|
|
|
continue;
|
|
|
|
|
// duplicate the node
|
|
|
|
|
Abc_NtkDupObj(pNtkNew, pObj);
|
|
|
|
|
if ( Abc_ObjFaninNum(pObj) == 1 )
|
|
|
|
|
{
|
|
|
|
|
assert( !Abc_ObjFaninC0(pObj) );
|
|
|
|
|
pObj->pCopy->pData = Abc_SopCreateBuf( pNtkNew->pManFunc );
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
pObj->pCopy->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
|
|
|
|
}
|
|
|
|
|
// connect the objects
|
|
|
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
|
|
|
|
{
|
2005-09-15 17:01:00 +02:00
|
|
|
assert( (int)pObj->Id == i );
|
2005-09-12 17:01:00 +02:00
|
|
|
// skip PIs and the constant
|
|
|
|
|
if ( Abc_ObjFaninNum(pObj) == 0 )
|
|
|
|
|
continue;
|
|
|
|
|
// create the edge
|
2005-11-21 17:01:00 +01:00
|
|
|
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin0(pObj), Seq_NodeGetRing(pObj,0), Seq_ObjFaninL0(pObj) );
|
2005-09-12 17:01:00 +02:00
|
|
|
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
|
|
|
|
if ( Abc_ObjFaninNum(pObj) == 1 )
|
|
|
|
|
{
|
|
|
|
|
// create the complemented edge
|
|
|
|
|
if ( Abc_ObjFaninC0(pObj) )
|
|
|
|
|
Abc_ObjSetFaninC( pObj->pCopy, 0 );
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// create the edge
|
2005-11-21 17:01:00 +01:00
|
|
|
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin1(pObj), Seq_NodeGetRing(pObj,1), Seq_ObjFaninL1(pObj) );
|
2005-09-12 17:01:00 +02:00
|
|
|
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
|
|
|
|
// the complemented edges are subsumed by the node function
|
|
|
|
|
}
|
|
|
|
|
// add the latches and their names
|
2005-09-16 17:01:00 +02:00
|
|
|
Abc_NtkAddDummyLatchNames( pNtkNew );
|
2005-09-12 17:01:00 +02:00
|
|
|
Abc_NtkForEachLatch( pNtkNew, pObjNew, i )
|
|
|
|
|
{
|
|
|
|
|
Vec_PtrPush( pNtkNew->vCis, pObjNew );
|
|
|
|
|
Vec_PtrPush( pNtkNew->vCos, pObjNew );
|
|
|
|
|
}
|
|
|
|
|
// fix the problem with complemented and duplicated CO edges
|
|
|
|
|
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
|
|
|
|
|
if ( !Abc_NtkCheck( pNtkNew ) )
|
2005-09-15 17:01:00 +02:00
|
|
|
fprintf( stdout, "Abc_NtkSeqToLogicSop(): Network check has failed.\n" );
|
2005-09-12 17:01:00 +02:00
|
|
|
return pNtkNew;
|
|
|
|
|
}
|
2005-11-14 17:01:00 +01:00
|
|
|
|
2005-09-12 17:01:00 +02:00
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Creates latches on one edge.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2005-11-14 17:01:00 +01:00
|
|
|
Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, Seq_Lat_t * pRing, int nLatches )
|
2005-09-12 17:01:00 +02:00
|
|
|
{
|
|
|
|
|
Abc_Obj_t * pLatch;
|
|
|
|
|
if ( nLatches == 0 )
|
2005-09-15 17:01:00 +02:00
|
|
|
{
|
|
|
|
|
assert( pFanin->pCopy );
|
2005-09-12 17:01:00 +02:00
|
|
|
return pFanin->pCopy;
|
2005-09-15 17:01:00 +02:00
|
|
|
}
|
2005-11-14 17:01:00 +01:00
|
|
|
pFanin = Abc_NodeSeqToLogic( pNtkNew, pFanin, Seq_LatNext(pRing), nLatches - 1 );
|
2005-09-12 17:01:00 +02:00
|
|
|
pLatch = Abc_NtkCreateLatch( pNtkNew );
|
2005-11-14 17:01:00 +01:00
|
|
|
pLatch->pData = (void *)Seq_LatInit( pRing );
|
2005-09-12 17:01:00 +02:00
|
|
|
Abc_ObjAddFanin( pLatch, pFanin );
|
|
|
|
|
return pLatch;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-13 17:01:00 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// END OF FILE ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|