abc/src/base/abci/abcFraig.c

817 lines
28 KiB
C
Raw Normal View History

2005-07-29 17:01:00 +02:00
/**CFile****************************************************************
FileName [abcFraig.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Procedures interfacing with the FRAIG package.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcFraig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "base/abc/abc.h"
#include "proof/fraig/fraig.h"
#include "base/main/main.h"
2005-07-29 17:01:00 +02:00
2010-11-01 09:35:04 +01:00
ABC_NAMESPACE_IMPL_START
2005-07-29 17:01:00 +02:00
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
2008-01-31 05:01:00 +01:00
extern Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
static Abc_Ntk_t * Abc_NtkFromFraig2( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
static Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig );
static void Abc_NtkFromFraig2_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, Vec_Ptr_t * vNodeReprs );
extern Fraig_Node_t * Abc_NtkToFraigExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtkMain, Abc_Ntk_t * pNtkExdc );
static void Abc_NtkFraigRemapUsingExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
static int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk );
static void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
2005-07-29 17:01:00 +02:00
////////////////////////////////////////////////////////////////////////
2008-01-31 05:01:00 +01:00
/// FUNCTION DEFINITIONS ///
2005-07-29 17:01:00 +02:00
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Interfaces the network with the FRAIG package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2008-01-31 05:01:00 +01:00
Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExdc )
2005-07-29 17:01:00 +02:00
{
2010-11-01 09:35:04 +01:00
Fraig_Params_t * pPars = (Fraig_Params_t *)pParams;
2005-07-29 17:01:00 +02:00
Abc_Ntk_t * pNtkNew;
2008-01-31 05:01:00 +01:00
Fraig_Man_t * pMan;
// check if EXDC is present
if ( fExdc && pNtk->pExdc == NULL )
fExdc = 0, printf( "Warning: Networks has no EXDC.\n" );
2005-07-29 17:01:00 +02:00
// perform fraiging
2010-11-01 09:35:04 +01:00
pMan = (Fraig_Man_t *)Abc_NtkToFraig( pNtk, pParams, fAllNodes, fExdc );
2008-01-31 05:01:00 +01:00
// add algebraic choices
// if ( pPars->fChoicing )
// Fraig_ManAddChoices( pMan, 0, 6 );
2005-07-29 17:01:00 +02:00
// prove the miter if asked to
2005-09-04 17:01:00 +02:00
if ( pPars->fTryProve )
2005-07-29 17:01:00 +02:00
Fraig_ManProveMiter( pMan );
// reconstruct FRAIG in the new network
2008-01-31 05:01:00 +01:00
if ( fExdc )
pNtkNew = Abc_NtkFromFraig2( pMan, pNtk );
else
pNtkNew = Abc_NtkFromFraig( pMan, pNtk );
2005-07-29 17:01:00 +02:00
Fraig_ManFree( pMan );
2008-01-31 05:01:00 +01:00
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
2005-07-29 17:01:00 +02:00
// make sure that everything is okay
2005-09-05 17:01:00 +02:00
if ( !Abc_NtkCheck( pNtkNew ) )
2005-07-29 17:01:00 +02:00
{
printf( "Abc_NtkFraig: The network check has failed.\n" );
Abc_NtkDelete( pNtkNew );
return NULL;
}
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Transforms the strashed network into FRAIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2008-01-31 05:01:00 +01:00
void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExdc )
2005-07-29 17:01:00 +02:00
{
2008-01-31 05:01:00 +01:00
int fInternal = ((Fraig_Params_t *)pParams)->fInternal;
2005-07-29 17:01:00 +02:00
Fraig_Man_t * pMan;
2008-07-02 17:01:00 +02:00
ProgressBar * pProgress = NULL;
2005-07-29 17:01:00 +02:00
Vec_Ptr_t * vNodes;
2008-01-31 05:01:00 +01:00
Abc_Obj_t * pNode;
2005-07-29 17:01:00 +02:00
int i;
2005-08-29 17:01:00 +02:00
assert( Abc_NtkIsStrash(pNtk) );
2005-07-29 17:01:00 +02:00
// create the FRAIG manager
2010-11-01 09:35:04 +01:00
pMan = Fraig_ManCreate( (Fraig_Params_t *)pParams );
2005-07-29 17:01:00 +02:00
2008-01-31 05:01:00 +01:00
// map the constant node
2008-01-30 17:01:00 +01:00
Abc_NtkCleanCopy( pNtk );
2008-01-31 05:01:00 +01:00
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
// create PIs and remember them in the old nodes
2005-07-29 17:01:00 +02:00
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i);
2008-01-31 05:01:00 +01:00
2005-07-29 17:01:00 +02:00
// perform strashing
2005-08-22 17:01:00 +02:00
vNodes = Abc_AigDfs( pNtk, fAllNodes, 0 );
2008-01-31 05:01:00 +01:00
if ( !fInternal )
2005-09-04 17:01:00 +02:00
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
2005-07-29 17:01:00 +02:00
{
2008-01-31 05:01:00 +01:00
if ( Abc_ObjFaninNum(pNode) == 0 )
2008-01-30 17:01:00 +01:00
continue;
2010-11-01 09:35:04 +01:00
if ( pProgress )
2008-01-31 05:01:00 +01:00
Extra_ProgressBarUpdate( pProgress, i, NULL );
pNode->pCopy = (Abc_Obj_t *)Fraig_NodeAnd( pMan,
2010-11-01 09:35:04 +01:00
Fraig_NotCond( Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) ),
Fraig_NotCond( Abc_ObjFanin1(pNode)->pCopy, (int)Abc_ObjFaninC1(pNode) ) );
2005-07-29 17:01:00 +02:00
}
2010-11-01 09:35:04 +01:00
if ( pProgress )
2005-09-04 17:01:00 +02:00
Extra_ProgressBarStop( pProgress );
2005-07-29 17:01:00 +02:00
Vec_PtrFree( vNodes );
2008-01-31 05:01:00 +01:00
// use EXDC to change the mapping of nodes into FRAIG nodes
if ( fExdc )
Abc_NtkFraigRemapUsingExdc( pMan, pNtk );
2005-07-29 17:01:00 +02:00
// set the primary outputs
Abc_NtkForEachCo( pNtk, pNode, i )
2005-09-04 17:01:00 +02:00
Fraig_ManSetPo( pMan, (Fraig_Node_t *)Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ) );
2005-07-29 17:01:00 +02:00
return pMan;
}
/**Function*************************************************************
2008-01-31 05:01:00 +01:00
Synopsis [Derives EXDC node for the given network.]
Description [Assumes that EXDCs of all POs are the same.
Returns the EXDC of the first PO.]
SideEffects []
SeeAlso []
***********************************************************************/
Fraig_Node_t * Abc_NtkToFraigExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtkMain, Abc_Ntk_t * pNtkExdc )
{
Abc_Ntk_t * pNtkStrash;
Abc_Obj_t * pObj;
Fraig_Node_t * gResult;
char ** ppNames;
int i, k;
// strash the EXDC network
pNtkStrash = Abc_NtkStrash( pNtkExdc, 0, 0, 0 );
Abc_NtkCleanCopy( pNtkStrash );
Abc_AigConst1(pNtkStrash)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
// set the mapping of the PI nodes
ppNames = Abc_NtkCollectCioNames( pNtkMain, 0 );
Abc_NtkForEachCi( pNtkStrash, pObj, i )
{
for ( k = 0; k < Abc_NtkCiNum(pNtkMain); k++ )
if ( strcmp( Abc_ObjName(pObj), ppNames[k] ) == 0 )
{
pObj->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, k);
break;
}
assert( pObj->pCopy != NULL );
}
2009-02-15 17:01:00 +01:00
ABC_FREE( ppNames );
2008-01-31 05:01:00 +01:00
// build FRAIG for each node
Abc_AigForEachAnd( pNtkStrash, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Fraig_NodeAnd( pMan,
2010-11-01 09:35:04 +01:00
Fraig_NotCond( Abc_ObjFanin0(pObj)->pCopy, (int)Abc_ObjFaninC0(pObj) ),
Fraig_NotCond( Abc_ObjFanin1(pObj)->pCopy, (int)Abc_ObjFaninC1(pObj) ) );
2008-01-31 05:01:00 +01:00
// get the EXDC to be returned
pObj = Abc_NtkPo( pNtkStrash, 0 );
2010-11-01 09:35:04 +01:00
gResult = Fraig_NotCond( Abc_ObjFanin0(pObj)->pCopy, (int)Abc_ObjFaninC0(pObj) );
2008-01-31 05:01:00 +01:00
Abc_NtkDelete( pNtkStrash );
return gResult;
}
/**Function*************************************************************
Synopsis [Changes mapping of the old nodes into FRAIG nodes using EXDC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFraigRemapUsingExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
{
Fraig_Node_t * gNodeNew, * gNodeExdc;
stmm_table * tTable;
stmm_generator * gen;
Abc_Obj_t * pNode, * pNodeBest;
Abc_Obj_t * pClass, ** ppSlot;
Vec_Ptr_t * vNexts;
int i;
// get the global don't-cares
assert( pNtk->pExdc );
gNodeExdc = Abc_NtkToFraigExdc( pMan, pNtk, pNtk->pExdc );
// save the next pointers
vNexts = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
Vec_PtrWriteEntry( vNexts, pNode->Id, pNode->pNext );
// find the classes of AIG nodes which have FRAIG nodes assigned
Abc_NtkCleanNext( pNtk );
tTable = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
Abc_NtkForEachNode( pNtk, pNode, i )
if ( pNode->pCopy )
{
gNodeNew = Fraig_NodeAnd( pMan, (Fraig_Node_t *)pNode->pCopy, Fraig_Not(gNodeExdc) );
if ( !stmm_find_or_add( tTable, (char *)Fraig_Regular(gNodeNew), (char ***)&ppSlot ) )
*ppSlot = NULL;
pNode->pNext = *ppSlot;
*ppSlot = pNode;
}
// for reach non-trival class, find the node with minimum level, and replace other nodes by it
Abc_AigSetNodePhases( pNtk );
stmm_foreach_item( tTable, gen, (char **)&gNodeNew, (char **)&pClass )
{
if ( pClass->pNext == NULL )
continue;
// find the node with minimum level
pNodeBest = pClass;
for ( pNode = pClass->pNext; pNode; pNode = pNode->pNext )
if ( pNodeBest->Level > pNode->Level )
pNodeBest = pNode;
// remap the class nodes
for ( pNode = pClass; pNode; pNode = pNode->pNext )
pNode->pCopy = Abc_ObjNotCond( pNodeBest->pCopy, pNode->fPhase ^ pNodeBest->fPhase );
}
stmm_free_table( tTable );
// restore the next pointers
Abc_NtkCleanNext( pNtk );
Abc_NtkForEachNode( pNtk, pNode, i )
2010-11-01 09:35:04 +01:00
pNode->pNext = (Abc_Obj_t *)Vec_PtrEntry( vNexts, pNode->Id );
2008-01-31 05:01:00 +01:00
Vec_PtrFree( vNexts );
}
/**Function*************************************************************
Synopsis [Transforms FRAIG into strashed network with choices.]
2005-07-29 17:01:00 +02:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
{
2008-01-31 05:01:00 +01:00
ProgressBar * pProgress;
2005-07-29 17:01:00 +02:00
Abc_Ntk_t * pNtkNew;
2005-09-04 17:01:00 +02:00
Abc_Obj_t * pNode, * pNodeNew;
2005-07-29 17:01:00 +02:00
int i;
// create the new network
2008-01-31 05:01:00 +01:00
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
2005-07-29 17:01:00 +02:00
// make the mapper point to the new network
Abc_NtkForEachCi( pNtk, pNode, i )
Fraig_NodeSetData1( Fraig_ManReadIthVar(pMan, i), (Fraig_Node_t *)pNode->pCopy );
// set the constant node
2008-01-31 05:01:00 +01:00
Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_AigConst1(pNtkNew) );
2005-07-29 17:01:00 +02:00
// process the nodes in topological order
2008-01-31 05:01:00 +01:00
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
2005-07-29 17:01:00 +02:00
Abc_NtkForEachCo( pNtk, pNode, i )
{
2008-01-31 05:01:00 +01:00
Extra_ProgressBarUpdate( pProgress, i, NULL );
2005-09-04 17:01:00 +02:00
pNodeNew = Abc_NodeFromFraig_rec( pNtkNew, Fraig_ManReadOutputs(pMan)[i] );
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
2005-07-29 17:01:00 +02:00
}
2008-01-31 05:01:00 +01:00
Extra_ProgressBarStop( pProgress );
Abc_NtkReassignIds( pNtkNew );
2005-07-29 17:01:00 +02:00
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Transforms into AIG one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig )
{
Abc_Obj_t * pRes, * pRes0, * pRes1, * pResMin, * pResCur;
Fraig_Node_t * pNodeTemp, * pNodeFraigR = Fraig_Regular(pNodeFraig);
void ** ppTail;
// check if the node was already considered
2008-07-02 17:01:00 +02:00
if ( (pRes = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeFraigR)) )
2005-07-29 17:01:00 +02:00
return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) );
// solve the children
pRes0 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadOne(pNodeFraigR) );
pRes1 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadTwo(pNodeFraigR) );
// derive the new node
2010-11-01 09:35:04 +01:00
pRes = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, pRes0, pRes1 );
2005-07-29 17:01:00 +02:00
pRes->fPhase = Fraig_NodeReadSimInv( pNodeFraigR );
// if the node has an equivalence class, find its representative
if ( Fraig_NodeReadRepr(pNodeFraigR) == NULL && Fraig_NodeReadNextE(pNodeFraigR) != NULL )
{
// go through the FRAIG nodes belonging to this equivalence class
// and find the representative node (the node with the smallest level)
pResMin = pRes;
for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) )
{
assert( Fraig_NodeReadData1(pNodeTemp) == NULL );
pResCur = Abc_NodeFromFraig_rec( pNtkNew, pNodeTemp );
if ( pResMin->Level > pResCur->Level )
pResMin = pResCur;
}
// link the nodes in such a way that representative goes first
ppTail = &pResMin->pData;
if ( pRes != pResMin )
{
*ppTail = pRes;
ppTail = &pRes->pData;
}
for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) )
{
pResCur = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeTemp);
assert( pResCur );
if ( pResMin == pResCur )
continue;
*ppTail = pResCur;
ppTail = &pResCur->pData;
}
assert( *ppTail == NULL );
// update the phase of the node
pRes = Abc_ObjNotCond( pResMin, (pRes->fPhase ^ pResMin->fPhase) );
}
Fraig_NodeSetData1( pNodeFraigR, (Fraig_Node_t *)pRes );
return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) );
}
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis [Transforms FRAIG into strashed network without choices.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromFraig2( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
{
ProgressBar * pProgress;
stmm_table * tTable;
Vec_Ptr_t * vNodeReprs;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pNode, * pRepr, ** ppSlot;
int i;
// map the nodes into their lowest level representives
tTable = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
pNode = Abc_AigConst1(pNtk);
if ( !stmm_find_or_add( tTable, (char *)Fraig_Regular(pNode->pCopy), (char ***)&ppSlot ) )
*ppSlot = pNode;
Abc_NtkForEachCi( pNtk, pNode, i )
if ( !stmm_find_or_add( tTable, (char *)Fraig_Regular(pNode->pCopy), (char ***)&ppSlot ) )
*ppSlot = pNode;
Abc_NtkForEachNode( pNtk, pNode, i )
if ( pNode->pCopy )
{
if ( !stmm_find_or_add( tTable, (char *)Fraig_Regular(pNode->pCopy), (char ***)&ppSlot ) )
*ppSlot = pNode;
else if ( (*ppSlot)->Level > pNode->Level )
*ppSlot = pNode;
}
// save representatives for each node
vNodeReprs = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
if ( pNode->pCopy )
{
if ( !stmm_lookup( tTable, (char *)Fraig_Regular(pNode->pCopy), (char **)&pRepr ) )
assert( 0 );
if ( pNode != pRepr )
Vec_PtrWriteEntry( vNodeReprs, pNode->Id, pRepr );
}
stmm_free_table( tTable );
// create the new network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
// perform strashing
Abc_AigSetNodePhases( pNtk );
Abc_NtkIncrementTravId( pNtk );
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
Abc_NtkFromFraig2_rec( pNtkNew, Abc_ObjFanin0(pNode), vNodeReprs );
}
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodeReprs );
// finalize the network
Abc_NtkFinalize( pNtk, pNtkNew );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Transforms into AIG one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFromFraig2_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, Vec_Ptr_t * vNodeReprs )
{
Abc_Obj_t * pRepr;
// skip the PIs and constants
if ( Abc_ObjFaninNum(pNode) < 2 )
return;
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
assert( Abc_ObjIsNode( pNode ) );
// get the node's representative
2010-11-01 09:35:04 +01:00
if ( (pRepr = (Abc_Obj_t *)Vec_PtrEntry(vNodeReprs, pNode->Id)) )
2008-01-31 05:01:00 +01:00
{
Abc_NtkFromFraig2_rec( pNtkNew, pRepr, vNodeReprs );
pNode->pCopy = Abc_ObjNotCond( pRepr->pCopy, pRepr->fPhase ^ pNode->fPhase );
return;
}
Abc_NtkFromFraig2_rec( pNtkNew, Abc_ObjFanin0(pNode), vNodeReprs );
Abc_NtkFromFraig2_rec( pNtkNew, Abc_ObjFanin1(pNode), vNodeReprs );
2010-11-01 09:35:04 +01:00
pNode->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
2008-01-31 05:01:00 +01:00
}
2005-07-29 17:01:00 +02:00
/**Function*************************************************************
Synopsis [Interfaces the network with the FRAIG package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew;
2005-08-29 17:01:00 +02:00
if ( !Abc_NtkIsSopLogic(pNtk) )
2005-07-29 17:01:00 +02:00
{
printf( "Abc_NtkFraigTrust: Trust mode works for netlists and logic SOP networks.\n" );
return NULL;
}
if ( !Abc_NtkFraigTrustCheck(pNtk) )
{
printf( "Abc_NtkFraigTrust: The network does not look like an AIG with choice nodes.\n" );
return NULL;
}
// perform strashing
2008-01-31 05:01:00 +01:00
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
2005-07-29 17:01:00 +02:00
Abc_NtkFraigTrustOne( pNtk, pNtkNew );
Abc_NtkFinalize( pNtk, pNtkNew );
2008-01-31 05:01:00 +01:00
Abc_NtkReassignIds( pNtkNew );
2005-07-29 17:01:00 +02:00
// print a warning about choice nodes
2005-09-02 17:01:00 +02:00
printf( "Warning: The resulting AIG contains %d choice nodes.\n", Abc_NtkGetChoiceNum( pNtkNew ) );
2005-07-29 17:01:00 +02:00
// make sure that everything is okay
2005-09-05 17:01:00 +02:00
if ( !Abc_NtkCheck( pNtkNew ) )
2005-07-29 17:01:00 +02:00
{
printf( "Abc_NtkFraigTrust: The network check has failed.\n" );
Abc_NtkDelete( pNtkNew );
return NULL;
}
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Checks whether the node can be processed in the trust mode.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i, nFanins;
Abc_NtkForEachNode( pNtk, pNode, i )
{
nFanins = Abc_ObjFaninNum(pNode);
if ( nFanins < 2 )
continue;
2010-11-01 09:35:04 +01:00
if ( nFanins == 2 && Abc_SopIsAndType((char *)pNode->pData) )
2005-07-29 17:01:00 +02:00
continue;
2010-11-01 09:35:04 +01:00
if ( !Abc_SopIsOrType((char *)pNode->pData) )
2005-07-29 17:01:00 +02:00
return 0;
}
return 1;
}
/**Function*************************************************************
Synopsis [Interfaces the network with the FRAIG package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
ProgressBar * pProgress;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pNodeNew, * pObj;
int i;
// perform strashing
2005-08-14 17:01:00 +02:00
vNodes = Abc_NtkDfs( pNtk, 0 );
2005-07-29 17:01:00 +02:00
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
2005-07-29 17:01:00 +02:00
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// get the node
assert( Abc_ObjIsNode(pNode) );
// strash the node
2008-01-31 05:01:00 +01:00
pNodeNew = Abc_NodeFraigTrust( pNtkNew, pNode );
2005-07-29 17:01:00 +02:00
// get the old object
if ( Abc_NtkIsNetlist(pNtk) )
pObj = Abc_ObjFanout0( pNode ); // the fanout net
else
pObj = pNode; // the node itself
// make sure the node is not yet strashed
assert( pObj->pCopy == NULL );
// mark the old object with the new AIG node
pObj->pCopy = pNodeNew;
}
Vec_PtrFree( vNodes );
Extra_ProgressBarStop( pProgress );
}
/**Function*************************************************************
Synopsis [Transforms one node into a FRAIG in the trust mode.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2008-01-31 05:01:00 +01:00
Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
2005-07-29 17:01:00 +02:00
{
Abc_Obj_t * pSum, * pFanin;
void ** ppTail;
int i, nFanins, fCompl;
assert( Abc_ObjIsNode(pNode) );
// get the number of node's fanins
nFanins = Abc_ObjFaninNum( pNode );
2010-11-01 09:35:04 +01:00
assert( nFanins == Abc_SopGetVarNum((char *)pNode->pData) );
2005-07-29 17:01:00 +02:00
// check if it is a constant
if ( nFanins == 0 )
2010-11-01 09:35:04 +01:00
return Abc_ObjNotCond( Abc_AigConst1(pNtkNew), Abc_SopIsConst0((char *)pNode->pData) );
2005-07-29 17:01:00 +02:00
if ( nFanins == 1 )
2010-11-01 09:35:04 +01:00
return Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_SopIsInv((char *)pNode->pData) );
if ( nFanins == 2 && Abc_SopIsAndType((char *)pNode->pData) )
return Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc,
Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, !Abc_SopGetIthCareLit((char *)pNode->pData,0) ),
Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, !Abc_SopGetIthCareLit((char *)pNode->pData,1) ) );
assert( Abc_SopIsOrType((char *)pNode->pData) );
fCompl = Abc_SopGetIthCareLit((char *)pNode->pData,0);
2005-07-29 17:01:00 +02:00
// get the root of the choice node (the first fanin)
pSum = Abc_ObjFanin0(pNode)->pCopy;
// connect other fanins
ppTail = &pSum->pData;
Abc_ObjForEachFanin( pNode, pFanin, i )
{
if ( i == 0 )
continue;
*ppTail = pFanin->pCopy;
ppTail = &pFanin->pCopy->pData;
// set the complemented bit of this cut
2010-11-01 09:35:04 +01:00
if ( fCompl ^ Abc_SopGetIthCareLit((char *)pNode->pData, i) )
2005-07-29 17:01:00 +02:00
pFanin->pCopy->fPhase = 1;
}
assert( *ppTail == NULL );
return pSum;
}
/**Function*************************************************************
Synopsis [Interfaces the network with the FRAIG package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2008-01-31 05:01:00 +01:00
int Abc_NtkFraigStore( Abc_Ntk_t * pNtkAdd )
2005-07-29 17:01:00 +02:00
{
2008-01-31 05:01:00 +01:00
Vec_Ptr_t * vStore;
Abc_Ntk_t * pNtk;
// create the network to be stored
pNtk = Abc_NtkStrash( pNtkAdd, 0, 0, 0 );
if ( pNtk == NULL )
2005-07-29 17:01:00 +02:00
{
2008-01-31 05:01:00 +01:00
printf( "Abc_NtkFraigStore: Initial strashing has failed.\n" );
2005-07-29 17:01:00 +02:00
return 0;
}
// get the network currently stored
2008-01-31 05:01:00 +01:00
vStore = Abc_FrameReadStore();
if ( Vec_PtrSize(vStore) > 0 )
2005-07-29 17:01:00 +02:00
{
2008-01-31 05:01:00 +01:00
// check that the networks have the same PIs
extern int Abc_NodeCompareCiCo( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew );
if ( !Abc_NodeCompareCiCo(pNtk, (Abc_Ntk_t *)Vec_PtrEntry(vStore, 0)) )
2005-07-29 17:01:00 +02:00
{
// reorder PIs of pNtk2 according to pNtk1
if ( !Abc_NtkCompareSignals( pNtk, (Abc_Ntk_t *)Vec_PtrEntry(vStore, 0), 1, 1 ) )
{
printf( "Trying to store the network with different primary inputs.\n" );
printf( "The previously stored networks are deleted and this one is added.\n" );
Abc_NtkFraigStoreClean();
}
2005-07-29 17:01:00 +02:00
}
}
2008-01-31 05:01:00 +01:00
Vec_PtrPush( vStore, pNtk );
// printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pNtk) );
2005-07-29 17:01:00 +02:00
return 1;
}
/**Function*************************************************************
Synopsis [Interfaces the network with the FRAIG package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFraigRestore( int nPatsRand, int nPatsDyna, int nBTLimit )
2005-07-29 17:01:00 +02:00
{
2008-01-31 05:01:00 +01:00
extern Abc_Ntk_t * Abc_NtkFraigPartitioned( Vec_Ptr_t * vStore, void * pParams );
2005-07-29 17:01:00 +02:00
Fraig_Params_t Params;
2008-01-31 05:01:00 +01:00
Vec_Ptr_t * vStore;
Abc_Ntk_t * pNtk, * pFraig;
2005-07-29 17:01:00 +02:00
int nWords1, nWords2, nWordsMin;
// abctime clk = Abc_Clock();
2005-07-29 17:01:00 +02:00
// get the stored network
2008-01-31 05:01:00 +01:00
vStore = Abc_FrameReadStore();
if ( Vec_PtrSize(vStore) == 0 )
2005-07-29 17:01:00 +02:00
{
printf( "There are no network currently in storage.\n" );
return NULL;
}
2008-01-31 05:01:00 +01:00
// printf( "Currently stored %d networks will be fraiged.\n", Vec_PtrSize(vStore) );
2010-11-01 09:35:04 +01:00
pNtk = (Abc_Ntk_t *)Vec_PtrEntry( vStore, 0 );
2008-01-31 05:01:00 +01:00
// swap the first and last network
// this should lead to the primary choice being "better" because of synthesis
2012-05-06 16:52:56 +02:00
if ( Vec_PtrSize(vStore) > 1 )
{
pNtk = (Abc_Ntk_t *)Vec_PtrPop( vStore );
Vec_PtrPush( vStore, Vec_PtrEntry(vStore,0) );
Vec_PtrWriteEntry( vStore, 0, pNtk );
}
2007-09-06 17:01:00 +02:00
2005-07-29 17:01:00 +02:00
// to determine the number of simulation patterns
// use the following strategy
// at least 64 words (32 words random and 32 words dynamic)
// no more than 256M for one circuit (128M + 128M)
nWords1 = 32;
2008-01-31 05:01:00 +01:00
nWords2 = (1<<27) / (Abc_NtkNodeNum(pNtk) + Abc_NtkCiNum(pNtk));
2012-01-21 13:30:10 +01:00
nWordsMin = Abc_MinInt( nWords1, nWords2 );
2005-07-29 17:01:00 +02:00
// set parameters for fraiging
Fraig_ParamsSetDefault( &Params );
Params.nPatsRand = nPatsRand ? nPatsRand : nWordsMin * 32; // the number of words of random simulation info
Params.nPatsDyna = nPatsDyna ? nPatsDyna : nWordsMin * 32; // the number of words of dynamic simulation info
Params.nBTLimit = nBTLimit; // the max number of backtracks to perform
2008-01-31 05:01:00 +01:00
Params.fFuncRed = 1; // performs only one level hashing
Params.fFeedBack = 1; // enables solver feedback
Params.fDist1Pats = 1; // enables distance-1 patterns
Params.fDoSparse = 1; // performs equiv tests for sparse functions
Params.fChoicing = 1; // enables recording structural choices
Params.fTryProve = 0; // tries to solve the final miter
2008-07-02 17:01:00 +02:00
Params.fInternal = 1; // does not show progress bar
2008-01-31 05:01:00 +01:00
Params.fVerbose = 0; // the verbosiness flag
// perform partitioned computation of structural choices
pFraig = Abc_NtkFraigPartitioned( vStore, &Params );
Abc_NtkFraigStoreClean();
//ABC_PRT( "Total choicing time", Abc_Clock() - clk );
2005-07-29 17:01:00 +02:00
return pFraig;
}
/**Function*************************************************************
Synopsis [Interfaces the network with the FRAIG package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFraigStoreClean()
{
2008-01-31 05:01:00 +01:00
Vec_Ptr_t * vStore;
Abc_Ntk_t * pNtk;
int i;
vStore = Abc_FrameReadStore();
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Abc_Ntk_t *, vStore, pNtk, i )
2008-01-31 05:01:00 +01:00
Abc_NtkDelete( pNtk );
Vec_PtrClear( vStore );
2005-07-29 17:01:00 +02:00
}
/**Function*************************************************************
Synopsis [Checks the correctness of stored networks.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFraigStoreCheck( Abc_Ntk_t * pFraig )
{
Abc_Obj_t * pNode0, * pNode1;
int nPoOrig, nPoFinal, nStored;
int i, k;
// check that the PO functions are correct
nPoFinal = Abc_NtkPoNum(pFraig);
2008-01-31 05:01:00 +01:00
nStored = Abc_FrameReadStoreSize();
2005-07-29 17:01:00 +02:00
assert( nPoFinal % nStored == 0 );
nPoOrig = nPoFinal / nStored;
for ( i = 0; i < nPoOrig; i++ )
{
pNode0 = Abc_ObjFanin0( Abc_NtkPo(pFraig, i) );
for ( k = 1; k < nStored; k++ )
{
pNode1 = Abc_ObjFanin0( Abc_NtkPo(pFraig, k*nPoOrig+i) );
if ( pNode0 != pNode1 )
printf( "Verification for PO #%d of network #%d has failed. The PO function is not used.\n", i+1, k+1 );
}
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
2010-11-01 09:35:04 +01:00
ABC_NAMESPACE_IMPL_END