summaryrefslogtreecommitdiffstats
path: root/src/base
diff options
context:
space:
mode:
authorMathias Soeken <mathias.soeken@gmail.com>2017-02-22 19:00:28 -0800
committerMathias Soeken <mathias.soeken@gmail.com>2017-02-22 19:00:28 -0800
commit28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e (patch)
tree6b7962dc72653e3bf615c5901854774eca9d23c8 /src/base
parent5af44731bff0061c724912cf76e86dddbb4f2c7a (diff)
parentdd8cc7e9a27e2bd962d612911c6fd9508c6c1e0d (diff)
downloadabc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.tar.gz
abc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.tar.bz2
abc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.zip
Merged alanmi/abc into default
Diffstat (limited to 'src/base')
-rw-r--r--src/base/abc/abcUtil.c161
-rw-r--r--src/base/abci/abc.c1059
-rw-r--r--src/base/abci/abcCollapse.c4
-rw-r--r--src/base/abci/abcDar.c12
-rw-r--r--src/base/abci/abcDetect.c3
-rw-r--r--src/base/abci/abcDress3.c30
-rw-r--r--src/base/abci/abcExact.c2
-rw-r--r--src/base/abci/abcMfs.c2
-rw-r--r--src/base/abci/abcVerify.c14
-rw-r--r--src/base/cmd/cmd.c135
-rw-r--r--src/base/cmd/cmdAuto.c684
-rw-r--r--src/base/cmd/cmdLoad.c21
-rw-r--r--src/base/cmd/module.make1
-rw-r--r--src/base/io/io.c4
-rw-r--r--src/base/io/ioWriteDot.c4
-rw-r--r--src/base/main/mainFrame.c4
-rw-r--r--src/base/main/mainInt.h2
-rw-r--r--src/base/main/mainReal.c4
-rw-r--r--src/base/wlc/module.make3
-rw-r--r--src/base/wlc/wlc.h58
-rw-r--r--src/base/wlc/wlcAbc.c181
-rw-r--r--src/base/wlc/wlcAbs.c701
-rw-r--r--src/base/wlc/wlcAbs2.c410
-rw-r--r--src/base/wlc/wlcBlast.c51
-rw-r--r--src/base/wlc/wlcCom.c949
-rw-r--r--src/base/wlc/wlcNtk.c570
-rw-r--r--src/base/wlc/wlcReadSmt.c336
-rw-r--r--src/base/wlc/wlcReadVer.c5
-rw-r--r--src/base/wlc/wlcShow.c337
-rw-r--r--src/base/wlc/wlcSim.c22
-rw-r--r--src/base/wlc/wlcUif.c290
-rw-r--r--src/base/wlc/wlcWriteVer.c2
32 files changed, 5301 insertions, 760 deletions
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index f01ef07a..77b55bb3 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -1077,6 +1077,7 @@ void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate )
***********************************************************************/
int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
{
+ int fAddBuffers = 1;
Vec_Ptr_t * vDrivers, * vCoTerms;
Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
int i, k, LevelMax, nTotal = 0;
@@ -1191,6 +1192,12 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
// collect COs that needs fixing by adding buffers or duplicating
vCoTerms = Vec_PtrAlloc( 100 );
Abc_NtkIncrementTravId( pNtk );
+
+ // The following cases should be addressed only if the network is written
+ // into a BLIF file. Otherwise, it is possible to skip them:
+ // (1) if a CO points to a CI with a different name
+ // (2) if an internal node drives more than one CO
+ if ( fAddBuffers )
Abc_NtkForEachCo( pNtk, pNode, i )
{
// if the driver is a CI and has different name, this is an error
@@ -2926,6 +2933,160 @@ void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
Vec_IntWriteEntry( pNtkNew->vPhases, Abc_ObjId( (Abc_Obj_t *)pObj->pCopy ), Vec_IntEntry(pNtk->vPhases, i) );
}
+/**Function*************************************************************
+
+ Synopsis [Starts a new network using existing network as a model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkDeriveWithOnePo( Abc_Ntk_t * pNtk, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues )
+{
+ int fCopyNames = 1;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pFanin, * pObjNew, * pOutputNew;
+ Vec_Ptr_t * vFanins = Vec_PtrAlloc( 100 );
+ int i, k, Id, Value;
+ // start the network
+ pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
+ // duplicate the name and the spec
+ pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
+ pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
+ // clean the node copy fields
+ Abc_NtkCleanCopy( pNtk );
+ // map the constant nodes
+ if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
+ Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
+ // clone CIs/CIs/boxes
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NtkDupObj( pNtkNew, pObj, fCopyNames );
+ //Abc_NtkForEachPo( pNtk, pObj, i )
+ // Abc_NtkDupObj( pNtkNew, pObj, fCopyNames );
+ // create one PO
+ pObjNew = Abc_NtkCreateObj( pNtkNew, ABC_OBJ_PO );
+ Abc_ObjAssignName( pObjNew, "monitor", NULL );
+ // create boxes
+ Abc_NtkForEachBox( pNtk, pObj, i )
+ Abc_NtkDupBox( pNtkNew, pObj, fCopyNames );
+
+ // duplicate nodes (CIs/COs/latches are already duplicated)
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ if ( pObj->pCopy == NULL && !Abc_ObjIsPo(pObj) )
+ Abc_NtkDupObj(pNtkNew, pObj, 0);
+ // reconnect all objects except boxes (they are already connected) and POs (they will be connected later)
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ if ( !Abc_ObjIsPo(pObj) && !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
+
+ // AND nodes (with interters if needed)
+ pOutputNew = NULL;
+ Vec_IntForEachEntryTwo( vNodeIds, vNodeValues, Id, Value, i )
+ {
+ pObjNew = Abc_NtkObj( pNtk, Id )->pCopy;
+ if ( Value == 0 ) // negative polarity - add inverter
+ pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew );
+ if ( pOutputNew == NULL )
+ pOutputNew = pObjNew;
+ else
+ {
+ Vec_PtrFillTwo( vFanins, 2, pOutputNew, pObjNew );
+ pOutputNew = Abc_NtkCreateNodeAnd( pNtkNew, vFanins );
+ }
+ }
+ Vec_PtrFree( vFanins );
+ // create the only POs, which is the AND of the corresponding nodes
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkNew, 0), pOutputNew );
+
+ // check that the CI/CO/latches are copied correctly
+ assert( Abc_NtkPoNum(pNtkNew) == 1 );
+ assert( Abc_NtkCiNum(pNtkNew) == Abc_NtkCiNum(pNtk) );
+ assert( Abc_NtkLatchNum(pNtkNew) == Abc_NtkLatchNum(pNtk) );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the AIG representing a property.]
+
+ Description [Given is a sequential logic network (Abc_Ntk_t) and
+ an array of nodes (vector of object IDs) and their values (vector of 0s or 1s).
+ This procedure creates a sequential AIG (Abc_Ntk_t), which can be given to a
+ sequential model checker (in particular "pdr") to prove that the given
+ combination of values never appears at the intenal nodes of the network,
+ or produce a counter-example showing that it can appear.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCreatePropertyMonitor( Abc_Ntk_t * p, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues )
+{
+ Abc_Ntk_t * pMonitor, * pStrashed, * pResult;
+ // sequential cleanup parameters
+ int fLatchConst = 1;
+ int fLatchEqual = 1;
+ int fSaveNames = 1;
+ int fUseMvSweep = 0;
+ int nFramesSymb = 1;
+ int nFramesSatur = 512;
+ int fVerbose = 0;
+ int fVeryVerbose = 0;
+ // expecting sequential logic network
+ assert( Abc_NtkIsLogic(p) );
+ assert( Abc_NtkLatchNum(p) > 0 );
+ assert( Vec_IntSize(vNodeIds) > 0 );
+ assert( Vec_IntSize(vNodeIds) == Vec_IntSize(vNodeValues) );
+ // derive ABC network whose only output is 1 iff the given nodes have the given values
+ pMonitor = Abc_NtkDeriveWithOnePo( p, vNodeIds, vNodeValues );
+ // perform structural hashing
+ pStrashed = Abc_NtkStrash( pMonitor, 0, 1, 0 );
+ Abc_NtkDelete( pMonitor );
+ // it is a good idea to run sequential cleanup before giving the network to PDR
+ pResult = Abc_NtkDarLatchSweep( pStrashed, fLatchConst, fLatchEqual, fSaveNames, fUseMvSweep, nFramesSymb, nFramesSatur, fVerbose, fVeryVerbose );
+ Abc_NtkDelete( pStrashed );
+ return pResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Testbench.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCreatePropertyMonitorTest( Abc_Ntk_t * p )
+{
+ Abc_Ntk_t * pNtk;
+ Vec_Int_t * vNodeIds = Vec_IntAlloc( 100 );
+ Vec_Int_t * vNodeValues = Vec_IntAlloc( 100 );
+
+ // this test will only work for the network, which has nodes with internal IDs such as these
+ Vec_IntPush( vNodeIds, 90 );
+ Vec_IntPush( vNodeIds, 80 );
+ Vec_IntPush( vNodeIds, 100 );
+
+ Vec_IntPush( vNodeValues, 1 );
+ Vec_IntPush( vNodeValues, 0 );
+ Vec_IntPush( vNodeValues, 1 );
+
+ pNtk = Abc_NtkCreatePropertyMonitor( p, vNodeIds, vNodeValues );
+
+ Vec_IntFree( vNodeIds );
+ Vec_IntFree( vNodeValues );
+
+ return pNtk;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 7da88d3c..466af66a 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -1,15 +1,15 @@
/**CFile****************************************************************
-
- FileName [abc.c]
+
+ FileName [abc.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
-
+
Synopsis [Command file.]
Author [Alan Mishchenko]
-
+
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
@@ -42,6 +42,8 @@
#include "bool/kit/kit.h"
#include "map/amap/amap.h"
#include "opt/ret/retInt.h"
+#include "sat/xsat/xsat.h"
+#include "sat/satoko/satoko.h"
#include "sat/cnf/cnf.h"
#include "proof/cec/cec.h"
#include "proof/acec/acec.h"
@@ -306,6 +308,9 @@ static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Satoko ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -479,6 +484,8 @@ static int Abc_CommandAbc9Fadds ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Decla ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -520,7 +527,7 @@ extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -545,7 +552,7 @@ void Abc_FrameReplaceCex( Abc_Frame_t * pAbc, Abc_Cex_t ** ppCex )
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -623,7 +630,7 @@ Vec_Int_t * Abc_FrameDeriveStatusArray( Vec_Ptr_t * vCexes )
Vec_PtrForEachEntry( Abc_Cex_t *, vCexes, pCex, i )
if ( pCex != NULL )
Vec_IntWriteEntry( vStatuses, i, 0 ); // set this output as SAT
- return vStatuses;
+ return vStatuses;
}
/**Function*************************************************************
@@ -951,6 +958,9 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "match", Abc_CommandMatch, 0 );
Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "&satoko", Abc_CommandAbc9Satoko, 0 );
Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 );
Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 );
@@ -966,8 +976,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "constr", Abc_CommandConstr, 0 );
Cmd_CommandAdd( pAbc, "Verification", "unfold", Abc_CommandUnfold, 1 );
Cmd_CommandAdd( pAbc, "Verification", "fold", Abc_CommandFold, 1 );
- Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong
- Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong
+ Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong
+ Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong
Cmd_CommandAdd( pAbc, "Verification", "bm", Abc_CommandBm, 1 );
Cmd_CommandAdd( pAbc, "Verification", "bm2", Abc_CommandBm2, 1 );
Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 );
@@ -1121,6 +1131,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&atree", Abc_CommandAbc9ATree, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&decla", Abc_CommandAbc9Decla, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 );
@@ -2717,8 +2729,8 @@ int Abc_CommandPrintStatus( Abc_Frame_t * pAbc, int argc, char ** argv )
{
if ( fShort )
{
- printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).",
- Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1),
+ printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).",
+ Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1),
Vec_IntCountEntry(pAbc->vStatuses, -1), Vec_IntSize(pAbc->vStatuses) );
}
else
@@ -5296,7 +5308,7 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( Vec_IntSize(pAbc->vIndFlops) != Abc_NtkLatchNum(pNtk) )
{
- Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n",
+ Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n",
Vec_IntSize(pAbc->vIndFlops), Abc_NtkLatchNum(pNtk) );
return 0;
}
@@ -6380,7 +6392,7 @@ int Abc_CommandTestRPO(Abc_Frame_t * pAbc, int argc, char ** argv) {
goto usage;
}
}
- if (argc != globalUtilOptind + 1)
+ if (argc != globalUtilOptind + 1)
{
Abc_Print(1, "Input file is not given.\n");
goto usage;
@@ -12007,7 +12019,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
}
*/
// if ( pNtk )
-// Abc_NtkMakeLegit( pNtk );
+// Abc_NtkMakeLegit( pNtk );
{
// extern void Ifd_ManDsdTest();
// Ifd_ManDsdTest();
@@ -14270,7 +14282,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -14311,7 +14323,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -14390,7 +14402,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -15765,7 +15777,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
}
nGatesMin = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nGatesMin < 0 )
+ if ( nGatesMin < 0 )
goto usage;
break;
case 'a':
@@ -16468,7 +16480,7 @@ usage:
SeeAlso []
***********************************************************************/
-#if 0
+#if 0
int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char Buffer[100];
@@ -16839,7 +16851,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'N':
@@ -17213,7 +17225,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
}
}
-
+
// complain if truth tables are requested but the cut size is too large
if ( pPars->fTruth && pPars->nLutSize > IF_MAX_FUNC_LUTSIZE )
{
@@ -18120,7 +18132,7 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_LatchSetInit0( pObj );
else if ( pInitStr[i] == '1' )
Abc_LatchSetInit1( pObj );
- else
+ else
Abc_LatchSetInitDc( pObj );
return 0;
}
@@ -18302,7 +18314,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fUseCex )
{
- char * pInit;
+ char * pInit;
Abc_Cex_t * pTemp;
int k, nFlopsX = 0;
if ( pAbc->pCex == NULL )
@@ -18317,7 +18329,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv )
// compare this value
if ( Abc_NtkPiNum(pNtk) + nFlopsX != pAbc->pCex->nPis )
{
- Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n",
+ Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n",
Abc_NtkPiNum(pNtk), Abc_NtkLatchNum(pNtk), pAbc->pCex->nPis );
return 1;
}
@@ -19529,7 +19541,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Abc_NtkIsComb(pNtk) )
{
- Abc_Print( -1, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" );
+ Abc_Print( 0, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" );
return 0;
}
@@ -20701,7 +20713,7 @@ int Abc_CommandSim3( Abc_Frame_t * pAbc, int argc, char ** argv )
extern int Abc_NtkDarSeqSim3( Abc_Ntk_t * pNtk, Ssw_RarPars_t * pPars );
Ssw_RarPars_t Pars, * pPars = &Pars;
Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc);
- Vec_Ptr_t * vSeqModelVec;
+ Vec_Ptr_t * vSeqModelVec;
int c;
Ssw_RarSetDefaultParams( pPars );
Extra_UtilGetoptReset();
@@ -23168,6 +23180,302 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandXSat( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ abctime clk;
+ int c;
+ int fVerbose = 0;
+ int nConfLimit = 0;
+ int nInsLimit = 0;
+ int nLearnedStart = 0;
+ int nLearnedDelta = 0;
+ int nLearnedPerce = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CILDEhv" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nConfLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nConfLimit < 0 )
+ goto usage;
+ break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nInsLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nInsLimit < 0 )
+ goto usage;
+ break;
+ case 'L':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLearnedStart = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLearnedStart < 0 )
+ goto usage;
+ break;
+ case 'D':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLearnedDelta = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLearnedDelta < 0 )
+ goto usage;
+ break;
+ case 'E':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-E\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLearnedPerce = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLearnedPerce < 0 )
+ goto usage;
+ break;
+ case 'h':
+ goto usage;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc == globalUtilOptind + 1 )
+ {
+ char * pFileName = argv[globalUtilOptind];
+ xSAT_Solver_t * p;
+ int status;
+
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ return 0;
+ }
+ xSAT_SolverParseDimacs( pFile, &p );
+
+ clk = Abc_Clock();
+ status = xSAT_SolverSolve( p );
+ fclose( pFile );
+
+ xSAT_SolverPrintStats( p );
+ if ( status == 0 )
+ Abc_Print( 1, "UNDECIDED " );
+ else if ( status == 1 )
+ Abc_Print( 1, "SATISFIABLE " );
+ else
+ Abc_Print( 1, "UNSATISFIABLE " );
+
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ xSAT_SolverDestroy( p );
+ return 0;
+ }
+
+usage:
+ Abc_Print( -2, "usage: xsat [-CILDE num] [-hv]<file>.cnf\n" );
+ Abc_Print( -2, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" );
+ Abc_Print( -2, "\t derives CNF from the current network and leaves it unchanged\n" );
+ Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
+ Abc_Print( -2, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit );
+ Abc_Print( -2, "\t-L num : starting value for learned clause removal [default = %d]\n", nLearnedStart );
+ Abc_Print( -2, "\t-D num : delta value for learned clause removal [default = %d]\n", nLearnedDelta );
+ Abc_Print( -2, "\t-E num : ratio percentage for learned clause removal [default = %d]\n", nLearnedPerce );
+ Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv );
+
+ // create default options
+ satoko_opts_t opts, * popts;
+ satoko_default_opts(&opts);
+
+ // override default options
+ popts = Cmd_DeriveOptionFromSettings( argc, argv );
+ if ( popts == NULL )
+ goto usage;
+ memcpy( &opts, popts, sizeof(satoko_opts_t) );
+ ABC_FREE( popts );
+
+ if ( argc == globalUtilOptind + 1 )
+ {
+ abctime clk;
+ char * pFileName = argv[globalUtilOptind];
+ satoko_t * p;
+ int status;
+
+ status = satoko_parse_dimacs( pFileName, &p );
+ satoko_configure(p, &opts);
+
+ clk = Abc_Clock();
+ if ( status == SATOKO_OK )
+ status = satoko_solve( p );
+
+ if ( status == SATOKO_UNDEC )
+ Abc_Print( 1, "UNDECIDED " );
+ else if ( status == SATOKO_SAT )
+ Abc_Print( 1, "SATISFIABLE " );
+ else
+ Abc_Print( 1, "UNSATISFIABLE " );
+
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ satoko_destroy( p );
+ return 0;
+ }
+
+usage:
+#ifdef SATOKO_ACT_VAR_FIXED
+ Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRSTU num] [-hv]<file>.cnf\n" );
+#else
+ Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRS num] [-hv]<file>.cnf\n" );
+#endif
+ Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit );
+ Abc_Print( -2, "\t-P num : limit on the number of propagations [default = %d]\n", opts.conf_limit );
+ Abc_Print( -2, "\n\tConstants used for restart heuristic:\n");
+ Abc_Print( -2, "\t-D num : Constant value used by restart heuristics in forcing restarts [default = %f]\n", opts.f_rst );
+ Abc_Print( -2, "\t-E num : Constant value used by restart heuristics in blocking restarts [default = %f]\n", opts.b_rst );
+ Abc_Print( -2, "\t-F num : Lower bound n.of conflicts for start blocking restarts [default = %d]\n", opts.fst_block_rst );
+ Abc_Print( -2, "\t-G num : Size of the moving avarege queue for LBD (force restart) [default = %d]\n", opts.sz_lbd_bqueue );
+ Abc_Print( -2, "\t-H num : Size of the moving avarege queue for Trail size (block restart) [default = %d]\n", opts.sz_trail_bqueue );
+ Abc_Print( -2, "\n\tConstants used for clause database reduction heuristic:\n");
+ Abc_Print( -2, "\t-I num : N.of conflicts before first clause databese reduction [default = %d]\n", opts.n_conf_fst_reduce );
+ Abc_Print( -2, "\t-J num : Increment to reduce [default = %d]\n", opts.inc_reduce );
+ Abc_Print( -2, "\t-K num : Special increment to reduce [default = %d]\n", opts.inc_special_reduce );
+ Abc_Print( -2, "\t-L num : Protecs clauses from deletion for one turn if its LBD is lower [default = %d]\n", opts.lbd_freeze_clause );
+ Abc_Print( -2, "\t-M num : Percentage of learned clauses to remove [default = %d]\n", ( int )( 100 * opts.learnt_ratio ) );
+ Abc_Print( -2, "\t-N num : Max percentage of garbage in clause database [default = %d]\n", ( int )( 100 * opts.garbage_max_ratio ) );
+ Abc_Print( -2, "\n\tConstants used for binary resolution (clause minimization):\n");
+ Abc_Print( -2, "\t-O num : Max clause size for binary resolution [default = %d]\n", opts.clause_max_sz_bin_resol );
+ Abc_Print( -2, "\t-Q num : Min clause LBD for binary resolution [default = %d]\n", opts.clause_min_lbd_bin_resol );
+ Abc_Print( -2, "\n\tConstants used for branching (VSIDS heuristic):\n");
+ Abc_Print( -2, "\t-R num : Clause activity decay factor (when using float clause activity) [default = %f]\n", opts.clause_decay );
+ Abc_Print( -2, "\t-S num : Varibale activity decay factor [default = %f]\n", opts.var_decay );
+#ifdef SATOKO_ACT_VAR_FIXED
+ Abc_Print( -2, "\t-T num : Variable activity limit valeu [default = 0x%08X]\n", opts.var_act_limit );
+ Abc_Print( -2, "\t-U num : Variable activity re-scale factor [default = 0x%08X]\n", opts.var_act_rescale );
+#endif
+ Abc_Print( -2, "\n\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem );
+ int c, fSplit = 0, fIncrem = 0;
+
+ satoko_opts_t opts;
+ satoko_default_opts(&opts);
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Csivh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ opts.conf_limit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.conf_limit < 0 )
+ goto usage;
+ break;
+ case 's':
+ fSplit ^= 1;
+ break;
+ case 'i':
+ fIncrem ^= 1;
+ break;
+ case 'v':
+ opts.verbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" );
+ return 1;
+ }
+ Gia_ManSatokoCall( pAbc->pGia, &opts, fSplit, fIncrem );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &satoko [-C num] [-sivh]\n" );
+ Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit );
+ Abc_Print( -2, "\t-s : split multi-output miter into individual outputs [default = %s]\n", fSplit? "yes": "no" );
+ Abc_Print( -2, "\t-i : split multi-output miter and solve incrementally [default = %s]\n", fIncrem? "yes": "no" );
+ Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandPSat( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
@@ -24155,7 +24463,7 @@ int Abc_CommandBmc3( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
vStatuses = Abc_FrameDeriveStatusArray( vSeqModelVec );
- Abc_FrameReplacePoStatuses( pAbc, &vStatuses );
+ Abc_FrameReplacePoStatuses( pAbc, &vStatuses );
if ( vSeqModelVec )
Abc_FrameReplaceCexVec( pAbc, &vSeqModelVec );
else
@@ -25483,47 +25791,47 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
+{
FILE * pOut, * pErr;
Abc_Ntk_t *pNtk, *pNtk1, *pNtk2;
- int fDelete1, fDelete2;
+ int fDelete1, fDelete2;
Abc_Obj_t * pObj;
char ** pArgvNew;
- int c, nArgcNew, i;
+ int c, nArgcNew, i;
extern void saucyGateWay( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodePo, FILE * gFile, int fBooleanMatching,
int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree);
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
- pErr = Abc_FrameReadErr(pAbc);
-
+ pErr = Abc_FrameReadErr(pAbc);
+
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
- goto usage;
+ goto usage;
default:
Abc_Print( -2, "Unknown switch.\n");
goto usage;
}
}
-
+
pArgvNew = argv + globalUtilOptind;
nArgcNew = argc - globalUtilOptind;
if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew , &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
return 1;
-
- if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) ||
+
+ if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) ||
(unsigned)Abc_NtkPoNum(pNtk1) != (unsigned)Abc_NtkPoNum(pNtk2) )
{
Abc_Print( -2, "Mismatch in the number of inputs or outputs\n");
@@ -25532,7 +25840,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
return 1;
}
-
+
Abc_NtkPermute(pNtk2, 1, 1, 0, NULL );
Abc_NtkShortNames(pNtk2);
@@ -25562,7 +25870,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv )
saucyGateWay( pNtk1, NULL, NULL, 1, 0, 0, 0, 0, 0);
if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
- if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
+ if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
return 0;
usage:
@@ -25570,8 +25878,8 @@ usage:
Abc_Print( -2, "\t performs Boolean matching (PP-equivalence)\n" );
Abc_Print( -2, "\t for equivalent circuits, permutation that maps one circuit\n" );
Abc_Print( -2, "\t to another is printed to standard output (PIs and POs of the\n" );
- Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" );
- Abc_Print( -2, "\t second network have prefix \"N2:\")\n" );
+ Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" );
+ Abc_Print( -2, "\t second network have prefix \"N2:\")\n" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\tfile1 : the file with the first network\n");
Abc_Print( -2, "\tfile2 : the file with the second network\n");
@@ -25593,14 +25901,14 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
+{
Abc_Ntk_t *pNtk;
char * outputName = NULL;
FILE * gFile = NULL;
@@ -25629,20 +25937,20 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
outputName = argv[globalUtilOptind];
if ( !strcmp(argv[globalUtilOptind], "all") )
fOutputsOneAtTime ^= 1;
- globalUtilOptind++;
+ globalUtilOptind++;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-F\" should be followed by a file name.\n" );
goto usage;
- }
+ }
if ( (gFile = fopen( argv[globalUtilOptind], "w" )) == NULL )
{
- Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] );
+ Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] );
return 1;
}
- globalUtilOptind++;
+ globalUtilOptind++;
break;
case 'i':
fFixOutputs ^= 1;
@@ -25665,9 +25973,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -2, "Unknown switch.\n");
goto usage;
}
- }
-
- pNtk = Abc_FrameReadNtk(pAbc);
+ }
+
+ pNtk = Abc_FrameReadNtk(pAbc);
if ( pNtk == NULL )
{
@@ -25690,21 +25998,21 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_NtkForEachPo( pNtk, pNodePo, i ) {
printf("Ouput %s\n\n", Abc_ObjName(pNodePo));
saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree );
- printf("----------------------------------------\n");
+ printf("----------------------------------------\n");
}
fclose(hadi);
} else if (outputName != NULL) {
int i;
- Abc_Obj_t * pNodePo;
+ Abc_Obj_t * pNodePo;
Abc_NtkForEachPo( pNtk, pNodePo, i ) {
if (!strcmp(Abc_ObjName(pNodePo), outputName)) {
saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree );
Abc_NtkDelete( pNtk );
return 0;
- }
+ }
}
Abc_Print( -1, "Output not found\n" );
- return 1;
+ return 1;
} else
saucyGateWay( pNtk, NULL, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree );
@@ -25715,9 +26023,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
Abc_Print( -2, "usage: saucy3 [-O <name>] [-F <file>] [-iosqvh]\n\n" );
Abc_Print( -2, "\t computes functional symmetries of the netowrk\n" );
- Abc_Print( -2, "\t prints symmetry generators to the standard output\n" );
+ Abc_Print( -2, "\t prints symmetry generators to the standard output\n" );
Abc_Print( -2, "\t-O <name> : (optional) compute symmetries only for output given by name\n");
- Abc_Print( -2, "\t only inputs in the output cone are permuted\n");
+ Abc_Print( -2, "\t only inputs in the output cone are permuted\n");
Abc_Print( -2, "\t (special case) name=all, compute symmetries for each\n" );
Abc_Print( -2, "\t output, but only one output at a time\n" );
Abc_Print( -2, "\t [default = compute symmetries by permuting all I/Os]\n" );
@@ -25726,8 +26034,8 @@ usage:
Abc_Print( -2, "\t-o : permute just the outputs (fix the inputs) [default = no]\n");
Abc_Print( -2, "\t-s : only look for swaps of inputs [default = no]\n");
Abc_Print( -2, "\t-q : quiet (do not print symmetry generators) [default = no]\n");
- Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n");
- Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n");
+ Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t \n" );
Abc_Print( -2, "\t This command was contributed by Hadi Katebi from U Michigan.\n" );
@@ -25863,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
Pdr_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGaxrmsipdegovwzh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF )
{
switch ( c )
{
@@ -25911,10 +26219,10 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nConfGenLimit < 0 )
goto usage;
break;
- case 'R':
+ case 'Q':
if ( globalUtilOptind >= argc )
{
- Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" );
+ Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" );
goto usage;
}
pPars->nRestLimit = atoi(argv[globalUtilOptind]);
@@ -25955,6 +26263,17 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nTimeOutGap < 0 )
goto usage;
break;
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nRandomSeed = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nRandomSeed < 0 )
+ goto usage;
+ break;
case 'a':
pPars->fSolveAll ^= 1;
break;
@@ -25967,6 +26286,15 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'm':
pPars->fMonoCnf ^= 1;
break;
+ case 'u':
+ pPars->fNewXSim ^= 1;
+ break;
+ case 'y':
+ pPars->fFlopPrio ^= 1;
+ break;
+ case 'f':
+ pPars->fFlopOrder ^= 1;
+ break;
case 's':
pPars->fShortest ^= 1;
break;
@@ -25985,9 +26313,24 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'g':
pPars->fSkipGeneral ^= 1;
break;
+ case 'j':
+ pPars->fSimpleGeneral ^= 1;
+ break;
case 'o':
pPars->fUsePropOut ^= 1;
break;
+ case 'n':
+ pPars->fSkipDown ^= 1;
+ break;
+ case 'c':
+ pPars->fCtgs ^= 1;
+ break;
+ case 't':
+ pPars->fUseAbs ^= 1;
+ break;
+ case 'k':
+ pPars->fUseSimpleRef ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -26029,33 +26372,49 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: pdr [-MFCDRTHG <num>] [-axrmsipdegovwzh]\n" );
+ Abc_Print( -2, "usage: pdr [-MFCDQTHGS <num>] [-axrmuyfsipdegjonctkvwzh]\n" );
Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" );
- Abc_Print( -2, "\t pioneered by Aaron Bradley (http://ecee.colorado.edu/~bradleya/ic3/)\n" );
+ Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" );
Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" );
Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle );
Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax );
Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit );
Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit );
- Abc_Print( -2, "\t-R num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit );
+ Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit );
Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut );
Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne );
Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap );
+ Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed );
Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" );
Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" );
Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" );
Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" );
+ Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" );
+ Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" );
+ Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" );
Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" );
Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" );
Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" );
Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" );
Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" );
Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" );
+ Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" );
Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" );
+ Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" );
+ Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" );
+ Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" );
+ Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" );
- Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t-h : print the command usage\n\n");
+ Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n");
+ Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n");
+ Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n");
+ Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n");
+
+
+
return 1;
}
@@ -27055,7 +27414,7 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
pAig = Gia_ManReadMiniLut( FileName );
// else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) )
// Abc3_ReadShowHie( FileName, fSkipStrash );
- else
+ else
pAig = Gia_AigerRead( FileName, fGiaSimple, fSkipStrash, 0 );
if ( pAig )
Abc_FrameUpdateGia( pAbc, pAig );
@@ -27466,8 +27825,8 @@ int Abc_CommandAbc9Get( Abc_Frame_t * pAbc, int argc, char ** argv )
Vec_FltFreeP( &pGia->vOutReqs );
pGia->DefInArrs = Abc_NtkReadDefaultArrivalWorst(pNtk);
pGia->DefOutReqs = Abc_NtkReadDefaultRequiredWorst(pNtk);
- pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) );
- pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) );
+ pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) );
+ pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) );
}
Abc_FrameUpdateGia( pAbc, pGia );
return 0;
@@ -27626,7 +27985,7 @@ usage:
Synopsis [Compares to versions of the design and finds the best.]
Description []
-
+
SideEffects []
SeeAlso []
@@ -27637,11 +27996,11 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int
int nCurLuts, nCurEdges, nCurLevels;
Gia_ManLutParams( p, &nCurLuts, &nCurEdges, &nCurLevels );
if ( pBest == NULL ||
- Gia_ManPiNum(pBest) != Gia_ManPiNum(p) ||
- Gia_ManPoNum(pBest) != Gia_ManPoNum(p) ||
+ Gia_ManPiNum(pBest) != Gia_ManPiNum(p) ||
+ Gia_ManPoNum(pBest) != Gia_ManPoNum(p) ||
Gia_ManRegNum(pBest) != Gia_ManRegNum(p) ||
strcmp(Gia_ManName(pBest), Gia_ManName(p)) ||
- (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) ||
+ (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) ||
( fArea && (*pnBestLuts > nCurLuts || (*pnBestLuts == nCurLuts && *pnBestLevels > nCurLevels)))
)
{
@@ -27659,7 +28018,7 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -27697,7 +28056,7 @@ int Abc_CommandAbc9Save( Abc_Frame_t * pAbc, int argc, char ** argv )
// save the design as best
Gia_ManStopP( &pAbc->pGiaBest );
pAbc->pGiaBest = Gia_ManDupWithAttributes( pAbc->pGia );
- return 0;
+ return 0;
usage:
Abc_Print( -2, "usage: &save [-ah]\n" );
@@ -27712,7 +28071,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -28451,15 +28810,21 @@ usage:
int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Vec_Int_t * vBold = NULL;
- int c, fAdders = 0;
+ int c, fAdders = 0, fFadds = 0, fPath = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "afph" ) ) != EOF )
{
switch ( c )
{
case 'a':
fAdders ^= 1;
break;
+ case 'f':
+ fFadds ^= 1;
+ break;
+ case 'p':
+ fPath ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -28482,14 +28847,16 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv )
Gia_ManForEachLut( pAbc->pGia, c )
Vec_IntPush( vBold, c );
}
- Gia_ManShow( pAbc->pGia, vBold, fAdders );
+ Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds, fPath );
Vec_IntFreeP( &vBold );
return 0;
usage:
- Abc_Print( -2, "usage: &show [-ah]\n" );
+ Abc_Print( -2, "usage: &show [-afph]\n" );
Abc_Print( -2, "\t shows the current GIA using GSView\n" );
Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" );
+ Abc_Print( -2, "\t-f : toggle showing only full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle showing the critical path of a LUT mapping [default = %s]\n", fPath? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -30868,7 +31235,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv )
}
nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nRelaxRatio < 0 )
+ if ( nRelaxRatio < 0 )
goto usage;
break;
case 'a':
@@ -30908,7 +31275,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv )
printf( "DSD manager has incompatible number of variables. Delay minimization is not performed.\n" );
fDelayMin = 0;
}
- }
+ }
pTemp = Gia_ManAigSyn2( pAbc->pGia, fOldAlgo, fCoarsen, fCutMin, nRelaxRatio, fDelayMin, fVerbose, fVeryVerbose );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
@@ -31005,7 +31372,7 @@ int Abc_CommandAbc9Synch2( Abc_Frame_t * pAbc, int argc, char ** argv )
}
nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nRelaxRatio < 0 )
+ if ( nRelaxRatio < 0 )
goto usage;
break;
case 'f':
@@ -31813,7 +32180,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( Gia_ManRegNum(pAbc->pGia) == 0 )
{
- Abc_Print( -1, "The network is combinational.\n" );
+ Abc_Print( 0, "The network is combinational.\n" );
return 0;
}
pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars );
@@ -32774,8 +33141,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Cec_ParCec_t ParsCec, * pPars = &ParsCec;
FILE * pFile;
- Gia_Man_t * pSecond, * pMiter;
- char * FileName, * pTemp;
+ Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter;
char ** pArgvNew;
int c, nArgcNew, fMiter = 0, fDualOutput = 0, fDumpMiter = 0;
Cec_ManCecSetDefaultParams( pPars );
@@ -32830,13 +33196,15 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
- if ( pAbc->pGia == NULL )
- {
- Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no AIG.\n" );
- return 1;
- }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
if ( fMiter )
{
+ if ( pAbc->pGia == NULL || nArgcNew != 0 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Cec(): A miter cannot be given as an argument of command &cec and should be entered using &r.\n" );
+ return 1;
+ }
if ( fDualOutput )
{
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
@@ -32845,57 +33213,97 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( !pPars->fSilent )
- Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ Abc_Print( 1, "Assuming the current network is a double-output miter.\n" );
pAbc->Status = Cec_ManVerify( pAbc->pGia, pPars );
}
else
{
Gia_Man_t * pTemp;
if ( !pPars->fSilent )
- Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ Abc_Print( 1, "Assuming the current network is a single-output miter.\n" );
pTemp = Gia_ManDemiterToDual( pAbc->pGia );
pAbc->Status = Cec_ManVerify( pTemp, pPars );
ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb );
Gia_ManStop( pTemp );
- }
+ }
Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
return 0;
}
-
- pArgvNew = argv + globalUtilOptind;
- nArgcNew = argc - globalUtilOptind;
- if ( nArgcNew != 1 )
+ if ( nArgcNew > 2 )
{
- if ( pAbc->pGia->pSpec == NULL )
+ Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" );
+ return 1;
+ }
+ if ( nArgcNew == 2 )
+ {
+ char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp;
+ int n;
+ for ( n = 0; n < 2; n++ )
{
- Abc_Print( -1, "File name is not given on the command line.\n" );
- return 1;
+ // fix the wrong symbol
+ for ( pTemp = pFileNames[n]; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( pFileNames[n], "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] );
+ if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 );
+ if ( pGias[n] == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] );
+ return 0;
+ }
}
- FileName = pAbc->pGia->pSpec;
}
else
- FileName = pArgvNew[0];
- // fix the wrong symbol
- for ( pTemp = FileName; *pTemp; pTemp++ )
- if ( *pTemp == '>' )
- *pTemp = '\\';
- if ( (pFile = fopen( FileName, "r" )) == NULL )
- {
- Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
- if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
- Abc_Print( 1, "Did you mean \"%s\"?", FileName );
- Abc_Print( 1, "\n" );
- return 1;
- }
- fclose( pFile );
- pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
- if ( pSecond == NULL )
{
- Abc_Print( -1, "Reading AIGER has failed.\n" );
- return 0;
+ char * FileName, * pTemp;
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" );
+ return 1;
+ }
+ pGias[0] = pAbc->pGia;
+ if ( nArgcNew == 1 )
+ FileName = pArgvNew[0];
+ else
+ {
+ assert( nArgcNew == 0 );
+ if ( pAbc->pGia->pSpec == NULL )
+ {
+ Abc_Print( -1, "File name is not given on the command line.\n" );
+ return 1;
+ }
+ FileName = pAbc->pGia->pSpec;
+ }
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 );
+ if ( pGias[1] == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
}
// compute the miter
- pMiter = Gia_ManMiter( pAbc->pGia, pSecond, 0, 1, 0, 0, pPars->fVerbose );
+ pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, 1, 0, 0, pPars->fVerbose );
if ( pMiter )
{
if ( fDumpMiter )
@@ -32904,10 +33312,12 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0 );
}
pAbc->Status = Cec_ManVerify( pMiter, pPars );
- Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
+ Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
Gia_ManStop( pMiter );
}
- Gia_ManStop( pSecond );
+ if ( pGias[0] != pAbc->pGia )
+ Gia_ManStop( pGias[0] );
+ Gia_ManStop( pGias[1] );
return 0;
usage:
@@ -33749,7 +34159,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'T':
@@ -34867,7 +35277,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'L':
@@ -34878,7 +35288,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nCoarseLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nCoarseLimit < 0 )
+ if ( pPars->nCoarseLimit < 0 )
goto usage;
break;
case 'E':
@@ -34889,7 +35299,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nAreaTuner = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nAreaTuner < 0 )
+ if ( pPars->nAreaTuner < 0 )
goto usage;
break;
case 'D':
@@ -35099,7 +35509,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'L':
@@ -35110,7 +35520,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nCoarseLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nCoarseLimit < 0 )
+ if ( pPars->nCoarseLimit < 0 )
goto usage;
break;
case 'E':
@@ -35121,7 +35531,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nAreaTuner = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nAreaTuner < 0 )
+ if ( pPars->nAreaTuner < 0 )
goto usage;
break;
case 'D':
@@ -35303,7 +35713,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'L':
@@ -35314,7 +35724,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nCoarseLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nCoarseLimit < 0 )
+ if ( pPars->nCoarseLimit < 0 )
goto usage;
break;
case 'E':
@@ -35325,7 +35735,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nAreaTuner = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nAreaTuner < 0 )
+ if ( pPars->nAreaTuner < 0 )
goto usage;
break;
case 'D':
@@ -35518,7 +35928,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nRelaxRatio = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nRelaxRatio < 0 )
+ if ( pPars->nRelaxRatio < 0 )
goto usage;
break;
case 'L':
@@ -35529,7 +35939,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nCoarseLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nCoarseLimit < 0 )
+ if ( pPars->nCoarseLimit < 0 )
goto usage;
break;
case 'E':
@@ -35540,7 +35950,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->nAreaTuner = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( pPars->nAreaTuner < 0 )
+ if ( pPars->nAreaTuner < 0 )
goto usage;
break;
case 'D':
@@ -35886,7 +36296,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv )
{
//Edg_ManAssignEdgeNew( pAbc->pGia, nEdges, fVerbose );
Seg_ManComputeDelay( pAbc->pGia, DelayMax, nFanouts, nEdges==2, fVerbose );
- return 0;
+ return 0;
}
if ( pAbc->pGia->pManTime && fReverse )
{
@@ -35895,7 +36305,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( fReverse )
DelayMax = Gia_ManComputeEdgeDelay2( pAbc->pGia );
- else
+ else
DelayMax = Gia_ManComputeEdgeDelay( pAbc->pGia, nEdges == 2 );
//printf( "The number of edges = %d. Delay = %d.\n", Gia_ManEvalEdgeCount(pAbc->pGia), DelayMax );
return 0;
@@ -36025,7 +36435,7 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
Abc_Print( -2, "usage: &satlut [-NICDQ num] [-drwvh]\n" );
- Abc_Print( -2, "\t performs SAT-based remapping of the 4-LUT network\n" );
+ Abc_Print( -2, "\t performs SAT-based remapping of the LUT-mapped network\n" );
Abc_Print( -2, "\t-N num : the limit on AIG nodes in the window (num <= 128) [default = %d]\n", nNumber );
Abc_Print( -2, "\t-I num : the limit on the number of improved windows [default = %d]\n", nImproves );
Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nBTLimit );
@@ -37751,9 +38161,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp;
Vec_Int_t * vPos;
- int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fVerbose = 0;
+ int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWavh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaevh" ) ) != EOF )
{
switch ( c )
{
@@ -37815,6 +38225,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'a':
fUseAllCis ^= 1;
break;
+ case 'e':
+ fExtractAll ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -37829,6 +38242,21 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Cone(): There is no AIG.\n" );
return 1;
}
+ if ( fExtractAll )
+ {
+ char Buffer[1000];
+ Gia_Obj_t * pObj;
+ int i, nDigits = Abc_Base10Log(Gia_ManPoNum(pAbc->pGia));
+ Gia_ManForEachPo( pAbc->pGia, pObj, i )
+ {
+ Gia_Man_t * pOne = Gia_ManDupDfsCone( pAbc->pGia, pObj );
+ sprintf( Buffer, "%s_%0*d.aig", Extra_FileNameGeneric(pAbc->pGia->pSpec), nDigits, i );
+ Gia_AigerWrite( pOne, Buffer, 0, 0 );
+ Gia_ManStop( pOne );
+ }
+ printf( "Dumped all outputs into individual AIGER files.\n" );
+ return 0;
+ }
if ( nLevelMax || nTimeWindow )
{
if ( nLevelMax && nTimeWindow )
@@ -37876,7 +38304,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &cone [-ORPLW num] [-avh]\n" );
+ Abc_Print( -2, "usage: &cone [-ORPLW num] [-aevh]\n" );
Abc_Print( -2, "\t extracting multi-output sequential logic cones\n" );
Abc_Print( -2, "\t-O num : the index of first PO to extract [default = %d]\n", iOutNum );
Abc_Print( -2, "\t-R num : (optional) the number of outputs to extract [default = %d]\n", nOutRange );
@@ -37884,6 +38312,7 @@ usage:
Abc_Print( -2, "\t-L num : (optional) extract cones with higher level [default = %d]\n", nLevelMax );
Abc_Print( -2, "\t-W num : (optional) extract cones falling into this window [default = %d]\n", nTimeWindow );
Abc_Print( -2, "\t-a : toggle keeping all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" );
+ Abc_Print( -2, "\t-e : toggle writing all outputs into individual files [default = %s]\n", fExtractAll? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -38307,7 +38736,7 @@ int Abc_CommandAbc9MultiProve( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pAbc->Status = Gia_ManMultiProve( pAbc->pGia, pPars );
vStatuses = Abc_FrameDeriveStatusArray( pAbc->pGia->vSeqModelVec );
- Abc_FrameReplacePoStatuses( pAbc, &vStatuses );
+ Abc_FrameReplacePoStatuses( pAbc, &vStatuses );
Abc_FrameReplaceCexVec( pAbc, &pAbc->pGia->vSeqModelVec );
return 0;
@@ -38454,7 +38883,7 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv )
Bmc_AndPar_t Pars, * pPars = &Pars;
memset( pPars, 0, sizeof(Bmc_AndPar_t) );
pPars->nStart = 0; // starting timeframe
- pPars->nFramesMax = 0; // maximum number of timeframes
+ pPars->nFramesMax = 0; // maximum number of timeframes
pPars->nFramesAdd = 50; // the number of additional frames
pPars->nConfLimit = 0; // maximum number of conflicts at a node
pPars->nTimeOut = 0; // timeout in seconds
@@ -38463,9 +38892,9 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->fDumpFrames = 0; // dump unrolled timeframes
pPars->fUseSynth = 0; // use synthesis
pPars->fUseOldCnf = 0; // use old CNF construction
- pPars->fVerbose = 0; // verbose
- pPars->fVeryVerbose = 0; // very verbose
- pPars->fNotVerbose = 0; // skip line-by-line print-out
+ pPars->fVerbose = 0; // verbose
+ pPars->fVeryVerbose = 0; // very verbose
+ pPars->fNotVerbose = 0; // skip line-by-line print-out
pPars->iFrame = 0; // explored up to this frame
pPars->nFailOuts = 0; // the number of failed outputs
pPars->nDropOuts = 0; // the number of dropped outputs
@@ -39166,7 +39595,7 @@ usage:
Abc_Print( -2, "\t ((a&b)^p) complement at the output\n");
Abc_Print( -2, "\t (((a^p)&(b^q))^r) complement at the inputs and at the output\n");
Abc_Print( -2, "\t (a?(b?~s:r):(b?q:p)) functionally observable fault at the output\n");
- Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n");
+ Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n");
return 1;
}
@@ -40039,7 +40468,7 @@ int Abc_CommandAbc9Demiter( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char pName0[1000] = "miter_part0.aig";
char pName1[1000] = "miter_part1.aig";
- Gia_Man_t * pPart1, * pPart2;
+ Gia_Man_t * pPart1, * pPart2;
if ( Gia_ManPoNum(pAbc->pGia) % 2 != 0 )
{
Abc_Print( -1, "Abc_CommandAbc9Demiter(): Does not look like a dual-output miter.\n" );
@@ -40387,14 +40816,12 @@ usage:
int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pFile;
- Cec_ParCec_t ParsCec, * pPars = &ParsCec;
- Gia_Man_t * pSecond;
- char * FileName, * pTemp;
+ Acec_ParCec_t ParsCec, * pPars = &ParsCec;
char ** pArgvNew;
- int c, nArgcNew, fMiter = 0, fDualOutput = 0, fTwoOutput = 0;
- Cec_ManCecSetDefaultParams( pPars );
+ int c, nArgcNew;
+ Acec_ManCecSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdtvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtbvh" ) ) != EOF )
{
switch ( c )
{
@@ -40420,17 +40847,17 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->TimeLimit < 0 )
goto usage;
break;
- case 'n':
- pPars->fNaive ^= 1;
- break;
case 'm':
- fMiter ^= 1;
+ pPars->fMiter ^= 1;
break;
case 'd':
- fDualOutput ^= 1;
+ pPars->fDualOutput ^= 1;
break;
case 't':
- fTwoOutput ^= 1;
+ pPars->fTwoOutput ^= 1;
+ break;
+ case 'b':
+ pPars->fBooth ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
@@ -40441,15 +40868,20 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
- if ( fMiter )
+ if ( pPars->fMiter )
{
Gia_Man_t * pGia0, * pGia1, * pDual;
+ if ( argc != globalUtilOptind )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Acec(): If the input is a miter, it cannot be given on the command line.\n" );
+ return 1;
+ }
if ( pAbc->pGia == NULL )
{
Abc_Print( -1, "Abc_CommandAbc9Acec(): There is no AIG.\n" );
return 1;
}
- if ( fDualOutput )
+ if ( pPars->fDualOutput )
{
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
{
@@ -40459,29 +40891,29 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( !pPars->fSilent )
Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
Gia_ManDemiterDual( pAbc->pGia, &pGia0, &pGia1 );
- pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
+ pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
}
- else if ( fTwoOutput )
+ else if ( pPars->fTwoOutput )
{
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
{
- Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" );
+ Abc_Print( -1, "The two-output miter should have an even number of outputs.\n" );
return 1;
}
if ( !pPars->fSilent )
Abc_Print( 1, "Assuming the current network is a two-word miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
Gia_ManDemiterTwoWords( pAbc->pGia, &pGia0, &pGia1 );
- pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
+ pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
}
- else
+ else // regular single- or multi-output miter
{
if ( !pPars->fSilent )
- Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ Abc_Print( 1, "Assuming the current network is a regular single- or multi-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
pDual = Gia_ManDemiterToDual( pAbc->pGia );
Gia_ManDemiterDual( pDual, &pGia0, &pGia1 );
Gia_ManStop( pDual );
- pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
- }
+ pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
+ }
Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb );
Gia_ManStop( pGia0 );
Gia_ManStop( pGia1 );
@@ -40490,55 +40922,201 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
pArgvNew = argv + globalUtilOptind;
nArgcNew = argc - globalUtilOptind;
- if ( nArgcNew != 1 )
+ if ( nArgcNew == 0 || nArgcNew == 1 )
{
- if ( pAbc->pGia->pSpec == NULL )
+ Gia_Man_t * pSecond;
+ char * pTemp, * FileName = NULL;
+ if ( nArgcNew == 0 )
{
- Abc_Print( -1, "File name is not given on the command line.\n" );
- return 1;
+ FileName = pAbc->pGia->pSpec;
+ if ( FileName == NULL )
+ {
+ Abc_Print( -1, "File name is not given on the command line.\n" );
+ return 1;
+ }
+ }
+ else // if ( nArgcNew == 1 )
+ {
+ FileName = pArgvNew[0];
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
}
- FileName = pAbc->pGia->pSpec;
+ pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
+ if ( pSecond == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ pAbc->Status = Acec_Solve( pAbc->pGia, pSecond, pPars );
+ Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
+ Gia_ManStop( pSecond );
}
- else
- FileName = pArgvNew[0];
- // fix the wrong symbol
- for ( pTemp = FileName; *pTemp; pTemp++ )
- if ( *pTemp == '>' )
- *pTemp = '\\';
- if ( (pFile = fopen( FileName, "r" )) == NULL )
+ else if ( nArgcNew == 2 )
{
- Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
- if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
- Abc_Print( 1, "Did you mean \"%s\"?", FileName );
- Abc_Print( 1, "\n" );
- return 1;
+ Gia_Man_t * pGias[2] = {NULL}; int i;
+ char * pTemp, * FileName[2] = { pArgvNew[0], pArgvNew[1] };
+ for ( i = 0; i < 2; i++ )
+ {
+ // fix the wrong symbol
+ for ( pTemp = FileName[i]; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName[i], "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName[i] );
+ if ( (FileName[i] = Extra_FileGetSimilarName( FileName[i], ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName[i] );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGias[i] = Gia_AigerRead( FileName[i], 0, 0, 0 );
+ if ( pGias[i] == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ }
+ pAbc->Status = Acec_Solve( pGias[0], pGias[1], pPars );
+ Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
+ Gia_ManStop( pGias[0] );
+ Gia_ManStop( pGias[1] );
}
- fclose( pFile );
- pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
- if ( pSecond == NULL )
+ else
{
- Abc_Print( -1, "Reading AIGER has failed.\n" );
- return 0;
+ Abc_Print( -1, "Too many command-line arguments.\n" );
+ return 1;
}
- pAbc->Status = Gia_PolynCec( pAbc->pGia, pSecond, pPars );
- Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
- Gia_ManStop( pSecond );
return 0;
usage:
- Abc_Print( -2, "usage: &acec [-CT num] [-nmdtvh]\n" );
+ Abc_Print( -2, "usage: &acec [-CT num] [-mdtbvh] <file1> <file2>\n" );
Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit );
- Abc_Print( -2, "\t-n : toggle using naive SAT-based checking [default = %s]\n", pPars->fNaive? "yes":"no");
- Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits");
- Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no");
- Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", fTwoOutput? "yes":"no");
+ Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits");
+ Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no");
+ Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no");
+ Abc_Print( -2, "\t-b : toggle working with Booth multipliers [default = %s]\n", pPars->fBooth? "yes":"no");
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n");
+ Abc_Print( -2, "\tfile2 : (optional) the file with the second network\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Gia_Man_t * pTemp;
+ int c, fBooth = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'b':
+ fBooth ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" );
+ return 0;
+ }
+ pTemp = Acec_Normalize( pAbc->pGia, fBooth, fVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &anorm [-bvh]\n" );
+ Abc_Print( -2, "\t normalize adder trees in the current AIG\n" );
+ Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Decla( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Gia_Man_t * pTemp;
+ int c, fBooth = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'b':
+ fBooth ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Decla(): There is no AIG.\n" );
+ return 0;
+ }
+ pTemp = Acec_ManDecla( pAbc->pGia, fBooth, fVerbose );
+ Abc_FrameUpdateGia( pAbc, pTemp );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &decla [-bvh]\n" );
+ Abc_Print( -2, "\t removes carry look ahead adders\n" );
+ Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
+
/**Function*************************************************************
Synopsis []
@@ -40687,7 +41265,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -40701,7 +41279,7 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv )
Sfm_ParSetDefault( pPars );
pPars->nTfoLevMax = 5;
pPars->nDepthMax = 100;
- pPars->nWinSizeMax = 2000;
+ pPars->nWinSizeMax = 2000;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCNdaebvwh" ) ) != EOF )
{
@@ -40852,7 +41430,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -40865,7 +41443,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
Sbd_Par_t Pars, * pPars = &Pars;
Sbd_ParSetDefault( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "KWFMCacvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCmcdpvwh" ) ) != EOF )
{
switch ( c )
{
@@ -40880,6 +41458,39 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nLutSize < 0 )
goto usage;
break;
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nLutNum = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nLutNum < 0 )
+ goto usage;
+ break;
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nCutSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nCutSize < 0 )
+ goto usage;
+ break;
+ case 'P':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nCutNum = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nCutNum < 0 )
+ goto usage;
+ break;
case 'W':
if ( globalUtilOptind >= argc )
{
@@ -40924,11 +41535,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nBTLimit < 0 )
goto usage;
break;
- case 'a':
- pPars->fArea ^= 1;
+ case 'm':
+ pPars->fMapping ^= 1;
break;
case 'c':
- pPars->fCover ^= 1;
+ pPars->fMoreCuts ^= 1;
+ break;
+ case 'd':
+ pPars->fFindDivs ^= 1;
+ break;
+ case 'p':
+ pPars->fUsePath ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
@@ -40944,33 +41561,35 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( pAbc->pGia == NULL )
{
- Abc_Print( -1, "Abc_CommandAbc9Mfs(): There is no AIG.\n" );
+ Abc_Print( -1, "Abc_CommandAbc9Mfsd(): There is no AIG.\n" );
return 0;
}
if ( Gia_ManBufNum(pAbc->pGia) )
{
- Abc_Print( -1, "Abc_CommandAbc9Mfs(): This command does not work with barrier buffers.\n" );
+ Abc_Print( -1, "Abc_CommandAbc9Mfsd(): This command does not work with barrier buffers.\n" );
return 1;
}
if ( Gia_ManHasMapping(pAbc->pGia) )
- {
- Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has mapping (run &st to unmap).\n" );
- return 0;
- }
+ Abc_Print( 1, "The current AIG has mapping, which can be used to determine critical path if \"-p\" is selected.\n" );
pTemp = Sbd_NtkPerform( pAbc->pGia, pPars );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
- Abc_Print( -2, "usage: &mfsd [-KWFMC <num>] [-acvwh]\n" );
+ Abc_Print( -2, "usage: &mfsd [-KSNPWFMC <num>] [-mcdpvwh]\n" );
Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" );
Abc_Print( -2, "\t-K <num> : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize );
+ Abc_Print( -2, "\t-S <num> : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum );
+ Abc_Print( -2, "\t-N <num> : the cut size considered for optimization (2 <= num <= 10) [default = %d]\n", pPars->nCutSize );
+ Abc_Print( -2, "\t-P <num> : the number of cuts computed at a node (1 <= num <= 500) [default = %d]\n", pPars->nCutNum );
Abc_Print( -2, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels );
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax );
Abc_Print( -2, "\t-M <num> : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax );
Abc_Print( -2, "\t-C <num> : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit );
- Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" );
- Abc_Print( -2, "\t-c : toggle using complete slow covering procedure [default = %s]\n", pPars->fCover? "yes": "no" );
+ Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -41324,7 +41943,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -41385,7 +42004,7 @@ usage:
Synopsis []
Description []
-
+
SideEffects []
SeeAlso []
@@ -42400,9 +43019,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
// Jf_ManTestCnf( pAbc->pGia );
// Gia_ManCheckFalseTest( pAbc->pGia, nFrames );
// Gia_ParTest( pAbc->pGia, nWords, nProcs );
-// Gia_PolynExplore( pAbc->pGia );
-// Gia_ManTestSatEnum( pAbc->pGia );
-
+//Cec2_ManSimulateTest( pAbc->pGia );
// printf( "\nThis command is currently disabled.\n\n" );
return 0;
usage:
diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c
index 8c2b3b39..1542c25a 100644
--- a/src/base/abci/abcCollapse.c
+++ b/src/base/abci/abcCollapse.c
@@ -537,8 +537,6 @@ extern Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose );
extern int Gia_ManCoLargestSupp( Gia_Man_t * p, Vec_Wec_t * vSupps );
extern Vec_Wec_t * Gia_ManIsoStrashReduceInt( Gia_Man_t * p, Vec_Wec_t * vSupps, int fVerbose );
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
/**Function*************************************************************
Synopsis [Derives GIA for the network.]
@@ -802,7 +800,7 @@ Vec_Ptr_t * Abc_GiaDeriveSops( Abc_Ntk_t * pNtkNew, Gia_Man_t * p, Vec_Wec_t * v
if ( fCnfShared )
{
vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
- pCnf = Mf_ManGenerateCnf( p, 8, 1, 0, 0 );
+ pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 1, 0, 0, 0 );
}
vSopsRepr = Vec_PtrStart( Vec_IntSize(vReprs) );
pProgress = Extra_ProgressBarStart( stdout, Vec_IntSize(vReprs) );
diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c
index 9f672485..147f7c2f 100644
--- a/src/base/abci/abcDar.c
+++ b/src/base/abci/abcDar.c
@@ -1946,17 +1946,17 @@ finish:
// report the miter
if ( RetValue == 1 )
{
- Abc_Print( 1, "Networks are equivalent. " );
+ Abc_Print( 1, "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
- Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else
{
- Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_Print( 1, "Networks are UNDECIDED. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
fflush( stdout );
@@ -3695,17 +3695,17 @@ int Abc_NtkDarInduction( Abc_Ntk_t * pNtk, int nTimeOut, int nFramesMax, int nCo
RetValue = Saig_ManInduction( pMan, nTimeOut, nFramesMax, nConfMax, fUnique, fUniqueAll, fGetCex, fVerbose, fVeryVerbose );
if ( RetValue == 1 )
{
- Abc_Print( 1, "Networks are equivalent. " );
+ Abc_Print( 1, "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
- Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else
{
- Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_Print( 1, "Networks are UNDECIDED. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( fGetCex )
diff --git a/src/base/abci/abcDetect.c b/src/base/abci/abcDetect.c
index 8b8bba64..7adbed5d 100644
--- a/src/base/abci/abcDetect.c
+++ b/src/base/abci/abcDetect.c
@@ -901,8 +901,7 @@ Vec_Int_t * Abc_NtkFinCheckPair( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t
}
else
{
- extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
if ( pSat == NULL )
{
diff --git a/src/base/abci/abcDress3.c b/src/base/abci/abcDress3.c
index 33545f0a..ce0cb7f5 100644
--- a/src/base/abci/abcDress3.c
+++ b/src/base/abci/abcDress3.c
@@ -35,32 +35,6 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
- Synopsis [Compute equivalence classes of nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NtkComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose )
-{
- Gia_Man_t * pTemp;
- Cec_ParFra_t ParsFra, * pPars = &ParsFra;
- Cec_ManFraSetDefaultParams( pPars );
- pPars->fUseOrigIds = 1;
- pPars->fSatSweeping = 1;
- pPars->nBTLimit = nConfs;
- pPars->fVerbose = fVerbose;
- pTemp = Cec_ManSatSweeping( pGia, pPars, 0 );
- Gia_ManStop( pTemp );
- pTemp = Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv );
- Gia_ManStop( pTemp );
-}
-
-/**Function*************************************************************
-
Synopsis [Converts AIG from HOP to GIA.]
Description []
@@ -315,13 +289,15 @@ void Abc_NtkDumpEquivFile( char * pFileName, Vec_Int_t * vClasses, Abc_Ntk_t * p
void Abc_NtkDumpEquiv( Abc_Ntk_t * pNtks[2], char * pFileName, int nConfs, int fByName, int fVerbose )
{
//abctime clk = Abc_Clock();
+ Gia_Man_t * pTemp;
Vec_Int_t * vClasses;
// derive shared AIG for the two networks
Gia_Man_t * pGia = Abc_NtkAigToGiaTwo( pNtks[0], pNtks[1], fByName );
if ( fVerbose )
printf( "Computing equivalences for networks \"%s\" and \"%s\" with conflict limit %d.\n", Abc_NtkName(pNtks[0]), Abc_NtkName(pNtks[1]), nConfs );
// compute equivalences in this AIG
- Abc_NtkComputeGiaEquivs( pGia, nConfs, fVerbose );
+ pTemp = Gia_ManComputeGiaEquivs( pGia, nConfs, fVerbose );
+ Gia_ManStop( pTemp );
//if ( fVerbose )
// Abc_PrintTime( 1, "Equivalence computation time", Abc_Clock() - clk );
if ( fVerbose )
diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c
index 9ab1c3ac..2064873a 100644
--- a/src/base/abci/abcExact.c
+++ b/src/base/abci/abcExact.c
@@ -873,7 +873,7 @@ static void Ses_StoreRead( Ses_Store_t * pStore, const char * pFilename, int fSy
fclose( pFile );
- printf( "read %lu entries from file\n", nEntries );
+ printf( "read %lu entries from file\n", (long)nEntries );
}
// computes top decomposition of variables wrt. to AND and OR
diff --git a/src/base/abci/abcMfs.c b/src/base/abci/abcMfs.c
index e33d6c73..d44ca1a0 100644
--- a/src/base/abci/abcMfs.c
+++ b/src/base/abci/abcMfs.c
@@ -259,7 +259,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
if ( nFaninMax > 6 )
{
Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" );
- return 0;
+ return 1;
}
if ( !Abc_NtkHasSop(pNtk) )
if ( !Abc_NtkToSop( pNtk, -1, ABC_INFINITY ) )
diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c
index 25d1d113..7199c529 100644
--- a/src/base/abci/abcVerify.c
+++ b/src/base/abci/abcVerify.c
@@ -122,6 +122,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
***********************************************************************/
void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose )
{
+ abctime clk = Abc_Clock();
Prove_Params_t Params, * pParams = &Params;
// Fraig_Params_t Params;
// Fraig_Man_t * pMan;
@@ -170,18 +171,20 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
RetValue = Abc_NtkMiterIsConstant( pMiter );
if ( RetValue == 0 )
{
- printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
+ printf( "Networks are NOT EQUIVALENT after structural hashing. " );
// report the error
pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 );
Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel );
ABC_FREE( pMiter->pModel );
Abc_NtkDelete( pMiter );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return;
}
if ( RetValue == 1 )
{
- printf( "Networks are equivalent after structural hashing.\n" );
+ printf( "Networks are equivalent after structural hashing. " );
Abc_NtkDelete( pMiter );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return;
}
/*
@@ -220,18 +223,19 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
// pParams->fVerbose = 1;
RetValue = Abc_NtkIvyProve( &pMiter, pParams );
if ( RetValue == -1 )
- printf( "Networks are undecided (resource limits is reached).\n" );
+ printf( "Networks are undecided (resource limits is reached). " );
else if ( RetValue == 0 )
{
int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel );
if ( pSimInfo[0] != 1 )
printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" );
else
- printf( "Networks are NOT EQUIVALENT.\n" );
+ printf( "Networks are NOT EQUIVALENT. " );
ABC_FREE( pSimInfo );
}
else
- printf( "Networks are equivalent.\n" );
+ printf( "Networks are equivalent. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
if ( pMiter->pModel )
Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel );
Abc_NtkDelete( pMiter );
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
index 0b7c1788..853f5710 100644
--- a/src/base/cmd/cmd.c
+++ b/src/base/cmd/cmd.c
@@ -60,6 +60,7 @@ static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv
static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandStarter ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandAutoTuner ( Abc_Frame_t * pAbc, int argc, char ** argv );
extern int Cmd_CommandAbcLoadPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -110,6 +111,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1 );
Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0 );
Cmd_CommandAdd( pAbc, "Various", "starter", CmdCommandStarter, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "autotuner", CmdCommandAutoTuner, 0 );
Cmd_CommandAdd( pAbc, "Various", "load_plugin", Cmd_CommandAbcLoadPlugIn, 0 );
}
@@ -1147,26 +1149,7 @@ usage:
#if defined(WIN32) && !defined(__cplusplus)
#include <direct.h>
-
-// these structures are defined in <io.h> but are for some reason invisible
-typedef unsigned long _fsize_t; // Could be 64 bits for Win32
-
-struct _finddata_t {
- unsigned attrib;
- time_t time_create; // -1 for FAT file systems
- time_t time_access; // -1 for FAT file systems
- time_t time_write;
- _fsize_t size;
- char name[260];
-};
-
-extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
-extern int _findnext( long handle, struct _finddata_t *fileinfo );
-extern int _findclose( long handle );
-
-//extern char * _getcwd( char * buffer, int maxlen );
-//extern int _chdir( const char *dirname );
-
+#include <io.h>
/**Function*************************************************************
@@ -2476,6 +2459,118 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores );
+ FILE * pFile;
+ char * pFileConf = NULL;
+ char * pFileList = NULL;
+ char * pFileName;
+ int c, nCores = 3;
+ int fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NCFvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nCores = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nCores < 0 )
+ goto usage;
+ break;
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by a string (possibly in quotes).\n" );
+ goto usage;
+ }
+ pFileConf = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by a string (possibly in quotes).\n" );
+ goto usage;
+ }
+ pFileList = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pFileConf == NULL )
+ {
+ Abc_Print( -2, "File containing configuration for autotuning is not given.\n" );
+ return 1;
+ }
+ if ( pFileList == NULL )
+ {
+ Abc_Print( -2, "File contining list of files for autotuning is not given.\n" );
+ return 1;
+ }
+ // get the input file name
+ pFileName = pFileConf;
+ if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL )
+// if ( (pFile = fopen( pFileName, "rb" )) == NULL )
+ {
+ Abc_Print( -2, "Cannot open configuration file \"%s\". ", pFileName );
+ if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) ))
+ Abc_Print( -2, "Did you mean \"%s\"?", pFileName );
+ Abc_Print( -2, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ // get the input file name
+ pFileName = pFileList;
+ if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL )
+// if ( (pFile = fopen( pFileName, "rb" )) == NULL )
+ {
+ Abc_Print( -2, "Cannot open the file list \"%s\". ", pFileName );
+ if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) ))
+ Abc_Print( -2, "Did you mean \"%s\"?", pFileName );
+ Abc_Print( -2, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ // run commands
+ Cmd_RunAutoTuner( pFileConf, pFileList, nCores );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" );
+ Abc_Print( -2, "\t performs autotuning\n" );
+ Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores );
+ Abc_Print( -2, "\t-C cmd : configuration file with settings for autotuning\n" );
+ Abc_Print( -2, "\t-F cmd : list of AIGER files to be used for autotuning\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
/**Function********************************************************************
Synopsis [Print the version string.]
diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c
new file mode 100644
index 00000000..8151c2e5
--- /dev/null
+++ b/src/base/cmd/cmdAuto.c
@@ -0,0 +1,684 @@
+/**CFile****************************************************************
+
+ FileName [cmdAuto.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Autotuner.]
+
+ Author [Alan Mishchenko, Bruno Schmitt]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdAuto.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "misc/util/abc_global.h"
+#include "misc/extra/extra.h"
+#include "aig/gia/gia.h"
+#include "sat/satoko/satoko.h"
+
+#ifdef ABC_USE_PTHREADS
+
+#ifdef _WIN32
+#include "../lib/pthread.h"
+#else
+#include <pthread.h>
+#include <unistd.h>
+#endif
+
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string
+#define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call
+
+extern int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Printing option structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts )
+{
+ printf( "-C %d ", (int)pOpts->conf_limit );
+ printf( "-V %.3f ", (float)pOpts->var_decay );
+ printf( "-W %.3f ", (float)pOpts->clause_decay );
+ if ( pOpts->verbose )
+ printf( "-v" );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [The main evaluation procedure for an array of AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts )
+{
+ Gia_Man_t * pGia;
+ int i, TotalCost = 0;
+ //printf( "Tuning with options: " );
+ //Cmd_RunAutoTunerPrintOptions( pOpts );
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
+ TotalCost += Gia_ManSatokoCallOne( pGia, pOpts, -1 );
+ return TotalCost;
+}
+
+/**Function*************************************************************
+
+ Synopsis [The main evaluation procedure for the set of AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#ifndef ABC_USE_PTHREADS
+
+int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nCores )
+{
+ return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts );
+}
+
+#else // pthreads are used
+
+
+#define CMD_THR_MAX 100
+typedef struct Cmd_AutoData_t_
+{
+ Gia_Man_t * pGia;
+ satoko_opts_t * pOpts;
+ int iThread;
+ int nTimeOut;
+ int fWorking;
+ int Result;
+} Cmd_AutoData_t;
+
+void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg )
+{
+ Cmd_AutoData_t * pThData = (Cmd_AutoData_t *)pArg;
+ volatile int * pPlace = &pThData->fWorking;
+ while ( 1 )
+ {
+ while ( *pPlace == 0 );
+ assert( pThData->fWorking );
+ if ( pThData->pGia == NULL ) // kills itself when there is nothing to do
+ {
+ pthread_exit( NULL );
+ assert( 0 );
+ return NULL;
+ }
+ pThData->Result = Gia_ManSatokoCallOne( pThData->pGia, pThData->pOpts, -1 );
+ pThData->fWorking = 0;
+ }
+ assert( 0 );
+ return NULL;
+}
+int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs )
+{
+ Cmd_AutoData_t ThData[CMD_THR_MAX];
+ pthread_t WorkerThread[CMD_THR_MAX];
+ int i, status, fWorkToDo = 1, TotalCost = 0;
+ Vec_Ptr_t * vStack;
+ if ( nProcs == 1 )
+ return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts );
+ // subtract manager thread
+ nProcs--;
+ assert( nProcs >= 1 && nProcs <= CMD_THR_MAX );
+ // start threads
+ for ( i = 0; i < nProcs; i++ )
+ {
+ ThData[i].pGia = NULL;
+ ThData[i].pOpts = pOpts;
+ ThData[i].iThread = i;
+ ThData[i].nTimeOut = -1;
+ ThData[i].fWorking = 0;
+ ThData[i].Result = -1;
+ status = pthread_create( WorkerThread + i, NULL,Cmd_RunAutoTunerEvalWorkerThread, (void *)(ThData + i) ); assert( status == 0 );
+ }
+ // look at the threads
+ vStack = Vec_PtrDup(vAigs);
+ while ( fWorkToDo )
+ {
+ fWorkToDo = (int)(Vec_PtrSize(vStack) > 0);
+ for ( i = 0; i < nProcs; i++ )
+ {
+ // check if this thread is working
+ if ( ThData[i].fWorking )
+ {
+ fWorkToDo = 1;
+ continue;
+ }
+ // check if this thread has recently finished
+ if ( ThData[i].pGia != NULL )
+ {
+ assert( ThData[i].Result >= 0 );
+ TotalCost += ThData[i].Result;
+ ThData[i].pGia = NULL;
+ }
+ if ( Vec_PtrSize(vStack) == 0 )
+ continue;
+ // give this thread a new job
+ assert( ThData[i].pGia == NULL );
+ ThData[i].pGia = (Gia_Man_t *)Vec_PtrPop( vStack );
+ ThData[i].fWorking = 1;
+ }
+ }
+ Vec_PtrFree( vStack );
+ // stop threads
+ for ( i = 0; i < nProcs; i++ )
+ {
+ assert( !ThData[i].fWorking );
+ // stop
+ ThData[i].pGia = NULL;
+ ThData[i].fWorking = 1;
+ }
+ return TotalCost;
+}
+
+#endif // pthreads are used
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives all possible param stucts according to the config file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Cmd_DeriveConvertIntoString( int argc, char ** argv )
+{
+ char pBuffer[CMD_AUTO_LINE_MAX] = {0};
+ int i;
+ for ( i = 0; i < argc; i++ )
+ {
+ strcat( pBuffer, argv[i] );
+ strcat( pBuffer, " " );
+ }
+ return Abc_UtilStrsav(pBuffer);
+}
+satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv )
+{
+ int c;
+ satoko_opts_t opts, * pOpts;
+ satoko_default_opts(&opts);
+ Extra_UtilGetoptReset();
+#ifdef SATOKO_ACT_VAR_FIXED
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF )
+#else
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF )
+#endif
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.conf_limit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.conf_limit < 0 )
+ return NULL;
+ break;
+ case 'P':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.prop_limit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.prop_limit < 0 )
+ return NULL;
+ break;
+ case 'D':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.f_rst = atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.f_rst < 0 )
+ return NULL;
+ break;
+ case 'E':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.b_rst = atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.b_rst < 0 )
+ return NULL;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'G':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'H':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'J':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'L':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'M':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100;
+ globalUtilOptind++;
+ if ( opts.learnt_ratio < 0 )
+ return NULL;
+ break;
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100;
+ globalUtilOptind++;
+ if ( opts.garbage_max_ratio < 0 )
+ return NULL;
+ break;
+ case 'O':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'Q':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
+ return NULL;
+ }
+ opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
+ case 'R':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.clause_decay = atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.clause_decay < 0 )
+ return NULL;
+ break;
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.var_decay = atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( opts.var_decay < 0 )
+ return NULL;
+ break;
+#ifdef SATOKO_ACT_VAR_FIXED
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16);
+ globalUtilOptind++;
+ break;
+ case 'U':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" );
+ return NULL;
+ }
+ opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16);
+ globalUtilOptind++;
+ break;
+#endif
+ case 'h':
+ return NULL;
+ case 'v':
+ opts.verbose ^= 1;
+ break;
+
+ default:
+ return NULL;
+ }
+ }
+ // return a copy of this parameter structure
+ pOpts = ABC_ALLOC( satoko_opts_t, 1 );
+ memcpy( pOpts, &opts, sizeof(satoko_opts_t) );
+ return pOpts;
+}
+void Cmf_CreateOptions_rec( Vec_Wec_t * vPars, int iPar, char Argv[CMD_AUTO_ARG_MAX][20], int Argc, Vec_Ptr_t * vOpts )
+{
+ Vec_Int_t * vLine;
+ int Symb, Num, i;
+ assert( Argc <= CMD_AUTO_ARG_MAX );
+ if ( Vec_WecSize(vPars) == iPar )
+ {
+ satoko_opts_t * pOpts;
+ char * pArgv[CMD_AUTO_ARG_MAX];
+ for ( i = 0; i < Argc; i++ )
+ pArgv[i] = Argv[i];
+ pOpts = Cmd_DeriveOptionFromSettings( Argc, pArgv );
+ if ( pOpts == NULL )
+ printf( "Cannot parse command line options...\n" );
+ else
+ {
+ Vec_PtrPush( vOpts, pOpts );
+ Vec_PtrPush( vOpts, Cmd_DeriveConvertIntoString(Argc, pArgv) );
+ printf( "Adding settings %s\n", (char *)Vec_PtrEntryLast(vOpts) );
+ }
+ return;
+ }
+ vLine = Vec_WecEntry( vPars, iPar );
+ // consider binary option
+ if ( Vec_IntSize(vLine) == 2 )
+ {
+ Symb = Vec_IntEntry( vLine, 0 );
+ Num = Vec_IntEntry( vLine, 1 );
+ assert( Abc_Int2Float(Num) == -1.0 );
+ // create one setting without this option
+ Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc, vOpts );
+ // create another setting with this option
+ sprintf( Argv[Argc], "-%c", Symb );
+ Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+1, vOpts );
+ return;
+ }
+ // consider numeric option
+ Vec_IntForEachEntryDouble( vLine, Symb, Num, i )
+ {
+ float NumF = Abc_Int2Float(Num);
+ // create setting with this option
+ assert( NumF >= 0 );
+ sprintf( Argv[Argc], "-%c", Symb );
+ if ( NumF == (float)(int)NumF )
+ sprintf( Argv[Argc+1], "%d", (int)NumF );
+ else
+ sprintf( Argv[Argc+1], "%.3f", NumF );
+ Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+2, vOpts );
+ }
+}
+Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars )
+{
+ char Argv[CMD_AUTO_ARG_MAX][20];
+ int Symb, Num, i, Argc = 0;
+ Vec_Ptr_t * vOpts = Vec_PtrAlloc( 100 );
+ Vec_Int_t * vLine = Vec_WecEntry( vPars, 0 );
+ printf( "Creating all possible settings to be used by the autotuner:\n" );
+ sprintf( Argv[Argc++], "autotuner" );
+ Vec_IntForEachEntryDouble( vLine, Symb, Num, i )
+ {
+ float NumF = Abc_Int2Float(Num);
+ sprintf( Argv[Argc++], "-%c", Symb );
+ if ( NumF < 0.0 )
+ continue;
+ if ( NumF == (float)(int)NumF )
+ sprintf( Argv[Argc++], "%d", (int)NumF );
+ else
+ sprintf( Argv[Argc++], "%.3f", NumF );
+ }
+ Cmf_CreateOptions_rec( vPars, 1, Argv, Argc, vOpts );
+ printf( "Finished creating %d settings.\n\n", Vec_PtrSize(vOpts)/2 );
+ return vOpts;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Parses config file and derives AIGs listed in file list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; }
+static inline int Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; }
+static inline int Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; }
+static inline int Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; }
+
+Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig )
+{
+ Vec_Wec_t * vPars;
+ Vec_Int_t * vLine;
+ char * pThis, pBuffer[CMD_AUTO_LINE_MAX];
+ FILE * pFile = fopen( pConfig, "rb" );
+ if ( pFile == NULL )
+ { printf( "File containing list of files \"%s\" cannot be opened.\n", pConfig ); return NULL; }
+ vPars = Vec_WecAlloc( 100 );
+ while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL )
+ {
+ // get the command from the file
+ if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#')
+ continue;
+ // skip trailing spaces
+ while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) )
+ pBuffer[strlen(pBuffer)-1] = 0;
+ // read the line
+ vLine = Vec_WecPushLevel( vPars );
+ for ( pThis = pBuffer; *pThis; )
+ {
+ if ( Cmf_IsLowerCaseChar(*pThis) )
+ {
+ Vec_IntPushTwo( vLine, (int)*pThis, Abc_Float2Int((float)-1.0) );
+ pThis++;
+ while ( Cmf_IsSpace(*pThis) )
+ pThis++;
+ continue;
+ }
+ if ( Cmf_IsUpperCaseChar(*pThis) )
+ {
+ char Param = *pThis++;
+ if ( !Cmf_IsDigit(*pThis) )
+ { printf( "Upper-case character (%c) should be followed by a number without space in line \"%s\".\n", Param, pBuffer ); return NULL; }
+ Vec_IntPushTwo( vLine, (int)Param, Abc_Float2Int(atof(pThis)) );
+ while ( Cmf_IsDigit(*pThis) )
+ pThis++;
+ while ( Cmf_IsSpace(*pThis) )
+ pThis++;
+ continue;
+ }
+ printf( "Expecting a leading lower-case or upper-case digit in line \"%s\".\n", pBuffer );
+ return NULL;
+ }
+ }
+ fclose( pFile );
+ return vPars;
+}
+Vec_Ptr_t * Cmd_ReadFiles( char * pFileList )
+{
+ Gia_Man_t * pGia;
+ Vec_Ptr_t * vAigs;
+ char pBuffer[CMD_AUTO_LINE_MAX];
+ FILE * pFile = fopen( pFileList, "rb" );
+ if ( pFile == NULL )
+ { printf( "File containing list of files \"%s\" cannot be opened.\n", pFileList ); return NULL; }
+ vAigs = Vec_PtrAlloc( 100 );
+ while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL )
+ {
+ // get the command from the file
+ if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#')
+ continue;
+ // skip trailing spaces
+ while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) )
+ pBuffer[strlen(pBuffer)-1] = 0;
+ // read the file
+ pGia = Gia_AigerRead( pBuffer, 0, 0, 0 );
+ if ( pGia == NULL )
+ {
+ printf( "Cannot read AIG from file \"%s\".\n", pBuffer );
+ continue;
+ }
+ Vec_PtrPush( vAigs, pGia );
+ }
+ fclose( pFile );
+ return vAigs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Autotuner for SAT solver "satoko".]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wec_t * vPars = Cmd_ReadParamChoices( pConfig );
+ Vec_Ptr_t * vAigs = Cmd_ReadFiles( pFileList );
+ Vec_Ptr_t * vOpts = vPars ? Cmf_CreateOptions( vPars ) : NULL;
+ int i; char * pString, * pStringBest = NULL;
+ satoko_opts_t * pOpts, * pOptsBest = NULL;
+ int Result, ResultBest = 0x7FFFFFFF;
+ Gia_Man_t * pGia;
+ // iterate through all possible option settings
+ if ( vAigs && vOpts )
+ {
+ Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i )
+ {
+ abctime clk = Abc_Clock();
+ printf( "Evaluating settings: %20s... \n", pString );
+ Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores );
+ printf( "Cost = %6d. ", Result );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( ResultBest > Result )
+ {
+ ResultBest = Result;
+ pStringBest = pString;
+ pOptsBest = pOpts;
+ }
+ }
+ printf( "The best settings are: %20s \n", pStringBest );
+ printf( "Best cost = %6d. ", ResultBest );
+ Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
+ }
+ // cleanup
+ if ( vPars ) Vec_WecFree( vPars );
+ if ( vOpts ) Vec_PtrFreeFree( vOpts );
+ if ( vAigs )
+ {
+ Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
+ Gia_ManStop( pGia );
+ Vec_PtrFree( vAigs );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c
index 7f7c1b60..accd9440 100644
--- a/src/base/cmd/cmdLoad.c
+++ b/src/base/cmd/cmdLoad.c
@@ -97,26 +97,7 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv )
#if defined(WIN32) && !defined(__cplusplus)
#include <direct.h>
-
-
-// these structures are defined in <io.h> but are for some reason invisible
-typedef unsigned long _fsize_t; // Could be 64 bits for Win32
-
-struct _finddata_t {
- unsigned attrib;
- time_t time_create; // -1 for FAT file systems
- time_t time_access; // -1 for FAT file systems
- time_t time_write;
- _fsize_t size;
- char name[260];
-};
-
-extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
-extern int _findnext( long handle, struct _finddata_t *fileinfo );
-extern int _findclose( long handle );
-
-//extern char * _getcwd( char * buffer, int maxlen );
-//extern int _chdir( const char *dirname );
+#include <io.h>
/**Function*************************************************************
diff --git a/src/base/cmd/module.make b/src/base/cmd/module.make
index b09ffa81..1042fbb0 100644
--- a/src/base/cmd/module.make
+++ b/src/base/cmd/module.make
@@ -1,6 +1,7 @@
SRC += src/base/cmd/cmd.c \
src/base/cmd/cmdAlias.c \
src/base/cmd/cmdApi.c \
+ src/base/cmd/cmdAuto.c \
src/base/cmd/cmdFlag.c \
src/base/cmd/cmdHist.c \
src/base/cmd/cmdLoad.c \
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 093eccca..2e1ae591 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -2150,7 +2150,7 @@ int IoCommandWriteCnf2( Abc_Frame_t * pAbc, int argc, char **argv )
extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
FILE * pFile;
char * pFileName;
- int nLutSize = 6;
+ int nLutSize = 8;
int fNewAlgo = 1;
int fCnfObjIds = 0;
int fAddOrCla = 1;
@@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv )
Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose );
}
else
- pCare = Bmc_CexCareMinimize( pAig, pCex, fCheckCex, fVerbose );
+ pCare = Bmc_CexCareMinimize( pAig, Saig_ManPiNum(pAig), pCex, 4, fCheckCex, fVerbose );
Aig_ManStop( pAig );
}
// output flop values (unaffected by the minimization)
diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c
index 3431c761..d9687c6e 100644
--- a/src/base/io/ioWriteDot.c
+++ b/src/base/io/ioWriteDot.c
@@ -394,7 +394,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pFanin->Id );
- fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
+ fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" );
// fprintf( pFile, ", label = \"%c\"", 'a' + k );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
@@ -764,7 +764,7 @@ void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pFanin->Id );
- fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
+ fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" );
// fprintf( pFile, ", label = \"%c\"", 'a' + k );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c
index 05cb09c1..9647d020 100644
--- a/src/base/main/mainFrame.c
+++ b/src/base/main/mainFrame.c
@@ -95,8 +95,6 @@ void Abc_FrameSetStatus( int Status ) { ABC_FREE( s_Globa
void Abc_FrameSetManDsd( void * pMan ) { if (s_GlobalFrame->pManDsd && s_GlobalFrame->pManDsd != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd, 0); s_GlobalFrame->pManDsd = pMan; }
void Abc_FrameSetManDsd2( void * pMan ) { if (s_GlobalFrame->pManDsd2 && s_GlobalFrame->pManDsd2 != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd2, 0); s_GlobalFrame->pManDsd2 = pMan; }
void Abc_FrameSetInv( Vec_Int_t * vInv ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcInv); s_GlobalFrame->pAbcWlcInv = vInv; }
-void Abc_FrameSetCnf( Vec_Int_t * vCnf ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcCnf); s_GlobalFrame->pAbcWlcCnf = vCnf; }
-void Abc_FrameSetStr( Vec_Str_t * vStr ) { Vec_StrFreeP(&s_GlobalFrame->pAbcWlcStr); s_GlobalFrame->pAbcWlcStr = vStr; }
void Abc_FrameSetJsonStrs( Abc_Nam_t * pStrs ) { Abc_NamDeref( s_GlobalFrame->pJsonStrs ); s_GlobalFrame->pJsonStrs = pStrs; }
void Abc_FrameSetJsonObjs( Vec_Wec_t * vObjs ) { Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); s_GlobalFrame->vJsonObjs = vObjs; }
@@ -227,8 +225,6 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
ABC_FREE( p->pCex2 );
ABC_FREE( p->pCex );
Vec_IntFreeP( &p->pAbcWlcInv );
- Vec_IntFreeP( &p->pAbcWlcCnf );
- Vec_StrFreeP( &p->pAbcWlcStr );
Abc_NamDeref( s_GlobalFrame->pJsonStrs );
Vec_WecFreeP(&s_GlobalFrame->vJsonObjs );
ABC_FREE( p );
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
index ff59b81a..278a9191 100644
--- a/src/base/main/mainInt.h
+++ b/src/base/main/mainInt.h
@@ -129,8 +129,6 @@ struct Abc_Frame_t_
void * pAbc85Delay;
void * pAbcWlc;
Vec_Int_t * pAbcWlcInv;
- Vec_Int_t * pAbcWlcCnf;
- Vec_Str_t * pAbcWlcStr;
void * pAbcBac;
void * pAbcCba;
void * pAbcPla;
diff --git a/src/base/main/mainReal.c b/src/base/main/mainReal.c
index ee43d38d..31bfef75 100644
--- a/src/base/main/mainReal.c
+++ b/src/base/main/mainReal.c
@@ -196,7 +196,7 @@ int Abc_RealMain( int argc, char * argv[] )
case 't':
if ( TypeCheck( pAbc, globalUtilOptarg ) )
{
- if ( !strcmp(globalUtilOptarg, "none") == 0 )
+ if ( (!strcmp(globalUtilOptarg, "none")) == 0 )
{
fInitRead = 1;
sprintf( sReadCmd, "read_%s", globalUtilOptarg );
@@ -211,7 +211,7 @@ int Abc_RealMain( int argc, char * argv[] )
case 'T':
if ( TypeCheck( pAbc, globalUtilOptarg ) )
{
- if (!strcmp(globalUtilOptarg, "none") == 0)
+ if ( (!strcmp(globalUtilOptarg, "none")) == 0)
{
fFinalWrite = 1;
sprintf( sWriteCmd, "write_%s", globalUtilOptarg);
diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make
index 5a95a63f..c4330264 100644
--- a/src/base/wlc/module.make
+++ b/src/base/wlc/module.make
@@ -1,4 +1,5 @@
SRC += src/base/wlc/wlcAbs.c \
+ src/base/wlc/wlcAbs2.c \
src/base/wlc/wlcAbc.c \
src/base/wlc/wlcBlast.c \
src/base/wlc/wlcCom.c \
@@ -7,6 +8,8 @@ SRC += src/base/wlc/wlcAbs.c \
src/base/wlc/wlcReadSmt.c \
src/base/wlc/wlcReadVer.c \
src/base/wlc/wlcSim.c \
+ src/base/wlc/wlcShow.c \
src/base/wlc/wlcStdin.c \
+ src/base/wlc/wlcUif.c \
src/base/wlc/wlcWin.c \
src/base/wlc/wlcWriteVer.c
diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h
index 1df3e5e9..686d9f00 100644
--- a/src/base/wlc/wlc.h
+++ b/src/base/wlc/wlc.h
@@ -140,6 +140,7 @@ struct Wlc_Ntk_t_
int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type
int nAnds[WLC_OBJ_NUMBER]; // counter of AND gates after blasting
int fSmtLib; // the network comes from an SMT-LIB file
+ int nAssert; // the number of asserts
// memory for objects
Wlc_Obj_t * pObjs;
int iObj;
@@ -156,6 +157,23 @@ struct Wlc_Ntk_t_
Vec_Int_t vTravIds; // trav IDs of the objects
Vec_Int_t vCopies; // object first bits
Vec_Int_t vBits; // object mapping into AIG nodes
+ Vec_Int_t vLevels; // object levels
+ Vec_Int_t vRefs; // object reference counters
+};
+
+typedef struct Wlc_Par_t_ Wlc_Par_t;
+struct Wlc_Par_t_
+{
+ int nBitsAdd; // adder bit-width
+ int nBitsMul; // multiplier bit-widht
+ int nBitsMux; // MUX bit-width
+ int nBitsFlop; // flop bit-width
+ int nIterMax; // the max number of iterations
+ int fXorOutput; // XOR outputs of word-level miter
+ int fCheckClauses; // Check clauses in the reloaded trace
+ int fPushClauses; // Push clauses in the reloaded trace
+ int fVerbose; // verbose output
+ int fPdrVerbose; // verbose output
};
static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; }
@@ -205,6 +223,8 @@ static inline int Wlc_ObjSign( Wlc_Obj_t * p )
static inline int * Wlc_ObjConstValue( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_CONST); return Wlc_ObjFanins(p); }
static inline int Wlc_ObjTableId( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_TABLE); return p->Fanins[1]; }
static inline word * Wlc_ObjTable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return (word *)Vec_PtrEntry( p->vTables, Wlc_ObjTableId(pObj) ); }
+static inline int Wlc_ObjLevelId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vLevels, iObj ); }
+static inline int Wlc_ObjLevel( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_ObjLevelId( p, Wlc_ObjId(p, pObj) ); }
static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vCopies, p->nObjsAlloc, 0 ); }
static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; }
@@ -217,7 +237,8 @@ static inline int Wlc_NtkHasNameId( Wlc_Ntk_t * p )
static inline void Wlc_ObjSetNameId( Wlc_Ntk_t * p, int iObj, int i ) { Vec_IntWriteEntry( &p->vNameIds, iObj, i ); }
static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vNameIds, iObj ); }
-static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkCoNum(p) - Wlc_NtkCiNum(p) + Wlc_ObjCiId(pObj)); }
+static inline Wlc_Obj_t * Wlc_ObjFo2Fi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkPoNum(p) + Wlc_ObjCiId(pObj) - Wlc_NtkPiNum(p)); }
+static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) { return iCoId < Wlc_NtkPoNum(p) ? Wlc_NtkPo(p, iCoId) : Wlc_NtkCi(p, Wlc_NtkPiNum(p) + iCoId - Wlc_NtkPoNum(p)); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
@@ -229,6 +250,8 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
#define Wlc_NtkForEachObj( p, pObj, i ) \
for ( i = 1; (i < Wlc_NtkObjNumMax(p)) && (((pObj) = Wlc_NtkObj(p, i)), 1); i++ )
+#define Wlc_NtkForEachObjReverse( p, pObj, i ) \
+ for ( i = Wlc_NtkObjNumMax(p) - 1; (i > 0) && (((pObj) = Wlc_NtkObj(p, i)), 1); i-- )
#define Wlc_NtkForEachObjVec( vVec, p, pObj, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && (((pObj) = Wlc_NtkObj(p, Vec_IntEntry(vVec, i))), 1); i++ )
#define Wlc_NtkForEachPi( p, pPi, i ) \
@@ -255,16 +278,17 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
////////////////////////////////////////////////////////////////////////
/*=== wlcAbs.c ========================================================*/
-extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 );
-extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p );
-extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p );
-extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes );
-extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs );
+extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
+extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
+/*=== wlcAbs2.c ========================================================*/
+extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
/*=== wlcBlast.c ========================================================*/
extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth );
/*=== wlcCom.c ========================================================*/
extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk );
/*=== wlcNtk.c ========================================================*/
+extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars );
+extern char * Wlc_ObjTypeName( Wlc_Obj_t * p );
extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc );
extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg );
extern int Wlc_ObjCreate( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg, Vec_Int_t * vFanins );
@@ -274,13 +298,25 @@ extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj );
extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type );
extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins );
extern void Wlc_NtkFree( Wlc_Ntk_t * p );
+extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p );
+extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p );
+extern int Wlc_NtkCountRealPis( Wlc_Ntk_t * p );
extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj );
extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray );
extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type );
-extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose );
-extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p );
+extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose );
extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p );
+extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq );
+extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq );
+extern Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops );
+extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p );
+extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis );
+extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p );
extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p );
+extern void Wlc_NtkShortNames( Wlc_Ntk_t * p );
+extern int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p );
+extern void Wlc_NtkSetRefs( Wlc_Ntk_t * p );
+extern int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew );
/*=== wlcReadSmt.c ========================================================*/
extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree );
extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree );
@@ -291,6 +327,12 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p );
extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd );
/*=== wlcReadVer.c ========================================================*/
extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr );
+/*=== wlcUif.c ========================================================*/
+extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 );
+extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p );
+extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p );
+extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes );
+extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs );
/*=== wlcWin.c =============================================================*/
extern void Wlc_WinProfileArith( Wlc_Ntk_t * p );
/*=== wlcWriteVer.c ========================================================*/
diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c
index 0bf27f7b..1836f4ed 100644
--- a/src/base/wlc/wlcAbc.c
+++ b/src/base/wlc/wlcAbc.c
@@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
+void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose )
{
Wlc_Obj_t * pObj;
int i, k, nNum, nRange, nBits = 0;
@@ -53,7 +53,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
nRange = Wlc_ObjRange(pObj);
for ( k = 0; k < nRange; k++ )
{
- nNum = Vec_IntEntry(vInv, nBits + k);
+ nNum = Vec_IntEntry(vCounts, nBits + k);
if ( nNum )
break;
}
@@ -65,7 +65,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
for ( k = 0; k < nRange; k++ )
{
- nNum = Vec_IntEntry( vInv, nBits + k );
+ nNum = Vec_IntEntry( vCounts, nBits + k );
if ( nNum == 0 )
continue;
printf( " [%d] -> %d", k, nNum );
@@ -73,8 +73,8 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
printf( "\n");
nBits += nRange;
}
- //printf( "%d %d\n", Vec_IntSize(vInv), nBits );
- assert( Vec_IntSize(vInv) == nBits );
+ //printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
+ assert( Vec_IntSize(vCounts) == nBits );
}
/**Function*************************************************************
@@ -88,8 +88,14 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose )
+Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv )
{
+ extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
+ extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts );
+
+ Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
+ Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts );
+
Wlc_Obj_t * pObj;
int i, k, nNum, nRange, nBits = 0;
Abc_Ntk_t * pMainNtk = NULL;
@@ -98,46 +104,69 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop,
// start the network
pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
// duplicate the name and the spec
- pMainNtk->pName = Extra_UtilStrsav(pNtk->pName);
+ pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv");
// create primary inputs
- Wlc_NtkForEachCi( pNtk, pObj, i )
+ if ( pNtk == NULL )
{
- if ( pObj->Type != WLC_OBJ_FO )
- continue;
- nRange = Wlc_ObjRange(pObj);
- for ( k = 0; k < nRange; k++ )
+ int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) );
+ Vec_IntForEachEntry( vCounts, Entry, i )
{
- nNum = Vec_IntEntry(vInv, nBits + k);
- if ( nNum )
- break;
+ if ( Entry == 0 )
+ continue;
+ pMainObj = Abc_NtkCreatePi( pMainNtk );
+ sprintf( Buffer, "pi%d", i );
+ Abc_ObjAssignName( pMainObj, Buffer, NULL );
}
- if ( k == nRange )
+ if ( Abc_NtkPiNum(pMainNtk) != nInputs )
{
- nBits += nRange;
- continue;
+ printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" );
+ Abc_NtkDelete( pMainNtk );
+ return NULL;
}
- //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
- for ( k = 0; k < nRange; k++ )
+ }
+ else
+ {
+ Wlc_NtkForEachCi( pNtk, pObj, i )
{
- nNum = Vec_IntEntry( vInv, nBits + k );
- if ( nNum == 0 )
+ if ( pObj->Type != WLC_OBJ_FO )
continue;
- //printf( " [%d] -> %d", k, nNum );
- pMainObj = Abc_NtkCreatePi( pMainNtk );
- sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
- Abc_ObjAssignName( pMainObj, Buffer, NULL );
+ nRange = Wlc_ObjRange(pObj);
+ for ( k = 0; k < nRange; k++ )
+ {
+ nNum = Vec_IntEntry(vCounts, nBits + k);
+ if ( nNum )
+ break;
+ }
+ if ( k == nRange )
+ {
+ nBits += nRange;
+ continue;
+ }
+ //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
+ for ( k = 0; k < nRange; k++ )
+ {
+ nNum = Vec_IntEntry( vCounts, nBits + k );
+ if ( nNum == 0 )
+ continue;
+ //printf( " [%d] -> %d", k, nNum );
+ pMainObj = Abc_NtkCreatePi( pMainNtk );
+ sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
+ Abc_ObjAssignName( pMainObj, Buffer, NULL );
+ }
+ //printf( "\n");
+ nBits += nRange;
}
- //printf( "\n");
- nBits += nRange;
}
- //printf( "%d %d\n", Vec_IntSize(vInv), nBits );
- assert( Vec_IntSize(vInv) == nBits );
+ //printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
+ assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits );
// create node
pMainObj = Abc_NtkCreateNode( pMainNtk );
Abc_NtkForEachPi( pMainNtk, pMainTemp, i )
Abc_ObjAddFanin( pMainObj, pMainTemp );
pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) );
+ Vec_IntFree( vCounts );
+ Vec_StrFree( vSop );
// create PO
pMainTemp = Abc_NtkCreatePo( pMainNtk );
Abc_ObjAddFanin( pMainTemp, pMainObj );
@@ -145,6 +174,98 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop,
return pMainNtk;
}
+/**Function*************************************************************
+
+ Synopsis [Translate current network into an invariant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia )
+{
+ int nRegs = Gia_ManRegNum(pGia);
+ Vec_Int_t * vRes = NULL;
+ if ( Abc_NtkPoNum(pNtk) != 1 )
+ printf( "The number of outputs is other than 1.\n" );
+ else if ( Abc_NtkNodeNum(pNtk) != 1 )
+ printf( "The number of internal nodes is other than 1.\n" );
+ else
+ {
+ Abc_Nam_t * pNames = NULL;
+ Abc_Obj_t * pFanin, * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) );
+ char * pName, * pCube, * pSop = (char *)pNode->pData;
+ Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) );
+ int i, k, Value, nLits, Counter = 0;
+ if ( pGia->vNamesIn )
+ {
+ // hash the names
+ pNames = Abc_NamStart( 100, 16 );
+ Vec_PtrForEachEntry( char *, pGia->vNamesIn, pName, i )
+ {
+ Value = Abc_NamStrFindOrAdd( pNames, pName, NULL );
+ assert( Value == i+1 );
+ //printf( "%s(%d) ", pName, i );
+ }
+ //printf( "\n" );
+ }
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ assert( Abc_ObjIsCi(pFanin) );
+ pName = Abc_ObjName(pFanin);
+ if ( pNames )
+ {
+ Value = Abc_NamStrFind(pNames, pName) - 1 - Gia_ManPiNum(pGia);
+ if ( Value < 0 )
+ {
+ if ( Counter++ == 0 )
+ printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
+ Value = i;
+ }
+ }
+ else
+ {
+ for ( k = (int)strlen(pName)-1; k >= 0; k-- )
+ if ( pName[k] < '0' || pName[k] > '9' )
+ break;
+ if ( k == (int)strlen(pName)-1 )
+ {
+ if ( Counter++ == 0 )
+ printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
+ Value = i;
+ }
+ else
+ Value = atoi(pName + k + 1);
+ }
+ Vec_IntPush( vFanins, Value );
+ }
+ if ( Counter )
+ printf( "Cannot read names for %d inputs of the invariant.\n", Counter );
+ if ( pNames )
+ Abc_NamStop( pNames );
+ assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) );
+ vRes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) );
+ Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube )
+ {
+ nLits = 0;
+ Abc_CubeForEachVar( pCube, Value, k )
+ if ( Value != '-' )
+ nLits++;
+ Vec_IntPush( vRes, nLits );
+ Abc_CubeForEachVar( pCube, Value, k )
+ if ( Value != '-' )
+ Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') );
+ }
+ Vec_IntPush( vRes, nRegs );
+ Vec_IntFree( vFanins );
+ }
+ return vRes;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c
index 73ff7328..e33424f7 100644
--- a/src/base/wlc/wlcAbs.c
+++ b/src/base/wlc/wlcAbs.c
@@ -8,7 +8,7 @@
Synopsis [Abstraction for word-level networks.]
- Author [Alan Mishchenko]
+ Author [Yen-Sheng Ho, Alan Mishchenko]
Affiliation [UC Berkeley]
@@ -19,6 +19,10 @@
***********************************************************************/
#include "wlc.h"
+#include "proof/pdr/pdr.h"
+#include "proof/pdr/pdrInt.h"
+#include "aig/gia/giaAig.h"
+#include "sat/bmc/bmc.h"
ABC_NAMESPACE_IMPL_START
@@ -26,161 +30,330 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast );
+extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap );
+extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
- Synopsis [Check if two objects have the same input/output signatures.]
+ Synopsis [Mark operators that meet the abstraction criteria.]
- Description []
+ Description [This procedure returns the array of objects (vLeaves) that
+ should be abstracted because of their high bit-width. It uses input array (vUnmark)
+ to not abstract those objects that have been refined in the previous rounds.]
SideEffects []
SeeAlso []
***********************************************************************/
-int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 )
+static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
{
- Wlc_Obj_t * pFanin, * pFanin2; int k;
- if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) )
- return 0;
- if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) )
- return 0;
- if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) )
- return 0;
- for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
+ Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ Wlc_Obj_t * pObj; int i, Count[4] = {0};
+ Wlc_NtkForEachObj( p, pObj, i )
{
- pFanin = Wlc_ObjFanin(p, pObj, k);
- pFanin2 = Wlc_ObjFanin(p, pObj2, k);
- if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) )
- return 0;
- if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) )
- return 0;
+ if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
+ continue;
+ if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
+ continue;
+ }
+ if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
+ continue;
+ }
+ if ( pObj->Type == WLC_OBJ_MUX )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
+ continue;
+ }
+ if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
+ continue;
+ }
}
- return 1;
+ if ( fVerbose )
+ printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] );
+ return vLeaves;
}
/**Function*************************************************************
- Synopsis [Collect IDs of the multipliers.]
+ Synopsis [Marks nodes to be included in the abstracted network.]
- Description []
+ Description [Marks all objects that will be included in the abstracted model.
+ Stops at the objects (vLeaves) that are abstracted away. Returns three arrays:
+ a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the
+ set of flops present as flops in the abstracted network.]
SideEffects []
SeeAlso []
***********************************************************************/
-Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p )
+static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
- Wlc_Obj_t * pObj; int i;
- Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 );
+ int i, iFanin;
+ if ( pObj->Mark )
+ return;
+ pObj->Mark = 1;
+ if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
+ {
+ assert( !Wlc_ObjIsPi(pObj) );
+ Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
+ return;
+ }
+ if ( Wlc_ObjIsCi(pObj) )
+ {
+ if ( Wlc_ObjIsPi(pObj) )
+ Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
+ else
+ Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
+ return;
+ }
+ Wlc_ObjForEachFanin( pObj, iFanin, i )
+ Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
+}
+static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
+{
+ Wlc_Obj_t * pObj;
+ int i, Count = 0;
+ Wlc_NtkCleanMarks( p );
+ Wlc_NtkForEachCo( p, pObj, i )
+ Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
+
+/*
+ Vec_IntClear(vFlops);
+ Wlc_NtkForEachCi( p, pObj, i ) {
+ if ( !Wlc_ObjIsPi(pObj) ) {
+ Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
+ pObj->Mark = 1;
+ }
+ }
+*/
+
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
Wlc_NtkForEachObj( p, pObj, i )
- if ( pObj->Type == WLC_OBJ_ARI_MULTI )
- Vec_IntPush( vBoxIds, i );
- if ( Vec_IntSize( vBoxIds ) > 0 )
- return vBoxIds;
- Vec_IntFree( vBoxIds );
- return NULL;
+ Count += pObj->Mark;
+// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n",
+// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops),
+// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
+ Vec_IntSort( vPisOld, 0 );
+ Vec_IntSort( vPisNew, 0 );
+ Vec_IntSort( vFlops, 0 );
+ Wlc_NtkCleanMarks( p );
}
/**Function*************************************************************
- Synopsis [Returns all pairs of uifable multipliers.]
+ Synopsis [Derive word-level abstracted model based on the parameter values.]
- Description []
+ Description [Retuns the word-level abstracted network and the set of pseudo-PIs
+ (vPisNew), which were created during abstraction. If the abstraction is
+ satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs
+ and their MFFC cones will be listed in the array (vUnmark), which will
+ force the abstraction to not stop at these pseudo-PIs in the future.]
SideEffects []
SeeAlso []
***********************************************************************/
-Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p )
+static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, Vec_Int_t ** pvFlops, int fVerbose )
{
- Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p );
- Vec_Int_t * vPairs = Vec_IntAlloc( 2 );
- Wlc_Obj_t * pObj, * pObj2; int i, k;
- // iterate through unique pairs
- Wlc_NtkForEachObjVec( vMultis, p, pObj, i )
- Wlc_NtkForEachObjVec( vMultis, p, pObj2, k )
- {
- if ( k == i )
- break;
- if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) )
- {
- Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) );
- Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) );
- }
- }
- Vec_IntFree( vMultis );
- if ( Vec_IntSize( vPairs ) > 0 )
- return vPairs;
- Vec_IntFree( vPairs );
- return NULL;
+ Wlc_Ntk_t * pNtkNew = NULL;
+ Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
+ Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
+ Vec_Int_t * vFlops = Vec_IntAlloc( 100 );
+ Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
+ Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
+ Vec_BitFree( vLeaves );
+ pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
+ Vec_IntFree( vPisOld );
+ if ( pvFlops )
+ *pvFlops = vFlops;
+ else
+ Vec_IntFree( vFlops );
+ if ( pvPisNew )
+ *pvPisNew = vPisNew;
+ else
+ Vec_IntFree( vPisNew );
+ return pNtkNew;
}
+/**Function*************************************************************
+
+ Synopsis [Find what objects need to be un-abstracted.]
+
+ Description [Returns a subset of pseudo-PIs (vPisNew), which will be
+ prevented from being abstracted in the future rounds of abstraction.
+ The AIG manager (pGia) is a bit-level view of the abstracted model.
+ The counter-example (pCex) is used to find waht PPIs to refine.]
+
+ SideEffects []
+ SeeAlso []
+
+***********************************************************************/
+static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
+{
+ Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
+ Abc_Cex_t * pCexCare;
+ Wlc_Obj_t * pObj;
+ // count the number of bit-level PPIs and map them into word-level objects they were derived from
+ int f, i, b, nRealPis, nPpiBits = 0;
+ Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
+ Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
+ for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
+ Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
+ // since PPIs are ordered last, the previous bits are real PIs
+ nRealPis = pCex->nPis - nPpiBits;
+ // find the care-set
+ pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
+ assert( pCexCare->nPis == pCex->nPis );
+ // detect care PPIs
+ for ( f = 0; f <= pCexCare->iFrame; f++ )
+ for ( i = nRealPis; i < pCexCare->nPis; i++ )
+ if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
+ Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
+ Abc_CexFree( pCexCare );
+ Vec_IntFree( vMap );
+ if ( Vec_IntSize(vRefine) == 0 )// real CEX
+ Vec_IntFreeP( &vRefine );
+ return vRefine;
+}
/**Function*************************************************************
- Synopsis [Abstracts nodes by replacing their outputs with new PIs.]
+ Synopsis [Mark MFFC cones of the un-abstracted objects.]
- Description [If array is NULL, abstract all multipliers.]
+ Description [The MFFC cones of the objects in vRefine are traversed
+ and all their nodes are marked in vUnmark.]
SideEffects []
SeeAlso []
***********************************************************************/
-Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
+static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
{
- Vec_Int_t * vNodes = vNodesInit;
- Wlc_Ntk_t * pNew;
- Wlc_Obj_t * pObj;
- int i, k, iObj, iFanin;
- // get multipliers if not given
- if ( vNodes == NULL )
- vNodes = Wlc_NtkCollectMultipliers( p );
- if ( vNodes == NULL )
- return NULL;
- // mark nodes
- Wlc_NtkForEachObjVec( vNodes, p, pObj, i )
- pObj->Mark = 1;
- // iterate through the nodes in the DFS order
- Wlc_NtkCleanCopy( p );
- Wlc_NtkForEachObj( p, pObj, i )
+ int i, Fanin, Counter = 1;
+ if ( Wlc_ObjIsCi(pNode) )
+ return 0;
+ Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
+ Wlc_ObjForEachFanin( pNode, Fanin, i )
{
- if ( i == Vec_IntSize(&p->vCopies) )
- break;
- if ( pObj->Mark ) {
- // clean
- pObj->Mark = 0;
- // add fresh PI with the same number of bits
- iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 );
- }
- else {
- // update fanins
- Wlc_ObjForEachFanin( pObj, iFanin, k )
- Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin);
- // node to remain
- iObj = i;
- }
- Wlc_ObjSetCopy( p, i, iObj );
+ Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
+ if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
+ Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
}
- // POs do not change in this procedure
- if ( vNodes != vNodesInit )
- Vec_IntFree( vNodes );
- // reconstruct topological order
- pNew = Wlc_NtkDupDfs( p );
- Wlc_NtkTransferNames( pNew, p );
- return pNew;
+ return Counter;
+}
+static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
+{
+ int i, Fanin, Counter = 1;
+ if ( Wlc_ObjIsCi(pNode) )
+ return 0;
+ Wlc_ObjForEachFanin( pNode, Fanin, i )
+ {
+ if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
+ Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
+ Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
+ }
+ return Counter;
+}
+static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
+{
+ int Count1, Count2;
+ // if this is a flop output, compute MFFC of the corresponding flop input
+ while ( Wlc_ObjIsCi(pNode) )
+ {
+ Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
+ pNode = Wlc_ObjFo2Fi(p, pNode);
+ }
+ assert( !Wlc_ObjIsCi(pNode) );
+ // dereference the node (and set the bits in vUnmark)
+ Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
+ // reference it back
+ Count2 = Wlc_NtkNodeRef_rec( p, pNode );
+ assert( Count1 == Count2 );
+ return Count1;
+}
+static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
+{
+ Wlc_Obj_t * pObj; int i, nNodes = 0;
+ if ( Vec_IntSize(&p->vRefs) == 0 )
+ Wlc_NtkSetRefs( p );
+ Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
+ nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
+ return nNodes;
}
/**Function*************************************************************
- Synopsis [Adds UIF constraints to node pairs and updates POs.]
+ Synopsis [Computes the map for remapping flop IDs used in the clauses.]
+
+ Description [Takes the original network (Wlc_Ntk_t) and the array of word-level
+ flops used in the old abstraction (vFfOld) and those used in the new abstraction
+ (vFfNew). Returns the integer map, which remaps every binary flop found
+ in the old abstraction into a binary flop found in the new abstraction.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_NtkFlopsRemap( Wlc_Ntk_t * p, Vec_Int_t * vFfOld, Vec_Int_t * vFfNew )
+{
+ Vec_Int_t * vMap = Vec_IntAlloc( 1000 ); // the resulting map
+ Vec_Int_t * vMapFfNew2Bit1 = Vec_IntAlloc( 1000 ); // first binary bit of each new word-level flop
+ int i, b, iFfOld, iFfNew, iBit1New, nBits = 0;
+ // map object IDs of old flops into their flop indexes
+ Vec_Int_t * vMapFfObj2FfId = Vec_IntStartFull( Wlc_NtkObjNumMax(p) );
+ Vec_IntForEachEntry( vFfNew, iFfNew, i )
+ Vec_IntWriteEntry( vMapFfObj2FfId, iFfNew, i );
+ // map each new flop index into its first bit
+ Vec_IntForEachEntry( vFfNew, iFfNew, i )
+ {
+ Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfNew );
+ int nRange = Wlc_ObjRange( pObj );
+ Vec_IntPush( vMapFfNew2Bit1, nBits );
+ nBits += nRange;
+ }
+ assert( Vec_IntSize(vMapFfNew2Bit1) == Vec_IntSize(vFfNew) );
+ // remap old binary flops into new binary flops
+ Vec_IntForEachEntry( vFfOld, iFfOld, i )
+ {
+ Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfOld );
+ int nRange = Wlc_ObjRange( pObj );
+ iFfNew = Vec_IntEntry( vMapFfObj2FfId, iFfOld );
+ assert( iFfNew >= 0 ); // every old flop should be present in the new abstraction
+ // find the first bit of this new flop
+ iBit1New = Vec_IntEntry( vMapFfNew2Bit1, iFfNew );
+ for ( b = 0; b < nRange; b++ )
+ Vec_IntPush( vMap, iBit1New + b );
+ }
+ Vec_IntFree( vMapFfNew2Bit1 );
+ Vec_IntFree( vMapFfObj2FfId );
+ return vMap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs PDR with word-level abstraction.]
Description []
@@ -189,98 +362,266 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
SeeAlso []
***********************************************************************/
-Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit )
+int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
- Vec_Int_t * vPairs = vPairsInit;
- Wlc_Ntk_t * pNew;
- Wlc_Obj_t * pObj, * pObj2;
- Vec_Int_t * vUifConstrs, * vCompares, * vFanins;
- int i, k, iObj, iObj2, iObjNew, iObjNew2;
- int iFanin, iFanin2, iFaninNew;
- // get multiplier pairs if not given
- if ( vPairs == NULL )
- vPairs = Wlc_NtkFindUifableMultiplierPairs( p );
- if ( vPairs == NULL )
- return NULL;
- // sanity checks
- assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 );
- // iterate through node pairs
- vFanins = Vec_IntAlloc( 100 );
- vCompares = Vec_IntAlloc( 100 );
- vUifConstrs = Vec_IntAlloc( 100 );
- Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i )
+ abctime clk = Abc_Clock();
+ abctime pdrClk;
+ Pdr_Man_t * pPdr;
+ Vec_Vec_t * vClauses = NULL;
+ Vec_Int_t * vFfOld = NULL, * vFfNew = NULL, * vMap = NULL;
+ int nIters, nNodes, nDcFlops, RetValue = -1, nGiaFfNumOld = -1;
+ // start the bitmap to mark objects that cannot be abstracted because of refinement
+ // currently, this bitmap is empty because abstraction begins without refinement
+ Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ // set up parameters to run PDR
+ Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
+ Pdr_ManSetDefaultParams( pPdrPars );
+ pPdrPars->fVerbose = pPars->fPdrVerbose;
+ pPdrPars->fVeryVerbose = 0;
+
+ // perform refinement iterations
+ for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
{
- // get two nodes
- pObj = Wlc_NtkObj( p, iObj );
- pObj2 = Wlc_NtkObj( p, iObj2 );
- assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) );
- // create fanin comparator nodes
- Vec_IntClear( vCompares );
- Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Aig_Man_t * pAig;
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vPisNew, * vRefine;
+ Gia_Man_t * pGia, * pTemp;
+ Wlc_Ntk_t * pAbs;
+
+ if ( pPars->fVerbose )
+ printf( "\nIteration %d:\n", nIters );
+
+ // get abstracted GIA and the set of pseudo-PIs (vPisNew)
+ pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, &vFfNew, pPars->fVerbose );
+ pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
+
+ // map old flops into new flops
+ if ( vFfOld )
{
- iFanin2 = Wlc_ObjFaninId( pObj2, k );
- Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 );
- iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins );
- Vec_IntPush( vCompares, iFaninNew );
- // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
- // Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
- pObj = Wlc_NtkObj( p, iObj );
+ assert( nGiaFfNumOld >= 0 );
+ vMap = Wlc_NtkFlopsRemap( p, vFfOld, vFfNew );
+ //Vec_IntPrint( vMap );
+ // if reset flop was added in the previous iteration, it will be added again in this iteration
+ // remap the last flop (reset flop) into the last flop (reset flop) of the current AIG
+ if ( Vec_IntSize(vMap) + 1 == nGiaFfNumOld )
+ Vec_IntPush( vMap, Gia_ManRegNum(pGia)-1 );
+ assert( Vec_IntSize(vMap) == nGiaFfNumOld );
+ Vec_IntFreeP( &vFfOld );
}
- // concatenate fanin comparators
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares );
- // create reduction-OR node
- Vec_IntFill( vFanins, 1, iObjNew );
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins );
- // craete output comparator node
- Vec_IntFillTwo( vFanins, 2, iObj, iObj2 );
- iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins );
- // create implication node (iObjNew is already complemented above)
- Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 );
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins );
- // save the constraint
- Vec_IntPush( vUifConstrs, iObjNew );
- }
- // derive the AND of the UIF contraints
- assert( Vec_IntSize(vUifConstrs) > 0 );
- if ( Vec_IntSize(vUifConstrs) == 1 )
- iObjNew = Vec_IntEntry( vUifConstrs, 0 );
- else
- {
- // concatenate
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs );
- // create reduction-AND node
- Vec_IntFill( vFanins, 1, iObjNew );
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins );
+ ABC_SWAP( Vec_Int_t *, vFfOld, vFfNew );
+ nGiaFfNumOld = Gia_ManRegNum(pGia);
+
+ // if the abstraction has flops with DC-init state,
+ // new PIs were introduced by bit-blasting at the end of the PI list
+ // here we move these variables to be *before* PPIs, because
+ // PPIs are supposed to be at the end of the PI list for refinement
+ nDcFlops = Wlc_NtkDcFlopNum(pAbs);
+ if ( nDcFlops > 0 ) // DC-init flops are present
+ {
+ pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
+ Gia_ManStop( pTemp );
+ }
+ // if the word-level outputs have to be XORs, this is a place to do it
+ if ( pPars->fXorOutput )
+ {
+ pGia = Gia_ManTransformMiter2( pTemp = pGia );
+ Gia_ManStop( pTemp );
+ }
+ if ( pPars->fVerbose )
+ {
+ printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
+ Gia_ManPrintStats( pGia, NULL );
+ }
+ Wlc_NtkFree( pAbs );
+
+ // try to prove abstracted GIA by converting it to AIG and calling PDR
+ pAig = Gia_ManToAigSimple( pGia );
+
+ pPdr = Pdr_ManStart( pAig, pPdrPars, NULL );
+ pdrClk = Abc_Clock();
+
+ if ( vClauses ) {
+ assert( Vec_VecSize( vClauses) >= 2 );
+ IPdr_ManRestore( pPdr, vClauses, vMap );
+ }
+ Vec_IntFreeP( &vMap );
+
+ RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses );
+ pPdr->tTotal += Abc_Clock() - pdrClk;
+
+ pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
+
+ // consider outcomes
+ if ( pCex == NULL )
+ {
+ assert( RetValue ); // proved or undecided
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ Pdr_ManStop( pPdr );
+ Aig_ManStop( pAig );
+ break;
+ }
+
+ // perform refinement
+ vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ if ( vRefine == NULL ) // real CEX
+ {
+ Abc_CexFree( pCex ); // return CEX in the future
+ Pdr_ManStop( pPdr );
+ Aig_ManStop( pAig );
+ break;
+ }
+
+ // spurious CEX, continue solving
+ vClauses = IPdr_ManSaveClauses( pPdr, 0 );
+
+ Pdr_ManStop( pPdr );
+
+ // update the set of objects to be un-abstracted
+ nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
+ if ( pPars->fVerbose )
+ printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
+ Vec_IntFree( vRefine );
+ Abc_CexFree( pCex );
+ Aig_ManStop( pAig );
}
- // update each PO to point to the new node
- Wlc_NtkForEachPo( p, pObj, i )
+
+ Vec_IntFreeP( &vFfOld );
+ Vec_BitFree( vUnmark );
+ // report the result
+ if ( pPars->fVerbose )
+ printf( "\n" );
+ printf( "Abstraction " );
+ if ( RetValue == 0 )
+ printf( "resulted in a real CEX" );
+ else if ( RetValue == 1 )
+ printf( "is successfully proved" );
+ else
+ printf( "timed out" );
+ printf( " after %d iterations. ", nIters );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs abstraction.]
+
+ Description [Derives initial abstraction based on user-specified
+ parameter values, which tell what is the smallest bit-width of a
+ primitive that is being abstracted away. Currently only add/sub,
+ mul/div, mux, and flop are supported with individual parameters.
+ The second step is to refine the initial abstraction until the
+ point when the property is proved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
+{
+ abctime clk = Abc_Clock();
+ int nIters, nNodes, nDcFlops, RetValue = -1;
+ // start the bitmap to mark objects that cannot be abstracted because of refinement
+ // currently, this bitmap is empty because abstraction begins without refinement
+ Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ // set up parameters to run PDR
+ Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
+ Pdr_ManSetDefaultParams( pPdrPars );
+ //pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction)
+ //pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization)
+ //pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization)
+ //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
+ pPdrPars->fVerbose = pPars->fPdrVerbose;
+ pPdrPars->fVeryVerbose = 0;
+ // perform refinement iterations
+ for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
{
- iObj = Wlc_ObjId(p, pObj);
- Vec_IntFillTwo( vFanins, 2, iObj, iObjNew );
- iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins );
- // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
- // Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
- pObj = Wlc_NtkObj( p, iObj );
- // update PO/CO arrays
- assert( Vec_IntEntry(&p->vPos, i) == iObj );
- assert( Vec_IntEntry(&p->vCos, i) == iObj );
- Vec_IntWriteEntry( &p->vPos, i, iObjNew );
- Vec_IntWriteEntry( &p->vCos, i, iObjNew );
- // transfer the PO attribute
- Wlc_NtkObj(p, iObjNew)->fIsPo = 1;
- assert( pObj->fIsPo );
- pObj->fIsPo = 0;
+ Aig_Man_t * pAig;
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vPisNew, * vRefine;
+ Gia_Man_t * pGia, * pTemp;
+ Wlc_Ntk_t * pAbs;
+
+ if ( pPars->fVerbose )
+ printf( "\nIteration %d:\n", nIters );
+
+ // get abstracted GIA and the set of pseudo-PIs (vPisNew)
+ pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, NULL, pPars->fVerbose );
+ pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
+
+ // if the abstraction has flops with DC-init state,
+ // new PIs were introduced by bit-blasting at the end of the PI list
+ // here we move these variables to be *before* PPIs, because
+ // PPIs are supposed to be at the end of the PI list for refinement
+ nDcFlops = Wlc_NtkDcFlopNum(pAbs);
+ if ( nDcFlops > 0 ) // DC-init flops are present
+ {
+ pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
+ Gia_ManStop( pTemp );
+ }
+ // if the word-level outputs have to be XORs, this is a place to do it
+ if ( pPars->fXorOutput )
+ {
+ pGia = Gia_ManTransformMiter2( pTemp = pGia );
+ Gia_ManStop( pTemp );
+ }
+ if ( pPars->fVerbose )
+ {
+ printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
+ Gia_ManPrintStats( pGia, NULL );
+ }
+ Wlc_NtkFree( pAbs );
+
+ // try to prove abstracted GIA by converting it to AIG and calling PDR
+ pAig = Gia_ManToAigSimple( pGia );
+ RetValue = Pdr_ManSolve( pAig, pPdrPars );
+ pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
+ Aig_ManStop( pAig );
+
+ // consider outcomes
+ if ( pCex == NULL )
+ {
+ assert( RetValue ); // proved or undecided
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ break;
+ }
+
+ // perform refinement
+ vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ if ( vRefine == NULL ) // real CEX
+ {
+ Abc_CexFree( pCex ); // return CEX in the future
+ break;
+ }
+
+ // update the set of objects to be un-abstracted
+ nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
+ if ( pPars->fVerbose )
+ printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
+ Vec_IntFree( vRefine );
+ Abc_CexFree( pCex );
}
- // cleanup
- Vec_IntFree( vUifConstrs );
- Vec_IntFree( vCompares );
- Vec_IntFree( vFanins );
- if ( vPairs != vPairsInit )
- Vec_IntFree( vPairs );
- // reconstruct topological order
- pNew = Wlc_NtkDupDfs( p );
- Wlc_NtkTransferNames( pNew, p );
- return pNew;
+ Vec_BitFree( vUnmark );
+ // report the result
+ if ( pPars->fVerbose )
+ printf( "\n" );
+ printf( "Abstraction " );
+ if ( RetValue == 0 )
+ printf( "resulted in a real CEX" );
+ else if ( RetValue == 1 )
+ printf( "is successfully proved" );
+ else
+ printf( "timed out" );
+ printf( " after %d iterations. ", nIters );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c
new file mode 100644
index 00000000..9bccdf62
--- /dev/null
+++ b/src/base/wlc/wlcAbs2.c
@@ -0,0 +1,410 @@
+/**CFile****************************************************************
+
+ FileName [wlcAbs2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Abstraction for word-level networks.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlcAbs2.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wlc.h"
+#include "proof/pdr/pdr.h"
+#include "aig/gia/giaAig.h"
+#include "sat/bmc/bmc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Mark operators that meet the abstraction criteria.]
+
+ Description [This procedure returns the array of objects (vLeaves) that
+ should be abstracted because of their high bit-width. It uses input array (vUnmark)
+ to not abstract those objects that have been refined in the previous rounds.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
+{
+ Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ Wlc_Obj_t * pObj; int i, Count[4] = {0};
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
+ continue;
+ if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
+ continue;
+ }
+ if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
+ continue;
+ }
+ if ( pObj->Type == WLC_OBJ_MUX )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
+ continue;
+ }
+ if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
+ {
+ if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
+ Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
+ continue;
+ }
+ }
+ if ( fVerbose )
+ printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] );
+ return vLeaves;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks nodes to be included in the abstracted network.]
+
+ Description [Marks all objects that will be included in the abstracted model.
+ Stops at the objects (vLeaves) that are abstracted away. Returns three arrays:
+ a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the
+ set of flops present as flops in the abstracted network.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
+{
+ int i, iFanin;
+ if ( pObj->Mark )
+ return;
+ pObj->Mark = 1;
+ if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
+ {
+ assert( !Wlc_ObjIsPi(pObj) );
+ Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
+ return;
+ }
+ if ( Wlc_ObjIsCi(pObj) )
+ {
+ if ( Wlc_ObjIsPi(pObj) )
+ Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
+ else
+ Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
+ return;
+ }
+ Wlc_ObjForEachFanin( pObj, iFanin, i )
+ Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
+}
+static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
+{
+ Wlc_Obj_t * pObj;
+ int i, Count = 0;
+ Wlc_NtkCleanMarks( p );
+ Wlc_NtkForEachCo( p, pObj, i )
+ Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
+ Wlc_NtkForEachObj( p, pObj, i )
+ Count += pObj->Mark;
+// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n",
+// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops),
+// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
+ Vec_IntSort( vPisOld, 0 );
+ Vec_IntSort( vPisNew, 0 );
+ Vec_IntSort( vFlops, 0 );
+ Wlc_NtkCleanMarks( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive word-level abstracted model based on the parameter values.]
+
+ Description [Retuns the word-level abstracted network and the set of pseudo-PIs
+ (vPisNew), which were created during abstraction. If the abstraction is
+ satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs
+ and their MFFC cones will be listed in the array (vUnmark), which will
+ force the abstraction to not stop at these pseudo-PIs in the future.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose )
+{
+ Wlc_Ntk_t * pNtkNew = NULL;
+ Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
+ Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
+ Vec_Int_t * vFlops = Vec_IntAlloc( 100 );
+ Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
+ Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
+ Vec_BitFree( vLeaves );
+ pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
+ Vec_IntFree( vPisOld );
+ Vec_IntFree( vFlops );
+ if ( pvPisNew )
+ *pvPisNew = vPisNew;
+ else
+ Vec_IntFree( vPisNew );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find what objects need to be un-abstracted.]
+
+ Description [Returns a subset of pseudo-PIs (vPisNew), which will be
+ prevented from being abstracted in the future rounds of abstraction.
+ The AIG manager (pGia) is a bit-level view of the abstracted model.
+ The counter-example (pCex) is used to find waht PPIs to refine.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
+{
+ Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
+ Abc_Cex_t * pCexCare;
+ Wlc_Obj_t * pObj;
+ // count the number of bit-level PPIs and map them into word-level objects they were derived from
+ int f, i, b, nRealPis, nPpiBits = 0;
+ Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
+ Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
+ for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
+ Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
+ // since PPIs are ordered last, the previous bits are real PIs
+ nRealPis = pCex->nPis - nPpiBits;
+ // find the care-set
+ pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
+ assert( pCexCare->nPis == pCex->nPis );
+ // detect care PPIs
+ for ( f = 0; f <= pCexCare->iFrame; f++ )
+ for ( i = nRealPis; i < pCexCare->nPis; i++ )
+ if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
+ Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
+ Abc_CexFree( pCexCare );
+ Vec_IntFree( vMap );
+ if ( Vec_IntSize(vRefine) == 0 )// real CEX
+ Vec_IntFreeP( &vRefine );
+ return vRefine;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Mark MFFC cones of the un-abstracted objects.]
+
+ Description [The MFFC cones of the objects in vRefine are traversed
+ and all their nodes are marked in vUnmark.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
+{
+ int i, Fanin, Counter = 1;
+ if ( Wlc_ObjIsCi(pNode) )
+ return 0;
+ Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
+ Wlc_ObjForEachFanin( pNode, Fanin, i )
+ {
+ Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
+ if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
+ Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
+ }
+ return Counter;
+}
+static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
+{
+ int i, Fanin, Counter = 1;
+ if ( Wlc_ObjIsCi(pNode) )
+ return 0;
+ Wlc_ObjForEachFanin( pNode, Fanin, i )
+ {
+ if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
+ Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
+ Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
+ }
+ return Counter;
+}
+static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
+{
+ int Count1, Count2;
+ // if this is a flop output, compute MFFC of the corresponding flop input
+ while ( Wlc_ObjIsCi(pNode) )
+ {
+ Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
+ pNode = Wlc_ObjFo2Fi(p, pNode);
+ }
+ assert( !Wlc_ObjIsCi(pNode) );
+ // dereference the node (and set the bits in vUnmark)
+ Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
+ // reference it back
+ Count2 = Wlc_NtkNodeRef_rec( p, pNode );
+ assert( Count1 == Count2 );
+ return Count1;
+}
+static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
+{
+ Wlc_Obj_t * pObj; int i, nNodes = 0;
+ if ( Vec_IntSize(&p->vRefs) == 0 )
+ Wlc_NtkSetRefs( p );
+ Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
+ nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
+ return nNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs abstraction.]
+
+ Description [Derives initial abstraction based on user-specified
+ parameter values, which tell what is the smallest bit-width of a
+ primitive that is being abstracted away. Currently only add/sub,
+ mul/div, mux, and flop are supported with individual parameters.
+ The second step is to refine the initial abstraction until the
+ point when the property is proved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
+{
+ abctime clk = Abc_Clock();
+ int nIters, nNodes, nDcFlops, RetValue = -1;
+ // start the bitmap to mark objects that cannot be abstracted because of refinement
+ // currently, this bitmap is empty because abstraction begins without refinement
+ Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
+ // set up parameters to run PDR
+ Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
+ Pdr_ManSetDefaultParams( pPdrPars );
+ pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction)
+ pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization)
+ pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization)
+ //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
+ pPdrPars->fVerbose = pPars->fPdrVerbose;
+ // perform refinement iterations
+ for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
+ {
+ Aig_Man_t * pAig;
+ Abc_Cex_t * pCex;
+ Vec_Int_t * vPisNew, * vRefine;
+ Gia_Man_t * pGia, * pTemp;
+ Wlc_Ntk_t * pAbs;
+
+ if ( pPars->fVerbose )
+ printf( "\nIteration %d:\n", nIters );
+
+ // get abstracted GIA and the set of pseudo-PIs (vPisNew)
+ pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose );
+ pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
+
+ // if the abstraction has flops with DC-init state,
+ // new PIs were introduced by bit-blasting at the end of the PI list
+ // here we move these variables to be *before* PPIs, because
+ // PPIs are supposed to be at the end of the PI list for refinement
+ nDcFlops = Wlc_NtkDcFlopNum(pAbs);
+ if ( nDcFlops > 0 ) // DC-init flops are present
+ {
+ pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
+ Gia_ManStop( pTemp );
+ }
+ // if the word-level outputs have to be XORs, this is a place to do it
+ if ( pPars->fXorOutput )
+ {
+ pGia = Gia_ManTransformMiter2( pTemp = pGia );
+ Gia_ManStop( pTemp );
+ }
+ if ( pPars->fVerbose )
+ {
+ printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
+ Gia_ManPrintStats( pGia, NULL );
+ }
+ Wlc_NtkFree( pAbs );
+
+ // try to prove abstracted GIA by converting it to AIG and calling PDR
+ pAig = Gia_ManToAigSimple( pGia );
+ RetValue = Pdr_ManSolve( pAig, pPdrPars );
+ pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
+ Aig_ManStop( pAig );
+
+ // consider outcomes
+ if ( pCex == NULL )
+ {
+ assert( RetValue ); // proved or undecided
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ break;
+ }
+
+ // perform refinement
+ vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
+ Gia_ManStop( pGia );
+ Vec_IntFree( vPisNew );
+ if ( vRefine == NULL ) // real CEX
+ {
+ Abc_CexFree( pCex ); // return CEX in the future
+ break;
+ }
+
+ // update the set of objects to be un-abstracted
+ nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
+ if ( pPars->fVerbose )
+ printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
+ Vec_IntFree( vRefine );
+ Abc_CexFree( pCex );
+ }
+ Vec_BitFree( vUnmark );
+ // report the result
+ if ( pPars->fVerbose )
+ printf( "\n" );
+ printf( "Abstraction " );
+ if ( RetValue == 0 )
+ printf( "resulted in a real CEX" );
+ else if ( RetValue == 1 )
+ printf( "is successfully proved" );
+ else
+ printf( "timed out" );
+ printf( " after %d iterations. ", nIters );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c
index ec3b040d..f4de8ee6 100644
--- a/src/base/wlc/wlcBlast.c
+++ b/src/base/wlc/wlcBlast.c
@@ -643,6 +643,41 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level )
Vec_IntInsert( vProd, i + 1, Node );
Vec_IntInsert( vLevel, i + 1, Level );
}
+void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds )
+{
+ int fVerbose = 0;
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel; word Truth;
+ int i, k, iLit;
+ Vec_WecForEachLevel( vProds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
+ Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) );
+ printf( "Booth partial products: %d pps, %d unique, %d nodes.\n",
+ Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) );
+ Vec_IntPrint( vSupp );
+
+ if ( fVerbose )
+ Vec_WecForEachLevel( vProds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ printf( "Obj = %4d : ", Abc_Lit2Var(iLit) );
+ printf( "Compl = %d ", Abc_LitIsCompl(iLit) );
+ printf( "Rank = %2d ", i );
+ Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp );
+ Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
+ if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
+ if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
+ if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
+ printf( " " );
+ Vec_IntPrint( vSupp );
+ if ( k == Vec_IntSize(vLevel)-1 )
+ printf( "\n" );
+ }
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+}
void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes )
{
Vec_Int_t * vLevel, * vProd;
@@ -812,6 +847,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
Vec_WecPush( vLevels, k, 0 );
}
//Vec_WecPrint( vProds, 0 );
+ //Wlc_BlastPrintMatrix( pNew, vProds );
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes );
@@ -836,6 +872,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
int fVerbose = 0;
int fUseOldMultiplierBlasting = 0;
+ int fSkipBitRange = 0;
Tim_Man_t * pManTime = NULL;
Gia_Man_t * pTemp, * pNew, * pExtra = NULL;
Wlc_Obj_t * pObj;
@@ -1381,7 +1418,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
}
else
{
- pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 1 );
+ pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 0 );
Gia_ManDupRemapLiterals( vBits, pTemp );
Gia_ManStop( pTemp );
}
@@ -1412,7 +1449,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1439,7 +1476,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1462,7 +1499,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1477,7 +1514,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1496,7 +1533,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
- if ( nRange == 1 )
+ if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@@ -1509,7 +1546,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) );
}
- pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName );
+ //pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName );
// dump the miter parts
if ( 0 )
{
diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c
index f3eb6dd7..df736e70 100644
--- a/src/base/wlc/wlcCom.c
+++ b/src/base/wlc/wlcCom.c
@@ -28,22 +28,31 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPdrAbs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv );
static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; }
static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); }
static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; }
static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; }
-static inline Vec_Int_t * Wlc_AbcGetCnf( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcCnf; }
-static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcStr; }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -62,14 +71,25 @@ static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc )
******************************************************************************/
void Wlc_Init( Abc_Frame_t * pAbc )
{
- Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 );
- Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%pdra", Abc_CommandPdrAbs, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 );
+
+ Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 );
}
/**Function********************************************************************
@@ -275,15 +295,20 @@ usage:
int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int fShowCones = 0;
int fShowMulti = 0;
int fShowAdder = 0;
int fDistrib = 0;
+ int fTwoSides = 0;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "madvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "cmadtvh" ) ) != EOF )
{
switch ( c )
{
+ case 'c':
+ fShowCones ^= 1;
+ break;
case 'm':
fShowMulti ^= 1;
break;
@@ -293,6 +318,9 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'd':
fDistrib ^= 1;
break;
+ case 't':
+ fTwoSides ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -307,18 +335,110 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 1, "Abc_CommandPs(): There is no current design.\n" );
return 0;
}
- Wlc_NtkPrintStats( pNtk, fDistrib, fVerbose );
+ Wlc_NtkPrintStats( pNtk, fDistrib, fTwoSides, fVerbose );
+ if ( fShowCones )
+ Wlc_NtkProfileCones( pNtk );
if ( fShowMulti )
Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_MULTI );
if ( fShowAdder )
Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_ADD );
return 0;
usage:
- Abc_Print( -2, "usage: %%ps [-madvh]\n" );
+ Abc_Print( -2, "usage: %%ps [-cmadtvh]\n" );
Abc_Print( -2, "\t prints statistics\n" );
- Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" );
- Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" );
- Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle printing cones [default = %s]\n", fShowCones? "yes": "no" );
+ Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" );
+ Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" );
+ Abc_Print( -2, "\t-t : toggle printing stats for LHS and RHS [default = %s]\n", fTwoSides? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, iOutput = -1, Range = 1, fAllPis = 0, fSeq = 0, fVerbose = 0;
+ char * pName;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORisvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'O':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ iOutput = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( iOutput < 0 )
+ goto usage;
+ break;
+ case 'R':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Range = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( Range < 0 )
+ goto usage;
+ break;
+ case 'i':
+ fAllPis ^= 1;
+ break;
+ case 's':
+ fSeq ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" );
+ return 0;
+ }
+ if ( iOutput < 0 || iOutput >= Wlc_NtkCoNum(pNtk) )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkCoNum(pNtk) );
+ return 0;
+ }
+ printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" );
+ pName = Wlc_NtkNewName( pNtk, iOutput, fSeq );
+ Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis );
+ pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq );
+ ABC_FREE( pNtk->pName );
+ pNtk->pName = Abc_UtilStrsav( pName );
+ Wlc_AbcUpdateNtk( pAbc, pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%cone [-OR num] [-isvh]\n" );
+ Abc_Print( -2, "\t extracts logic cone of one or more word-level outputs\n" );
+ Abc_Print( -2, "\t-O num : zero-based index of the first word-level output to extract [default = %d]\n", iOutput );
+ Abc_Print( -2, "\t-R num : total number of word-level outputs to extract [default = %d]\n", Range );
+ Abc_Print( -2, "\t-i : toggle using support composed of all primary inputs [default = %s]\n", fAllPis? "yes": "no" );
+ Abc_Print( -2, "\t-s : toggle performing extracting sequential cones [default = %s]\n", fSeq? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -335,6 +455,357 @@ usage:
SeeAlso []
******************************************************************************/
+int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ Wlc_Par_t Pars, * pPars = &Pars;
+ int c;
+ Wlc_ManSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsAdd = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsAdd < 0 )
+ goto usage;
+ break;
+ case 'M':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMul = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMul < 0 )
+ goto usage;
+ break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMux = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMux < 0 )
+ goto usage;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsFlop = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsFlop < 0 )
+ goto usage;
+ break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nIterMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nIterMax < 0 )
+ goto usage;
+ break;
+ case 'x':
+ pPars->fXorOutput ^= 1;
+ break;
+ case 'c':
+ pPars->fCheckClauses ^= 1;
+ break;
+ case 'p':
+ pPars->fPushClauses ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'w':
+ pPars->fPdrVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_NtkPdrAbs( pNtk, pPars );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-cpxvwh]\n" );
+ Abc_Print( -2, "\t abstraction for word-level networks\n" );
+ Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd );
+ Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul );
+ Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux );
+ Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop );
+ Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax );
+ Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle checking clauses in the reloaded trace [default = %s]\n", pPars->fCheckClauses? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle pushing clauses in the reloaded trace [default = %s]\n", pPars->fPushClauses? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ Wlc_Par_t Pars, * pPars = &Pars;
+ int c;
+ Wlc_ManSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsAdd = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsAdd < 0 )
+ goto usage;
+ break;
+ case 'M':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMul = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMul < 0 )
+ goto usage;
+ break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMux = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMux < 0 )
+ goto usage;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsFlop = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsFlop < 0 )
+ goto usage;
+ break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nIterMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nIterMax < 0 )
+ goto usage;
+ break;
+ case 'x':
+ pPars->fXorOutput ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'w':
+ pPars->fPdrVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_NtkAbsCore( pNtk, pPars );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%abs [-AMXFI num] [-xvwh]\n" );
+ Abc_Print( -2, "\t abstraction for word-level networks\n" );
+ Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd );
+ Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul );
+ Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux );
+ Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop );
+ Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax );
+ Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandAbs2( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ Wlc_Par_t Pars, * pPars = &Pars;
+ int c;
+ Wlc_ManSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsAdd = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsAdd < 0 )
+ goto usage;
+ break;
+ case 'M':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMul = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMul < 0 )
+ goto usage;
+ break;
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsMux = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsMux < 0 )
+ goto usage;
+ break;
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBitsFlop = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBitsFlop < 0 )
+ goto usage;
+ break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nIterMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nIterMax < 0 )
+ goto usage;
+ break;
+ case 'x':
+ pPars->fXorOutput ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'w':
+ pPars->fPdrVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_NtkAbsCore2( pNtk, pPars );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%abs2 [-AMXFI num] [-xvwh]\n" );
+ Abc_Print( -2, "\t abstraction for word-level networks\n" );
+ Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd );
+ Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul );
+ Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux );
+ Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop );
+ Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax );
+ Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
@@ -440,10 +911,200 @@ usage:
SeeAlso []
******************************************************************************/
-int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_WinProfileArith( pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%profile [-vh]\n" );
+ Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" );
+ return 0;
+ }
+ Wlc_NtkShortNames( pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%short_names [-vh]\n" );
+ Abc_Print( -2, "\t derives short names for all objects of the network\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandShow( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold );
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, fVerbose = 0;
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( -1, "Empty network.\n" );
+ return 1;
+ }
+ Wlc_NtkShow( pNtk, NULL );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: %%show [-h]\n" );
+ Abc_Print( -2, " visualizes the network structure using DOT and GSVIEW\n" );
+#ifdef WIN32
+ Abc_Print( -2, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" );
+ Abc_Print( -2, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" );
+#endif
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p );
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" );
+ return 0;
+ }
+ // transform
+ //pNtk = Wlc_NtkUifNodePairs( pNtk, NULL );
+ //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL );
+ //Wlc_AbcUpdateNtk( pAbc, pNtk );
+ //Wlc_GenerateSmtStdout( pAbc );
+ //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc );
+ pNtk = Wlc_NtkDupSingleNodes( pNtk );
+ Wlc_AbcUpdateNtk( pAbc, pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%test [-vh]\n" );
+ Abc_Print( -2, "\t experiments with word-level networks\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandInvPs( Abc_Frame_t * pAbc, int argc, char ** argv )
{
+ extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose );
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ Vec_Int_t * vCounts;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
@@ -461,24 +1122,66 @@ int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( pNtk == NULL )
{
- Abc_Print( 1, "Abc_CommandPsInv(): There is no current design.\n" );
+ Abc_Print( 1, "Abc_CommandInvPs(): There is no current design.\n" );
return 0;
}
- if ( Wlc_AbcGetNtk(pAbc) == NULL )
+ if ( Wlc_AbcGetInv(pAbc) == NULL )
{
- Abc_Print( 1, "Abc_CommandPsInv(): There is no saved invariant.\n" );
+ Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" );
return 0;
}
+ vCounts = Pdr_InvCounts( Wlc_AbcGetInv(pAbc) );
+ Wlc_NtkPrintInvStats( pNtk, vCounts, fVerbose );
+ Vec_IntFree( vCounts );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: inv_ps [-vh]\n" );
+ Abc_Print( -2, "\t prints statistics for inductive invariant\n" );
+ Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose );
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
if ( Wlc_AbcGetInv(pAbc) == NULL )
{
- Abc_Print( 1, "Abc_CommandPsInv(): Invariant is not available.\n" );
+ Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" );
return 0;
}
- Wlc_NtkPrintInvStats( pNtk, Wlc_AbcGetInv(pAbc), fVerbose );
+ Pdr_InvPrint( Wlc_AbcGetInv(pAbc), fVerbose );
return 0;
- usage:
- Abc_Print( -2, "usage: %%psinv [-vh]\n" );
- Abc_Print( -2, "\t prints statistics for inductive invariant\n" );
+usage:
+ Abc_Print( -2, "usage: inv_print [-vh]\n" );
+ Abc_Print( -2, "\t prints the current inductive invariant\n" );
Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -496,12 +1199,11 @@ int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv )
SeeAlso []
******************************************************************************/
-int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose );
- Abc_Ntk_t * pMainNtk;
- Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
- int c, fVerbose = 0;
+ abctime clk = Abc_Clock();
+ extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose );
+ int c, nFailed, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{
@@ -516,28 +1218,81 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
- if ( pNtk == NULL )
+ if ( pAbc->pGia == NULL )
{
- Abc_Print( 1, "Abc_CommandGetInv(): There is no current design.\n" );
+ Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" );
return 0;
}
- if ( Wlc_AbcGetNtk(pAbc) == NULL )
+ if ( Wlc_AbcGetInv(pAbc) == NULL )
{
- Abc_Print( 1, "Abc_CommandGetInv(): There is no saved invariant.\n" );
+ Abc_Print( 1, "Abc_CommandInvMin(): There is no saved invariant.\n" );
return 0;
}
+ if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(Wlc_AbcGetInv(pAbc)) )
+ {
+ Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" );
+ return 0;
+ }
+ nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc), fVerbose );
+ if ( nFailed )
+ printf( "Invariant verification failed for %d clauses (out of %d). ", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) );
+ else
+ printf( "Invariant verification succeeded. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: inv_check [-vh]\n" );
+ Abc_Print( -2, "\t checks that the invariant is indeed an inductive invariant\n" );
+ Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv );
+ Abc_Ntk_t * pMainNtk;
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
if ( Wlc_AbcGetInv(pAbc) == NULL )
{
- Abc_Print( 1, "Abc_CommandGetInv(): Invariant is not available.\n" );
+ Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" );
return 0;
}
// derive the network
- pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), Wlc_AbcGetStr(pAbc), fVerbose );
+ pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) );
// replace the current network
- Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk );
+ if ( pMainNtk )
+ Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk );
return 0;
- usage:
- Abc_Print( -2, "usage: %%getinv [-vh]\n" );
+usage:
+ Abc_Print( -2, "usage: inv_get [-vh]\n" );
Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" );
Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
@@ -556,34 +1311,45 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv )
SeeAlso []
******************************************************************************/
-int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia );
+ Vec_Int_t * vInv = NULL;
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{
switch ( c )
{
- case 'v':
- fVerbose ^= 1;
- break;
- case 'h':
- goto usage;
- default:
- goto usage;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
}
}
if ( pNtk == NULL )
{
- Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" );
+ Abc_Print( 1, "Abc_CommandInvPut(): There is no current design.\n" );
return 0;
}
- Wlc_WinProfileArith( pNtk );
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandInvPut(): There is no current AIG.\n" );
+ return 0;
+ }
+ // derive the network
+ vInv = Wlc_NtkGetPut( pNtk, pAbc->pGia );
+ if ( vInv )
+ Abc_FrameSetInv( vInv );
return 0;
usage:
- Abc_Print( -2, "usage: %%profile [-vh]\n" );
- Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" );
+ Abc_Print( -2, "usage: inv_put [-vh]\n" );
+ Abc_Print( -2, "\t inputs the current network in the main-space as an invariant\n" );
+ Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -600,42 +1366,57 @@ usage:
SeeAlso []
******************************************************************************/
-int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p );
- Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
- int c, fVerbose = 0;
+ extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose );
+ extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose );
+ Vec_Int_t * vInv, * vInv2;
+ int c, fLits = 0, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "lvh" ) ) != EOF )
{
switch ( c )
{
- case 'v':
- fVerbose ^= 1;
- break;
- case 'h':
- goto usage;
- default:
- goto usage;
+ case 'l':
+ fLits ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
}
}
- if ( pNtk == NULL )
+ if ( pAbc->pGia == NULL )
{
- Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" );
+ Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" );
return 0;
}
- // transform
- //pNtk = Wlc_NtkUifNodePairs( pNtk, NULL );
- //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL );
- //Wlc_AbcUpdateNtk( pAbc, pNtk );
- //Wlc_GenerateSmtStdout( pAbc );
- //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc );
- pNtk = Wlc_NtkDupSingleNodes( pNtk );
- Wlc_AbcUpdateNtk( pAbc, pNtk );
+ if ( Wlc_AbcGetInv(pAbc) == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandInvMin(): Invariant is not available.\n" );
+ return 0;
+ }
+ vInv = Wlc_AbcGetInv(pAbc);
+ if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(vInv) )
+ {
+ Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" );
+ return 0;
+ }
+ if ( fLits )
+ vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv, fVerbose );
+ else
+ vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv, fVerbose );
+ if ( vInv2 )
+ Abc_FrameSetInv( vInv2 );
return 0;
usage:
- Abc_Print( -2, "usage: %%test [-vh]\n" );
- Abc_Print( -2, "\t experiments with word-level networks\n" );
+ Abc_Print( -2, "usage: inv_min [-lvh]\n" );
+ Abc_Print( -2, "\t performs minimization of the current invariant\n" );
+ Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" );
+ Abc_Print( -2, "\t-l : toggle minimizing literals rather than clauses [default = %s]\n", fLits? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c
index 6f396771..c8fc15a7 100644
--- a/src/base/wlc/wlcNtk.c
+++ b/src/base/wlc/wlcNtk.c
@@ -88,12 +88,40 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
NULL // 54: unused
};
+char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; }
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars )
+{
+ memset( pPars, 0, sizeof(Wlc_Par_t) );
+ pPars->nBitsAdd = ABC_INFINITY; // adder bit-width
+ pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht
+ pPars->nBitsMux = ABC_INFINITY; // MUX bit-width
+ pPars->nBitsFlop = ABC_INFINITY; // flop bit-width
+ pPars->nIterMax = 1000; // the max number of iterations
+ pPars->fXorOutput = 1; // XOR outputs of word-level miter
+ pPars->fCheckClauses = 1; // Check clauses in the reloaded trace
+ pPars->fPushClauses = 0; // Push clauses in the reloaded trace
+ pPars->fVerbose = 0; // verbose output`
+ pPars->fPdrVerbose = 0; // show verbose PDR output
+}
+
+/**Function*************************************************************
+
Synopsis [Working with models.]
Description []
@@ -195,14 +223,14 @@ void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins )
{
assert( pObj->nFanins == 0 );
pObj->nFanins = Vec_IntSize(vFanins);
- if ( Wlc_ObjHasArray(pObj) )
- pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) );
- memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) );
// special treatment of CONST, SELECT and TABLE
if ( pObj->Type == WLC_OBJ_CONST )
pObj->nFanins = 0;
else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE )
pObj->nFanins = 1;
+ if ( Wlc_ObjHasArray(pObj) )
+ pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) );
+ memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) );
}
void Wlc_NtkFree( Wlc_Ntk_t * p )
{
@@ -224,6 +252,8 @@ void Wlc_NtkFree( Wlc_Ntk_t * p )
ABC_FREE( p->vValues.pArray );
ABC_FREE( p->vCopies.pArray );
ABC_FREE( p->vBits.pArray );
+ ABC_FREE( p->vLevels.pArray );
+ ABC_FREE( p->vRefs.pArray );
ABC_FREE( p->pInits );
ABC_FREE( p->pObjs );
ABC_FREE( p->pName );
@@ -246,6 +276,91 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p )
/**Function*************************************************************
+ Synopsis [Assigns object levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkCreateLevels( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ int i, k, iFanin, Level, LevelMax = 0;
+ Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ Level = 0;
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Level = Abc_MaxInt( Level, Wlc_ObjLevelId(p, iFanin) + 1 );
+ Vec_IntWriteEntry( &p->vLevels, i, Level );
+ LevelMax = Abc_MaxInt( LevelMax, Level );
+ }
+ return LevelMax;
+}
+int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ int i, k, iFanin, Level, LevelMax = 0;
+ Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
+ Wlc_NtkForEachObjReverse( p, pObj, i )
+ {
+ if ( Wlc_ObjIsCi(pObj) )
+ continue;
+ Level = Wlc_ObjLevel(p, pObj) + 1;
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Vec_IntUpdateEntry( &p->vLevels, iFanin, Level );
+ LevelMax = Abc_MaxInt( LevelMax, Level );
+ }
+ // reverse the values
+ Wlc_NtkForEachObj( p, pObj, i )
+ Vec_IntWriteEntry( &p->vLevels, i, LevelMax - Wlc_ObjLevelId(p, i) );
+ Wlc_NtkForEachCi( p, pObj, i )
+ Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), 0 );
+ return LevelMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects statistics for each side of the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] )
+{
+ Wlc_Obj_t * pObj;
+ int n, i;
+ if ( Wlc_NtkPoNum(p) != 2 )
+ return;
+ for ( n = 0; n < 2; n++ )
+ {
+ Wlc_NtkMarkCone( p, n, 1, 1, 0 );
+ Wlc_NtkForEachObj( p, pObj, i )
+ if ( pObj->Mark )
+ nObjs[n][pObj->Type]++;
+ }
+ Wlc_NtkCleanMarks( p );
+}
+int Wlc_NtkCountRealPis( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ int i, Count = 0;
+ Wlc_NtkMarkCone( p, -1, -1, 1, 0 );
+ Wlc_NtkForEachPi( p, pObj, i )
+ Count += pObj->Mark;
+ Wlc_NtkCleanMarks( p );
+ return Count;
+}
+
+/**Function*************************************************************
+
Synopsis [Prints distribution of operator types.]
Description []
@@ -298,13 +413,18 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty
Vec_WrdReverseOrder( vType );
Vec_WrdReverseOrder( vOccur );
}
-void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
+void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fTwoSides, int fVerbose )
{
+ int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type
Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0;
Vec_Ptr_t * vTypes, * vOccurs;
Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER );
word Sign;
int i, k, s, s0, s1;
+ if ( Wlc_NtkPoNum(p) != 2 )
+ fTwoSides = 0;
+ if ( fTwoSides )
+ Wlc_NtkCollectStats( p, nObjs );
// allocate statistics arrays
vTypes = Vec_PtrStart( WLC_OBJ_NUMBER );
vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER );
@@ -409,11 +529,11 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
else if ( pObj->Type == WLC_OBJ_REDUCT_XOR )
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_XOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NAND )
- Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
+ Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NOR )
- Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
+ Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NXOR )
- Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
+ Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
else if ( pObj->Type == WLC_OBJ_ARI_ADD )
Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_ADD, 9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
else if ( pObj->Type == WLC_OBJ_ARI_SUB )
@@ -435,28 +555,41 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
else if ( pObj->Type == WLC_OBJ_ARI_SQUARE )
Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQUARE, 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) );
}
- if ( nCountRange )
+ if ( nCountRange && Vec_IntSize(&p->vNameIds) > 0 )
{
printf( "Warning: %d objects of the design have non-zero-based ranges.\n", nCountRange );
printf( "In particular, object %6d with name \"%s\" has range %d=[%d:%d]\n", Wlc_ObjId(p, pObjRange),
Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg );
}
// print by occurrence
- printf( "ID : name occurrence and2 (occurrence)<output_range>=<input_range>.<input_range> ...\n" );
+ printf( "ID : name occurrence%s and2 (occurrence)<output_range>=<input_range>.<input_range> ...\n", fTwoSides ? " Left Share Right":"" );
for ( i = 0; i < WLC_OBJ_NUMBER; i++ )
{
Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i );
Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, i );
if ( p->nObjs[i] == 0 )
continue;
- printf( "%2d : %-8s %6d%8d ", i, Wlc_Names[i], p->nObjs[i], Vec_IntEntry(vAnds, i) );
+ printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] );
+ if ( fTwoSides )
+ {
+ int nTotal = i == WLC_OBJ_PI ? Wlc_NtkCountRealPis(p) : p->nObjs[i];
+ printf( " " );
+ printf( "%6d", nObjs[0][i] );
+ printf( "%6d", nObjs[0][i]+nObjs[1][i]-nTotal );
+ printf( "%6d", nObjs[1][i] );
+ }
+ printf( "%8d ", Vec_IntEntry(vAnds, i) );
// sort by occurence
Wlc_NtkPrintDistribSortOne( vTypes, vOccurs, i );
Vec_WrdForEachEntry( vType, Sign, k )
{
Wlc_NtkPrintDistribFromSign( Sign, &s, &s0, &s1 );
if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) )
+ {
printf( "\n " );
+ if ( fTwoSides )
+ printf( " " );
+ }
printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) );
printf( "%s%d", Abc_LitIsCompl(s)?"-":"", Abc_Lit2Var(s) );
if ( s0 )
@@ -535,19 +668,19 @@ void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type )
Wlc_NtkPrintNode( p, pObj );
}
}
-void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose )
+void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose )
{
int i;
printf( "%-20s : ", p->pName );
- printf( "PI = %4d ", Wlc_NtkPiNum(p) );
+ printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) );
printf( "PO = %4d ", Wlc_NtkPoNum(p) );
printf( "FF = %4d ", Wlc_NtkFfNum(p) );
- printf( "Obj = %6d ", Wlc_NtkObjNum(p) );
+ printf( "Obj = %6d ", Wlc_NtkObjNum(p) - Wlc_NtkPiNum(p) - Wlc_NtkPoNum(p) - Wlc_NtkFfNum(p) );
printf( "Mem = %.3f MB", 1.0*Wlc_NtkMemUsage(p)/(1<<20) );
printf( "\n" );
if ( fDistrib )
{
- Wlc_NtkPrintDistrib( p, fVerbose );
+ Wlc_NtkPrintDistrib( p, fTwoSides, fVerbose );
return;
}
if ( !fVerbose )
@@ -566,6 +699,80 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p )
+{
+ int i;
+ assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) );
+ assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) );
+ assert( pNew->pManName == NULL && p->pManName != NULL );
+ Wlc_NtkCleanNameId( pNew );
+ for ( i = 0; i < p->nObjsAlloc; i++ )
+ if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) )
+ Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) );
+ pNew->pManName = p->pManName;
+ p->pManName = NULL;
+ Vec_IntErase( &p->vNameIds );
+ // transfer table
+ pNew->pMemTable = p->pMemTable; p->pMemTable = NULL;
+ pNew->vTables = p->vTables; p->vTables = NULL;
+}
+char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq )
+{
+ static char pBuffer[1000];
+ sprintf( pBuffer, "%s_o%d_%s", p->pName, iCoId, fSeq ? "seq": "comb" );
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduce init vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit )
+{
+ Vec_Int_t * vInitNew = Vec_IntDup( vInit );
+ Wlc_Obj_t * pObj; int i, k = 0;
+ assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) );
+ Wlc_NtkForEachCi( p, pObj, i )
+ if ( !Wlc_ObjIsPi(pObj) && pObj->Mark )
+ Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i - Wlc_NtkPiNum(p)) );
+ Vec_IntShrink( vInitNew, k );
+ return vInitNew;
+}
+char * Wlc_ReduceMarkedInitStr( Wlc_Ntk_t * p, char * pInit )
+{
+ char * pInitNew = Abc_UtilStrsav( pInit );
+ Wlc_Obj_t * pObj; int i, b, nBits = 0, k = 0;
+ Wlc_NtkForEachCi( p, pObj, i )
+ {
+ if ( !Wlc_ObjIsPi(pObj) && pObj->Mark )
+ for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
+ pInitNew[k++] = pInitNew[nBits+b];
+ if ( !Wlc_ObjIsPi(pObj) )
+ nBits += Wlc_ObjRange(pObj);
+ }
+ pInitNew[k] = '\0';
+ assert( nBits == (int)strlen(pInit) );
+ return pInitNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Duplicates the network in a topological order.]
Description []
@@ -623,47 +830,214 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v
Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
Wlc_ObjDup( pNew, p, iObj, vFanins );
}
-Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p )
+Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq )
{
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj;
Vec_Int_t * vFanins;
int i;
- Wlc_NtkCleanCopy( p );
vFanins = Vec_IntAlloc( 100 );
+ Wlc_NtkCleanCopy( p );
pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
pNew->fSmtLib = p->fSmtLib;
Wlc_NtkForEachCi( p, pObj, i )
- Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ if ( !fMarked || pObj->Mark )
+ {
+ unsigned Type = pObj->Type;
+ if ( !fSeq ) pObj->Type = WLC_OBJ_PI;
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ pObj->Type = Type;
+ }
Wlc_NtkForEachCo( p, pObj, i )
- Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ if ( !fMarked || pObj->Mark )
+ Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
- Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi );
+ if ( !fMarked || pObj->Mark )
+ Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 );
+ Vec_IntFree( vFanins );
+ if ( fSeq )
+ {
+ if ( fMarked )
+ {
+ if ( p->vInits )
+ pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits );
+ if ( p->pInits )
+ pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits );
+ }
+ else
+ {
+ if ( p->vInits )
+ pNew->vInits = Vec_IntDup( p->vInits );
+ if ( p->pInits )
+ pNew->pInits = Abc_UtilStrsav( p->pInits );
+ }
+ }
+ if ( p->pSpec )
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Wlc_NtkTransferNames( pNew, p );
+ return pNew;
+}
+Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
+{
+ Wlc_Ntk_t * pNew;
+ Wlc_Obj_t * pObj;
+ Vec_Int_t * vFanins;
+ int i;
+ Wlc_NtkCleanCopy( p );
+ pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
+ pNew->fSmtLib = p->fSmtLib;
+
+ // duplicate marked PIs
+ vFanins = Vec_IntAlloc( 100 );
+ Wlc_NtkForEachObjVec( vPisOld, p, pObj, i )
+ {
+ assert( Wlc_ObjIsPi(pObj) );
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ }
+ // duplicate additional PIs
+ Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
+ {
+ unsigned Type = pObj->Type;
+ int nFanins = Wlc_ObjFaninNum(pObj);
+ assert( !Wlc_ObjIsPi(pObj) );
+ pObj->Type = WLC_OBJ_PI;
+ pObj->nFanins = 0;
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ pObj->Type = Type;
+ pObj->nFanins = (unsigned)nFanins;
+ }
+ // duplicate flop outputs
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ {
+ assert( !Wlc_ObjIsPi(pObj) && Wlc_ObjIsCi(pObj) );
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ }
+
+ // duplicate logic cones of primary outputs
+ Wlc_NtkForEachPo( p, pObj, i )
+ Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ // duplidate logic cone of flop inputs
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj)), vFanins );
+
+ // duplicate POs
+ Wlc_NtkForEachPo( p, pObj, i )
+ Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), 0 );
+ // duplicate flop inputs
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, Wlc_ObjFo2Fi(p, pObj)), 1 );
+ Vec_IntFree( vFanins );
+
+ // mark flop outputs
+ Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
+ pObj->Mark = 1;
if ( p->vInits )
- pNew->vInits = Vec_IntDup( p->vInits );
+ pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits );
if ( p->pInits )
- pNew->pInits = Abc_UtilStrsav( p->pInits );
- Vec_IntFree( vFanins );
+ pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits );
+ Wlc_NtkCleanMarks( p );
+
if ( p->pSpec )
- pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ //Wlc_NtkTransferNames( pNew, p );
return pNew;
}
-void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p )
+
+/**Function*************************************************************
+
+ Synopsis [Select the cone of the given output.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkCleanMarks( Wlc_Ntk_t * p )
{
+ Wlc_Obj_t * pObj;
int i;
- assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) );
- assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) );
- assert( pNew->pManName == NULL && p->pManName != NULL );
- Wlc_NtkCleanNameId( pNew );
- for ( i = 0; i < p->nObjsAlloc; i++ )
- if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) )
- Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) );
- pNew->pManName = p->pManName;
- p->pManName = NULL;
- Vec_IntErase( &p->vNameIds );
- // transfer table
- pNew->pMemTable = p->pMemTable; p->pMemTable = NULL;
- pNew->vTables = p->vTables; p->vTables = NULL;
+ Wlc_NtkForEachObj( p, pObj, i )
+ pObj->Mark = 0;
+}
+int Wlc_NtkCountMarked( Wlc_Ntk_t * p, int * pnPis, int * pnFos, int * pnAdders, int * pnMults )
+{
+ Wlc_Obj_t * pObj;
+ int i, nNodes = 0;
+ *pnPis = *pnFos = *pnAdders = *pnMults = 0;
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ if ( !pObj->Mark )
+ continue;
+ if ( Wlc_ObjIsPi(pObj) )
+ (*pnPis)++;
+ else if ( Wlc_ObjIsCi(pObj) )
+ (*pnFos)++;
+ else if ( pObj->Mark )
+ {
+ nNodes++;
+ if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB )
+ (*pnAdders)++;
+ else if ( pObj->Type == WLC_OBJ_ARI_MULTI )
+ (*pnMults)++;
+ }
+ }
+ return nNodes;
+}
+void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops )
+{
+ int i, iFanin;
+ if ( pObj->Mark )
+ return;
+ pObj->Mark = 1;
+ if ( Wlc_ObjIsCi(pObj) )
+ {
+ if ( !Wlc_ObjIsPi(pObj) )
+ Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) );
+ return;
+ }
+ Wlc_ObjForEachFanin( pObj, iFanin, i )
+ Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops );
+}
+void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis )
+{
+ Vec_Int_t * vFlops;
+ Wlc_Obj_t * pObj;
+ int i, CiId, CoId;
+ Wlc_NtkCleanMarks( p );
+ if ( fAllPis )
+ Wlc_NtkForEachPi( p, pObj, i )
+ pObj->Mark = 1;
+ vFlops = Vec_IntAlloc( 100 );
+ Wlc_NtkForEachCo( p, pObj, i )
+ if ( iCoId == -1 || (i >= iCoId && i < iCoId + Range) )
+ Wlc_NtkMarkCone_rec( p, pObj, vFlops );
+ if ( fSeq )
+ Vec_IntForEachEntry( vFlops, CiId, i )
+ {
+ CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p);
+ Wlc_NtkMarkCone_rec( p, Wlc_NtkCo(p, CoId), vFlops );
+ }
+ Vec_IntFree( vFlops );
+}
+void Wlc_NtkProfileCones( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ int i, nPis, nFos, nNodes, nAdders, nMults;
+ Wlc_NtkForEachCo( p, pObj, i )
+ {
+ Wlc_NtkMarkCone( p, i, 1, 0, 0 );
+ nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults );
+ printf( "Cone %5d : ", i );
+ printf( "PI = %4d ", nPis );
+ printf( "FO = %4d ", nFos );
+ printf( "Node = %6d ", nNodes );
+ printf( "Add/Sub = %4d ", nAdders );
+ printf( "Mult = %4d ", nMults );
+ printf( "\n" );
+ }
+ Wlc_NtkCleanMarks( p );
}
/**Function*************************************************************
@@ -723,6 +1097,128 @@ Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Creates short names for all objects.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkShortNames( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj;
+ char pBuffer[100];
+ int nDigits, NameId, fFound, i;
+ int nFlops = Wlc_NtkCoNum(p) - Wlc_NtkPoNum(p);
+ nDigits = Abc_Base10Log( nFlops );
+ Wlc_NtkForEachCo( p, pObj, i )
+ {
+ if ( Wlc_ObjIsPo(pObj) )
+ continue;
+ sprintf( pBuffer, "%s%0*d", "fi", nDigits, i - Wlc_NtkPoNum(p) );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+ Wlc_NtkForEachCi( p, pObj, i )
+ {
+ if ( Wlc_ObjIsPi(pObj) )
+ continue;
+ sprintf( pBuffer, "%s%0*d", "fo", nDigits, i - Wlc_NtkPiNum(p) );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+ nDigits = Abc_Base10Log( Wlc_NtkPoNum(p) );
+ Wlc_NtkForEachPo( p, pObj, i )
+ {
+ sprintf( pBuffer, "%s%0*d", "po", nDigits, i );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+ nDigits = Abc_Base10Log( Wlc_NtkPiNum(p) );
+ Wlc_NtkForEachPi( p, pObj, i )
+ {
+ sprintf( pBuffer, "%s%0*d", "pi", nDigits, i );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+ nDigits = Abc_Base10Log( Wlc_NtkObjNum(p) );
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ if ( Wlc_ObjIsCi(pObj) || Wlc_ObjIsCo(pObj) )
+ continue;
+ sprintf( pBuffer, "%s%0*d", "n", nDigits, i );
+ NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
+ Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count the number of flops initialized to DC value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p )
+{
+ int i, nFlops, Count = 0;
+ if ( p->pInits == NULL )
+ return 0;
+ nFlops = strlen(p->pInits);
+ for ( i = 0; i < nFlops; i++ )
+ Count += (p->pInits[i] == 'x' || p->pInits[i] == 'X');
+ return Count;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create references.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkSetRefs( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj; int i, k, Fanin;
+ Vec_IntFill( &p->vRefs, Wlc_NtkObjNumMax(p), 0 );
+ Wlc_NtkForEachObj( p, pObj, i )
+ Wlc_ObjForEachFanin( pObj, Fanin, k )
+ Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
+ Wlc_NtkForEachCo( p, pObj, i )
+ Vec_IntAddToEntry( &p->vRefs, Wlc_ObjId(p, pObj), 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [This procedure simply count the number of PPI bits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew )
+{
+ Wlc_Obj_t * pObj;
+ int i, Count = 0;
+ Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
+ Count += Wlc_ObjRange(pObj);
+ return Count;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c
index d07a54c4..69a01ab0 100644
--- a/src/base/wlc/wlcReadSmt.c
+++ b/src/base/wlc/wlcReadSmt.c
@@ -48,6 +48,9 @@ struct Smt_Prs_t_
char ErrorStr[1000];
};
+//#define SMT_GLO_SUFFIX "_glb"
+#define SMT_GLO_SUFFIX ""
+
// parser name types
typedef enum {
SMT_PRS_NONE = 0,
@@ -219,6 +222,8 @@ static inline int Smt_StrToType( char * pName, int * pfSigned )
Type = WLC_OBJ_ARI_REM, *pfSigned = 1; // 40: arithmetic remainder
else if ( !strcmp(pName, "bvsmod") )
Type = WLC_OBJ_ARI_MODULUS, *pfSigned = 1; // 40: arithmetic modulus
+ else if ( !strcmp(pName, "=") )
+ Type = WLC_OBJ_COMP_EQU; // 40: arithmetic modulus
// else if ( !strcmp(pName, "") )
// Type = WLC_OBJ_ARI_POWER; // 41: arithmetic power
else if ( !strcmp(pName, "bvneg") )
@@ -255,6 +260,8 @@ static inline int Smt_PrsReadType( Smt_Prs_t * p, int iSig, int * pfSigned, int
}
}
+static inline int Smt_StrType( char * str ) { return Smt_StrToType(str, NULL); }
+
/**Function*************************************************************
Synopsis []
@@ -274,20 +281,27 @@ static inline int Smt_PrsCreateNodeOld( Wlc_Ntk_t * pNtk, int Type, int fSigned,
assert( Type > 0 );
assert( Range >= 0 );
assert( fSigned >= 0 );
- Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins );
- if ( fSigned )
- Wlc_NtkObj(pNtk, iObj)->Signed = fSigned;
- if ( Type == WLC_OBJ_SHIFT_RA )
- Wlc_NtkObj(pNtk, iObj)->Signed = 1;
+
+ // add node's name
if ( pName == NULL )
{
sprintf( Buffer, "_n%d_", iObj );
pName = Buffer;
}
- // add node's name
NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound );
assert( !fFound );
assert( iObj == NameId );
+
+ Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins );
+ if ( fSigned )
+ {
+ Wlc_NtkObj(pNtk, iObj)->Signed = fSigned;
+// if ( Vec_IntSize(vFanins) > 0 )
+// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 0))->Signed = fSigned;
+// if ( Vec_IntSize(vFanins) > 1 )
+// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 1))->Signed = fSigned;
+ }
+
return iObj;
}
static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, int Range, Vec_Int_t * vFanins, char * pName )
@@ -302,8 +316,7 @@ static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, in
assert( Range >= 0 );
assert( fSigned >= 0 );
- // allow more than 2 fanins for specific operators
- // if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX )
+ //if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX )
// explicitely secify allowed multi operators
if (Vec_IntSize(vFanins)<=2 ||
!( Type == WLC_OBJ_BIT_AND || // 16:`` bitwise AND
@@ -362,17 +375,17 @@ FINISHED_WITH_FANINS:
Vec_IntFree(v2Fanins);
- // to deal with long shifts create extra bit select (ROTATE as well ??)
+ //added to deal with long shifts create extra bit select (ROTATE as well ??)
// this is a temporary hack
- // basically we keep only 32 bits.
- // bits 0 - 30 are kept same as original
- // bit 31 will be the reduction or of all bits from 31 to Range-1
+ // basically we keep only 32 bits.
+ // bit[31] will be the copy of original MSB (sign bit, just in case) UPDATE: assume it is unsigned first????
+ // bit[31] will be the reduction or of any bits from [31] to Range
if (Type == WLC_OBJ_SHIFT_R || Type == WLC_OBJ_SHIFT_RA || Type == WLC_OBJ_SHIFT_L)
{
- int iFanin1 = Vec_IntEntry(vFanins,1);
- int range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) );
- int iObj1, iObj2, iObj3;
+ int range1, iObj1, iObj2, iObj3;
assert(Vec_IntSize(vFanins)>=2);
+ iFanin1 = Vec_IntEntry(vFanins,1);
+ range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) );
if (range1>32)
{
Vec_Int_t * newFanins = Vec_IntAlloc(10);
@@ -389,6 +402,8 @@ FINISHED_WITH_FANINS:
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj1), newFanins );
+ //printf("obj1: %d\n",iObj1);
+
// bit select of larger bits
Vec_IntPop(newFanins);
Vec_IntPop(newFanins);
@@ -402,6 +417,7 @@ FINISHED_WITH_FANINS:
assert( iObj2 == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj2), newFanins );
+ //printf("obj2: %d\n",iObj2);
// reduction or
Vec_IntPop( newFanins );
@@ -416,6 +432,7 @@ FINISHED_WITH_FANINS:
assert( iObj3 == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj3), newFanins );
+ //printf("obj3: %d\n",iObj3);
// concat all together
Vec_IntWriteEntry( newFanins, 0, iObj3 );
@@ -429,6 +446,7 @@ FINISHED_WITH_FANINS:
assert( iObj == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), newFanins );
+ //printf("obj: %d\n",iObj);
// pushing the new node
Vec_IntWriteEntry(vFanins, 1, iObj);
@@ -461,34 +479,22 @@ FINISHED_WITH_FANINS:
return iObj;
}
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
static inline char * Smt_GetHexFromDecimalString(char * pStr)
{
int i,k=0, nDigits = strlen(pStr);
int digit, carry = 0;
- int metNonZeroBit;
- int nBits;
- char * hex;
+ int metNonZeroBit = 0;
Vec_Int_t * decimal = Vec_IntAlloc(nDigits);
Vec_Int_t * rev;
+ int nBits;
+ char * hex;
for (i=0;i<nDigits;i++)
Vec_IntPush(decimal,pStr[i]-'0');
- // firstly fill-in the reversed vector
+ // firstly fillin the reversed vector
rev = Vec_IntAlloc(10);
- metNonZeroBit = 0;
while(k<nDigits)
{
digit = Vec_IntEntry(decimal,k);
@@ -501,7 +507,7 @@ static inline char * Smt_GetHexFromDecimalString(char * pStr)
break;
else
{
- Vec_IntPush(rev,carry);
+ Vec_IntPush(rev,carry);
carry = 0;
k = 0;
metNonZeroBit = 0;
@@ -564,12 +570,17 @@ static inline char * Smt_GetHexFromDecimalString(char * pStr)
default: assert(0);
}
hex[nBits/4-1-k] = letter;
+ //if (k<Vec_IntSize(rev))
+ // Vec_IntPush(vFanins,Vec_IntEntry(rev,k));
+ //else
+ // Vec_IntPush(vFanins,0);
}
hex[nBits/4] = '\0';
Vec_IntFree(rev);
return hex;
-}
+}
+
static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits, char * pName )
{
int i, nDigits, iObj;
@@ -578,6 +589,25 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
{
if ( pStr[0] >= '0' && pStr[0] <= '9' )
{
+ // added: sanity check for large constants
+ /*
+ Vec_Int_t * temp = Vec_IntAlloc(10);
+ int fullBits = -1;
+ Smt_GetBinaryFromDecimalString(pStr,temp,&fullBits);
+ Vec_IntFree(temp);
+ assert(fullBits < 32);*/
+
+ char * pHex = Smt_GetHexFromDecimalString(pStr);
+
+ if ( nBits == -1 )
+ nBits = strlen(pHex)*4;
+
+ //printf("nbits: %d\n",nBits);
+
+ Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
+ nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex );
+ ABC_FREE( pHex );
+
/*
int w, nWords, Number = atoi( pStr );
if ( nBits == -1 )
@@ -589,15 +619,6 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
for ( w = 0; w < nWords; w++ )
Vec_IntPush( vFanins, w ? 0 : Number );
*/
-
- // convert decimal to hex to parse large constants
- char * pHex = Smt_GetHexFromDecimalString(pStr);
-
- if ( nBits == -1 )
- nBits = strlen(pHex)*4;
-
- Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
- nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex );
}
else
{
@@ -616,7 +637,10 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
if ( pStr[2+i] == '1' )
Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i );
else if ( pStr[2+i] != '0' )
+ {
+ Vec_IntFree( vFanins );
return 0;
+ }
}
else if ( pStr[1] == 'x' ) // hexadecimal
{
@@ -625,9 +649,16 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 );
if ( nDigits != (nBits + 3)/4 )
+ {
+ Vec_IntFree( vFanins );
return 0;
+ }
+ }
+ else
+ {
+ Vec_IntFree( vFanins );
+ return 0;
}
- else return 0;
// create constant node
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_CONST, 0, nBits, vFanins, pName );
Vec_IntFree( vFanins );
@@ -648,12 +679,6 @@ int Smt_PrsBuildNode( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int RangeOut,
// s3087
int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
assert( fFound );
- // create buffer if the name of the fanin has different name
- if ( pName && strcmp(pStr, pName) )
- {
- Vec_IntFill( &p->vTempFans, 1, iObj );
- iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, RangeOut, &p->vTempFans, pName );
- }
return iObj;
}
}
@@ -804,13 +829,6 @@ Wlc_Ntk_t * Smt_PrsBuild( Smt_Prs_t * p )
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
- vFans2 = Smt_VecEntryNode(p, vFans, 2);
- if ( Vec_IntSize(vFans2) > 0 )
- {
- printf( "File parsing error: Uninterpreted functions are not supported.\n" );
- Wlc_NtkFree( pNtk ); pNtk = NULL;
- goto finish;
- }
// check type (Bool or BitVec)
Fan = Vec_IntEntry(vFans, 3);
if ( Smt_EntryIsName(Fan) )
@@ -1006,6 +1024,14 @@ char * Smt_PrsGenName( Smt_Prs_t * p )
}
int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pName )
{
+ char suffix[100];
+ sprintf(suffix,"_as%d",pNtk->nAssert);
+
+ //char * prepStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode));
+ //printf("prestr: %s\n",prepStr);
+
+ //printf("inode: %d %d\n",iNode,Smt_EntryIsName(iNode));
+
if ( Smt_EntryIsName(iNode) )
{
char * pStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode));
@@ -1018,7 +1044,27 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
return Smt_PrsBuildConstant( pNtk, pStr, -1, pName ? pName : Smt_PrsGenName(p) );
else
{
- int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
+ int fFound, iObj;
+ // look either for global DECLARE-FUN variable or local LET
+ char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb
+ char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1);
+ strcpy(pStr_glb,pStr);
+ strcat(pStr_glb,SMT_GLO_SUFFIX);
+ strcpy(pStr_loc,pStr);
+ strcat(pStr_loc,suffix);
+
+ fFound = Abc_NamStrFind( pNtk->pManName, pStr_glb );
+
+ if (fFound)
+ pStr = pStr_glb;
+ else
+ {
+ assert( Abc_NamStrFind( pNtk->pManName, pStr_loc ));
+ pStr = pStr_loc;
+ }
+ // FIXME: delete memory of pStr
+
+ iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
assert( fFound );
// create buffer if the name of the fanin has different name
if ( pName && strcmp(Wlc_ObjName(pNtk, iObj), pName) )
@@ -1026,9 +1072,11 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
Vec_IntFill( &p->vTempFans, 1, iObj );
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, Wlc_ObjRange(Wlc_NtkObj(pNtk, iObj)), &p->vTempFans, pName );
}
+ ABC_FREE( pStr_glb );
+ ABC_FREE( pStr_loc );
return iObj;
}
- }
+ }
else
{
Vec_Int_t * vRoots, * vRoots1, * vFans3;
@@ -1039,7 +1087,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
if ( Smt_EntryIsName(iRoot0) )
{
char * pName2, * pStr0 = Abc_NamStr(p->pStrs, Abc_Lit2Var(iRoot0));
- if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET )
+ if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET || Abc_Lit2Var(iRoot0) == SMT_PRS_DEFINE_FUN) //added define-fun is similar to let
{
// let ((s35550 (bvor s48 s35549)))
assert( Vec_IntSize(vRoots) == 3 );
@@ -1051,6 +1099,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
// iterate through the parts
Vec_IntForEachEntry( vRoots1, Fan, k )
{
+ char * temp;
// s35550 (bvor s48 s35549)
assert( !Smt_EntryIsName(Fan) );
vFans3 = Smt_EntryNode(p, Fan);
@@ -1059,11 +1108,26 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
Fan3 = Vec_IntEntry(vFans3, 0);
assert( Smt_EntryIsName(Fan3) );
pName2 = Smt_EntryName(p, Fan3);
+ // create a local name with suffix
+ if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET )
+ {
+ temp = (char *)malloc(strlen(pName2) + strlen(suffix) + 1);
+ strcpy(temp, pName2);
+ strcat(temp,suffix);
+ }
+ else
+ { temp = (char *)malloc(strlen(pName2) + 4 + 1);
+ strcpy(temp, pName2);
+ strcat(temp,SMT_GLO_SUFFIX);
+ }
+ // FIXME: need to delete memory of pName2
+ pName2 = temp;
// get function
Fan3 = Vec_IntEntry(vFans3, 1);
//assert( !Smt_EntryIsName(Fan3) );
// solve the problem
iObj = Smt_PrsBuild2_rec( pNtk, p, Fan3, -1, pName2 ); // NULL ); //pName2 );
+ ABC_FREE( temp );
if ( iObj == 0 )
return 0;
// create buffer
@@ -1133,7 +1197,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
int iObj = Abc_NamStrFind( pNtk->pManName, pStr0 );
if ( iObj )
return iObj;
-
Type0 = Smt_StrToType( pStr0, &fSigned );
if ( Type0 == 0 )
return 0;
@@ -1151,7 +1214,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
}
Vec_IntPush( vFanins, iObj );
}
-
// find range
Range = 0;
if ( Type0 >= WLC_OBJ_LOGIC_NOT && Type0 <= WLC_OBJ_REDUCT_XOR )
@@ -1197,7 +1259,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Wlc_Ntk_t * pNtk;
Vec_Int_t * vFansRoot, * vFans, * vFans2;
Vec_Int_t * vAsserts = Vec_IntAlloc(100);
- int i, Root, Fan, iObj, NameId, Range, Status, nBits = 0;
+ int i, Root, Fan, iObj, NameId, Range, nBits = 0;
char * pName, * pRange;
// start network and create primary inputs
pNtk = Wlc_NtkAlloc( p->pName, 1000 );
@@ -1214,22 +1276,22 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// create variables
if ( Abc_Lit2Var(Fan) == SMT_PRS_DECLARE_FUN )
{
+ char * pName_glb;
assert( Vec_IntSize(vFans) == 4 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DECLARE_FUN) );
// get name
Fan = Vec_IntEntry(vFans, 1);
assert( Smt_EntryIsName(Fan) );
pName = Smt_EntryName(p, Fan);
+ // added: giving a global suffix
+ pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
+ strcpy(pName_glb,pName);
+ strcat(pName_glb,SMT_GLO_SUFFIX);
+ // FIXME: delete memory of pName
+ pName = pName_glb;
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
- vFans2 = Smt_VecEntryNode(p, vFans, 2);
- if ( Vec_IntSize(vFans2) > 0 )
- {
- printf( "File parsing error: Uninterpreted functions are not supported.\n" );
- Wlc_NtkFree( pNtk ); pNtk = NULL;
- goto finish;
- }
// check type (Bool or BitVec)
Fan = Vec_IntEntry(vFans, 3);
if ( Smt_EntryIsName(Fan) )
@@ -1259,9 +1321,11 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Vec_IntPush( &pNtk->vValues, nBits );
Vec_IntPush( &pNtk->vValues, Range );
nBits += Range;
+ ABC_FREE( pName_glb );
}
// create constants
- else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN )
+ /*
+ else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) // added: we parse DEFINE_FUN in LET
{
assert( Vec_IntSize(vFans) == 5 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) );
@@ -1269,6 +1333,14 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Fan = Vec_IntEntry(vFans, 1);
assert( Smt_EntryIsName(Fan) );
pName = Smt_EntryName(p, Fan);
+
+ // added: giving a global suffix
+ char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
+ strcpy(pName_glb,pName);
+ strcat(pName_glb,SMT_GLO_SUFFIX);
+ // FIXME: delete memory of pName
+ pName = pName_glb;
+
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
@@ -1278,13 +1350,17 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
{
// (define-fun s_2 () Bool false)
assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) );
- iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), -1, pName );
- if ( iObj == 0 )
- {
- Wlc_NtkFree( pNtk ); pNtk = NULL;
- goto finish;
- }
- continue;
+ Range = 1;
+ pValue = Smt_VecEntryName(p, vFans, 4);
+
+ //printf("value: %s\n",pValue);
+
+ if ( !strcmp("false", pValue) )
+ pValue = "#b0";
+ else if ( !strcmp("true", pValue) )
+ pValue = "#b1";
+ else assert( 0 );
+ Status = Smt_PrsBuildConstant( pNtk, pValue, Range, pName );
}
else
{
@@ -1292,6 +1368,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// (define-fun s1 () (_ BitVec 8) (bvneg #x7f))
// get range
Fan = Vec_IntEntry(vFans, 3);
+
assert( !Smt_EntryIsName(Fan) );
vFans2 = Smt_VecEntryNode(p, vFans, 3);
assert( Vec_IntSize(vFans2) == 3 );
@@ -1299,11 +1376,24 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) );
// get range
Fan = Vec_IntEntry(vFans2, 2);
+
assert( Smt_EntryIsName(Fan) );
pRange = Smt_EntryName(p, Fan);
Range = atoi(pRange);
+
+ // added: can parse functions too
+ Vec_Int_t * vFans3 = Smt_VecEntryNode(p, vFans, 4);
+ Fan = Vec_IntEntry(vFans3, 0);
+
// get constant
- Fan = Vec_IntEntry(vFans, 4);
+ //Fan = Vec_IntEntry(vFans, 4);
+
+ //printf("fan3: %s\n",Fan);
+ //printf("fan0: %s\n",Smt_VecEntryName(p, vFans3, 0));
+ //printf("fan1: %s\n",Smt_VecEntryName(p, vFans3, 1));
+ //printf("fan2: %s\n",Smt_VecEntryName(p, vFans3, 2));
+ //printf("fan3: %s\n",Smt_VecEntryName(p, vFans3, 3));
+
Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName );
}
if ( !Status )
@@ -1312,6 +1402,57 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
goto finish;
}
}
+ */
+ // added: new way to parse define-fun
+ // create constants
+ else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN )
+ {
+ char * pName_glb;
+ // (define-fun def_16001 () Bool (or def_15999 def_16000))
+ // (define-fun def_15990 () (_ BitVec 24) (concat def_15988 def_15989))
+ assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) );
+ assert( Vec_IntSize(vFans) == 5 ); // const or definition
+
+ // get name
+ Fan = Vec_IntEntry(vFans, 1);
+ assert( Smt_EntryIsName(Fan) );
+ pName = Smt_EntryName(p, Fan);
+ // added: giving a global suffix
+ pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
+ strcpy(pName_glb,pName);
+ strcat(pName_glb,SMT_GLO_SUFFIX);
+ // FIXME: delete memory of pName
+ pName = pName_glb;
+
+ //get range
+ Fan = Vec_IntEntry(vFans, 3);
+ if ( Smt_EntryIsName(Fan) )
+ {
+ // (define-fun s_2 () Bool false)
+ assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) );
+ Range = 1;
+ }
+ else
+ {
+ // (define-fun s702 () (_ BitVec 4) #xe)
+ // (define-fun s1 () (_ BitVec 8) (bvneg #x7f))
+ assert( !Smt_EntryIsName(Fan) );
+ vFans2 = Smt_VecEntryNode(p, vFans, 3);
+ assert( Vec_IntSize(vFans2) == 3 );
+ assert( !strcmp("_", Smt_VecEntryName(p, vFans2, 0)) );
+ assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) );
+ // get range
+ Fan = Vec_IntEntry(vFans2, 2);
+ assert( Smt_EntryIsName(Fan) );
+ pRange = Smt_EntryName(p, Fan);
+ Range = atoi(pRange);
+ }
+
+ iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), Range, pName );
+ assert( iObj );
+ ABC_FREE( pName_glb );
+ }
+
// collect assertion outputs
else if ( Abc_Lit2Var(Fan) == SMT_PRS_ASSERT )
{
@@ -1321,6 +1462,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
//(assert (not (= s0 #x00)))
assert( Vec_IntSize(vFans) == 2 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_ASSERT) );
+ pNtk->nAssert++; // added
iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 1), -1, NULL );
if ( iObj == 0 )
{
@@ -1336,6 +1478,9 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// build AND of asserts
if ( Vec_IntSize(vAsserts) == 1 )
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, 1, vAsserts, "miter" );
+ // added: 0 asserts
+ else if ( Vec_IntSize(vAsserts) == 0 )
+ iObj = Smt_PrsBuildConstant( pNtk, "#b1", 1, "miter" );
else
{
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vAsserts), vAsserts, NULL );
@@ -1413,18 +1558,35 @@ static inline char * Smt_PrsLoadFile( char * pFileName, char ** ppLimit )
static inline int Smt_PrsRemoveComments( char * pBuffer, char * pLimit )
{
char * pTemp; int nCount1 = 0, nCount2 = 0, fHaveBar = 0;
+ int backslash = 0;
for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ )
{
if ( *pTemp == '(' )
- nCount1++;
+ { if ( !fHaveBar ) nCount1++; }
else if ( *pTemp == ')' )
- nCount2++;
+ { if ( !fHaveBar ) nCount2++; }
else if ( *pTemp == '|' )
fHaveBar ^= 1;
else if ( *pTemp == ';' && !fHaveBar )
while ( *pTemp && *pTemp != '\n' )
*pTemp++ = ' ';
+ // added: hack to remove quotes
+ else if ( *pTemp == '\"' && *(pTemp-1) != '\\' && !fHaveBar )
+ {
+ *pTemp++ = ' ';
+ while ( *pTemp && (*pTemp != '\"' || backslash))
+ {
+ if (*pTemp == '\\')
+ backslash = 1;
+ else
+ backslash = 0;
+ *pTemp++ = ' ';
+ }
+ // remove the last quote symbol
+ *pTemp = ' ';
+ }
}
+
if ( nCount1 != nCount2 )
printf( "The input SMTLIB file has different number of opening and closing parentheses (%d and %d).\n", nCount1, nCount2 );
else if ( nCount1 == 0 )
@@ -1486,6 +1648,7 @@ static inline void Smt_PrsSkipNonSpaces( Smt_Prs_t * p )
}
void Smt_PrsReadLines( Smt_Prs_t * p )
{
+ int fFirstTime = 1;
assert( Vec_IntSize(&p->vStack) == 0 );
//assert( Vec_WecSize(&p->vDepth) == 0 );
assert( Vec_WecSize(&p->vObjs) == 0 );
@@ -1499,6 +1662,16 @@ void Smt_PrsReadLines( Smt_Prs_t * p )
for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ )
{
Smt_PrsSkipSpaces( p );
+ if ( fFirstTime && *p->pCur == '|' )
+ {
+ fFirstTime = 0;
+ *p->pCur = ' ';
+ while ( *p->pCur && *p->pCur != '|' )
+ *p->pCur++ = ' ';
+ if ( *p->pCur == '|' )
+ *p->pCur = ' ';
+ continue;
+ }
if ( *p->pCur == '(' )
{
// add new node at this depth
@@ -1524,12 +1697,13 @@ void Smt_PrsReadLines( Smt_Prs_t * p )
{
// remove strange characters (this can lead to name clashes)
int iToken;
+ /* commented out for SMT comp
char * pTemp;
if ( *pStart == '?' )
*pStart = '_';
for ( pTemp = pStart; pTemp < p->pCur; pTemp++ )
if ( *pTemp == '.' )
- *pTemp = '_';
+ *pTemp = '_';*/
// create and save token for this string
iToken = Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur--, NULL );
Vec_IntPush( Vec_WecEntry(&p->vObjs, Vec_IntEntryLast(&p->vStack)), Abc_Var2Lit(iToken, 1) );
diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c
index fa3efacd..e4a65ecf 100644
--- a/src/base/wlc/wlcReadVer.c
+++ b/src/base/wlc/wlcReadVer.c
@@ -28,7 +28,7 @@ ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
// Word-level Verilog file parser
-#define WLV_PRS_MAX_LINE 1000
+#define WLV_PRS_MAX_LINE 10000
typedef struct Wlc_Prs_t_ Wlc_Prs_t;
struct Wlc_Prs_t_
@@ -1265,8 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
if ( !Wlc_PrsDerive( p ) )
goto finish;
// derive topological order
- pNtk = Wlc_NtkDupDfs( p->pNtk );
- Wlc_NtkTransferNames( pNtk, p->pNtk );
+ pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 );
pNtk->pSpec = Abc_UtilStrsav( pFileName );
finish:
Wlc_PrsPrintErrorMessage( p );
diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c
new file mode 100644
index 00000000..1601d602
--- /dev/null
+++ b/src/base/wlc/wlcShow.c
@@ -0,0 +1,337 @@
+/**CFile****************************************************************
+
+ FileName [wlcShow.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Parses several flavors of word-level Verilog.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlcShow.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the graph structure of WLC for DOT.]
+
+ Description [Useful for graph visualization using tools such as GraphViz:
+ http://www.graphviz.org/]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold )
+{
+ FILE * pFile;
+ Wlc_Obj_t * pNode;
+ int LevelMax, Prev, Level, i;
+
+ if ( Wlc_NtkObjNum(p) > 2000 )
+ {
+ fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 2000 );
+ return;
+ }
+ if ( (pFile = fopen( pFileName, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // mark the nodes
+ if ( vBold )
+ Wlc_NtkForEachObjVec( vBold, p, pNode, i )
+ pNode->Mark = 1;
+
+ // compute levels
+ LevelMax = 1 + Wlc_NtkCreateLevelsRev( p );
+
+ // write the DOT header
+ fprintf( pFile, "# %s\n", "WLC structure generated by ABC" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "digraph WLC {\n" );
+ fprintf( pFile, "size = \"7.5,10\";\n" );
+// fprintf( pFile, "ranksep = 0.5;\n" );
+// fprintf( pFile, "nodesep = 0.5;\n" );
+ fprintf( pFile, "center = true;\n" );
+// fprintf( pFile, "orientation = landscape;\n" );
+// fprintf( pFile, "edge [fontsize = 10];\n" );
+// fprintf( pFile, "edge [dir = none];\n" );
+ fprintf( pFile, "edge [dir = back];\n" );
+ fprintf( pFile, "\n" );
+
+ // labels on the left of the picture
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " node [shape = plaintext];\n" );
+ fprintf( pFile, " edge [style = invis];\n" );
+ fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
+ fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
+ // generate node names with labels
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ fprintf( pFile, " [label = " );
+ // label name
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "];\n" );
+ }
+
+ // genetate the sequence of visible/invisible nodes to mark levels
+ fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
+ for ( Level = LevelMax; Level >= 0; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ // the connector
+ if ( Level != 0 )
+ fprintf( pFile, " ->" );
+ else
+ fprintf( pFile, ";" );
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate title box on top
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle1;\n" );
+ fprintf( pFile, " title1 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=20,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "%s", "WLC structure generated by ABC" );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "Benchmark \\\"%s\\\". ", p->pName );
+// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate statistics box
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle2;\n" );
+ fprintf( pFile, " title2 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=18,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkCiNum(p), LevelMax-1 );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate the COs
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", LevelMax );
+ // generate the CO nodes
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ pNode = Wlc_ObjCo2PoFo(p, i);
+ fprintf( pFile, " NodePo%d [label = \"%s_in %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
+ fprintf( pFile, ", shape = %s", i < Wlc_NtkPoNum(p) ? "invtriangle" : "box" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate nodes of each rank
+ for ( Level = LevelMax - 1; Level > 0; Level-- )
+ {
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", Level );
+ Wlc_NtkForEachObj( p, pNode, i )
+ {
+ if ( (int)Wlc_ObjLevel(p, pNode) != Level )
+ continue;
+
+ if ( pNode->Type == WLC_OBJ_CONST )
+ {
+ fprintf( pFile, " Node%d [label = \"0x", i );
+ Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 );
+ fprintf( pFile, "\"" );
+ }
+ else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_MUX )
+ fprintf( pFile, " Node%d [label = \"%d\"", i, Wlc_ObjRange(pNode) );
+ else if ( pNode->Type >= WLC_OBJ_LOGIC_NOT && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
+ fprintf( pFile, " Node%d [label = \"%s\"", i, Wlc_ObjTypeName(pNode) );
+ else
+ fprintf( pFile, " Node%d [label = \"%s %d\"", i, Wlc_ObjTypeName(pNode), Wlc_ObjRange(pNode) );
+
+ if ( pNode->Type == WLC_OBJ_ARI_MULTI )
+ fprintf( pFile, ", shape = doublecircle" );
+ else if ( pNode->Type >= WLC_OBJ_COMP_EQU && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
+ fprintf( pFile, ", shape = diamond" );
+ else if ( pNode->Type == WLC_OBJ_BIT_SELECT || pNode->Type == WLC_OBJ_BIT_CONCAT )
+ fprintf( pFile, ", shape = box" );
+ else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_BIT_ZEROPAD || pNode->Type == WLC_OBJ_BIT_SIGNEXT )
+ fprintf( pFile, ", shape = triangle" );
+ else if ( pNode->Type == WLC_OBJ_MUX )
+ fprintf( pFile, ", shape = trapezium" );
+ else
+ fprintf( pFile, ", shape = ellipse" );
+
+ if ( vBold ? pNode->Mark : ((pNode->Type >= WLC_OBJ_ARI_ADD && pNode->Type <= WLC_OBJ_ARI_SQUARE) || pNode->Type == WLC_OBJ_BIT_NOT) )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ }
+
+ // generate the CI nodes
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", 0 );
+ // generate the CI nodes
+ Wlc_NtkForEachCi( p, pNode, i )
+ {
+ fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
+ fprintf( pFile, ", shape = %s", i < Wlc_NtkPiNum(p) ? "triangle" : "box" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate invisible edges from the square down
+ fprintf( pFile, "title1 -> title2 [style = invis];\n" );
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ pNode = Wlc_ObjCo2PoFo( p, i );
+ fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) );
+ }
+ // generate invisible edges among the COs
+ Prev = -1;
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ pNode = Wlc_ObjCo2PoFo( p, i );
+ if ( i > 0 )
+ fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
+ Prev = Wlc_ObjId(p, pNode);
+ }
+ // generate invisible edges among the CIs
+ Prev = -1;
+ Wlc_NtkForEachCi( p, pNode, i )
+ {
+ if ( i > 0 )
+ fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
+ Prev = Wlc_ObjId(p, pNode);
+ }
+
+ // generate edges
+ Wlc_NtkForEachCo( p, pNode, i )
+ {
+ fprintf( pFile, "NodePo%d", Wlc_ObjId(p, Wlc_ObjCo2PoFo(p, i)) );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", Wlc_ObjId(p, pNode) );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "solid" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ Wlc_NtkForEachObj( p, pNode, i )
+ {
+ int k, iFanin;
+ if ( Wlc_ObjIsCi(pNode) )
+ continue;
+ // generate the edge from this node to the next
+ Wlc_ObjForEachFanin( pNode, iFanin, k )
+ {
+ fprintf( pFile, "Node%d", i );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", iFanin );
+ fprintf( pFile, " [" );
+ fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "solid" );
+ if ( pNode->Type == WLC_OBJ_MUX && k == 0 )
+ fprintf( pFile, ", style = %s", "bold" );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
+ }
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+
+ // unmark nodes
+ if ( vBold )
+ Wlc_NtkCleanMarks( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold )
+{
+ extern void Abc_ShowFile( char * FileNameDot );
+ FILE * pFile;
+ char FileNameDot[200];
+ sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(p->pName, ".dot") );
+ // check that the file can be opened
+ if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
+ return;
+ }
+ fclose( pFile );
+ // generate the file
+ Wlc_NtkDumpDot( p, FileNameDot, vBold );
+ // visualize the file
+ Abc_ShowFile( FileNameDot );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wlc/wlcSim.c b/src/base/wlc/wlcSim.c
index 20ac8c61..e2fcd1f8 100644
--- a/src/base/wlc/wlcSim.c
+++ b/src/base/wlc/wlcSim.c
@@ -43,13 +43,13 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj )
{
- return Vec_WrdEntryP( p->vSims, p->iPatsPi * iObj );
+ return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );
}
static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj )
{
int w;
word * pSim = Wlc_ObjSim( p, iObj );
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = Gia_ManRandomW( 0 );
}
static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )
@@ -57,7 +57,7 @@ static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )
int w;
word * pSimRo = Wlc_ObjSim( p, iObj );
word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) );
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSimRo[w] = pSimRi[w];
}
static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )
@@ -67,10 +67,10 @@ static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )
word * pSimCo = Wlc_ObjSim( p, iObj );
word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
if ( Gia_ObjFaninC0(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSimCo[w] = ~pSimDri[w];
else
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSimCo[w] = pSimDri[w];
}
static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )
@@ -81,16 +81,16 @@ static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )
word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );
if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = ~pSim0[w] & ~pSim1[w];
else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = ~pSim0[w] & pSim1[w];
else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = pSim0[w] & ~pSim1[w];
else
- for ( w = 0; w < p->iPatsPi; w++ )
+ for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = pSim0[w] & pSim1[w];
}
@@ -135,7 +135,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int
// allocate simulation info for one timeframe
Vec_WrdFreeP( &pGia->vSims );
pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords );
- pGia->iPatsPi = nWords;
+ pGia->nSimWords = nWords;
// allocate resulting simulation info
vRes = Vec_PtrAlloc( Vec_IntSize(vNodes) );
Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i )
@@ -188,7 +188,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int
printf( "Replaced %d dangling internal bits with constant 0.\n", Counter );
}
Vec_WrdFreeP( &pGia->vSims );
- pGia->iPatsPi = 0;
+ pGia->nSimWords = 0;
Gia_ManStop( pGia );
return vRes;
}
diff --git a/src/base/wlc/wlcUif.c b/src/base/wlc/wlcUif.c
new file mode 100644
index 00000000..78451c17
--- /dev/null
+++ b/src/base/wlc/wlcUif.c
@@ -0,0 +1,290 @@
+/**CFile****************************************************************
+
+ FileName [wlcUif.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Abstraction for word-level networks.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlcUif.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Check if two objects have the same input/output signatures.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 )
+{
+ Wlc_Obj_t * pFanin, * pFanin2; int k;
+ if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) )
+ return 0;
+ if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) )
+ return 0;
+ if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) )
+ return 0;
+ for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
+ {
+ pFanin = Wlc_ObjFanin(p, pObj, k);
+ pFanin2 = Wlc_ObjFanin(p, pObj2, k);
+ if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) )
+ return 0;
+ if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) )
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect IDs of the multipliers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p )
+{
+ Wlc_Obj_t * pObj; int i;
+ Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 );
+ Wlc_NtkForEachObj( p, pObj, i )
+ if ( pObj->Type == WLC_OBJ_ARI_MULTI )
+ Vec_IntPush( vBoxIds, i );
+ if ( Vec_IntSize( vBoxIds ) > 0 )
+ return vBoxIds;
+ Vec_IntFree( vBoxIds );
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns all pairs of uifable multipliers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p )
+{
+ Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p );
+ Vec_Int_t * vPairs = Vec_IntAlloc( 2 );
+ Wlc_Obj_t * pObj, * pObj2; int i, k;
+ // iterate through unique pairs
+ Wlc_NtkForEachObjVec( vMultis, p, pObj, i )
+ Wlc_NtkForEachObjVec( vMultis, p, pObj2, k )
+ {
+ if ( k == i )
+ break;
+ if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) )
+ {
+ Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) );
+ Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) );
+ }
+ }
+ Vec_IntFree( vMultis );
+ if ( Vec_IntSize( vPairs ) > 0 )
+ return vPairs;
+ Vec_IntFree( vPairs );
+ return NULL;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Abstracts nodes by replacing their outputs with new PIs.]
+
+ Description [If array is NULL, abstract all multipliers.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
+{
+ Vec_Int_t * vNodes = vNodesInit;
+ Wlc_Ntk_t * pNew;
+ Wlc_Obj_t * pObj;
+ int i, k, iObj, iFanin;
+ // get multipliers if not given
+ if ( vNodes == NULL )
+ vNodes = Wlc_NtkCollectMultipliers( p );
+ if ( vNodes == NULL )
+ return NULL;
+ // mark nodes
+ Wlc_NtkForEachObjVec( vNodes, p, pObj, i )
+ pObj->Mark = 1;
+ // iterate through the nodes in the DFS order
+ Wlc_NtkCleanCopy( p );
+ Wlc_NtkForEachObj( p, pObj, i )
+ {
+ if ( i == Vec_IntSize(&p->vCopies) )
+ break;
+ if ( pObj->Mark ) {
+ // clean
+ pObj->Mark = 0;
+ // add fresh PI with the same number of bits
+ iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 );
+ }
+ else {
+ // update fanins
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin);
+ // node to remain
+ iObj = i;
+ }
+ Wlc_ObjSetCopy( p, i, iObj );
+ }
+ // POs do not change in this procedure
+ if ( vNodes != vNodesInit )
+ Vec_IntFree( vNodes );
+ // reconstruct topological order
+ pNew = Wlc_NtkDupDfs( p, 0, 1 );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds UIF constraints to node pairs and updates POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit )
+{
+ Vec_Int_t * vPairs = vPairsInit;
+ Wlc_Ntk_t * pNew;
+ Wlc_Obj_t * pObj, * pObj2;
+ Vec_Int_t * vUifConstrs, * vCompares, * vFanins;
+ int i, k, iObj, iObj2, iObjNew, iObjNew2;
+ int iFanin, iFanin2, iFaninNew;
+ // get multiplier pairs if not given
+ if ( vPairs == NULL )
+ vPairs = Wlc_NtkFindUifableMultiplierPairs( p );
+ if ( vPairs == NULL )
+ return NULL;
+ // sanity checks
+ assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 );
+ // iterate through node pairs
+ vFanins = Vec_IntAlloc( 100 );
+ vCompares = Vec_IntAlloc( 100 );
+ vUifConstrs = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i )
+ {
+ // get two nodes
+ pObj = Wlc_NtkObj( p, iObj );
+ pObj2 = Wlc_NtkObj( p, iObj2 );
+ assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) );
+ // create fanin comparator nodes
+ Vec_IntClear( vCompares );
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ {
+ iFanin2 = Wlc_ObjFaninId( pObj2, k );
+ Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 );
+ iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins );
+ Vec_IntPush( vCompares, iFaninNew );
+ // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
+ // Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
+ pObj = Wlc_NtkObj( p, iObj );
+ }
+ // concatenate fanin comparators
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares );
+ // create reduction-OR node
+ Vec_IntFill( vFanins, 1, iObjNew );
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins );
+ // craete output comparator node
+ Vec_IntFillTwo( vFanins, 2, iObj, iObj2 );
+ iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins );
+ // create implication node (iObjNew is already complemented above)
+ Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 );
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins );
+ // save the constraint
+ Vec_IntPush( vUifConstrs, iObjNew );
+ }
+ // derive the AND of the UIF contraints
+ assert( Vec_IntSize(vUifConstrs) > 0 );
+ if ( Vec_IntSize(vUifConstrs) == 1 )
+ iObjNew = Vec_IntEntry( vUifConstrs, 0 );
+ else
+ {
+ // concatenate
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs );
+ // create reduction-AND node
+ Vec_IntFill( vFanins, 1, iObjNew );
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins );
+ }
+ // update each PO to point to the new node
+ Wlc_NtkForEachPo( p, pObj, i )
+ {
+ iObj = Wlc_ObjId(p, pObj);
+ Vec_IntFillTwo( vFanins, 2, iObj, iObjNew );
+ iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins );
+ // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
+ // Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
+ pObj = Wlc_NtkObj( p, iObj );
+ // update PO/CO arrays
+ assert( Vec_IntEntry(&p->vPos, i) == iObj );
+ assert( Vec_IntEntry(&p->vCos, i) == iObj );
+ Vec_IntWriteEntry( &p->vPos, i, iObjNew );
+ Vec_IntWriteEntry( &p->vCos, i, iObjNew );
+ // transfer the PO attribute
+ Wlc_NtkObj(p, iObjNew)->fIsPo = 1;
+ assert( pObj->fIsPo );
+ pObj->fIsPo = 0;
+ }
+ // cleanup
+ Vec_IntFree( vUifConstrs );
+ Vec_IntFree( vCompares );
+ Vec_IntFree( vFanins );
+ if ( vPairs != vPairsInit )
+ Vec_IntFree( vPairs );
+ // reconstruct topological order
+ pNew = Wlc_NtkDupDfs( p, 0, 1 );
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c
index cf0e528f..c4dee094 100644
--- a/src/base/wlc/wlcWriteVer.c
+++ b/src/base/wlc/wlcWriteVer.c
@@ -409,7 +409,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
fprintf( pFile, " reg%d (", i );
fprintf( pFile, " .q( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
fprintf( pFile, " .qbar()," );
- fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFoToFi(p, pObj))) );
+ fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj))) );
fprintf( pFile, " .clk( %s ),", "1\'b0" );
fprintf( pFile, " .arst( %s ),", "1\'b0" );
if ( p->vInits )