Commit d4291dab by Alan Mishchenko

Cumulative changes of the last two weeks.

parent 624af674
......@@ -13,6 +13,7 @@ lib/
docs/
src/ext/
src/xxx/
*~
*.orig
......
......@@ -1747,10 +1747,6 @@ SOURCE=.\src\opt\mfs\mfsDiv.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\mfs\mfsGia.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\mfs\mfsInt.h
# End Source File
# Begin Source File
......@@ -3071,6 +3067,10 @@ SOURCE=.\src\aig\aig\aigDfs.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\aig\aigDoms.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\aig\aigDup.c
# End Source File
# Begin Source File
......@@ -4035,56 +4035,84 @@ SOURCE=.\src\aig\llb\llb.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbCex.c
SOURCE=.\src\aig\llb\llb1Cluster.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbCluster.c
SOURCE=.\src\aig\llb\llb1Constr.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbConstr.c
SOURCE=.\src\aig\llb\llb1Core.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbCore.c
SOURCE=.\src\aig\llb\llb1Group.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbFlow.c
SOURCE=.\src\aig\llb\llb1Hint.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbHint.c
SOURCE=.\src\aig\llb\llb1Man.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbInt.h
SOURCE=.\src\aig\llb\llb1Matrix.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbMan.c
SOURCE=.\src\aig\llb\llb1Pivot.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbMatrix.c
SOURCE=.\src\aig\llb\llb1Reach.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbPart.c
SOURCE=.\src\aig\llb\llb1Sched.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbPivot.c
SOURCE=.\src\aig\llb\llb2Bad.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbReach.c
SOURCE=.\src\aig\llb\llb2Core.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbSched.c
SOURCE=.\src\aig\llb\llb2Driver.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llb2Dump.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llb2Flow.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llb2Image.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llb3Image.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llb3Nonlin.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\llb\llbInt.h
# End Source File
# End Group
# Begin Group "bll"
# PROP Default_Filter ""
# End Group
# End Group
# End Group
......
link.exe @<<
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 lib\abcd.lib /nologo /subsystem:console /incremental:yes /pdb:".\DebugExe\abc.pdb" /debug /machine:I386 /out:"_TEST/abc.exe" ".\DebugExe\main.obj" ".\lib\abcd.lib"
......@@ -22,3 +22,24 @@ Using AIG Package in ABC
The above process should not produce memory leaks.
Using GIA Package in ABC
- Add #include "gia.h".
- Start the AIG package using Gia_ManStart( int nObjMax ).
(Parameter 'nNodeMax' should approximately reflect the expected number of objects, including PIs, POs, flop inputs, and flop outputs. If the number of objects is more, memory will be automatically reallocated.)
- Assign primary inputs using Gia_ManAppendCi().
- Assign flop outputs using Gia_ManAppendCi().
(It is important to create all PIs first, before creating flop outputs).
(Flop control logic, if present, should be elaborated into AND gates. For example, to represent a flop enable, create the driver of enable signal, which can be a PI or an internal node, and then add logic for <flop_input_new> = MUX( <enable>, <flop_input>, <flop_output> ). The output of this logic feeds into the flop.
- Construct AIG in the topological order using Gia_ManHashAnd(), Gia_ManHashOr(), Gia_Not(), etc.
- If constant-0/1 AIG nodes are needed, use Gia_ManConst0() or Gia_ManConst1()
- Create primary outputs using Gia_ManAppendCo().
- Create flop inputs using Gia_ManAppendCo().
(it is important to create all POs first, before creating register inputs).
- Set the number of flops by calling Gia_ManSetRegNum().
- Remove dangling AIG nodes (produced by structural hashing) by running Gia_ManCleanup(), which will return a new AIG. If object mapping is defined for the original AIG, it should be remapped into the new AIG.
- Dump AIG into an AIGER file use Gia_DumpAiger().
- For each object in the design annotated with the constructed AIG node (pNode), remember its AIG node ID by calling Gia_ObjId(pNode).
- Quit the AIG package using Gia_ManStop().
The above process should not produce memory leaks.
r examples/apex4.pla; resyn; if; cec; ps; clp; resyn; map; cec; ps
r examples/C2670.blif; st; w 1.aig; cec 1.aig
r examples/C2670.blif; st; short_names; w 1.bench; cec 1.bench
r examples/C2670.blif; st; short_names; ren -s; w 1.eqn; cec 1.eqn
r examples/C2670.blif; resyn2; if -K 8; cec; ps; u; map; cec; ps
r examples/frg2.blif; dsd; muxes; cec; ps; clp; share; resyn; map; cec; ps
r examples/frg2.blif; bdd; muxes; cec; ps; clp; st; ren -b; muxes; cec; ps
r examples/i10.blif; resyn2; fpga; cec; ps; u; map; cec; ps
r examples/i10.blif; choice; fpga; cec; ps; u; map; cec; ps
r examples/pj1.blif; st; if; cec; ps; u; map; cec; ps
r examples/s38417.blif; comb; w 1.blif; resyn; if; cec 1.blif; ps
r examples/s38417.blif; resyn; if; cec; ps; u; map; cec; ps
r examples/s38584.bench; resyn; ren -s; fx; if; cec; ps; u; map; cec; ps
r examples/s444.blif; b; esd -v; print_exdc; dsd; cec; ps
r examples/s444.blif; double; frames -F 5; w 1.blif; ffpga -K 8; cec 1.blif
r examples/s5378.blif; frames -F 5; cycle; w 1.blif; ps; ret; ps; sec 1.blif
r examples/s6669.blif; cycle; w 1.blif; ps; ret -M 3; resyn; ps; sec 1.blif
time
......@@ -470,6 +470,7 @@ extern void Aig_ManCutStop( Aig_ManCut_t * p );
/*=== aigDfs.c ==========================================================*/
extern int Aig_ManVerifyTopoOrder( Aig_Man_t * p );
extern Vec_Ptr_t * Aig_ManDfs( Aig_Man_t * p, int fNodesOnly );
extern Vec_Ptr_t * Aig_ManDfsAll( Aig_Man_t * p );
extern Vec_Ptr_t * Aig_ManDfsPreorder( Aig_Man_t * p, int fNodesOnly );
extern Vec_Vec_t * Aig_ManLevelize( Aig_Man_t * p );
extern Vec_Ptr_t * Aig_ManDfsNodes( Aig_Man_t * p, Aig_Obj_t ** ppNodes, int nNodes );
......@@ -501,6 +502,7 @@ extern Vec_Ptr_t * Aig_ManOrderPios( Aig_Man_t * p, Aig_Man_t * pOrder );
extern Aig_Man_t * Aig_ManDupDfsGuided( Aig_Man_t * p, Vec_Ptr_t * vPios );
extern Aig_Man_t * Aig_ManDupLevelized( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupWithoutPos( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupFlopsOnly( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupRepres( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupRepresDfs( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int fImpl );
......
......@@ -178,6 +178,70 @@ Vec_Ptr_t * Aig_ManDfs( Aig_Man_t * p, int fNodesOnly )
SeeAlso []
***********************************************************************/
void Aig_ManDfsAll_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
return;
Aig_ObjSetTravIdCurrent(p, pObj);
if ( Aig_ObjIsPi(pObj) )
{
Vec_PtrPush( vNodes, pObj );
return;
}
if ( Aig_ObjIsPo(pObj) )
{
Aig_ManDfsAll_rec( p, Aig_ObjFanin0(pObj), vNodes );
Vec_PtrPush( vNodes, pObj );
return;
}
assert( Aig_ObjIsNode(pObj) );
Aig_ManDfsAll_rec( p, Aig_ObjFanin0(pObj), vNodes );
Aig_ManDfsAll_rec( p, Aig_ObjFanin1(pObj), vNodes );
Vec_PtrPush( vNodes, pObj );
}
/**Function*************************************************************
Synopsis [Collects objects of the AIG in the DFS order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Aig_ManDfsAll( Aig_Man_t * p )
{
Vec_Ptr_t * vNodes;
Aig_Obj_t * pObj;
int i;
Aig_ManIncrementTravId( p );
vNodes = Vec_PtrAlloc( Aig_ManObjNumMax(p) );
// add constant
Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
Vec_PtrPush( vNodes, Aig_ManConst1(p) );
// collect nodes reachable in the DFS order
Aig_ManForEachPo( p, pObj, i )
Aig_ManDfsAll_rec( p, pObj, vNodes );
Aig_ManForEachPi( p, pObj, i )
if ( !Aig_ObjIsTravIdCurrent(p, pObj) )
Vec_PtrPush( vNodes, pObj );
assert( Vec_PtrSize(vNodes) == Aig_ManObjNum(p) );
return vNodes;
}
/**Function*************************************************************
Synopsis [Collects internal nodes in the DFS order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManDfsPreorder_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
if ( pObj == NULL )
......
......@@ -913,6 +913,33 @@ Aig_Man_t * Aig_ManDupWithoutPos( Aig_Man_t * p )
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates the AIG manager.]
Description [Assumes topological ordering of nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManDupFlopsOnly( Aig_Man_t * p )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj;
int i;
pNew = Aig_ManDupWithoutPos( p );
Saig_ManForEachLi( p, pObj, i )
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
Aig_ManCleanup( pNew );
Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
if ( !Aig_ManCheck(pNew) )
printf( "Aig_ManDupFlopsOnly(): The check has failed.\n" );
return pNew;
}
/**Function*************************************************************
......
......@@ -370,6 +370,15 @@ int Aig_ManComputeReachable( DdManager * dd, Aig_Man_t * p, DdNode ** pbParts, D
if ( pPars->fVerbose )
// fprintf( stdout, "\r" );
fprintf( stdout, "\n" );
if ( pPars->fVerbose )
{
double nMints = Cudd_CountMinterm(dd, bReached, Saig_ManRegNum(p) );
// Extra_bddPrint( dd, bReached );printf( "\n" );
fprintf( stdout, "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p)) );
fflush( stdout );
}
}
Cudd_RecursiveDeref( dd, bNext );
// free the onion rings
......
......@@ -31,7 +31,6 @@
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_HEADER_START
......@@ -50,11 +49,14 @@ struct Gia_ParLlb_t_
int fUseFlow; // use flow computation
int nVolumeMax; // the largest volume
int nVolumeMin; // the smallest volume
int nPartValue; // partitioning value
int fBackward; // enable backward reachability
int fReorder; // enable dynamic variable reordering
int fIndConstr; // extract inductive constraints
int fUsePivots; // use internal pivot variables
int fCluster; // use partition clustering
int fSchedule; // use cluster scheduling
int fDumpReached; // dump reached states into a file
int fVerbose; // print verbose information
int fVeryVerbose; // print dependency matrices
int fSilent; // do not print any infomation
......
/**CFile****************************************************************
FileName [llbCluster.c]
FileName [llb1Cluster.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbCluster.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Cluster.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......
/**CFile****************************************************************
FileName [llbConstr.c]
FileName [llb1Constr.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbConstr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Constr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......
/**CFile****************************************************************
FileName [llbCore.c]
FileName [llb1Core.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Core.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......@@ -24,7 +24,6 @@
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -47,7 +46,7 @@ ABC_NAMESPACE_IMPL_START
void Llb_ManSetDefaultParams( Gia_ParLlb_t * p )
{
memset( p, 0, sizeof(Gia_ParLlb_t) );
p->nBddMax = 1000000;
p->nBddMax = 10000000;
p->nIterMax = 10000000;
p->nClusterMax = 20;
p->nHintDepth = 0;
......@@ -55,11 +54,14 @@ void Llb_ManSetDefaultParams( Gia_ParLlb_t * p )
p->fUseFlow = 0; // use flow
p->nVolumeMax = 100; // max volume
p->nVolumeMin = 30; // min volume
p->nPartValue = 5; // partitioning value
p->fBackward = 0; // forward by default
p->fReorder = 1;
p->fIndConstr = 0;
p->fUsePivots = 0;
p->fCluster = 0;
p->fSchedule = 0;
p->fDumpReached = 0;
p->fVerbose = 0;
p->fVeryVerbose = 0;
p->fSilent = 0;
......
/**CFile****************************************************************
FileName [llbPart.c]
FileName [llb1Group.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbPart.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Group.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......
/**CFile****************************************************************
FileName [llbHint.c]
FileName [llb1Hint.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbHint.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Hint.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......@@ -205,8 +205,8 @@ int Llb_ManModelCheckAigWithHints( Aig_Man_t * pAigGlo, Gia_ParLlb_t * pPars )
Finish:
if ( ddGlo )
{
if ( ddGlo->bReached )
Cudd_RecursiveDeref( ddGlo, ddGlo->bReached );
if ( ddGlo->bFunc )
Cudd_RecursiveDeref( ddGlo, ddGlo->bFunc );
Extra_StopManager( ddGlo );
}
Vec_IntFreeP( &vHFCands );
......
/**CFile****************************************************************
FileName [llbMan.c]
FileName [llb1Man.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Man.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......@@ -142,8 +142,8 @@ void Llb_ManStop( Llb_Man_t * p )
}
if ( p->ddG )
{
if ( p->ddG->bReached )
Cudd_RecursiveDeref( p->ddG, p->ddG->bReached );
if ( p->ddG->bFunc )
Cudd_RecursiveDeref( p->ddG, p->ddG->bFunc );
Extra_StopManager( p->ddG );
}
Aig_ManStop( p->pAig );
......
/**CFile****************************************************************
FileName [llbMatrix.c]
FileName [llb1Matrix.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbMatrix.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Matrix.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......
/**CFile****************************************************************
FileName [llbPivot.c]
FileName [llb1Pivot.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbPivot.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Pivot.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......
/**CFile****************************************************************
FileName [llbReach.c]
FileName [llb1Reach.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbReach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Reach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......@@ -346,6 +346,22 @@ DdNode * Llb_ManCreateConstraints( Llb_Man_t * p, Vec_Int_t * vHints, int fUseNs
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Cex_t * Llb_ManDeriveCex( Llb_Man_t * p, DdNode * bInter, int iOutFail, int iIter )
{
return NULL;
}
/**Function*************************************************************
Synopsis [Perform reachability with hints and returns reached states in ppGlo.]
Description []
......@@ -358,7 +374,6 @@ DdNode * Llb_ManCreateConstraints( Llb_Man_t * p, Vec_Int_t * vHints, int fUseNs
int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo )
{
int fCheckOutputs = !p->pPars->fSkipOutCheck;
int fInternalReorder = 0;
int * pNs2Glo = Vec_IntArray( p->vNs2Glo );
int * pGlo2Cs = Vec_IntArray( p->vGlo2Cs );
DdNode * bCurrent, * bReached, * bNext, * bTemp, * bCube;
......@@ -403,9 +418,9 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo
// perform reachability analysis
// compute the starting set of states
if ( p->ddG->bReached )
if ( p->ddG->bFunc )
{
bReached = p->ddG->bReached; p->ddG->bReached = NULL;
bReached = p->ddG->bFunc; p->ddG->bFunc = NULL;
bCurrent = Extra_TransferPermute( p->ddG, p->dd, bReached, pGlo2Cs ); Cudd_Ref( bCurrent );
}
else
......@@ -548,28 +563,22 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo
if ( p->pPars->fVerbose )
{
fprintf( stdout, "F =%3d : ", nIters );
fprintf( stdout, "Image =%6d ", nBddSize );
fprintf( stdout, "%8d (%4d %3d) ",
Cudd_ReadKeys(p->dd), Cudd_ReadReorderings(p->dd), Cudd_ReadGarbageCollections(p->dd) );
fprintf( stdout, "Reach =%6d ", Cudd_DagSize(bReached) );
fprintf( stdout, "%8d (%4d %3d) ",
Cudd_ReadKeys(p->ddG), Cudd_ReadReorderings(p->ddG), Cudd_ReadGarbageCollections(p->ddG) );
fprintf( stdout, "F =%5d : ", nIters );
fprintf( stdout, "Im =%6d ", nBddSize );
fprintf( stdout, "(%4d %3d) ", Cudd_ReadReorderings(p->dd), Cudd_ReadGarbageCollections(p->dd) );
fprintf( stdout, "Rea =%6d ", Cudd_DagSize(bReached) );
fprintf( stdout, "(%4d%4d) ", Cudd_ReadReorderings(p->ddG), Cudd_ReadGarbageCollections(p->ddG) );
Abc_PrintTime( 1, "Time", clock() - clk2 );
}
if ( fInternalReorder && p->pPars->fReorder && nBddSize > nThreshold )
{
if ( p->pPars->fVerbose )
fprintf( stdout, "Reordering... Before = %5d. ", Cudd_DagSize(bReached) );
Cudd_ReduceHeap( p->dd, CUDD_REORDER_SYMM_SIFT, 100 );
// Cudd_AutodynDisable( p->dd );
/*
if ( p->pPars->fVerbose )
fprintf( stdout, "After = %5d.\r", Cudd_DagSize(bReached) );
nThreshold *= 2;
{
double nMints = Cudd_CountMinterm(p->ddG, bReached, Saig_ManRegNum(p->pAig) );
// Extra_bddPrint( p->ddG, bReached );printf( "\n" );
fprintf( stdout, "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p->pAig)) );
fflush( stdout );
}
if ( p->pPars->fVerbose )
// fprintf( stdout, "\r" );
// fprintf( stdout, "\n" );
Abc_PrintTime( 1, "T", clock() - clk2 );
*/
}
Cudd_RecursiveDeref( p->dd, bConstrCs ); bConstrCs = NULL;
Cudd_RecursiveDeref( p->dd, bConstrNs ); bConstrNs = NULL;
......@@ -598,8 +607,8 @@ int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, DdManager ** pddGlo
}
if ( pddGlo )
{
assert( p->ddG->bReached == NULL );
p->ddG->bReached = bReached; bReached = NULL;
assert( p->ddG->bFunc == NULL );
p->ddG->bFunc = bReached; bReached = NULL;
assert( *pddGlo == NULL );
*pddGlo = p->ddG; p->ddG = NULL;
}
......
/**CFile****************************************************************
FileName [llb.c]
FileName [llb1Sched.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [BDD based reachability.]
Synopsis []
Synopsis [Partition scheduling algorithm.]
Author [Alan Mishchenko]
......@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llb.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: llb1Sched.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
......
/**CFile****************************************************************
FileName [llb2Bad.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [BDD based reachability.]
Synopsis [Computing bad states.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llb2Bad.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "llbInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes bad in working manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode * Llb_BddComputeBad( Aig_Man_t * pInit, DdManager * dd )
{
Vec_Ptr_t * vNodes;
DdNode * bBdd0, * bBdd1, * bTemp, * bResult;
Aig_Obj_t * pObj;
int i;
assert( Cudd_ReadSize(dd) == Aig_ManPiNum(pInit) );
// initialize elementary variables
Aig_ManConst1(pInit)->pData = Cudd_ReadOne( dd );
Saig_ManForEachLo( pInit, pObj, i )
pObj->pData = Cudd_bddIthVar( dd, i );
Saig_ManForEachPi( pInit, pObj, i )
pObj->pData = Cudd_bddIthVar( dd, Aig_ManRegNum(pInit) + i );
// compute internal nodes
vNodes = Aig_ManDfsNodes( pInit, (Aig_Obj_t **)Vec_PtrArray(pInit->vPos), Saig_ManPoNum(pInit) );
Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
{
if ( !Aig_ObjIsNode(pObj) )
continue;
bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) );
pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( (DdNode *)pObj->pData );
}
// quantify PIs of each PO
bResult = Cudd_ReadLogicZero( dd ); Cudd_Ref( bResult );
Saig_ManForEachPo( pInit, pObj, i )
{
bBdd0 = Cudd_NotCond( Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
bResult = Cudd_bddOr( dd, bTemp = bResult, bBdd0 ); Cudd_Ref( bResult );
Cudd_RecursiveDeref( dd, bTemp );
}
// deref
Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
{
if ( !Aig_ObjIsNode(pObj) )
continue;
Cudd_RecursiveDeref( dd, pObj->pData );
}
Vec_PtrFree( vNodes );
Cudd_Deref( bResult );
return bResult;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode * Llb_BddQuantifyPis( Aig_Man_t * pInit, DdManager * dd, DdNode * bFunc )
{
DdNode * bVar, * bCube, * bTemp;
Aig_Obj_t * pObj;
int i;
assert( Cudd_ReadSize(dd) == Aig_ManPiNum(pInit) );
// create PI cube
bCube = Cudd_ReadOne( dd ); Cudd_Ref( bCube );
Saig_ManForEachPi( pInit, pObj, i )
{
bVar = Cudd_bddIthVar( dd, Aig_ManRegNum(pInit) + i );
bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube );
Cudd_RecursiveDeref( dd, bTemp );
}
// quantify PI cube
bFunc = Cudd_bddExistAbstract( dd, bFunc, bCube ); Cudd_Ref( bFunc );
Cudd_RecursiveDeref( dd, bCube );
Cudd_Deref( bFunc );
return bFunc;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
/**CFile****************************************************************
FileName [llb2Driver.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [BDD based reachability.]
Synopsis [Procedures working with flop drivers.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llb2Driver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "llbInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// driver issue:arises when creating
// - driver ref-counter array
// - Ns2Glo maps
// - final partition
// - change-phase cube
// LI variable is used when
// - driver drives more than one LI
// - driver is a PI
// - driver is a constant
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns the array of times each flop driver is referenced.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Llb_DriverCountRefs( Aig_Man_t * p )
{
Vec_Int_t * vCounts;
Aig_Obj_t * pObj;
int i;
vCounts = Vec_IntStart( Aig_ManObjNumMax(p) );
Saig_ManForEachLi( p, pObj, i )
Vec_IntAddToEntry( vCounts, Aig_ObjFaninId0(pObj), 1 );
return vCounts;
}
/**Function*************************************************************
Synopsis [Returns array of NS variables.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Llb_DriverCollectNs( Aig_Man_t * pAig, Vec_Int_t * vDriRefs )
{
Vec_Int_t * vVars;
Aig_Obj_t * pObj, * pDri;
int i;
vVars = Vec_IntAlloc( Aig_ManRegNum(pAig) );
Saig_ManForEachLi( pAig, pObj, i )
{
pDri = Aig_ObjFanin0(pObj);
if ( Vec_IntEntry( vDriRefs, Aig_ObjId(pDri) ) != 1 || Saig_ObjIsPi(pAig, pDri) || Aig_ObjIsConst1(pDri) )
Vec_IntPush( vVars, Aig_ObjId(pObj) );
else
Vec_IntPush( vVars, Aig_ObjId(pDri) );
}
return vVars;
}
/**Function*************************************************************
Synopsis [Returns array of CS variables.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Llb_DriverCollectCs( Aig_Man_t * pAig )
{
Vec_Int_t * vVars;
Aig_Obj_t * pObj;
int i;
vVars = Vec_IntAlloc( Aig_ManRegNum(pAig) );
Saig_ManForEachLo( pAig, pObj, i )
Vec_IntPush( vVars, Aig_ObjId(pObj) );
return vVars;
}
/**Function*************************************************************
Synopsis [Create cube for phase swapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode * Llb_DriverPhaseCube( Aig_Man_t * pAig, Vec_Int_t * vDriRefs, DdManager * dd )
{
DdNode * bCube, * bVar, * bTemp;
Aig_Obj_t * pObj;
int i;
bCube = Cudd_ReadOne( dd ); Cudd_Ref( bCube );
Saig_ManForEachLi( pAig, pObj, i )
{
assert( Vec_IntEntry( vDriRefs, Aig_ObjFaninId0(pObj) ) >= 1 );
if ( Vec_IntEntry( vDriRefs, Aig_ObjFaninId0(pObj) ) != 1 )
continue;
if ( !Aig_ObjFaninC0(pObj) )
continue;
bVar = Cudd_bddIthVar( dd, Aig_ObjFaninId0(pObj) );
bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube );
Cudd_RecursiveDeref( dd, bTemp );
}
Cudd_Deref( bCube );
return bCube;
}
/**Function*************************************************************
Synopsis [Compute the last partition.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdManager * Llb_DriverLastPartition( Aig_Man_t * p, Vec_Int_t * vVarsNs )
{
int fVerbose = 1;
DdManager * dd;
DdNode * bVar1, * bVar2, * bProd, * bRes, * bTemp;
Aig_Obj_t * pObj;
int i;
dd = Cudd_Init( Aig_ManObjNumMax(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
bRes = Cudd_ReadOne(dd); Cudd_Ref( bRes );
// mark the duplicated flop inputs
Aig_ManForEachNodeVec( p, vVarsNs, pObj, i )
{
if ( !Saig_ObjIsLi(p, pObj) )
continue;
bVar1 = Cudd_bddIthVar( dd, Aig_ObjId(pObj) );
bVar2 = Cudd_bddIthVar( dd, Aig_ObjFaninId0(pObj) );
if ( Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) )
bVar2 = Cudd_ReadOne(dd);
bVar2 = Cudd_NotCond( bVar2, Aig_ObjFaninC0(pObj) );
bProd = Cudd_bddXnor( dd, bVar1, bVar2 ); Cudd_Ref( bProd );
bRes = Cudd_bddAnd( dd, bTemp = bRes, bProd ); Cudd_Ref( bRes );
Cudd_RecursiveDeref( dd, bTemp );
Cudd_RecursiveDeref( dd, bProd );
}
/*
Saig_ManForEachLi( p, pObj, i )
printf( "%d ", Aig_ObjId(pObj) );
printf( "\n" );
Saig_ManForEachLi( p, pObj, i )
printf( "%c%d ", Aig_ObjFaninC0(pObj)? '-':'+', Aig_ObjFaninId0(pObj) );
printf( "\n" );
*/
Cudd_AutodynDisable( dd );
// Cudd_RecursiveDeref( dd, bRes );
// Extra_StopManager( dd );
dd->bFunc = bRes;
return dd;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
/**CFile****************************************************************
FileName [llb2Dump.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [BDD based reachability.]
Synopsis [Dumps the BDD of reached states into a file.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llb2Dump.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "llbInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns a dummy name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Llb_ManGetDummyName( char * pPrefix, int Num, int nDigits )
{
static char Buffer[2000];
sprintf( Buffer, "%s%0*d", pPrefix, nDigits, Num );
return Buffer;
}
/**Function*************************************************************
Synopsis [Writes reached state BDD into a BLIF file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Llb_ManDumpReached( DdManager * ddG, DdNode * bReached, char * pModel, char * pFileName )
{
FILE * pFile;
Vec_Ptr_t * vNamesIn, * vNamesOut;
char * pName;
int i, nDigits;
// reorder the BDD
Cudd_ReduceHeap( ddG, CUDD_REORDER_SYMM_SIFT, 1 );
// create input names
nDigits = Extra_Base10Log( Cudd_ReadSize(ddG) );
vNamesIn = Vec_PtrAlloc( Cudd_ReadSize(ddG) );
for ( i = 0; i < Cudd_ReadSize(ddG); i++ )
{
pName = Llb_ManGetDummyName( "ff", i, nDigits );
Vec_PtrPush( vNamesIn, Extra_UtilStrsav(pName) );
}
// create output names
vNamesOut = Vec_PtrAlloc( 1 );
Vec_PtrPush( vNamesOut, Extra_UtilStrsav("Reached") );
// write the file
pFile = fopen( pFileName, "wb" );
Cudd_DumpBlif( ddG, 1, &bReached, (char **)Vec_PtrArray(vNamesIn), (char **)Vec_PtrArray(vNamesOut), pModel, pFile );
fclose( pFile );
// cleanup
Vec_PtrForEachEntry( char *, vNamesIn, pName, i )
ABC_FREE( pName );
Vec_PtrForEachEntry( char *, vNamesOut, pName, i )
ABC_FREE( pName );
Vec_PtrFree( vNamesIn );
Vec_PtrFree( vNamesOut );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
/**CFile****************************************************************
FileName [llbCex.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [BDD based reachability.]
Synopsis [Deriving counter-example.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llbCex.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "llbInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Cex_t * Llb_ManDeriveCex( Llb_Man_t * p, DdNode * bInter, int iOutFail, int iIter )
{
return NULL;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
......@@ -37,11 +37,8 @@
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_HEADER_START
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
......@@ -109,8 +106,6 @@ struct Llb_Grp_t_
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== llbCex.c =======================================================*/
extern Abc_Cex_t * Llb_ManDeriveCex( Llb_Man_t * p, DdNode * bInter, int iOutFail, int iIter );
/*=== llbConstr.c ======================================================*/
extern Vec_Int_t * Llb_ManDeriveConstraints( Aig_Man_t * p );
extern void Llb_ManPrintEntries( Aig_Man_t * p, Vec_Int_t * vCands );
......@@ -118,8 +113,10 @@ extern void Llb_ManPrintEntries( Aig_Man_t * p, Vec_Int_t * vCands );
extern int Llb_ManModelCheckAig( Aig_Man_t * pAigGlo, Gia_ParLlb_t * pPars, Vec_Int_t * vHints, DdManager ** pddGlo );
/*=== llbCluster.c ======================================================*/
extern void Llb_ManCluster( Llb_Mtr_t * p );
/*=== llbDump.c ======================================================*/
extern void Llb_ManDumpReached( DdManager * ddG, DdNode * bReached, char * pModel, char * pFileName );
/*=== llbFlow.c ======================================================*/
extern Llb_Man_t * Llb_ManStartFlow( Aig_Man_t * pAigGlo, Aig_Man_t * pAig, Gia_ParLlb_t * pPars );
extern Vec_Ptr_t * Llb_ManFlow( Aig_Man_t * p, Vec_Ptr_t * vSources, int * pnFlow );
/*=== llbHint.c ======================================================*/
extern int Llb_ManReachabilityWithHints( Llb_Man_t * p );
extern int Llb_ManModelCheckAigWithHints( Aig_Man_t * pAigGlo, Gia_ParLlb_t * pPars );
......@@ -148,7 +145,30 @@ extern int Llb_ManReachability( Llb_Man_t * p, Vec_Int_t * vHints, D
/*=== llbSched.c =====================================================*/
extern void Llb_MtrSchedule( Llb_Mtr_t * p );
/*=== llb2Bad.c ======================================================*/
extern DdNode * Llb_BddComputeBad( Aig_Man_t * pInit, DdManager * dd );
extern DdNode * Llb_BddQuantifyPis( Aig_Man_t * pInit, DdManager * dd, DdNode * bFunc );
/*=== llb2Core.c ======================================================*/
extern DdNode * Llb_CoreComputeCube( DdManager * dd, Vec_Int_t * vVars, int fUseVarIndex, char * pValues );
/*=== llb2Driver.c ======================================================*/
extern Vec_Int_t * Llb_DriverCountRefs( Aig_Man_t * p );
extern Vec_Int_t * Llb_DriverCollectNs( Aig_Man_t * pAig, Vec_Int_t * vDriRefs );
extern Vec_Int_t * Llb_DriverCollectCs( Aig_Man_t * pAig );
extern DdNode * Llb_DriverPhaseCube( Aig_Man_t * pAig, Vec_Int_t * vDriRefs, DdManager * dd );
extern DdManager * Llb_DriverLastPartition( Aig_Man_t * p, Vec_Int_t * vVarsNs );
/*=== llb2Image.c ======================================================*/
extern Vec_Ptr_t * Llb_ImgSupports( Aig_Man_t * p, Vec_Ptr_t * vDdMans, Vec_Int_t * vStart, Vec_Int_t * vStop, int fAddPis, int fVerbose );
extern void Llb_ImgSchedule( Vec_Ptr_t * vSupps, Vec_Ptr_t ** pvQuant0, Vec_Ptr_t ** pvQuant1, int fVerbose );
extern DdManager * Llb_ImgPartition( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper );
extern void Llb_ImgQuantifyFirst( Aig_Man_t * pAig, Vec_Ptr_t * vDdMans, Vec_Ptr_t * vQuant0, int fVerbose );
extern void Llb_ImgQuantifyReset( Vec_Ptr_t * vDdMans );
extern DdNode * Llb_ImgComputeImage( Aig_Man_t * pAig, Vec_Ptr_t * vDdMans, DdManager * dd, DdNode * bInit,
Vec_Ptr_t * vQuant0, Vec_Ptr_t * vQuant1, Vec_Int_t * vDriRefs,
int TimeTarget, int fBackward, int fReorder, int fVerbose );
/*=== llb3Image.c ======================================================*/
extern DdNode * Llb_NonlinImage( Aig_Man_t * pAig, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int * pVars2Q,
DdManager * dd, DdNode * bCurrent, int fReorder, int fVerbose, int * pOrder, int Limit );
ABC_NAMESPACE_HEADER_END
......
SRC += src/aig/llb/llbCex.c \
src/aig/llb/llbCluster.c \
src/aig/llb/llbConstr.c \
src/aig/llb/llbCore.c \
src/aig/llb/llbHint.c \
src/aig/llb/llbMan.c \
src/aig/llb/llbMatrix.c \
src/aig/llb/llbPart.c \
src/aig/llb/llbPivot.c \
src/aig/llb/llbReach.c \
src/aig/llb/llbSched.c
SRC += src/aig/llb/llb.c \
src/aig/llb/llb1Cluster.c \
src/aig/llb/llb1Constr.c \
src/aig/llb/llb1Core.c \
src/aig/llb/llb1Group.c \
src/aig/llb/llb1Hint.c \
src/aig/llb/llb1Man.c \
src/aig/llb/llb1Matrix.c \
src/aig/llb/llb1Pivot.c \
src/aig/llb/llb1Reach.c \
src/aig/llb/llb1Sched.c \
src/aig/llb/llb2Bad.c \
src/aig/llb/llb2Core.c \
src/aig/llb/llb2Driver.c \
src/aig/llb/llb2Dump.c \
src/aig/llb/llb2Flow.c \
src/aig/llb/llb2Image.c \
src/aig/llb/llb3Image.c \
src/aig/llb/llb3Nonlin.c
......@@ -99,7 +99,7 @@ Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose
Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pNode, i )
Vec_PtrWriteEntry( vNodes, i, pNode->pCopy );
Nwk_ManFree( pNtk );
assert( Vec_PtrSize(vNodes) <= Aig_ManRegNum(p) );
// assert( Vec_PtrSize(vNodes) <= Aig_ManRegNum(p) );
return vNodes;
}
......
......@@ -22,6 +22,7 @@
#include "ssw.h"
#include "fra.h"
#include "bbr.h"
#include "pdr.h"
ABC_NAMESPACE_IMPL_START
......@@ -173,15 +174,32 @@ Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlo
{
extern int Saig_BmcPerform( Aig_Man_t * pAig, int nStart, int nFramesMax, int nNodesMax, int nTimeOut, int nConfMaxOne, int nConfMaxAll, int fVerbose, int fVerbOverwrite, int * piFrames );
Vec_Int_t * vFlopsNew;
int i, Entry;
int i, Entry, RetValue;
*piRetValue = -1;
if ( fUseDprove && Aig_ManRegNum(pAbs) > 0 )
{
/*
Fra_Sec_t SecPar, * pSecPar = &SecPar;
int RetValue;
Fra_SecSetDefaultParams( pSecPar );
pSecPar->fVerbose = fVerbose;
RetValue = Fra_FraigSec( pAbs, pSecPar, NULL );
*/
Abc_Cex_t * pCex = NULL;
Aig_Man_t * pAbsOrpos = Saig_ManDupOrpos( pAbs );
Pdr_Par_t Pars, * pPars = &Pars;
Pdr_ManSetDefaultParams( pPars );
pPars->nTimeOut = 10;
pPars->fVerbose = fVerbose;
if ( pPars->fVerbose )
printf( "Running property directed reachability...\n" );
RetValue = Pdr_ManSolve( pAbsOrpos, pPars, &pCex );
if ( pCex )
pCex->iPo = Ssw_SmlFindOutputCounterExample( pAbs, pCex );
Aig_ManStop( pAbsOrpos );
pAbs->pSeqModel = pCex;
if ( RetValue )
*piRetValue = 1;
}
else if ( fUseBdds && (Aig_ManRegNum(pAbs) > 0 && Aig_ManRegNum(pAbs) <= 80) )
{
......@@ -195,7 +213,9 @@ Aig_Man_t * Saig_ManCexRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlo
pPars->fReorderImage = 1;
pPars->fVerbose = fVerbose;
pPars->fSilent = 0;
Aig_ManVerifyUsingBdds( pAbs, pPars );
RetValue = Aig_ManVerifyUsingBdds( pAbs, pPars );
if ( RetValue )
*piRetValue = 1;
}
else
{
......
......@@ -222,7 +222,7 @@ int Saig_TsiStateHash( unsigned * pState, int nWords, int nTableSize )
SeeAlso []
***********************************************************************/
int Saig_TsiCountNonXValuedRegisters( Saig_Tsim_t * p, int nWords, int nPref )
int Saig_TsiCountNonXValuedRegisters( Saig_Tsim_t * p, int nPref )
{
unsigned * pState;
int nRegs = p->pAig->nRegs;
......@@ -246,6 +246,53 @@ int Saig_TsiCountNonXValuedRegisters( Saig_Tsim_t * p, int nWords, int nPref )
/**Function*************************************************************
Synopsis [Computes flops that are stuck-at constant.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Saig_TsiComputeTransient( Saig_Tsim_t * p, int nPref )
{
Vec_Int_t * vCounters;
unsigned * pState;
int ValueThis, ValuePrev = -1, StepPrev = -1;
int i, k, nRegs = p->pAig->nRegs;
vCounters = Vec_IntStart( nPref );
for ( i = 0; i < nRegs; i++ )
{
Vec_PtrForEachEntry( unsigned *, p->vStates, pState, k )
{
ValueThis = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i );
//printf( "%s", (ValueThis == 1)? "0" : ((ValueThis == 2)? "1" : "x") );
assert( ValueThis != 0 );
if ( ValuePrev != ValueThis )
{
ValuePrev = ValueThis;
StepPrev = k;
}
}
//printf( "\n" );
if ( ValueThis == SAIG_XVSX )
continue;
if ( StepPrev >= nPref )
continue;
Vec_IntAddToEntry( vCounters, StepPrev, 1 );
}
Vec_IntForEachEntry( vCounters, ValueThis, i )
{
if ( ValueThis == 0 )
continue;
// printf( "%3d : %3d\n", i, ValueThis );
}
return vCounters;
}
/**Function*************************************************************
Synopsis [Count non-X-valued registers in the simulation data.]
Description []
......@@ -821,7 +868,7 @@ int Saig_ManPhaseFrameNum( Aig_Man_t * p, Vec_Int_t * vInits )
SeeAlso []
***********************************************************************/
int Saig_ManPhasePrefixLength( Aig_Man_t * p, int fVerbose, int fVeryVerbose )
int Saig_ManPhasePrefixLength( Aig_Man_t * p, int fVerbose, int fVeryVerbose, Vec_Int_t ** pvTrans )
{
Saig_Tsim_t * pTsi;
int nFrames, nPrefix, nNonXRegs;
......@@ -835,7 +882,11 @@ int Saig_ManPhasePrefixLength( Aig_Man_t * p, int fVerbose, int fVeryVerbose )
// derive information
nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords );
nFrames = Vec_PtrSize(pTsi->vStates) - 1 - nPrefix;
nNonXRegs = Saig_TsiCountNonXValuedRegisters( pTsi, pTsi->nWords, nPrefix );
nNonXRegs = Saig_TsiCountNonXValuedRegisters( pTsi, nPrefix );
if ( pvTrans )
*pvTrans = Saig_TsiComputeTransient( pTsi, nPrefix );
// print statistics
if ( fVerbose )
printf( "Lead = %5d. Loop = %5d. Total flops = %5d. Binary flops = %5d.\n", nPrefix, nFrames, p->nRegs, nNonXRegs );
......@@ -871,7 +922,7 @@ Aig_Man_t * Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrame
// derive information
pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords );
pTsi->nCycle = Vec_PtrSize(pTsi->vStates) - 1 - pTsi->nPrefix;
pTsi->nNonXRegs = Saig_TsiCountNonXValuedRegisters(pTsi, pTsi->nWords, ABC_MIN(pTsi->nPrefix,nPref));
pTsi->nNonXRegs = Saig_TsiCountNonXValuedRegisters(pTsi, ABC_MIN(pTsi->nPrefix,nPref));
// print statistics
if ( fVerbose )
{
......@@ -927,7 +978,7 @@ Aig_Man_t * Saig_ManPhaseAbstractAuto( Aig_Man_t * p, int fVerbose )
// derive information
pTsi->nPrefix = Saig_TsiComputePrefix( pTsi, (unsigned *)Vec_PtrEntryLast(pTsi->vStates), pTsi->nWords );
pTsi->nCycle = Vec_PtrSize(pTsi->vStates) - 1 - pTsi->nPrefix;
pTsi->nNonXRegs = Saig_TsiCountNonXValuedRegisters(pTsi, pTsi->nWords, 0);
pTsi->nNonXRegs = Saig_TsiCountNonXValuedRegisters(pTsi, 0);
// print statistics
if ( fVerbose )
{
......
......@@ -147,6 +147,32 @@ Aig_Man_t * Saig_ManTemporDecompose( Aig_Man_t * pAig, int nFrames )
/**Function*************************************************************
Synopsis [Find index of first non-zero entry.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Vec_IntLastNonZeroBeforeLimit( Vec_Int_t * vTemp, int Limit )
{
int Entry, i;
if ( vTemp == NULL )
return -1;
Vec_IntForEachEntryReverse( vTemp, Entry, i )
{
if ( i >= Limit )
continue;
if ( Entry )
return i;
}
return -1;
}
/**Function*************************************************************
Synopsis []
Description []
......@@ -156,19 +182,33 @@ Aig_Man_t * Saig_ManTemporDecompose( Aig_Man_t * pAig, int nFrames )
SeeAlso []
***********************************************************************/
Aig_Man_t * Saig_ManTempor( Aig_Man_t * pAig, int nFrames, int TimeOut, int nConfLimit, int fUseBmc, int fVerbose, int fVeryVerbose )
Aig_Man_t * Saig_ManTempor( Aig_Man_t * pAig, int nFrames, int TimeOut, int nConfLimit, int fUseBmc, int fUseTransSigs, int fVerbose, int fVeryVerbose )
{
extern int Saig_ManPhasePrefixLength( Aig_Man_t * p, int fVerbose, int fVeryVerbose );
extern int Saig_ManPhasePrefixLength( Aig_Man_t * p, int fVerbose, int fVeryVerbose, Vec_Int_t ** pvTrans );
Vec_Int_t * vTransSigs = NULL;
int RetValue, nFramesFinished = -1;
assert( nFrames >= 0 );
if ( nFrames == 0 )
{
nFrames = Saig_ManPhasePrefixLength( pAig, fVerbose, fVeryVerbose );
nFrames = Saig_ManPhasePrefixLength( pAig, fVerbose, fVeryVerbose, &vTransSigs );
if ( nFrames == 1 )
{
Vec_IntFreeP( &vTransSigs );
printf( "The leading sequence has length 1. Temporal decomposition is not performed.\n" );
return NULL;
}
if ( fUseTransSigs )
{
int Entry, i, iLast = -1;
Vec_IntForEachEntry( vTransSigs, Entry, i )
iLast = Entry ? i :iLast;
if ( iLast > 0 && iLast < nFrames )
{
Abc_Print( 1, "Reducing frame count from %d to %d to fit the last transient.\n", nFrames, iLast );
nFrames = iLast;
}
}
Abc_Print( 1, "Using computed frame number (%d).\n", nFrames );
}
else
......@@ -176,18 +216,27 @@ Aig_Man_t * Saig_ManTempor( Aig_Man_t * pAig, int nFrames, int TimeOut, int nCon
// run BMC2
if ( fUseBmc )
{
RetValue = Saig_BmcPerform( pAig, 0, nFrames, 5000, TimeOut, nConfLimit, 0, fVerbose, 0, &nFramesFinished );
RetValue = Saig_BmcPerform( pAig, 0, nFrames, 2000, TimeOut, nConfLimit, 0, fVerbose, 0, &nFramesFinished );
if ( RetValue == 0 )
{
Vec_IntFreeP( &vTransSigs );
printf( "A cex found in the first %d frames.\n", nFrames );
return NULL;
}
if ( nFramesFinished < nFrames )
{
int iLastBefore = Vec_IntLastNonZeroBeforeLimit( vTransSigs, nFramesFinished );
if ( iLastBefore < 1 || !fUseTransSigs )
{
Vec_IntFreeP( &vTransSigs );
printf( "BMC for %d frames could not be completed. A cex may exist!\n", nFrames );
return NULL;
}
assert( iLastBefore < nFramesFinished );
printf( "BMC succeeded to frame %d. Adjusting frame count to be (%d) based on the last transient signal.\n", nFramesFinished, iLastBefore );
}
}
Vec_IntFreeP( &vTransSigs );
return Saig_ManTemporDecompose( pAig, nFrames );
}
......
......@@ -2940,15 +2940,15 @@ Abc_Ntk_t * Abc_NtkDarEnlarge( Abc_Ntk_t * pNtk, int nFrames, int fVerbose )
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDarTempor( Abc_Ntk_t * pNtk, int nFrames, int TimeOut, int nConfLimit, int fUseBmc, int fVerbose, int fVeryVerbose )
Abc_Ntk_t * Abc_NtkDarTempor( Abc_Ntk_t * pNtk, int nFrames, int TimeOut, int nConfLimit, int fUseBmc, int fUseTransSigs, int fVerbose, int fVeryVerbose )
{
extern Aig_Man_t * Saig_ManTempor( Aig_Man_t * pAig, int nFrames, int TimeOut, int nConfLimit, int fUseBmc, int fVerbose, int fVeryVerbose );
extern Aig_Man_t * Saig_ManTempor( Aig_Man_t * pAig, int nFrames, int TimeOut, int nConfLimit, int fUseBmc, int fUseTransSigs, int fVerbose, int fVeryVerbose );
Abc_Ntk_t * pNtkAig;
Aig_Man_t * pMan, * pTemp;
pMan = Abc_NtkToDar( pNtk, 0, 1 );
if ( pMan == NULL )
return NULL;
pTemp = Saig_ManTempor( pMan, nFrames, TimeOut, nConfLimit, fUseBmc, fVerbose, fVeryVerbose );
pTemp = Saig_ManTempor( pMan, nFrames, TimeOut, nConfLimit, fUseBmc, fUseTransSigs, fVerbose, fVeryVerbose );
Aig_ManStop( pMan );
if ( pTemp == NULL )
return Abc_NtkDup( pNtk );
......@@ -3937,11 +3937,13 @@ void Abc_NtkDarConstrProfile( Abc_Ntk_t * pNtk, int fVerbose )
SeeAlso []
***********************************************************************/
void Abc_NtkDarTest( Abc_Ntk_t * pNtk )
void Abc_NtkDarTest( Abc_Ntk_t * pNtk, int Num )
{
// extern void Saig_ManDetectConstr( Aig_Man_t * p );
// extern void Saig_ManDetectConstrFuncTest( Aig_Man_t * p );
extern void Saig_ManFoldConstrTest( Aig_Man_t * pAig );
// extern void Saig_ManFoldConstrTest( Aig_Man_t * pAig );
extern void Llb_ManComputeDomsTest( Aig_Man_t * pAig, int Num );
// extern void Fsim_ManTest( Aig_Man_t * pAig );
......@@ -3992,6 +3994,15 @@ Aig_ManPrintStats( pMan );
// Pdr_ManEquivClasses( pMan );
}
// Llb_ManComputeDomsTest( pMan, Num );
{
extern void Llb_ManMinCutTest( Aig_Man_t * pMan, int Num );
extern void Llb_BddStructAnalysis( Aig_Man_t * pMan );
extern void Llb_NonlinExperiment( Aig_Man_t * pAig, int Num );
// Llb_BddStructAnalysis( pMan );
Llb_ManMinCutTest( pMan, Num );
// Llb_NonlinExperiment( pMan, Num );
}
// Saig_MvManSimulate( pMan, 1 );
// Saig_ManDetectConstr( pMan );
......
......@@ -720,6 +720,7 @@ EXTERN DdNode * Cudd_addRoundOff ARGS((DdManager *dd, DdNode *f, int N));
EXTERN DdNode * Cudd_addWalsh ARGS((DdManager *dd, DdNode **x, DdNode **y, int n));
EXTERN DdNode * Cudd_addResidue ARGS((DdManager *dd, int n, int m, int options, int top));
EXTERN DdNode * Cudd_bddAndAbstract ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube));
EXTERN DdNode * Cudd_bddAndAbstractLimit ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit));
EXTERN int Cudd_ApaNumberOfDigits ARGS((int binaryDigits));
EXTERN DdApaNumber Cudd_NewApaNumber ARGS((int digits));
EXTERN void Cudd_ApaCopy ARGS((int digits, DdApaNumber source, DdApaNumber dest));
......
......@@ -109,6 +109,46 @@ Cudd_bddAndAbstract(
} /* end of Cudd_bddAndAbstract */
/**Function********************************************************************
Synopsis [Takes the AND of two BDDs and simultaneously abstracts the
variables in cube. Returns NULL if too many nodes are required.]
Description [Takes the AND of two BDDs and simultaneously abstracts
the variables in cube. The variables are existentially abstracted.
Returns a pointer to the result is successful; NULL otherwise.
In particular, if the number of new nodes created exceeds
<code>limit</code>, this function returns NULL.]
SideEffects [None]
SeeAlso [Cudd_bddAndAbstract]
******************************************************************************/
DdNode *
Cudd_bddAndAbstractLimit(
DdManager * manager,
DdNode * f,
DdNode * g,
DdNode * cube,
unsigned int limit)
{
DdNode *res;
unsigned int saveLimit = manager->maxLive;
manager->maxLive = (manager->keys - manager->dead) +
(manager->keysZ - manager->deadZ) + limit;
do {
manager->reordered = 0;
res = cuddBddAndAbstractRecur(manager, f, g, cube);
} while (manager->reordered == 1);
manager->maxLive = saveLimit;
return(res);
} /* end of Cudd_bddAndAbstractLimit */
/*---------------------------------------------------------------------------*/
/* Definition of internal functions */
/*---------------------------------------------------------------------------*/
......
......@@ -174,7 +174,8 @@ Cudd_Init(
unique->memused += sizeof(DdNode *) * unique->maxSize;
unique->bReached = NULL;
unique->bFunc = NULL;
unique->bFunc2 = NULL;
return(unique);
} /* end of Cudd_Init */
......
......@@ -439,7 +439,8 @@ struct DdManager { /* specialized DD symbol table */
int nvars; /* variables used so far */
int threshold; /* for pseudo var threshold value*/
#endif
DdNode * bReached;
DdNode * bFunc;
DdNode * bFunc2;
};
typedef struct Move {
......
......@@ -196,6 +196,8 @@ extern DdNode * Extra_bddCreateExor( DdManager * dd, int nVars );
extern DdNode * Extra_zddPrimes( DdManager * dd, DdNode * F );
extern void Extra_bddPermuteArray( DdManager * dd, DdNode ** bNodesIn, DdNode ** bNodesOut, int nNodes, int *permut );
extern DdNode * Extra_bddComputeCube( DdManager * dd, DdNode ** bXVars, int nVars );
extern DdNode * Extra_bddChangePolarity( DdManager * dd, DdNode * bFunc, DdNode * bVars );
extern DdNode * extraBddChangePolarity( DdManager * dd, DdNode * bFunc, DdNode * bVars );
#ifndef ABC_PRB
#define ABC_PRB(dd,f) printf("%s = ", #f); Extra_bddPrint(dd,f); printf("\n")
......
......@@ -1013,6 +1013,32 @@ DdNode * Extra_bddComputeCube( DdManager * dd, DdNode ** bXVars, int nVars )
return bRes;
}
/**Function********************************************************************
Synopsis [Changes the polarity of vars listed in the cube.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
DdNode * Extra_bddChangePolarity(
DdManager * dd, /* the DD manager */
DdNode * bFunc,
DdNode * bVars)
{
DdNode *res;
do {
dd->reordered = 0;
res = extraBddChangePolarity( dd, bFunc, bVars );
} while (dd->reordered == 1);
return(res);
} /* end of Extra_bddChangePolarity */
/*---------------------------------------------------------------------------*/
/* Definition of internal functions */
/*---------------------------------------------------------------------------*/
......@@ -1659,6 +1685,121 @@ cuddBddPermuteRecur( DdManager * manager /* DD manager */ ,
} /* end of cuddBddPermuteRecur */
/**Function********************************************************************
Synopsis [Performs the reordering-sensitive step of Extra_bddChangePolarity().]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
DdNode * extraBddChangePolarity(
DdManager * dd, /* the DD manager */
DdNode * bFunc,
DdNode * bVars)
{
DdNode * bRes;
if ( bVars == b1 )
return bFunc;
if ( Cudd_IsConstant(bFunc) )
return bFunc;
if ( bRes = cuddCacheLookup2(dd, extraBddChangePolarity, bFunc, bVars) )
return bRes;
else
{
DdNode * bFR = Cudd_Regular(bFunc);
int LevelF = dd->perm[bFR->index];
int LevelV = dd->perm[bVars->index];
if ( LevelV < LevelF )
bRes = extraBddChangePolarity( dd, bFunc, cuddT(bVars) );
else // if ( LevelF <= LevelV )
{
DdNode * bRes0, * bRes1;
DdNode * bF0, * bF1;
DdNode * bVarsNext;
// cofactor the functions
if ( bFR != bFunc ) // bFunc is complemented
{
bF0 = Cudd_Not( cuddE(bFR) );
bF1 = Cudd_Not( cuddT(bFR) );
}
else
{
bF0 = cuddE(bFR);
bF1 = cuddT(bFR);
}
if ( LevelF == LevelV )
bVarsNext = cuddT(bVars);
else
bVarsNext = bVars;
bRes0 = extraBddChangePolarity( dd, bF0, bVarsNext );
if ( bRes0 == NULL )
return NULL;
cuddRef( bRes0 );
bRes1 = extraBddChangePolarity( dd, bF1, bVarsNext );
if ( bRes1 == NULL )
{
Cudd_RecursiveDeref( dd, bRes0 );
return NULL;
}
cuddRef( bRes1 );
if ( LevelF == LevelV )
{ // swap the cofactors
DdNode * bTemp;
bTemp = bRes0;
bRes0 = bRes1;
bRes1 = bTemp;
}
/* only aRes0 and aRes1 are referenced at this point */
/* consider the case when Res0 and Res1 are the same node */
if ( bRes0 == bRes1 )
bRes = bRes1;
/* consider the case when Res1 is complemented */
else if ( Cudd_IsComplement(bRes1) )
{
bRes = cuddUniqueInter(dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0));
if ( bRes == NULL )
{
Cudd_RecursiveDeref(dd,bRes0);
Cudd_RecursiveDeref(dd,bRes1);
return NULL;
}
bRes = Cudd_Not(bRes);
}
else
{
bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
if ( bRes == NULL )
{
Cudd_RecursiveDeref(dd,bRes0);
Cudd_RecursiveDeref(dd,bRes1);
return NULL;
}
}
cuddDeref( bRes0 );
cuddDeref( bRes1 );
}
/* insert the result into cache */
cuddCacheInsert2(dd, extraBddChangePolarity, bFunc, bVars, bRes);
return bRes;
}
} /* end of extraBddChangePolarity */
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -311,14 +311,15 @@ static inline void Hash_FltRemove( Hash_Flt_t *p, int key )
***********************************************************************/
static inline void Hash_FltFree( Hash_Flt_t *p ) {
int bin;
Hash_Flt_Entry_t *pEntry;
Hash_Flt_Entry_t *pEntry, *pTemp;
// free bins
for(bin = 0; bin < p->nBins; bin++) {
pEntry = p->pArray[bin];
while(pEntry) {
pTemp = pEntry;
pEntry = pEntry->pNext;
ABC_FREE( pEntry );
ABC_FREE( pTemp );
}
}
......
/**CFile****************************************************************
FileName [vecGen.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hash maps.]
Synopsis [Hash maps.]
Author [Aaron P. Hurst, Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - Jan 26, 2011.]
Revision [$Id: vecGen.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $]
***********************************************************************/
#ifndef __HASH_GEN_H__
#define __HASH_GEN_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "extra.h"
ABC_NAMESPACE_HEADER_START
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Hash_Gen_t_ Hash_Gen_t;
typedef struct Hash_Gen_Entry_t_ Hash_Gen_Entry_t;
struct Hash_Gen_Entry_t_
{
char * key;
void * data;
struct Hash_Gen_Entry_t_ * pNext;
};
struct Hash_Gen_t_
{
int nSize;
int nBins;
int (* fHash)(void * key, int nBins);
int (* fComp)(void * key, void * key);
Hash_Gen_Entry_t ** pArray;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define Hash_GenForEachEntry( pHash, pEntry, bin ) \
for(bin=-1, pEntry=NULL; bin < pHash->nBins; (!pEntry)?(pEntry=pHash->pArray[++bin]):(pEntry=pEntry->pNext)) \
if (pEntry)
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Default hash function for strings.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static int Hash_DefaultHashFuncStr( void * key, int nBins )
{
int i, Value = 0;
if ( key[0] == 0 )
return 0;
for ( i = strlen(key)-1; i >= 0; i-- )
Value = 5 * Value + key[i];
return Value % nBins;
}
/**Function*************************************************************
Synopsis [Allocates a hash map with the given number of bins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Hash_Gen_t * Hash_GenAlloc(
int nBins,
int (*Hash_FuncHash)(void *, int),
int (*Hash_FuncComp)(void *, void *) )
{
Hash_Gen_t * p;
int i;
assert(nBins > 0);
p = ABC_CALLOC( Hash_Gen_t, 1 );
p->nBins = nBins;
p->fHash = Hash_FuncHash? Hash_FuncHash : (int (*)(void *, int))Hash_DefaultHashFuncStr;
p->fComp = Hash_FuncComp? Hash_FuncComp : (int (*)(void *, void *))strcmp;
p->nSize = 0;
p->pArray = ABC_CALLOC( Hash_Gen_Entry_t *, nBins );
return p;
}
/**Function*************************************************************
Synopsis [Returns 1 if a key already exists.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Hash_GenExists( Hash_Gen_t *p, void * key )
{
int bin;
Hash_Gen_Entry_t *pEntry;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pEntry = p->pArray[bin];
while(pEntry) {
if ( !p->fComp(pEntry->key,key) ) {
return 1;
}
pEntry = pEntry->pNext;
}
return 0;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key and writes value.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_GenWriteEntry( Hash_Gen_t *p, void * key, void * data )
{
int bin;
Hash_Gen_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if ( !p->fComp(pEntry->key,key) ) {
pEntry->data = data;
return;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ABC_ALLOC( Hash_Gen_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = data;
return;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key.]
Description [fCreate specifies whether a new entry should be created.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void * Hash_GenEntry( Hash_Gen_t *p, void * key, int fCreate )
{
int bin;
Hash_Gen_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if ( !p->fComp(pEntry->key,key) )
return pEntry->data;
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
if (fCreate) {
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ABC_ALLOC( Hash_Gen_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = NULL;
return pEntry->data;
}
return NULL;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key and returns the pointer to it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void** Hash_GenEntryPtr( Hash_Gen_t *p, void * key )
{
int bin;
Hash_Gen_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if ( !p->fComp(pEntry->key,key) )
return &(pEntry->data);
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ABC_ALLOC( Hash_Gen_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = NULL;
return &(pEntry->data);
}
/**Function*************************************************************
Synopsis [Deletes an entry.]
Description [Returns data, if there was any.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void* Hash_GenRemove( Hash_Gen_t *p, void * key )
{
int bin;
void * data;
Hash_Gen_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if ( !p->fComp(pEntry->key,key) ) {
p->nSize--;
data = pEntry->data;
*pLast = pEntry->pNext;
return data;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// could not find key
return NULL;
}
/**Function*************************************************************
Synopsis [Frees the hash.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_GenFree( Hash_Gen_t *p )
{
int bin;
Hash_Gen_Entry_t *pEntry, *pTemp;
// free bins
for(bin = 0; bin < p->nBins; bin++) {
pEntry = p->pArray[bin];
while(pEntry) {
pTemp = pEntry;
pEntry = pEntry->pNext;
ABC_FREE( pTemp );
}
}
// free hash
ABC_FREE( p->pArray );
ABC_FREE( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_HEADER_END
#endif
......@@ -115,19 +115,17 @@ static inline Hash_Ptr_t * Hash_PtrAlloc( int nBins )
static inline int Hash_PtrExists( Hash_Ptr_t *p, int key )
{
int bin;
Hash_Ptr_Entry_t *pEntry, **pLast;
Hash_Ptr_Entry_t *pEntry;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
return 1;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
......@@ -310,16 +308,18 @@ static inline void* Hash_PtrRemove( Hash_Ptr_t *p, int key )
SeeAlso []
***********************************************************************/
static inline void Hash_PtrFree( Hash_Ptr_t *p ) {
static inline void Hash_PtrFree( Hash_Ptr_t *p )
{
int bin;
Hash_Ptr_Entry_t *pEntry;
Hash_Ptr_Entry_t *pEntry, *pTemp;
// free bins
for(bin = 0; bin < p->nBins; bin++) {
pEntry = p->pArray[bin];
while(pEntry) {
pTemp = pEntry;
pEntry = pEntry->pNext;
ABC_FREE( pEntry );
ABC_FREE( pTemp );
}
}
......
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