Commit 6e496de7 by Alan Mishchenko

Version abc50817

parent 9b3fa55b
......@@ -181,6 +181,10 @@ SOURCE=.\src\base\abc\abcPrint.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcReconv.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcRefs.c
# End Source File
# Begin Source File
......@@ -193,6 +197,10 @@ SOURCE=.\src\base\abc\abcRes.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcResRef.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcSat.c
# End Source File
# Begin Source File
......@@ -1088,6 +1096,38 @@ SOURCE=.\src\opt\fxu\fxuSingle.c
SOURCE=.\src\opt\fxu\fxuUpdate.c
# End Source File
# End Group
# Begin Group "rwr"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\opt\rwr\rwr.h
# End Source File
# Begin Source File
SOURCE=.\src\opt\rwr\rwrCut.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\rwr\rwrEva.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\rwr\rwrExp.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\rwr\rwrLib.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\rwr\rwrMan.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\rwr\rwrUtil.c
# End Source File
# End Group
# End Group
# Begin Group "map"
......@@ -1427,6 +1467,10 @@ SOURCE=.\src\misc\vec\vecPtr.h
SOURCE=.\src\misc\vec\vecStr.h
# End Source File
# Begin Source File
SOURCE=.\src\misc\vec\vecVec.h
# End Source File
# End Group
# End Group
# End Group
......
No preview for this file type
......@@ -6,13 +6,14 @@
--------------------Configuration: abc - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPBEE.tmp" with contents
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP12A1.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR"Debug/" /Fp"Debug/abc.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"C:\_projects\abc\src\map\mapper\mapperCut.c"
"C:\_projects\abc\src\base\abc\abcStrash.c"
"C:\_projects\abc\src\opt\rwr\rwrUtil.c"
]
Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPBEE.tmp"
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPBEF.tmp" with contents
Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP12A1.tmp"
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP12A2.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/abc.pdb" /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept
.\Debug\abc.obj
......@@ -269,14 +270,22 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
.\Debug\safe_mem.obj
.\Debug\strsav.obj
.\Debug\texpand.obj
.\Debug\abcReconv.obj
.\Debug\abcResRef.obj
.\Debug\rwrMan.obj
.\Debug\rwrCut.obj
.\Debug\rwrExp.obj
.\Debug\rwrLib.obj
.\Debug\rwrEva.obj
.\Debug\rwrUtil.obj
]
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPBEF.tmp"
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP12A2.tmp"
<h3>Output Window</h3>
Compiling...
mapperCut.c
C:\_projects\abc\src\map\mapper\mapperCut.c(927) : warning C4101: 'Place' : unreferenced local variable
abcStrash.c
rwrUtil.c
Linking...
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPBF0.tmp" with contents
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP12A3.tmp" with contents
[
/nologo /o"Debug/abc.bsc"
.\Debug\abc.sbr
......@@ -532,15 +541,23 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPBF0.tmp" with conte
.\Debug\pathsearch.sbr
.\Debug\safe_mem.sbr
.\Debug\strsav.sbr
.\Debug\texpand.sbr]
Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPBF0.tmp"
.\Debug\texpand.sbr
.\Debug\abcReconv.sbr
.\Debug\abcResRef.sbr
.\Debug\rwrMan.sbr
.\Debug\rwrCut.sbr
.\Debug\rwrExp.sbr
.\Debug\rwrLib.sbr
.\Debug\rwrEva.sbr
.\Debug\rwrUtil.sbr]
Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP12A3.tmp"
Creating browse info file...
<h3>Output Window</h3>
<h3>Results</h3>
abc.exe - 0 error(s), 1 warning(s)
abc.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>
......@@ -18,6 +18,8 @@ alias rp read_pla
alias rv read_verilog
alias rsup read_super mcnc5_old.super
alias rlib read_library
alias rw rewrite
alias rf refactor
alias sa set autoexec ps
alias so source -x
alias st strash
......
......@@ -23,18 +23,20 @@
/*
AIG is an And-Inv Graph with structural hashing.
It is always structurally hashed. It means that at any time:
- for each AND gate, there are no other AND gates with the same children
- the constants are propagated
- there is no single-input nodes (inverters/buffers)
- for each AND gate, there are no other AND gates with the same children.
- there are no dangling nodes (the nodes without fanout)
- the level of each AND gate reflects the levels of this fanins
- the EXOR-status of each node is up-to-date
The operations that are performed on AIG:
- building new nodes (Abc_AigAnd)
- elementary Boolean operations (Abc_AigOr, Abc_AigXor, etc)
- propagation of constants (Abc_AigReplace)
- variable substitution (Abc_AigReplace)
- performing elementary Boolean operations (Abc_AigOr, Abc_AigXor, etc)
- replacing one node by another (Abc_AigReplace)
- propagating constants (Abc_AigReplace)
When AIG is duplicated, the new graph is struturally hashed too.
If this repeated hashing leads to fewer nodes, it means the original
AIG was not strictly hashed (using the three criteria above).
AIG was not strictly hashed (one of the conditions above is violated).
*/
////////////////////////////////////////////////////////////////////////
......@@ -54,6 +56,7 @@ struct Abc_Aig_t_
Vec_Ptr_t * vStackDelete; // the nodes to be deleted
Vec_Ptr_t * vStackReplaceOld; // the nodes to be replaced
Vec_Ptr_t * vStackReplaceNew; // the nodes to be used for replacement
Vec_Vec_t * vLevels; // the nodes to be updated
};
// iterators through the entries in the linked lists of nodes
......@@ -81,6 +84,7 @@ static void Abc_AigResize( Abc_Aig_t * pMan );
// incremental AIG procedures
static void Abc_AigReplace_int( Abc_Aig_t * pMan );
static void Abc_AigDelete_int( Abc_Aig_t * pMan );
static void Abc_AigUpdateLevel_int( Abc_Aig_t * pMan );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -111,6 +115,7 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig )
pMan->vStackDelete = Vec_PtrAlloc( 100 );
pMan->vStackReplaceOld = Vec_PtrAlloc( 100 );
pMan->vStackReplaceNew = Vec_PtrAlloc( 100 );
pMan->vLevels = Vec_VecAlloc( 100 );
// save the current network
pMan->pNtkAig = pNtkAig;
// allocate constant nodes
......@@ -193,6 +198,7 @@ void Abc_AigFree( Abc_Aig_t * pMan )
assert( Vec_PtrSize( pMan->vStackReplaceOld ) == 0 );
assert( Vec_PtrSize( pMan->vStackReplaceNew ) == 0 );
// free the table
Vec_VecFree( pMan->vLevels );
Vec_PtrFree( pMan->vStackDelete );
Vec_PtrFree( pMan->vStackReplaceOld );
Vec_PtrFree( pMan->vStackReplaceNew );
......@@ -268,12 +274,11 @@ bool Abc_AigCheck( Abc_Aig_t * pMan )
printf( "Abc_AigCheck: The AIG has non-standard nodes.\n" );
return 0;
}
if ( pObj->Level != 1 + ABC_MAX( Abc_ObjFanin0(pObj)->Level, Abc_ObjFanin1(pObj)->Level ) )
printf( "Abc_AigCheck: Node \"%s\" has level that does not agree with the fanin levels.\n", Abc_ObjName(pObj) );
pAnd = Abc_AigAndLookup( pMan, Abc_ObjChild0(pObj), Abc_ObjChild1(pObj) );
if ( pAnd != pObj )
{
printf( "Abc_AigCheck: Node \"%s\" is not in the structural hashing table.\n", Abc_ObjName(pObj) );
return 0;
}
}
// count the number of nodes in the table
Counter = 0;
......@@ -290,6 +295,30 @@ bool Abc_AigCheck( Abc_Aig_t * pMan )
/**Function*************************************************************
Synopsis [Computes the number of logic levels not counting PIs/POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_AigGetLevelNum( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i, LevelsMax;
assert( Abc_NtkIsAig(pNtk) );
// perform the traversal
LevelsMax = 0;
Abc_NtkForEachCo( pNtk, pNode, i )
if ( LevelsMax < (int)Abc_ObjFanin0(pNode)->Level )
LevelsMax = (int)Abc_ObjFanin0(pNode)->Level;
return LevelsMax;
}
/**Function*************************************************************
Synopsis [Read the constant 1 node.]
Description []
......@@ -349,6 +378,7 @@ Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
Abc_ObjAddFanin( pAnd, p1 );
// set the level of the new node
pAnd->Level = 1 + ABC_MAX( Abc_ObjRegular(p0)->Level, Abc_ObjRegular(p1)->Level );
pAnd->fExor = Abc_NodeIsExorType(pAnd);
// add the node to the corresponding linked list in the table
Key = Abc_HashKey2( p0, p1, pMan->nBins );
pAnd->pNext = pMan->pBins[Key];
......@@ -612,6 +642,7 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew )
Abc_AigReplace_int( pMan );
while ( Vec_PtrSize(pMan->vStackDelete) )
Abc_AigDelete_int( pMan );
Abc_AigUpdateLevel_int( pMan );
}
/**Function*************************************************************
......@@ -627,8 +658,8 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew )
***********************************************************************/
void Abc_AigReplace_int( Abc_Aig_t * pMan )
{
Abc_Obj_t * pOld, * pNew, * pFanin1, * pFanin2, * pFanout, * pFanoutNew;
int k, iFanin;
Abc_Obj_t * pOld, * pNew, * pFanin1, * pFanin2, * pFanout, * pFanoutNew, * pFanoutFanout;
int k, v, iFanin;
// get the pair of nodes to replace
assert( Vec_PtrSize(pMan->vStackReplaceOld) > 0 );
pOld = Vec_PtrPop( pMan->vStackReplaceOld );
......@@ -668,6 +699,12 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan )
Abc_ObjRemoveFanins( pFanout );
// update the old fanout with new fanins and add it to the table
Abc_AigAndCreateFrom( pMan, pFanin1, pFanin2, pFanout );
// schedule the updated node for updating level
Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout );
// the node has changed, update EXOR status of the fanouts
Abc_ObjForEachFanout( pFanout, pFanoutFanout, v )
if ( Abc_NodeIsAigAnd(pFanoutFanout) )
pFanoutFanout->fExor = Abc_NodeIsExorType(pFanoutFanout);
}
// schedule deletion of the old node
if ( Abc_NodeIsAigAnd(pOld) && pOld->fMarkA == 0 )
......@@ -688,6 +725,25 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan )
SeeAlso []
***********************************************************************/
void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pOld )
{
assert( Vec_PtrSize(pMan->vStackDelete) == 0 );
Vec_PtrPush( pMan->vStackDelete, pOld );
while ( Vec_PtrSize(pMan->vStackDelete) )
Abc_AigDelete_int( pMan );
}
/**Function*************************************************************
Synopsis [Performs internal deletion step.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_AigDelete_int( Abc_Aig_t * pMan )
{
Abc_Obj_t * pNode, * pFanin;
......@@ -717,6 +773,52 @@ void Abc_AigDelete_int( Abc_Aig_t * pMan )
Abc_NtkDeleteObj( pNode );
}
/**Function*************************************************************
Synopsis [Updates the level of the node after it has changed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_AigUpdateLevel_int( Abc_Aig_t * pMan )
{
Abc_Obj_t * pNode, * pFanout;
Vec_Ptr_t * vVec;
unsigned LevelNew;
int i, k, v;
// go through the nodes and update the level of their fanouts
Vec_VecForEachLevel( pMan->vLevels, vVec, i )
{
if ( Vec_PtrSize(vVec) == 0 )
continue;
Vec_PtrForEachEntry( vVec, pNode, k )
{
assert( Abc_ObjIsNode(pNode) );
Abc_ObjForEachFanout( pNode, pFanout, v )
{
if ( Abc_ObjIsCo(pFanout) )
continue;
// get the new level of this fanout
LevelNew = 1 + ABC_MAX( Abc_ObjFanin0(pFanout)->Level, Abc_ObjFanin1(pFanout)->Level );
if ( pFanout->Level == LevelNew ) // no change
continue;
// update the fanout level
pFanout->Level = LevelNew;
// add the fanout to be updated
Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout );
}
}
Vec_PtrClear( vVec );
}
}
......@@ -775,6 +877,7 @@ bool Abc_AigNodeHasComplFanoutEdgeTrav( Abc_Obj_t * pNode )
return 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -395,7 +395,7 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
Value = 0;
}
}
/*
// make sure fanins are not duplicated
for ( i = 0; i < pObj->vFanins.nSize; i++ )
for ( k = i + 1; k < pObj->vFanins.nSize; k++ )
......@@ -412,7 +412,7 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
printf( "Warning: Node %s has", Abc_ObjName(pObj) );
printf( " duplicated fanout %s.\n", Abc_ObjName(Abc_ObjFanout(pObj,k)) );
}
*/
return Value;
}
......
......@@ -26,7 +26,8 @@
static void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
static void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
static void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLevels );
static void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
static void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Vec_t * vLevels );
static int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode );
static bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode );
......@@ -49,23 +50,23 @@ static bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode );
Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode;
Abc_Obj_t * pObj;
int i;
// set the traversal ID
Abc_NtkIncrementTravId( pNtk );
// start the array of nodes
vNodes = Vec_PtrAlloc( 100 );
Abc_NtkForEachCo( pNtk, pNode, i )
Abc_NtkForEachCo( pNtk, pObj, i )
{
Abc_NodeSetTravIdCurrent( pNode );
Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode)), vNodes );
Abc_NodeSetTravIdCurrent( pObj );
Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)), vNodes );
}
// collect dangling nodes if asked to
if ( fCollectAll )
{
Abc_NtkForEachNode( pNtk, pNode, i )
if ( !Abc_NodeIsTravIdCurrent(pNode) )
Abc_NtkDfs_rec( pNode, vNodes );
Abc_NtkForEachNode( pNtk, pObj, i )
if ( !Abc_NodeIsTravIdCurrent(pObj) )
Abc_NtkDfs_rec( pObj, vNodes );
}
return vNodes;
}
......@@ -138,6 +139,75 @@ void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
/**Function*************************************************************
Synopsis [Returns the reverse DFS ordered array of logic nodes.]
Description [Collects only the internal nodes, leaving CIs and CO.
However it marks with the current TravId both CIs and COs.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj, * pFanout;
int i, k;
// set the traversal ID
Abc_NtkIncrementTravId( pNtk );
// start the array of nodes
vNodes = Vec_PtrAlloc( 100 );
Abc_NtkForEachCi( pNtk, pObj, i )
{
Abc_NodeSetTravIdCurrent( pObj );
pObj = Abc_ObjFanout0Ntk(pObj);
Abc_ObjForEachFanout( pObj, pFanout, k )
Abc_NtkDfsReverse_rec( pFanout, vNodes );
}
// add constant nodes in the end
Abc_NtkForEachNode( pNtk, pObj, i )
if ( Abc_NodeIsConst(pObj) )
Vec_PtrPush( vNodes, pObj );
return vNodes;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Abc_Obj_t * pFanout;
int i;
assert( !Abc_ObjIsNet(pNode) );
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// skip the CI
if ( Abc_ObjIsCo(pNode) )
return;
assert( Abc_ObjIsNode( pNode ) );
// visit the transitive fanin of the node
pNode = Abc_ObjFanout0Ntk(pNode);
Abc_ObjForEachFanout( pNode, pFanout, i )
Abc_NtkDfsReverse_rec( pFanout, vNodes );
// add the node after the fanins have been added
Vec_PtrPush( vNodes, pNode );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of logic nodes.]
Description [Collects only the internal nodes, leaving CIs and CO.
......@@ -220,20 +290,21 @@ void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi )
Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi )
{
Vec_Ptr_t * vLevels;
Vec_Vec_t * vLevels;
Abc_Obj_t * pFanout;
int i;
assert( fTfi == 0 );
assert( !Abc_NtkIsNetlist(pNode->pNtk) );
// set the traversal ID
Abc_NtkIncrementTravId( pNode->pNtk );
vLevels = Vec_PtrAlloc( 100 );
vLevels = Vec_VecAlloc( 100 );
if ( Abc_ObjIsNode(pNode) )
Abc_DfsLevelizedTfo_rec( pNode, vLevels );
else
{
assert( Abc_ObjIsCi(pNode) );
Abc_NodeSetTravIdCurrent( pNode );
Abc_ObjForEachFanout( pNode, pFanout, i )
Abc_DfsLevelizedTfo_rec( pFanout, vLevels );
......@@ -252,7 +323,7 @@ Vec_Ptr_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi )
SeeAlso []
***********************************************************************/
void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLevels )
void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Vec_t * vLevels )
{
Abc_Obj_t * pFanout;
int i;
......@@ -266,14 +337,7 @@ void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLevels )
return;
assert( Abc_ObjIsNode(pNode) );
// add the node to the structure
if ( vLevels->nSize <= (int)pNode->Level )
{
Vec_PtrGrow( vLevels, pNode->Level + 1 );
for ( i = vLevels->nSize; i <= (int)pNode->Level; i++ )
vLevels->pArray[i] = Vec_PtrAlloc( 16 );
vLevels->nSize = pNode->Level + 1;
}
Vec_PtrPush( vLevels->pArray[pNode->Level], pNode );
Vec_VecPush( vLevels, pNode->Level, pNode );
// visit the TFO
Abc_ObjForEachFanout( pNode, pFanout, i )
Abc_DfsLevelizedTfo_rec( pFanout, vLevels );
......@@ -373,7 +437,7 @@ bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk )
Abc_NtkIncrementTravId( pNtk );
// pNode->TravId == pNet->nTravIds means "pNode is on the path"
// pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path"
// pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited"
// pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited"
// traverse the network to detect cycles
fAcyclic = 1;
Abc_NtkForEachCo( pNtk, pNode, i )
......@@ -381,12 +445,12 @@ bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk )
pNode = Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode));
if ( Abc_NodeIsTravIdPrevious(pNode) )
continue;
// traverse the output logic cone to detect the combinational loops
if ( ( fAcyclic = Abc_NtkIsAcyclic_rec(pNode) ) == 0 )
{ // stop as soon as the first loop is detected
fprintf( stdout, " (the output node)\n" );
break;
}
// traverse the output logic cone
if ( fAcyclic = Abc_NtkIsAcyclic_rec(pNode) )
continue;
// stop as soon as the first loop is detected
fprintf( stdout, " (cone of CO \"%s\")\n", Abc_ObjName(pNode) );
break;
}
return fAcyclic;
}
......@@ -408,7 +472,6 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
Abc_Obj_t * pFanin;
int fAcyclic, i;
assert( !Abc_ObjIsNet(pNode) );
// skip the PI
if ( Abc_ObjIsCi(pNode) )
return 1;
assert( Abc_ObjIsNode( pNode ) );
......@@ -433,14 +496,12 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
// check if the fanin is visited
if ( Abc_NodeIsTravIdPrevious(pFanin) )
continue;
// traverse searching for the loop
fAcyclic = Abc_NtkIsAcyclic_rec( pFanin );
// traverse the fanin's cone searching for the loop
if ( fAcyclic = Abc_NtkIsAcyclic_rec(pFanin) )
continue;
// return as soon as the loop is detected
if ( fAcyclic == 0 )
{
fprintf( stdout, " <-- %s", Abc_ObjName(pNode) );
return 0;
}
fprintf( stdout, " <-- %s", Abc_ObjName(pNode) );
return 0;
}
// mark this node as a visited node
Abc_NodeSetTravIdPrevious( pNode );
......
......@@ -195,7 +195,7 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk )
***********************************************************************/
char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, Vec_Str_t * vCube, int fMode )
{
int fVerify = 1;
int fVerify = 0;
char * pSop;
DdNode * bFuncNew, * bCover, * zCover, * zCover0, * zCover1;
int nCubes, nCubes0, nCubes1, fPhase;
......
......@@ -42,6 +42,8 @@
***********************************************************************/
void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
{
int Num;
fprintf( pFile, "%-15s:", pNtk->pName );
fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
......@@ -58,7 +60,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
else if ( Abc_NtkIsAig(pNtk) )
{
fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
fprintf( pFile, " choice = %5d", Abc_NtkCountChoiceNodes(pNtk) );
if ( Num = Abc_NtkCountChoiceNodes(pNtk) )
fprintf( pFile, " (choice = %d)", Num );
if ( Num = Abc_NtkCountExors(pNtk) )
fprintf( pFile, " (exor = %d)", Num );
}
else if ( Abc_NtkIsSeq(pNtk) )
fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
......@@ -84,7 +89,9 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
assert( 0 );
}
if ( !Abc_NtkIsSeq(pNtk) )
if ( Abc_NtkIsAig(pNtk) )
fprintf( pFile, " lev = %3d", Abc_AigGetLevelNum(pNtk) );
else if ( !Abc_NtkIsSeq(pNtk) )
fprintf( pFile, " lev = %3d", Abc_NtkGetLevelNum(pNtk) );
fprintf( pFile, "\n" );
......@@ -360,14 +367,49 @@ void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile )
{
Abc_Obj_t * pNode;
int i, Length;
assert( Abc_NtkIsAig(pNtk) );
// print the delay profile
if ( fProfile )
if ( fProfile && Abc_NtkIsMapped(pNtk) )
{
int nIntervals = 12;
float DelayMax, DelayCur, DelayDelta;
int * pLevelCounts;
int DelayInt, nOutsSum, nOutsTotal;
// get the max delay and delta
DelayMax = Abc_NtkDelayTrace( pNtk );
DelayDelta = DelayMax/nIntervals;
// collect outputs by delay
pLevelCounts = ALLOC( int, nIntervals );
memset( pLevelCounts, 0, sizeof(int) * nIntervals );
Abc_NtkForEachCo( pNtk, pNode, i )
{
DelayCur = Abc_NodeReadArrival( Abc_ObjFanin0(pNode) )->Worst;
DelayInt = (int)(DelayCur / DelayDelta);
if ( DelayInt >= nIntervals )
DelayInt = nIntervals - 1;
pLevelCounts[DelayInt]++;
}
nOutsSum = 0;
nOutsTotal = Abc_NtkCoNum(pNtk);
for ( i = 0; i < nIntervals; i++ )
{
nOutsSum += pLevelCounts[i];
printf( "[%8.2f - %8.2f] : COs = %4d. %5.1f %%\n",
DelayDelta * i, DelayDelta * (i+1), pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal );
}
free( pLevelCounts );
return;
}
else if ( fProfile )
{
int LevelMax, * pLevelCounts;
int nOutsSum, nOutsTotal;
if ( !Abc_NtkIsAig(pNtk) )
Abc_NtkGetLevelNum(pNtk);
LevelMax = 0;
Abc_NtkForEachCo( pNtk, pNode, i )
if ( LevelMax < (int)Abc_ObjFanin0(pNode)->Level )
......@@ -385,8 +427,10 @@ void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile )
nOutsSum += pLevelCounts[i];
printf( "Level = %4d. COs = %4d. %5.1f %%\n", i, pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal );
}
free( pLevelCounts );
return;
}
assert( Abc_NtkIsAig(pNtk) );
// find the longest name
Length = 0;
......
......@@ -24,7 +24,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fFanouts, bool fReference );
static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -47,7 +47,7 @@ int Abc_NodeMffcSize( Abc_Obj_t * pNode )
assert( !Abc_ObjIsComplement( pNode ) );
assert( Abc_ObjIsNode( pNode ) );
nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0 ); // dereference
nConeSize2 = Abc_NodeRefDeref( pNode, 0, 1 ); // reference
nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0 ); // reference
assert( nConeSize1 == nConeSize2 );
assert( nConeSize1 > 0 );
return nConeSize1;
......@@ -55,7 +55,7 @@ int Abc_NodeMffcSize( Abc_Obj_t * pNode )
/**Function*************************************************************
Synopsis [Procedure returns the size of the MFFC of the node.]
Synopsis [Lavels MFFC with the current traversal ID.]
Description []
......@@ -64,11 +64,16 @@ int Abc_NodeMffcSize( Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
int Abc_NodeMffcRemove( Abc_Obj_t * pNode )
int Abc_NodeMffcLabel( Abc_Obj_t * pNode )
{
int nConeSize1, nConeSize2;
assert( !Abc_ObjIsComplement( pNode ) );
assert( Abc_ObjIsNode( pNode ) );
return Abc_NodeRefDeref( pNode, 1, 0 ); // dereference
nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0 ); // dereference
nConeSize2 = Abc_NodeRefDeref( pNode, 1, 1 ); // reference
assert( nConeSize1 == nConeSize2 );
assert( nConeSize1 > 0 );
return nConeSize1;
}
/**Function*************************************************************
......@@ -82,10 +87,12 @@ int Abc_NodeMffcRemove( Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fFanouts, bool fReference )
int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel )
{
Abc_Obj_t * pNode0, * pNode1;
int Counter;
if ( fLabel )
Abc_NodeSetTravIdCurrent( pNode );
if ( Abc_ObjIsCi(pNode) )
return 0;
pNode0 = Abc_ObjFanin( pNode, 0 );
......@@ -94,34 +101,18 @@ int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fFanouts, bool fReference )
if ( fReference )
{
if ( pNode0->vFanouts.nSize++ == 0 )
{
Counter += Abc_NodeRefDeref( pNode0, fFanouts, fReference );
if ( fFanouts )
Abc_ObjAddFanin( pNode, pNode0 );
}
Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel );
if ( pNode1->vFanouts.nSize++ == 0 )
{
Counter += Abc_NodeRefDeref( pNode1, fFanouts, fReference );
if ( fFanouts )
Abc_ObjAddFanin( pNode, pNode1 );
}
Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel );
}
else
{
assert( pNode0->vFanouts.nSize > 0 );
assert( pNode1->vFanouts.nSize > 0 );
if ( --pNode0->vFanouts.nSize == 0 )
{
Counter += Abc_NodeRefDeref( pNode0, fFanouts, fReference );
if ( fFanouts )
Abc_ObjDeleteFanin( pNode, pNode0 );
}
Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel );
if ( --pNode1->vFanouts.nSize == 0 )
{
Counter += Abc_NodeRefDeref( pNode1, fFanouts, fReference );
if ( fFanouts )
Abc_ObjDeleteFanin( pNode, pNode1 );
}
Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel );
}
return Counter;
}
......
/**CFile****************************************************************
FileName [abcResRef.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Resynthesis based on refactoring.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcResRef.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
struct Abc_ManRef_t_
{
// user specified parameters
int nNodeSizeMax; // the limit on the size of the supernode
int nConeSizeMax; // the limit on the size of the containing cone
int fVerbose; // the verbosity flag
// the node currently processed
Abc_Obj_t * pNode; // the node currently considered
// internal parameters
DdManager * dd; // the BDD manager
DdNode * bCubeX; // the cube of PI variables
Vec_Str_t * vCube; // temporary cube for generating covers
Vec_Int_t * vForm; // the factored form (temporary)
// runtime statistics
int time1;
int time2;
int time3;
int time4;
};
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Resynthesizes the node using refactoring.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode )
{
return 0;
}
/**Function*************************************************************
Synopsis [Derives the factored form of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
/*
Vec_Int_t * Abc_NodeRefactor( Abc_ManRef_t * p )
{
Vec_Int_t * vForm;
DdManager * dd = p->dd;
DdNode * bFuncNode, * bFuncCone, * bCare, * bFuncOn, * bFuncOnDc;
char * pSop;
int nFanins;
assert( p->vFaninsNode->nSize < p->nNodeSizeMax );
assert( p->vFaninsCone->nSize < p->nConeSizeMax );
// get the function of the node
bFuncNode = Abc_NodeConeBdd( dd, p->dd->vars, p->pNode, p->vFaninsNode, p->vVisited );
Cudd_Ref( bFuncNode );
nFanins = p->vFaninsNode->nSize;
if ( p->nConeSizeMax > p->nNodeSizeMax )
{
// get the function of the cone
bFuncCone = Abc_NodeConeBdd( dd, p->dd->vars + p->nNodeSizeMax, p->pNode, p->vFaninsCone, p->vVisited );
Cudd_Ref( bFuncCone );
// get the care set
bCare = Cudd_bddXorExistAbstract( p->dd, Cudd_Not(bFuncNode), bFuncCone, p->bCubeX ); Cudd_Ref( bCare );
Cudd_RecursiveDeref( dd, bFuncCone );
// compute the on-set and off-set of the function of the node
bFuncOn = Cudd_bddAnd( dd, bFuncNode, bCare ); Cudd_Ref( bFuncOn );
bFuncOnDc = Cudd_bddAnd( dd, Cudd_Not(bFuncNode), bCare ); Cudd_Ref( bFuncOnDc );
bFuncOnDc = Cudd_Not( bFuncOnDc );
Cudd_RecursiveDeref( dd, bCare );
// get the cover
pSop = Abc_ConvertBddToSop( NULL, dd, bFuncOn, bFuncOnDc, nFanins, p->vCube, -1 );
Cudd_RecursiveDeref( dd, bFuncOn );
Cudd_RecursiveDeref( dd, bFuncOnDc );
}
else
{
// get the cover
pSop = Abc_ConvertBddToSop( NULL, dd, bFuncNode, bFuncNode, nFanins, p->vCube, -1 );
}
Cudd_RecursiveDeref( dd, bFuncNode );
// derive the factored form
vForm = Ft_Factor( pSop );
free( pSop );
return vForm;
}
*/
/**Function*************************************************************
Synopsis [Starts the resynthesis manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_ManRef_t * Abc_NtkManRefStart()
{
Abc_ManRef_t * p;
p = ALLOC( Abc_ManRef_t, 1 );
memset( p, 0, sizeof(Abc_ManRef_t) );
p->vCube = Vec_StrAlloc( 100 );
// start the BDD manager
p->dd = Cudd_Init( p->nNodeSizeMax + p->nConeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
Cudd_zddVarsFromBddVars( p->dd, 2 );
p->bCubeX = Extra_bddComputeRangeCube( p->dd, p->nNodeSizeMax, p->dd->size ); Cudd_Ref( p->bCubeX );
return p;
}
/**Function*************************************************************
Synopsis [Stops the resynthesis manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkManRefStop( Abc_ManRef_t * p )
{
if ( p->bCubeX ) Cudd_RecursiveDeref( p->dd, p->bCubeX );
if ( p->dd ) Extra_StopManager( p->dd );
Vec_StrFree( p->vCube );
free( p );
}
/**Function*************************************************************
Synopsis [Stops the resynthesis manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NtkManRefResult( Abc_ManRef_t * p )
{
return p->vForm;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -31,6 +31,7 @@ static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig,
static Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode );
static Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
static Abc_Obj_t * Abc_NodeStrashFactor2( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
static void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate );
static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, bool fDuplicate );
......@@ -179,7 +180,7 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
// decide when to use factoring
if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
return Abc_NodeStrashFactor( pMan, pNode, pSop );
return Abc_NodeStrashFactor2( pMan, pNode, pSop );
return Abc_NodeStrashSop( pMan, pNode, pSop );
}
......@@ -289,6 +290,81 @@ Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pS
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashFactor2( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop )
{
Vec_Int_t * vForm;
Vec_Ptr_t * vAnds;
Abc_Obj_t * pAnd, * pFanin;
int i;
// derive the factored form
vForm = Ft_Factor( pSop );
// collect the fanins
vAnds = Vec_PtrAlloc( 20 );
Abc_ObjForEachFanin( pRoot, pFanin, i )
Vec_PtrPush( vAnds, pFanin->pCopy );
// perform strashing
pAnd = Abc_NodeStrashDec( pMan, vAnds, vForm );
Vec_PtrFree( vAnds );
Vec_IntFree( vForm );
return pAnd;
}
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashDec( Abc_Aig_t * pMan, Vec_Ptr_t * vFanins, Vec_Int_t * vForm )
{
Abc_Obj_t * pAnd, * pAnd0, * pAnd1;
Ft_Node_t * pFtNode;
int i, nVars;
// sanity checks
nVars = Ft_FactorGetNumVars( vForm );
assert( nVars >= 0 );
assert( vForm->nSize > nVars );
assert( nVars == vFanins->nSize );
// check for constant function
pFtNode = Ft_NodeRead( vForm, 0 );
if ( pFtNode->fConst )
return Abc_ObjNotCond( Abc_AigConst1(pMan), pFtNode->fCompl );
// compute the function of other nodes
for ( i = nVars; i < vForm->nSize; i++ )
{
pFtNode = Ft_NodeRead( vForm, i );
pAnd0 = Abc_ObjNotCond( vFanins->pArray[pFtNode->iFanin0], pFtNode->fCompl0 );
pAnd1 = Abc_ObjNotCond( vFanins->pArray[pFtNode->iFanin1], pFtNode->fCompl1 );
pAnd = Abc_AigAnd( pMan, pAnd0, pAnd1 );
Vec_PtrPush( vFanins, pAnd );
}
assert( vForm->nSize = vFanins->nSize );
// complement the result if necessary
pFtNode = Ft_NodeReadLast( vForm );
pAnd = Abc_ObjNotCond( pAnd, pFtNode->fCompl );
return pAnd;
}
/**Function*************************************************************
Synopsis [Appends the second network to the first.]
Description [Modifies the first network by adding the logic of the second.
......
......@@ -447,9 +447,62 @@ void Abc_VecObjPushUniqueOrderByLevel( Vec_Ptr_t * p, Abc_Obj_t * pNode )
/**Function*************************************************************
Synopsis [Marks and counts the number of exors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkCountExors( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i, Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i )
Counter += pNode->fExor;
return Counter;
}
/**Function*************************************************************
Synopsis [Returns 1 if the node is the root of EXOR/NEXOR.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NodeIsExorType( Abc_Obj_t * pNode )
{
Abc_Obj_t * pNode0, * pNode1;
// check that the node is regular
assert( !Abc_ObjIsComplement(pNode) );
// if the node is not AND, this is not EXOR
if ( !Abc_NodeIsAigAnd(pNode) )
return 0;
// if the children are not complemented, this is not EXOR
if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
return 0;
// get children
pNode0 = Abc_ObjFanin0(pNode);
pNode1 = Abc_ObjFanin1(pNode);
// if the children are not ANDs, this is not EXOR
if ( Abc_ObjFaninNum(pNode0) != 2 || Abc_ObjFaninNum(pNode1) != 2 )
return 0;
// otherwise, the node is EXOR iff its grand-children are the same
return (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) || Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1)) &&
(Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) || Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1));
}
/**Function*************************************************************
Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
Description [The node can be complemented.]
Description []
SideEffects []
......@@ -920,6 +973,54 @@ void Abc_NtkAlphaOrderSignals( Abc_Ntk_t * pNtk, int fComb )
pObj->pCopy = NULL;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkShortNames( Abc_Ntk_t * pNtk )
{
stmm_table * tObj2NameNew;
Abc_Obj_t * pObj;
char Buffer[100];
char * pNameNew;
int Length, i;
tObj2NameNew = stmm_init_table(stmm_ptrcmp, stmm_ptrhash);
// create new names and add them to the table
Length = Extra_Base10Log( Abc_NtkPiNum(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
{
sprintf( Buffer, "pi%0*d", Length, i );
pNameNew = Abc_NtkRegisterName( pNtk, Buffer );
stmm_insert( tObj2NameNew, (char *)pObj, pNameNew );
}
// create new names and add them to the table
Length = Extra_Base10Log( Abc_NtkPoNum(pNtk) );
Abc_NtkForEachPo( pNtk, pObj, i )
{
sprintf( Buffer, "po%0*d", Length, i );
pNameNew = Abc_NtkRegisterName( pNtk, Buffer );
stmm_insert( tObj2NameNew, (char *)pObj, pNameNew );
}
// create new names and add them to the table
Length = Extra_Base10Log( Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pObj, i )
{
sprintf( Buffer, "lat%0*d", Length, i );
pNameNew = Abc_NtkRegisterName( pNtk, Buffer );
stmm_insert( tObj2NameNew, (char *)pObj, pNameNew );
}
stmm_free_table( pNtk->tObj2Name );
pNtk->tObj2Name = tObj2NameNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -88,6 +88,9 @@ PRT( "Time", p->timeMatch );
}
//////////////////////////////////////////////////////////////////////
if ( !p->fAreaRecovery )
return 1;
//////////////////////////////////////////////////////////////////////
// perform area recovery using area flow
clk = clock();
......
......@@ -926,7 +926,7 @@ Map_Cut_t * Map_CutTableConsider( Map_Man_t * pMan, Map_CutTable_t * p, Map_Node
Map_Cut_t * pCut;
int Place, i;
// int clk;
/*
// check the cut
Place = Map_CutTableLookup( p, ppNodes, nNodes );
if ( Place == -1 )
......@@ -934,7 +934,6 @@ Map_Cut_t * Map_CutTableConsider( Map_Man_t * pMan, Map_CutTable_t * p, Map_Node
assert( nNodes > 0 );
// create the new cut
//clk = clock();
*/
pCut = Map_CutAlloc( pMan );
//pMan->time1 += clock() - clk;
pCut->nLeaves = nNodes;
......@@ -944,15 +943,12 @@ Map_Cut_t * Map_CutTableConsider( Map_Man_t * pMan, Map_CutTable_t * p, Map_Node
pCut->ppLeaves[i] = ppNodes[i];
// pCut->fLevel += ppNodes[i]->Level;
}
/*
// pCut->fLevel /= nNodes;
// add the cut to the table
assert( p->pBins[Place] == NULL );
p->pBins[Place] = pCut;
// add the cut to the new list
p->pCuts[ p->nCuts++ ] = Place;
*/
return pCut;
}
......
......@@ -140,10 +140,13 @@ void Map_SuperLibFree( Map_SuperLib_t * p )
{
// if ( s_pLib == p->pGenlib )
// s_pLib = NULL;
if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == p->pGenlib )
Abc_FrameSetLibGen(Abc_FrameGetGlobalFrame(), NULL);
// if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == p->pGenlib )
// Abc_FrameSetLibGen(Abc_FrameGetGlobalFrame(), NULL);
// Mio_LibraryDelete( p->pGenlib );
assert( p->pGenlib == Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
Mio_LibraryDelete( p->pGenlib );
Abc_FrameSetLibGen(Abc_FrameGetGlobalFrame(), NULL);
}
if ( p->tTableC )
Map_SuperTableFree( p->tTableC );
......
......@@ -98,6 +98,9 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
return;
Map_TruthsCutOne( p, pCut, uTruth );
//assert( pCut->nLeaves < 5 );
//Rwt_ManExploreCount( uTruth[0] & 0xFFFF );
// compute the canonical form for the positive phase
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
......
......@@ -31,8 +31,9 @@
#include "vecFan.h"
#include "vecInt.h"
#include "vecPtr.h"
#include "vecStr.h"
#include "vecPtr.h"
#include "vecVec.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
......
......@@ -48,16 +48,12 @@ struct Vec_Ptr_t_
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
// iterators through entries
#define Vec_PtrForEachEntry( vVec, pEntry, i ) \
for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \
for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
#define Vec_PtrForEachEntryByLevel( vVec, pEntry, i, k ) \
for ( i = 0; i < Vec_PtrSize(vVec); i++ ) \
Vec_PtrForEachEntry( ((Vec_Ptr_t *)Vec_PtrEntry(vVec, i)), pEntry, k )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [vecVec.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Resizable arrays.]
Synopsis [Resizable vector of resizable vectors.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __VEC_VEC_H__
#define __VEC_VEC_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "extra.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Vec_Vec_t_ Vec_Vec_t;
struct Vec_Vec_t_
{
int nSize;
int nCap;
void ** pArray;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
// iterators through levels
#define Vec_VecForEachLevel( vGlob, vVec, i ) \
for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = Vec_VecEntry(vGlob, i)), 1); i++ )
#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
for ( i = LevelStart; (i < Vec_PtrSize(vGlob)) && (((vVec) = Vec_VecEntry(vGlob, i)), 1); i++ )
#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
for ( i = LevelStart; (i <= LevelStop) && (((vVec) = Vec_VecEntry(vGlob, i)), 1); i++ )
// iteratores through entries
#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \
for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \
for ( i = LevelStart; i <= LevelStop; i++ ) \
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates a vector with the given capacity.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
{
Vec_Vec_t * p;
p = ALLOC( Vec_Vec_t, 1 );
if ( nCap > 0 && nCap < 8 )
nCap = 8;
p->nSize = 0;
p->nCap = nCap;
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_VecSize( Vec_Vec_t * p )
{
return p->nSize;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void * Vec_VecEntry( Vec_Vec_t * p, int i )
{
assert( i >= 0 && i < p->nSize );
return p->pArray[i];
}
/**Function*************************************************************
Synopsis [Frees the vector.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecFree( Vec_Vec_t * p )
{
Vec_Ptr_t * vVec;
int i;
Vec_VecForEachLevel( p, vVec, i )
Vec_PtrFree( vVec );
Vec_PtrFree( (Vec_Ptr_t *)p );
}
/**Function*************************************************************
Synopsis [Frees the vector of vectors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_VecSizeSize( Vec_Vec_t * p )
{
Vec_Ptr_t * vVec;
int i, Counter = 0;
Vec_VecForEachLevel( p, vVec, i )
Counter += vVec->nSize;
return Counter;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecClear( Vec_Vec_t * p )
{
Vec_Ptr_t * vVec;
int i;
Vec_VecForEachLevel( p, vVec, i )
Vec_PtrClear( vVec );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry )
{
if ( p->nSize < Level + 1 )
{
int i;
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
for ( i = p->nSize; i < Level + 1; i++ )
p->pArray[i] = Vec_PtrAlloc( 0 );
p->nSize = Level + 1;
}
Vec_PtrPush( p->pArray[Level], Entry );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif
/**CFile****************************************************************
FileName [rwr.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: rwr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __RWR_H__
#define __RWR_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
#define RWR_LIMIT 1048576/4 // ((1 << 20)
typedef struct Rwr_Node_t_ Rwr_Node_t;
struct Rwr_Node_t_ // 24 bytes
{
int Id; // ID
int TravId; // traversal ID
unsigned uTruth : 16; // truth table
unsigned Volume : 8; // volume
unsigned Level : 5; // level
unsigned fMark : 1; // mark
unsigned fUsed : 1; // mark
unsigned fExor : 1; // mark
Rwr_Node_t * p0; // first child
Rwr_Node_t * p1; // second child
Rwr_Node_t * pNext; // next in the table
};
typedef struct Rwr_Cut_t_ Rwr_Cut_t;
struct Rwr_Cut_t_ // 24 bytes
{
unsigned nLeaves : 3; // the number of leaves
unsigned fTime : 1; // set to 1 if meets the required times
unsigned fGain : 1; // set to 1 if does not increase nodes
unsigned Volume : 11; // the gain in the number of nodes
unsigned uTruth : 16; // the truth table
Abc_Obj_t * ppLeaves[4]; // the leaves
Rwr_Cut_t * pNext; // the next cut in the list
};
struct Abc_ManRwr_t_
{
// internal lookups
int nFuncs; // the number of four var functions
unsigned short * puCanons; // canonical forms
char * puPhases; // canonical phases
char * pPractical; // practical classes
unsigned short puPerms[256][16]; // permutations for three var functions
// node space
Vec_Ptr_t * vForest; // all the nodes
Rwr_Node_t ** pTable; // the hash table of nodes by their canonical form
Extra_MmFixed_t * pMmNode; // memory for nodes and cuts
int nTravIds; // the counter of traversal IDs
int nConsidered; // the number of nodes considered
int nAdded; // the number of nodes added to lists
int nClasses; // the number of NN classes
// intermediate data
Vec_Int_t * vFanNums; // the number of fanouts of each node (used to free cuts)
Vec_Int_t * vReqTimes; // the required times for each node (used for delay-driven evalution)
// the result of resynthesis
Vec_Int_t * vForm; // the decomposition tree (temporary)
Vec_Ptr_t * vFanins; // the fanins array (temporary)
Vec_Ptr_t * vTfo; // the TFO node array (temporary)
Vec_Vec_t * vLevels; // the levelized structure (temporary)
int nGainMax;
// runtime statistics
int time1;
int time2;
int time3;
int time4;
};
// manipulation of complemented attributes
static inline bool Rwr_IsComplement( Rwr_Node_t * p ) { return (bool)(((unsigned)p) & 01); }
static inline Rwr_Node_t * Rwr_Regular( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) & ~01); }
static inline Rwr_Node_t * Rwr_Not( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) ^ 01); }
static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_Node_t *)((unsigned)(p) ^ (c)); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== rwrLib.c ==========================================================*/
extern void Rwr_ManPrecompute( Abc_ManRwr_t * p );
extern void Rwr_ManWriteToFile( Abc_ManRwr_t * p, char * pFileName );
extern void Rwr_ManLoadFromFile( Abc_ManRwr_t * p, char * pFileName );
extern void Rwr_ManPrint( Abc_ManRwr_t * p );
extern Rwr_Node_t * Rwr_ManAddVar( Abc_ManRwr_t * p, unsigned uTruth );
/*=== rwrMan.c ==========================================================*/
extern unsigned short Rwr_FunctionPhase( unsigned uTruth, unsigned uPhase );
/*=== rwrUtil.c ==========================================================*/
extern Vec_Int_t * Rwt_NtkFanoutCounters( Abc_Ntk_t * pNtk );
extern Vec_Int_t * Rwt_NtkRequiredLevels( Abc_Ntk_t * pNtk );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif
/**CFile****************************************************************
FileName [rwrCut.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting package.]
Synopsis [Cut computation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: rwrCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "rwr.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Rwr_Cut_t * Rwr_CutAlloc( Abc_ManRwr_t * p );
static Rwr_Cut_t * Rwr_CutCreateTriv( Abc_ManRwr_t * p, Abc_Obj_t * pNode );
static Rwr_Cut_t * Rwr_CutsMerge( Abc_ManRwr_t * p, Rwr_Cut_t * pCut0, Rwr_Cut_t * pCut1, int fCompl0, int fCompl1 );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Assigns elementary cuts to the PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkManRwrStartCuts( Abc_ManRwr_t * p, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i;
// set the trivial cuts
Abc_NtkCleanCopy( pNtk );
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Rwr_CutCreateTriv( p, pNode );
// precompute the required times for all internal nodes
p->vFanNums = Rwt_NtkFanoutCounters( pNtk );
// save the fanout counters for all internal nodes
p->vReqTimes = Rwt_NtkRequiredLevels( pNtk );
}
/**Function*************************************************************
Synopsis [Computes cuts for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeRwrComputeCuts( Abc_ManRwr_t * p, Abc_Obj_t * pNode )
{
Rwr_Cut_t * pCuts0, * pCuts1, * pTemp0, * pTemp1, * pCut;
Rwr_Cut_t * pList = NULL, ** ppPlace = &pList; // linked list of cuts
assert( Abc_ObjIsNode(pNode) );
if ( Abc_NodeIsConst(pNode) )
return;
// create the elementary cut
pCut = Rwr_CutCreateTriv( p, pNode );
// add it to the linked list
*ppPlace = pCut; ppPlace = &pCut->pNext;
// create cuts by merging pairwise
pCuts0 = (Rwr_Cut_t *)Abc_ObjFanin0(pNode)->pCopy;
pCuts1 = (Rwr_Cut_t *)Abc_ObjFanin1(pNode)->pCopy;
assert( pCuts0 && pCuts1 );
for ( pTemp0 = pCuts0; pTemp0; pTemp0 = pTemp0->pNext )
for ( pTemp1 = pCuts1; pTemp1; pTemp1 = pTemp1->pNext )
{
pCut = Rwr_CutsMerge( p, pTemp0, pTemp1, Abc_ObjFaninC0(pNode), Abc_ObjFaninC1(pNode) );
if ( pCut == NULL )
continue;
// add it to the linked list
*ppPlace = pCut; ppPlace = &pCut->pNext;
}
// set the linked list
pNode->pCopy = (Abc_Obj_t *)pList;
}
/**Function*************************************************************
Synopsis [Start the cut computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Rwr_Cut_t * Rwr_CutsMerge( Abc_ManRwr_t * p, Rwr_Cut_t * pCut0, Rwr_Cut_t * pCut1, int fCompl0, int fCompl1 )
{
Abc_Obj_t * ppNodes[4], * pNodeTemp;
Rwr_Cut_t * pCut;
unsigned uPhase, uTruth0, uTruth1;
int i, k, min, nTotal;
// solve the most typical case: both cuts are four input
if ( pCut0->nLeaves == 4 && pCut1->nLeaves == 4 )
{
for ( i = 0; i < 4; i++ )
if ( pCut0->ppLeaves[i] != pCut1->ppLeaves[i] )
return NULL;
// create the cut
pCut = Rwr_CutAlloc( p );
pCut->nLeaves = 4;
for ( i = 0; i < 4; i++ )
pCut->ppLeaves[i] = pCut0->ppLeaves[i];
pCut->uTruth = (fCompl0? ~pCut0->uTruth : pCut0->uTruth) & (fCompl1? ~pCut1->uTruth : pCut1->uTruth) & 0xFFFF;
return pCut;
}
// create the set of new nodes
// count the number of unique entries in pCut1
nTotal = pCut0->nLeaves;
for ( i = 0; i < (int)pCut1->nLeaves; i++ )
{
// try to find this entry among the leaves of pCut0
for ( k = 0; k < (int)pCut0->nLeaves; k++ )
if ( pCut1->ppLeaves[i] == pCut0->ppLeaves[k] )
break;
if ( k < (int)pCut0->nLeaves ) // found
continue;
// we found a new entry to add
if ( nTotal == 4 )
return NULL;
ppNodes[nTotal++] = pCut1->ppLeaves[i];
}
// we know that the feasible cut exists
// add the starting entries
for ( k = 0; k < (int)pCut0->nLeaves; k++ )
ppNodes[k] = pCut0->ppLeaves[k];
// selection-sort the entries
for ( i = 0; i < nTotal - 1; i++ )
{
min = i;
for ( k = i+1; k < nTotal; k++ )
if ( ppNodes[k]->Id < ppNodes[min]->Id )
min = k;
pNodeTemp = ppNodes[i];
ppNodes[i] = ppNodes[min];
ppNodes[min] = pNodeTemp;
}
// find the mapping from the old nodes to the new
if ( pCut0->nLeaves == 4 )
uTruth0 = pCut0->uTruth;
else
{
uPhase = 0;
for ( i = 0; i < (int)pCut0->nLeaves; i++ )
{
for ( k = 0; k < nTotal; k++ )
if ( pCut0->ppLeaves[i] == ppNodes[k] )
break;
uPhase |= (1 << k);
}
assert( uPhase < 16 );
assert( pCut0->uTruth < 256 );
uTruth0 = p->puPerms[pCut0->uTruth][uPhase];
}
// find the mapping from the old nodes to the new
if ( pCut1->nLeaves == 4 )
uTruth1 = pCut1->uTruth;
else
{
uPhase = 0;
for ( i = 0; i < (int)pCut1->nLeaves; i++ )
{
for ( k = 0; k < nTotal; k++ )
if ( pCut1->ppLeaves[i] == ppNodes[k] )
break;
uPhase |= (1 << k);
}
assert( uPhase < 16 );
assert( pCut1->uTruth < 256 );
uTruth1 = p->puPerms[pCut1->uTruth][uPhase];
}
// create the cut
pCut = Rwr_CutAlloc( p );
pCut->nLeaves = nTotal;
for ( i = 0; i < nTotal; i++ )
pCut->ppLeaves[i] = ppNodes[i];
pCut->uTruth = (fCompl0? ~uTruth0 : uTruth0) & (fCompl1? ~uTruth1 : uTruth1) & 0xFFFF;
return pCut;
}
/**Function*************************************************************
Synopsis [Start the cut computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Rwr_Cut_t * Rwr_CutAlloc( Abc_ManRwr_t * p )
{
Rwr_Cut_t * pCut;
pCut = (Rwr_Cut_t *)Extra_MmFixedEntryFetch( p->pMmNode );
memset( pCut, 0, sizeof(Rwr_Cut_t) );
return pCut;
}
/**Function*************************************************************
Synopsis [Start the cut computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Rwr_Cut_t * Rwr_CutCreateTriv( Abc_ManRwr_t * p, Abc_Obj_t * pNode )
{
Rwr_Cut_t * pCut;
pCut = Rwr_CutAlloc( p );
pCut->nLeaves = 1;
pCut->ppLeaves[0] = pNode;
pCut->uTruth = 0xAAAA;
return pCut;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [rwrDec.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting package.]
Synopsis [Evaluation and decomposition procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: rwrDec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "rwr.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Rwr_CutEvaluate( Abc_ManRwr_t * p, Rwr_Cut_t * pCut );
static void Rwr_CutDecompose( Abc_ManRwr_t * p, Rwr_Cut_t * pCut, Vec_Int_t * vForm );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs rewriting for one node.]
Description [This procedure considers all the cuts computed for the node
and tries to rewrite each of them using the "forest" of different AIG
structures precomputed and stored in the RWR manager.
Determines the best rewriting and computes the gain in the number of AIG
nodes in the final network. In the end, p->vFanins contains information
about the best cut that can be used for rewriting, while p->vForm gives
the decomposition tree (represented using factored form data structure).
Returns gain in the number of nodes or -1 if node cannot be rewritten.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NodeRwrRewrite( Abc_ManRwr_t * p, Abc_Obj_t * pNode )
{
Vec_Ptr_t Vector = {0,0,0}, * vFanins = &Vector;
Rwr_Cut_t * pCut, * pCutBest;
int BestGain = -1;
int i, Required = Vec_IntEntry( p->vReqTimes, pNode->Id );
// go through the cuts
for ( pCut = (Rwr_Cut_t *)pNode->pCopy, pCut = pCut->pNext; pCut; pCut = pCut->pNext )
{
// collect the TFO
vFanins->nSize = pCut->nLeaves;
vFanins->pArray = pCut->ppLeaves;
Abc_NodeCollectTfoCands( pNode->pNtk, pNode, vFanins, Required, p->vLevels, p->vTfo );
// evaluate the cut
Rwr_CutEvaluate( p, pCut );
// check if the cut is the best
if ( pCut->fTime && pCut->fGain )
{
pCutBest = pCut;
BestGain = pCut->Volume;
}
}
if ( BestGain == -1 )
return -1;
// we found a good cut
// prepare the fanins
Vec_PtrClear( p->vFanins );
for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
Vec_PtrPush( p->vFanins, pCutBest->ppLeaves[i] );
// collect the TFO again
Abc_NodeCollectTfoCands( pNode->pNtk, pNode, p->vFanins, Required, p->vLevels, p->vTfo );
// perform the decomposition
Rwr_CutDecompose( p, pCutBest, p->vForm );
// the best fanins are in p->vFanins, the result of decomposition is in p->vForm
return BestGain;
}
/**Function*************************************************************
Synopsis [Evaluates one cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Rwr_CutEvaluate( Abc_ManRwr_t * p, Rwr_Cut_t * pCut )
{
}
/**Function*************************************************************
Synopsis [Evaluates one cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Rwr_CutDecompose( Abc_ManRwr_t * p, Rwr_Cut_t * pCut, Vec_Int_t * vForm )
{
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [rwrExp.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting package.]
Synopsis [Computation of practically used NN-classes of 4-input cuts.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: rwrExp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "rwr.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef struct Abc_ManRwrExp_t_ Abc_ManRwrExp_t;
struct Abc_ManRwrExp_t_
{
// internal lookups
int nFuncs; // the number of four-var functions
unsigned short * puCanons; // canonical forms
int * pnCounts; // the counters of functions in each class
int nConsidered; // the number of nodes considered
int nClasses; // the number of NN classes
};
static Abc_ManRwrExp_t * s_pManRwrExp = NULL;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Collects stats about 4-var functions appearing in netlists.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Rwt_ManExploreStart()
{
Abc_ManRwrExp_t * p;
unsigned uTruth;
int i, k, nClasses;
int clk = clock();
p = ALLOC( Abc_ManRwrExp_t, 1 );
memset( p, 0, sizeof(Abc_ManRwrExp_t) );
// canonical forms
p->nFuncs = (1<<16);
p->puCanons = ALLOC( unsigned short, p->nFuncs );
memset( p->puCanons, 0, sizeof(unsigned short) * p->nFuncs );
// counters
p->pnCounts = ALLOC( int, p->nFuncs );
memset( p->pnCounts, 0, sizeof(int) * p->nFuncs );
// initialize the canonical forms
nClasses = 1;
for ( i = 1; i < p->nFuncs-1; i++ )
{
if ( p->puCanons[i] )
continue;
nClasses++;
for ( k = 0; k < 32; k++ )
{
uTruth = Rwr_FunctionPhase( (unsigned)i, (unsigned)k );
if ( p->puCanons[uTruth] == 0 )
p->puCanons[uTruth] = (unsigned short)i;
else
assert( p->puCanons[uTruth] == (unsigned short)i );
}
}
// set info for constant 1
p->puCanons[p->nFuncs-1] = 0;
printf( "The number of NN-canonical forms = %d.\n", nClasses );
s_pManRwrExp = p;
}
/**Function*************************************************************
Synopsis [Collects stats about 4-var functions appearing in netlists.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Rwt_ManExploreCount( unsigned uTruth )
{
assert( uTruth < (1<<16) );
s_pManRwrExp->pnCounts[ s_pManRwrExp->puCanons[uTruth] ]++;
}
/**Function*************************************************************
Synopsis [Collects stats about 4-var functions appearing in netlists.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Rwt_ManExplorePrint()
{
FILE * pFile;
int i, CountMax, CountWrite, nCuts, nClasses;
int * pDistrib;
int * pReprs;
// find the max number of occurences
nCuts = nClasses = 0;
CountMax = 0;
for ( i = 0; i < s_pManRwrExp->nFuncs; i++ )
{
if ( CountMax < s_pManRwrExp->pnCounts[i] )
CountMax = s_pManRwrExp->pnCounts[i];
nCuts += s_pManRwrExp->pnCounts[i];
if ( s_pManRwrExp->pnCounts[i] > 0 )
nClasses++;
}
printf( "Number of cuts considered = %8d.\n", nCuts );
printf( "Classes occurring at least once = %8d.\n", nClasses );
// print the distribution of classes
pDistrib = ALLOC( int, CountMax + 1 );
pReprs = ALLOC( int, CountMax + 1 );
memset( pDistrib, 0, sizeof(int)*(CountMax + 1) );
for ( i = 0; i < s_pManRwrExp->nFuncs; i++ )
{
pDistrib[ s_pManRwrExp->pnCounts[i] ]++;
pReprs[ s_pManRwrExp->pnCounts[i] ] = i;
}
printf( "Occurence = %6d. Num classes = %4d. \n", 0, 2288-nClasses );
for ( i = 1; i <= CountMax; i++ )
if ( pDistrib[i] )
{
printf( "Occurence = %6d. Num classes = %4d. Repr = ", i, pDistrib[i] );
Extra_PrintBinary( stdout, (unsigned*)&(pReprs[i]), 16 );
printf( "\n" );
}
free( pDistrib );
free( pReprs );
// write into a file all classes above limit (5)
CountWrite = 0;
pFile = fopen( "nnclass_stats.txt", "w" );
for ( i = 0; i < s_pManRwrExp->nFuncs; i++ )
if ( s_pManRwrExp->pnCounts[i] > 5 )
{
fprintf( pFile, "%d ", i );
CountWrite++;
}
fclose( pFile );
printf( "%d classes written into file \"%s\".\n", CountWrite, "nnclass_stats.txt" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [rwrUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting package.]
Synopsis [Various utilities.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: rwrUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "rwr.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates the array of fanout counters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Rwt_NtkFanoutCounters( Abc_Ntk_t * pNtk )
{
Vec_Int_t * vFanNums;
Abc_Obj_t * pObj;
int i;
vFanNums = Vec_IntAlloc( 0 );
Vec_IntFill( vFanNums, Abc_NtkObjNumMax(pNtk), -1 );
Abc_NtkForEachObj( pNtk, pObj, i )
if ( Abc_ObjIsNode( pObj ) )
Vec_IntWriteEntry( vFanNums, i, Abc_ObjFanoutNum(pObj) );
return vFanNums;
}
/**Function*************************************************************
Synopsis [Creates the array of required times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Rwt_NtkRequiredLevels( Abc_Ntk_t * pNtk )
{
Vec_Int_t * vReqTimes;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj, * pFanout;
int i, k, nLevelsMax, nLevelsCur;
// start the required times
vReqTimes = Vec_IntAlloc( 0 );
Vec_IntFill( vReqTimes, Abc_NtkObjNumMax(pNtk), ABC_INFINITY );
// compute levels in reverse topological order
Abc_NtkForEachCo( pNtk, pObj, i )
Vec_IntWriteEntry( vReqTimes, pObj->Id, 0 );
vNodes = Abc_NtkDfsReverse( pNtk );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
nLevelsCur = 0;
Abc_ObjForEachFanout( pObj, pFanout, k )
if ( nLevelsCur < Vec_IntEntry(vReqTimes, pFanout->Id) )
nLevelsCur = Vec_IntEntry(vReqTimes, pFanout->Id);
Vec_IntWriteEntry( vReqTimes, pObj->Id, nLevelsCur + 1 );
}
Vec_PtrFree( vNodes );
// convert levels into required times: RetTime = NumLevels + 1 - Level
nLevelsMax = Abc_AigGetLevelNum(pNtk) + 1;
Abc_NtkForEachNode( pNtk, pObj, i )
Vec_IntWriteEntry( vReqTimes, pObj->Id, nLevelsMax - Vec_IntEntry(vReqTimes, pObj->Id) );
// Abc_NtkForEachNode( pNtk, pObj, i )
// printf( "(%d,%d)", pObj->Level, Vec_IntEntry(vReqTimes, pObj->Id) );
// printf( "\n" );
return vReqTimes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -136,7 +136,7 @@ int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets )
{
Sim_Pat_t * pPat;
Vec_Int_t * vTargets;
Vec_Ptr_t * vNodesByLevel;
Vec_Vec_t * vNodesByLevel;
Abc_Obj_t * pNodeCi, * pNode;
int i, k, v, Output, LuckyPat, fType0, fType1;
int Counter = 0;
......@@ -147,7 +147,7 @@ int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets )
// complement the simulation info of the selected CI
Sim_UtilFlipSimInfo( p, pNodeCi );
// simulate the levelized structure of nodes
Vec_PtrForEachEntryByLevel( vNodesByLevel, pNode, i, k )
Vec_VecForEachEntry( vNodesByLevel, pNode, i, k )
{
fType0 = Abc_NodeIsTravIdCurrent( Abc_ObjFanin0(pNode) );
fType1 = Abc_NodeIsTravIdCurrent( Abc_ObjFanin1(pNode) );
......@@ -213,7 +213,7 @@ int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets )
}
}
}
Vec_PtrFreeFree( vNodesByLevel );
Vec_VecFree( vNodesByLevel );
return Counter;
}
......
......@@ -52,16 +52,17 @@ struct Ft_Node_t_
};
/*
The factored form of a SOP is an array (Vec_Int_t) of entries Ft_Node_t.
The factored form of an SOP is an array (Vec_Int_t) of entries of type Ft_Node_t.
If the SOP has n input variables (some of them may not be in the true support)
the first n entries of the factored form array have 0s. This representation
makes it each to translate the factored form into an AIG.
The node structure contains fanins of the node and their complemented attributes
(using AIG semantics). The elementary variable (buffer or interver) are
represented as a node with the same fanins. For example: x' = AND( x', x' ).
The constant node cannot be represented. Constant functions should be detected
before calling the factoring procedure.
the first n entries of the factored form array are zeros. The other entries of the array
represent the internal AND nodes of the factored form, and possibly the constant node.
This representation makes it easy to translate the factored form into an AIG.
The factored AND nodes contains fanins of the node and their complemented attributes
(using AIG semantics). The elementary variable (buffer or interver) are represented
as a node with the same fanins. For example: x' = AND( x', x' ).
The constant node is represented a special node with the constant flag set.
If the constant node and the elementary variable are present, no other internal
AND nodes are allowed in the factored form.
*/
// working with complemented attributes of objects
......
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