Commit 7ff4c2b2 by Alan Mishchenko

Version abc80420

parent b51685d6
......@@ -3142,6 +3142,10 @@ SOURCE=.\src\aig\nwk\nwk.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\nwk\nwkAig.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\nwk\nwkBidec.c
# End Source File
# Begin Source File
......@@ -3158,6 +3162,10 @@ SOURCE=.\src\aig\nwk\nwkFanio.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\nwk\nwkFlow.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\nwk\nwkMan.c
# End Source File
# Begin Source File
......
......@@ -66,7 +66,10 @@ typedef enum {
// the AIG node
struct Aig_Obj_t_ // 8 words
{
Aig_Obj_t * pNext; // strashing table
union {
Aig_Obj_t * pNext; // strashing table
int PioNum; // the number of PI/PO
};
Aig_Obj_t * pFanin0; // fanin
Aig_Obj_t * pFanin1; // fanin
Aig_Obj_t * pHaig; // pointer to the HAIG node
......@@ -551,6 +554,7 @@ extern void Aig_ManReprStop( Aig_Man_t * p );
extern void Aig_ObjCreateRepr( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * pNode2 );
extern void Aig_ManTransferRepr( Aig_Man_t * pNew, Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p, int fOrdered );
extern Aig_Man_t * Aig_ManDupReprBasic( Aig_Man_t * p );
extern int Aig_ManCountReprs( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManRehash( Aig_Man_t * p );
extern int Aig_ObjCheckTfi( Aig_Man_t * p, Aig_Obj_t * pNew, Aig_Obj_t * pOld );
......@@ -563,6 +567,7 @@ extern Aig_Man_t * Aig_ManRetimeFrontier( Aig_Man_t * p, int nStepsMax );
/*=== aigScl.c ==========================================================*/
extern Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap );
extern int Aig_ManSeqCleanup( Aig_Man_t * p );
extern int Aig_ManSeqCleanupBasic( Aig_Man_t * p );
extern int Aig_ManCountMergeRegs( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose );
extern void Aig_ManComputeSccs( Aig_Man_t * p );
......
......@@ -50,6 +50,8 @@ Aig_Man_t * Aig_ManDup( Aig_Man_t * p )
pNew->pName = Aig_UtilStrsav( p->pName );
pNew->pSpec = Aig_UtilStrsav( p->pSpec );
pNew->nRegs = p->nRegs;
pNew->nTruePis = p->nTruePis;
pNew->nTruePos = p->nTruePos;
pNew->nAsserts = p->nAsserts;
if ( p->vFlopNums )
pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
......
......@@ -302,6 +302,34 @@ Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p, int fOrdered )
/**Function*************************************************************
Synopsis [Duplicates AIG with representatives without removing registers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManDupReprBasic( Aig_Man_t * p )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj;
int i;
assert( p->pReprs != NULL );
// reconstruct AIG with representatives
pNew = Aig_ManDupRepr( p, 0 );
// perfrom sequential cleanup but do not remove registers
Aig_ManSeqCleanupBasic( pNew );
// remove pointers to the dead nodes
Aig_ManForEachObj( p, pObj, i )
if ( pObj->pData && Aig_ObjIsNone(pObj->pData) )
pObj->pData = NULL;
return pNew;
}
/**Function*************************************************************
Synopsis [Transfer representatives and return the number of critical fanouts.]
Description []
......
......@@ -240,6 +240,60 @@ int Aig_ManSeqCleanup( Aig_Man_t * p )
Synopsis [Returns the number of dangling nodes removed.]
Description [This cleanup procedure is different in that
it removes logic but does not remove the dangling latches.]
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManSeqCleanupBasic( Aig_Man_t * p )
{
Vec_Ptr_t * vNodes;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i;
// assert( Aig_ManBufNum(p) == 0 );
// mark the PIs
Aig_ManIncrementTravId( p );
Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
Aig_ManForEachPiSeq( p, pObj, i )
Aig_ObjSetTravIdCurrent( p, pObj );
// prepare to collect nodes reachable from POs
vNodes = Vec_PtrAlloc( 100 );
Aig_ManForEachPoSeq( p, pObj, i )
Vec_PtrPush( vNodes, pObj );
// remember latch inputs in latch outputs
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
pObjLo->pNext = pObjLi;
// mark the nodes reachable from these nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
Aig_ManSeqCleanup_rec( p, pObj, vNodes );
assert( Vec_PtrSize(vNodes) <= Aig_ManPoNum(p) );
// clean latch output pointers
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
pObjLo->pNext = NULL;
// if some latches are removed, update PIs/POs
if ( Vec_PtrSize(vNodes) < Aig_ManPoNum(p) )
{
// add constant drivers to the dangling latches
Aig_ManForEachPo( p, pObj, i )
if ( !Aig_ObjIsTravIdCurrent(p, pObj) )
Aig_ObjPatchFanin0( p, pObj, Aig_ManConst0(p) );
}
Vec_PtrFree( vNodes );
// remove dangling nodes
return Aig_ManCleanup( p );
}
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
......
......@@ -580,6 +580,10 @@ clk2 = clock();
// Fra_ImpRecordInManager( p, pManAigNew );
// cleanup the new manager
Aig_ManSeqCleanup( pManAigNew );
// remove pointers to the dead nodes
// Aig_ManForEachObj( pManAig, pObj, i )
// if ( pObj->pData && Aig_ObjIsNone(pObj->pData) )
// pObj->pData = NULL;
// Aig_ManCountMergeRegs( pManAigNew );
p->timeTrav += clock() - clk2;
p->timeTotal = clock() - clk;
......
......@@ -120,6 +120,7 @@ struct Ntl_Net_t_
{
Ntl_Net_t * pNext; // next net in the hash table
void * pCopy; // the copy of this object
void * pCopy2; // the copy of this object
Ntl_Obj_t * pDriver; // driver of the net
char nVisits; // the number of times the net is visited
char fMark; // temporary mark
......
......@@ -233,7 +233,10 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
pRoot = Ntl_ManRootModel( p );
// clear net visited flags
Ntl_ModelForEachNet( pRoot, pNet, i )
{
pNet->nVisits = 0;
pNet->pCopy = NULL;
}
// collect primary inputs
Ntl_ModelForEachPi( pRoot, pObj, i )
{
......@@ -417,7 +420,10 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p )
pRoot = Ntl_ManRootModel( p );
// clear net visited flags
Ntl_ModelForEachNet( pRoot, pNet, i )
{
pNet->nVisits = 0;
pNet->pCopy = NULL;
}
// collect primary inputs
Ntl_ModelForEachPi( pRoot, pObj, i )
{
......@@ -486,9 +492,17 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p )
Aig_Man_t * Ntl_ManCollapseForCec( Ntl_Man_t * p )
{
Aig_Man_t * pAig;
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i;
// clear net visited flags
pRoot = Ntl_ManRootModel(p);
Ntl_ModelForEachNet( pRoot, pNet, i )
{
pNet->nVisits = 0;
pNet->pCopy = NULL;
}
// create the manager
p->pAig = Aig_ManStart( 10000 );
p->pAig->pName = Aig_UtilStrsav( p->pName );
......@@ -557,6 +571,13 @@ Aig_Man_t * Ntl_ManCollapseForSec( Ntl_Man_t * p1, Ntl_Man_t * p2 )
Aig_ObjCreatePo( pAig, Aig_ManConst1(pAig) );
/////////////////////////////////////////////////////
// clear net visited flags
pRoot1 = Ntl_ManRootModel(p1);
Ntl_ModelForEachNet( pRoot1, pNet, i )
{
pNet->nVisits = 0;
pNet->pCopy = NULL;
}
// primary inputs
Ntl_ManForEachCiNet( p1, pObj, i )
{
......@@ -571,7 +592,6 @@ Aig_Man_t * Ntl_ManCollapseForSec( Ntl_Man_t * p1, Ntl_Man_t * p2 )
pNet->nVisits = 2;
}
// latch outputs
pRoot1 = Ntl_ManRootModel(p1);
Ntl_ModelForEachLatch( pRoot1, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
......@@ -614,6 +634,13 @@ Aig_Man_t * Ntl_ManCollapseForSec( Ntl_Man_t * p1, Ntl_Man_t * p2 )
}
/////////////////////////////////////////////////////
// clear net visited flags
pRoot2 = Ntl_ManRootModel(p2);
Ntl_ModelForEachNet( pRoot2, pNet, i )
{
pNet->nVisits = 0;
pNet->pCopy = NULL;
}
// primary inputs
Ntl_ManForEachCiNet( p2, pObj, i )
{
......@@ -628,7 +655,6 @@ Aig_Man_t * Ntl_ManCollapseForSec( Ntl_Man_t * p1, Ntl_Man_t * p2 )
pNet->nVisits = 2;
}
// latch outputs
pRoot2 = Ntl_ManRootModel(p2);
Ntl_ModelForEachLatch( pRoot2, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
......
......@@ -369,6 +369,128 @@ Ntl_Man_t * Ntl_ManSsw( Ntl_Man_t * p, Fra_Ssw_t * pPars )
}
/**Function*************************************************************
Synopsis [Transfers the copy field into the second copy field.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManTransferCopy( Ntl_Man_t * p )
{
Ntl_Net_t * pNet;
Ntl_Mod_t * pRoot;
int i;
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachNet( pRoot, pNet, i )
{
pNet->pCopy2 = pNet->pCopy;
pNet->pCopy = NULL;
}
}
/**Function*************************************************************
Synopsis [Reattaches one white-box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManAttachWhiteBox( Ntl_Man_t * p, Aig_Man_t * pAigCol, Aig_Man_t * pAigRed, Ntl_Man_t * pNew, Ntl_Obj_t * pBox )
{
}
/**Function*************************************************************
Synopsis [Reattaches white-boxes after reducing the netlist.]
Description [The following parameters are given:
Original netlist (p) whose nets point to the nodes of collapsed AIG.
Collapsed AIG (pAigCol) whose objects point to those of reduced AIG.
Reduced AIG (pAigRed) whose objects point to the nets of the new netlist.
The new netlist is changed by this procedure to have those white-boxes
from the original AIG (p) those outputs are preserved after reduction.
Note that if outputs are preserved, the inputs are also preserved.]
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManAttachWhiteBoxes( Ntl_Man_t * p, Aig_Man_t * pAigCol, Aig_Man_t * pAigRed, Ntl_Man_t * pNew, int fVerbose )
{
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pBox;
Ntl_Net_t * pNet;
int i, k, Counter = 0;
// go through the white-boxes and check if they are preserved
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachBox( pRoot, pBox, i )
{
Ntl_ObjForEachFanout( pBox, pNet, k )
{
// skip dangling outputs of the box
if ( pNet->pCopy == NULL )
continue;
// skip the outputs that are not preserved after merging equivalence
if ( Aig_Regular(pNet->pCopy2)->pData == NULL )
continue;
break;
}
if ( k == Ntl_ObjFanoutNum(pBox) )
continue;
// the box is preserved
Ntl_ManAttachWhiteBox( p, pAigCol, pAigRed, pNew, pBox );
Counter++;
}
if ( fVerbose )
printf( "Attached %d boxed (out of %d).\n", Counter, Ntl_ModelBoxNum(pRoot) );
}
/**Function*************************************************************
Synopsis [Returns AIG with WB after sequential SAT sweeping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntl_Man_t * Ntl_ManSsw2( Ntl_Man_t * p, Fra_Ssw_t * pPars )
{
Ntl_Man_t * pNew;
Aig_Man_t * pAigRed, * pAigCol;
// collapse the AIG
pAigCol = Ntl_ManCollapse( p );
pAigCol->nRegs = Ntl_ModelLatchNum(Ntl_ManRootModel(p));
// transform the collapsed AIG
pAigRed = Fra_FraigInduction( pAigCol, pPars );
Aig_ManStop( pAigRed );
pAigRed = Aig_ManDupReprBasic( pAigCol );
// insert the result back
Ntl_ManTransferCopy( p );
pNew = Ntl_ManInsertAig( p, pAigRed );
// attach the white-boxes
Ntl_ManAttachWhiteBoxes( p, pAigCol, pAigRed, pNew, pPars->fVerbose );
Ntl_ManSweep( pNew, pPars->fVerbose );
// cleanup
Aig_ManStop( pAigRed );
Aig_ManStop( pAigCol );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
SRC += src/aig/nwk/nwkCheck.c \
SRC += src/aig/nwk/nwkAig.c \
src/aig/nwk/nwkCheck.c \
src/aig/nwk/nwkBidec.c \
src/aig/nwk/nwkDfs.c \
src/aig/nwk/nwkFanio.c \
src/aig/nwk/nwkFlow.c \
src/aig/nwk/nwkMan.c \
src/aig/nwk/nwkMap.c \
src/aig/nwk/nwkObj.c \
......
......@@ -75,6 +75,10 @@ struct Nwk_Man_t_
Vec_Ptr_t * vTemp; // array used for incremental updates
int nTravIds; // the counter of traversal IDs
int nRealloced; // the number of realloced nodes
// sequential information
int nLatches; // the total number of latches
int nTruePis; // the number of true primary inputs
int nTruePos; // the number of true primary outputs
};
struct Nwk_Obj_t_
......@@ -88,7 +92,8 @@ struct Nwk_Obj_t_
unsigned fInvert : 1; // complemented attribute
unsigned MarkA : 1; // temporary mark
unsigned MarkB : 1; // temporary mark
unsigned PioId : 26; // number of this node in the PI/PO list
unsigned MarkC : 1; // temporary mark
unsigned PioId : 25; // number of this node in the PI/PO list
int Id; // unique ID
int TravId; // traversal ID
// timing information
......@@ -140,6 +145,8 @@ static inline int Nwk_ObjIsNode( Nwk_Obj_t * p ) { return p->Ty
static inline int Nwk_ObjIsLatch( Nwk_Obj_t * p ) { return p->Type == NWK_OBJ_LATCH; }
static inline int Nwk_ObjIsPi( Nwk_Obj_t * p ) { return Nwk_ObjIsCi(p) && (p->pMan->pManTime == NULL || Tim_ManBoxForCi(p->pMan->pManTime, p->PioId) == -1); }
static inline int Nwk_ObjIsPo( Nwk_Obj_t * p ) { return Nwk_ObjIsCo(p) && (p->pMan->pManTime == NULL || Tim_ManBoxForCo(p->pMan->pManTime, p->PioId) == -1); }
static inline int Nwk_ObjIsLi( Nwk_Obj_t * p ) { return p->pMan->nTruePos && Nwk_ObjIsCo(p) && (int)p->PioId >= p->pMan->nTruePos; }
static inline int Nwk_ObjIsLo( Nwk_Obj_t * p ) { return p->pMan->nTruePis && Nwk_ObjIsCi(p) && (int)p->PioId >= p->pMan->nTruePis; }
static inline float Nwk_ObjArrival( Nwk_Obj_t * pObj ) { return pObj->tArrival; }
static inline float Nwk_ObjRequired( Nwk_Obj_t * pObj ) { return pObj->tRequired; }
......@@ -190,10 +197,26 @@ static inline int Nwk_ManTimeMore( float f1, float f2, float Eps ) { r
#define Nwk_ObjForEachFanout( pObj, pFanout, i ) \
for ( i = 0; (i < (int)(pObj)->nFanouts) && ((pFanout) = (pObj)->pFanio[(pObj)->nFanins+i]); i++ )
// sequential iterators
#define Nwk_ManForEachPiSeq( p, pObj, i ) \
Vec_PtrForEachEntryStop( p->vCis, pObj, i, (p)->nTruePis )
#define Nwk_ManForEachPoSeq( p, pObj, i ) \
Vec_PtrForEachEntryStop( p->vCos, pObj, i, (p)->nTruePos )
#define Nwk_ManForEachLoSeq( p, pObj, i ) \
for ( i = 0; (i < (p)->nLatches) && (((pObj) = Vec_PtrEntry(p->vCis, i+(p)->nTruePis)), 1); i++ )
#define Nwk_ManForEachLiSeq( p, pObj, i ) \
for ( i = 0; (i < (p)->nLatches) && (((pObj) = Vec_PtrEntry(p->vCos, i+(p)->nTruePos)), 1); i++ )
#define Nwk_ManForEachLiLoSeq( p, pObjLi, pObjLo, i ) \
for ( i = 0; (i < (p)->nLatches) && (((pObjLi) = Nwk_ManCo(p, i+(p)->nTruePos)), 1) \
&& (((pObjLo) = Nwk_ManCi(p, i+(p)->nTruePis)), 1); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== nwkAig.c ==========================================================*/
extern Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose );
/*=== nwkBidec.c ==========================================================*/
extern void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose );
extern Hop_Obj_t * Nwk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare );
......@@ -221,6 +244,9 @@ extern void Nwk_ObjDeleteFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFanin
extern void Nwk_ObjPatchFanin( Nwk_Obj_t * pObj, Nwk_Obj_t * pFaninOld, Nwk_Obj_t * pFaninNew );
extern void Nwk_ObjTransferFanout( Nwk_Obj_t * pNodeFrom, Nwk_Obj_t * pNodeTo );
extern void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNew );
/*=== nwkFlow.c ============================================================*/
extern Vec_Ptr_t * Nwk_ManRetimeCutForward( Nwk_Man_t * pMan, int nLatches, int fVerbose );
extern Vec_Ptr_t * Nwk_ManRetimeCutBackward( Nwk_Man_t * pMan, int nLatches, int fVerbose );
/*=== nwkMan.c ============================================================*/
extern Nwk_Man_t * Nwk_ManAlloc();
extern void Nwk_ManFree( Nwk_Man_t * p );
......@@ -258,6 +284,7 @@ extern int Nwk_NodeCompareLevelsDecrease( Nwk_Obj_t ** pp1, Nwk_Obj_
extern void Nwk_ObjPrint( Nwk_Obj_t * pObj );
extern void Nwk_ManDumpBlif( Nwk_Man_t * pNtk, char * pFileName, Vec_Ptr_t * vCiNames, Vec_Ptr_t * vCoNames );
extern void Nwk_ManPrintFanioNew( Nwk_Man_t * pNtk );
extern void Nwk_ManCleanMarks( Nwk_Man_t * pNtk );
#ifdef __cplusplus
}
......
/**CFile****************************************************************
FileName [nwkAig.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Translating of AIG into the network.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: nwkAig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Converts AIG into the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Nwk_Man_t * Nwk_ManDeriveFromAig( Aig_Man_t * p )
{
Nwk_Man_t * pNtk;
Aig_Obj_t * pObj;
int i;
pNtk = Nwk_ManAlloc();
pNtk->nFanioPlus = 0;
Hop_ManStop( pNtk->pManHop );
pNtk->pManHop = NULL;
pNtk->pName = Aig_UtilStrsav( p->pName );
pNtk->pSpec = Aig_UtilStrsav( p->pSpec );
pObj = Aig_ManConst1(p);
pObj->pData = Nwk_ManCreateNode( pNtk, 0, pObj->nRefs );
Aig_ManForEachPi( p, pObj, i )
pObj->pData = Nwk_ManCreateCi( pNtk, pObj->nRefs );
Aig_ManForEachNode( p, pObj, i )
{
pObj->pData = Nwk_ManCreateNode( pNtk, 2, pObj->nRefs );
Nwk_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData );
Nwk_ObjAddFanin( pObj->pData, Aig_ObjFanin1(pObj)->pData );
}
Aig_ManForEachPo( p, pObj, i )
{
pObj->pData = Nwk_ManCreateCo( pNtk );
Nwk_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData );
}
return pNtk;
}
/**Function*************************************************************
Synopsis [Converts AIG into the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose )
{
Vec_Ptr_t * vNodes;
Nwk_Man_t * pNtk;
Nwk_Obj_t * pNode;
Aig_Obj_t * pObj;
int i;
pNtk = Nwk_ManDeriveFromAig( p );
if ( fForward )
vNodes = Nwk_ManRetimeCutForward( pNtk, Aig_ManRegNum(p), fVerbose );
else
vNodes = Nwk_ManRetimeCutBackward( pNtk, Aig_ManRegNum(p), fVerbose );
Aig_ManForEachObj( p, pObj, i )
((Nwk_Obj_t *)pObj->pData)->pCopy = pObj;
Vec_PtrForEachEntry( vNodes, pNode, i )
Vec_PtrWriteEntry( vNodes, i, pNode->pCopy );
Nwk_ManFree( pNtk );
assert( Vec_PtrSize(vNodes) <= Aig_ManRegNum(p) );
return vNodes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -447,6 +447,24 @@ void Nwk_ManPrintFanioNew( Nwk_Man_t * pNtk )
nFanoutsMax, 1.0*nFanoutsAll/Nwk_ManNodeNum(pNtk) );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nwk_ManCleanMarks( Nwk_Man_t * pMan )
{
Nwk_Obj_t * pObj;
int i;
Nwk_ManForEachObj( pMan, pObj, i )
pObj->MarkA = pObj->MarkB = 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
SRC += src/aig/saig/saig_.c \
src/aig/saig/saigPhase.c \
src/aig/saig/saigRetMin.c
/**CFile****************************************************************
FileName [saigRetMin.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Sequential AIG package.]
Synopsis [Min-area retiming for the AIG.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: saigRetMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "saig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Marks the TFI cone with the current traversal ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Saig_ManMarkCone_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
{
if ( pObj == NULL )
return;
if ( Aig_ObjIsTravIdCurrent( p, pObj ) )
return;
Aig_ObjSetTravIdCurrent( p, pObj );
Saig_ManMarkCone_rec( p, Aig_ObjFanin0(pObj) );
Saig_ManMarkCone_rec( p, Aig_ObjFanin1(pObj) );
}
/**Function*************************************************************
Synopsis [Marks the TFI cones with the current traversal ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Saig_ManMarkCones( Aig_Man_t * p, Vec_Ptr_t * vNodes )
{
Aig_Obj_t * pObj;
int i;
Aig_ManIncrementTravId( p );
Vec_PtrForEachEntry( vNodes, pObj, i )
Saig_ManMarkCone_rec( p, pObj );
}
/**Function*************************************************************
Synopsis [Counts the number of nodes to get registers after retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Saig_ManRetimeCountCut( Aig_Man_t * p, Vec_Ptr_t * vCut )
{
Vec_Ptr_t * vNodes;
Aig_Obj_t * pObj, * pFanin;
int i, RetValue;
Saig_ManMarkCones( p, vCut );
vNodes = Vec_PtrAlloc( 1000 );
Aig_ManForEachObj( p, pObj, i )
{
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
continue;
pFanin = Aig_ObjFanin0( pObj );
if ( pFanin && !pFanin->fMarkA && Aig_ObjIsTravIdCurrent(p, pFanin) )
{
Vec_PtrPush( vNodes, pFanin );
pFanin->fMarkA = 1;
}
pFanin = Aig_ObjFanin1( pObj );
if ( pFanin && !pFanin->fMarkA && Aig_ObjIsTravIdCurrent(p, pFanin) )
{
Vec_PtrPush( vNodes, pFanin );
pFanin->fMarkA = 1;
}
}
RetValue = Vec_PtrSize( vNodes );
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->fMarkA = 0;
Vec_PtrFree( vNodes );
return RetValue;
}
/**Function*************************************************************
Synopsis [Duplicates the AIG while retiming the registers to the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Saig_ManRetimeDupForward_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj )
{
if ( pObj->pData )
return;
assert( Aig_ObjIsNode(pObj) );
Saig_ManRetimeDupForward_rec( pNew, Aig_ObjFanin0(pObj) );
Saig_ManRetimeDupForward_rec( pNew, Aig_ObjFanin1(pObj) );
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
}
/**Function*************************************************************
Synopsis [Duplicates the AIG while retiming the registers to the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i;
// mark the cones under the cut
// assert( Vec_PtrSize(vCut) == Saig_ManRetimeCountCut(p, vCut) );
// create the new manager
pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
pNew->pName = Aig_UtilStrsav( p->pName );
pNew->pSpec = Aig_UtilStrsav( p->pSpec );
pNew->nRegs = Vec_PtrSize(vCut);
pNew->nTruePis = p->nTruePis;
pNew->nTruePos = p->nTruePos;
// create the true PIs
Aig_ManCleanData( p );
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
Saig_ManForEachPi( p, pObj, i )
pObj->pData = Aig_ObjCreatePi( pNew );
// create the registers
Vec_PtrForEachEntry( vCut, pObj, i )
pObj->pData = Aig_NotCond( Aig_ObjCreatePi(pNew), pObj->fPhase );
// duplicate the logic above the cut
Aig_ManForEachPo( p, pObj, i )
Saig_ManRetimeDupForward_rec( pNew, Aig_ObjFanin0(pObj) );
// create the true POs
Saig_ManForEachPo( p, pObj, i )
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
// remember value in LI
Saig_ManForEachLi( p, pObj, i )
pObj->pData = Aig_ObjChild0Copy(pObj);
// transfer values from the LIs to the LOs
Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
pObjLo->pData = pObjLi->pData;
// erase the data values on the internal nodes of the cut
Vec_PtrForEachEntry( vCut, pObj, i )
if ( !Aig_ObjIsPi(pObj) )
pObj->pData = NULL;
// duplicate the logic below the cut
Vec_PtrForEachEntry( vCut, pObj, i )
{
Saig_ManRetimeDupForward_rec( pNew, pObj );
Aig_ObjCreatePo( pNew, Aig_NotCond(pObj->pData, pObj->fPhase) );
}
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates the AIG while retiming the registers to the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Saig_ManRetimeDupBackward( Aig_Man_t * p, Vec_Ptr_t * vCut )
{
Aig_Man_t * pNew;
pNew = Aig_ManDup( p );
return pNew;
}
/**Function*************************************************************
Synopsis [Performs min-area retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int fForwardOnly, int fBackwardOnly, int fVerbose )
{
Vec_Ptr_t * vCut;
Aig_Man_t * pNew, * pTemp;
pNew = Aig_ManDup( p );
// perform several iterations of forward retiming
if ( !fBackwardOnly )
while ( 1 )
{
vCut = Nwk_ManDeriveRetimingCut( pNew, 1, fVerbose );
if ( Vec_PtrSize(vCut) >= Aig_ManRegNum(pNew) )
{
Vec_PtrFree( vCut );
break;
}
pNew = Saig_ManRetimeDupForward( pTemp = pNew, vCut );
Aig_ManStop( pTemp );
Vec_PtrFree( vCut );
}
// perform one iteration of backward retiming
if ( !fForwardOnly )
{
vCut = Nwk_ManDeriveRetimingCut( pNew, 0, fVerbose );
if ( Vec_PtrSize(vCut) < Aig_ManRegNum(pNew) )
{
pNew = Saig_ManRetimeDupBackward( pTemp = pNew, vCut );
Aig_ManStop( pTemp );
}
Vec_PtrFree( vCut );
}
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -11021,7 +11021,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->nFlowIters = 1;
pPars->nAreaIters = 2;
pPars->DelayTarget = -1;
pPars->Epsilon = (float)0.001;
pPars->Epsilon = (float)0.005;
pPars->fPreprocess = 1;
pPars->fArea = 0;
pPars->fFancy = 0;
......@@ -11918,23 +11918,30 @@ int Abc_CommandDRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
int fMinArea;
int fForwardOnly;
int fBackwardOnly;
int nStepsMax;
int fFastAlgo;
int fVerbose;
int c;
extern Abc_Ntk_t * Abc_NtkDarRetime( Abc_Ntk_t * pNtk, int nStepsMax, int fVerbose );
extern Abc_Ntk_t * Abc_NtkDarRetimeF( Abc_Ntk_t * pNtk, int nStepsMax, int fVerbose );
extern Abc_Ntk_t * Abc_NtkDarRetimeMinArea( Abc_Ntk_t * pNtk, int fForwardOnly, int fBackwardOnly, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fMinArea = 1;
fForwardOnly = 1;
fBackwardOnly = 0;
nStepsMax = 100000;
fFastAlgo = 0;
fFastAlgo = 1;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Savh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "Smfbavh" ) ) != EOF )
{
switch ( c )
{
......@@ -11949,6 +11956,15 @@ int Abc_CommandDRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nStepsMax < 0 )
goto usage;
break;
case 'm':
fMinArea ^= 1;
break;
case 'f':
fForwardOnly ^= 1;
break;
case 'b':
fBackwardOnly ^= 1;
break;
case 'a':
fFastAlgo ^= 1;
break;
......@@ -11981,7 +11997,9 @@ int Abc_CommandDRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// perform the retiming
if ( fFastAlgo )
if ( fMinArea )
pNtkRes = Abc_NtkDarRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose );
else if ( fFastAlgo )
pNtkRes = Abc_NtkDarRetime( pNtk, nStepsMax, fVerbose );
else
pNtkRes = Abc_NtkDarRetimeF( pNtk, nStepsMax, fVerbose );
......@@ -11995,10 +12013,13 @@ int Abc_CommandDRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: dretime [-S num] [-avh]\n" );
fprintf( pErr, "usage: dretime [-S num] [-mfbavh]\n" );
fprintf( pErr, "\t retimes the current network forward\n" );
fprintf( pErr, "\t-S num : the max number of retiming steps to perform [default = %d]\n", nStepsMax );
fprintf( pErr, "\t-a : enables a fast algorithm [default = %s]\n", fFastAlgo? "yes": "no" );
fprintf( pErr, "\t-m : toggle min-area and most-forward retiming [default = %s]\n", fMinArea? "min-area": "most-fwd" );
fprintf( pErr, "\t-f : enables forward-only retiming [default = %s]\n", fForwardOnly? "yes": "no" );
fprintf( pErr, "\t-b : enables backward-only retiming [default = %s]\n", fBackwardOnly? "yes": "no" );
fprintf( pErr, "\t-S num : the max number of forward retiming steps to perform [default = %d]\n", nStepsMax );
fprintf( pErr, "\t-a : enables a fast most-forward algorithm [default = %s]\n", fFastAlgo? "yes": "no" );
fprintf( pErr, "\t-v : enables verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
......
......@@ -50,7 +50,7 @@ Nwk_Man_t * Abc_NtkToNtkNew( Abc_Ntk_t * pNtk )
int i, k;
if ( !Abc_NtkIsLogic(pNtk) )
{
fprintf( stdout, "Thsi is not a logic network.\n" );
fprintf( stdout, "This is not a logic network.\n" );
return 0;
}
// convert into the AIG
......@@ -219,7 +219,7 @@ PRT( "Time", clock() - clk );
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkNtkTest( Abc_Ntk_t * pNtk, If_Lib_t * pLutLib )
Abc_Ntk_t * Abc_NtkNtkTest4( Abc_Ntk_t * pNtk, If_Lib_t * pLutLib )
{
extern int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib );
......@@ -236,6 +236,37 @@ Abc_Ntk_t * Abc_NtkNtkTest( Abc_Ntk_t * pNtk, If_Lib_t * pLutLib )
return pNtkNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkNtkTest( Abc_Ntk_t * pNtk, If_Lib_t * pLutLib )
{
Vec_Ptr_t * vNodes;
extern Vec_Ptr_t * Nwk_ManRetimeCutForward( Nwk_Man_t * pMan, int nLatches, int fVerbose );
extern Vec_Ptr_t * Nwk_ManRetimeCutBackward( Nwk_Man_t * pMan, int nLatches, int fVerbose );
Mfx_Par_t Pars, * pPars = &Pars;
Abc_Ntk_t * pNtkNew;
Nwk_Man_t * pMan;
pMan = Abc_NtkToNtkNew( pNtk );
vNodes = Nwk_ManRetimeCutBackward( pMan, Abc_NtkLatchNum(pNtk), 1 );
// vNodes = Nwk_ManRetimeCutForward( pMan, Abc_NtkLatchNum(pNtk), 1 );
Vec_PtrFree( vNodes );
pNtkNew = Abc_NtkFromNtkNew( pNtk, pMan );
Nwk_ManFree( pMan );
return pNtkNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -1429,6 +1429,40 @@ Abc_Ntk_t * Abc_NtkDarRetime( Abc_Ntk_t * pNtk, int nStepsMax, int fVerbose )
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDarRetimeMinArea( Abc_Ntk_t * pNtk, int fForwardOnly, int fBackwardOnly, int fVerbose )
{
extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int fForwardOnly, int fBackwardOnly, int fVerbose );
Abc_Ntk_t * pNtkAig;
Aig_Man_t * pMan, * pTemp;
pMan = Abc_NtkToDar( pNtk, 0, 1 );
if ( pMan == NULL )
return NULL;
if ( pMan->vFlopNums )
Vec_IntFree( pMan->vFlopNums );
pMan->vFlopNums = NULL;
pMan->nTruePis = Aig_ManPiNum(pMan) - Aig_ManRegNum(pMan);
pMan->nTruePos = Aig_ManPoNum(pMan) - Aig_ManRegNum(pMan);
pMan = Saig_ManRetimeMinArea( pTemp = pMan, fForwardOnly, fBackwardOnly, fVerbose );
Aig_ManStop( pTemp );
pNtkAig = Abc_NtkFromDarSeqSweep( pNtk, pMan );
Aig_ManStop( pMan );
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDarRetimeF( Abc_Ntk_t * pNtk, int nStepsMax, int fVerbose )
{
Abc_Ntk_t * pNtkAig;
......
......@@ -347,7 +347,7 @@ Abc_FlowRetime_MainLoop( ) {
pManMR->pInitNtk = NULL;
} while(1);
assert(!pManMR->fComputeInitState || pManMR->pInitNtk);
// assert(!pManMR->fComputeInitState || pManMR->pInitNtk);
if (pManMR->fComputeInitState) Abc_NtkDelete(pManMR->pInitNtk);
if (pManMR->fGuaranteeInitState) ; /* Abc_NtkDelete(pNtkCopy); note: original ntk deleted later */
......@@ -478,6 +478,7 @@ int
Abc_FlowRetime_PushFlows( Abc_Ntk_t * pNtk, bool fVerbose ) {
int i, j, flow = 0, last, srcDist = 0;
Abc_Obj_t *pObj, *pObj2;
int clk = clock();
pManMR->constraintMask |= BLOCK;
......@@ -522,6 +523,7 @@ Abc_FlowRetime_PushFlows( Abc_Ntk_t * pNtk, bool fVerbose ) {
if (fVerbose) vprintf("max-flow2 = %d\n", flow);
PRT( "time", clock() - clk );
return flow;
}
......
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