Commit da5e0785 by Alan Mishchenko

Version abc61111

parent faf1265b
......@@ -202,6 +202,10 @@ SOURCE=.\src\base\abci\abcCut.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcDebug.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcDsd.c
# End Source File
# Begin Source File
......@@ -1338,10 +1342,6 @@ SOURCE=.\src\opt\ret\retArea.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\ret\retBwd.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\ret\retCore.c
# End Source File
# Begin Source File
......@@ -1354,7 +1354,7 @@ SOURCE=.\src\opt\ret\retFlow.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\ret\retFwd.c
SOURCE=.\src\opt\ret\retIncrem.c
# End Source File
# Begin Source File
......
......@@ -96,6 +96,7 @@ alias shake "st; ps; sat -C 5000; rw -l; ps; sat -C 5000; b -l; rf -l; ps;
alias src_rw "st; rw -l; rwz -l; rwz -l"
alias src_rs "st; rs -K 6 -N 2 -l; rs -K 9 -N 2 -l; rs -K 12 -N 2 -l"
alias src_rws "st; rw -l; rs -K 6 -N 2 -l; rwz -l; rs -K 9 -N 2 -l; rwz -l; rs -K 12 -N 2 -l"
alias resyn2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; rw; rs -K 10; rwz; rs -K 10 -N 2; b; rs -K 12; rfz; rs -K 12 -N 2; rwz; b"
alias compress2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l"
# temporaries
......
......@@ -344,8 +344,8 @@ static inline bool Abc_ObjIsPo( Abc_Obj_t * pObj ) { return pO
static inline bool Abc_ObjIsBi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BI; }
static inline bool Abc_ObjIsBo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BO; }
static inline bool Abc_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_BI; }
static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_BO || pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_BO; }
static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_BI || pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsTerm( Abc_Obj_t * pObj ) { return Abc_ObjIsCi(pObj) || Abc_ObjIsCo(pObj); }
static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; }
static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; }
......@@ -547,6 +547,7 @@ extern void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFani
extern Abc_Obj_t * Abc_ObjInsertBetween( Abc_Obj_t * pNodeIn, Abc_Obj_t * pNodeOut, Abc_ObjType_t Type );
extern void Abc_ObjTransferFanout( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew );
extern void Abc_ObjReplace( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew );
extern int Abc_ObjFanoutFaninNum( Abc_Obj_t * pFanout, Abc_Obj_t * pFanin );
/*=== abcFraig.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExdc );
extern void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExdc );
......@@ -573,6 +574,7 @@ extern bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch );
extern int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk );
extern int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk );
extern Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk );
extern void Abc_NtkInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues );
/*=== abcLib.c ==========================================================*/
extern Abc_Lib_t * Abc_LibCreate( char * pName );
extern void Abc_LibFree( Abc_Lib_t * pLib );
......@@ -599,6 +601,7 @@ extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj );
extern void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes );
extern void Abc_NtkDeleteAll_rec( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName );
extern Abc_Obj_t * Abc_NtkDupBox( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pBox, int fCopyName );
extern Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pNode );
......@@ -808,6 +811,7 @@ extern Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t **
extern int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc, Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 );
extern void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
extern void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
extern Vec_Ptr_t * Abc_NtkCollectLatches( Abc_Ntk_t * pNtk );
extern int Abc_NodeCompareLevelsIncrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 );
extern int Abc_NodeCompareLevelsDecrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 );
extern Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk );
......
......@@ -20,7 +20,7 @@
#include "abc.h"
#include "main.h"
#include "seq.h"
//#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
......@@ -638,6 +638,10 @@ int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode )
Abc_Obj_t * pFanin;
int i, Level;
assert( !Abc_ObjIsNet(pNode) );
if ( pNode->Id == 27278 )
{
int x = 0;
}
// skip the PI
if ( Abc_ObjIsCi(pNode) )
return 0;
......
......@@ -19,7 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "seqInt.h"
//#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -128,7 +128,7 @@ void Abc_ObjRemoveFanins( Abc_Obj_t * pObj )
void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew )
{
Abc_Obj_t * pFaninNewR = Abc_ObjRegular(pFaninNew);
int iFanin, nLats;//, fCompl;
int iFanin;//, nLats;//, fCompl;
assert( !Abc_ObjIsComplement(pObj) );
assert( !Abc_ObjIsComplement(pFaninOld) );
assert( pFaninOld != pFaninNewR );
......@@ -153,8 +153,8 @@ void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFa
if ( Abc_ObjIsComplement(pFaninNew) )
Abc_ObjXorFaninC( pObj, iFanin );
if ( Abc_NtkIsSeq(pObj->pNtk) && (nLats = Seq_ObjFaninL(pObj, iFanin)) )
Seq_ObjSetFaninL( pObj, iFanin, nLats );
// if ( Abc_NtkIsSeq(pObj->pNtk) && (nLats = Seq_ObjFaninL(pObj, iFanin)) )
// Seq_ObjSetFaninL( pObj, iFanin, nLats );
// update the fanout of the fanin
if ( !Vec_IntRemove( &pFaninOld->vFanouts, pObj->Id ) )
{
......@@ -223,8 +223,7 @@ void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo )
int nFanoutsOld, i;
assert( !Abc_ObjIsComplement(pNodeFrom) );
assert( !Abc_ObjIsComplement(pNodeTo) );
assert( Abc_ObjIsNode(pNodeFrom) || Abc_ObjIsCi(pNodeFrom) );
assert( !Abc_ObjIsPo(pNodeTo) );
assert( !Abc_ObjIsPo(pNodeFrom) && !Abc_ObjIsPo(pNodeTo) );
assert( pNodeFrom->pNtk == pNodeTo->pNtk );
assert( pNodeFrom != pNodeTo );
assert( Abc_ObjFanoutNum(pNodeFrom) > 0 );
......@@ -264,6 +263,27 @@ void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew )
Abc_NtkDeleteObj( pNodeOld );
}
/**Function*************************************************************
Synopsis [Returns the index of the fanin in the fanin list of the fanout.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_ObjFanoutFaninNum( Abc_Obj_t * pFanout, Abc_Obj_t * pFanin )
{
Abc_Obj_t * pObj;
int i;
Abc_ObjForEachFanin( pFanout, pObj, i )
if ( pObj == pFanin )
return i;
return -1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -46,9 +46,9 @@ bool Abc_NtkLatchIsSelfFeed_rec( Abc_Obj_t * pLatch, Abc_Obj_t * pLatchRoot )
if ( pLatch == pLatchRoot )
return 1;
pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
if ( !Abc_ObjIsBi(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
if ( !Abc_ObjIsBo(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
return 0;
return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatchRoot );
return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatch );
}
/**Function*************************************************************
......@@ -67,7 +67,7 @@ bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch )
Abc_Obj_t * pFanin;
assert( Abc_ObjIsLatch(pLatch) );
pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
if ( !Abc_ObjIsBi(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
if ( !Abc_ObjIsBo(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
return 0;
return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatch );
}
......@@ -183,13 +183,32 @@ void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches )
***********************************************************************/
Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk )
{
Vec_Int_t * vArray;
Vec_Int_t * vValues;
Abc_Obj_t * pLatch;
int i;
vValues = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pLatch, i )
Vec_IntPush( vValues, Abc_LatchIsInit1(pLatch) );
return vValues;
}
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues )
{
Abc_Obj_t * pLatch;
int i;
vArray = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pLatch, i )
Vec_IntPush( vArray, Abc_LatchIsInit1(pLatch) );
return vArray;
pLatch->pData = (void *)(vValues? (Vec_IntEntry(vValues,i)? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC);
}
......
......@@ -148,11 +148,11 @@ int Abc_LibDeriveBlackBoxes( Abc_Ntk_t * pNtk, Abc_Lib_t * pLib )
{
// go through the fanin nets
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjInsertBetween( pFanin, pObj, ABC_OBJ_BO );
Abc_ObjInsertBetween( pFanin, pObj, ABC_OBJ_BI );
// go through the fanout nets
Abc_ObjForEachFanout( pObj, pFanout, k )
{
Abc_ObjInsertBetween( pObj, pFanout, ABC_OBJ_BI );
Abc_ObjInsertBetween( pObj, pFanout, ABC_OBJ_BO );
// if the name is not given assign name
if ( pFanout->pData == NULL )
{
......
......@@ -19,7 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "seq.h"
//#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
......@@ -22,7 +22,7 @@
#include "abcInt.h"
#include "main.h"
#include "mio.h"
#include "seqInt.h"
//#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -343,7 +343,7 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
Abc_NtkDupObj(pNtkNew, pObj, 0);
// reconnect all objects (no need to transfer attributes on edges)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBi(pObj) )
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
}
......@@ -357,6 +357,92 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Duplicate the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDouble( Abc_Ntk_t * pNtk )
{
char Buffer[500];
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin;
int i, k;
assert( Abc_NtkIsLogic(pNtk) );
// start the network
pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
sprintf( Buffer, "%s%s", pNtk->pName, "_doubled" );
pNtkNew->pName = Extra_UtilStrsav(Buffer);
// clean the node copy fields
Abc_NtkCleanCopy( pNtk );
// clone CIs/CIs/boxes
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Abc_NtkForEachAssert( pNtk, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Abc_NtkForEachBox( pNtk, pObj, i )
Abc_NtkDupBox( pNtkNew, pObj, 0 );
// copy the internal nodes
// duplicate the nets and nodes (CIs/COs/latches already dupped)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->pCopy == NULL )
Abc_NtkDupObj(pNtkNew, pObj, 0);
// reconnect all objects (no need to transfer attributes on edges)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// clean the node copy fields
Abc_NtkCleanCopy( pNtk );
// clone CIs/CIs/boxes
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Abc_NtkForEachAssert( pNtk, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Abc_NtkForEachBox( pNtk, pObj, i )
Abc_NtkDupBox( pNtkNew, pObj, 0 );
// copy the internal nodes
// duplicate the nets and nodes (CIs/COs/latches already dupped)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->pCopy == NULL )
Abc_NtkDupObj(pNtkNew, pObj, 0);
// reconnect all objects (no need to transfer attributes on edges)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// assign names
Abc_NtkForEachCi( pNtk, pObj, i )
{
Abc_ObjAssignName( Abc_NtkCi(pNtkNew, i), "1_", Abc_ObjName(pObj) );
Abc_ObjAssignName( Abc_NtkCi(pNtkNew, Abc_NtkCiNum(pNtk) + i), "2_", Abc_ObjName(pObj) );
}
Abc_NtkForEachCo( pNtk, pObj, i )
{
Abc_ObjAssignName( Abc_NtkCo(pNtkNew, i), "1_", Abc_ObjName(pObj) );
Abc_ObjAssignName( Abc_NtkCo(pNtkNew, Abc_NtkCoNum(pNtk) + i), "2_", Abc_ObjName(pObj) );
}
// perform the final check
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Attaches the second network at the bottom of the first.]
Description [Returns the first network. Deletes the second network.]
......
......@@ -129,10 +129,10 @@ Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
Vec_PtrPush( pNtk->vCos, pObj );
break;
case ABC_OBJ_BI:
if ( pNtk->vCis ) Vec_PtrPush( pNtk->vCis, pObj );
if ( pNtk->vCos ) Vec_PtrPush( pNtk->vCos, pObj );
break;
case ABC_OBJ_BO:
if ( pNtk->vCos ) Vec_PtrPush( pNtk->vCos, pObj );
if ( pNtk->vCis ) Vec_PtrPush( pNtk->vCis, pObj );
break;
case ABC_OBJ_ASSERT:
Vec_PtrPush( pNtk->vAsserts, pObj );
......@@ -171,11 +171,11 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
Abc_Ntk_t * pNtk = pObj->pNtk;
Vec_Ptr_t * vNodes;
int i;
assert( !Abc_ObjIsComplement(pObj) );
// remove from the table of names
if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) )
Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id);
// delete fanins and fanouts
assert( !Abc_ObjIsComplement(pObj) );
vNodes = Vec_PtrAlloc( 100 );
Abc_NodeCollectFanouts( pObj, vNodes );
for ( i = 0; i < vNodes->nSize; i++ )
......@@ -210,10 +210,10 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
Vec_PtrRemove( pNtk->vCos, pObj );
break;
case ABC_OBJ_BI:
if ( pNtk->vCis ) Vec_PtrRemove( pNtk->vCis, pObj );
if ( pNtk->vCos ) Vec_PtrRemove( pNtk->vCos, pObj );
break;
case ABC_OBJ_BO:
if ( pNtk->vCos ) Vec_PtrRemove( pNtk->vCos, pObj );
if ( pNtk->vCis ) Vec_PtrRemove( pNtk->vCis, pObj );
break;
case ABC_OBJ_ASSERT:
Vec_PtrRemove( pNtk->vAsserts, pObj );
......@@ -253,7 +253,6 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
***********************************************************************/
void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes )
{
Abc_Ntk_t * pNtk = pObj->pNtk;
Vec_Ptr_t * vNodes;
int i;
assert( !Abc_ObjIsComplement(pObj) );
......@@ -280,6 +279,33 @@ void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes )
/**Function*************************************************************
Synopsis [Deletes the node and MFFC of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkDeleteAll_rec( Abc_Obj_t * pObj )
{
Vec_Ptr_t * vNodes;
int i;
assert( !Abc_ObjIsComplement(pObj) );
assert( Abc_ObjFanoutNum(pObj) == 0 );
// delete fanins and fanouts
vNodes = Vec_PtrAlloc( 100 );
Abc_NodeCollectFanins( pObj, vNodes );
Abc_NtkDeleteObj( pObj );
Vec_PtrForEachEntry( vNodes, pObj, i )
if ( Abc_ObjFanoutNum(pObj) == 0 )
Abc_NtkDeleteAll_rec( pObj );
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis [Duplicate the Obj.]
Description []
......@@ -401,7 +427,7 @@ Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName )
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PO );
if ( Num >= 0 )
return Abc_ObjFanin0( Abc_NtkObj( pNtk, Num ) );
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BO );
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BI );
if ( Num >= 0 )
return Abc_ObjFanin0( Abc_NtkObj( pNtk, Num ) );
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_NODE );
......@@ -474,7 +500,7 @@ Abc_Obj_t * Abc_NtkFindCi( Abc_Ntk_t * pNtk, char * pName )
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PI );
if ( Num >= 0 )
return Abc_NtkObj( pNtk, Num );
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BI );
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BO );
if ( Num >= 0 )
return Abc_NtkObj( pNtk, Num );
return NULL;
......@@ -498,7 +524,7 @@ Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName )
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PO );
if ( Num >= 0 )
return Abc_NtkObj( pNtk, Num );
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BO );
Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BI );
if ( Num >= 0 )
return Abc_NtkObj( pNtk, Num );
return NULL;
......
......@@ -259,7 +259,8 @@ void Abc_NtkShow( Abc_Ntk_t * pNtk, int fGateNames )
char FileNameDot[200];
int i;
assert( !Abc_NtkHasAig(pNtk) );
assert( !Abc_NtkIsStrash(pNtk) );
Abc_NtkLogicToSop( pNtk, 0 );
// create the file name
Abc_ShowGetFileName( pNtk->pName, FileNameDot );
// check that the file can be opened
......@@ -273,7 +274,8 @@ void Abc_NtkShow( Abc_Ntk_t * pNtk, int fGateNames )
// collect all nodes in the network
vNodes = Vec_PtrAlloc( 100 );
Abc_NtkForEachObj( pNtk, pNode, i )
Vec_PtrPush( vNodes, pNode );
// if ( !Abc_ObjIsBi(pNode) && !Abc_ObjIsBo(pNode) )
Vec_PtrPush( vNodes, pNode );
// write the DOT file
Io_WriteDotNtk( pNtk, vNodes, NULL, FileNameDot, fGateNames );
Vec_PtrFree( vNodes );
......
......@@ -22,7 +22,7 @@
#include "main.h"
#include "mio.h"
#include "dec.h"
#include "seq.h"
//#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -1038,6 +1038,28 @@ void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
/**Function*************************************************************
Synopsis [Collects all latches in the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkCollectLatches( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vLatches;
Abc_Obj_t * pObj;
int i;
vLatches = Vec_PtrAlloc( 10 );
Abc_NtkForEachObj( pNtk, pObj, i )
Vec_PtrPush( vLatches, pObj );
return vLatches;
}
/**Function*************************************************************
Synopsis [Procedure used for sorting the nodes in increasing order of levels.]
Description []
......
......@@ -20,7 +20,7 @@
#include "abc.h"
#include "cut.h"
#include "seqInt.h"
//#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -401,6 +401,7 @@ void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
***********************************************************************/
void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv )
{
/*
int CutSetNum;
assert( Abc_NtkIsSeq(pObj->pNtk) );
assert( Abc_ObjFaninNum(pObj) == 2 );
......@@ -408,6 +409,7 @@ void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv )
CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1;
Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Seq_ObjFaninL0(pObj), Seq_ObjFaninL1(pObj), fTriv, CutSetNum );
*/
}
/**Function*************************************************************
......
/**CFile****************************************************************
FileName [abcDebug.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Automated debugging procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcDebug.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Abc_NtkCountFaninsTotal( Abc_Ntk_t * pNtk );
static Abc_Ntk_t * Abc_NtkAutoDebugModify( Abc_Ntk_t * pNtk, int ObjNum, int fConst1 );
extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Takes a network and a procedure to test.]
Description [The network demonstrates the bug in the procedure.
Procedure should return 1 if the bug is demonstrated.]
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkAutoDebug( Abc_Ntk_t * pNtk, int (*pFuncError) (Abc_Ntk_t *) )
{
Abc_Ntk_t * pNtkMod;
char * pFileName = "bug_found.blif";
int i, nSteps, nIter, ModNum, RandNum = 1, clk, clkTotal = clock();
assert( Abc_NtkIsLogic(pNtk) );
srand( 0x123123 );
// create internal copy of the network
pNtk = Abc_NtkDup(pNtk);
if ( !(*pFuncError)( pNtk ) )
{
printf( "The original network does not cause the bug. Quitting.\n" );
Abc_NtkDelete( pNtk );
return;
}
// perform incremental modifications
for ( nIter = 0; ; nIter++ )
{
clk = clock();
// count how many ways of modifying the network exists
nSteps = 2 * Abc_NtkCountFaninsTotal(pNtk);
// try modifying the network as many times
RandNum ^= rand();
for ( i = 0; i < nSteps; i++ )
{
// get the shifted number of bug
ModNum = (i + RandNum) % nSteps;
// get the modified network
pNtkMod = Abc_NtkAutoDebugModify( pNtk, ModNum/2, ModNum%2 );
// write the network
Io_WriteBlifLogic( pNtk, "bug_temp.blif", 1 );
// check if the bug is still there
if ( (*pFuncError)( pNtkMod ) ) // bug is still there
{
Abc_NtkDelete( pNtk );
pNtk = pNtkMod;
break;
}
else // no bug
Abc_NtkDelete( pNtkMod );
}
printf( "Iteration %6d : Nodes = %6d. Steps = %6d. Error step = %3d. ", nIter, Abc_NtkObjNum(pNtk), nSteps, i );
PRT( "Time", clock() - clk );
if ( i == nSteps ) // could not modify it while preserving the bug
break;
}
// write out the final network
Io_WriteBlifLogic( pNtk, pFileName, 1 );
printf( "Final network written into file \"%s\". ", pFileName );
PRT( "Total time", clock() - clkTotal );
Abc_NtkDelete( pNtk );
}
/**Function*************************************************************
Synopsis [Counts the total number of fanins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkCountFaninsTotal( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj, * pFanin;
int i, k, Counter = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
{
if ( Abc_NodeIsConst(pFanin) )
continue;
Counter++;
}
return Counter;
}
/**Function*************************************************************
Synopsis [Returns the node and fanin to be modified.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkFindGivenFanin( Abc_Ntk_t * pNtk, int Step, Abc_Obj_t ** ppObj, Abc_Obj_t ** ppFanin )
{
Abc_Obj_t * pObj, * pFanin;
int i, k, Counter = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
{
if ( Abc_NodeIsConst(pFanin) )
continue;
if ( Counter++ == Step )
{
*ppObj = pObj;
*ppFanin = pFanin;
return 1;
}
}
return 0;
}
/**Function*************************************************************
Synopsis [Perform modification with the given number.]
Description [Modification consists of replacing the node by a constant.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkAutoDebugModify( Abc_Ntk_t * pNtkInit, int Step, int fConst1 )
{
Abc_Ntk_t * pNtk;
Abc_Obj_t * pObj, * pFanin, * pConst;
// copy the network
pNtk = Abc_NtkDup( pNtkInit );
assert( Abc_NtkNodeNum(pNtk) == Abc_NtkNodeNum(pNtkInit) );
// find the object number
Abc_NtkFindGivenFanin( pNtk, Step, &pObj, &pFanin );
// consider special case
if ( Abc_ObjIsPo(pObj) && Abc_NodeIsConst(pFanin) )
{
Abc_NtkDeleteAll_rec( pObj );
return pNtk;
}
// plug in a constant node
pConst = fConst1? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk);
Abc_ObjTransferFanout( pFanin, pConst );
Abc_NtkDeleteAll_rec( pFanin );
Abc_NtkSweep( pNtk, 0 );
Abc_NtkCleanupSeq( pNtk, 0 );
Abc_NtkLogicToSop( pNtk, 0 );
Abc_NtkCycleInitStateSop( pNtk, 20, 0 );
return pNtk;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -84,7 +84,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
}
if ( fSeq && Abc_NtkCountSelfFeedLatches(pNtk) )
{
printf( "Warning: The network has %d self-feeding latches. Quitting.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
// return NULL;
}
// print warning about choice nodes
......@@ -369,7 +369,7 @@ Abc_Ntk_t * Abc_NtkIvySat( Abc_Ntk_t * pNtk, int nConfLimit, int fVerbose )
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkIvyFraig( Abc_Ntk_t * pNtk, int nConfLimit, int fProve, int fVerbose )
Abc_Ntk_t * Abc_NtkIvyFraig( Abc_Ntk_t * pNtk, int nConfLimit, int fDoSparse, int fProve, int fVerbose )
{
Ivy_FraigParams_t Params, * pParams = &Params;
Abc_Ntk_t * pNtkAig;
......@@ -379,8 +379,9 @@ Abc_Ntk_t * Abc_NtkIvyFraig( Abc_Ntk_t * pNtk, int nConfLimit, int fProve, int f
return NULL;
Ivy_FraigParamsDefault( pParams );
pParams->nBTLimitNode = nConfLimit;
pParams->fVerbose = fVerbose;
pParams->fProve = fProve;
pParams->fVerbose = fVerbose;
pParams->fProve = fProve;
pParams->fDoSparse = fDoSparse;
pMan = Ivy_FraigPerform( pTemp = pMan, pParams );
Ivy_ManStop( pTemp );
pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 0, 0 );
......@@ -668,8 +669,8 @@ Abc_Ntk_t * Abc_NtkFromAigSeq( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan, int fHaig
Ivy_ManForEachNodeVec( pMan, vLatches, pNode, i )
{
pObjNew = Abc_NtkCreateLatch( pNtk );
pFaninNew0 = Abc_NtkCreateBo( pNtk );
pFaninNew1 = Abc_NtkCreateBi( pNtk );
pFaninNew0 = Abc_NtkCreateBi( pNtk );
pFaninNew1 = Abc_NtkCreateBo( pNtk );
Abc_ObjAddFanin( pObjNew, pFaninNew0 );
Abc_ObjAddFanin( pFaninNew1, pObjNew );
if ( fHaig || Ivy_ObjInit(pNode) == IVY_INIT_DC )
......
......@@ -343,7 +343,7 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly
*/
// reset references
Abc_NtkForEachObj( pNtk, pObj, i )
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBi(pObj) )
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
Abc_ObjForEachFanin( pObj, pFanin, k )
pFanin->vFanouts.nSize++;
......
......@@ -22,7 +22,7 @@
#include "dec.h"
#include "main.h"
#include "mio.h"
#include "seq.h"
//#include "seq.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -142,7 +142,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
fprintf( pTable, "\n" );
fclose( pTable );
}
*/
*/
/*
// print the statistic into a file
......@@ -162,14 +162,22 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
/*
// print the statistic into a file
{
static int Counter = 0;
extern int timeRetime;
FILE * pTable;
pTable = fopen( "stats.txt", "a+" );
fprintf( pTable, "%s ", pNtk->pName );
Counter++;
pTable = fopen( "sap/stats_retime.txt", "a+" );
fprintf( pTable, "%s ", pNtk->pName );
fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) );
fprintf( pTable, "\n" );
fprintf( pTable, "%d ", Abc_NtkGetLevelNum(pNtk) );
fprintf( pTable, "%.2f ", (float)(timeRetime)/(float)(CLOCKS_PER_SEC) );
if ( Counter % 4 == 0 )
fprintf( pTable, "\n" );
fclose( pTable );
}
*/
/*
s_TotalNodes += Abc_NtkNodeNum(pNtk);
printf( "Total nodes = %6d %6.2f Mb Changes = %6d.\n",
......@@ -254,8 +262,18 @@ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
InitNums[Init]++;
pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
if ( !Abc_ObjIsNode(pFanin) || !Abc_NodeIsConst(pFanin) )
continue;
if ( Abc_NtkIsLogic(pNtk) )
{
if ( !Abc_NodeIsConst(pFanin) )
continue;
}
else if ( Abc_NtkIsStrash(pNtk) )
{
if ( !Abc_AigNodeIsConst(pFanin) )
continue;
}
else
assert( 0 );
// the latch input is a constant node
Counter0++;
......
......@@ -147,9 +147,9 @@ int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, bool fUpd
if ( fUpdateLevel )
Abc_NtkStartReverseLevels( pNtk );
// if ( Abc_NtkLatchNum(pNtk) )
// Abc_NtkForEachLatch(pNtk, pNode, i)
// pNode->pNext = pNode->pData;
if ( Abc_NtkLatchNum(pNtk) )
Abc_NtkForEachLatch(pNtk, pNode, i)
pNode->pNext = pNode->pData;
// resynthesize each node once
nNodes = Abc_NtkObjNumMax(pNtk);
......@@ -221,9 +221,9 @@ pManRes->timeTotal = clock() - clkStart;
Abc_NtkForEachObj( pNtk, pNode, i )
pNode->pData = NULL;
// if ( Abc_NtkLatchNum(pNtk) )
// Abc_NtkForEachLatch(pNtk, pNode, i)
// pNode->pData = pNode->pNext, pNode->pNext = NULL;
if ( Abc_NtkLatchNum(pNtk) )
Abc_NtkForEachLatch(pNtk, pNode, i)
pNode->pData = pNode->pNext, pNode->pNext = NULL;
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
......
......@@ -860,7 +860,7 @@ int Abc_NtkReplaceAutonomousLogic( Abc_Ntk_t * pNtk )
continue;
// skip constants and latches fed by constants
if ( Abc_NtkCheckConstant_rec(pFanin) != -1 ||
(Abc_ObjIsBi(pFanin) && Abc_NtkCheckConstant_rec(Abc_ObjFanin0(Abc_ObjFanin0(pFanin))) != -1) )
(Abc_ObjIsBo(pFanin) && Abc_NtkCheckConstant_rec(Abc_ObjFanin0(Abc_ObjFanin0(pFanin))) != -1) )
{
Abc_NtkSetTravId_rec( pFanin );
continue;
......@@ -874,6 +874,7 @@ int Abc_NtkReplaceAutonomousLogic( Abc_Ntk_t * pNtk )
Vec_PtrForEachEntry( vNodes, pNode, i )
{
pFanin = Abc_NtkCreatePi(pNtk);
Abc_ObjAssignName( pFanin, Abc_ObjName(pFanin), NULL );
Abc_NodeSetTravIdCurrent( pFanin );
Abc_ObjTransferFanout( pNode, pFanin );
}
......
......@@ -95,7 +95,7 @@ int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, bool fVerbose )
pNtk->pManGlob = NULL;
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtk->pExdc ) )
if ( pNtk->pExdc && !Abc_NtkCheck( pNtk->pExdc ) )
{
printf( "Abc_NtkExtractSequentialDcs: The network check has failed.\n" );
Abc_NtkDelete( pNtk->pExdc );
......
......@@ -286,7 +286,7 @@ void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
SeeAlso []
***********************************************************************/
void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nFrames, int fVerbose )
int Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nFrames, int fVerbose )
{
Fraig_Params_t Params;
Fraig_Man_t * pMan;
......@@ -299,7 +299,7 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
if ( pMiter == NULL )
{
printf( "Miter computation has failed.\n" );
return;
return 0;
}
RetValue = Abc_NtkMiterIsConstant( pMiter );
if ( RetValue == 0 )
......@@ -310,13 +310,13 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, pMiter->pModel, nFrames );
FREE( pMiter->pModel );
Abc_NtkDelete( pMiter );
return;
return 0;
}
if ( RetValue == 1 )
{
Abc_NtkDelete( pMiter );
printf( "Networks are equivalent after structural hashing.\n" );
return;
return 1;
}
// create the timeframes
......@@ -325,7 +325,7 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
if ( pFrames == NULL )
{
printf( "Frames computation has failed.\n" );
return;
return 0;
}
RetValue = Abc_NtkMiterIsConstant( pFrames );
if ( RetValue == 0 )
......@@ -336,13 +336,13 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
// Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, pFrames->pModel, nFrames );
FREE( pFrames->pModel );
Abc_NtkDelete( pFrames );
return;
return 0;
}
if ( RetValue == 1 )
{
Abc_NtkDelete( pFrames );
printf( "Networks are equivalent after framing.\n" );
return;
return 1;
}
// convert the miter into a FRAIG
......@@ -372,6 +372,7 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
Fraig_ManFree( pMan );
// delete the miter
Abc_NtkDelete( pFrames );
return RetValue == 1;
}
/**Function*************************************************************
......
......@@ -24,9 +24,9 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define XVS0 1
#define XVS1 2
#define XVSX 3
#define XVS0 ABC_INIT_ZERO
#define XVS1 ABC_INIT_ONE
#define XVSX ABC_INIT_DC
static inline void Abc_ObjSetXsim( Abc_Obj_t * pObj, int Value ) { pObj->pCopy = (void *)Value; }
static inline int Abc_ObjGetXsim( Abc_Obj_t * pObj ) { return (int)pObj->pCopy; }
......@@ -157,6 +157,49 @@ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVer
}
}
/**Function*************************************************************
Synopsis [Cycles the circuit to create a new initial state.]
Description [Simulates the circuit with random input for the given
number of timeframes to get a better initial state.]
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkCycleInitState( Abc_Ntk_t * pNtk, int nFrames, int fVerbose )
{
Abc_Obj_t * pObj;
int i, f;
assert( Abc_NtkIsStrash(pNtk) );
srand( 0x12341234 );
// initialize the values
Abc_ObjSetXsim( Abc_AigConst1(pNtk), XVS1 );
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchIsInit1(pObj)? XVS1 : XVS0 );
// simulate for the given number of timeframes
for ( f = 0; f < nFrames; f++ )
{
Abc_AigForEachAnd( pNtk, pObj, i )
Abc_ObjSetXsim( pObj, Abc_XsimAnd(Abc_ObjGetXsimFanin0(pObj), Abc_ObjGetXsimFanin1(pObj)) );
Abc_NtkForEachCo( pNtk, pObj, i )
Abc_ObjSetXsim( pObj, Abc_ObjGetXsimFanin0(pObj) );
// assign input values
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
// transfer the latch values
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_ObjGetXsim(Abc_ObjFanin0(pObj)) );
}
// set the final values
Abc_NtkForEachLatch( pNtk, pObj, i )
pObj->pData = (void *)Abc_ObjGetXsim(Abc_ObjFanout0(pObj));
}
///////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -6,6 +6,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcClpBdd.c \
src/base/abci/abcClpSop.c \
src/base/abci/abcCut.c \
src/base/abci/abcDebug.c \
src/base/abci/abcDsd.c \
src/base/abci/abcEspresso.c \
src/base/abci/abcExtract.c \
......
......@@ -40,6 +40,7 @@ static int IoCommandReadTruth ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBaf ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBlif ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBench ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteCellNet( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteCnf ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteDot ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteEqn ( Abc_Frame_t * pAbc, int argc, char **argv );
......@@ -84,6 +85,7 @@ void Io_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "I/O", "write_baf", IoCommandWriteBaf, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_blif", IoCommandWriteBlif, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_bench", IoCommandWriteBench, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_cellnet", IoCommandWriteCellNet, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_cnf", IoCommandWriteCnf, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_dot", IoCommandWriteDot, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_eqn", IoCommandWriteEqn, 0 );
......@@ -1189,6 +1191,68 @@ usage:
SeeAlso []
***********************************************************************/
int IoCommandWriteCellNet( Abc_Frame_t * pAbc, int argc, char **argv )
{
Abc_Ntk_t * pNtk;
char * FileName;
int c;
extern void Io_WriteCellNet( Abc_Ntk_t * pNtk, char * pFileName );
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
pNtk = pAbc->pNtkCur;
if ( pNtk == NULL )
{
fprintf( pAbc->Out, "Empty network.\n" );
return 0;
}
if ( argc != globalUtilOptind + 1 )
{
goto usage;
}
// get the input file name
FileName = argv[globalUtilOptind];
if ( !Abc_NtkIsLogic(pNtk) )
{
fprintf( pAbc->Out, "The network should be a logic network (if it an AIG, use command \"logic\")\n" );
return 0;
}
// derive the netlist
Io_WriteCellNet( pNtk, FileName );
return 0;
usage:
fprintf( pAbc->Err, "usage: write_cellnet [-h] <file>\n" );
fprintf( pAbc->Err, "\t write the network is the cellnet format\n" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int IoCommandWriteCnf( Abc_Frame_t * pAbc, int argc, char **argv )
{
char * FileName;
......
......@@ -100,10 +100,10 @@ Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck )
pObj = Abc_NtkCreateLatch(pNtkNew);
Abc_ObjAssignName( pObj, pCur, NULL ); while ( *pCur++ );
pNode0 = Abc_NtkCreateBo(pNtkNew);
pNode0 = Abc_NtkCreateBi(pNtkNew);
Abc_ObjAssignName( pNode0, pCur, NULL ); while ( *pCur++ );
pNode1 = Abc_NtkCreateBi(pNtkNew);
pNode1 = Abc_NtkCreateBo(pNtkNew);
Abc_ObjAssignName( pNode1, pCur, NULL ); while ( *pCur++ );
Vec_PtrPush( vNodes, pNode1 );
......
......@@ -142,6 +142,8 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
Abc_ObjSetData( pNode, Abc_SopCreateBuf(pNtk->pManFunc) );
else if ( strcmp(pType, "NOT") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateInv(pNtk->pManFunc) );
else if ( strncmp(pType, "MUX", 3) == 0 )
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1-0 1\n-11 1\n") );
else
{
printf( "Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) );
......
......@@ -354,7 +354,7 @@ int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
***********************************************************************/
int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
{
Abc_Ntk_t * pNtk = p->pNtkCur;
Abc_Obj_t * pLatch;
int ResetValue;
......
......@@ -120,13 +120,13 @@ Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO )
// get the LI net
pNet = Abc_NtkFindOrCreateNet( pNtk, pNetLI );
// add the BO terminal
pTerm = Abc_NtkCreateBo( pNtk );
pTerm = Abc_NtkCreateBi( pNtk );
Abc_ObjAddFanin( pTerm, pNet );
// add the latch box
pLatch = Abc_NtkCreateLatch( pNtk );
Abc_ObjAddFanin( pLatch, pTerm );
// add the BI terminal
pTerm = Abc_NtkCreateBi( pNtk );
pTerm = Abc_NtkCreateBo( pNtk );
Abc_ObjAddFanin( pTerm, pLatch );
// get the LO net
pNet = Abc_NtkFindOrCreateNet( pNtk, pNetLO );
......
......@@ -19,7 +19,9 @@
***********************************************************************/
#include "io.h"
#include "seqInt.h"
#include "main.h"
#include "mio.h"
//#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -292,6 +294,10 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
{
if ( Abc_ObjFaninNum(pNode) == 0 )
continue;
if ( Abc_ObjIsBo(pNode) )
continue;
if ( fMulti && Abc_ObjIsNode(pNode) )
{
Vec_Ptr_t * vSuper;
......@@ -305,6 +311,10 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
pFanin = Abc_ObjRegular(pFanin);
if ( !pFanin->fMarkC )
continue;
if ( Abc_ObjIsBi(pFanin) )
continue;
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d%s", pFanin->Id, (Abc_ObjIsLatch(pFanin)? "_out":"") );
......@@ -316,7 +326,7 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
continue;
}
// generate the edge from this node to the next
if ( Abc_ObjFanin0(pNode)->fMarkC )
if ( Abc_ObjFanin0(pNode)->fMarkC && !Abc_ObjIsBi(Abc_ObjFanin0(pNode)) )
{
fprintf( pFile, "Node%d%s", pNode->Id, (Abc_ObjIsLatch(pNode)? "_in":"") );
fprintf( pFile, " -> " );
......@@ -331,7 +341,7 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
if ( Abc_ObjFaninNum(pNode) == 1 )
continue;
// generate the edge from this node to the next
if ( Abc_ObjFanin1(pNode)->fMarkC )
if ( Abc_ObjFanin1(pNode)->fMarkC && !Abc_ObjIsBi(Abc_ObjFanin1(pNode)) )
{
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
......@@ -392,7 +402,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds;
int Limit = 300;
assert( !Abc_NtkHasAig(pNtk) );
assert( !Abc_NtkIsStrash(pNtk) );
if ( vNodes->nSize < 1 )
{
......@@ -606,7 +616,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, " rank = same;\n" );
// the labeling node of this level
fprintf( pFile, " Level%d;\n", LevelMin );
// generat the PO nodes
// generate the PO nodes
Vec_PtrForEachEntry( vNodes, pNode, i )
{
if ( !Abc_ObjIsCi(pNode) )
......@@ -653,6 +663,11 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
{
if ( !Abc_ObjFanin0(pNode)->fMarkC )
continue;
// added to fix the bug after adding boxes
if ( Abc_ObjIsBo(pNode) || Abc_ObjIsBi(pFanin) )
continue;
// generate the edge from this node to the next
fprintf( pFile, "Node%d%s", pNode->Id, (Abc_ObjIsLatch(pNode)? "_in":"") );
fprintf( pFile, " -> " );
......
......@@ -19,7 +19,7 @@
***********************************************************************/
#include "io.h"
#include "seqInt.h"
//#include "seqInt.h"
/*
-------- Original Message --------
......@@ -159,7 +159,8 @@ void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj )
{
fprintf( pFile, " %s", Abc_ObjName(pFanout) );
fprintf( pFile, " ([%s_to_", Abc_ObjName(pObj) );
fprintf( pFile, "%s] = %d)", Abc_ObjName(pFanout), Seq_ObjFanoutL(pObj, pFanout) );
// fprintf( pFile, "%s] = %d)", Abc_ObjName(pFanout), Seq_ObjFanoutL(pObj, pFanout) );
fprintf( pFile, "%s] = %d)", Abc_ObjName(pFanout), 0 );
if ( i != Abc_ObjFanoutNum(pObj) - 1 )
fprintf( pFile, "," );
}
......@@ -204,6 +205,83 @@ void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk )
}
/**Function*************************************************************
Synopsis [Writes the adjacency list for a sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteCellNet( Abc_Ntk_t * pNtk, char * pFileName )
{
FILE * pFile;
Abc_Obj_t * pObj, * pFanout;
int i, k;
assert( Abc_NtkIsLogic(pNtk) );
// start the output stream
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
{
fprintf( stdout, "Io_WriteCellNet(): Cannot open the output file \"%s\".\n", pFileName );
return;
}
fprintf( pFile, "# CellNet file for network \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
// the only tricky part with writing is handling latches:
// each latch comes with (a) single-input latch-input node, (b) latch proper, (c) single-input latch-output node
// we arbitrarily decide to use the interger ID of the latch-input node to represent the latch in the file
// (this ID is used for both the cell and the net driven by that cell)
// write the PIs
Abc_NtkForEachPi( pNtk, pObj, i )
fprintf( pFile, "cell %d is 0\n", pObj->Id );
// write the POs
Abc_NtkForEachPo( pNtk, pObj, i )
fprintf( pFile, "cell %d is 1\n", pObj->Id );
// write the latches (use the ID of latch input)
Abc_NtkForEachLatch( pNtk, pObj, i )
fprintf( pFile, "cell %d is 2\n", Abc_ObjFanin0(pObj)->Id );
// write the logic nodes
Abc_NtkForEachNode( pNtk, pObj, i )
fprintf( pFile, "cell %d is %d\n", pObj->Id, 3+Abc_ObjFaninNum(pObj) );
// write the nets driven by PIs
Abc_NtkForEachPi( pNtk, pObj, i )
{
fprintf( pFile, "net %d %d 0", pObj->Id, pObj->Id );
Abc_ObjForEachFanout( pObj, pFanout, k )
fprintf( pFile, " %d %d", pFanout->Id, 1 + Abc_ObjFanoutFaninNum(pFanout, pObj) );
fprintf( pFile, "\n" );
}
// write the nets driven by latches
Abc_NtkForEachLatch( pNtk, pObj, i )
{
fprintf( pFile, "net %d %d 0", Abc_ObjFanin0(pObj)->Id, Abc_ObjFanin0(pObj)->Id );
pObj = Abc_ObjFanout0(pObj);
Abc_ObjForEachFanout( pObj, pFanout, k )
fprintf( pFile, " %d %d", pFanout->Id, 1 + Abc_ObjFanoutFaninNum(pFanout, pObj) );
fprintf( pFile, "\n" );
}
// write the nets driven by nodes
Abc_NtkForEachNode( pNtk, pObj, i )
{
fprintf( pFile, "net %d %d 0", pObj->Id, pObj->Id );
Abc_ObjForEachFanout( pObj, pFanout, k )
fprintf( pFile, " %d %d", pFanout->Id, 1 + Abc_ObjFanoutFaninNum(pFanout, pObj) );
fprintf( pFile, "\n" );
}
fprintf( pFile, "\n" );
fclose( pFile );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -110,6 +110,7 @@ int Nm_ManTableDelete( Nm_Man_t * p, int ObjId )
{
Nm_Entry_t ** ppSpot, * pEntry, * pPrev;
int fRemoved;
p->nEntries--;
// remove the entry from the table Id->Name
assert( Nm_ManTableLookupId(p, ObjId) != NULL );
ppSpot = p->pBinsI2N + Nm_HashNumber(ObjId, p->nBins);
......
SRC += src/opt/dec/retArea.c \
src/opt/dec/retBwd.c \
src/opt/dec/retCore.c \
src/opt/dec/retDelay.c \
src/opt/dec/retFlow.c \
src/opt/dec/retFwd.c \
src/opt/dec/retInit.c
SRC += src/opt/ret/retArea.c \
src/opt/ret/retCore.c \
src/opt/ret/retDelay.c \
src/opt/ret/retFlow.c \
src/opt/ret/retIncrem.c \
src/opt/ret/retInit.c
/**CFile****************************************************************
FileName [retBwd.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Retiming package.]
Synopsis [Most backward retiming.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - Oct 31, 2006.]
Revision [$Id: retBwd.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
***********************************************************************/
#include "retInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose )
{
printf( "Not implemented.\n" );
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -24,6 +24,8 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
int timeRetime = 0;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -39,36 +41,74 @@
SeeAlso []
***********************************************************************/
int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fVerbose )
int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fVerbose )
{
int RetValue;
int nLatches = Abc_NtkLatchNum(pNtk);
int nLevels = Abc_NtkGetLevelNum(pNtk);
int RetValue = 0, clkTotal = clock();
assert( Mode > 0 && Mode < 6 );
assert( !fForwardOnly || !fBackwardOnly );
// perform forward retiming
switch ( Mode )
{
case 1: // forward
RetValue = Abc_NtkRetimeForward( pNtk, fVerbose );
RetValue = Abc_NtkRetimeIncremental( pNtk, 1, 0, fVerbose );
break;
case 2: // backward
RetValue = Abc_NtkRetimeBackward( pNtk, fVerbose );
RetValue = Abc_NtkRetimeIncremental( pNtk, 0, 0, fVerbose );
break;
case 3: // min-area
RetValue = Abc_NtkRetimeMinArea( pNtk, fVerbose );
RetValue = Abc_NtkRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose );
break;
case 4: // min-delay
RetValue = Abc_NtkRetimeMinDelay( pNtk, fVerbose );
if ( !fBackwardOnly )
RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, fVerbose );
if ( !fForwardOnly )
RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, fVerbose );
break;
case 5: // min-area + min-delay
RetValue = Abc_NtkRetimeMinArea( pNtk, fVerbose );
RetValue += Abc_NtkRetimeMinDelay( pNtk, fVerbose );
RetValue = Abc_NtkRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose );
if ( !fBackwardOnly )
RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, fVerbose );
if ( !fForwardOnly )
RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, fVerbose );
break;
default:
printf( "Unknown retiming option.\n" );
break;
}
if ( fVerbose )
{
printf( "Reduction in area = %3d. Reduction in delay = %3d. ",
nLatches - Abc_NtkLatchNum(pNtk), nLevels - Abc_NtkGetLevelNum(pNtk) );
PRT( "Total runtime", clock() - clkTotal );
}
timeRetime = clock() - clkTotal;
return RetValue;
}
/**Function*************************************************************
Synopsis [Used for automated debugging.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeDebug( Abc_Ntk_t * pNtk )
{
extern int Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nFrames, int fVerbose );
Abc_Ntk_t * pNtkRet;
assert( Abc_NtkIsLogic(pNtk) );
Abc_NtkLogicToSop( pNtk, 0 );
pNtkRet = Abc_NtkDup( pNtk );
Abc_NtkRetime( pNtkRet, 3, 0, 1, 0 );
return !Abc_NtkSecFraig( pNtk, pNtkRet, 10000, 3, 0 );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -24,30 +24,44 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Abc_NtkRetimeMinDelayTry( Abc_Ntk_t * pNtk, int fForward, int fInitial, int nIterLimit, int * pIterBest, int fVerbose );
static int Abc_NtkRetimeTiming( Abc_Ntk_t * pNtk, int fForward, Vec_Ptr_t * vCritical );
static int Abc_NtkRetimeTiming_rec( Abc_Obj_t * pObj, int fForward );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Synopsis [Retimes incrementally for minimum delay.]
Description []
Description [This procedure cannot be called in the application code
because it assumes that the network is preprocessed by removing LIs/LOs.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, int fVerbose )
int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkCopy, int nIterLimit, int fForward, int fVerbose )
{
printf( "Not implemented.\n" );
return 0;
int IterBest, DelayBest;
int IterBest2, DelayBest2;
// try to find the best delay iteration on a copy
DelayBest = Abc_NtkRetimeMinDelayTry( pNtkCopy, fForward, 0, nIterLimit, &IterBest, fVerbose );
if ( IterBest == 0 )
return 1;
// perform the given number of iterations on the original network
DelayBest2 = Abc_NtkRetimeMinDelayTry( pNtk, fForward, 1, IterBest, &IterBest2, fVerbose );
assert( DelayBest == DelayBest2 );
assert( IterBest == IterBest2 );
return 1;
}
/**Function*************************************************************
Synopsis []
Synopsis [Returns the best delay and the number of best iteration.]
Description []
......@@ -56,7 +70,217 @@ int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, int fVerbose )
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeMinDelayTry( Abc_Ntk_t * pNtk, int fForward, int fInitial, int nIterLimit, int * pIterBest, int fVerbose )
{
Abc_Ntk_t * pNtkNew = NULL;
Vec_Ptr_t * vCritical;
Vec_Int_t * vValues;
Abc_Obj_t * pObj;
int i, k, IterBest, DelayCur, DelayBest, DelayStart;
// transfer intitial values
if ( fInitial )
{
if ( fForward )
Abc_NtkRetimeTranferToCopy( pNtk );
else
{
// save initial value of the latches
vValues = Abc_NtkRetimeCollectLatchValues( pNtk );
// start the network for initial value computation
pNtkNew = Abc_NtkRetimeBackwardInitialStart( pNtk );
}
}
// find the best iteration
DelayBest = ABC_INFINITY; IterBest = 0;
vCritical = Vec_PtrAlloc( 100 );
for ( i = 0; ; i++ )
{
// perform moves for the timing-critical nodes
DelayCur = Abc_NtkRetimeTiming( pNtk, fForward, vCritical );
if ( i == 0 )
DelayStart = DelayCur;
// record this position if it has the best delay
if ( DelayBest > DelayCur )
{
DelayBest = DelayCur;
IterBest = i;
}
// quit after timing analysis
if ( i == nIterLimit )
break;
// try retiming to improve the delay
Vec_PtrForEachEntry( vCritical, pObj, k )
if ( Abc_NtkRetimeNodeIsEnabled(pObj, fForward) )
Abc_NtkRetimeNode( pObj, fForward, fInitial );
}
Vec_PtrFree( vCritical );
// transfer the initial state back to the latches
if ( fInitial )
{
if ( fForward )
Abc_NtkRetimeTranferFromCopy( pNtk );
else
{
Abc_NtkRetimeBackwardInitialFinish( pNtk, pNtkNew, vValues, fVerbose );
Abc_NtkDelete( pNtkNew );
Vec_IntFree( vValues );
}
}
if ( !fInitial && fVerbose )
printf( "%s : Starting delay = %3d. Final delay = %3d. IterBest = %2d (out of %2d).\n",
fForward? "Forward " : "Backward", DelayStart, DelayBest, IterBest, nIterLimit );
*pIterBest = IterBest;
return DelayBest;
}
/**Function*************************************************************
Synopsis [Returns the set of timing-critical nodes.]
Description [Performs static timing analysis on the network. Uses
unit-delay model.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeTiming( Abc_Ntk_t * pNtk, int fForward, Vec_Ptr_t * vCritical )
{
Vec_Ptr_t * vLatches;
Abc_Obj_t * pObj, * pNext;
int i, k, LevelCur, LevelMax = 0;
// mark all objects except nodes
Abc_NtkIncrementTravId(pNtk);
vLatches = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( Abc_ObjIsLatch(pObj) )
Vec_PtrPush( vLatches, pObj );
if ( Abc_ObjIsNode(pObj) )
continue;
pObj->Level = 0;
Abc_NodeSetTravIdCurrent( pObj );
}
// perform analysis from CIs/COs
if ( fForward )
{
Vec_PtrForEachEntry( vLatches, pObj, i )
{
Abc_ObjForEachFanout( pObj, pNext, k )
{
LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward );
if ( LevelMax < LevelCur )
LevelMax = LevelCur;
}
}
Abc_NtkForEachPi( pNtk, pObj, i )
{
Abc_ObjForEachFanout( pObj, pNext, k )
{
LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward );
if ( LevelMax < LevelCur )
LevelMax = LevelCur;
}
}
}
else
{
Vec_PtrForEachEntry( vLatches, pObj, i )
{
LevelCur = Abc_NtkRetimeTiming_rec( Abc_ObjFanin0(pObj), fForward );
if ( LevelMax < LevelCur )
LevelMax = LevelCur;
}
Abc_NtkForEachPo( pNtk, pObj, i )
{
LevelCur = Abc_NtkRetimeTiming_rec( Abc_ObjFanin0(pObj), fForward );
if ( LevelMax < LevelCur )
LevelMax = LevelCur;
}
}
// collect timing critical nodes, which should be retimed forward/backward
Vec_PtrClear( vCritical );
Abc_NtkIncrementTravId(pNtk);
if ( fForward )
{
Vec_PtrForEachEntry( vLatches, pObj, i )
{
Abc_ObjForEachFanout( pObj, pNext, k )
{
if ( Abc_NodeIsTravIdCurrent(pNext) )
continue;
if ( LevelMax != (int)pNext->Level )
continue;
// new critical node
Vec_PtrPush( vCritical, pNext );
Abc_NodeSetTravIdCurrent( pNext );
}
}
}
else
{
Vec_PtrForEachEntry( vLatches, pObj, i )
{
Abc_ObjForEachFanin( pObj, pNext, k )
{
if ( Abc_NodeIsTravIdCurrent(pNext) )
continue;
if ( LevelMax != (int)pNext->Level )
continue;
// new critical node
Vec_PtrPush( vCritical, pNext );
Abc_NodeSetTravIdCurrent( pNext );
}
}
}
Vec_PtrFree( vLatches );
return LevelMax;
}
/**Function*************************************************************
Synopsis [Recursively performs timing analysis.]
Description [Performs static timing analysis on the network. Uses
unit-delay model.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeTiming_rec( Abc_Obj_t * pObj, int fForward )
{
Abc_Obj_t * pNext;
int i, LevelCur, LevelMax = 0;
// skip visited nodes
if ( Abc_NodeIsTravIdCurrent(pObj) )
return pObj->Level;
Abc_NodeSetTravIdCurrent(pObj);
// visit the next nodes
if ( fForward )
{
Abc_ObjForEachFanout( pObj, pNext, i )
{
LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward );
if ( LevelMax < LevelCur )
LevelMax = LevelCur;
}
}
else
{
Abc_ObjForEachFanin( pObj, pNext, i )
{
LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward );
if ( LevelMax < LevelCur )
LevelMax = LevelCur;
}
}
// printf( "Node %3d -> Level %3d.\n", pObj->Id, LevelMax + 1 );
pObj->Level = LevelMax + 1;
return pObj->Level;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -126,9 +126,12 @@ Vec_Ptr_t * Abc_NtkMaxFlow( Abc_Ntk_t * pNtk, int fForward, int fVerbose )
printf( "Abc_NtkMaxFlow() error! The computed min-cut is not a cut!\n" );
// report the results
if ( fVerbose )
{
printf( "Latches = %6d. %s max-flow = %6d. Min-cut = %6d. ",
Abc_NtkLatchNum(pNtk), fForward? "Forward " : "Backward", Flow, Vec_PtrSize(vMinCut) );
PRT( "Time", clock() - clk );
}
// Abc_NtkMaxFlowPrintCut( vMinCut );
return vMinCut;
......@@ -377,6 +380,15 @@ int Abc_NtkMaxFlowVerifyCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward
return 0;
}
}
/*
{
// count the volume of the cut
int Counter = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
Counter += Abc_NodeIsTravIdCurrent( pObj );
printf( "Volume = %d.\n", Counter );
}
*/
return 1;
}
......
/**CFile****************************************************************
FileName [retFwd.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Retiming package.]
Synopsis [Most forward retiming.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - Oct 31, 2006.]
Revision [$Id: retFwd.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
***********************************************************************/
#include "retInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRetimeForward( Abc_Ntk_t * pNtk, int fVerbose )
{
printf( "Not implemented.\n" );
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -44,20 +44,28 @@
////////////////////////////////////////////////////////////////////////
/*=== retArea.c ========================================================*/
extern int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fVerbose );
/*=== retBwd.c ========================================================*/
extern int Abc_NtkRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose );
extern int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fForwardOnly, int fBackwardOnly, int fVerbose );
/*=== retCore.c ========================================================*/
extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fVerbose );
extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fVerbose );
/*=== retDelay.c ========================================================*/
extern int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, int fVerbose );
extern int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkCopy, int nIterLimit, int fForward, int fVerbose );
/*=== retDirect.c ========================================================*/
extern int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int fForward, int fMinDelay, int fVerbose );
extern void Abc_NtkRetimeShareLatches( Abc_Ntk_t * pNtk );
extern int Abc_NtkRetimeNodeIsEnabled( Abc_Obj_t * pObj, int fForward );
extern void Abc_NtkRetimeNode( Abc_Obj_t * pObj, int fForward, int fInitial );
/*=== retFlow.c ========================================================*/
extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_NtkMaxFlow( Abc_Ntk_t * pNtk, int fForward, int fVerbose );
/*=== retFwd.c ========================================================*/
extern int Abc_NtkRetimeForward( Abc_Ntk_t * pNtk, int fVerbose );
/*=== retInit.c ========================================================*/
extern void Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, int fVerbose );
extern Vec_Int_t * Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtkSat, Vec_Int_t * vValues, int fVerbose );
extern int Abc_ObjSopSimulate( Abc_Obj_t * pObj );
extern void Abc_NtkRetimeTranferToCopy( Abc_Ntk_t * pNtk );
extern void Abc_NtkRetimeTranferFromCopy( Abc_Ntk_t * pNtk );
extern Vec_Int_t * Abc_NtkRetimeCollectLatchValues( Abc_Ntk_t * pNtk );
extern void Abc_NtkRetimeInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues );
extern Abc_Ntk_t * Abc_NtkRetimeBackwardInitialStart( Abc_Ntk_t * pNtk );
extern void Abc_NtkRetimeBackwardInitialFinish( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, Vec_Int_t * vValuesOld, int fVerbose );
#endif
......
/**CFile****************************************************************
FileName [esopMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Cover manipulation package.]
Synopsis [SOP manipulation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: esopMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "esop.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the minimization manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Esop_Man_t * Esop_ManAlloc( int nVars )
{
Esop_Man_t * pMan;
// start the manager
pMan = ALLOC( Esop_Man_t, 1 );
memset( pMan, 0, sizeof(Esop_Man_t) );
pMan->nVars = nVars;
pMan->nWords = Esop_BitWordNum( nVars * 2 );
pMan->pMemMan1 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (1 - 1) );
pMan->pMemMan2 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (2 - 1) );
pMan->pMemMan4 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (4 - 1) );
pMan->pMemMan8 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (8 - 1) );
// allocate storage for the temporary cover
pMan->ppStore = ALLOC( Esop_Cube_t *, pMan->nVars + 1 );
// create tautology cubes
Esop_ManClean( pMan, nVars );
pMan->pOne0 = Esop_CubeAlloc( pMan );
pMan->pOne1 = Esop_CubeAlloc( pMan );
pMan->pTemp = Esop_CubeAlloc( pMan );
pMan->pBubble = Esop_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0;
// create trivial cubes
Esop_ManClean( pMan, 1 );
pMan->pTriv0 = Esop_CubeAllocVar( pMan, 0, 0 );
pMan->pTriv1 = Esop_CubeAllocVar( pMan, 0, 0 );
Esop_ManClean( pMan, nVars );
return pMan;
}
/**Function*************************************************************
Synopsis [Cleans the minimization manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_ManClean( Esop_Man_t * p, int nSupp )
{
// set the size of the cube manager
p->nVars = nSupp;
p->nWords = Esop_BitWordNum(2*nSupp);
// clean the storage
memset( p->ppStore, 0, sizeof(Esop_Cube_t *) * (nSupp + 1) );
p->nCubes = 0;
}
/**Function*************************************************************
Synopsis [Stops the minimization manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_ManFree( Esop_Man_t * p )
{
Mem_FixedStop ( p->pMemMan1, 0 );
Mem_FixedStop ( p->pMemMan2, 0 );
Mem_FixedStop ( p->pMemMan4, 0 );
Mem_FixedStop ( p->pMemMan8, 0 );
free( p->ppStore );
free( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [esopMin.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Cover manipulation package.]
Synopsis [ESOP manipulation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: esopMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "esop.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Esop_EsopRewrite( Esop_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [ESOP minimization procedure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_EsopMinimize( Esop_Man_t * p )
{
int nCubesInit, nCubesOld, nIter;
if ( p->nCubes < 3 )
return;
nIter = 0;
nCubesInit = p->nCubes;
do {
nCubesOld = p->nCubes;
Esop_EsopRewrite( p );
nIter++;
}
while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 );
// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes );
}
/**Function*************************************************************
Synopsis [Performs one round of rewriting using distance 2 cubes.]
Description [The weakness of this procedure is that it tries each cube
with only one distance-2 cube. If this pair does not lead to improvement
the cube is inserted into the cover anyhow, and we try another pair.
A possible improvement would be to try this cube with all distance-2
cubes, until an improvement is found, or until all such cubes are tried.]
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_EsopRewrite( Esop_Man_t * p )
{
Esop_Cube_t * pCube, ** ppPrev;
Esop_Cube_t * pThis, ** ppPrevT;
int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld;
int nPairs = 0;
// insert the bubble before the first cube
p->pBubble->pNext = p->ppStore[0];
p->ppStore[0] = p->pBubble;
p->pBubble->nLits = 0;
// go through the cubes
while ( 1 )
{
// get the index of the bubble
Index = p->pBubble->nLits;
// find the bubble
Esop_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev )
if ( pCube == p->pBubble )
break;
assert( pCube == p->pBubble );
// remove the bubble, get the next cube after the bubble
*ppPrev = p->pBubble->pNext;
pCube = p->pBubble->pNext;
if ( pCube == NULL )
for ( Index++; Index <= p->nVars; Index++ )
if ( p->ppStore[Index] )
{
ppPrev = &(p->ppStore[Index]);
pCube = p->ppStore[Index];
break;
}
// stop if there is no more cubes
if ( pCube == NULL )
break;
// find the first dist2 cube
Esop_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
if ( pThis == NULL && Index < p->nVars )
Esop_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
if ( pThis == NULL && Index < p->nVars - 1 )
Esop_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT )
if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
// continue if there is no dist2 cube
if ( pThis == NULL )
{
// insert the bubble after the cube
p->pBubble->pNext = pCube->pNext;
pCube->pNext = p->pBubble;
p->pBubble->nLits = pCube->nLits;
continue;
}
nPairs++;
// remove the cubes, insert the bubble instead of pCube
*ppPrevT = pThis->pNext;
*ppPrev = p->pBubble;
p->pBubble->pNext = pCube->pNext;
p->pBubble->nLits = pCube->nLits;
p->nCubes -= 2;
// Exorlink-2:
// A{v00} B{v01} + A{v10} B{v11} =
// A{v00+v10} B{v01} + A{v10} B{v01+v11} =
// A{v00} B{v01+v11} + A{v00+v10} B{v11}
// save the dist2 parameters
v00 = Esop_CubeGetVar( pCube, Var0 );
v01 = Esop_CubeGetVar( pCube, Var1 );
v10 = Esop_CubeGetVar( pThis, Var0 );
v11 = Esop_CubeGetVar( pThis, Var1 );
//printf( "\n" );
//Esop_CubeWrite( stdout, pCube );
//Esop_CubeWrite( stdout, pThis );
// derive the first pair of resulting cubes
Esop_CubeXorVar( pCube, Var0, v10 );
pCube->nLits -= (v00 != 3);
pCube->nLits += ((v00 ^ v10) != 3);
Esop_CubeXorVar( pThis, Var1, v01 );
pThis->nLits -= (v11 != 3);
pThis->nLits += ((v01 ^ v11) != 3);
// add the cubes
nCubesOld = p->nCubes;
Esop_EsopAddCube( p, pCube );
Esop_EsopAddCube( p, pThis );
// check if the cubes were absorbed
if ( p->nCubes < nCubesOld + 2 )
continue;
// pull out both cubes
assert( pThis == p->ppStore[pThis->nLits] );
p->ppStore[pThis->nLits] = pThis->pNext;
assert( pCube == p->ppStore[pCube->nLits] );
p->ppStore[pCube->nLits] = pCube->pNext;
p->nCubes -= 2;
// derive the second pair of resulting cubes
Esop_CubeXorVar( pCube, Var0, v10 );
pCube->nLits -= ((v00 ^ v10) != 3);
pCube->nLits += (v00 != 3);
Esop_CubeXorVar( pCube, Var1, v11 );
pCube->nLits -= (v01 != 3);
pCube->nLits += ((v01 ^ v11) != 3);
Esop_CubeXorVar( pThis, Var0, v00 );
pThis->nLits -= (v10 != 3);
pThis->nLits += ((v00 ^ v10) != 3);
Esop_CubeXorVar( pThis, Var1, v01 );
pThis->nLits -= ((v01 ^ v11) != 3);
pThis->nLits += (v11 != 3);
// add them anyhow
Esop_EsopAddCube( p, pCube );
Esop_EsopAddCube( p, pThis );
}
// printf( "Pairs = %d ", nPairs );
}
/**Function*************************************************************
Synopsis [Adds the cube to storage.]
Description [Returns 0 if the cube is added or removed. Returns 1
if the cube is glued with some other cube and has to be added again.
Do not forget to clean the storage!]
SideEffects []
SeeAlso []
***********************************************************************/
int Esop_EsopAddCubeInt( Esop_Man_t * p, Esop_Cube_t * pCube )
{
Esop_Cube_t * pThis, ** ppPrev;
// try to find the identical cube
Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
{
if ( Esop_CubesAreEqual( pCube, pThis ) )
{
*ppPrev = pThis->pNext;
Esop_CubeRecycle( p, pCube );
Esop_CubeRecycle( p, pThis );
p->nCubes--;
return 0;
}
}
// find a distance-1 cube if it exists
if ( pCube->nLits < pCube->nVars )
Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev )
{
if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
Esop_CubesTransform( pCube, pThis, p->pTemp );
pCube->nLits++;
Esop_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
}
Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
{
if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
Esop_CubesTransform( pCube, pThis, p->pTemp );
pCube->nLits--;
Esop_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
}
if ( pCube->nLits > 0 )
Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev )
{
if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
Esop_CubesTransform( pCube, pThis, p->pTemp );
Esop_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
}
// add the cube
pCube->pNext = p->ppStore[pCube->nLits];
p->ppStore[pCube->nLits] = pCube;
p->nCubes++;
return 0;
}
/**Function*************************************************************
Synopsis [Adds the cube to storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube )
{
assert( pCube != p->pBubble );
assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) );
while ( Esop_EsopAddCubeInt( p, pCube ) );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [esopUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Cover manipulation package.]
Synopsis [Utilities.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: esopUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "esop.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_CubeWrite( FILE * pFile, Esop_Cube_t * pCube )
{
int i;
assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) );
for ( i = 0; i < (int)pCube->nVars; i++ )
if ( Esop_CubeHasBit(pCube, i*2) )
{
if ( Esop_CubeHasBit(pCube, i*2+1) )
fprintf( pFile, "-" );
else
fprintf( pFile, "0" );
}
else
{
if ( Esop_CubeHasBit(pCube, i*2+1) )
fprintf( pFile, "1" );
else
fprintf( pFile, "?" );
}
fprintf( pFile, " 1\n" );
// fprintf( pFile, " %d\n", pCube->nLits );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_CoverWrite( FILE * pFile, Esop_Cube_t * pCover )
{
Esop_Cube_t * pCube;
Esop_CoverForEachCube( pCover, pCube )
Esop_CubeWrite( pFile, pCube );
printf( "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_CoverWriteStore( FILE * pFile, Esop_Man_t * p )
{
Esop_Cube_t * pCube;
int i;
for ( i = 0; i <= p->nVars; i++ )
{
Esop_CoverForEachCube( p->ppStore[i], pCube )
{
printf( "%2d : ", i );
if ( pCube == p->pBubble )
{
printf( "Bubble\n" );
continue;
}
Esop_CubeWrite( pFile, pCube );
}
}
printf( "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop )
{
char Buffer[1000];
Esop_Cube_t * pCube;
FILE * pFile;
int i;
sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" );
for ( i = strlen(Buffer) - 1; i >= 0; i-- )
if ( Buffer[i] == '<' || Buffer[i] == '>' )
Buffer[i] = '_';
pFile = fopen( Buffer, "w" );
fprintf( pFile, "# %s cover for output %s generated by ABC\n", fEsop? "ESOP":"SOP", pName );
fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 );
fprintf( pFile, ".o %d\n", 1 );
fprintf( pFile, ".p %d\n", Esop_CoverCountCubes(pCover) );
if ( fEsop ) fprintf( pFile, ".type esop\n" );
Esop_CoverForEachCube( pCover, pCube )
Esop_CubeWrite( pFile, pCube );
fprintf( pFile, ".e\n" );
fclose( pFile );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_CoverCheck( Esop_Man_t * p )
{
Esop_Cube_t * pCube;
int i;
for ( i = 0; i <= p->nVars; i++ )
Esop_CoverForEachCube( p->ppStore[i], pCube )
assert( i == (int)pCube->nLits );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Esop_CubeCheck( Esop_Cube_t * pCube )
{
int i;
for ( i = 0; i < (int)pCube->nVars; i++ )
if ( Esop_CubeGetVar( pCube, i ) == 0 )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Converts the cover from the sorted structure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Esop_Cube_t * Esop_CoverCollect( Esop_Man_t * p, int nSuppSize )
{
Esop_Cube_t * pCov = NULL, ** ppTail = &pCov;
Esop_Cube_t * pCube, * pCube2;
int i;
for ( i = 0; i <= nSuppSize; i++ )
{
Esop_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 )
{
assert( i == (int)pCube->nLits );
*ppTail = pCube;
ppTail = &pCube->pNext;
assert( pCube->uData[0] ); // not a bubble
}
}
*ppTail = NULL;
return pCov;
}
/**Function*************************************************************
Synopsis [Sorts the cover in the increasing number of literals.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Esop_CoverExpand( Esop_Man_t * p, Esop_Cube_t * pCover )
{
Esop_Cube_t * pCube, * pCube2;
Esop_ManClean( p, p->nVars );
Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
{
pCube->pNext = p->ppStore[pCube->nLits];
p->ppStore[pCube->nLits] = pCube;
p->nCubes++;
}
}
/**Function*************************************************************
Synopsis [Sorts the cover in the increasing number of literals.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Esop_CoverSuppVarNum( Esop_Man_t * p, Esop_Cube_t * pCover )
{
Esop_Cube_t * pCube;
int i, Counter;
if ( pCover == NULL )
return 0;
// clean the cube
for ( i = 0; i < (int)pCover->nWords; i++ )
p->pTemp->uData[i] = ~((unsigned)0);
// add the bit data
Esop_CoverForEachCube( pCover, pCube )
for ( i = 0; i < (int)pCover->nWords; i++ )
p->pTemp->uData[i] &= pCube->uData[i];
// count the vars
Counter = 0;
for ( i = 0; i < (int)pCover->nVars; i++ )
Counter += ( Esop_CubeGetVar(p->pTemp, i) != 3 );
return Counter;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
SRC += src/temp/esop/esopMan.c \
src/temp/esop/esopMin.c \
src/temp/esop/esopUtil.c
......@@ -136,6 +136,7 @@ struct Ivy_FraigParams_t_
double dActConeBumpMax; // the largest bump in activity
int fProve; // prove the miter outputs
int fVerbose; // verbose output
int fDoSparse; // skip sparse functions
int nBTLimitNode; // conflict limit at a node
int nBTLimitMiter; // conflict limit at an output
int nBTLimitGlobal; // conflict limit global
......
......@@ -216,6 +216,7 @@ void Ivy_FraigParamsDefault( Ivy_FraigParams_t * pParams )
pParams->dSimSatur = 0.005; // the ratio of refined classes when saturation is reached
pParams->fPatScores = 0; // enables simulation pattern scoring
pParams->MaxScore = 25; // max score after which resimulation is used
pParams->fDoSparse = 1; // skips sparse functions
// pParams->dActConeRatio = 0.05; // the ratio of cone to be bumped
// pParams->dActConeBumpMax = 5.0; // the largest bump of activity
pParams->dActConeRatio = 0.3; // the ratio of cone to be bumped
......@@ -1227,6 +1228,69 @@ int Ivy_FraigRefineClass_rec( Ivy_FraigMan_t * p, Ivy_Obj_t * pClass )
RetValue = Ivy_FraigRefineClass_rec( p, pClassNew );
return RetValue + 1;
}
/**Function*************************************************************
Synopsis [Creates the counter-example from the successful pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_FraigCheckOutputSimsSavePattern( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj )
{
Ivy_FraigSim_t * pSims;
int i, k, BestPat, * pModel;
// find the word of the pattern
pSims = Ivy_ObjSim(pObj);
for ( i = 0; i < p->nSimWords; i++ )
if ( pSims->pData[i] )
break;
assert( i < p->nSimWords );
// find the bit of the pattern
for ( k = 0; k < 32; k++ )
if ( pSims->pData[i] & (1 << k) )
break;
assert( k < 32 );
// determine the best pattern
BestPat = i * 32 + k;
// fill in the counter-example data
pModel = ALLOC( int, Ivy_ManPiNum(p->pManFraig) );
Ivy_ManForEachPi( p->pManAig, pObj, i )
pModel[i] = Ivy_InfoHasBit(Ivy_ObjSim(pObj)->pData, BestPat);
// set the model
assert( p->pManFraig->pData == NULL );
p->pManFraig->pData = pModel;
return;
}
/**Function*************************************************************
Synopsis [Returns 1 if the one of the output is already non-constant 0.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_FraigCheckOutputSims( Ivy_FraigMan_t * p )
{
Ivy_Obj_t * pObj;
int i;
Ivy_ManForEachPo( p->pManAig, pObj, i )
if ( !Ivy_NodeHasZeroSim( p, Ivy_ObjFanin0(pObj) ) )
{
// create the counter-example from this pattern
Ivy_FraigCheckOutputSimsSavePattern( p, Ivy_ObjFanin0(pObj) );
return 1;
}
return 0;
}
/**Function*************************************************************
......@@ -1244,6 +1308,13 @@ int Ivy_FraigRefineClasses( Ivy_FraigMan_t * p )
{
Ivy_Obj_t * pClass, * pClass2;
int clk, RetValue, Counter = 0;
// check if some outputs already became non-constant
// this is a special case when computation can be stopped!!!
if ( p->pParams->fProve )
Ivy_FraigCheckOutputSims( p );
if ( p->pManFraig->pData )
return 0;
// refine the classed
clk = clock();
Ivy_FraigForEachEquivClassSafe( p->lClasses.pHead, pClass, pClass2 )
{
......@@ -1447,27 +1518,6 @@ void Ivy_FraigSavePattern3( Ivy_FraigMan_t * p )
/**Function*************************************************************
Synopsis [Returns 1 if the one of the output is already non-constant 0.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_FraigCheckOutputSims( Ivy_FraigMan_t * p )
{
Ivy_Obj_t * pObj;
int i;
Ivy_ManForEachPo( p->pManAig, pObj, i )
if ( !Ivy_NodeHasZeroSim( p, Ivy_ObjFanin0(pObj) ) )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Performs simulation of the manager.]
Description []
......@@ -1490,11 +1540,15 @@ void Ivy_FraigSimulate( Ivy_FraigMan_t * p )
Ivy_FraigAssignDist1( p, p->pPatWords );
Ivy_FraigSimulateOne( p );
nChanges = Ivy_FraigRefineClasses( p );
if ( p->pManFraig->pData )
return;
//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) );
Ivy_FraigSavePattern1( p );
Ivy_FraigAssignDist1( p, p->pPatWords );
Ivy_FraigSimulateOne( p );
nChanges = Ivy_FraigRefineClasses( p );
if ( p->pManFraig->pData )
return;
//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) );
// refine classes by random simulation
do {
......@@ -1502,13 +1556,11 @@ void Ivy_FraigSimulate( Ivy_FraigMan_t * p )
Ivy_FraigSimulateOne( p );
nClasses = p->lClasses.nItems;
nChanges = Ivy_FraigRefineClasses( p );
if ( p->pManFraig->pData )
return;
//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) );
} while ( (double)nChanges / nClasses > p->pParams->dSimSatur );
// Ivy_FraigPrintSimClasses( p );
// check if some outputs already became non-constant
// if ( Ivy_FraigCheckOutputSims(p) )
// printf( "Special case: One of the POs is already non-const zero.\n" );
}
......@@ -1620,6 +1672,8 @@ void Ivy_FraigResimulate( Ivy_FraigMan_t * p )
if ( p->pParams->fPatScores )
Ivy_FraigCleanPatScores( p );
nChanges = Ivy_FraigRefineClasses( p );
if ( p->pManFraig->pData )
return;
if ( nChanges < 1 )
printf( "Error: A counter-example did not refine classes!\n" );
assert( nChanges >= 1 );
......@@ -1635,6 +1689,8 @@ void Ivy_FraigResimulate( Ivy_FraigMan_t * p )
Ivy_FraigSimulateOne( p );
Ivy_FraigCleanPatScores( p );
nChanges = Ivy_FraigRefineClasses( p );
if ( p->pManFraig->pData )
return;
//printf( "Refined class!!! = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) );
if ( nChanges == 0 )
break;
......@@ -1765,6 +1821,14 @@ void Ivy_FraigMiterProve( Ivy_FraigMan_t * p )
memset( p->pManFraig->pData, 0, sizeof(int) * Ivy_ManPiNum(p->pManFraig) );
break;
}
/*
// check the representative of this node
pRepr = Ivy_ObjClassNodeRepr(Ivy_ObjFanin0(pObj));
if ( Ivy_Regular(pRepr) != p->pManAig->pConst1 )
printf( "Representative is not constant 1.\n" );
else
printf( "Representative is constant 1.\n" );
*/
// try to prove the output constant 0
RetValue = Ivy_FraigNodeIsConst( p, Ivy_Regular(pObjNew) );
if ( RetValue == 1 ) // proved equivalent
......@@ -1816,7 +1880,11 @@ p->nClassesBeg = p->lClasses.nItems;
Ivy_ManForEachNode( p->pManAig, pObj, i )
{
Extra_ProgressBarUpdate( p->pProgress, k++, NULL );
pObj->pEquiv = Ivy_FraigAnd( p, pObj );
// default to simple strashing if simulation detected a counter-example for a PO
if ( p->pManFraig->pData )
pObj->pEquiv = Ivy_And( p->pManFraig, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) );
else
pObj->pEquiv = Ivy_FraigAnd( p, pObj );
assert( pObj->pEquiv != NULL );
// pTemp = Ivy_Regular(pObj->pEquiv);
// assert( Ivy_Regular(pObj->pEquiv)->Type );
......@@ -1826,7 +1894,7 @@ p->nClassesEnd = p->lClasses.nItems;
// try to prove the outputs of the miter
p->nNodesMiter = Ivy_ManNodeNum(p->pManFraig);
// Ivy_FraigMiterStatus( p->pManFraig );
if ( p->pParams->fProve )
if ( p->pParams->fProve && p->pManFraig->pData == NULL )
Ivy_FraigMiterProve( p );
// add the POs
Ivy_ManForEachPo( p->pManAig, pObj, i )
......@@ -1860,7 +1928,7 @@ p->nClassesEnd = p->lClasses.nItems;
***********************************************************************/
Ivy_Obj_t * Ivy_FraigAnd( Ivy_FraigMan_t * p, Ivy_Obj_t * pObjOld )
{
{
Ivy_Obj_t * pObjNew, * pFanin0New, * pFanin1New, * pObjReprNew;
int RetValue;
// get the fraiged fanins
......@@ -1869,8 +1937,13 @@ Ivy_Obj_t * Ivy_FraigAnd( Ivy_FraigMan_t * p, Ivy_Obj_t * pObjOld )
// get the candidate fraig node
pObjNew = Ivy_And( p->pManFraig, pFanin0New, pFanin1New );
// get representative of this class
if ( Ivy_ObjClassNodeRepr(pObjOld) == NULL ) // this is a unique node
if ( Ivy_ObjClassNodeRepr(pObjOld) == NULL || // this is a unique node
(!p->pParams->fDoSparse && Ivy_ObjClassNodeRepr(pObjOld) == p->pManAig->pConst1) ) // this is a sparse node
{
// if ( Ivy_ObjClassNodeRepr(pObjOld) == p->pManAig->pConst1 )
// {
// int x = 0;
// }
assert( Ivy_Regular(pFanin0New) != Ivy_Regular(pFanin1New) );
assert( pObjNew != Ivy_Regular(pFanin0New) );
assert( pObjNew != Ivy_Regular(pFanin1New) );
......
......@@ -411,7 +411,7 @@ int Ivy_ManLatchIsSelfFeed( Ivy_Obj_t * pLatch )
int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel )
{
Ivy_Obj_t * pNode;
int LimitFactor = 100;
int LimitFactor = 5;
int NodeBeg = Ivy_ManNodeNum(p);
int nSteps;
for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ )
......@@ -430,7 +430,8 @@ int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel )
Ivy_NodeFixBufferFanins( p, pNode, fUpdateLevel );
if ( nSteps > NodeBeg * LimitFactor )
{
printf( "This circuit cannot be forward retimed completely. Structural hashing is not finished after %d forward latch moves.\n", NodeBeg * LimitFactor );
printf( "Structural hashing is not finished after %d forward latch moves.\n", NodeBeg * LimitFactor );
printf( "This circuit cannot be forward-retimed completely. Quitting.\n" );
break;
}
}
......
SRC += src/temp/player/playerToAbc.c \
src/temp/player/playerCore.c \
src/temp/player/playerMan.c \
src/temp/player/playerUtil.c
/**CFile****************************************************************
FileName [player.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [PLA decomposition package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: player.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __XYZ_H__
#define __XYZ_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "ivy.h"
#include "esop.h"
#include "vec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef struct Pla_Man_t_ Pla_Man_t;
typedef struct Pla_Obj_t_ Pla_Obj_t;
// storage for node information
struct Pla_Obj_t_
{
unsigned fFixed : 1; // fixed node
unsigned Depth : 31; // the depth in terms of LUTs/PLAs
int nRefs; // the number of references
Vec_Int_t vSupp[2]; // supports in two frames
Esop_Cube_t * pCover[2]; // esops in two frames
};
// storage for additional information
struct Pla_Man_t_
{
// general characteristics
int nLutMax; // the number of vars
int nPlaMax; // the number of vars
int nCubesMax; // the limit on the number of cubes in the intermediate covers
Ivy_Man_t * pManAig; // the AIG manager
Pla_Obj_t * pPlaStrs; // memory for structures
Esop_Man_t * pManMin; // the cube manager
// arrays to map local variables
Vec_Int_t * vComTo0; // mapping of common variables into first fanin
Vec_Int_t * vComTo1; // mapping of common variables into second fanin
Vec_Int_t * vPairs0; // the first var in each pair of common vars
Vec_Int_t * vPairs1; // the second var in each pair of common vars
Vec_Int_t * vTriv0; // trival support of the first node
Vec_Int_t * vTriv1; // trival support of the second node
// statistics
int nNodes; // the number of nodes processed
int nNodesLut; // the number of nodes processed
int nNodesPla; // the number of nodes processed
int nNodesBoth; // the number of nodes processed
int nNodesDeref; // the number of nodes processed
};
#define PLAYER_FANIN_LIMIT 128
#define PLA_MIN(a,b) (((a) < (b))? (a) : (b))
#define PLA_MAX(a,b) (((a) > (b))? (a) : (b))
#define PLA_EMPTY ((Esop_Cube_t *)1)
static inline Pla_Man_t * Ivy_ObjPlaMan( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return (Pla_Man_t *)p->pData; }
static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return ((Pla_Man_t *)p->pData)->pPlaStrs + pObj->Id; }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/*=== playerToAbc.c ==============================================================*/
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose );
/*=== playerCore.c =============================================================*/
extern Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose );
/*=== playerMan.c ==============================================================*/
extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax );
extern void Pla_ManFree( Pla_Man_t * p );
extern void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr );
/*=== playerUtil.c =============================================================*/
extern int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp );
extern Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit );
extern Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit );
extern void Pla_ManComputeStats( Ivy_Man_t * pAig, Vec_Int_t * vNodes );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [playerAbc.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [PLAyer decomposition package.]
Synopsis [Bridge between ABC and PLAyer.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 20, 2006.]
Revision [$Id: playerAbc.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "player.h"
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p );
static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#if 0
/**Function*************************************************************
Synopsis [Gives the current ABC network to PLAyer for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose )
{
int fUseRewriting = 1;
Ivy_Man_t * pMan, * pManExt;
Abc_Ntk_t * pNtkAig;
if ( !Abc_NtkIsStrash(pNtk) )
return NULL;
// convert to the new AIG manager
pMan = Ivy_ManFromAbc( pNtk );
// check the correctness of conversion
if ( !Ivy_ManCheck( pMan ) )
{
printf( "Abc_NtkPlayer: Internal AIG check has failed.\n" );
Ivy_ManStop( pMan );
return NULL;
}
if ( fVerbose )
Ivy_ManPrintStats( pMan );
if ( fUseRewriting )
{
// simplify
pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 );
Ivy_ManStop( pManExt );
if ( fVerbose )
Ivy_ManPrintStats( pMan );
}
// perform decomposition/mapping into PLAs/LUTs
pManExt = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
Ivy_ManStop( pMan );
pMan = pManExt;
if ( fVerbose )
Ivy_ManPrintStats( pMan );
// convert from the extended AIG manager into an SOP network
pNtkAig = Ivy_ManToAbc( pNtk, pMan );
Ivy_ManStop( pMan );
// chech the resulting network
if ( !Abc_NtkCheck( pNtkAig ) )
{
printf( "Abc_NtkPlayer: The network check has failed.\n" );
Abc_NtkDelete( pNtkAig );
return NULL;
}
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Converts from strashed AIG in ABC into strash AIG in IVY.]
Description [Assumes DFS ordering of nodes in the AIG of ABC.]
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk )
{
Ivy_Man_t * pMan;
Abc_Obj_t * pObj;
int i;
// create the manager
pMan = Ivy_ManStart( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), Abc_NtkNodeNum(pNtk) + 10 );
// create the PIs
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i);
// perform the conversion of the internal nodes
Abc_AigForEachAnd( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Ivy_And( (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) );
// create the POs
Abc_NtkForEachCo( pNtk, pObj, i )
Ivy_ObjConnect( Ivy_ManPo(pMan, i), (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) );
Ivy_ManCleanup( pMan );
return pMan;
}
/**Function*************************************************************
Synopsis [Converts AIG manager after PLA/LUT mapping into a logic ABC network.]
Description [The AIG manager contains nodes with extended functionality.
Node types are in pObj->Type. Node fanins are in pObj->vFanins. Functions
of LUT nodes are in pMan->vTruths.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
{
Abc_Ntk_t * pNtkNew;
Vec_Int_t * vIvyNodes, * vIvyFanins, * vTruths = pMan->vTruths;
Abc_Obj_t * pObj, * pObjNew, * pFaninNew;
Ivy_Obj_t * pIvyNode, * pIvyFanin;
int pCompls[PLAYER_FANIN_LIMIT];
int i, k, Fanin, nFanins;
// start the new ABC network
pNtkNew = Abc_NtkStartFrom( pNtkOld, ABC_NTK_LOGIC, ABC_FUNC_SOP );
// transfer the pointers to the basic nodes
Ivy_ManCleanTravId(pMan);
Ivy_ManConst1(pMan)->TravId = Abc_AigConst1(pNtkNew)->Id;
Abc_NtkForEachCi( pNtkNew, pObjNew, i )
Ivy_ManPi(pMan, i)->TravId = pObjNew->Id;
// construct the logic network isomorphic to logic network in the AIG manager
vIvyNodes = Ivy_ManDfsExt( pMan );
Ivy_ManForEachNodeVec( pMan, vIvyNodes, pIvyNode, i )
{
// get fanins of the old node
vIvyFanins = Ivy_ObjGetFanins( pIvyNode );
nFanins = Vec_IntSize(vIvyFanins);
// create the new node
pObjNew = Abc_NtkCreateNode( pNtkNew );
Vec_IntForEachEntry( vIvyFanins, Fanin, k )
{
pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_EdgeId(Fanin) );
pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
Abc_ObjAddFanin( pObjNew, pFaninNew );
pCompls[k] = Ivy_EdgeIsComplement(Fanin);
assert( Ivy_ObjIsAndMulti(pIvyNode) || nFanins == 1 || pCompls[k] == 0 ); // EXOR/LUT cannot have complemented fanins
}
assert( k <= PLAYER_FANIN_LIMIT );
// create logic function of the node
if ( Ivy_ObjIsAndMulti(pIvyNode) )
pObjNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, nFanins, pCompls );
else if ( Ivy_ObjIsExorMulti(pIvyNode) )
pObjNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nFanins );
else if ( Ivy_ObjIsLut(pIvyNode) )
pObjNew->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, nFanins, Ivy_ObjGetTruth(pIvyNode) );
else assert( 0 );
assert( Abc_SopGetVarNum(pObjNew->pData) == nFanins );
pIvyNode->TravId = pObjNew->Id;
}
//Pla_ManComputeStats( pMan, vIvyNodes );
Vec_IntFree( vIvyNodes );
// connect the PO nodes
Abc_NtkForEachCo( pNtkOld, pObj, i )
{
// get the old fanin of the PO node
vIvyFanins = Ivy_ObjGetFanins( Ivy_ManPo(pMan, i) );
Fanin = Vec_IntEntry( vIvyFanins, 0 );
pIvyFanin = Ivy_ManObj( pMan, Ivy_EdgeId(Fanin) );
// get the new ABC node corresponding to the old fanin
pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
if ( Ivy_EdgeIsComplement(Fanin) ) // complement
{
// pFaninNew = Abc_NtkCreateNodeInv(pNtkNew, pFaninNew);
if ( Abc_ObjIsCi(pFaninNew) )
pFaninNew = Abc_NtkCreateNodeInv(pNtkNew, pFaninNew);
else
{
// clone the node
pObjNew = Abc_NtkCloneObj( pFaninNew );
// set complemented functions
pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pFaninNew->pData );
Abc_SopComplement(pObjNew->pData);
// return the new node
pFaninNew = pObjNew;
}
assert( Abc_SopGetVarNum(pFaninNew->pData) == Abc_ObjFaninNum(pFaninNew) );
}
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
}
// remove dangling nodes
Abc_NtkForEachNode(pNtkNew, pObj, i)
if ( Abc_ObjFanoutNum(pObj) == 0 )
Abc_NtkDeleteObj(pObj);
// fix CIs feeding directly into COs
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
return pNtkNew;
}
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [playerBuild.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [PLA decomposition package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006.]
Revision [$Id: playerBuild.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "player.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld );
static Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Esop_Cube_t * pCube, Vec_Int_t * vSupp );
static Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 );
static int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#if 0
/**Function*************************************************************
Synopsis [Constructs the AIG manager (IVY) for the network after mapping.]
Description [Uses extended node types (multi-input AND, multi-input EXOR, LUT).]
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * pOld )
{
Ivy_Man_t * pNew;
Ivy_Obj_t * pObjOld, * pObjNew;
int i;
// start the new manager
pNew = Ivy_ManStart( Ivy_ManPiNum(pOld), Ivy_ManPoNum(pOld), 2*Ivy_ManNodeNum(pOld) + 10 );
pNew->fExtended = 1;
// transfer the const/PI numbers
Ivy_ManCleanTravId(pOld);
Ivy_ManConst1(pOld)->TravId = Ivy_ManConst1(pNew)->Id;
Ivy_ManForEachPi( pOld, pObjOld, i )
pObjOld->TravId = Ivy_ManPi(pNew, i)->Id;
// recursively construct the network
Ivy_ManForEachPo( pOld, pObjOld, i )
{
pObjNew = Pla_ManToAig_rec( pNew, Ivy_ObjFanin0(pObjOld) );
Ivy_ObjStartFanins( Ivy_ManPo(pNew, i), 1 );
Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_EdgeCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) );
}
// compute the LUT functions
Pla_ManToAigLutFuncs( pNew, pOld );
return pNew;
}
/**Function*************************************************************
Synopsis [Recursively construct the new node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld )
{
Pla_Man_t * p = Ivy_ObjMan(pObjOld)->pData;
Vec_Int_t * vSupp;
Esop_Cube_t * pCover, * pCube;
Ivy_Obj_t * pFaninOld, * pFaninNew, * pObjNew;
Pla_Obj_t * pStr;
int Entry, nCubes, ObjNewId, i;
// skip the node if it is a constant or already processed
if ( Ivy_ObjIsConst1(pObjOld) || pObjOld->TravId )
return Ivy_ManObj( pNew, pObjOld->TravId );
assert( Ivy_ObjIsAnd(pObjOld) || Ivy_ObjIsExor(pObjOld) );
// get the support and the cover
pStr = Ivy_ObjPlaStr( pNew, pObjOld );
if ( Vec_IntSize( &pStr->vSupp[0] ) <= p->nLutMax )
{
vSupp = &pStr->vSupp[0];
pCover = PLA_EMPTY;
}
else
{
vSupp = &pStr->vSupp[1];
pCover = pStr->pCover[1];
assert( pCover != PLA_EMPTY );
}
// process the fanins
Vec_IntForEachEntry( vSupp, Entry, i )
Pla_ManToAig_rec( pNew, Ivy_ObjObj(pObjOld, Entry) );
// consider the case of a LUT
if ( pCover == PLA_EMPTY )
{
pObjNew = Ivy_ObjCreateExt( pNew, IVY_LUT );
Ivy_ObjStartFanins( pObjNew, p->nLutMax );
// remember new object ID in case it changes
ObjNewId = pObjNew->Id;
Vec_IntForEachEntry( vSupp, Entry, i )
{
pFaninOld = Ivy_ObjObj( pObjOld, Entry );
Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninOld->TravId, 0) );
}
// get the new object
pObjNew = Ivy_ManObj(pNew, ObjNewId);
}
else
{
// for each cube, construct the node
nCubes = Esop_CoverCountCubes( pCover );
if ( nCubes == 0 )
pObjNew = Ivy_ManToAigConst( pNew, 0 );
else if ( nCubes == 1 )
pObjNew = Ivy_ManToAigCube( pNew, pObjOld, pCover, vSupp );
else
{
pObjNew = Ivy_ObjCreateExt( pNew, IVY_EXORM );
Ivy_ObjStartFanins( pObjNew, p->nLutMax );
// remember new object ID in case it changes
ObjNewId = pObjNew->Id;
Esop_CoverForEachCube( pCover, pCube )
{
pFaninNew = Ivy_ManToAigCube( pNew, pObjOld, pCube, vSupp );
Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninNew->Id, 0) );
}
// get the new object
pObjNew = Ivy_ManObj(pNew, ObjNewId);
}
}
pObjOld->TravId = pObjNew->Id;
pObjNew->TravId = pObjOld->Id;
return pObjNew;
}
/**Function*************************************************************
Synopsis [Returns constant 1 node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 )
{
Ivy_Obj_t * pObjNew;
pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM );
Ivy_ObjStartFanins( pObjNew, 1 );
Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate(0, !fConst1) );
return pObjNew;
}
/**Function*************************************************************
Synopsis [Derives the decomposed network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Esop_Cube_t * pCube, Vec_Int_t * vSupp )
{
Ivy_Obj_t * pObjNew, * pFaninOld;
int i, Value;
// if tautology cube, create constant 1 node
if ( pCube->nLits == 0 )
return Ivy_ManToAigConst( pNew, 1 );
// create AND node
pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM );
Ivy_ObjStartFanins( pObjNew, pCube->nLits );
// add fanins
for ( i = 0; i < (int)pCube->nVars; i++ )
{
Value = Esop_CubeGetVar( pCube, i );
assert( Value != 0 );
if ( Value == 3 )
continue;
pFaninOld = Ivy_ObjObj( pObjOld, Vec_IntEntry(vSupp, i) );
Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate( pFaninOld->TravId, Value==1 ) );
}
assert( Ivy_ObjFaninNum(pObjNew) == (int)pCube->nLits );
return pObjNew;
}
/**Function*************************************************************
Synopsis [Recursively construct the new node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld )
{
Vec_Int_t * vSupp, * vFanins, * vNodes, * vTemp;
Ivy_Obj_t * pObjOld, * pObjNew;
unsigned * pComputed, * pTruth;
int i, k, Counter = 0;
// create mapping from the LUT nodes into truth table indices
assert( pNew->vTruths == NULL );
vNodes = Vec_IntAlloc( 100 );
vTemp = Vec_IntAlloc( 100 );
pNew->vTruths = Vec_IntStart( Ivy_ManObjIdNext(pNew) );
Ivy_ManForEachObj( pNew, pObjNew, i )
{
if ( Ivy_ObjIsLut(pObjNew) )
Vec_IntWriteEntry( pNew->vTruths, i, 8 * Counter++ );
else
Vec_IntWriteEntry( pNew->vTruths, i, -1 );
}
// allocate memory
pNew->pMemory = ALLOC( unsigned, 8 * Counter );
memset( pNew->pMemory, 0, sizeof(unsigned) * 8 * Counter );
// derive truth tables
Ivy_ManForEachObj( pNew, pObjNew, i )
{
if ( !Ivy_ObjIsLut(pObjNew) )
continue;
pObjOld = Ivy_ManObj( pOld, pObjNew->TravId );
vSupp = Ivy_ObjPlaStr(pNew, pObjOld)->vSupp;
assert( Vec_IntSize(vSupp) <= 8 );
pTruth = Ivy_ObjGetTruth( pObjNew );
pComputed = Ivy_ManCutTruth( pNew, pObjOld, vSupp, vNodes, vTemp );
// check if the truth table is constant 0
for ( k = 0; k < 8; k++ )
if ( pComputed[k] )
break;
if ( k == 8 )
{
// create inverter
for ( k = 0; k < 8; k++ )
pComputed[k] = 0x55555555;
// point it to the constant 1 node
vFanins = Ivy_ObjGetFanins( pObjNew );
Vec_IntClear( vFanins );
Vec_IntPush( vFanins, Ivy_EdgeCreate(0, 1) );
}
memcpy( pTruth, pComputed, sizeof(unsigned) * 8 );
// Extra_PrintBinary( stdout, pTruth, 16 ); printf( "\n" );
}
Vec_IntFree( vTemp );
Vec_IntFree( vNodes );
return Counter;
}
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [playerMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [PLA decomposition package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006.]
Revision [$Id: playerMan.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "player.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates the PLA/LUT mapping manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * pAig, int nLutMax, int nPlaMax )
{
Pla_Man_t * pMan;
assert( !(nLutMax < 2 || nLutMax > 8 || nPlaMax < 8 || nPlaMax > 128) );
// start the manager
pMan = ALLOC( Pla_Man_t, 1 );
memset( pMan, 0, sizeof(Pla_Man_t) );
pMan->nLutMax = nLutMax;
pMan->nPlaMax = nPlaMax;
pMan->nCubesMax = 2 * nPlaMax; // higher limit, later reduced
pMan->pManAig = pAig;
// set up the temporaries
pMan->vComTo0 = Vec_IntAlloc( 2 * nPlaMax );
pMan->vComTo1 = Vec_IntAlloc( 2 * nPlaMax );
pMan->vPairs0 = Vec_IntAlloc( nPlaMax );
pMan->vPairs1 = Vec_IntAlloc( nPlaMax );
pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 );
pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 );
// allocate memory for object structures
pMan->pPlaStrs = ALLOC( Pla_Obj_t, Ivy_ManObjIdMax(pAig)+1 );
memset( pMan->pPlaStrs, 0, sizeof(Pla_Obj_t) * (Ivy_ManObjIdMax(pAig)+1) );
// create the cube manager
pMan->pManMin = Esop_ManAlloc( nPlaMax );
// save the resulting manager
assert( pAig->pData == NULL );
pAig->pData = pMan;
return pMan;
}
/**Function*************************************************************
Synopsis [Frees the PLA/LUT mapping manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pla_ManFree( Pla_Man_t * p )
{
Pla_Obj_t * pStr;
int i;
Esop_ManFree( p->pManMin );
Vec_IntFree( p->vTriv0 );
Vec_IntFree( p->vTriv1 );
Vec_IntFree( p->vComTo0 );
Vec_IntFree( p->vComTo1 );
Vec_IntFree( p->vPairs0 );
Vec_IntFree( p->vPairs1 );
for ( i = 0, pStr = p->pPlaStrs; i <= Ivy_ManObjIdMax(p->pManAig); i++, pStr++ )
FREE( pStr->vSupp[0].pArray ), FREE( pStr->vSupp[1].pArray );
free( p->pPlaStrs );
free( p );
}
/**Function*************************************************************
Synopsis [Cleans the PLA/LUT structure of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr )
{
if ( pStr->pCover[0] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[0] );
if ( pStr->pCover[1] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[1] );
if ( pStr->vSupp[0].pArray ) free( pStr->vSupp[0].pArray );
if ( pStr->vSupp[1].pArray ) free( pStr->vSupp[1].pArray );
memset( pStr, 0, sizeof(Pla_Obj_t) );
pStr->pCover[0] = PLA_EMPTY;
pStr->pCover[1] = PLA_EMPTY;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment