Commit c5c9e37a by Alan Mishchenko

Version abc60825

parent 735bca16
...@@ -787,7 +787,8 @@ extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk ); ...@@ -787,7 +787,8 @@ extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk ); extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanNext( Abc_Ntk_t * pNtk ); extern void Abc_NtkCleanNext( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanMarkA( 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 Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode );
extern bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ); extern bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk );
extern int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate ); extern int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate );
......
...@@ -744,6 +744,9 @@ void Abc_ConvertAigToBdd_rec2( DdManager * dd, Aig_Obj_t * pObj ) ...@@ -744,6 +744,9 @@ void Abc_ConvertAigToBdd_rec2( DdManager * dd, Aig_Obj_t * pObj )
DdNode * Abc_ConvertAigToBdd( DdManager * dd, Aig_Obj_t * pRoot ) DdNode * Abc_ConvertAigToBdd( DdManager * dd, Aig_Obj_t * pRoot )
{ {
DdNode * bFunc; 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 // construct BDD
Abc_ConvertAigToBdd_rec1( dd, Aig_Regular(pRoot) ); Abc_ConvertAigToBdd_rec1( dd, Aig_Regular(pRoot) );
// hold on to the result // hold on to the result
......
...@@ -112,12 +112,11 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) ...@@ -112,12 +112,11 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk ) int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk )
{ {
Abc_Obj_t * pNode; Abc_Obj_t * pNode;
int i, Counter, fChanged; int i, Counter;
assert( Abc_NtkIsBddLogic(pNtk) ); assert( Abc_NtkIsBddLogic(pNtk) );
Counter = 0; Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i ) Abc_NtkForEachNode( pNtk, pNode, i )
while ( fChanged = Abc_NodeRemoveDupFanins(pNode) ) Counter += Abc_NodeRemoveDupFanins( pNode );
Counter += fChanged;
return Counter; return Counter;
} }
...@@ -132,7 +131,7 @@ int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk ) ...@@ -132,7 +131,7 @@ int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode ) int Abc_NodeRemoveDupFanins_int( Abc_Obj_t * pNode )
{ {
Abc_Obj_t * pFanin1, * pFanin2; Abc_Obj_t * pFanin1, * pFanin2;
int i, k; int i, k;
...@@ -165,6 +164,24 @@ int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode ) ...@@ -165,6 +164,24 @@ int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode )
/**Function************************************************************* /**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.] Synopsis [Computes support of the node.]
Description [] Description []
......
...@@ -321,6 +321,9 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk ) ...@@ -321,6 +321,9 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj, * pNet, * pDriver, * pFanin; Abc_Obj_t * pObj, * pNet, * pDriver, * pFanin;
int i, k; int i, k;
// remove dangling nodes
Abc_NtkCleanup( pNtk, 0 );
assert( Abc_NtkIsLogic(pNtk) ); assert( Abc_NtkIsLogic(pNtk) );
assert( Abc_NtkLogicHasSimpleCos(pNtk) ); assert( Abc_NtkLogicHasSimpleCos(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) ) if ( Abc_NtkIsBddLogic(pNtk) )
...@@ -340,11 +343,7 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk ) ...@@ -340,11 +343,7 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
} }
// duplicate all nodes // duplicate all nodes
Abc_NtkForEachNode( pNtk, pObj, i ) Abc_NtkForEachNode( pNtk, pObj, i )
{
if ( Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 )
continue;
Abc_NtkDupObj(pNtkNew, pObj, 0); Abc_NtkDupObj(pNtkNew, pObj, 0);
}
// first add the nets to the CO drivers // first add the nets to the CO drivers
Abc_NtkForEachCo( pNtk, pObj, i ) Abc_NtkForEachCo( pNtk, pObj, i )
{ {
...@@ -367,13 +366,14 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk ) ...@@ -367,13 +366,14 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
pDriver->pCopy->pCopy = pNet; pDriver->pCopy->pCopy = pNet;
} }
else else
{
assert( !strcmp( Abc_ObjName(pDriver->pCopy->pCopy), Abc_ObjName(pObj) ) ); assert( !strcmp( Abc_ObjName(pDriver->pCopy->pCopy), Abc_ObjName(pObj) ) );
Abc_ObjAddFanin( pObj->pCopy, pDriver->pCopy->pCopy );
}
} }
// create the missing nets // create the missing nets
Abc_NtkForEachNode( pNtk, pObj, i ) 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 if ( pObj->pCopy->pCopy ) // the net of the new object is already created
continue; continue;
// create the new net // create the new net
......
...@@ -767,6 +767,12 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ) ...@@ -767,6 +767,12 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
Abc_Obj_t * pNet, * pNode; Abc_Obj_t * pNet, * pNode;
int i; int i;
if ( Abc_NtkNodeNum(pNtk) == 0 )
{
pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
return;
}
// check for non-driven nets // check for non-driven nets
vNets = Vec_PtrAlloc( 100 ); vNets = Vec_PtrAlloc( 100 );
Abc_NtkForEachNet( pNtk, pNet, i ) Abc_NtkForEachNet( pNtk, pNet, i )
...@@ -784,7 +790,7 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ) ...@@ -784,7 +790,7 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
// print the warning // print the warning
if ( vNets->nSize > 0 ) 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++ ) for ( i = 0; i < vNets->nSize; i++ )
{ {
if ( i == 0 ) if ( i == 0 )
......
...@@ -444,12 +444,10 @@ void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk ) ...@@ -444,12 +444,10 @@ void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Abc_Obj_t * Abc_NodeHasCoFanout( Abc_Obj_t * pNode ) Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode )
{ {
Abc_Obj_t * pFanout; Abc_Obj_t * pFanout;
int i; int i;
if ( !Abc_ObjIsNode(pNode) )
return NULL;
Abc_ObjForEachFanout( pNode, pFanout, i ) Abc_ObjForEachFanout( pNode, pFanout, i )
if ( Abc_ObjIsCo(pFanout) ) if ( Abc_ObjIsCo(pFanout) )
return pFanout; return pFanout;
...@@ -458,9 +456,30 @@ Abc_Obj_t * Abc_NodeHasCoFanout( Abc_Obj_t * pNode ) ...@@ -458,9 +456,30 @@ Abc_Obj_t * Abc_NodeHasCoFanout( Abc_Obj_t * pNode )
/**Function************************************************************* /**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.] 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 This is possible if all COs with non-complemented fanin edge pointing to this
node have the same name.] node have the same name.]
...@@ -473,8 +492,6 @@ Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode ) ...@@ -473,8 +492,6 @@ Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode )
{ {
Abc_Obj_t * pFanout, * pFanoutCo; Abc_Obj_t * pFanout, * pFanoutCo;
int i; int i;
if ( !Abc_ObjIsNode(pNode) )
return NULL;
pFanoutCo = NULL; pFanoutCo = NULL;
Abc_ObjForEachFanout( pNode, pFanout, i ) Abc_ObjForEachFanout( pNode, pFanout, i )
{ {
...@@ -497,13 +514,60 @@ Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode ) ...@@ -497,13 +514,60 @@ Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode )
/**Function************************************************************* /**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.] Synopsis [Returns 1 if COs of a logic network are simple.]
Description [The COs of a logic network are simple under three conditions: Description [The COs of a logic network are simple under three conditions:
(1) The edge from CO to its driver is not complemented. (1) The edge from CO to its driver is not complemented.
(2) No two COs share the same driver. (2) If CI is a driver of a CO, they have the same name.]
(3) The driver is not a CI unless the CI and the CO have the same name (2) If two COs share the same driver, they have the same name.]
(and so the inv/buf should not be written into a file).]
SideEffects [] SideEffects []
...@@ -514,19 +578,27 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ) ...@@ -514,19 +578,27 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
{ {
Abc_Obj_t * pNode, * pDriver; Abc_Obj_t * pNode, * pDriver;
int i; int i;
assert( !Abc_NtkIsNetlist(pNtk) ); assert( Abc_NtkIsLogic(pNtk) );
// check if there are complemented or idential POs
Abc_NtkIncrementTravId( pNtk ); Abc_NtkIncrementTravId( pNtk );
Abc_NtkForEachCo( pNtk, pNode, i ) Abc_NtkForEachCo( pNtk, pNode, i )
{ {
// if the driver is complemented, this is an error
pDriver = Abc_ObjFanin0(pNode); pDriver = Abc_ObjFanin0(pNode);
if ( Abc_ObjFaninC0(pNode) ) if ( Abc_ObjFaninC0(pNode) )
return 0; return 0;
if ( Abc_NodeIsTravIdCurrent(pDriver) ) // if the driver is a CI and has different name, this is an error
return 0; if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
if ( Abc_ObjIsCi(pDriver) && strcmp( Abc_ObjName(pDriver), Abc_ObjName(pNode) ) != 0 )
return 0; return 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); 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;
} }
return 1; return 1;
} }
...@@ -536,10 +608,9 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ) ...@@ -536,10 +608,9 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
Synopsis [Transforms the network to have simple COs.] Synopsis [Transforms the network to have simple COs.]
Description [The COs of a logic network are simple under three conditions: Description [The COs of a logic network are simple under three conditions:
(1) The edge from the CO to its driver is not complemented. (1) The edge from CO to its driver is not complemented.
(2) No two COs share the same driver (unless they have the same name!). (2) If CI is a driver of a CO, they have the same name.]
(3) The driver is not a CI unless the CI and the CO have the same name (2) If two COs share the same driver, they have the same name.
(and so the inv/buf should not be written into a file).
In some cases, such as FPGA mapping, we prevent the increase in delay In some cases, such as FPGA mapping, we prevent the increase in delay
by duplicating the driver nodes, rather than adding invs/bufs.] by duplicating the driver nodes, rather than adding invs/bufs.]
...@@ -550,58 +621,41 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ) ...@@ -550,58 +621,41 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
***********************************************************************/ ***********************************************************************/
int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate ) int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate )
{ {
Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin; Abc_Obj_t * pNode, * pDriver;
int i, k, nDupGates = 0; int i, nDupGates = 0;
assert( Abc_NtkIsLogic(pNtk) ); assert( Abc_NtkIsLogic(pNtk) );
// process the COs by adding inverters and buffers when necessary Abc_NtkIncrementTravId( pNtk );
Abc_NtkForEachCo( pNtk, pNode, i ) Abc_NtkForEachCo( pNtk, pNode, i )
{ {
// if the driver is complemented, this is an error
pDriver = Abc_ObjFanin0(pNode); 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) ); Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
nDupGates++;
continue; continue;
} }
} // if the driver is a CI and has different name, this is an error
else if ( !Abc_ObjFaninC0(pNode) ) 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 Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
if ( Abc_NodeHasUniqueCoFanout(pDriver) ) nDupGates++;
continue; 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 pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
Abc_NodeComplement( pDriverNew ); Abc_NodeSetTravIdCurrent(pDriver);
Abc_ObjXorFaninC( pNode, 0 ); 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_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
Abc_ObjXorFaninC( pNode, 0 );
}
else
pDriverNew = Abc_NodeCreateBuf( pNtk, pDriver );
}
// update the fanin of the PO node
Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
assert( Abc_ObjFanoutNum(pDriverNew) == 1 );
nDupGates++; nDupGates++;
// remove the old driver if it dangles continue;
if ( Abc_ObjFanoutNum(pDriver) == 0 ) }
Abc_NtkDeleteObj( pDriver );
} }
assert( Abc_NtkLogicHasSimpleCos(pNtk) ); assert( Abc_NtkLogicHasSimpleCos(pNtk) );
return nDupGates; return nDupGates;
......
...@@ -2175,9 +2175,9 @@ int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -2175,9 +2175,9 @@ int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Empty network.\n" ); fprintf( pErr, "Empty network.\n" );
return 1; 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; return 1;
} }
// modify the current network // modify the current network
...@@ -3401,7 +3401,7 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -3401,7 +3401,7 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv )
} }
if ( !Abc_NtkLogicToSop(pNtk, fDirect) ) if ( !Abc_NtkLogicToSop(pNtk, fDirect) )
{ {
fprintf( pErr, "Converting to BDD has failed.\n" ); fprintf( pErr, "Converting to SOP has failed.\n" );
return 1; return 1;
} }
return 0; return 0;
......
...@@ -593,7 +593,7 @@ int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter ) ...@@ -593,7 +593,7 @@ int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter )
Abc_NtkForEachPo( pMiter, pNodePo, i ) Abc_NtkForEachPo( pMiter, pNodePo, i )
{ {
pChild = Abc_ObjChild0( pNodePo ); pChild = Abc_ObjChild0( pNodePo );
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) ) if ( Abc_AigNodeIsConst(pChild) )
{ {
assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter) ); assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter) );
if ( !Abc_ObjIsComplement(pChild) ) if ( !Abc_ObjIsComplement(pChild) )
...@@ -629,7 +629,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ) ...@@ -629,7 +629,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
if ( Abc_NtkPoNum(pMiter) == 1 ) if ( Abc_NtkPoNum(pMiter) == 1 )
{ {
pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) ); pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) );
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) ) if ( Abc_AigNodeIsConst(pChild) )
{ {
if ( Abc_ObjIsComplement(pChild) ) if ( Abc_ObjIsComplement(pChild) )
printf( "Unsatisfiable.\n" ); printf( "Unsatisfiable.\n" );
...@@ -645,7 +645,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ) ...@@ -645,7 +645,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
{ {
pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) ); pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) );
printf( "Output #%2d : ", i ); printf( "Output #%2d : ", i );
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) ) if ( Abc_AigNodeIsConst(pChild) )
{ {
if ( Abc_ObjIsComplement(pChild) ) if ( Abc_ObjIsComplement(pChild) )
printf( "Unsatisfiable.\n" ); printf( "Unsatisfiable.\n" );
......
...@@ -197,7 +197,7 @@ stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose ) ...@@ -197,7 +197,7 @@ stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose )
if ( pNodeAig == NULL ) if ( pNodeAig == NULL )
continue; continue;
// skip the nodes that fanout into COs // skip the nodes that fanout into COs
if ( Abc_NodeHasCoFanout(pNode) ) if ( Abc_NodeFindCoFanout(pNode) )
continue; continue;
// get the FRAIG node // get the FRAIG node
gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) ); 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 ) ...@@ -495,12 +495,8 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
int i, Counter; int i, Counter;
assert( Abc_NtkIsLogic(pNtk) ); assert( Abc_NtkIsLogic(pNtk) );
// mark the nodes reachable from the POs // mark the nodes reachable from the POs
for ( i = 0; i < vNodes->nSize; i++ ) Vec_PtrForEachEntry( vNodes, pNode, i )
{
pNode = vNodes->pArray[i];
assert( Abc_ObjIsNode(pNode) );
pNode->fMarkA = 1; pNode->fMarkA = 1;
}
// remove the non-marked nodes // remove the non-marked nodes
Counter = 0; Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i ) Abc_NtkForEachNode( pNtk, pNode, i )
...@@ -510,7 +506,7 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes ) ...@@ -510,7 +506,7 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
Counter++; Counter++;
} }
// unmark the remaining nodes // unmark the remaining nodes
Abc_NtkForEachNode( pNtk, pNode, i ) Vec_PtrForEachEntry( vNodes, pNode, i )
pNode->fMarkA = 0; pNode->fMarkA = 0;
// check // check
if ( !Abc_NtkCheck( pNtk ) ) if ( !Abc_NtkCheck( pNtk ) )
...@@ -534,86 +530,40 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes ) ...@@ -534,86 +530,40 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
***********************************************************************/ ***********************************************************************/
int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose ) int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
{ {
Abc_Obj_t * pNode; Vec_Ptr_t * vNodes;
int i, fConvert, nSwept, nSweptNew; Abc_Obj_t * pNode, * pFanout, * pDriver;
assert( Abc_NtkIsSopLogic(pNtk) || Abc_NtkIsBddLogic(pNtk) ); int i, nNodesOld;
// convert to the BDD representation assert( Abc_NtkIsLogic(pNtk) );
fConvert = 0; // convert network to BDD representation
if ( Abc_NtkIsSopLogic(pNtk) ) if ( !Abc_NtkLogicToBdd(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 fprintf( stdout, "Converting to BDD has failed.\n" );
Abc_NtkForEachNode( pNtk, pNode, i ) return 1;
if ( i && Abc_ObjFaninNum(pNode) < 2 ) }
Abc_NodeSweep( pNode, fVerbose ); // perform cleanup
// make the network minimum base nNodesOld = Abc_NtkNodeNum(pNtk);
Abc_NtkCleanup( pNtk, 0 );
// prepare nodes for sweeping
Abc_NtkRemoveDupFanins(pNtk); Abc_NtkRemoveDupFanins(pNtk);
Abc_NtkMinimumBase(pNtk); Abc_NtkMinimumBase(pNtk);
// perform final clean up (in case new danglies are created) // collect sweepable nodes
nSweptNew = Abc_NtkCleanup( pNtk, 0 ); vNodes = Vec_PtrAlloc( 100 );
nSwept += nSweptNew; Abc_NtkForEachNode( pNtk, pNode, i )
} if ( Abc_ObjFaninNum(pNode) < 2 )
while ( nSweptNew ); Vec_PtrPush( vNodes, pNode );
// conver back to BDD // sweep the nodes
if ( fConvert ) while ( Vec_PtrSize(vNodes) > 0 )
Abc_NtkBddToSop(pNtk, 0);
// report
if ( fVerbose )
printf( "Sweep removed %d nodes.\n", nSwept );
// check
if ( !Abc_NtkCheck( pNtk ) )
{
printf( "Abc_NtkSweep: The network check 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 )
{
if ( Abc_ObjIsCo(pFanout) )
{
if ( Abc_ObjFaninNum(pNode) == 1 )
{ {
pDriver = Abc_ObjFanin0(pNode); // get any sweepable node
if ( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 1 || Abc_ObjFanoutNum(pNode) > 1 ) pNode = Vec_PtrPop(vNodes);
if ( !Abc_ObjIsNode(pNode) )
continue; continue;
// the driver is a node and its only fanout is this node // get any non-CO fanout of this node
if ( Abc_NodeIsInv(pNode) ) pFanout = Abc_NodeFindNonCoFanout(pNode);
pDriver->pData = Cudd_Not(pDriver->pData); if ( pFanout == NULL )
// replace the fanin of the fanout
Abc_ObjPatchFanin( pFanout, pNode, pDriver );
}
continue; continue;
} assert( Abc_ObjIsNode(pFanout) );
// the fanout is a regular node // transform the function of the fanout
if ( Abc_ObjFaninNum(pNode) == 0 ) if ( Abc_ObjFaninNum(pNode) == 0 )
Abc_NodeConstantInput( pFanout, pNode, Abc_NodeIsConst0(pNode) ); Abc_NodeConstantInput( pFanout, pNode, Abc_NodeIsConst0(pNode) );
else else
...@@ -624,10 +574,44 @@ void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose ) ...@@ -624,10 +574,44 @@ void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose )
Abc_NodeComplementInput( pFanout, pNode ); Abc_NodeComplementInput( pFanout, pNode );
Abc_ObjPatchFanin( pFanout, pNode, pDriver ); 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************************************************************* /**Function*************************************************************
Synopsis [Replaces the local function by its cofactor.] Synopsis [Replaces the local function by its cofactor.]
......
...@@ -1057,7 +1057,7 @@ int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm ...@@ -1057,7 +1057,7 @@ int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm
Abc_Obj_t * pBox; Abc_Obj_t * pBox;
int i; int i;
// go through the boxes // go through the boxes
Abc_NtkForEachBox( pNtk, pBox, i ) Abc_NtkForEachBlackbox( pNtk, pBox, i )
if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) ) if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) )
return 1; return 1;
Abc_NtkFinalizeRead( pNtk ); Abc_NtkFinalizeRead( pNtk );
......
...@@ -137,7 +137,7 @@ static inline int Aig_ManObjNum( Aig_Man_t * p ) { return p->nC ...@@ -137,7 +137,7 @@ static inline int Aig_ManObjNum( Aig_Man_t * p ) { return p->nC
static inline Aig_Type_t Aig_ObjType( Aig_Obj_t * pObj ) { return pObj->Type; } static inline Aig_Type_t Aig_ObjType( Aig_Obj_t * pObj ) { return pObj->Type; }
static inline int Aig_ObjIsNone( Aig_Obj_t * pObj ) { return pObj->Type == AIG_NONE; } static inline int Aig_ObjIsNone( Aig_Obj_t * pObj ) { return pObj->Type == AIG_NONE; }
static inline int Aig_ObjIsConst1( Aig_Obj_t * pObj ) { return pObj->Type == AIG_CONST1; } static inline int Aig_ObjIsConst1( Aig_Obj_t * pObj ) { assert(!Aig_IsComplement(pObj)); return pObj->Type == AIG_CONST1; }
static inline int Aig_ObjIsPi( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PI; } static inline int Aig_ObjIsPi( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PI; }
static inline int Aig_ObjIsPo( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PO; } static inline int Aig_ObjIsPo( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PO; }
static inline int Aig_ObjIsAnd( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND; } static inline int Aig_ObjIsAnd( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND; }
......
...@@ -325,9 +325,12 @@ Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pRoo ...@@ -325,9 +325,12 @@ Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pRoo
if ( Aig_ObjIsConst1( Aig_Regular(pRoot) ) ) if ( Aig_ObjIsConst1( Aig_Regular(pRoot) ) )
return Aig_NotCond( Aig_ManConst1(pDest), Aig_IsComplement(pRoot) ); return Aig_NotCond( Aig_ManConst1(pDest), Aig_IsComplement(pRoot) );
// set the PI mapping // set the PI mapping
Aig_ManForEachPi( pDest, pObj, i ) Aig_ManForEachPi( pSour, pObj, i )
if ( i < nVars ) {
Aig_IthVar(pSour, i)->pData = Aig_IthVar(pDest, i); if ( i == nVars )
break;
pObj->pData = Aig_IthVar(pDest, i);
}
// transfer and set markings // transfer and set markings
Aig_Transfer_rec( pDest, Aig_Regular(pRoot) ); Aig_Transfer_rec( pDest, Aig_Regular(pRoot) );
// clear the markings // clear the markings
......
...@@ -56,6 +56,7 @@ Aig_Man_t * Aig_ManStart() ...@@ -56,6 +56,7 @@ Aig_Man_t * Aig_ManStart()
Aig_ManStartMemory( p ); Aig_ManStartMemory( p );
// create the constant node // create the constant node
p->pConst1 = Aig_ManFetchMemory( p ); p->pConst1 = Aig_ManFetchMemory( p );
p->pConst1->Type = AIG_CONST1;
p->pConst1->fPhase = 1; p->pConst1->fPhase = 1;
p->nCreated = 1; p->nCreated = 1;
// start the table // start the table
......
...@@ -183,6 +183,7 @@ Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ) ...@@ -183,6 +183,7 @@ Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 )
***********************************************************************/ ***********************************************************************/
Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 ) Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 )
{ {
/*
Aig_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp; Aig_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp;
int Count0, Count1; int Count0, Count1;
// consider trivial cases // consider trivial cases
...@@ -190,6 +191,9 @@ Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * ...@@ -190,6 +191,9 @@ Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t *
return Aig_Exor( p, pC, p0 ); return Aig_Exor( p, pC, p0 );
// other cases can be added // other cases can be added
// implement the first MUX (F = C * x1 + C' * x0) // implement the first MUX (F = C * x1 + C' * x0)
// check for constants here!!!
pTempA1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, p1, AIG_AND) ); pTempA1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, p1, AIG_AND) );
pTempA2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), p0, AIG_AND) ); pTempA2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), p0, AIG_AND) );
if ( pTempA1 && pTempA2 ) if ( pTempA1 && pTempA2 )
...@@ -217,8 +221,8 @@ Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * ...@@ -217,8 +221,8 @@ Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t *
pTempB1 = pTempB1? pTempB1 : Aig_And(p, pC, Aig_Not(p1)); pTempB1 = pTempB1? pTempB1 : Aig_And(p, pC, Aig_Not(p1));
pTempB2 = pTempB2? pTempB2 : Aig_And(p, Aig_Not(pC), Aig_Not(p0)); pTempB2 = pTempB2? pTempB2 : Aig_And(p, Aig_Not(pC), Aig_Not(p0));
return Aig_Not( Aig_Or( p, pTempB1, pTempB2 ) ); return Aig_Not( Aig_Or( p, pTempB1, pTempB2 ) );
*/
// return Aig_Or( Aig_And(pC, p1), Aig_And(Aig_Not(pC), p0) ); return Aig_Or( p, Aig_And(p, pC, p1), Aig_And(p, Aig_Not(pC), p0) );
} }
/**Function************************************************************* /**Function*************************************************************
......
...@@ -34,6 +34,18 @@ typedef enum { ...@@ -34,6 +34,18 @@ typedef enum {
VER_SIG_WIRE VER_SIG_WIRE
} Ver_SignalType_t; } Ver_SignalType_t;
// types of verilog gates
typedef enum {
VER_GATE_AND = 0,
VER_GATE_OR,
VER_GATE_XOR,
VER_GATE_BUF,
VER_GATE_NAND,
VER_GATE_NOR,
VER_GATE_XNOR,
VER_GATE_NOT
} Ver_GateType_t;
static Ver_Man_t * Ver_ParseStart( char * pFileName, Abc_Lib_t * pGateLib ); static Ver_Man_t * Ver_ParseStart( char * pFileName, Abc_Lib_t * pGateLib );
static void Ver_ParseStop( Ver_Man_t * p ); static void Ver_ParseStop( Ver_Man_t * p );
static void Ver_ParseFreeData( Ver_Man_t * p ); static void Ver_ParseFreeData( Ver_Man_t * p );
...@@ -44,6 +56,7 @@ static int Ver_ParseAssign( Ver_Man_t * p ); ...@@ -44,6 +56,7 @@ static int Ver_ParseAssign( Ver_Man_t * p );
static int Ver_ParseAlways( Ver_Man_t * p ); static int Ver_ParseAlways( Ver_Man_t * p );
static int Ver_ParseInitial( Ver_Man_t * p ); static int Ver_ParseInitial( Ver_Man_t * p );
static int Ver_ParseGate( Ver_Man_t * p, Abc_Ntk_t * pNtkGate ); static int Ver_ParseGate( Ver_Man_t * p, Abc_Ntk_t * pNtkGate );
static int Ver_ParseGateStandard( Ver_Man_t * pMan, Ver_GateType_t GateType );
static Abc_Obj_t * Ver_ParseCreatePi( Abc_Ntk_t * pNtk, char * pName ); static Abc_Obj_t * Ver_ParseCreatePi( Abc_Ntk_t * pNtk, char * pName );
static Abc_Obj_t * Ver_ParseCreatePo( Abc_Ntk_t * pNtk, char * pName ); static Abc_Obj_t * Ver_ParseCreatePo( Abc_Ntk_t * pNtk, char * pName );
...@@ -201,6 +214,7 @@ void Ver_ParseFreeData( Ver_Man_t * p ) ...@@ -201,6 +214,7 @@ void Ver_ParseFreeData( Ver_Man_t * p )
{ {
if ( p->pNtkCur ) if ( p->pNtkCur )
{ {
p->pNtkCur->pManFunc = NULL;
Abc_NtkDelete( p->pNtkCur ); Abc_NtkDelete( p->pNtkCur );
p->pNtkCur = NULL; p->pNtkCur = NULL;
} }
...@@ -324,7 +338,25 @@ int Ver_ParseModule( Ver_Man_t * pMan ) ...@@ -324,7 +338,25 @@ int Ver_ParseModule( Ver_Man_t * pMan )
while ( 1 ) while ( 1 )
{ {
Extra_ProgressBarUpdate( pMan->pProgress, Ver_StreamGetCurPosition(p), NULL ); Extra_ProgressBarUpdate( pMan->pProgress, Ver_StreamGetCurPosition(p), NULL );
if ( !strcmp( pWord, "assign" ) )
if ( !strcmp( pWord, "and" ) )
RetValue = Ver_ParseGateStandard( pMan, VER_GATE_AND );
else if ( !strcmp( pWord, "or" ) )
RetValue = Ver_ParseGateStandard( pMan, VER_GATE_OR );
else if ( !strcmp( pWord, "xor" ) )
RetValue = Ver_ParseGateStandard( pMan, VER_GATE_XOR );
else if ( !strcmp( pWord, "buf" ) )
RetValue = Ver_ParseGateStandard( pMan, VER_GATE_BUF );
else if ( !strcmp( pWord, "nand" ) )
RetValue = Ver_ParseGateStandard( pMan, VER_GATE_NAND );
else if ( !strcmp( pWord, "nor" ) )
RetValue = Ver_ParseGateStandard( pMan, VER_GATE_NOR );
else if ( !strcmp( pWord, "xnor" ) )
RetValue = Ver_ParseGateStandard( pMan, VER_GATE_XNOR );
else if ( !strcmp( pWord, "not" ) )
RetValue = Ver_ParseGateStandard( pMan, VER_GATE_NOT );
else if ( !strcmp( pWord, "assign" ) )
RetValue = Ver_ParseAssign( pMan ); RetValue = Ver_ParseAssign( pMan );
else if ( !strcmp( pWord, "always" ) ) else if ( !strcmp( pWord, "always" ) )
RetValue = Ver_ParseAlways( pMan ); RetValue = Ver_ParseAlways( pMan );
...@@ -348,6 +380,9 @@ int Ver_ParseModule( Ver_Man_t * pMan ) ...@@ -348,6 +380,9 @@ int Ver_ParseModule( Ver_Man_t * pMan )
} }
if ( RetValue == 0 ) if ( RetValue == 0 )
return 0; return 0;
// skip the comments
if ( !Ver_ParseSkipComments( pMan ) )
return 0;
// get new word // get new word
pWord = Ver_ParseGetName( pMan ); pWord = Ver_ParseGetName( pMan );
if ( pWord == NULL ) if ( pWord == NULL )
...@@ -469,14 +504,6 @@ int Ver_ParseAssign( Ver_Man_t * pMan ) ...@@ -469,14 +504,6 @@ int Ver_ParseAssign( Ver_Man_t * pMan )
Ver_ParsePrintErrorMessage( pMan ); Ver_ParsePrintErrorMessage( pMan );
return 0; return 0;
} }
// get the fanout net
pNet = Abc_NtkFindNet( pNtk, pWord );
if ( pNet == NULL )
{
sprintf( pMan->sError, "Cannot read the assign statement for %s (output wire is not defined).", pWord );
Ver_ParsePrintErrorMessage( pMan );
return 0;
}
// get the equal sign // get the equal sign
if ( Ver_StreamPopChar(p) != '=' ) if ( Ver_StreamPopChar(p) != '=' )
{ {
...@@ -893,6 +920,97 @@ int Ver_ParseGate( Ver_Man_t * pMan, Abc_Ntk_t * pNtkGate ) ...@@ -893,6 +920,97 @@ int Ver_ParseGate( Ver_Man_t * pMan, Abc_Ntk_t * pNtkGate )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Parses one directive.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ver_ParseGateStandard( Ver_Man_t * pMan, Ver_GateType_t GateType )
{
Ver_Stream_t * p = pMan->pReader;
Aig_Man_t * pAig = pMan->pNtkCur->pManFunc;
Abc_Obj_t * pNet, * pNode;
char * pWord, Symbol;
// this is gate name - throw it away
if ( Ver_StreamPopChar(p) != '(' )
{
sprintf( pMan->sError, "Cannot parse a standard gate (expected opening paranthesis)." );
Ver_ParsePrintErrorMessage( pMan );
return 0;
}
Ver_ParseSkipComments( pMan );
// create the node
pNode = Abc_NtkCreateNode( pMan->pNtkCur );
// parse pairs of formal/actural inputs
while ( 1 )
{
// parse the output name
pWord = Ver_ParseGetName( pMan );
if ( pWord == NULL )
return 0;
// get the net corresponding to this output
pNet = Abc_NtkFindNet( pMan->pNtkCur, pWord );
if ( pNet == NULL )
{
sprintf( pMan->sError, "Net is missing in gate %s.", pWord );
Ver_ParsePrintErrorMessage( pMan );
return 0;
}
// if this is the first net, add it as an output
if ( Abc_ObjFanoutNum(pNode) == 0 )
Abc_ObjAddFanin( pNet, pNode );
else
Abc_ObjAddFanin( pNode, pNet );
// check if it is the end of gate
Ver_ParseSkipComments( pMan );
Symbol = Ver_StreamPopChar(p);
if ( Symbol == ')' )
break;
// skip comma
if ( Symbol != ',' )
{
sprintf( pMan->sError, "Cannot parse a standard gate %s (expected closing paranthesis).", Abc_ObjName(Abc_ObjFanout0(pNode)) );
Ver_ParsePrintErrorMessage( pMan );
return 0;
}
Ver_ParseSkipComments( pMan );
}
if ( (GateType == VER_GATE_BUF || GateType == VER_GATE_NOT) && Abc_ObjFaninNum(pNode) != 1 )
{
sprintf( pMan->sError, "Buffer or interver with multiple fanouts %s (currently not supported).", Abc_ObjName(Abc_ObjFanout0(pNode)) );
Ver_ParsePrintErrorMessage( pMan );
return 0;
}
// check if it is the end of gate
Ver_ParseSkipComments( pMan );
if ( Ver_StreamPopChar(p) != ';' )
{
sprintf( pMan->sError, "Cannot read standard gate %s (expected closing semicolumn).", Abc_ObjName(Abc_ObjFanout0(pNode)) );
Ver_ParsePrintErrorMessage( pMan );
return 0;
}
// add logic function
if ( GateType == VER_GATE_AND || GateType == VER_GATE_NAND )
pNode->pData = Aig_CreateAnd( pAig, Abc_ObjFaninNum(pNode) );
else if ( GateType == VER_GATE_OR || GateType == VER_GATE_NOR )
pNode->pData = Aig_CreateOr( pAig, Abc_ObjFaninNum(pNode) );
else if ( GateType == VER_GATE_XOR || GateType == VER_GATE_XNOR )
pNode->pData = Aig_CreateExor( pAig, Abc_ObjFaninNum(pNode) );
else if ( GateType == VER_GATE_BUF || GateType == VER_GATE_NOT )
pNode->pData = Aig_CreateAnd( pAig, Abc_ObjFaninNum(pNode) );
if ( GateType == VER_GATE_NAND || GateType == VER_GATE_NOR || GateType == VER_GATE_XNOR || GateType == VER_GATE_NOT )
pNode->pData = Aig_Not( pNode->pData );
return 1;
}
/**Function*************************************************************
Synopsis [Creates PI terminal and net.] Synopsis [Creates PI terminal and net.]
Description [] Description []
......
...@@ -392,7 +392,7 @@ int Ver_FormulaParserFindVar( char * pString, Vec_Ptr_t * vNames ) ...@@ -392,7 +392,7 @@ int Ver_FormulaParserFindVar( char * pString, Vec_Ptr_t * vNames )
if ( nLength2 != nLength ) if ( nLength2 != nLength )
continue; continue;
pTemp2 = Vec_PtrEntry( vNames, 2*i + 1 ); pTemp2 = Vec_PtrEntry( vNames, 2*i + 1 );
if ( strncmp( pTemp, pTemp2, nLength ) ) if ( strncmp( pString, pTemp2, nLength ) )
continue; continue;
return i; return i;
} }
......
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