summaryrefslogtreecommitdiffstats
path: root/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'src/base')
-rw-r--r--src/base/abc/abc.h3
-rw-r--r--src/base/abc/abcFunc.c3
-rw-r--r--src/base/abc/abcMinBase.c25
-rw-r--r--src/base/abc/abcNetlist.c12
-rw-r--r--src/base/abc/abcNtk.c8
-rw-r--r--src/base/abc/abcUtil.c170
-rw-r--r--src/base/abci/abc.c6
-rw-r--r--src/base/abci/abcMiter.c6
-rw-r--r--src/base/abci/abcSweep.c152
-rw-r--r--src/base/io/ioReadBlif.c2
10 files changed, 226 insertions, 161 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index 1a3f3264..a921081b 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -787,7 +787,8 @@ extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanNext( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk );
-extern Abc_Obj_t * Abc_NodeHasCoFanout( Abc_Obj_t * pNode );
+extern Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode );
+extern Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode );
extern Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode );
extern bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk );
extern int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate );
diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c
index 7ffe7eac..7818cc05 100644
--- a/src/base/abc/abcFunc.c
+++ b/src/base/abc/abcFunc.c
@@ -744,6 +744,9 @@ void Abc_ConvertAigToBdd_rec2( DdManager * dd, Aig_Obj_t * pObj )
DdNode * Abc_ConvertAigToBdd( DdManager * dd, Aig_Obj_t * pRoot )
{
DdNode * bFunc;
+ // check the case of a constant
+ if ( Aig_ObjIsConst1( Aig_Regular(pRoot) ) )
+ return Cudd_NotCond( Cudd_ReadOne(dd), Aig_IsComplement(pRoot) );
// construct BDD
Abc_ConvertAigToBdd_rec1( dd, Aig_Regular(pRoot) );
// hold on to the result
diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c
index 604dd96e..13f422f4 100644
--- a/src/base/abc/abcMinBase.c
+++ b/src/base/abc/abcMinBase.c
@@ -112,12 +112,11 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
- int i, Counter, fChanged;
+ int i, Counter;
assert( Abc_NtkIsBddLogic(pNtk) );
Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i )
- while ( fChanged = Abc_NodeRemoveDupFanins(pNode) )
- Counter += fChanged;
+ Counter += Abc_NodeRemoveDupFanins( pNode );
return Counter;
}
@@ -132,7 +131,7 @@ int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode )
+int Abc_NodeRemoveDupFanins_int( Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanin1, * pFanin2;
int i, k;
@@ -165,6 +164,24 @@ int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode )
/**Function*************************************************************
+ Synopsis [Removes duplicated fanins if present.]
+
+ Description [Returns the number of fanins removed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode )
+{
+ int Counter = 0;
+ while ( Abc_NodeRemoveDupFanins_int(pNode) )
+ Counter++;
+ return Counter;
+}
+/**Function*************************************************************
+
Synopsis [Computes support of the node.]
Description []
diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c
index 0650896d..f71093ef 100644
--- a/src/base/abc/abcNetlist.c
+++ b/src/base/abc/abcNetlist.c
@@ -321,6 +321,9 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj, * pNet, * pDriver, * pFanin;
int i, k;
+ // remove dangling nodes
+ Abc_NtkCleanup( pNtk, 0 );
+
assert( Abc_NtkIsLogic(pNtk) );
assert( Abc_NtkLogicHasSimpleCos(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
@@ -340,11 +343,7 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
}
// duplicate all nodes
Abc_NtkForEachNode( pNtk, pObj, i )
- {
- if ( Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 )
- continue;
Abc_NtkDupObj(pNtkNew, pObj, 0);
- }
// first add the nets to the CO drivers
Abc_NtkForEachCo( pNtk, pObj, i )
{
@@ -367,13 +366,14 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
pDriver->pCopy->pCopy = pNet;
}
else
+ {
assert( !strcmp( Abc_ObjName(pDriver->pCopy->pCopy), Abc_ObjName(pObj) ) );
+ Abc_ObjAddFanin( pObj->pCopy, pDriver->pCopy->pCopy );
+ }
}
// create the missing nets
Abc_NtkForEachNode( pNtk, pObj, i )
{
- if ( Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 )
- continue;
if ( pObj->pCopy->pCopy ) // the net of the new object is already created
continue;
// create the new net
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index 37461c22..d7283d55 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -767,6 +767,12 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
Abc_Obj_t * pNet, * pNode;
int i;
+ if ( Abc_NtkNodeNum(pNtk) == 0 )
+ {
+ pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
+ return;
+ }
+
// check for non-driven nets
vNets = Vec_PtrAlloc( 100 );
Abc_NtkForEachNet( pNtk, pNet, i )
@@ -784,7 +790,7 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
// print the warning
if ( vNets->nSize > 0 )
{
- printf( "Constant-zero drivers were added to %d non-driven nets:\n", vNets->nSize );
+ printf( "Constant-zero drivers were added to %d non-driven nets in network %s:\n", vNets->nSize, pNtk->pName );
for ( i = 0; i < vNets->nSize; i++ )
{
if ( i == 0 )
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index 2dbfef33..6e506b0e 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -444,12 +444,10 @@ void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeHasCoFanout( Abc_Obj_t * pNode )
+Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanout;
int i;
- if ( !Abc_ObjIsNode(pNode) )
- return NULL;
Abc_ObjForEachFanout( pNode, pFanout, i )
if ( Abc_ObjIsCo(pFanout) )
return pFanout;
@@ -458,9 +456,30 @@ Abc_Obj_t * Abc_NodeHasCoFanout( Abc_Obj_t * pNode )
/**Function*************************************************************
+ Synopsis [Checks if the internal node has CO fanout.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pFanout;
+ int i;
+ Abc_ObjForEachFanout( pNode, pFanout, i )
+ if ( !Abc_ObjIsCo(pFanout) )
+ return pFanout;
+ return NULL;
+}
+
+/**Function*************************************************************
+
Synopsis [Checks if the internal node has CO drivers with the same name.]
- Description [Checks if the internal node can borrow a name from CO fanouts.
+ Description [Checks if the internal node can borrow its name from CO fanouts.
This is possible if all COs with non-complemented fanin edge pointing to this
node have the same name.]
@@ -473,8 +492,6 @@ Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanout, * pFanoutCo;
int i;
- if ( !Abc_ObjIsNode(pNode) )
- return NULL;
pFanoutCo = NULL;
Abc_ObjForEachFanout( pNode, pFanout, i )
{
@@ -497,13 +514,60 @@ Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode )
/**Function*************************************************************
+ Synopsis [Fixes the CO driver problem.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fDuplicate )
+{
+ Abc_Ntk_t * pNtk = pDriver->pNtk;
+ Abc_Obj_t * pDriverNew, * pFanin;
+ int k;
+ if ( fDuplicate && !Abc_ObjIsCi(pDriver) )
+ {
+ pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
+ Abc_ObjForEachFanin( pDriver, pFanin, k )
+ Abc_ObjAddFanin( pDriverNew, pFanin );
+ if ( Abc_ObjFaninC0(pNodeCo) )
+ {
+ // change polarity of the duplicated driver
+ Abc_NodeComplement( pDriverNew );
+ Abc_ObjXorFaninC( pNodeCo, 0 );
+ }
+ }
+ else
+ {
+ // add inverters and buffers when necessary
+ if ( Abc_ObjFaninC0(pNodeCo) )
+ {
+ pDriverNew = Abc_NodeCreateInv( pNtk, pDriver );
+ Abc_ObjXorFaninC( pNodeCo, 0 );
+ }
+ else
+ pDriverNew = Abc_NodeCreateBuf( pNtk, pDriver );
+ }
+ // update the fanin of the PO node
+ Abc_ObjPatchFanin( pNodeCo, pDriver, pDriverNew );
+ assert( Abc_ObjFanoutNum(pDriverNew) == 1 );
+ // remove the old driver if it dangles
+ // (this happens when the duplicated driver had only one complemented fanout)
+ if ( Abc_ObjFanoutNum(pDriver) == 0 )
+ Abc_NtkDeleteObj( pDriver );
+}
+
+/**Function*************************************************************
+
Synopsis [Returns 1 if COs of a logic network are simple.]
Description [The COs of a logic network are simple under three conditions:
(1) The edge from CO to its driver is not complemented.
- (2) No two COs share the same driver.
- (3) The driver is not a CI unless the CI and the CO have the same name
- (and so the inv/buf should not be written into a file).]
+ (2) If CI is a driver of a CO, they have the same name.]
+ (2) If two COs share the same driver, they have the same name.]
SideEffects []
@@ -514,19 +578,27 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode, * pDriver;
int i;
- assert( !Abc_NtkIsNetlist(pNtk) );
- // check if there are complemented or idential POs
+ assert( Abc_NtkIsLogic(pNtk) );
Abc_NtkIncrementTravId( pNtk );
Abc_NtkForEachCo( pNtk, pNode, i )
{
+ // if the driver is complemented, this is an error
pDriver = Abc_ObjFanin0(pNode);
if ( Abc_ObjFaninC0(pNode) )
return 0;
- if ( Abc_NodeIsTravIdCurrent(pDriver) )
+ // if the driver is a CI and has different name, this is an error
+ if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
return 0;
- if ( Abc_ObjIsCi(pDriver) && strcmp( Abc_ObjName(pDriver), Abc_ObjName(pNode) ) != 0 )
+ // if the driver is visited for the first time, remember the CO name
+ if ( !Abc_NodeIsTravIdCurrent(pDriver) )
+ {
+ pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
+ Abc_NodeSetTravIdCurrent(pDriver);
+ continue;
+ }
+ // the driver has second CO - if they have different name, this is an error
+ if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
return 0;
- Abc_NodeSetTravIdCurrent(pDriver);
}
return 1;
}
@@ -536,10 +608,9 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
Synopsis [Transforms the network to have simple COs.]
Description [The COs of a logic network are simple under three conditions:
- (1) The edge from the CO to its driver is not complemented.
- (2) No two COs share the same driver (unless they have the same name!).
- (3) The driver is not a CI unless the CI and the CO have the same name
- (and so the inv/buf should not be written into a file).
+ (1) The edge from CO to its driver is not complemented.
+ (2) If CI is a driver of a CO, they have the same name.]
+ (2) If two COs share the same driver, they have the same name.
In some cases, such as FPGA mapping, we prevent the increase in delay
by duplicating the driver nodes, rather than adding invs/bufs.]
@@ -550,58 +621,41 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
***********************************************************************/
int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate )
{
- Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
- int i, k, nDupGates = 0;
+ Abc_Obj_t * pNode, * pDriver;
+ int i, nDupGates = 0;
assert( Abc_NtkIsLogic(pNtk) );
- // process the COs by adding inverters and buffers when necessary
+ Abc_NtkIncrementTravId( pNtk );
Abc_NtkForEachCo( pNtk, pNode, i )
{
+ // if the driver is complemented, this is an error
pDriver = Abc_ObjFanin0(pNode);
- if ( Abc_ObjIsCi(pDriver) )
+ if ( Abc_ObjFaninC0(pNode) )
{
- // skip the case when the driver is a different node with the same name
- if ( pDriver != pNode && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) == 0 )
- {
- assert( !Abc_ObjFaninC0(pNode) );
- continue;
- }
+ Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
+ nDupGates++;
+ continue;
}
- else if ( !Abc_ObjFaninC0(pNode) )
+ // if the driver is a CI and has different name, this is an error
+ if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
{
- // skip the case when all CO fanouts of the driver have the same name
- if ( Abc_NodeHasUniqueCoFanout(pDriver) )
- continue;
+ Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
+ nDupGates++;
+ continue;
}
- if ( fDuplicate && !Abc_ObjIsCi(pDriver) )
+ // if the driver is visited for the first time, remember the CO name
+ if ( !Abc_NodeIsTravIdCurrent(pDriver) )
{
- pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
- Abc_ObjForEachFanin( pDriver, pFanin, k )
- Abc_ObjAddFanin( pDriverNew, pFanin );
- if ( Abc_ObjFaninC0(pNode) )
- {
- // change polarity of the duplicated driver
- Abc_NodeComplement( pDriverNew );
- Abc_ObjXorFaninC( pNode, 0 );
- }
+ pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
+ Abc_NodeSetTravIdCurrent(pDriver);
+ continue;
}
- else
+ // the driver has second CO - if they have different name, this is an error
+ if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
{
- // add inverters and buffers when necessary
- if ( Abc_ObjFaninC0(pNode) )
- {
- pDriverNew = Abc_NodeCreateInv( pNtk, pDriver );
- Abc_ObjXorFaninC( pNode, 0 );
- }
- else
- pDriverNew = Abc_NodeCreateBuf( pNtk, pDriver );
+ Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
+ nDupGates++;
+ continue;
}
- // update the fanin of the PO node
- Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
- assert( Abc_ObjFanoutNum(pDriverNew) == 1 );
- nDupGates++;
- // remove the old driver if it dangles
- if ( Abc_ObjFanoutNum(pDriver) == 0 )
- Abc_NtkDeleteObj( pDriver );
}
assert( Abc_NtkLogicHasSimpleCos(pNtk) );
return nDupGates;
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index bbc9a226..0f20e4d8 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -2175,9 +2175,9 @@ int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Empty network.\n" );
return 1;
}
- if ( !Abc_NtkIsSopLogic(pNtk) && !Abc_NtkIsBddLogic(pNtk) )
+ if ( !Abc_NtkIsLogic(pNtk) )
{
- fprintf( pErr, "Sweep cannot be performed on an AIG or a mapped network (run \"unmap\").\n" );
+ fprintf( pErr, "The classical (SIS-like) sweep can only be performed on a logic network.\n" );
return 1;
}
// modify the current network
@@ -3401,7 +3401,7 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( !Abc_NtkLogicToSop(pNtk, fDirect) )
{
- fprintf( pErr, "Converting to BDD has failed.\n" );
+ fprintf( pErr, "Converting to SOP has failed.\n" );
return 1;
}
return 0;
diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c
index ab61dd45..64f414aa 100644
--- a/src/base/abci/abcMiter.c
+++ b/src/base/abci/abcMiter.c
@@ -593,7 +593,7 @@ int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter )
Abc_NtkForEachPo( pMiter, pNodePo, i )
{
pChild = Abc_ObjChild0( pNodePo );
- if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) )
+ if ( Abc_AigNodeIsConst(pChild) )
{
assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter) );
if ( !Abc_ObjIsComplement(pChild) )
@@ -629,7 +629,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
if ( Abc_NtkPoNum(pMiter) == 1 )
{
pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) );
- if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) )
+ if ( Abc_AigNodeIsConst(pChild) )
{
if ( Abc_ObjIsComplement(pChild) )
printf( "Unsatisfiable.\n" );
@@ -645,7 +645,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
{
pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) );
printf( "Output #%2d : ", i );
- if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) )
+ if ( Abc_AigNodeIsConst(pChild) )
{
if ( Abc_ObjIsComplement(pChild) )
printf( "Unsatisfiable.\n" );
diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c
index 7c6df88a..cac634da 100644
--- a/src/base/abci/abcSweep.c
+++ b/src/base/abci/abcSweep.c
@@ -197,7 +197,7 @@ stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose )
if ( pNodeAig == NULL )
continue;
// skip the nodes that fanout into COs
- if ( Abc_NodeHasCoFanout(pNode) )
+ if ( Abc_NodeFindCoFanout(pNode) )
continue;
// get the FRAIG node
gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) );
@@ -495,12 +495,8 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
int i, Counter;
assert( Abc_NtkIsLogic(pNtk) );
// mark the nodes reachable from the POs
- for ( i = 0; i < vNodes->nSize; i++ )
- {
- pNode = vNodes->pArray[i];
- assert( Abc_ObjIsNode(pNode) );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
pNode->fMarkA = 1;
- }
// remove the non-marked nodes
Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i )
@@ -510,7 +506,7 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
Counter++;
}
// unmark the remaining nodes
- Abc_NtkForEachNode( pNtk, pNode, i )
+ Vec_PtrForEachEntry( vNodes, pNode, i )
pNode->fMarkA = 0;
// check
if ( !Abc_NtkCheck( pNtk ) )
@@ -534,86 +530,40 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
***********************************************************************/
int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
{
- Abc_Obj_t * pNode;
- int i, fConvert, nSwept, nSweptNew;
- assert( Abc_NtkIsSopLogic(pNtk) || Abc_NtkIsBddLogic(pNtk) );
- // convert to the BDD representation
- fConvert = 0;
- if ( Abc_NtkIsSopLogic(pNtk) )
- Abc_NtkSopToBdd(pNtk), fConvert = 1;
- // perform cleanup to get rid of dangling nodes
- nSwept = Abc_NtkCleanup( pNtk, 0 );
- // make the network minimum base
- Abc_NtkRemoveDupFanins(pNtk);
- Abc_NtkMinimumBase(pNtk);
- do
- {
- // sweep constants and single-input nodes
- Abc_NtkForEachNode( pNtk, pNode, i )
- if ( i && Abc_ObjFaninNum(pNode) < 2 )
- Abc_NodeSweep( pNode, fVerbose );
- // make the network minimum base
- Abc_NtkRemoveDupFanins(pNtk);
- Abc_NtkMinimumBase(pNtk);
- // perform final clean up (in case new danglies are created)
- nSweptNew = Abc_NtkCleanup( pNtk, 0 );
- nSwept += nSweptNew;
- }
- while ( nSweptNew );
- // conver back to BDD
- if ( fConvert )
- Abc_NtkBddToSop(pNtk, 0);
- // report
- if ( fVerbose )
- printf( "Sweep removed %d nodes.\n", nSwept );
- // check
- if ( !Abc_NtkCheck( pNtk ) )
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pFanout, * pDriver;
+ int i, nNodesOld;
+ assert( Abc_NtkIsLogic(pNtk) );
+ // convert network to BDD representation
+ if ( !Abc_NtkLogicToBdd(pNtk) )
{
- printf( "Abc_NtkSweep: The network check has failed.\n" );
- return -1;
+ fprintf( stdout, "Converting to BDD has failed.\n" );
+ return 1;
}
- return nSwept;
-}
-
-/**Function*************************************************************
-
- Synopsis [Tranditional sweep of the network.]
-
- Description [Propagates constant and single-input node, removes dangling nodes.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose )
-{
- Abc_Obj_t * pFanout, * pDriver;
- Vec_Ptr_t * vFanout;
- int i;
- assert( Abc_ObjFaninNum(pNode) < 2 );
- assert( Abc_ObjFanoutNum(pNode) > 0 );
- // iterate through the fanouts
- vFanout = Vec_PtrAlloc( Abc_ObjFanoutNum(pNode) );
- Abc_NodeCollectFanouts( pNode, vFanout );
- Vec_PtrForEachEntry( vFanout, pFanout, i )
+ // perform cleanup
+ nNodesOld = Abc_NtkNodeNum(pNtk);
+ Abc_NtkCleanup( pNtk, 0 );
+ // prepare nodes for sweeping
+ Abc_NtkRemoveDupFanins(pNtk);
+ Abc_NtkMinimumBase(pNtk);
+ // collect sweepable nodes
+ vNodes = Vec_PtrAlloc( 100 );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ if ( Abc_ObjFaninNum(pNode) < 2 )
+ Vec_PtrPush( vNodes, pNode );
+ // sweep the nodes
+ while ( Vec_PtrSize(vNodes) > 0 )
{
- if ( Abc_ObjIsCo(pFanout) )
- {
- if ( Abc_ObjFaninNum(pNode) == 1 )
- {
- pDriver = Abc_ObjFanin0(pNode);
- if ( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 1 || Abc_ObjFanoutNum(pNode) > 1 )
- continue;
- // the driver is a node and its only fanout is this node
- if ( Abc_NodeIsInv(pNode) )
- pDriver->pData = Cudd_Not(pDriver->pData);
- // replace the fanin of the fanout
- Abc_ObjPatchFanin( pFanout, pNode, pDriver );
- }
+ // get any sweepable node
+ pNode = Vec_PtrPop(vNodes);
+ if ( !Abc_ObjIsNode(pNode) )
continue;
- }
- // the fanout is a regular node
+ // get any non-CO fanout of this node
+ pFanout = Abc_NodeFindNonCoFanout(pNode);
+ if ( pFanout == NULL )
+ continue;
+ assert( Abc_ObjIsNode(pFanout) );
+ // transform the function of the fanout
if ( Abc_ObjFaninNum(pNode) == 0 )
Abc_NodeConstantInput( pFanout, pNode, Abc_NodeIsConst0(pNode) );
else
@@ -624,10 +574,44 @@ void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose )
Abc_NodeComplementInput( pFanout, pNode );
Abc_ObjPatchFanin( pFanout, pNode, pDriver );
}
+ Abc_NodeRemoveDupFanins( pFanout );
+ Abc_NodeMinimumBase( pFanout );
+ // check if the fanout should be added
+ if ( Abc_ObjFaninNum(pFanout) < 2 )
+ Vec_PtrPush( vNodes, pFanout );
+ // check if the node has other fanouts
+ if ( Abc_ObjFanoutNum(pNode) > 0 )
+ Vec_PtrPush( vNodes, pNode );
+ else
+ Abc_NtkDeleteObj_rec( pNode );
}
- Vec_PtrFree( vFanout );
+ Vec_PtrFree( vNodes );
+ // sweep a node into its CO fanout if all of this is true:
+ // (a) this node is a single-input node
+ // (b) the driver of the node has only one fanout (this node)
+ // (c) the driver is a node
+ Abc_NtkForEachCo( pNtk, pFanout, i )
+ {
+ pNode = Abc_ObjFanin0(pFanout);
+ if ( Abc_ObjFaninNum(pNode) != 1 )
+ continue;
+ pDriver = Abc_ObjFanin0(pNode);
+ if ( !(Abc_ObjFanoutNum(pDriver) == 1 && Abc_ObjIsNode(pDriver)) )
+ continue;
+ // trasform this CO
+ if ( Abc_NodeIsInv(pNode) )
+ pDriver->pData = Cudd_Not(pDriver->pData);
+ Abc_ObjPatchFanin( pFanout, pNode, pDriver );
+ }
+ // perform cleanup
+ Abc_NtkCleanup( pNtk, 0 );
+ // report
+ if ( fVerbose )
+ printf( "Sweep removed %d nodes.\n", nNodesOld - Abc_NtkNodeNum(pNtk) );
+ return nNodesOld - Abc_NtkNodeNum(pNtk);
}
+
/**Function*************************************************************
Synopsis [Replaces the local function by its cofactor.]
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c
index 535789d2..8b7e015b 100644
--- a/src/base/io/ioReadBlif.c
+++ b/src/base/io/ioReadBlif.c
@@ -1057,7 +1057,7 @@ int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm
Abc_Obj_t * pBox;
int i;
// go through the boxes
- Abc_NtkForEachBox( pNtk, pBox, i )
+ Abc_NtkForEachBlackbox( pNtk, pBox, i )
if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) )
return 1;
Abc_NtkFinalizeRead( pNtk );