summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/aig/aig/aigUtil.c2
-rw-r--r--src/aig/gia/giaCex.c2
-rw-r--r--src/aig/gia/giaDup.c14
-rw-r--r--src/aig/gia/giaMan.c2
-rw-r--r--src/aig/gia/giaPat2.c97
-rw-r--r--src/aig/ioa/ioaReadAig.c2
-rw-r--r--src/aig/miniaig/abcOper.h4
-rw-r--r--src/base/abc/abc.h5
-rw-r--r--src/base/abc/abcAig.c5
-rw-r--r--src/base/abc/abcMinBase.c21
-rw-r--r--src/base/abc/abcNtk.c46
-rw-r--r--src/base/abc/abcSop.c69
-rw-r--r--src/base/abci/abc.c59
-rw-r--r--src/base/abci/abcExact.c2
-rw-r--r--src/base/abci/abcRefactor.c34
-rw-r--r--src/base/abci/abcRestruct.c2
-rw-r--r--src/base/abci/abcResub.c2
-rw-r--r--src/base/abci/abcRewrite.c31
-rw-r--r--src/base/abci/abcRr.c5
-rw-r--r--src/base/acb/acbTest.c2
-rw-r--r--src/base/cmd/cmd.c8
-rw-r--r--src/base/cmd/cmdLoad.c3
-rw-r--r--src/base/io/io.c53
-rw-r--r--src/base/main/mainInit.c4
-rw-r--r--src/base/main/mainInt.h1
-rw-r--r--src/base/wlc/wlcBlast.c44
-rw-r--r--src/base/wlc/wlcCom.c147
-rw-r--r--src/base/wlc/wlcMem.c2
-rw-r--r--src/base/wln/module.make4
-rw-r--r--src/base/wln/wln.h4
-rw-r--r--src/base/wln/wlnBlast.c388
-rw-r--r--src/base/wln/wlnCom.c353
-rw-r--r--src/base/wln/wlnGuide.c95
-rw-r--r--src/base/wln/wlnRead.c2441
-rw-r--r--src/base/wln/wlnRtl.c95
-rw-r--r--src/bool/dec/decAbc.c7
-rw-r--r--src/map/amap/amapRead.c66
-rw-r--r--src/map/amap/amapUniq.c7
-rw-r--r--src/map/mio/mioRead.c61
-rw-r--r--src/proof/cec/cec.h1
-rw-r--r--src/proof/cec/cecCec.c15
-rw-r--r--src/proof/cec/cecSolveG.c2
-rw-r--r--src/sat/bsat2/Solver.cpp2
-rw-r--r--src/sat/glucose/AbcGlucose.cpp11
-rw-r--r--src/sat/glucose/AbcGlucose.h2
-rw-r--r--src/sat/glucose/AbcGlucoseCmd.cpp11
-rw-r--r--src/sat/glucose/Glucose.cpp2
-rw-r--r--src/sat/glucose/System.cpp2
-rw-r--r--src/sat/glucose2/Glucose2.cpp2
-rw-r--r--src/sat/glucose2/System2.cpp2
-rw-r--r--src/sat/msat/msatClause.c2
-rw-r--r--src/sat/msat/msatSolverSearch.c10
52 files changed, 3908 insertions, 345 deletions
diff --git a/src/aig/aig/aigUtil.c b/src/aig/aig/aigUtil.c
index 52f9a184..68be112f 100644
--- a/src/aig/aig/aigUtil.c
+++ b/src/aig/aig/aigUtil.c
@@ -1333,7 +1333,7 @@ void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Abc_Cex_t * pCex )
pAig->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Aig_ManObjNumMax(pAig) ) );
// the register values in the counter-example should be zero
Saig_ManForEachLo( pAig, pObj, k )
- assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 );
+ assert( Abc_InfoHasBit(pCex->pData, iBit) == 0 ), iBit++;
// iterate through the timeframes
nObjs = Aig_ManObjNumMax(pAig);
for ( i = 0; i <= pCex->iFrame; i++ )
diff --git a/src/aig/gia/giaCex.c b/src/aig/gia/giaCex.c
index b0e72284..d1241873 100644
--- a/src/aig/gia/giaCex.c
+++ b/src/aig/gia/giaCex.c
@@ -195,7 +195,7 @@ void Gia_ManCounterExampleValueStart( Gia_Man_t * pGia, Abc_Cex_t * pCex )
pGia->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Gia_ManObjNum(pGia) ) );
// the register values in the counter-example should be zero
Gia_ManForEachRo( pGia, pObj, k )
- assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 );
+ assert( Abc_InfoHasBit(pCex->pData, iBit) == 0 ), iBit++;
// iterate through the timeframes
nObjs = Gia_ManObjNum(pGia);
for ( i = 0; i <= pCex->iFrame; i++ )
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index da4881cd..55f8901f 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -1086,6 +1086,20 @@ Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo )
Gia_ManSetRegNum( pNew, Gia_ManRegNum(pOne) + Gia_ManRegNum(pTwo) );
return pNew;
}
+void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits )
+{
+ Gia_Obj_t * pObj; int i;
+ assert( Vec_IntSize(vLits) == Gia_ManCiNum(p) );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Vec_IntEntry(vLits, i);
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Vec_IntClear( vLits );
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) );
+ assert( Vec_IntSize(vLits) == Gia_ManCoNum(p) );
+}
/**Function*************************************************************
diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c
index a40673a7..ec733b85 100644
--- a/src/aig/gia/giaMan.c
+++ b/src/aig/gia/giaMan.c
@@ -539,7 +539,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars )
Abc_Print( 1, " %s =%8d", p->pMuxes? "nod" : "and", Gia_ManAndNum(p) );
SetConsoleTextAttribute( hConsole, 13 ); // magenta
Abc_Print( 1, " lev =%5d", Gia_ManLevelNum(p) );
- Abc_Print( 1, " (%.2f)", Gia_ManLevelAve(p) );
+ Abc_Print( 1, " (%7.2f)", Gia_ManLevelAve(p) );
SetConsoleTextAttribute( hConsole, 7 ); // normal
}
#else
diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c
index f14ce34a..dff2c59d 100644
--- a/src/aig/gia/giaPat2.c
+++ b/src/aig/gia/giaPat2.c
@@ -346,7 +346,7 @@ void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits )
Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
else if ( Val0 == 4 && Val1 != 4 )
Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
- else if ( Val1 == 4 && Val1 != 4 )
+ else if ( Val1 == 4 && Val0 != 4 )
Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
else if ( Abc_Random(0) & 1 )
Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
@@ -890,6 +890,8 @@ int Min_ManCountSize( Vec_Wec_t * vCexes, int iFirst, int iLimit )
}
Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTries, int nMinCexes, Vec_Int_t * vStats[3], int fUseSim, int fUseSat, int fVerbose )
{
+ int fUseSynthesis = 1;
+ abctime clkSim = Abc_Clock(), clkSat = Abc_Clock();
Vec_Int_t * vOuts = vOuts0 ? vOuts0 : Vec_IntStartNatural( Gia_ManCoNum(p) );
Min_Man_t * pNew = Min_ManFromGia( p, vOuts );
Vec_Wec_t * vCexes = Vec_WecStart( Vec_IntSize(vOuts) * nMinCexes );
@@ -945,6 +947,7 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[0]) );
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[1]) );
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[2]) );
+ clkSim = Abc_Clock() - clkSim;
if ( fUseSat )
Gia_ManForEachCoVec( vOuts, p, pObj, i )
@@ -952,11 +955,13 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) )
continue;
{
+ abctime clk = Abc_Clock();
int iObj = Min_ManCo(pNew, i);
int Index = Gia_ObjCioId(pObj);
Vec_Int_t * vMap = Vec_IntAlloc( 100 );
Gia_Man_t * pCon = Gia_ManDupCones2( p, &Index, 1, vMap );
- Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCon, 8, 0, 0, 0, 0 );
+ Gia_Man_t * pCon1= fUseSynthesis ? Gia_ManAigSyn2( pCon, 0, 1, 0, 100, 0, 0, 0 ) : NULL;
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( fUseSynthesis ? pCon1 : pCon, 8, 0, 0, 0, 0 );
sat_solver* pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
int Lit = Abc_Var2Lit( 1, 0 );
int status = sat_solver_addclause( pSat, &Lit, &Lit+1 );
@@ -972,8 +977,11 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
while ( nAllCalls++ < 100 )
{
int v, iVar = pCnf->nVars - Gia_ManPiNum(pCon), nVars = Gia_ManPiNum(pCon);
- sat_solver_randomize( pSat, iVar, nVars );
+ if ( nAllCalls > 1 )
+ sat_solver_randomize( pSat, iVar, nVars );
status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
+ if ( status != l_True )
+ break;
assert( status == l_True );
Vec_IntClear( vLits );
for ( v = 0; v < nVars; v++ )
@@ -1004,11 +1012,22 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
sat_solver_delete( pSat );
Cnf_DataFree( pCnf );
Gia_ManStop( pCon );
+ Gia_ManStopP( &pCon1 );
Vec_IntFree( vMap );
+ if ( fVerbose )
+ {
+ printf( "SAT solving for output %3d (cexes = %5d) : ", i, nCurrCexes );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ }
}
}
+ clkSat = Abc_Clock() - clkSat - clkSim;
if ( fVerbose )
printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Simulation time ", clkSim );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "SAT solving time ", clkSat );
//Vec_WecPrint( vCexes, 0 );
if ( vOuts != vOuts0 )
Vec_IntFreeP( &vOuts );
@@ -1076,7 +1095,7 @@ Vec_Ptr_t * Min_ReloadCexes( Vec_Wec_t * vCexes, int nMinCexes )
Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, int nWords0, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose )
{
abctime clk = Abc_Clock();
- int fVeryVerbose = 0;
+ //int fVeryVerbose = 0;
Vec_Wrd_t * vSimsPi = NULL;
Vec_Int_t * vLevel;
int w, nBits, nTotal = 0, fFailed = ABC_INFINITY;
@@ -1259,39 +1278,51 @@ Vec_Wrd_t * Gia_ManCollectSims( Gia_Man_t * pSwp, int nWords, Vec_Int_t * vOuts,
Vec_Int_t * vMap = Vec_IntAlloc( 100 );
Gia_Man_t * pSwp2 = Gia_ManDupCones2( pSwp, Vec_IntArray(vOuts), Vec_IntSize(vOuts), vMap );
Vec_Wec_t * vCexes = Min_ManComputeCexes( pSwp2, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose );
- Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose );
- Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 );
- Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) );
- if ( fVerbose )
- Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) );
- if ( fVeryVerbose )
+ if ( Vec_IntSum(vStats[2]) == 0 )
{
- printf( "Unsolved = %4d ", Vec_IntSize(vOuts) );
- Gia_ManPrintStats( pSwp2, NULL );
- Vec_IntForEachEntry( vOuts, iObj, i )
+ for ( i = 0; i < 3; i++ )
+ Vec_IntFree( vStats[i] );
+ Vec_IntFree( vMap );
+ Gia_ManStop( pSwp2 );
+ Vec_WecFree( vCexes );
+ return NULL;
+ }
+ else
+ {
+ Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose );
+ Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 );
+ Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) );
+ if ( fVerbose )
+ Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) );
+ if ( fVeryVerbose )
{
- printf( "%4d : ", i );
- printf( "Out = %5d ", Vec_IntEntry(vMap, i) );
- printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) );
- printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) );
- printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) );
- printf( "Count = %5d ", Vec_IntEntry(vCounts, i) );
- printf( "\n" );
- if ( i == 20 )
- break;
+ printf( "Unsolved = %4d ", Vec_IntSize(vOuts) );
+ Gia_ManPrintStats( pSwp2, NULL );
+ Vec_IntForEachEntry( vOuts, iObj, i )
+ {
+ printf( "%4d : ", i );
+ printf( "Out = %5d ", Vec_IntEntry(vMap, i) );
+ printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) );
+ printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) );
+ printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) );
+ printf( "Count = %5d ", Vec_IntEntry(vCounts, i) );
+ printf( "\n" );
+ if ( i == 20 )
+ break;
+ }
}
+ for ( i = 0; i < 3; i++ )
+ Vec_IntFree( vStats[i] );
+ Vec_IntFree( vCounts );
+ Vec_WrdFree( vSimsPo );
+ Vec_WecFree( vCexes );
+ Gia_ManStop( pSwp2 );
+ //printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) );
+ vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi );
+ Vec_WrdFree( vSimsPo );
+ Vec_IntFree( vMap );
+ return vSimsPi;
}
- for ( i = 0; i < 3; i++ )
- Vec_IntFree( vStats[i] );
- Vec_IntFree( vCounts );
- Vec_WrdFree( vSimsPo );
- Vec_WecFree( vCexes );
- Gia_ManStop( pSwp2 );
- //printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) );
- vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi );
- Vec_WrdFree( vSimsPo );
- Vec_IntFree( vMap );
- return vSimsPi;
}
Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose )
{
diff --git a/src/aig/ioa/ioaReadAig.c b/src/aig/ioa/ioaReadAig.c
index 1d1dcbe2..c1eceef0 100644
--- a/src/aig/ioa/ioaReadAig.c
+++ b/src/aig/ioa/ioaReadAig.c
@@ -438,7 +438,7 @@ Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck )
// read the file into the buffer
nFileSize = Ioa_FileSize( pFileName );
pFile = fopen( pFileName, "rb" );
- pContents = ABC_ALLOC( char, nFileSize );
+ pContents = ABC_CALLOC( char, nFileSize+1 );
RetValue = fread( pContents, nFileSize, 1, pFile );
fclose( pFile );
diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h
index c3d6e176..cbe2a0f3 100644
--- a/src/aig/miniaig/abcOper.h
+++ b/src/aig/miniaig/abcOper.h
@@ -226,6 +226,10 @@ static inline const char * Abc_OperName( int Type )
if ( Type == ABC_OPER_ZEROPAD ) return "zPad";
if ( Type == ABC_OPER_SIGNEXT ) return "sExt";
+ if ( Type == ABC_OPER_BIT_MUX ) return "mux";
+ if ( Type == ABC_OPER_SEL_NMUX ) return "nmux";
+ if ( Type == ABC_OPER_SEL_SEL ) return "pmux";
+
if ( Type == ABC_OPER_CONST ) return "const";
if ( Type == ABC_OPER_TABLE ) return "table";
if ( Type == ABC_OPER_LUT ) return "lut";
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index e7f6c0ad..b4e22a38 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -559,7 +559,7 @@ extern ABC_DLL Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, A
extern ABC_DLL Abc_Obj_t * Abc_AigXor( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
extern ABC_DLL Abc_Obj_t * Abc_AigMux( Abc_Aig_t * pMan, Abc_Obj_t * pC, Abc_Obj_t * p1, Abc_Obj_t * p0 );
extern ABC_DLL Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs, int fImplic );
-extern ABC_DLL void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel );
+extern ABC_DLL int Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel );
extern ABC_DLL void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pOld );
extern ABC_DLL void Abc_AigRehash( Abc_Aig_t * pMan );
extern ABC_DLL int Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode );
@@ -784,6 +784,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateFromNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop );
+extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSops );
extern ABC_DLL void Abc_NtkDelete( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkMakeComb( Abc_Ntk_t * pNtk, int fRemoveLatches );
@@ -920,6 +921,8 @@ extern ABC_DLL int Abc_SopIsExorType( char * pSop );
extern ABC_DLL int Abc_SopCheck( char * pSop, int nFanins );
extern ABC_DLL char * Abc_SopFromTruthBin( char * pTruth );
extern ABC_DLL char * Abc_SopFromTruthHex( char * pTruth );
+extern ABC_DLL Vec_Ptr_t * Abc_SopFromTruthsBin( char * pTruth );
+extern ABC_DLL Vec_Ptr_t * Abc_SopFromTruthsHex( char * pTruth );
extern ABC_DLL char * Abc_SopEncoderPos( Mem_Flex_t * pMan, int iValue, int nValues );
extern ABC_DLL char * Abc_SopEncoderLog( Mem_Flex_t * pMan, int iBit, int nValues );
extern ABC_DLL char * Abc_SopDecoderPos( Mem_Flex_t * pMan, int nValues );
diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c
index d3347a13..636fe30a 100644
--- a/src/base/abc/abcAig.c
+++ b/src/base/abc/abcAig.c
@@ -847,7 +847,7 @@ Abc_Obj_t * Abc_AigMiter2( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
SeeAlso []
***********************************************************************/
-void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel )
+int Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel )
{
assert( Vec_PtrSize(pMan->vStackReplaceOld) == 0 );
assert( Vec_PtrSize(pMan->vStackReplaceNew) == 0 );
@@ -859,6 +859,8 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int f
{
pOld = (Abc_Obj_t *)Vec_PtrPop( pMan->vStackReplaceOld );
pNew = (Abc_Obj_t *)Vec_PtrPop( pMan->vStackReplaceNew );
+ if ( Abc_ObjFanoutNum(pOld) == 0 )
+ return 0;
Abc_AigReplace_int( pMan, pOld, pNew, fUpdateLevel );
}
if ( fUpdateLevel )
@@ -867,6 +869,7 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int f
if ( pMan->pNtkAig->vLevelsR )
Abc_AigUpdateLevelR_int( pMan );
}
+ return 1;
}
/**Function*************************************************************
diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c
index 991f65a4..92dbd0c9 100644
--- a/src/base/abc/abcMinBase.c
+++ b/src/base/abc/abcMinBase.c
@@ -113,7 +113,7 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
DdNode * bTemp, ** pbVars;
Vec_Str_t * vSupport;
int i, nVars, j, iFanin, iFanin2, k = 0;
- int fDupFanins = 0;
+ int ddSize, fDupFanins = 0;
assert( Abc_NtkIsBddLogic(pNode->pNtk) );
assert( Abc_ObjIsNode(pNode) );
@@ -127,8 +127,14 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
return 0;
}
- // remove unused fanins
- pbVars = ABC_CALLOC( DdNode *, Abc_ObjFaninNum(pNode) );
+ // remove unused fanins.
+
+ // By default, every BDD variable stays equivalent to itself.
+ ddSize = Cudd_ReadSize( dd );
+ pbVars = ABC_CALLOC( DdNode *, ddSize );
+ for (i = 0; i < ddSize; i += 1 ) {
+ pbVars[i] = Cudd_bddIthVar( dd, i );
+ }
Vec_IntForEachEntry( &pNode->vFanins, iFanin, i )
{
Abc_Obj_t * pFanin = Abc_NtkObj( pNode->pNtk, iFanin );
@@ -146,13 +152,18 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
Vec_IntWriteEntry( &pNode->vFanins, k++, iFanin );
else if ( !Vec_IntRemove( &pFanin->vFanouts, pNode->Id ) )
printf( "The obj %d is not found among the fanouts of obj %d ...\n", pNode->Id, iFanin );
+
+ // i-th variable becomes equivalent to j-th variable (can be itself)
pbVars[i] = Cudd_bddIthVar( dd, j );
}
Vec_IntShrink( &pNode->vFanins, k );
// update the function of the node
- pNode->pData = Cudd_bddVectorCompose( dd, bTemp = (DdNode *)pNode->pData, pbVars ); Cudd_Ref( (DdNode *)pNode->pData );
- Cudd_RecursiveDeref( dd, bTemp );
+ if ( ! Cudd_IsConstant((DdNode *) pNode->pData ) ) {
+ pNode->pData = Cudd_bddVectorCompose( dd, bTemp = (DdNode *)pNode->pData, pbVars );
+ Cudd_Ref( (DdNode *)pNode->pData );
+ Cudd_RecursiveDeref( dd, bTemp );
+ }
Vec_StrFree( vSupport );
ABC_FREE( pbVars );
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index f8e40b41..63353344 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -1272,6 +1272,52 @@ Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop )
/**Function*************************************************************
+ Synopsis [Creates the network composed of one node with the given SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSop )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pFanin, * pNode, * pNodePo;
+ Vec_Ptr_t * vNames;
+ int i, k, nVars; char Buffer[10];
+ char * pSop = (char *)Vec_PtrEntry(vSop, 0);
+ // start the network
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
+ pNtkNew->pName = Extra_UtilStrsav("ex");
+ // create PIs
+ Vec_PtrPush( pNtkNew->vObjs, NULL );
+ nVars = Abc_SopGetVarNum( pSop );
+ vNames = Abc_NodeGetFakeNames( nVars );
+ for ( i = 0; i < nVars; i++ )
+ Abc_ObjAssignName( Abc_NtkCreatePi(pNtkNew), (char *)Vec_PtrEntry(vNames, i), NULL );
+ Abc_NodeFreeNames( vNames );
+ // create the node, add PIs as fanins, set the function
+ Vec_PtrForEachEntry( char *, vSop, pSop, i )
+ {
+ pNode = Abc_NtkCreateNode( pNtkNew );
+ Abc_NtkForEachPi( pNtkNew, pFanin, k )
+ Abc_ObjAddFanin( pNode, pFanin );
+ pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, pSop );
+ // create the only PO
+ pNodePo = Abc_NtkCreatePo(pNtkNew);
+ Abc_ObjAddFanin( pNodePo, pNode );
+ sprintf( Buffer, "F%d", i );
+ Abc_ObjAssignName( pNodePo, Buffer, NULL );
+ }
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ fprintf( stdout, "Abc_NtkCreateWithNode(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Deletes the Ntk.]
Description []
diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c
index b91214af..8250102a 100644
--- a/src/base/abc/abcSop.c
+++ b/src/base/abc/abcSop.c
@@ -907,6 +907,41 @@ int Abc_SopCheck( char * pSop, int nFanins )
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_SopCheckReadTruth( Vec_Ptr_t * vRes, char * pToken, int fHex )
+{
+ char * pBase; int nVars;
+ int Log2 = Abc_Base2Log( strlen(pToken) );
+ if ( (1 << Log2) != (int)strlen(pToken) )
+ {
+ printf( "The truth table length (%d) is not power-of-2.\n", (int)strlen(pToken) );
+ Vec_PtrFreeData( vRes );
+ Vec_PtrShrink( vRes, 0 );
+ return 0;
+ }
+ if ( Vec_PtrSize(vRes) == 0 )
+ return 1;
+ pBase = (char *)Vec_PtrEntry( vRes, 0 );
+ nVars = Abc_SopGetVarNum( pBase );
+ if ( nVars != Log2+2*fHex )
+ {
+ printf( "Truth table #1 has %d vars while truth table #%d has %d vars.\n", nVars, Vec_PtrSize(vRes)+1, Log2+2*fHex );
+ Vec_PtrFreeData( vRes );
+ Vec_PtrShrink( vRes, 0 );
+ return 0;
+ }
+ return 1;
+}
/**Function*************************************************************
@@ -964,8 +999,8 @@ char * Abc_SopFromTruthBin( char * pTruth )
{
pCube = pSopCover + i * (nVars + 3);
for ( b = 0; b < nVars; b++ )
- if ( Mint & (1 << (nVars-1-b)) )
-// if ( Mint & (1 << b) )
+// if ( Mint & (1 << (nVars-1-b)) )
+ if ( Mint & (1 << b) )
pCube[b] = '1';
else
pCube[b] = '0';
@@ -976,6 +1011,21 @@ char * Abc_SopFromTruthBin( char * pTruth )
Vec_IntFree( vMints );
return pSopCover;
}
+Vec_Ptr_t * Abc_SopFromTruthsBin( char * pTruth )
+{
+ Vec_Ptr_t * vRes = Vec_PtrAlloc( 10 );
+ char * pCopy = Abc_UtilStrsav(pTruth);
+ char * pToken = strtok( pCopy, " \r\n\t|" );
+ while ( pToken )
+ {
+ if ( !Abc_SopCheckReadTruth( vRes, pToken, 0 ) )
+ break;
+ Vec_PtrPush( vRes, Abc_SopFromTruthBin(pToken) );
+ pToken = strtok( NULL, " \r\n\t|" );
+ }
+ ABC_FREE( pCopy );
+ return vRes;
+}
/**Function*************************************************************
@@ -1058,6 +1108,21 @@ char * Abc_SopFromTruthHex( char * pTruth )
Vec_IntFree( vMints );
return pSopCover;
}
+Vec_Ptr_t * Abc_SopFromTruthsHex( char * pTruth )
+{
+ Vec_Ptr_t * vRes = Vec_PtrAlloc( 10 );
+ char * pCopy = Abc_UtilStrsav(pTruth);
+ char * pToken = strtok( pCopy, " \r\n\t|" );
+ while ( pToken )
+ {
+ if ( !Abc_SopCheckReadTruth( vRes, pToken, 1 ) )
+ break;
+ Vec_PtrPush( vRes, Abc_SopFromTruthHex(pToken) );
+ pToken = strtok( NULL, " \r\n\t|" );
+ }
+ ABC_FREE( pCopy );
+ return vRes;
+}
/**Function*************************************************************
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 1d97f5e4..06d7cb08 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -7312,8 +7312,8 @@ usage:
***********************************************************************/
int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c;
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup;
+ int c, RetValue;
int fUpdateLevel;
int fPrecompute;
int fUseZeros;
@@ -7383,10 +7383,21 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// modify the current network
- if ( !Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose, fPlaceEnable ) )
+ pDup = Abc_NtkDup( pNtk );
+ RetValue = Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose, fPlaceEnable );
+ if ( RetValue == -1 )
{
- Abc_Print( -1, "Rewriting has failed.\n" );
- return 1;
+ Abc_FrameReplaceCurrentNetwork( pAbc, pDup );
+ printf( "An error occurred during computation. The original network is restored.\n" );
+ }
+ else
+ {
+ Abc_NtkDelete( pDup );
+ if ( RetValue == 0 )
+ {
+ Abc_Print( 0, "Rewriting has failed.\n" );
+ return 1;
+ }
}
return 0;
@@ -7415,8 +7426,8 @@ usage:
***********************************************************************/
int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c;
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup;
+ int c, RetValue;
int nNodeSizeMax;
int nConeSizeMax;
int fUpdateLevel;
@@ -7506,10 +7517,21 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// modify the current network
- if ( !Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ) )
+ pDup = Abc_NtkDup( pNtk );
+ RetValue = Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUpdateLevel, fUseZeros, fUseDcs, fVerbose );
+ if ( RetValue == -1 )
{
- Abc_Print( -1, "Refactoring has failed.\n" );
- return 1;
+ Abc_FrameReplaceCurrentNetwork( pAbc, pDup );
+ printf( "An error occurred during computation. The original network is restored.\n" );
+ }
+ else
+ {
+ Abc_NtkDelete( pDup );
+ if ( RetValue == 0 )
+ {
+ Abc_Print( 0, "Refactoring has failed.\n" );
+ return 1;
+ }
}
return 0;
@@ -37868,7 +37890,22 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
// compute the miter
- pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNew, 0, 0, pPars->fVerbose );
+ if ( Gia_ManCiNum(pGias[0]) < 6 )
+ {
+ Gia_Man_t * pGias0 = Gia_ManDup( pGias[0] );
+ Gia_Man_t * pGias1 = Gia_ManDup( pGias[1] );
+ for ( c = Gia_ManCiNum(pGias[0]); c < 6; c++ )
+ {
+ Gia_ManAppendCi(pGias0);
+ Gia_ManAppendCi(pGias1);
+ }
+ pMiter = Gia_ManMiter( pGias0, pGias1, 0, !fUseNew, 0, 0, pPars->fVerbose );
+ Gia_ManStop( pGias0 );
+ Gia_ManStop( pGias1 );
+ }
+ else
+ pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNew, 0, 0, pPars->fVerbose );
+
if ( pMiter )
{
if ( fDumpMiter )
diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c
index 42cf11c5..64225c61 100644
--- a/src/base/abci/abcExact.c
+++ b/src/base/abci/abcExact.c
@@ -1034,7 +1034,7 @@ static word * Ses_ManDeriveTruth( Ses_Man_t * pSes, char * pSol, int fInvert )
for ( i = 0; i < nGates; ++i )
{
f = *p++;
- assert( *p++ == 2 );
+ assert( *p == 2 ), p++;
j = *p++;
k = *p++;
diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c
index 3cc6d793..8ec5944f 100644
--- a/src/base/abci/abcRefactor.c
+++ b/src/base/abci/abcRefactor.c
@@ -325,7 +325,7 @@ void Abc_NtkManRefPrintStats( Abc_ManRef_t * p )
***********************************************************************/
int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose )
{
- extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
+ extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
Abc_ManRef_t * pManRef;
Abc_ManCut_t * pManCut;
@@ -333,7 +333,7 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, int f
Vec_Ptr_t * vFanins;
Abc_Obj_t * pNode;
abctime clk, clkStart = Abc_Clock();
- int i, nNodes;
+ int i, nNodes, RetValue = 1;
assert( Abc_NtkIsStrash(pNtk) );
// cleanup the AIG
@@ -377,7 +377,12 @@ pManRef->timeRes += Abc_Clock() - clk;
continue;
// acceptable replacement found, update the graph
clk = Abc_Clock();
- Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain );
+ if ( !Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain ) )
+ {
+ Dec_GraphFree( pFForm );
+ RetValue = -1;
+ break;
+ }
pManRef->timeNtk += Abc_Clock() - clk;
Dec_GraphFree( pFForm );
}
@@ -394,18 +399,21 @@ pManRef->timeTotal = Abc_Clock() - clkStart;
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
- // fix the levels
- if ( fUpdateLevel )
- Abc_NtkStopReverseLevels( pNtk );
- else
- Abc_NtkLevel( pNtk );
- // check
- if ( !Abc_NtkCheck( pNtk ) )
+ if ( RetValue != -1 )
{
- printf( "Abc_NtkRefactor: The network check has failed.\n" );
- return 0;
+ // fix the levels
+ if ( fUpdateLevel )
+ Abc_NtkStopReverseLevels( pNtk );
+ else
+ Abc_NtkLevel( pNtk );
+ // check
+ if ( !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkRefactor: The network check has failed.\n" );
+ return 0;
+ }
}
- return 1;
+ return RetValue;
}
diff --git a/src/base/abci/abcRestruct.c b/src/base/abci/abcRestruct.c
index ef5dd451..87f15238 100644
--- a/src/base/abci/abcRestruct.c
+++ b/src/base/abci/abcRestruct.c
@@ -105,7 +105,7 @@ static void Abc_NtkManRstPrintStats( Abc_ManRst_t * p );
***********************************************************************/
int Abc_NtkRestructure( Abc_Ntk_t * pNtk, int nCutMax, int fUpdateLevel, int fUseZeros, int fVerbose )
{
- extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
+ extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
Abc_ManRst_t * pManRst;
Cut_Man_t * pManCut;
diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c
index b8934e23..dc1b6036 100644
--- a/src/base/abci/abcResub.c
+++ b/src/base/abci/abcResub.c
@@ -136,7 +136,7 @@ extern abctime s_ResubTime;
***********************************************************************/
int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose )
{
- extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
+ extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
Abc_ManRes_t * pManRes;
Abc_ManCut_t * pManCut;
diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c
index 0b0881a6..1da7e4e8 100644
--- a/src/base/abci/abcRewrite.c
+++ b/src/base/abci/abcRewrite.c
@@ -60,14 +60,14 @@ extern void Abc_PlaceUpdate( Vec_Ptr_t * vAddedCells, Vec_Ptr_t * vUpdatedNets
***********************************************************************/
int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable )
{
- extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
+ extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
Cut_Man_t * pManCut;
Rwr_Man_t * pManRwr;
Abc_Obj_t * pNode;
// Vec_Ptr_t * vAddedCells = NULL, * vUpdatedNets = NULL;
Dec_Graph_t * pGraph;
- int i, nNodes, nGain, fCompl;
+ int i, nNodes, nGain, fCompl, RetValue = 1;
abctime clk, clkStart = Abc_Clock();
assert( Abc_NtkIsStrash(pNtk) );
@@ -138,7 +138,11 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk );
// complement the FF if needed
if ( fCompl ) Dec_GraphComplement( pGraph );
clk = Abc_Clock();
- Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
+ if ( !Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ) )
+ {
+ RetValue = -1;
+ break;
+ }
Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk );
if ( fCompl ) Dec_GraphComplement( pGraph );
@@ -175,17 +179,20 @@ Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart );
}
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
// fix the levels
- if ( fUpdateLevel )
- Abc_NtkStopReverseLevels( pNtk );
- else
- Abc_NtkLevel( pNtk );
- // check
- if ( !Abc_NtkCheck( pNtk ) )
+ if ( RetValue >= 0 )
{
- printf( "Abc_NtkRewrite: The network check has failed.\n" );
- return 0;
+ if ( fUpdateLevel )
+ Abc_NtkStopReverseLevels( pNtk );
+ else
+ Abc_NtkLevel( pNtk );
+ // check
+ if ( !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkRewrite: The network check has failed.\n" );
+ return 0;
+ }
}
- return 1;
+ return RetValue;
}
diff --git a/src/base/abci/abcRr.c b/src/base/abci/abcRr.c
index 52d1fd32..86c5f13e 100644
--- a/src/base/abci/abcRr.c
+++ b/src/base/abci/abcRr.c
@@ -397,10 +397,7 @@ int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Ab
else assert( 0 );
// replace
if ( pFanout == NULL )
- {
- Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pNode, pNodeNew, 1 );
- return 1;
- }
+ return Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pNode, pNodeNew, 1 );
// find the fanout after redundancy removal
if ( pNode == Abc_ObjFanin0(pFanout) )
pFanoutNew = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, Abc_ObjNotCond(pNodeNew,Abc_ObjFaninC0(pFanout)), Abc_ObjChild1(pFanout) );
diff --git a/src/base/acb/acbTest.c b/src/base/acb/acbTest.c
index 1faea72a..6290b88e 100644
--- a/src/base/acb/acbTest.c
+++ b/src/base/acb/acbTest.c
@@ -466,7 +466,7 @@ Gia_Man_t * Acb_NtkGiaDeriveMiter( Gia_Man_t * pOne, Gia_Man_t * pTwo, int Type
***********************************************************************/
void Acb_OutputFile( char * pFileName, Acb_Ntk_t * pNtkF, int * pModel )
{
- char * pFileName0 = pFileName? pFileName : "output";
+ const char * pFileName0 = pFileName? pFileName : "output";
FILE * pFile = fopen( pFileName0, "wb" );
if ( pFile == NULL )
{
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
index a0042443..fe7286b7 100644
--- a/src/base/cmd/cmd.c
+++ b/src/base/cmd/cmd.c
@@ -1161,7 +1161,7 @@ int CmdCommandScanDir( Abc_Frame_t * pAbc, int argc, char **argv )
struct _finddata_t c_file;
char * pDirStr = NULL;
char* pDirCur = NULL;
- long hFile;
+ ABC_PTRINT_T hFile;
char c;
Extra_UtilGetoptReset();
@@ -1354,7 +1354,7 @@ void CnfDupFileUnzip( char * pOldName )
int CmdCommandRenameFiles( Abc_Frame_t * pAbc, int argc, char **argv )
{
struct _finddata_t c_file;
- long hFile;
+ ABC_PTRINT_T hFile;
char pNewName[1000];
char * pDirStr = NULL;
char * pDirCur = NULL;
@@ -1515,7 +1515,7 @@ usage:
int CmdCommandLs( Abc_Frame_t * pAbc, int argc, char **argv )
{
struct _finddata_t c_file;
- long hFile;
+ ABC_PTRINT_T hFile;
int fLong = 0;
int fOnlyBLIF = 0;
char Buffer[25];
@@ -1618,7 +1618,7 @@ usage:
int CmdCommandScrGen( Abc_Frame_t * pAbc, int argc, char **argv )
{
struct _finddata_t c_file;
- long hFile;
+ ABC_PTRINT_T hFile;
FILE * pFile = NULL;
char * pFileStr = "test.s";
char * pDirStr = NULL;
diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c
index accd9440..bd511fec 100644
--- a/src/base/cmd/cmdLoad.c
+++ b/src/base/cmd/cmdLoad.c
@@ -114,7 +114,8 @@ Vec_Ptr_t * CmdCollectFileNames()
{
Vec_Ptr_t * vFileNames;
struct _finddata_t c_file;
- long hFile;
+ //long hFile;
+ ABC_PTRINT_T hFile;
if( (hFile = _findfirst( "*.exe", &c_file )) == -1L )
{
// Abc_Print( 0, "No files with extention \"%s\" in the current directory.\n", "exe" );
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 5cf74ef9..26bfb1f4 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -1115,7 +1115,7 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk;
char * pStr = NULL;
- char * pSopCover;
+ Vec_Ptr_t * vSops;
int fHex = 1;
int fFile = 0;
int c;
@@ -1142,28 +1142,36 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
if ( fFile )
+ {
+ FILE * pFile = fopen( argv[globalUtilOptind], "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "The file \"%s\" cannot be found.\n", argv[globalUtilOptind] );
+ return 1;
+ }
+ else
+ fclose( pFile );
pStr = Extra_FileReadContents( argv[globalUtilOptind] );
+ }
else
pStr = argv[globalUtilOptind];
- while ( pStr[ strlen(pStr) - 1 ] == '\n' || pStr[ strlen(pStr) - 1 ] == '\r' )
- pStr[ strlen(pStr) - 1 ] = '\0';
// convert truth table to SOP
if ( fHex )
- pSopCover = Abc_SopFromTruthHex(pStr);
+ vSops = Abc_SopFromTruthsHex(pStr);
else
- pSopCover = Abc_SopFromTruthBin(pStr);
+ vSops = Abc_SopFromTruthsBin(pStr);
if ( fFile )
ABC_FREE( pStr );
- if ( pSopCover == NULL || pSopCover[0] == 0 )
+ if ( Vec_PtrSize(vSops) == 0 )
{
- ABC_FREE( pSopCover );
+ Vec_PtrFreeFree( vSops );
fprintf( pAbc->Err, "Reading truth table has failed.\n" );
return 1;
}
- pNtk = Abc_NtkCreateWithNode( pSopCover );
- ABC_FREE( pSopCover );
+ pNtk = Abc_NtkCreateWithNodes( vSops );
+ Vec_PtrFreeFree( vSops );
if ( pNtk == NULL )
{
fprintf( pAbc->Err, "Deriving the network has failed.\n" );
@@ -1176,9 +1184,9 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
fprintf( pAbc->Err, "usage: read_truth [-xfh] <truth> <file>\n" );
- fprintf( pAbc->Err, "\t creates network with node having given truth table\n" );
- fprintf( pAbc->Err, "\t-x : toggles between bin and hex representation [default = %s]\n", fHex? "hex":"bin" );
- fprintf( pAbc->Err, "\t-f : toggles reading truth table from file [default = %s]\n", fFile? "yes": "no" );
+ fprintf( pAbc->Err, "\t creates network with node(s) having given truth table(s)\n" );
+ fprintf( pAbc->Err, "\t-x : toggles between bin and hex notation [default = %s]\n", fHex? "hex":"bin" );
+ fprintf( pAbc->Err, "\t-f : toggles reading truth table(s) from file [default = %s]\n", fFile? "yes": "no" );
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
fprintf( pAbc->Err, "\ttruth : truth table with most signficant bit first (e.g. 1000 for AND(a,b))\n" );
fprintf( pAbc->Err, "\tfile : file name with the truth table\n" );
@@ -3250,19 +3258,23 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv )
word * pTruth;
int nBytes;
int fReverse = 0;
- int fBinary = 0;
+ int fHex = 1;
+ int fBinaryFile = 0;
int c, i;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "rbh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "rxbh" ) ) != EOF )
{
switch ( c )
{
case 'r':
fReverse ^= 1;
break;
+ case 'x':
+ fHex ^= 1;
+ break;
case 'b':
- fBinary ^= 1;
+ fBinaryFile ^= 1;
break;
case 'h':
goto usage;
@@ -3300,19 +3312,22 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv )
Gia_ManForEachCo( pAbc->pGia, pObj, i )
{
pTruth = Gia_ObjComputeTruthTable( pAbc->pGia, pObj );
- if ( fBinary )
+ if ( fBinaryFile )
fwrite( pTruth, nBytes, 1, pFile );
- else
+ else if ( fHex )
Extra_PrintHex( pFile, (unsigned *)pTruth, Gia_ManPiNum(pAbc->pGia) ), fprintf( pFile, "\n" );
+ else
+ Extra_PrintBinary( pFile, (unsigned *)pTruth, 1 << Gia_ManPiNum(pAbc->pGia) ), fprintf( pFile, "\n" );
}
fclose( pFile );
return 0;
usage:
- fprintf( pAbc->Err, "usage: &write_truths [-rbh] <file>\n" );
+ fprintf( pAbc->Err, "usage: &write_truths [-rxbh] <file>\n" );
fprintf( pAbc->Err, "\t writes truth tables of each PO of GIA manager into a file\n" );
fprintf( pAbc->Err, "\t-r : toggle reversing bits in the truth table [default = %s]\n", fReverse? "yes":"no" );
- fprintf( pAbc->Err, "\t-b : toggle using binary format [default = %s]\n", fBinary? "yes":"no" );
+ fprintf( pAbc->Err, "\t-x : toggle writing in the hex notation [default = %s]\n", fHex? "yes":"no" );
+ fprintf( pAbc->Err, "\t-b : toggle using binary file format [default = %s]\n", fBinaryFile? "yes":"no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
return 1;
diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c
index 693cea90..d3ce672f 100644
--- a/src/base/main/mainInit.c
+++ b/src/base/main/mainInit.c
@@ -49,6 +49,8 @@ extern void Scl_Init( Abc_Frame_t * pAbc );
extern void Scl_End( Abc_Frame_t * pAbc );
extern void Wlc_Init( Abc_Frame_t * pAbc );
extern void Wlc_End( Abc_Frame_t * pAbc );
+extern void Wln_Init( Abc_Frame_t * pAbc );
+extern void Wln_End( Abc_Frame_t * pAbc );
extern void Bac_Init( Abc_Frame_t * pAbc );
extern void Bac_End( Abc_Frame_t * pAbc );
extern void Cba_Init( Abc_Frame_t * pAbc );
@@ -116,6 +118,7 @@ void Abc_FrameInit( Abc_Frame_t * pAbc )
Load_Init( pAbc );
Scl_Init( pAbc );
Wlc_Init( pAbc );
+ Wln_Init( pAbc );
Bac_Init( pAbc );
Cba_Init( pAbc );
Pla_Init( pAbc );
@@ -156,6 +159,7 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc )
Load_End( pAbc );
Scl_End( pAbc );
Wlc_End( pAbc );
+ Wln_End( pAbc );
Bac_End( pAbc );
Cba_End( pAbc );
Pla_End( pAbc );
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
index e860878e..5325adfe 100644
--- a/src/base/main/mainInt.h
+++ b/src/base/main/mainInt.h
@@ -145,6 +145,7 @@ struct Abc_Frame_t_
void * pAbc85Delay;
void * pAbcWlc;
Vec_Int_t * pAbcWlcInv;
+ void * pAbcRtl;
void * pAbcBac;
void * pAbcCba;
void * pAbcPla;
diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c
index c6edb3ab..cf7ae5df 100644
--- a/src/base/wlc/wlcBlast.c
+++ b/src/base/wlc/wlcBlast.c
@@ -2588,6 +2588,50 @@ Gia_Man_t * Wlc_BlastArray( char * pFileName )
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wlc_ComputePerm( Wlc_Ntk_t * pNtk, int nPis )
+{
+ Vec_Int_t * vPerm = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSizes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vOffs = Vec_IntAlloc( 100 );
+ Wlc_Obj_t * pObj;
+ int i, k, First, Size, nBitCis = 0, fChange = 1;
+ Wlc_NtkForEachPi( pNtk, pObj, i )
+ {
+ Vec_IntPush( vOffs, nBitCis );
+ Vec_IntPush( vSizes, Wlc_ObjRange(pObj) );
+ nBitCis += Wlc_ObjRange(pObj);
+ }
+ for ( k = 0; fChange; k++ )
+ {
+ fChange = 0;
+ Vec_IntForEachEntryTwo( vOffs, vSizes, First, Size, i )
+ if ( k < Size )
+ {
+ Vec_IntPush( vPerm, First+k );
+ fChange = 1;
+ }
+ }
+ assert( Vec_IntSize(vPerm) == nBitCis );
+ Vec_IntFree( vOffs );
+ Vec_IntFree( vSizes );
+ Vec_IntReverseOrder( vPerm );
+ for ( i = Vec_IntSize(vPerm); i < nPis; i++ )
+ Vec_IntPush( vPerm, i );
+ //Vec_IntPrint( vPerm );
+ return vPerm;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c
index b1573e73..dcddd042 100644
--- a/src/base/wlc/wlcCom.c
+++ b/src/base/wlc/wlcCom.c
@@ -21,7 +21,7 @@
#include "wlc.h"
#include "base/wln/wln.h"
#include "base/main/mainInt.h"
-#include "aig/miniaig/ndr.h"
+//#include "aig/miniaig/ndr.h"
ABC_NAMESPACE_IMPL_START
@@ -32,7 +32,6 @@ ABC_NAMESPACE_IMPL_START
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_CommandYosys ( 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 );
@@ -80,7 +79,6 @@ 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", "%yosys", Abc_CommandYosys, 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 );
@@ -308,130 +306,6 @@ usage:
SeeAlso []
******************************************************************************/
-int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
- extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose );
- extern Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose );
-
- FILE * pFile;
- char * pFileName = NULL;
- char * pTopModule= NULL;
- int fCollapse = 0;
- int fBlast = 0;
- int fInvert = 0;
- int fTechMap = 0;
- int fSkipStrash = 0;
- int c, fVerbose = 0;
- Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Tcaismvh" ) ) != EOF )
- {
- switch ( c )
- {
- case 'T':
- if ( globalUtilOptind >= argc )
- {
- Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" );
- goto usage;
- }
- pTopModule = argv[globalUtilOptind];
- globalUtilOptind++;
- break;
- case 'c':
- fCollapse ^= 1;
- break;
- case 'a':
- fBlast ^= 1;
- break;
- case 'i':
- fInvert ^= 1;
- break;
- case 's':
- fSkipStrash ^= 1;
- break;
- case 'm':
- fTechMap ^= 1;
- break;
- case 'v':
- fVerbose ^= 1;
- break;
- case 'h':
- goto usage;
- default:
- goto usage;
- }
- }
- if ( argc != globalUtilOptind + 1 )
- {
- printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" );
- return 0;
- }
- // get the file name
- pFileName = argv[globalUtilOptind];
- if ( (pFile = fopen( pFileName, "r" )) == NULL )
- {
- Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName );
- if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) )
- Abc_Print( 1, "Did you mean \"%s\"?", pFileName );
- Abc_Print( 1, "\n" );
- return 0;
- }
- fclose( pFile );
-
- // perform reading
- if ( fBlast )
- {
- Gia_Man_t * pNew = NULL;
- if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
- pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose );
- else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) )
- pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose );
- else
- {
- printf( "Abc_CommandYosys(): Unknown file extension.\n" );
- return 0;
- }
- Abc_FrameUpdateGia( pAbc, pNew );
- }
- else
- {
- Wln_Ntk_t * pNtk = NULL;
- if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
- pNtk = Wln_ReadSystemVerilog( pFileName, pTopModule, fVerbose );
- else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) )
- pNtk = Wln_ReadSystemVerilog( pFileName, pTopModule, fVerbose );
- else
- {
- printf( "Abc_CommandYosys(): Unknown file extension.\n" );
- return 0;
- }
- //Wlc_AbcUpdateNtk( pAbc, pNtk );
- }
- return 0;
-usage:
- Abc_Print( -2, "usage: %%yosys [-T <module>] [-caismvh] <file_name>\n" );
- Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" );
- Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" );
- Abc_Print( -2, "\t-c : toggle collapsing the design using Yosys [default = %s]\n", fCollapse? "yes": "no" );
- Abc_Print( -2, "\t-a : toggle bit-blasting the design using Yosys [default = %s]\n", fBlast? "yes": "no" );
- Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" );
- Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" );
- Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "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_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
@@ -1157,12 +1031,12 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Wlc_NtkPrintInputInfo( Wlc_Ntk_t * pNtk );
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
- Gia_Man_t * pNew = NULL; int c, fMiter = 0, fDumpNames = 0, fPrintInputInfo = 0;
+ Gia_Man_t * pNew = NULL; int c, fMiter = 0, fDumpNames = 0, fPrintInputInfo = 0, fReorder = 0;
Wlc_BstPar_t Par, * pPar = &Par;
Wlc_BstParDefault( pPar );
pPar->nOutputRange = 2;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqaydestnizvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqaydestrnizvh" ) ) != EOF )
{
switch ( c )
{
@@ -1244,6 +1118,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
pPar->fCreateMiter ^= 1;
fMiter ^= 1;
break;
+ case 'r':
+ fReorder ^= 1;
+ break;
case 'n':
fDumpNames ^= 1;
break;
@@ -1323,10 +1200,19 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 1, "Finished dumping file \"pio_name_map.txt\" containing PI/PO name mapping.\n" );
}
}
+ if ( fReorder )
+ {
+ extern Vec_Int_t * Wlc_ComputePerm( Wlc_Ntk_t * pNtk, int nPis );
+ Vec_Int_t * vPiPerm = Wlc_ComputePerm( pNtk, Gia_ManPiNum(pNew) );
+ Gia_Man_t * pTemp = Gia_ManDupPerm( pNew, vPiPerm );
+ Vec_IntFree( vPiPerm );
+ Gia_ManStop( pNew );
+ pNew = pTemp;
+ }
Abc_FrameUpdateGia( pAbc, pNew );
return 0;
usage:
- Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqaydestnizvh]\n" );
+ Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqaydestrnizvh]\n" );
Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" );
Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput );
Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange );
@@ -1343,6 +1229,7 @@ usage:
Abc_Print( -2, "\t-e : toggle creating miter with output word bits combined [default = %s]\n", pPar->fCreateWordMiter? "yes": "no" );
Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" );
Abc_Print( -2, "\t-t : toggle creating regular multi-output miter [default = %s]\n", fMiter? "yes": "no" );
+ Abc_Print( -2, "\t-r : toggle using interleaved variable ordering [default = %s]\n", fReorder? "yes": "no" );
Abc_Print( -2, "\t-n : toggle dumping signal names into a text file [default = %s]\n", fDumpNames? "yes": "no" );
Abc_Print( -2, "\t-i : toggle to print input names after blasting [default = %s]\n", fPrintInputInfo ? "yes": "no" );
Abc_Print( -2, "\t-z : toggle saving flop names after blasting [default = %s]\n", pPar->fSaveFfNames ? "yes": "no" );
diff --git a/src/base/wlc/wlcMem.c b/src/base/wlc/wlcMem.c
index da0fc846..b2d5c5ee 100644
--- a/src/base/wlc/wlcMem.c
+++ b/src/base/wlc/wlcMem.c
@@ -800,7 +800,7 @@ void Wlc_NtkTrace_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int iFrame, Vec_Int_t *
{
int Index = 3*(iFrame*Vec_IntSize(vMemObjs) + iNum);
int Value = (int)Vec_WrdEntry( vValues, Index );
- assert( Value == 0 && Value == 1 );
+ assert( Value == 0 || Value == 1 );
Wlc_NtkTrace_rec( p, Value ? Wlc_ObjFanin2(p, pObj) : Wlc_ObjFanin1(p, pObj), iFrame, vMemObjs, vValues, ValueA, vRes );
Vec_IntPush( vRes, (iObj << 11) | (iFrame << 1) | Value );
}
diff --git a/src/base/wln/module.make b/src/base/wln/module.make
index 308f7689..c1939126 100644
--- a/src/base/wln/module.make
+++ b/src/base/wln/module.make
@@ -1,8 +1,12 @@
SRC += src/base/wln/wln.c \
+ src/base/wln/wlnBlast.c \
+ src/base/wln/wlnCom.c \
+ src/base/wln/wlnGuide.c \
src/base/wln/wlnMem.c \
src/base/wln/wlnNdr.c \
src/base/wln/wlnNtk.c \
src/base/wln/wlnObj.c \
+ src/base/wln/wlnRead.c \
src/base/wln/wlnRetime.c \
src/base/wln/wlnRtl.c \
src/base/wln/wlnWlc.c \
diff --git a/src/base/wln/wln.h b/src/base/wln/wln.h
index 93a1a92a..c658a2fe 100644
--- a/src/base/wln/wln.h
+++ b/src/base/wln/wln.h
@@ -251,6 +251,10 @@ extern void Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk );
/*=== wlcWriteVer.c ========================================================*/
extern void Wln_WriteVer( Wln_Ntk_t * p, char * pFileName );
+/*=== wlcRead.c ========================================================*/
+typedef struct Rtl_Lib_t_ Rtl_Lib_t;
+extern Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec );
+extern void Rtl_LibFree( Rtl_Lib_t * p );
ABC_NAMESPACE_HEADER_END
diff --git a/src/base/wln/wlnBlast.c b/src/base/wln/wlnBlast.c
new file mode 100644
index 00000000..a3ac73c0
--- /dev/null
+++ b/src/base/wln/wlnBlast.c
@@ -0,0 +1,388 @@
+/**CFile****************************************************************
+
+ FileName [wlnBlast.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnBlast.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "base/wlc/wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_VecExtend( Vec_Int_t * p, int nRange, int fSigned )
+{
+ Vec_IntFillExtra( p, nRange, fSigned ? Vec_IntEntryLast(p) : 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 )
+{
+ extern void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes );
+ extern int Wlc_BlastReduction( Gia_Man_t * pNew, int * pFans, int nFans, int Type );
+ extern int Wlc_BlastLess( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits );
+ extern int Wlc_BlastLessSigned( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits );
+ extern void Wlc_BlastShiftRight( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes );
+ extern void Wlc_BlastShiftLeft( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes );
+ extern int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
+ extern void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
+ extern int Wlc_NtkCountConstBits( int * pArray, int nSize );
+ extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
+ extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
+ extern void Wlc_BlastZeroCondition( Gia_Man_t * pNew, int * pDiv, int nDiv, Vec_Int_t * vRes );
+ extern void Wlc_BlastDivider( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes );
+ extern void Wlc_BlastDividerSigned( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes );
+ extern void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes );
+
+ int k, iLit, iLit0, iLit1;
+ if ( nIns == 1 )
+ {
+ Vec_Int_t * vArg = vDatas;
+ Vec_Int_t * vRes = vDatas+3;
+ assert( Vec_IntSize(vRes) == 0 );
+ if ( Type == ABC_OPER_BIT_INV ) // Y = ~A $not
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Vec_IntForEachEntry( vArg, iLit, k )
+ Vec_IntPush( vRes, Abc_LitNot(iLit) );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_BUF ) // Y = +A $pos
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Vec_IntForEachEntry( vArg, iLit, k )
+ Vec_IntPush( vRes, iLit );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_MIN ) // Y = -A $neg
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Wlc_BlastMinus( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), vRes );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_AND ) // Y = &A $reduce_and
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_AND ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_OR ) // Y = |A $reduce_or $reduce_bool
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_XOR ) // Y = ^A $reduce_xor
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_XOR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_NXOR ) // Y = ~^A $reduce_xnor
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_NXOR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_LOGIC_NOT ) // Y = !A $logic_not
+ {
+ int iLit = Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR );
+ assert( nRange == 1 );
+ Vec_IntFill( vRes, 1, Abc_LitNot(iLit) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ assert( 0 );
+ return;
+ }
+
+ if ( nIns == 2 )
+ {
+ Vec_Int_t * vArg0 = vDatas;
+ Vec_Int_t * vArg1 = vDatas+1;
+ Vec_Int_t * vRes = vDatas+3;
+ int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(Vec_IntSize(vArg0), Vec_IntSize(vArg1)) );
+ int nSizeArg0 = Vec_IntSize(vArg0);
+ int nSizeArg1 = Vec_IntSize(vArg1);
+ Rtl_VecExtend( vArg0, nRangeMax, fSign0 );
+ Rtl_VecExtend( vArg1, nRangeMax, fSign1 );
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( Vec_IntSize(vRes) == 0 );
+ if ( Type == ABC_OPER_LOGIC_AND ) // Y = A && B $logic_and
+ {
+ int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR );
+ int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR );
+ assert( 1 == nRange );
+ Vec_IntFill( vRes, 1, Gia_ManHashAnd(pNew, iLit0, iLit1) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_LOGIC_OR ) // Y = A || B $logic_or
+ {
+ int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR );
+ int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR );
+ assert( 1 == nRange );
+ Vec_IntFill( vRes, 1, Gia_ManHashOr(pNew, iLit0, iLit1) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+
+ if ( Type == ABC_OPER_BIT_AND ) // Y = A & B $and
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashAnd(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_OR ) // Y = A | B $or
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashOr(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_XOR ) // Y = A ^ B $xor
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashXor(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_NXOR ) // Y = A ~^ B $xnor
+ {
+ assert( Vec_IntSize(vArg0) == nRange );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Abc_LitNot(Gia_ManHashXor(pNew, iLit0, iLit1)) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$lt") ) return ABC_OPER_COMP_LESS; // Y = A < B $lt
+ if ( !strcmp(pType, "$le") ) return ABC_OPER_COMP_LESSEQU; // Y = A <= B $le
+ if ( !strcmp(pType, "$ge") ) return ABC_OPER_COMP_MOREEQU; // Y = A >= B $ge
+ if ( !strcmp(pType, "$gt") ) return ABC_OPER_COMP_MORE; // Y = A > B $gt
+ if ( !strcmp(pType, "$eq") ) return ABC_OPER_COMP_EQU; // Y = A == B $eq
+ if ( !strcmp(pType, "$ne") ) return ABC_OPER_COMP_NOTEQU; // Y = A != B $ne
+*/
+ if ( Type == ABC_OPER_COMP_EQU || Type == ABC_OPER_COMP_NOTEQU )
+ {
+ iLit = 0;
+ assert( nRange == 1 );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, iLit0, iLit1) );
+ Vec_IntFill( vRes, 1, Abc_LitNotCond(iLit, Type == ABC_OPER_COMP_EQU) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_COMP_LESS || Type == ABC_OPER_COMP_LESSEQU ||
+ Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_MOREEQU )
+ {
+ int fSigned = fSign0 && fSign1;
+ int fSwap = (Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_LESSEQU);
+ int fCompl = (Type == ABC_OPER_COMP_MOREEQU || Type == ABC_OPER_COMP_LESSEQU);
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( nRange == 1 );
+ if ( fSwap )
+ ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 )
+ if ( fSigned )
+ iLit = Wlc_BlastLessSigned( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) );
+ else
+ iLit = Wlc_BlastLess( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) );
+ iLit = Abc_LitNotCond( iLit, fCompl );
+ Vec_IntFill( vRes, 1, iLit );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$shl") ) return ABC_OPER_SHIFT_L; // Y = A << B $shl
+ if ( !strcmp(pType, "$shr") ) return ABC_OPER_SHIFT_R; // Y = A >> B $shr
+ if ( !strcmp(pType, "$sshl") ) return ABC_OPER_SHIFT_LA; // Y = A <<< B $sshl
+ if ( !strcmp(pType, "$sshr") ) return ABC_OPER_SHIFT_RA; // Y = A >>> B $sshr
+*/
+ if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA ||
+ Type == ABC_OPER_SHIFT_L || Type == ABC_OPER_SHIFT_LA )
+ {
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA )
+ Wlc_BlastShiftRight( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, fSign0 && Type == ABC_OPER_SHIFT_RA, vRes );
+ else
+ Wlc_BlastShiftLeft( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, 0, vRes );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$add") ) return ABC_OPER_ARI_ADD; // Y = A + B $add
+ if ( !strcmp(pType, "$sub") ) return ABC_OPER_ARI_SUB; // Y = A - B $sub
+ if ( !strcmp(pType, "$mul") ) return ABC_OPER_ARI_MUL; // Y = A * B $mul
+ if ( !strcmp(pType, "$div") ) return ABC_OPER_ARI_DIV; // Y = A / B $div
+ if ( !strcmp(pType, "$mod") ) return ABC_OPER_ARI_MOD; // Y = A % B $mod
+ if ( !strcmp(pType, "$pow") ) return ABC_OPER_ARI_POW; // Y = A ** B $pow
+*/
+ if ( Type == ABC_OPER_ARI_ADD || Type == ABC_OPER_ARI_SUB )
+ {
+ //Vec_IntPrint( vArg0 );
+ //Vec_IntPrint( vArg1 );
+ Vec_IntAppend( vRes, vArg0 );
+ if ( Type == ABC_OPER_ARI_ADD )
+ Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 0 ); // result is in pFan0 (vRes)
+ else
+ Wlc_BlastSubtract( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 1 ); // result is in pFan0 (vRes)
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_MUL )
+ {
+ int fBooth = 1;
+ int fCla = 0;
+ int fSigned = fSign0 && fSign1;
+ Vec_IntShrink( vArg0, nSizeArg0 );
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ if ( Wlc_NtkCountConstBits(Vec_IntArray(vArg0), Vec_IntSize(vArg0)) < Wlc_NtkCountConstBits(Vec_IntArray(vArg1), Vec_IntSize(vArg1)) )
+ ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 )
+ if ( fBooth )
+ Wlc_BlastBooth( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL );
+ else
+ Wlc_BlastMultiplier3( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL );
+ if ( nRange > Vec_IntSize(vRes) )
+ Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 );
+ else
+ Vec_IntShrink( vRes, nRange );
+ assert( Vec_IntSize(vRes) == nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_DIV || Type == ABC_OPER_ARI_MOD )
+ {
+ int fDivBy0 = 1; // correct with 1
+ int fSigned = fSign0 && fSign1;
+ if ( fSigned )
+ Wlc_BlastDividerSigned( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes );
+ else
+ Wlc_BlastDivider( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes );
+ Vec_IntShrink( vRes, nRange );
+ if ( !fDivBy0 )
+ Wlc_BlastZeroCondition( pNew, Vec_IntArray(vArg1), nRange, vRes );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_POW )
+ {
+ Vec_Int_t * vTemp = vDatas+4;
+ Vec_IntGrow( vTemp, nRangeMax );
+ Vec_IntGrow( vRes, nRangeMax );
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ Wlc_BlastPower( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), Vec_IntSize(vArg1), vTemp, vRes );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ }
+
+ if ( nIns == 3 )
+ {
+ if ( Type == ABC_OPER_SEL_NMUX ) // $mux
+ {
+ Vec_Int_t * vArg0 = vDatas;
+ Vec_Int_t * vArg1 = vDatas+1;
+ Vec_Int_t * vArgS = vDatas+2;
+ Vec_Int_t * vRes = vDatas+3;
+ int iCtrl = Vec_IntEntry(vArgS, 0);
+ //Vec_IntPrint( vArg0 );
+ //Vec_IntPrint( vArg1 );
+ //Vec_IntPrint( vArgS );
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( Vec_IntSize(vArg0) == nRange );
+ assert( Vec_IntSize(vArgS) == 1 );
+ assert( Vec_IntSize(vRes) == 0 );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashMux(pNew, iCtrl, iLit1, iLit0) );
+ return;
+ }
+ if ( Type == ABC_OPER_SEL_SEL ) // $pmux
+ {
+ int i, k, iLit;
+ Vec_Int_t * vArgA = vDatas;
+ Vec_Int_t * vArgB = vDatas+1;
+ Vec_Int_t * vArgS = vDatas+2;
+ Vec_Int_t * vRes = vDatas+3;
+ Vec_Int_t * vTemp = vDatas+4;
+ assert( Vec_IntSize(vArgA) == nRange ); // widthA = widthY
+ assert( Vec_IntSize(vArgB) == Vec_IntSize(vArgA)*Vec_IntSize(vArgS) ); // widthB == widthA*widthS
+ assert( Vec_IntSize(vRes) == 0 );
+ for ( i = 0; i < nRange; i++ )
+ {
+ int iCond = 1;
+ Vec_IntClear( vTemp );
+ Vec_IntForEachEntry( vArgS, iLit, k ) // iLit = S[i]
+ {
+ //Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*(Vec_IntSize(vArgS)-1-k)+i)) ) ); // B[widthA*k+i]
+ Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*k+i)) ) ); // B[widthA*k+i]
+ iCond = Gia_ManHashAnd( pNew, iCond, Abc_LitNot(iLit) );
+ }
+ Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iCond, Vec_IntEntry(vArgA, i)) ) );
+ Vec_IntPush( vRes, Abc_LitNot( Gia_ManHashAndMulti(pNew, vTemp) ) );
+ }
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c
new file mode 100644
index 00000000..90ac4faa
--- /dev/null
+++ b/src/base/wln/wlnCom.c
@@ -0,0 +1,353 @@
+/**CFile****************************************************************
+
+ FileName [wlnCom.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnCom.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "base/main/mainInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Abc_CommandYosys ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSolve ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrint ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static inline Rtl_Lib_t * Wln_AbcGetRtl( Abc_Frame_t * pAbc ) { return (Rtl_Lib_t *)pAbc->pAbcRtl; }
+static inline void Wln_AbcFreeRtl( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcRtl ) Rtl_LibFree(Wln_AbcGetRtl(pAbc)); }
+static inline void Wln_AbcUpdateRtl( Abc_Frame_t * pAbc, Rtl_Lib_t * pLib ) { Wln_AbcFreeRtl(pAbc); pAbc->pAbcRtl = pLib; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_Init( Abc_Frame_t * pAbc )
+{
+ Cmd_CommandAdd( pAbc, "Word level", "%yosys", Abc_CommandYosys, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%solve", Abc_CommandSolve, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%print", Abc_CommandPrint, 0 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+void Wln_End( Abc_Frame_t * pAbc )
+{
+ Wln_AbcUpdateRtl( pAbc, NULL );
+}
+
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose );
+ extern Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose );
+
+ FILE * pFile;
+ char * pFileName = NULL;
+ char * pTopModule= NULL;
+ int fBlast = 0;
+ int fInvert = 0;
+ int fTechMap = 1;
+ int fSkipStrash = 0;
+ int fCollapse = 0;
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Tbismcvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" );
+ goto usage;
+ }
+ pTopModule = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
+ case 'b':
+ fBlast ^= 1;
+ break;
+ case 'i':
+ fInvert ^= 1;
+ break;
+ case 's':
+ fSkipStrash ^= 1;
+ break;
+ case 'm':
+ fTechMap ^= 1;
+ break;
+ case 'c':
+ fCollapse ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ {
+ printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" );
+ return 0;
+ }
+ // get the file name
+ pFileName = argv[globalUtilOptind];
+ if ( (pFile = fopen( pFileName, "r" )) == NULL )
+ {
+ Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName );
+ if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", pFileName );
+ Abc_Print( 1, "\n" );
+ return 0;
+ }
+ fclose( pFile );
+
+ // perform reading
+ if ( fBlast )
+ {
+ Gia_Man_t * pNew = NULL;
+ if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
+ pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose );
+ else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) )
+ pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose );
+ else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) )
+ pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose );
+ else
+ {
+ printf( "Abc_CommandYosys(): Unknown file extension.\n" );
+ return 0;
+ }
+ Abc_FrameUpdateGia( pAbc, pNew );
+ }
+ else
+ {
+ Rtl_Lib_t * pLib = NULL;
+ if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
+ pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose );
+ else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) )
+ pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose );
+ else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) )
+ pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose );
+ else
+ {
+ printf( "Abc_CommandYosys(): Unknown file extension.\n" );
+ return 0;
+ }
+ Wln_AbcUpdateRtl( pAbc, pLib );
+ }
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%yosys [-T <module>] [-bismcvh] <file_name>\n" );
+ Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" );
+ Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" );
+ Abc_Print( -2, "\t-b : toggle bit-blasting the design into an AIG using Yosys [default = %s]\n", fBlast? "yes": "no" );
+ Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" );
+ Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" );
+ Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggle collapsing design hierarchy using Yosys [default = %s]\n", fCollapse? "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_CommandPrint( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Rtl_LibPrintStats( Rtl_Lib_t * p );
+ extern void Rtl_LibPrintHieStats( Rtl_Lib_t * p );
+ extern void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p );
+ Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc);
+ int c, fHie = 0, fDesign = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "pdvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'p':
+ fHie ^= 1;
+ break;
+ case 'd':
+ fDesign ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pLib == NULL )
+ {
+ printf( "The design is not entered.\n" );
+ return 1;
+ }
+ Rtl_LibPrintStats( pLib );
+ if ( fHie )
+ Rtl_LibPrintHieStats( pLib );
+ if ( fDesign )
+ Rtl_LibPrint( NULL, pLib );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%print [-pdvh]\n" );
+ Abc_Print( -2, "\t print statistics about the hierarchical design\n" );
+ Abc_Print( -2, "\t-p : toggle printing of the hierarchy [default = %s]\n", fHie? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle printing of the design [default = %s]\n", fDesign? "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");
+ Abc_Print( -2, "\t<file> : text file name with guidance for solving\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Rtl_LibBlast( Rtl_Lib_t * pLib );
+ extern void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots );
+ extern void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk );
+ extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib );
+ extern void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p );
+
+ Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc);
+ int c, fOldBlast = 0, fPrepro = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "opvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'o':
+ fOldBlast ^= 1;
+ break;
+ case 'p':
+ fPrepro ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pLib == NULL )
+ {
+ printf( "The design is not entered.\n" );
+ return 1;
+ }
+ if ( argc == globalUtilOptind + 1 )
+ {
+ char * pFileName = argv[globalUtilOptind];
+ FILE * pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ Abc_Print( -1, "Cannot open file \"%s\" with the input test patterns.\n", pFileName );
+ return 0;
+ }
+ fclose( pFile );
+ printf( "Using guidance from file \"%s\".\n", pFileName );
+ Wln_SolveWithGuidance( pFileName, pLib );
+ }
+ else
+ {
+ printf( "Solving the miter without guidance.\n" );
+ if ( fOldBlast )
+ Rtl_LibBlast( pLib );
+ else
+ Rtl_LibBlast2( pLib, NULL );
+ if ( fPrepro )
+ Rtl_LibPreprocess( pLib );
+ Rtl_LibSolve( pLib, NULL );
+ }
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%solve [-opvh] <file>\n" );
+ Abc_Print( -2, "\t solving properties for the hierarchical design\n" );
+ Abc_Print( -2, "\t-o : toggle using old bit-blasting procedure [default = %s]\n", fOldBlast? "yes": "no" );
+ Abc_Print( -2, "\t-p : toggle preprocessing for verification [default = %s]\n", fPrepro? "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");
+ Abc_Print( -2, "\t<file> : text file name with guidance for solving\n");
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnGuide.c b/src/base/wln/wlnGuide.c
new file mode 100644
index 00000000..b7e656eb
--- /dev/null
+++ b/src/base/wln/wlnGuide.c
@@ -0,0 +1,95 @@
+/**CFile****************************************************************
+
+ FileName [wln.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wln_ReadFindToken( char * pToken, Abc_Nam_t * p )
+{
+ char * pBuffer = Abc_UtilStrsavTwo( "\\", pToken );
+ int RetValue = Abc_NamStrFindOrAdd( p, pBuffer, NULL );
+ ABC_FREE( pBuffer );
+ return RetValue;
+}
+void Wln_PrintGuidance( Vec_Wec_t * vGuide, Abc_Nam_t * p )
+{
+ Vec_Int_t * vLevel; int i, k, Obj;
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ {
+ Vec_IntForEachEntry( vLevel, Obj, k )
+ printf( "%s ", Obj >= 0 ? Abc_NamStr(p, Obj) : "[unknown]" );
+ printf( "\n" );
+ }
+}
+Vec_Wec_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p )
+{
+ char * pBuffer = ABC_CALLOC( char, 10000 ), * pToken;
+ Vec_Wec_t * vTokens = Vec_WecAlloc( 100 ); Vec_Int_t * vLevel;
+ FILE * pFile = fopen( pFileName, "rb" );
+ while ( fgets( pBuffer, 10000, pFile ) )
+ {
+ if ( pBuffer[0] == '#' )
+ continue;
+ vLevel = Vec_WecPushLevel( vTokens );
+ pToken = strtok( pBuffer, " \t\r\n" );
+ while ( pToken )
+ {
+ Vec_IntPush( vLevel, Vec_IntSize(vLevel) < 2 ? Abc_NamStrFindOrAdd(p, pToken, NULL) : Wln_ReadFindToken(pToken, p) );
+ pToken = strtok( NULL, " \t\r\n" );
+ }
+ if ( Vec_IntSize(vLevel) % 4 == 3 ) // account for "property"
+ Vec_IntPush( vLevel, -1 );
+ assert( Vec_IntSize(vLevel) % 4 == 0 );
+ }
+ fclose( pFile );
+ if ( Vec_WecSize(vTokens) == 0 )
+ printf( "Guidance is empty.\n" );
+ //Wln_PrintGuidance( vTokens, p );
+ ABC_FREE( pBuffer );
+ return vTokens;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c
new file mode 100644
index 00000000..95d2dd31
--- /dev/null
+++ b/src/base/wln/wlnRead.c
@@ -0,0 +1,2441 @@
+/**CFile****************************************************************
+
+ FileName [wln.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "proof/cec/cec.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define MAX_LINE 1000000
+
+#define MAX_MAP 32
+#define CELL_NUM 8
+#define WIRE_NUM 5
+#define TEMP_NUM 5
+#define CONST_SHIFT 99
+
+//typedef struct Rtl_Lib_t_ Rtl_Lib_t;
+struct Rtl_Lib_t_
+{
+ char * pSpec; // input file name
+ Vec_Ptr_t * vNtks; // modules
+ Abc_Nam_t * pManName; // object names
+ Vec_Int_t vConsts; // constants
+ Vec_Int_t vSlices; // selections
+ Vec_Int_t vConcats; // concatenations
+ FILE * pFile; // temp file
+ Vec_Int_t * vTokens; // temp tokens
+ int pMap[MAX_MAP]; // temp map
+ Vec_Int_t * vMap; // mapping NameId into wires
+ Vec_Int_t vAttrTemp; // temp
+ Vec_Int_t vTemp[TEMP_NUM]; // temp
+};
+
+typedef struct Rtl_Ntk_t_ Rtl_Ntk_t;
+struct Rtl_Ntk_t_
+{
+ int NameId; // model name
+ int nInputs; // word-level inputs
+ int nOutputs; // word-level outputs
+ Vec_Int_t vWires; // wires (name{upto,signed,in,out}+width+offset+number)
+ Vec_Int_t vCells; // instances ([0]type+[1]name+[2]mod+[3]ins+[4]nattr+[5]nparams+[6]nconns+[7]mark+(attr+params+conns))
+ Vec_Int_t vConns; // connection pairs
+ Vec_Int_t vStore; // storage for cells
+ Vec_Int_t vAttrs; // attributes
+ Rtl_Lib_t * pLib; // parent
+ Vec_Int_t vOrder; // topological order
+ Vec_Int_t vLits; // bit-level view
+ Vec_Int_t vDrivers; // bit-level view
+ Vec_Int_t vBitTemp; // storage for bits
+ Vec_Int_t vBitTemp2; // storage for bits
+ Gia_Man_t * pGia; // derived by bit-blasting
+ int Slice0; // first slice
+ int Slice1; // last slice
+ int iCopy; // place in array
+};
+
+static inline int Rtl_LibNtkNum( Rtl_Lib_t * pLib ) { return Vec_PtrSize(pLib->vNtks); }
+static inline Rtl_Ntk_t * Rtl_LibNtk( Rtl_Lib_t * pLib, int i ) { return (Rtl_Ntk_t *)Vec_PtrEntry(pLib->vNtks, i); }
+static inline Rtl_Ntk_t * Rtl_LibTop( Rtl_Lib_t * pLib ) { return Rtl_LibNtk( pLib, Rtl_LibNtkNum(pLib)-1 ); }
+static inline char * Rtl_LibStr( Rtl_Lib_t * pLib, int h ) { return Abc_NamStr(pLib->pManName, h); }
+static inline int Rtl_LibStrId( Rtl_Lib_t * pLib, char * s ) { return Abc_NamStrFind(pLib->pManName, s); }
+
+static inline Rtl_Ntk_t * Rtl_NtkModule( Rtl_Ntk_t * p, int i ) { return Rtl_LibNtk( p->pLib, i ); }
+
+static inline int Rtl_NtkStrId( Rtl_Ntk_t * p, char * s ) { return Abc_NamStrFind(p->pLib->pManName, s); }
+static inline char * Rtl_NtkStr( Rtl_Ntk_t * p, int h ) { return Abc_NamStr(p->pLib->pManName, h); }
+static inline char * Rtl_NtkName( Rtl_Ntk_t * p ) { return Rtl_NtkStr(p, p->NameId); }
+
+static inline FILE * Rtl_NtkFile( Rtl_Ntk_t * p ) { return p->pLib->pFile; }
+static inline int Rtl_NtkTokId( Rtl_Ntk_t * p, int i ) { return i < Vec_IntSize(p->pLib->vTokens) ? Vec_IntEntry(p->pLib->vTokens, i) : -1; }
+static inline char * Rtl_NtkTokStr( Rtl_Ntk_t * p, int i ) { return i < Vec_IntSize(p->pLib->vTokens) ? Rtl_NtkStr(p, Vec_IntEntry(p->pLib->vTokens, i)) : NULL; }
+static inline int Rtl_NtkTokCheck( Rtl_Ntk_t * p, int i, int Tok ) { return i == p->pLib->pMap[Tok]; }
+static inline int Rtl_NtkPosCheck( Rtl_Ntk_t * p, int i, int Tok ) { return Vec_IntEntry(p->pLib->vTokens, i) == p->pLib->pMap[Tok]; }
+
+static inline int Rtl_NtkInputNum( Rtl_Ntk_t * p ) { return p->nInputs; }
+static inline int Rtl_NtkOutputNum( Rtl_Ntk_t * p ) { return p->nOutputs; }
+static inline int Rtl_NtkAttrNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vAttrs)/2; }
+static inline int Rtl_NtkWireNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vWires)/WIRE_NUM; }
+static inline int Rtl_NtkCellNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vCells); }
+static inline int Rtl_NtkConNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vConns)/2; }
+static inline int Rtl_NtkObjNum( Rtl_Ntk_t * p ) { return p->nInputs + p->nOutputs + Rtl_NtkCellNum(p) + Rtl_NtkConNum(p); }
+
+static inline int * Rtl_NtkWire( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vWires, WIRE_NUM*i); }
+static inline int * Rtl_NtkCell( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vStore, Vec_IntEntry(&p->vCells, i)); }
+static inline int * Rtl_NtkCon( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vConns, 2*i); }
+
+static inline int Rtl_WireName( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i) >> 4; }
+static inline char * Rtl_WireNameStr( Rtl_Ntk_t * p, int i ) { return Rtl_NtkStr(p, Rtl_WireName(p, i)); }
+static inline int Rtl_WireFirst( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i); }
+static inline int Rtl_WireWidth( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+1); }
+static inline int Rtl_WireOffset( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+2); }
+static inline int Rtl_WireNumber( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+3); }
+static inline int Rtl_WireBitStart( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+4); }
+static inline int Rtl_WireMapNameToId( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(p->pLib->vMap, i); }
+
+static inline int Rtl_CellType( int * pCell ) { return pCell[0]; }
+static inline int Rtl_CellName( int * pCell ) { return pCell[1]; }
+static inline int Rtl_CellModule( int * pCell ) { return pCell[2]; }
+static inline int Rtl_CellInputNum( int * pCell ) { return pCell[3]; }
+static inline int Rtl_CellOutputNum( int * pCell ) { return pCell[6]-pCell[3]; }
+static inline int Rtl_CellAttrNum( int * pCell ) { return pCell[4]; }
+static inline int Rtl_CellParamNum( int * pCell ) { return pCell[5]; }
+static inline int Rtl_CellConNum( int * pCell ) { return pCell[6]; }
+static inline int Rtl_CellMark( int * pCell ) { return pCell[7]; }
+static inline Rtl_Ntk_t * Rtl_CellNtk( Rtl_Ntk_t * p, int * pCell ) { return Rtl_CellModule(pCell) >= ABC_INFINITY ? Rtl_NtkModule(p, Rtl_CellModule(pCell)-ABC_INFINITY) : NULL; }
+
+static inline char * Rtl_CellTypeStr( Rtl_Ntk_t * p, int * pCell ) { return Rtl_NtkStr(p, Rtl_CellType(pCell)); }
+static inline char * Rtl_CellNameStr( Rtl_Ntk_t * p, int * pCell ) { return Rtl_NtkStr(p, Rtl_CellName(pCell)); }
+
+static inline int Rtl_SigIsNone( int s ) { return (s & 0x3) == 0; }
+static inline int Rtl_SigIsConst( int s ) { return (s & 0x3) == 1; }
+static inline int Rtl_SigIsSlice( int s ) { return (s & 0x3) == 2; }
+static inline int Rtl_SigIsConcat( int s ) { return (s & 0x3) == 3; }
+
+#define Rtl_NtkForEachAttr( p, Par, Val, i ) \
+ for ( i = 0; i < Rtl_NtkAttrNum(p) && (Par = Vec_IntEntry(&p->vAttrs, 2*i)) && (Val = Vec_IntEntry(&p->vAttrs, 2*i+1)); i++ )
+#define Rtl_NtkForEachWire( p, pWire, i ) \
+ for ( i = 0; i < Rtl_NtkWireNum(p) && (pWire = Vec_IntEntryP(&p->vWires, WIRE_NUM*i)); i++ )
+#define Rtl_NtkForEachCell( p, pCell, i ) \
+ for ( i = 0; i < Rtl_NtkCellNum(p) && (pCell = Rtl_NtkCell(p, i)); i++ )
+#define Rtl_NtkForEachCon( p, pCon, i ) \
+ for ( i = 0; i < Rtl_NtkConNum(p) && (pCon = Vec_IntEntryP(&p->vConns, 2*i)); i++ )
+
+#define Rtl_CellForEachAttr( p, pCell, Par, Val, i ) \
+ for ( i = 0; i < pCell[4] && (Par = pCell[CELL_NUM+2*i]) && (Val = pCell[CELL_NUM+2*i+1]); i++ )
+#define Rtl_CellForEachParam( p, pCell, Par, Val, i ) \
+ for ( i = 0; i < pCell[5] && (Par = pCell[CELL_NUM+2*(pCell[4]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+i)+1]); i++ )
+#define Rtl_CellForEachConnect( p, pCell, Par, Val, i ) \
+ for ( i = 0; i < pCell[6] && (Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)+1]); i++ )
+
+#define Rtl_CellForEachInput( p, pCell, Par, Val, i ) \
+ Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i >= Rtl_CellInputNum(pCell) ) continue; else
+#define Rtl_CellForEachOutput( p, pCell, Par, Val, i ) \
+ Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i < Rtl_CellInputNum(pCell) ) continue; else
+
+extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Rtl_Ntk_t * Rtl_NtkAlloc( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p = ABC_CALLOC( Rtl_Ntk_t, 1 );
+ Vec_IntGrow( &p->vWires, 4 );
+ Vec_IntGrow( &p->vCells, 4 );
+ Vec_IntGrow( &p->vConns, 4 );
+ Vec_IntGrow( &p->vStore, 8 );
+ Vec_IntGrow( &p->vAttrs, 8 );
+ Vec_PtrPush( pLib->vNtks, (void *)p );
+ p->pLib = pLib;
+ return p;
+}
+void Rtl_NtkFree( Rtl_Ntk_t * p )
+{
+ Gia_ManStopP( &p->pGia );
+ ABC_FREE( p->vWires.pArray );
+ ABC_FREE( p->vCells.pArray );
+ ABC_FREE( p->vConns.pArray );
+ ABC_FREE( p->vStore.pArray );
+ ABC_FREE( p->vAttrs.pArray );
+ ABC_FREE( p->vOrder.pArray );
+ ABC_FREE( p->vLits.pArray );
+ ABC_FREE( p->vDrivers.pArray );
+ ABC_FREE( p->vBitTemp.pArray );
+ ABC_FREE( p->vBitTemp2.pArray );
+ ABC_FREE( p );
+}
+void Rtl_NtkCountPio( Rtl_Ntk_t * p, int Counts[4] )
+{
+ int i, * pWire;
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ if ( pWire[0] & 1 ) // PI
+ Counts[0]++, Counts[1] += pWire[1];
+ if ( pWire[0] & 2 ) // PO
+ Counts[2]++, Counts[3] += pWire[1];
+ }
+ assert( p->nInputs == Counts[0] );
+ assert( p->nOutputs == Counts[2] );
+}
+void Rtl_NtkPrintOpers( Rtl_Ntk_t * p )
+{
+ int i, * pCell, nBlack = 0, nUser = 0, Counts[ABC_OPER_LAST] = {0};
+ if ( Rtl_NtkCellNum(p) == 0 )
+ return;
+ Rtl_NtkForEachCell( p, pCell, i )
+ if ( Rtl_CellModule(pCell) < ABC_OPER_LAST )
+ Counts[Rtl_CellModule(pCell)]++;
+ else if ( Rtl_CellModule(pCell) == ABC_OPER_LAST-1 )
+ nBlack++;
+ else
+ nUser++;
+ printf( "There are %d instances in this network:\n", Rtl_NtkCellNum(p) );
+ if ( nBlack )
+ printf( " %s (%d)", "blackbox", nBlack );
+ if ( nUser )
+ printf( " %s (%d)", "user", nUser );
+ for ( i = 0; i < ABC_OPER_LAST; i++ )
+ if ( Counts[i] )
+ printf( " %s (%d)", Abc_OperName(i), Counts[i] );
+ printf( "\n" );
+}
+void Rtl_NtkPrintStats( Rtl_Ntk_t * p, int nNameSymbs )
+{
+ int Counts[4] = {0}; Rtl_NtkCountPio( p, Counts );
+ printf( "%*s : ", nNameSymbs, Rtl_NtkName(p) );
+ printf( "PI = %5d (%5d) ", Counts[0], Counts[1] );
+ printf( "PO = %5d (%5d) ", Counts[2], Counts[3] );
+ printf( "Wire = %6d ", Rtl_NtkWireNum(p) );
+ printf( "Cell = %6d ", Rtl_NtkCellNum(p) );
+ printf( "Con = %6d", Rtl_NtkConNum(p) );
+ printf( "\n" );
+ //Rtl_NtkPrintOpers( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_NtkPrintHieStats( Rtl_Ntk_t * p, int nOffset )
+{
+ Vec_Int_t * vFound = Vec_IntAlloc( 100 );
+ int i, * pCell;
+ for ( i = 0; i < 5*(nOffset-1); i++ )
+ printf( " " );
+ if ( nOffset )
+ printf( "|--> " );
+ printf( "%s\n", Rtl_NtkName(p) );
+ Rtl_NtkForEachCell( p, pCell, i )
+ if ( Rtl_CellModule(pCell) >= ABC_INFINITY )
+ {
+ Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY );
+ assert( pCell[6] == pModel->nInputs+pModel->nOutputs );
+ if ( Vec_IntFind(vFound, pModel->NameId) >= 0 )
+ continue;
+ Vec_IntPush( vFound, pModel->NameId );
+ Rtl_NtkPrintHieStats( pModel, nOffset+1 );
+ }
+ Vec_IntFree( vFound );
+}
+void Rtl_LibPrintHieStats( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ printf( "Hierarchy found in \"%s\":\n", p->pSpec );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ {
+ printf( "\n" );
+ printf( "MODULE %d: ", i );
+ Rtl_NtkPrintHieStats( pNtk, 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Rtl_Lib_t * Rtl_LibAlloc()
+{
+ Rtl_Lib_t * p = ABC_CALLOC( Rtl_Lib_t, 1 );
+ p->vNtks = Vec_PtrAlloc( 100 );
+ Vec_IntGrow( &p->vConsts, 1000 );
+ Vec_IntGrow( &p->vSlices, 1000 );
+ Vec_IntGrow( &p->vConcats, 1000 );
+ return p;
+}
+void Rtl_LibFree( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkFree( pNtk );
+ ABC_FREE( p->vConsts.pArray );
+ ABC_FREE( p->vSlices.pArray );
+ ABC_FREE( p->vConcats.pArray );
+ ABC_FREE( p->vAttrTemp.pArray );
+ for ( i = 0; i < TEMP_NUM; i++ )
+ ABC_FREE( p->vTemp[i].pArray );
+ Vec_IntFreeP( &p->vMap );
+ Vec_IntFreeP( &p->vTokens );
+ Abc_NamStop( p->pManName );
+ Vec_PtrFree( p->vNtks );
+ ABC_FREE( p->pSpec );
+ ABC_FREE( p );
+}
+int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ if ( pNtk->NameId == NameId )
+ return i;
+ return -1;
+}
+int Rtl_LibFindModule2( Rtl_Lib_t * p, int NameId, int iNtk0 )
+{
+ char * pName = Rtl_LibStr( p, NameId );
+ Rtl_Ntk_t * pNtk0 = Rtl_LibNtk( p, iNtk0 );
+ Rtl_Ntk_t * pNtk; int i;
+ int Counts0[4] = {0}; Rtl_NtkCountPio( pNtk0, Counts0 );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ if ( strstr(Rtl_NtkName(pNtk), pName+1) )
+ {
+ int Counts[4] = {0}; Rtl_NtkCountPio( pNtk, Counts );
+ if ( Counts[1] == Counts0[1] && Counts[3] == Counts0[3] )
+ return i;
+ }
+ return -1;
+}
+int Rtl_LibFindTwoModules( Rtl_Lib_t * p, int Name1, int Name2 )
+{
+ int iNtk1 = Rtl_LibFindModule( p, Name1 );
+ if ( Name2 == -1 )
+ return (iNtk1 << 16) | iNtk1;
+ else
+ {
+ int Counts1[4] = {0}, Counts2[4] = {0};
+ int iNtk2 = Rtl_LibFindModule( p, Name2 );
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 );
+ Rtl_NtkCountPio( pNtk1, Counts1 );
+ Rtl_NtkCountPio( pNtk2, Counts2 );
+ if ( Counts1[1] != Counts2[1] || Counts1[3] != Counts2[3] )
+ iNtk1 = Rtl_LibFindModule2( p, Name1, iNtk2 );
+ return (iNtk1 << 16) | iNtk2;
+ }
+}
+void Rtl_LibPrintStats( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i, nSymbs = 0;
+ printf( "Modules found in \"%s\":\n", p->pSpec );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ nSymbs = Abc_MaxInt( nSymbs, strlen(Rtl_NtkName(pNtk)) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkPrintStats( pNtk, nSymbs + 2 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+typedef enum {
+ RTL_NONE = 0, // 0: unused
+ RTL_MODULE, // 1: "module"
+ RTL_END, // 2: "end"
+ RTL_INPUT, // 3: "input"
+ RTL_OUTPUT, // 4: "output"
+ RTL_INOUT, // 5: "inout"
+ RTL_UPTO, // 6: "upto"
+ RTL_SIGNED, // 7: "signed"
+ RTL_OFFSET, // 8: "offset"
+ RTL_PARAMETER, // 9: "parameter"
+ RTL_WIRE, // 10: "wire"
+ RTL_CONNECT, // 11: "connect"
+ RTL_CELL, // 12: "cell"
+ RTL_WIDTH, // 13: "width"
+ RTL_ATTRIBUTE, // 14: "attribute"
+ RTL_UNUSED // 15: unused
+} Rtl_Type_t;
+
+static inline char * Rtl_Num2Name( int i )
+{
+ if ( i == 1 ) return "module";
+ if ( i == 2 ) return "end";
+ if ( i == 3 ) return "input";
+ if ( i == 4 ) return "output";
+ if ( i == 5 ) return "inout";
+ if ( i == 6 ) return "upto";
+ if ( i == 7 ) return "signed";
+ if ( i == 8 ) return "offset";
+ if ( i == 9 ) return "parameter";
+ if ( i == 10 ) return "wire";
+ if ( i == 11 ) return "connect";
+ if ( i == 12 ) return "cell";
+ if ( i == 13 ) return "width";
+ if ( i == 14 ) return "attribute";
+ return NULL;
+}
+
+static inline void Rtl_LibDeriveMap( Rtl_Lib_t * p )
+{
+ int i;
+ p->pMap[0] = -1;
+ for ( i = 1; i < RTL_UNUSED; i++ )
+ p->pMap[i] = Abc_NamStrFind( p->pManName, Rtl_Num2Name(i) );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rtl_LibReadType( char * pType )
+{
+ if ( !strcmp(pType, "$not") ) return ABC_OPER_BIT_INV; // Y = ~A $not
+ if ( !strcmp(pType, "$pos") ) return ABC_OPER_BIT_BUF; // Y = +A $pos
+ if ( !strcmp(pType, "$neg") ) return ABC_OPER_ARI_MIN; // Y = -A $neg
+ if ( !strcmp(pType, "$reduce_and") ) return ABC_OPER_RED_AND; // Y = &A $reduce_and
+ if ( !strcmp(pType, "$reduce_or") ) return ABC_OPER_RED_OR; // Y = |A $reduce_or
+ if ( !strcmp(pType, "$reduce_xor") ) return ABC_OPER_RED_XOR; // Y = ^A $reduce_xor
+ if ( !strcmp(pType, "$reduce_xnor") ) return ABC_OPER_RED_NXOR; // Y = ~^A $reduce_xnor
+ if ( !strcmp(pType, "$reduce_bool") ) return ABC_OPER_RED_OR; // Y = |A $reduce_bool
+ if ( !strcmp(pType, "$logic_not") ) return ABC_OPER_LOGIC_NOT; // Y = !A $logic_not
+
+ if ( !strcmp(pType, "$and") ) return ABC_OPER_BIT_AND; // Y = A & B $and
+ if ( !strcmp(pType, "$or") ) return ABC_OPER_BIT_OR; // Y = A | B $or
+ if ( !strcmp(pType, "$xor") ) return ABC_OPER_BIT_XOR; // Y = A ^ B $xor
+ if ( !strcmp(pType, "$xnor") ) return ABC_OPER_BIT_NXOR; // Y = A ~^ B $xnor
+
+ if ( !strcmp(pType, "$shl") ) return ABC_OPER_SHIFT_L; // Y = A << B $shl
+ if ( !strcmp(pType, "$shr") ) return ABC_OPER_SHIFT_R; // Y = A >> B $shr
+ if ( !strcmp(pType, "$sshl") ) return ABC_OPER_SHIFT_LA; // Y = A <<< B $sshl
+ if ( !strcmp(pType, "$sshr") ) return ABC_OPER_SHIFT_RA; // Y = A >>> B $sshr
+
+ if ( !strcmp(pType, "$shiftx") ) return ABC_OPER_SHIFT_R; // Y = A << B $shl <== temporary
+
+ if ( !strcmp(pType, "$logic_and") ) return ABC_OPER_LOGIC_AND; // Y = A && B $logic_and
+ if ( !strcmp(pType, "$logic_or") ) return ABC_OPER_LOGIC_OR; // Y = A || B $logic_or
+
+ if ( !strcmp(pType, "$lt") ) return ABC_OPER_COMP_LESS; // Y = A < B $lt
+ if ( !strcmp(pType, "$le") ) return ABC_OPER_COMP_LESSEQU; // Y = A <= B $le
+ if ( !strcmp(pType, "$ge") ) return ABC_OPER_COMP_MOREEQU; // Y = A >= B $ge
+ if ( !strcmp(pType, "$gt") ) return ABC_OPER_COMP_MORE; // Y = A > B $gt
+ if ( !strcmp(pType, "$eq") ) return ABC_OPER_COMP_EQU; // Y = A == B $eq
+ if ( !strcmp(pType, "$ne") ) return ABC_OPER_COMP_NOTEQU; // Y = A != B $ne
+ if ( !strcmp(pType, "$eqx") ) return ABC_OPER_COMP_EQU; // Y = A === B $eqx
+ if ( !strcmp(pType, "$nex") ) return ABC_OPER_COMP_NOTEQU; // Y = A !== B $nex
+
+ if ( !strcmp(pType, "$add") ) return ABC_OPER_ARI_ADD; // Y = A + B $add
+ if ( !strcmp(pType, "$sub") ) return ABC_OPER_ARI_SUB; // Y = A - B $sub
+ if ( !strcmp(pType, "$mul") ) return ABC_OPER_ARI_MUL; // Y = A * B $mul
+ if ( !strcmp(pType, "$div") ) return ABC_OPER_ARI_DIV; // Y = A / B $div
+ if ( !strcmp(pType, "$mod") ) return ABC_OPER_ARI_MOD; // Y = A % B $mod
+ if ( !strcmp(pType, "$pow") ) return ABC_OPER_ARI_POW; // Y = A ** B $pow
+
+ if ( !strcmp(pType, "$modfoor") ) return ABC_OPER_NONE; // [N/A] $modfoor
+ if ( !strcmp(pType, "$divfloor") ) return ABC_OPER_NONE; // [N/A] $divfloor
+
+ if ( !strcmp(pType, "$mux") ) return ABC_OPER_SEL_NMUX; // $mux
+ if ( !strcmp(pType, "$pmux") ) return ABC_OPER_SEL_SEL; // $pmux
+
+ if ( !strcmp(pType, "$dff") ) return ABC_OPER_DFF;
+ if ( !strcmp(pType, "$adff") ) return ABC_OPER_DFF;
+ if ( !strcmp(pType, "$sdff") ) return ABC_OPER_DFF;
+ assert( 0 );
+ return -1;
+}
+int Rtl_NtkReadType( Rtl_Ntk_t * p, int Type )
+{
+ extern int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId );
+ char * pType = Rtl_NtkStr( p, Type );
+ if ( pType[0] == '$' && strncmp(pType,"$paramod",strlen("$paramod")) )
+ return Rtl_LibReadType( pType );
+ return ABC_INFINITY + Rtl_LibFindModule( p->pLib, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [There is no need to normalize ranges in Yosys.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rtl_NtkRangeWires( Rtl_Ntk_t * p )
+{
+ int i, * pWire, nBits = 0;
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ //printf( "%s -> %d\n", Rtl_WireNameStr(p, i), nBits );
+ pWire[4] = nBits, nBits += Rtl_WireWidth(p, i);
+ }
+ return nBits;
+}
+void Rtl_NtkMapWires( Rtl_Ntk_t * p, int fUnmap )
+{
+ int i, Value;
+ assert( Vec_IntSize(p->pLib->vMap) == Abc_NamObjNumMax(p->pLib->pManName) );
+ for ( i = 0; i < Rtl_NtkWireNum(p); i++ )
+ {
+ int NameId = Rtl_WireName( p, i );
+ assert( Vec_IntEntry(p->pLib->vMap, NameId) == (fUnmap ? i : -1) );
+ Vec_IntWriteEntry( p->pLib->vMap, NameId, fUnmap ? -1 : i );
+ }
+ if ( fUnmap )
+ Vec_IntForEachEntry( p->pLib->vMap, Value, i )
+ assert( Value == -1 );
+}
+void Rtl_NtkNormRanges( Rtl_Ntk_t * p )
+{
+ int i, * pWire;
+ Rtl_NtkMapWires( p, 0 );
+ for ( i = p->Slice0; i < p->Slice1; i += 3 )
+ {
+ int NameId = Vec_IntEntry( &p->pLib->vSlices, i );
+ int Left = Vec_IntEntry( &p->pLib->vSlices, i+1 );
+ int Right = Vec_IntEntry( &p->pLib->vSlices, i+2 );
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int Offset = Rtl_WireOffset( p, Wire );
+ int First = Rtl_WireFirst( p, Wire );
+ assert( First >> 4 == NameId );
+ if ( Offset );
+ {
+ Left -= Offset;
+ Right -= Offset;
+ }
+ if ( First & 8 ) // upto
+ {
+ Vec_IntWriteEntry( &p->pLib->vSlices, i+1, Right );
+ Vec_IntWriteEntry( &p->pLib->vSlices, i+2, Left );
+ }
+ }
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ Vec_IntWriteEntry( &p->vWires, WIRE_NUM*i+0, Rtl_WireFirst(p, i) & ~0x8 ); // upto
+ Vec_IntWriteEntry( &p->vWires, WIRE_NUM*i+2, 0 ); // offset
+ }
+ Rtl_NtkMapWires( p, 1 );
+}
+void Rtl_LibNormRanges( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p; int i;
+ if ( pLib->vMap == NULL )
+ pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ Rtl_NtkNormRanges( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Rlt_NtkFindIOPerm( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vCost = Vec_IntAlloc( 100 );
+ int i, * pWire, * pPerm = NULL, Count = 0;
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ int First = Rtl_WireFirst( p, i );
+ int Number = Rtl_WireNumber( p, i );
+ int fIsPi = (int)((First & 1) > 0);
+ int fIsPo = (int)((First & 2) > 0);
+ assert( (fIsPi || fIsPo) == (Number > 0) );
+ if ( fIsPi || fIsPo )
+ Vec_IntPush( vCost, fIsPo*ABC_INFINITY + Number );
+ else
+ Vec_IntPush( vCost, 2*ABC_INFINITY + Count++ );
+ }
+ pPerm = Abc_MergeSortCost( Vec_IntArray(vCost), Vec_IntSize(vCost) );
+ Vec_IntFree( vCost );
+ return pPerm;
+}
+void Rtl_NtkOrderWires( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vTemp = Vec_IntAlloc( Vec_IntSize(&p->vWires) );
+ int i, k, * pWire, * pPerm = Rlt_NtkFindIOPerm( p );
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ pWire = Vec_IntEntryP( &p->vWires, WIRE_NUM*pPerm[i] );
+ for ( k = 0; k < WIRE_NUM; k++ )
+ Vec_IntPush( vTemp, pWire[k] );
+ }
+ ABC_FREE( pPerm );
+ assert( Vec_IntSize(&p->vWires) == Vec_IntSize(vTemp) );
+ ABC_SWAP( Vec_Int_t, p->vWires, *vTemp );
+ Vec_IntFree( vTemp );
+}
+void Rtl_LibUpdateInstances( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vMap = p->pLib->vMap;
+ Vec_Int_t * vTemp = &p->pLib->vTemp[2];
+ int i, k, Par, Val, * pCell, Value;
+ Rtl_NtkForEachCell( p, pCell, i )
+ if ( Rtl_CellModule(pCell) >= ABC_INFINITY )
+ {
+ Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY );
+ assert( pCell[6] == pModel->nInputs+pModel->nOutputs );
+ Rtl_CellForEachConnect( p, pCell, Par, Val, k )
+ Vec_IntWriteEntry( vMap, Par >> 2, k );
+ Vec_IntClear( vTemp );
+ for ( k = 0; k < pCell[6]; k++ )
+ {
+ int Perm = Vec_IntEntry( vMap, Rtl_WireName(pModel, k) );
+ int Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+Perm)];
+ int Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+Perm)+1];
+ assert( (Par >> 2) == Rtl_WireName(pModel, k) );
+ Vec_IntWriteEntry( vMap, Par >> 2, -1 );
+ Vec_IntPushTwo( vTemp, Par, Val );
+ assert( Perm >= 0 );
+ }
+ memcpy( pCell+CELL_NUM+2*(pCell[4]+pCell[5]), Vec_IntArray(vTemp), sizeof(int)*Vec_IntSize(vTemp) );
+ }
+ Vec_IntForEachEntry( p->pLib->vMap, Value, i )
+ assert( Value == -1 );
+}
+void Rtl_LibOrderWires( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p; int i;
+ if ( pLib->vMap == NULL )
+ pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ Rtl_NtkOrderWires( p );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ Rtl_LibUpdateInstances( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern int Rtl_NtkCountSignalRange( Rtl_Ntk_t * p, int Sig );
+
+int Rtl_NtkCountWireRange( Rtl_Ntk_t * p, int NameId )
+{
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int Width = Rtl_WireWidth( p, Wire );
+ return Width;
+}
+int Rtl_NtkCountSliceRange( Rtl_Ntk_t * p, int * pSlice )
+{
+ return pSlice[1] - pSlice[2] + 1;
+}
+int Rtl_NtkCountConcatRange( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i, nBits = 0;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ nBits += Rtl_NtkCountSignalRange( p, pConcat[i] );
+ return nBits;
+}
+int Rtl_NtkCountSignalRange( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ return Rtl_NtkCountWireRange( p, Sig >> 2 );
+ if ( Rtl_SigIsSlice(Sig) )
+ return Rtl_NtkCountSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ if ( Rtl_SigIsConcat(Sig) )
+ return Rtl_NtkCountConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ if ( Rtl_SigIsConst(Sig) )
+ assert( 0 );
+ return ABC_INFINITY;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern int Rtl_NtkCheckSignalRange( Rtl_Ntk_t * p, int Sig );
+
+int Rtl_NtkCheckWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right )
+{
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right <= Left && Right >= 0 );
+ for ( i = Right; i <= Left; i++ )
+ if ( Vec_IntEntry(&p->vLits, First+i) == -1 )
+ return 0;
+ return 1;
+}
+int Rtl_NtkCheckSliceRange( Rtl_Ntk_t * p, int * pSlice )
+{
+ return Rtl_NtkCheckWireRange( p, pSlice[0], pSlice[1], pSlice[2] );
+}
+int Rtl_NtkCheckConcatRange( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ if ( !Rtl_NtkCheckSignalRange( p, pConcat[i] ) )
+ return 0;
+ return 1;
+}
+int Rtl_NtkCheckSignalRange( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ return Rtl_NtkCheckWireRange( p, Sig >> 2, -1, -1 );
+ else if ( Rtl_SigIsConst(Sig) )
+ return 1;
+ else if ( Rtl_SigIsSlice(Sig) )
+ return Rtl_NtkCheckSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ else if ( Rtl_SigIsConcat(Sig) )
+ return Rtl_NtkCheckConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ else assert( 0 );
+ return -1;
+}
+
+
+extern void Rtl_NtkSetSignalRange( Rtl_Ntk_t * p, int Sig, int Value );
+
+void Rtl_NtkSetWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int Value )
+{
+ //char * pName = Rtl_NtkStr( p, NameId );
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right <= Left && Right >= 0 );
+ for ( i = Right; i <= Left; i++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+i) == -1 );
+ Vec_IntWriteEntry(&p->vLits, First+i, Value );
+ }
+ //printf( "Finished setting wire %s\n", Rtl_NtkStr(p, NameId) );
+}
+void Rtl_NtkSetSliceRange( Rtl_Ntk_t * p, int * pSlice, int Value )
+{
+ Rtl_NtkSetWireRange( p, pSlice[0], pSlice[1], pSlice[2], Value );
+}
+void Rtl_NtkSetConcatRange( Rtl_Ntk_t * p, int * pConcat, int Value )
+{
+ int i;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ Rtl_NtkSetSignalRange( p, pConcat[i], Value );
+}
+void Rtl_NtkSetSignalRange( Rtl_Ntk_t * p, int Sig, int Value )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ Rtl_NtkSetWireRange( p, Sig >> 2, -1, -1, Value );
+ else if ( Rtl_SigIsSlice(Sig) )
+ Rtl_NtkSetSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), Value );
+ else if ( Rtl_SigIsConcat(Sig) )
+ Rtl_NtkSetConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), Value );
+ else if ( Rtl_SigIsConst(Sig) )
+ assert( 0 );
+}
+
+
+void Rtl_NtkInitInputs( Rtl_Ntk_t * p )
+{
+ int b, i;
+ for ( i = 0; i < p->nInputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, i );
+ int Width = Rtl_WireWidth( p, i );
+ for ( b = 0; b < Width; b++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+b) == -1 );
+ Vec_IntWriteEntry( &p->vLits, First+b, Vec_IntSize(&p->vOrder) );
+ }
+ Vec_IntPush( &p->vOrder, i );
+ //printf( "Finished setting input %s\n", Rtl_WireNameStr(p, i) );
+ }
+}
+Vec_Int_t * Rtl_NtkCollectOutputs( Rtl_Ntk_t * p )
+{
+ //char * pNtkName = Rtl_NtkName(p);
+ int b, i;
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ for ( i = 0; i < p->nOutputs; i++ )
+ {
+ //char * pName = Rtl_WireNameStr(p, p->nInputs + i);
+ int First = Rtl_WireBitStart( p, p->nInputs + i );
+ int Width = Rtl_WireWidth( p, p->nInputs + i );
+ for ( b = 0; b < Width; b++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+b) != -1 );
+ Vec_IntPush( vRes, Vec_IntEntry(&p->vLits, First+b) );
+ }
+ }
+ return vRes;
+}
+int Rtl_NtkReviewCells( Rtl_Ntk_t * p )
+{
+ int i, k, Par, Val, * pCell, RetValue = 0;
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ if ( pCell[7] )
+ continue;
+ Rtl_CellForEachInput( p, pCell, Par, Val, k )
+ if ( !Rtl_NtkCheckSignalRange( p, Val ) )
+ break;
+ if ( k < Rtl_CellInputNum(pCell) )
+ continue;
+ Rtl_CellForEachOutput( p, pCell, Par, Val, k )
+ Rtl_NtkSetSignalRange( p, Val, Vec_IntSize(&p->vOrder) );
+ Vec_IntPush( &p->vOrder, p->nInputs + i );
+ pCell[7] = 1;
+ RetValue = 1;
+ //printf( "Setting cell %s as propagated.\n", Rtl_CellNameStr(p, pCell) );
+ }
+ return RetValue;
+}
+int Rtl_NtkReviewConnections( Rtl_Ntk_t * p )
+{
+ int i, * pCon, RetValue = 0;
+ Rtl_NtkForEachCon( p, pCon, i )
+ {
+ int Status0 = Rtl_NtkCheckSignalRange( p, pCon[0] );
+ int Status1 = Rtl_NtkCheckSignalRange( p, pCon[1] );
+ if ( Status0 == Status1 )
+ continue;
+ if ( !Status0 && Status1 )
+ ABC_SWAP( int, pCon[0], pCon[1] )
+ Rtl_NtkSetSignalRange( p, pCon[1], Vec_IntSize(&p->vOrder) );
+ Vec_IntPush( &p->vOrder, p->nInputs + Rtl_NtkCellNum(p) + i );
+ RetValue = 1;
+ }
+ return RetValue;
+}
+void Rtl_NtkPrintCellOrder( Rtl_Ntk_t * p )
+{
+ int i, iCell;
+ Vec_IntForEachEntry( &p->vOrder, iCell, i )
+ {
+ printf( "%4d : ", i );
+ printf( "Cell %4d ", iCell );
+ if ( iCell < p->nInputs )
+ printf( "Type Input " );
+ else if ( iCell < p->nInputs + Rtl_NtkCellNum(p) )
+ {
+ int * pCell = Rtl_NtkCell( p, iCell - p->nInputs );
+ printf( "Type %4d ", Rtl_CellType(pCell) );
+ printf( "%16s ", Rtl_CellTypeStr(p, pCell) );
+ printf( "%16s ", Rtl_CellNameStr(p, pCell) );
+ }
+ else
+ printf( "Type Connection " );
+ printf( "\n" );
+ }
+}
+void Rtl_NtkPrintUnusedCells( Rtl_Ntk_t * p )
+{
+ int i, * pCell;
+ printf( "\n*** Printing unused cells:\n" );
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ if ( pCell[7] )
+ continue;
+ printf( "Unused cell %s %s\n", Rtl_CellTypeStr(p, pCell), Rtl_CellNameStr(p, pCell) );
+ }
+ printf( "\n" );
+}
+void Rtl_NtkOrderCells( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vRes;
+ int nBits = Rtl_NtkRangeWires( p );
+ Vec_IntFill( &p->vLits, nBits, -1 );
+
+ Vec_IntClear( &p->vOrder );
+ Vec_IntGrow( &p->vOrder, Rtl_NtkObjNum(p) );
+ Rtl_NtkInitInputs( p );
+
+ Rtl_NtkMapWires( p, 0 );
+//Vec_IntPrint(&p->vLits);
+
+ Rtl_NtkReviewConnections( p );
+ while ( Rtl_NtkReviewCells(p) | Rtl_NtkReviewConnections(p) );
+ Rtl_NtkMapWires( p, 1 );
+
+ vRes = Rtl_NtkCollectOutputs( p );
+ Vec_IntFree( vRes );
+
+ //Rtl_NtkPrintCellOrder( p );
+}
+void Rtl_LibOrderCells( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p; int i;
+ if ( pLib->vMap == NULL )
+ pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) );
+ assert( Vec_IntSize(pLib->vMap) == Abc_NamObjNumMax(pLib->pManName) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ Rtl_NtkOrderCells( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_TokenUnspace( char * p )
+{
+ int i, Length = strlen(p), Quote = 0;
+ for ( i = 0; i < Length; i++ )
+ if ( p[i] == '\"' )
+ Quote ^= 1;
+ else if ( Quote && p[i] == ' ' )
+ p[i] = '\"';
+}
+void Rtl_TokenRespace( char * p )
+{
+ int i, Length = strlen(p);
+ assert( p[0] == '\"' && p[Length-1] == '\"' );
+ for ( i = 1; i < Length-1; i++ )
+ if ( p[i] == '\"' )
+ p[i] = ' ';
+}
+Vec_Int_t * Rtl_NtkReadFile( char * pFileName, Abc_Nam_t * p )
+{
+ Vec_Int_t * vTokens;
+ char * pTemp, * pBuffer;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ pBuffer = ABC_ALLOC( char, MAX_LINE );
+ Abc_NamStrFindOrAdd( p, "module", NULL );
+ assert( Abc_NamObjNumMax(p) == 2 );
+ vTokens = Vec_IntAlloc( 1000 );
+ while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL )
+ {
+ if ( pBuffer[0] == '#' )
+ continue;
+ Rtl_TokenUnspace( pBuffer );
+ pTemp = strtok( pBuffer, " \t\r\n" );
+ if ( pTemp == NULL )
+ continue;
+ while ( pTemp )
+ {
+ if ( *pTemp == '\"' ) Rtl_TokenRespace( pTemp );
+ Vec_IntPush( vTokens, Abc_NamStrFindOrAdd(p, pTemp, NULL) );
+ pTemp = strtok( NULL, " \t\r\n" );
+ }
+ Vec_IntPush( vTokens, -1 );
+ }
+ ABC_FREE( pBuffer );
+ fclose( pFile );
+ return vTokens;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern void Rtl_NtkPrintSig( Rtl_Ntk_t * p, int Sig );
+
+void Rtl_NtkPrintConst( Rtl_Ntk_t * p, int * pConst )
+{
+ int i;
+ if ( pConst[0] == -1 )
+ {
+ fprintf( Rtl_NtkFile(p), " %d", pConst[1] );
+ return;
+ }
+ fprintf( Rtl_NtkFile(p), " %d\'", pConst[0] );
+ for ( i = pConst[0] - 1; i >= 0; i-- )
+ fprintf( Rtl_NtkFile(p), "%d", Abc_InfoHasBit((unsigned *)pConst+1,i) );
+}
+void Rtl_NtkPrintSlice( Rtl_Ntk_t * p, int * pSlice )
+{
+ fprintf( Rtl_NtkFile(p), " %s", Rtl_NtkStr(p, pSlice[0]) );
+ if ( pSlice[1] == pSlice[2] )
+ fprintf( Rtl_NtkFile(p), " [%d]", pSlice[1] );
+ else
+ fprintf( Rtl_NtkFile(p), " [%d:%d]", pSlice[1], pSlice[2] );
+}
+void Rtl_NtkPrintConcat( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i;
+ fprintf( Rtl_NtkFile(p), " {" );
+ for ( i = 1; i <= pConcat[0]; i++ )
+ Rtl_NtkPrintSig( p, pConcat[i] );
+ fprintf( Rtl_NtkFile(p), " }" );
+}
+void Rtl_NtkPrintSig( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ fprintf( Rtl_NtkFile(p), " %s", Rtl_NtkStr(p, Sig >> 2) );
+ else if ( Rtl_SigIsConst(Sig) )
+ Rtl_NtkPrintConst( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) );
+ else if ( Rtl_SigIsSlice(Sig) )
+ Rtl_NtkPrintSlice( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ else if ( Rtl_SigIsConcat(Sig) )
+ Rtl_NtkPrintConcat( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ else assert( 0 );
+}
+void Rtl_NtkPrintWire( Rtl_Ntk_t * p, int * pWire )
+{
+ fprintf( Rtl_NtkFile(p), " wire" );
+ if ( pWire[1] != 1 ) fprintf( Rtl_NtkFile(p), " width %d", pWire[1] );
+ if ( pWire[2] != 0 ) fprintf( Rtl_NtkFile(p), " offset %d", pWire[2] );
+ if ( pWire[0] & 8 ) fprintf( Rtl_NtkFile(p), " upto" );
+ if ( pWire[0] & 1 ) fprintf( Rtl_NtkFile(p), " input %d", pWire[3] );
+ if ( pWire[0] & 2 ) fprintf( Rtl_NtkFile(p), " output %d", pWire[3] );
+ if ( pWire[0] & 4 ) fprintf( Rtl_NtkFile(p), " signed" );
+ fprintf( Rtl_NtkFile(p), " %s\n", Rtl_NtkStr(p, pWire[0] >> 4) );
+}
+void Rtl_NtkPrintCell( Rtl_Ntk_t * p, int * pCell )
+{
+ int i, Par, Val;
+ Rtl_CellForEachAttr( p, pCell, Par, Val, i )
+ fprintf( Rtl_NtkFile(p), " attribute %s %s\n", Rtl_NtkStr(p, Par), Rtl_NtkStr(p, Val) );
+ fprintf( Rtl_NtkFile(p), " cell %s %s\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkStr(p, pCell[1]) );
+ Rtl_CellForEachParam( p, pCell, Par, Val, i )
+ fprintf( Rtl_NtkFile(p), " parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" );
+ Rtl_CellForEachConnect( p, pCell, Par, Val, i )
+ fprintf( Rtl_NtkFile(p), " connect" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" );
+ fprintf( Rtl_NtkFile(p), " end\n" );
+}
+void Rtl_NtkPrintConnection( Rtl_Ntk_t * p, int * pCon )
+{
+ fprintf( Rtl_NtkFile(p), " connect" );
+ Rtl_NtkPrintSig( p, pCon[0] );
+ Rtl_NtkPrintSig( p, pCon[1] );
+ fprintf( Rtl_NtkFile(p), "\n" );
+}
+void Rtl_NtkPrint( Rtl_Ntk_t * p )
+{
+ int i, Par, Val, * pWire, * pCell, * pCon;
+ fprintf( Rtl_NtkFile(p), "\n" );
+ Rtl_NtkForEachAttr( p, Par, Val, i )
+ fprintf( Rtl_NtkFile(p), "attribute %s %s\n", Rtl_NtkStr(p, Par), Rtl_NtkStr(p, Val) );
+ fprintf( Rtl_NtkFile(p), "module %s\n", Rtl_NtkName(p) );
+ Rtl_NtkForEachWire( p, pWire, i )
+ Rtl_NtkPrintWire( p, pWire );
+ Rtl_NtkForEachCell( p, pCell, i )
+ Rtl_NtkPrintCell( p, pCell );
+ Rtl_NtkForEachCon( p, pCon, i )
+ Rtl_NtkPrintConnection( p, pCon );
+ fprintf( Rtl_NtkFile(p), "end\n" );
+}
+void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p )
+{
+ p->pFile = pFileName ? fopen( pFileName, "wb" ) : stdout;
+ if ( p->pFile == NULL )
+ {
+ printf( "Cannot open output file \"%s\".\n", pFileName );
+ return;
+ }
+ else
+ {
+ Rtl_Ntk_t * pNtk; int i;
+ fprintf( p->pFile, "\n" );
+ fprintf( p->pFile, "# Generated by ABC on %s\n", Extra_TimeStamp() );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkPrint( pNtk );
+ if ( p->pFile != stdout )
+ fclose( p->pFile );
+ p->pFile = NULL;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern int Rtl_NtkReadSig( Rtl_Ntk_t * p, int * pPos );
+
+int Rtl_NtkReadConst( Rtl_Ntk_t * p, char * pConst )
+{
+ Vec_Int_t * vConst = &p->pLib->vConsts;
+ int RetVal = Vec_IntSize( vConst );
+ int Width = atoi( pConst );
+ assert( pConst[0] >= '0' && pConst[0] <= '9' );
+ if ( strstr(pConst, "\'") )
+ {
+ int Length = strlen(pConst);
+ int nWords = (Width + 31) / 32;
+ int i, * pArray;
+ Vec_IntPush( vConst, Width );
+ Vec_IntFillExtra( vConst, Vec_IntSize(vConst) + nWords, 0 );
+ pArray = Vec_IntEntryP( vConst, RetVal + 1 );
+ for ( i = Length-1; i >= Length-Width; i-- )
+ if ( pConst[i] == '1' )
+ Abc_InfoSetBit( (unsigned *)pArray, Length-1-i );
+ }
+ else
+ {
+ Vec_IntPush( vConst, -1 );
+ Vec_IntPush( vConst, Width );
+ }
+ return (RetVal << 2) | 1;
+}
+int Rtl_NtkReadSlice( Rtl_Ntk_t * p, char * pSlice, int NameId )
+{
+ Vec_Int_t * vSlice = &p->pLib->vSlices;
+ int RetVal = Vec_IntSize( vSlice );
+ int Left = atoi( pSlice+1 );
+ char * pTwo = strstr( pSlice, ":" );
+ int Right = pTwo ? atoi( pTwo+1 ) : Left;
+ assert( pSlice[0] == '[' && pSlice[strlen(pSlice)-1] == ']' );
+ Vec_IntPush( vSlice, NameId );
+ Vec_IntPush( vSlice, Left );
+ Vec_IntPush( vSlice, Right );
+ return (RetVal << 2) | 2;
+}
+int Rtl_NtkReadConcat( Rtl_Ntk_t * p, int * pPos )
+{
+ Vec_Int_t * vConcat = &p->pLib->vConcats;
+ int RetVal = Vec_IntSize( vConcat ); char * pTok;
+ Vec_IntPush( vConcat, ABC_INFINITY );
+ do {
+ int Sig = Rtl_NtkReadSig( p, pPos );
+ Vec_IntPush( vConcat, Sig );
+ pTok = Rtl_NtkTokStr( p, *pPos );
+ }
+ while ( pTok[0] != '}' );
+ Vec_IntWriteEntry( vConcat, RetVal, Vec_IntSize(vConcat) - RetVal - 1 );
+ assert( pTok[0] == '}' );
+ (*pPos)++;
+ return (RetVal << 2) | 3;
+}
+int Rtl_NtkReadSig( Rtl_Ntk_t * p, int * pPos )
+{
+ int NameId = Rtl_NtkTokId( p, *pPos );
+ char * pSig = Rtl_NtkTokStr( p, (*pPos)++ );
+ if ( pSig[0] >= '0' && pSig[0] <= '9' )
+ return Rtl_NtkReadConst( p, pSig );
+ if ( pSig[0] == '{' )
+ return Rtl_NtkReadConcat( p, pPos );
+ else
+ {
+ char * pNext = Rtl_NtkTokStr( p, *pPos );
+ if ( pNext && pNext[0] == '[' )
+ {
+ (*pPos)++;
+ return Rtl_NtkReadSlice( p, pNext, NameId );
+ }
+ else
+ return NameId << 2;
+ }
+}
+int Rtl_NtkReadWire( Rtl_Ntk_t * p, int iPos )
+{
+ int i, Entry, Prev = -1;
+ int Width = 1, Upto = 0, Offset = 0, Out = 0, In = 0, Number = 0, Signed = 0;
+ assert( Rtl_NtkPosCheck(p, iPos-1, RTL_WIRE) );
+ Vec_IntClear( &p->pLib->vAttrTemp );
+ Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos )
+ {
+ //char * pTok = Rtl_NtkTokStr(p, i);
+ if ( Entry == -1 )
+ break;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_WIDTH) )
+ Width = atoi( Rtl_NtkTokStr(p, ++i) );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_OFFSET) )
+ Offset = atoi( Rtl_NtkTokStr(p, ++i) );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_INPUT) )
+ Number = atoi( Rtl_NtkTokStr(p, ++i) ), In = 1, p->nInputs++;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_OUTPUT) )
+ Number = atoi( Rtl_NtkTokStr(p, ++i) ), Out = 1, p->nOutputs++;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_SIGNED) )
+ Signed = 1;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_UPTO) )
+ Upto = 1;
+ Prev = Entry;
+ }
+ // add WIRE_NUM=5 entries
+ Vec_IntPush( &p->vWires, (Prev << 4) | (Upto << 3) | (Signed << 2) | (Out << 1) | (In << 0) );
+ Vec_IntPush( &p->vWires, Width );
+ Vec_IntPush( &p->vWires, Offset );
+ Vec_IntPush( &p->vWires, Number );
+ Vec_IntPush( &p->vWires, -1 );
+ assert( Rtl_NtkPosCheck(p, i, RTL_NONE) );
+ return i;
+}
+int Rtl_NtkReadAttribute( Rtl_Ntk_t * p, int iPos )
+{
+//char * pTok1 = Rtl_NtkTokStr(p, iPos-1);
+//char * pTok2 = Rtl_NtkTokStr(p, iPos);
+//char * pTok3 = Rtl_NtkTokStr(p, iPos+1);
+ assert( Rtl_NtkPosCheck(p, iPos-1, RTL_ATTRIBUTE) );
+ Vec_IntPush( &p->pLib->vAttrTemp, Rtl_NtkTokId(p, iPos++) );
+ Vec_IntPush( &p->pLib->vAttrTemp, Rtl_NtkTokId(p, iPos++) );
+ assert( Rtl_NtkPosCheck(p, iPos, RTL_NONE) );
+ return iPos;
+}
+int Rtl_NtkReadAttribute2( Rtl_Lib_t * p, int iPos )
+{
+//char * pTok1 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos-1));
+//char * pTok2 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos) );
+//char * pTok3 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos+1));
+ assert( Vec_IntEntry(p->vTokens, iPos-1) == p->pMap[RTL_ATTRIBUTE] );
+ Vec_IntPush( &p->vAttrTemp, Vec_IntEntry(p->vTokens, iPos++) );
+ Vec_IntPush( &p->vAttrTemp, Vec_IntEntry(p->vTokens, iPos++) );
+ assert( Vec_IntEntry(p->vTokens, iPos) == p->pMap[RTL_NONE] );
+ return iPos;
+}
+int Rtl_NtkReadConnect( Rtl_Ntk_t * p, int iPos )
+{
+//char * pTok1 = Rtl_NtkTokStr(p, iPos-1);
+//char * pTok2 = Rtl_NtkTokStr(p, iPos);
+//char * pTok3 = Rtl_NtkTokStr(p, iPos+1);
+ assert( Rtl_NtkPosCheck(p, iPos-1, RTL_CONNECT) );
+ Vec_IntPush( &p->vConns, Rtl_NtkReadSig(p, &iPos) );
+ Vec_IntPush( &p->vConns, Rtl_NtkReadSig(p, &iPos) );
+ assert( Rtl_NtkPosCheck(p, iPos, RTL_NONE) );
+ return iPos;
+}
+int Rtl_NtkReadCell( Rtl_Ntk_t * p, int iPos )
+{
+ Vec_Int_t * vAttrs = &p->pLib->vAttrTemp;
+ int iPosPars, iPosCons, Par, Val, i, Entry;
+ assert( Rtl_NtkPosCheck(p, iPos-1, RTL_CELL) );
+ Vec_IntPush( &p->vCells, Vec_IntSize(&p->vStore) );
+ Vec_IntPush( &p->vStore, Rtl_NtkTokId(p, iPos++) ); // 0
+ Vec_IntPush( &p->vStore, Rtl_NtkTokId(p, iPos++) ); // 1
+ Vec_IntPush( &p->vStore, -1 );
+ Vec_IntPush( &p->vStore, -1 );
+ assert( Vec_IntSize(vAttrs) % 2 == 0 );
+ Vec_IntPush( &p->vStore, Vec_IntSize(vAttrs)/2 );
+ iPosPars = Vec_IntSize(&p->vStore);
+ Vec_IntPush( &p->vStore, 0 ); // 5
+ iPosCons = Vec_IntSize(&p->vStore);
+ Vec_IntPush( &p->vStore, 0 ); // 6
+ Vec_IntPush( &p->vStore, 0 ); // 7
+ assert( Vec_IntSize(&p->vStore) == Vec_IntEntryLast(&p->vCells)+CELL_NUM );
+ Vec_IntAppend( &p->vStore, vAttrs );
+ Vec_IntClear( vAttrs );
+ Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos )
+ {
+ if ( Rtl_NtkTokCheck(p, Entry, RTL_END) )
+ break;
+ if ( Rtl_NtkTokCheck(p, Entry, RTL_PARAMETER) || Rtl_NtkTokCheck(p, Entry, RTL_CONNECT) )
+ {
+ int iPosCount = Rtl_NtkTokCheck(p, Entry, RTL_PARAMETER) ? iPosPars : iPosCons;
+ Vec_IntAddToEntry( &p->vStore, iPosCount, 1 );
+ i++;
+ Par = Rtl_NtkReadSig(p, &i);
+ Val = Rtl_NtkReadSig(p, &i);
+ Vec_IntPushTwo( &p->vStore, Par, Val );
+ }
+ assert( Rtl_NtkPosCheck(p, i, RTL_NONE) );
+ }
+ assert( Rtl_NtkPosCheck(p, i, RTL_END) );
+ i++;
+ assert( Rtl_NtkPosCheck(p, i, RTL_NONE) );
+ return i;
+}
+int Wln_ReadMatchEnd( Rtl_Ntk_t * p, int Mod )
+{
+ int i, Entry, Count = 0;
+ Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, Mod )
+ if ( Rtl_NtkTokCheck(p, Entry, RTL_CELL) )
+ Count++;
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_END) )
+ {
+ if ( Count == 0 )
+ return i;
+ Count--;
+ }
+ assert( 0 );
+ return -1;
+}
+int Rtl_NtkReadNtk( Rtl_Lib_t * pLib, int Mod )
+{
+ Rtl_Ntk_t * p = Rtl_NtkAlloc( pLib );
+ Vec_Int_t * vAttrs = &p->pLib->vAttrTemp;
+ int End = Wln_ReadMatchEnd( p, Mod ), i, Entry;
+ assert( Rtl_NtkPosCheck(p, Mod-1, RTL_MODULE) );
+ assert( Rtl_NtkPosCheck(p, End, RTL_END) );
+ p->NameId = Rtl_NtkTokId( p, Mod );
+ p->Slice0 = Vec_IntSize( &pLib->vSlices );
+ Vec_IntAppend( &p->vAttrs, vAttrs );
+ Vec_IntClear( vAttrs );
+ Vec_IntForEachEntryStartStop( pLib->vTokens, Entry, i, Mod, End )
+ {
+ if ( Rtl_NtkTokCheck(p, Entry, RTL_WIRE) )
+ i = Rtl_NtkReadWire( p, i+1 );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_ATTRIBUTE) )
+ i = Rtl_NtkReadAttribute( p, i+1 );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_CELL) )
+ i = Rtl_NtkReadCell( p, i+1 );
+ else if ( Rtl_NtkTokCheck(p, Entry, RTL_CONNECT) )
+ i = Rtl_NtkReadConnect( p, i+1 );
+ }
+ p->Slice1 = Vec_IntSize( &pLib->vSlices );
+ assert( Vec_IntSize(&p->vWires) % WIRE_NUM == 0 );
+ return End;
+}
+void Rtl_NtkReportUndefs( Rtl_Ntk_t * p )
+{
+ Vec_Int_t * vNames, * vCounts;
+ int i, iName, * pCell;
+ vNames = Vec_IntAlloc( 10 );
+ vCounts = Vec_IntAlloc( 10 );
+ Rtl_NtkForEachCell( p, pCell, i )
+ if ( Rtl_CellModule(pCell) == ABC_INFINITY-1 )
+ {
+ iName = Vec_IntFind(vNames, Rtl_CellType(pCell));
+ if ( iName == -1 )
+ {
+ iName = Vec_IntSize(vNames);
+ Vec_IntPush( vNames, Rtl_CellType(pCell) );
+ Vec_IntPush( vCounts, 0 );
+ }
+ Vec_IntAddToEntry( vCounts, iName, 1 );
+ }
+ Vec_IntForEachEntry( vNames, iName, i )
+ printf( " %s (%d)", Rtl_NtkStr(p, iName), Vec_IntEntry(vCounts, i) );
+ printf( "\n" );
+ Vec_IntFree( vNames );
+ Vec_IntFree( vCounts );
+}
+int Rtl_NtkSetParents( Rtl_Ntk_t * p )
+{
+ int i, * pCell, nUndef = 0;
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ pCell[2] = Rtl_NtkReadType( p, Rtl_CellType(pCell) );
+ if ( Rtl_CellModule(pCell) == ABC_INFINITY-1 )
+ nUndef++;
+ else
+ pCell[3] = Rtl_CellModule(pCell) < ABC_INFINITY ? pCell[6]-1 : Rtl_NtkModule(p, Rtl_CellModule(pCell)-ABC_INFINITY)->nInputs;
+ }
+ if ( !nUndef )
+ return 0;
+ printf( "Module \"%s\" has %d blackbox instances: ", Rtl_NtkName(p), nUndef );
+ Rtl_NtkReportUndefs( p );
+ return nUndef;
+}
+void Rtl_LibSetParents( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkSetParents( pNtk );
+}
+void Rtl_LibReorderModules_rec( Rtl_Ntk_t * p, Vec_Ptr_t * vNew )
+{
+ int i, * pCell;
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell );
+ if ( pMod && pMod->iCopy == -1 )
+ Rtl_LibReorderModules_rec( pMod, vNew );
+ }
+ assert( p->iCopy == -1 );
+ p->iCopy = Vec_PtrSize(vNew);
+ Vec_PtrPush( vNew, p );
+}
+void Rtl_NtkUpdateBoxes( Rtl_Ntk_t * p )
+{
+ int i, * pCell;
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell );
+ if ( pMod && pMod->iCopy >= 0 )
+ pCell[2] = ABC_INFINITY + pMod->iCopy;
+ }
+}
+void Rtl_LibUpdateBoxes( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Rtl_NtkUpdateBoxes( pNtk );
+}
+void Rtl_LibReorderModules( Rtl_Lib_t * p )
+{
+ Vec_Ptr_t * vNew = Vec_PtrAlloc( Vec_PtrSize(p->vNtks) );
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ if ( pNtk->iCopy == -1 )
+ Rtl_LibReorderModules_rec( pNtk, vNew );
+ assert( Vec_PtrSize(p->vNtks) == Vec_PtrSize(vNew) );
+ Rtl_LibUpdateBoxes( p );
+ Vec_PtrClear( p->vNtks );
+ Vec_PtrAppend( p->vNtks, vNew );
+ Vec_PtrFree( vNew );
+}
+Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec )
+{
+ Rtl_Lib_t * p = Rtl_LibAlloc(); int i, Entry;
+ p->pSpec = Abc_UtilStrsav( pFileSpec );
+ p->pManName = Abc_NamStart( 1000, 50 );
+ p->vTokens = Rtl_NtkReadFile( pFileName, p->pManName );
+ Rtl_LibDeriveMap( p );
+ Vec_IntClear( &p->vAttrTemp );
+ Vec_IntForEachEntry( p->vTokens, Entry, i )
+ if ( Entry == p->pMap[RTL_MODULE] )
+ i = Rtl_NtkReadNtk( p, i+1 );
+ else if ( Entry == p->pMap[RTL_ATTRIBUTE] )
+ i = Rtl_NtkReadAttribute2( p, i+1 );
+ Rtl_LibSetParents( p );
+ Rtl_LibReorderModules( p );
+ Rtl_LibOrderWires( p );
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern int Rtl_NtkMapSignalRange( Rtl_Ntk_t * p, int Sig, int iCell, int iBit );
+
+int Rtl_NtkMapWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int iCell, int iBit )
+{
+ //char * pName = Rtl_NtkStr( p, NameId );
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right >= 0 && Right <= Left );
+ for ( i = Right; i <= Left; i++ )
+ {
+ assert( Vec_IntEntry(&p->vDrivers, 2*(First+i)) == -4 );
+ Vec_IntWriteEntry(&p->vDrivers, 2*(First+i)+0, iCell );
+ Vec_IntWriteEntry(&p->vDrivers, 2*(First+i)+1, iBit + (i - Right) );
+ }
+ return Left - Right + 1;
+}
+int Rtl_NtkMapSliceRange( Rtl_Ntk_t * p, int * pSlice, int iCell, int iBit )
+{
+ return Rtl_NtkMapWireRange( p, pSlice[0], pSlice[1], pSlice[2], iCell, iBit );
+}
+int Rtl_NtkMapConcatRange( Rtl_Ntk_t * p, int * pConcat, int iCell, int iBit )
+{
+ int i, k = 0;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ k += Rtl_NtkMapSignalRange( p, pConcat[i], iCell, iBit+k );
+ return k;
+}
+int Rtl_NtkMapSignalRange( Rtl_Ntk_t * p, int Sig, int iCell, int iBit )
+{
+ int nBits = ABC_INFINITY;
+ if ( Rtl_SigIsNone(Sig) )
+ nBits = Rtl_NtkMapWireRange( p, Sig >> 2, -1, -1, iCell, iBit );
+ if ( Rtl_SigIsSlice(Sig) )
+ nBits = Rtl_NtkMapSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), iCell, iBit );
+ if ( Rtl_SigIsConcat(Sig) )
+ nBits = Rtl_NtkMapConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), iCell, iBit );
+ if ( Rtl_SigIsConst(Sig) )
+ assert( 0 );
+ return nBits;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern void Rtl_NtkCollectSignalInfo( Rtl_Ntk_t * p, int Sig );
+
+void Rtl_NtkCollectWireInfo( Rtl_Ntk_t * p, int NameId, int Left, int Right )
+{
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right >= 0 && Right <= Left );
+ for ( i = Right; i <= Left; i++ )
+ Vec_IntPush( &p->vBitTemp, First+i );
+}
+void Rtl_NtkCollectConstInfo( Rtl_Ntk_t * p, int * pConst )
+{
+ int i, nLimit = pConst[0];
+ if ( nLimit == -1 )
+ nLimit = 32;
+ for ( i = 0; i < nLimit; i++ )
+ Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit((unsigned *)pConst+1,i)-CONST_SHIFT );
+}
+void Rtl_NtkCollectSliceInfo( Rtl_Ntk_t * p, int * pSlice )
+{
+ Rtl_NtkCollectWireInfo( p, pSlice[0], pSlice[1], pSlice[2] );
+}
+void Rtl_NtkCollectConcatInfo( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i;
+ for ( i = pConcat[0]; i >= 1; i-- )
+ Rtl_NtkCollectSignalInfo( p, pConcat[i] );
+}
+void Rtl_NtkCollectSignalInfo( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ Rtl_NtkCollectWireInfo( p, Sig >> 2, -1, -1 );
+ else if ( Rtl_SigIsConst(Sig) )
+ Rtl_NtkCollectConstInfo( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) );
+ else if ( Rtl_SigIsSlice(Sig) )
+ Rtl_NtkCollectSliceInfo( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ else if ( Rtl_SigIsConcat(Sig) )
+ Rtl_NtkCollectConcatInfo( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ else assert( 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+extern void Rtl_NtkCollectSignalRange( Rtl_Ntk_t * p, int Sig );
+
+void Rtl_NtkCollectWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right )
+{
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right >= 0 && Right <= Left );
+ for ( i = Right; i <= Left; i++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+i) != -1 );
+ Vec_IntPush( &p->vBitTemp, Vec_IntEntry(&p->vLits, First+i) );
+ }
+}
+void Rtl_NtkCollectConstRange( Rtl_Ntk_t * p, int * pConst )
+{
+ int i, nLimit = pConst[0];
+ if ( nLimit == -1 )
+ nLimit = 32;
+ for ( i = 0; i < nLimit; i++ )
+ Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit((unsigned *)pConst+1,i) );
+}
+void Rtl_NtkCollectSliceRange( Rtl_Ntk_t * p, int * pSlice )
+{
+ Rtl_NtkCollectWireRange( p, pSlice[0], pSlice[1], pSlice[2] );
+}
+void Rtl_NtkCollectConcatRange( Rtl_Ntk_t * p, int * pConcat )
+{
+ int i;
+ for ( i = pConcat[0]; i >= 1; i-- )
+ Rtl_NtkCollectSignalRange( p, pConcat[i] );
+}
+void Rtl_NtkCollectSignalRange( Rtl_Ntk_t * p, int Sig )
+{
+ if ( Rtl_SigIsNone(Sig) )
+ Rtl_NtkCollectWireRange( p, Sig >> 2, -1, -1 );
+ else if ( Rtl_SigIsConst(Sig) )
+ Rtl_NtkCollectConstRange( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) );
+ else if ( Rtl_SigIsSlice(Sig) )
+ Rtl_NtkCollectSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) );
+ else if ( Rtl_SigIsConcat(Sig) )
+ Rtl_NtkCollectConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) );
+ else assert( 0 );
+}
+
+
+extern int Rtl_NtkInsertSignalRange( Rtl_Ntk_t * p, int Sig, int * pLits, int nLits );
+
+int Rtl_NtkInsertWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int * pLits, int nLits )
+{
+ //char * pName = Rtl_NtkStr( p, NameId );
+ int Wire = Rtl_WireMapNameToId( p, NameId );
+ int First = Rtl_WireBitStart( p, Wire );
+ int Width = Rtl_WireWidth( p, Wire ), i, k = 0;
+ Left = Left == -1 ? Width-1 : Left;
+ Right = Right == -1 ? 0 : Right;
+ assert ( Right >= 0 && Right <= Left );
+ for ( i = Right; i <= Left; i++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+i) == -1 );
+ Vec_IntWriteEntry(&p->vLits, First+i, pLits[k++] );
+ }
+ assert( k <= nLits );
+ return k;
+}
+int Rtl_NtkInsertSliceRange( Rtl_Ntk_t * p, int * pSlice, int * pLits, int nLits )
+{
+ return Rtl_NtkInsertWireRange( p, pSlice[0], pSlice[1], pSlice[2], pLits, nLits );
+}
+int Rtl_NtkInsertConcatRange( Rtl_Ntk_t * p, int * pConcat, int * pLits, int nLits )
+{
+ int i, k = 0;
+ for ( i = 1; i <= pConcat[0]; i++ )
+ k += Rtl_NtkInsertSignalRange( p, pConcat[i], pLits+k, nLits-k );
+ assert( k <= nLits );
+ return k;
+}
+int Rtl_NtkInsertSignalRange( Rtl_Ntk_t * p, int Sig, int * pLits, int nLits )
+{
+ int nBits = ABC_INFINITY;
+ if ( Rtl_SigIsNone(Sig) )
+ nBits = Rtl_NtkInsertWireRange( p, Sig >> 2, -1, -1, pLits, nLits );
+ if ( Rtl_SigIsSlice(Sig) )
+ nBits = Rtl_NtkInsertSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), pLits, nLits );
+ if ( Rtl_SigIsConcat(Sig) )
+ nBits = Rtl_NtkInsertConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), pLits, nLits );
+ if ( Rtl_SigIsConst(Sig) )
+ assert( 0 );
+ assert( nBits == nLits );
+ return nBits;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_NtkBlastInputs( Gia_Man_t * pNew, Rtl_Ntk_t * p )
+{
+ int b, i;
+ for ( i = 0; i < p->nInputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, i );
+ int Width = Rtl_WireWidth( p, i );
+ for ( b = 0; b < Width; b++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+b) == -1 );
+ Vec_IntWriteEntry( &p->vLits, First+b, Gia_ManAppendCi(pNew) );
+ }
+ }
+}
+void Rtl_NtkBlastOutputs( Gia_Man_t * pNew, Rtl_Ntk_t * p )
+{
+ int b, i;
+ for ( i = 0; i < p->nOutputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, p->nInputs + i );
+ int Width = Rtl_WireWidth( p, p->nInputs + i );
+ for ( b = 0; b < Width; b++ )
+ {
+ assert( Vec_IntEntry(&p->vLits, First+b) != -1 );
+ Gia_ManAppendCo( pNew, Vec_IntEntry(&p->vLits, First+b) );
+ }
+ }
+}
+void Rtl_NtkBlastConnect( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCon )
+{
+ int nBits;
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalRange( p, pCon[0] );
+ nBits = Rtl_NtkInsertSignalRange( p, pCon[1], Vec_IntArray(&p->vBitTemp), Vec_IntSize(&p->vBitTemp) );
+ assert( nBits == Vec_IntSize(&p->vBitTemp) );
+ //printf( "Finished blasting connection (Value = %d).\n", Vec_IntEntry(&p->vBitTemp, 0) );
+}
+void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell )
+{
+ extern Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p );
+ extern void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits );
+ Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY );
+ int k, Par, Val, nBits = 0;
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_CellForEachInput( p, pCell, Par, Val, k )
+ Rtl_NtkCollectSignalRange( p, Val );
+// if ( pModel->pGia == NULL )
+// pModel->pGia = Rtl_NtkBlast( pModel );
+ assert( pModel->pGia );
+ Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp );
+ Rtl_CellForEachOutput( p, pCell, Par, Val, k )
+ nBits += Rtl_NtkInsertSignalRange( p, Val, Vec_IntArray(&p->vBitTemp)+nBits, Vec_IntSize(&p->vBitTemp)-nBits );
+ assert( nBits == Vec_IntSize(&p->vBitTemp) );
+}
+
+int Rtl_NtkCellParamValue( Rtl_Ntk_t * p, int * pCell, char * pParam )
+{
+ int ParamId = Rtl_NtkStrId( p, pParam );
+ int i, Par, Val, ValOut = ABC_INFINITY, * pConst;
+// p->pLib->pFile = stdout;
+// Rtl_CellForEachParam( p, pCell, Par, Val, i )
+// fprintf( Rtl_NtkFile(p), " parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" );
+ Rtl_CellForEachParam( p, pCell, Par, Val, i )
+ if ( (Par >> 2) == ParamId )
+ {
+ assert( Rtl_SigIsConst(Val) );
+ pConst = Vec_IntEntryP( &p->pLib->vConsts, Val >> 2 );
+ assert( pConst[0] < 32 );
+ ValOut = pConst[1];
+ }
+ return ValOut;
+}
+void Rtl_NtkBlastOperator( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell )
+{
+ extern void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 );
+ Vec_Int_t * vRes = &p->pLib->vTemp[3];
+ int i, Par, Val, ValOut = -1, nBits = 0, nRange = -1;
+ int fSign0 = Rtl_NtkCellParamValue( p, pCell, "\\A_SIGNED" );
+ int fSign1 = Rtl_NtkCellParamValue( p, pCell, "\\B_SIGNED" );
+ Rtl_CellForEachOutput( p, pCell, Par, ValOut, i )
+ nRange = Rtl_NtkCountSignalRange( p, ValOut );
+ assert( nRange > 0 );
+ for ( i = 0; i < TEMP_NUM; i++ )
+ Vec_IntClear( &p->pLib->vTemp[i] );
+ //printf( "Starting blasting cell %s.\n", Rtl_CellNameStr(p, pCell) );
+ Rtl_CellForEachInput( p, pCell, Par, Val, i )
+ {
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalRange( p, Val );
+ Vec_IntAppend( &p->pLib->vTemp[i], &p->vBitTemp );
+ }
+ Rtl_NtkBlastNode( pNew, Rtl_CellModule(pCell), Rtl_CellInputNum(pCell), p->pLib->vTemp, nRange, fSign0, fSign1 );
+ assert( Vec_IntSize(vRes) > 0 );
+ nBits = Rtl_NtkInsertSignalRange( p, ValOut, Vec_IntArray(vRes)+nBits, Vec_IntSize(vRes)-nBits );
+ assert( nBits == Vec_IntSize(vRes) );
+ //printf( "Finished blasting cell %s (Value = %d).\n", Rtl_CellNameStr(p, pCell), Vec_IntEntry(vRes, 0) );
+}
+char * Rtl_ShortenName( char * pName, int nSize )
+{
+ static char Buffer[1000];
+ if ( (int)strlen(pName) <= nSize )
+ return pName;
+ Buffer[0] = 0;
+ strcat( Buffer, pName );
+ //Buffer[nSize-4] = ' ';
+ Buffer[nSize-3] = '.';
+ Buffer[nSize-2] = '.';
+ Buffer[nSize-1] = '.';
+ Buffer[nSize-0] = 0;
+ return Buffer;
+}
+Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p )
+{
+ Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 );
+ int i, iObj, * pCell, nBits = Rtl_NtkRangeWires( p );
+ char Buffer[100]; static int counter = 0;
+ Vec_IntFill( &p->vLits, nBits, -1 );
+ Rtl_NtkMapWires( p, 0 );
+ Rtl_NtkBlastInputs( pNew, p );
+ Gia_ManHashAlloc( pNew );
+ Vec_IntForEachEntry( &p->vOrder, iObj, i )
+ {
+ iObj -= Rtl_NtkInputNum(p);
+ if ( iObj < 0 )
+ continue;
+ if ( iObj >= Rtl_NtkCellNum(p) )
+ {
+ Rtl_NtkBlastConnect( pNew, p, Rtl_NtkCon(p, iObj - Rtl_NtkCellNum(p)) );
+ continue;
+ }
+ pCell = Rtl_NtkCell(p, iObj);
+ if ( Rtl_CellModule(pCell) >= ABC_INFINITY )
+ Rtl_NtkBlastHierarchy( pNew, p, pCell );
+ else if ( Rtl_CellModule(pCell) < ABC_OPER_LAST )
+ Rtl_NtkBlastOperator( pNew, p, pCell );
+ else
+ printf( "Cannot blast black box %s in module %s.\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkName(p) );
+ }
+ Gia_ManHashStop( pNew );
+ Rtl_NtkBlastOutputs( pNew, p );
+ Rtl_NtkMapWires( p, 1 );
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+
+sprintf( Buffer, "old%02d.aig", counter++ );
+Gia_AigerWrite( pNew, Buffer, 0, 0, 0 );
+printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) );
+Gia_ManPrintStats( pNew, NULL );
+ return pNew;
+}
+void Rtl_LibBlast( Rtl_Lib_t * pLib )
+{
+ Rtl_Ntk_t * p; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ if ( p->pGia == NULL )
+ p->pGia = Rtl_NtkBlast( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// -4 unassigned
+// -3 other bit
+// -2 constant
+// -1 primary input
+// 0+ cell
+int Rtl_NtkBlastCons( Rtl_Ntk_t * p )
+{
+ int c, i, iBit0, iBit1, * pCon, * pDri0, * pDri1, nChanges = 0;
+ Rtl_NtkForEachCon( p, pCon, c )
+ {
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalInfo( p, pCon[1] );
+ Vec_IntClearAppend( &p->vBitTemp2, &p->vBitTemp );
+
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalInfo( p, pCon[0] );
+ assert( Vec_IntSize(&p->vBitTemp2) == Vec_IntSize(&p->vBitTemp) );
+
+ Vec_IntForEachEntryTwo( &p->vBitTemp, &p->vBitTemp2, iBit0, iBit1, i )
+ {
+ pDri0 = iBit0 >= 0 ? Vec_IntEntryP(&p->vDrivers, 2*iBit0) : NULL;
+ pDri1 = iBit1 >= 0 ? Vec_IntEntryP(&p->vDrivers, 2*iBit1) : NULL;
+ assert( iBit0 >= 0 || iBit1 >= 0 );
+ if ( iBit0 < 0 )
+ {
+ if ( pDri1[0] == -4 )
+ {
+ assert( pDri1[1] == -4 );
+ pDri1[0] = -2;
+ pDri1[1] = iBit0+CONST_SHIFT;
+ nChanges++;
+ }
+ continue;
+ }
+ if ( iBit1 < 0 )
+ {
+ if ( pDri0[0] == -4 )
+ {
+ assert( pDri0[1] == -4 );
+ pDri0[0] = -2;
+ pDri0[1] = iBit1+CONST_SHIFT;
+ nChanges++;
+ }
+ continue;
+ }
+ if ( pDri0[0] == -4 && pDri1[0] != -4 )
+ {
+ assert( pDri0[1] == -4 );
+ pDri0[0] = -3;
+ pDri0[1] = iBit1;
+ nChanges++;
+ continue;
+ }
+ if ( pDri1[0] == -4 && pDri0[0] != -4 )
+ {
+ assert( pDri1[1] == -4 );
+ pDri1[0] = -3;
+ pDri1[1] = iBit0;
+ nChanges++;
+ continue;
+ }
+ }
+ }
+ //printf( "Changes %d\n", nChanges );
+ return nChanges;
+}
+void Rtl_NtkBlastMap( Rtl_Ntk_t * p, int nBits )
+{
+ int i, k, Par, Val, * pCell, iBit = 0;
+ Vec_IntFill( &p->vDrivers, 2*nBits, -4 );
+ for ( i = 0; i < p->nInputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, i );
+ int Width = Rtl_WireWidth( p, i );
+ for ( k = 0; k < Width; k++ )
+ {
+ assert( Vec_IntEntry(&p->vDrivers, 2*(First+k)) == -4 );
+ Vec_IntWriteEntry(&p->vDrivers, 2*(First+k)+0, -1 );
+ Vec_IntWriteEntry(&p->vDrivers, 2*(First+k)+1, iBit++ );
+ }
+ }
+ Rtl_NtkForEachCell( p, pCell, i )
+ {
+ int iBit = 0;
+ Rtl_CellForEachOutput( p, pCell, Par, Val, k )
+ iBit += Rtl_NtkMapSignalRange( p, Val, i, iBit );
+ }
+ for ( i = 0; i < 100; i++ )
+ if ( !Rtl_NtkBlastCons(p) )
+ break;
+ if ( i == 100 )
+ printf( "Mapping connections did not succeed after %d iterations.\n", i );
+// else
+// printf( "Mapping connections converged after %d iterations.\n", i );
+}
+int Rtl_NtkCollectOrComputeBit( Rtl_Ntk_t * p, int iBit )
+{
+ extern void Rtl_NtkBlast2_rec( Rtl_Ntk_t * p, int iBit, int * pDriver );
+ if ( Vec_IntEntry(&p->vLits, iBit) == -1 )
+ {
+ int * pDriver = Vec_IntEntryP(&p->vDrivers, 2*iBit);
+ assert( pDriver[0] != -4 );
+ Rtl_NtkBlast2_rec( p, iBit, pDriver );
+ }
+ assert( Vec_IntEntry(&p->vLits, iBit) >= 0 );
+ return Vec_IntEntry(&p->vLits, iBit);
+}
+int Rtl_NtkBlast2Spec( Rtl_Ntk_t * p, int * pCell, int iInput )
+{
+ int i, Par, Val, pLits[3] = {-1, -1, -1}, iBit;
+ Rtl_CellForEachInput( p, pCell, Par, Val, i )
+ {
+ Vec_Int_t * vTemp;
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalInfo( p, Val );
+ vTemp = Vec_IntDup( &p->vBitTemp );
+ iBit = Vec_IntEntry( vTemp, i==2 ? 0 : iInput );
+ if ( iBit >= 0 )
+ pLits[i] = Rtl_NtkCollectOrComputeBit( p, iBit );
+ else
+ pLits[i] = iBit+CONST_SHIFT;
+ assert( pLits[i] >= 0 );
+ Vec_IntFree( vTemp );
+ }
+ return Gia_ManHashMux(p->pGia, pLits[2], pLits[1], pLits[0]);
+}
+void Rtl_NtkBlastPrepareInputs( Rtl_Ntk_t * p, int * pCell )
+{
+ int i, k, Par, Val, iBit;
+ Rtl_CellForEachInput( p, pCell, Par, Val, i )
+ {
+ Vec_Int_t * vTemp;
+ Vec_IntClear( &p->vBitTemp );
+ Rtl_NtkCollectSignalInfo( p, Val );
+ vTemp = Vec_IntDup( &p->vBitTemp );
+ Vec_IntForEachEntry( vTemp, iBit, k )
+ if ( iBit >= 0 )
+ Rtl_NtkCollectOrComputeBit( p, iBit );
+ Vec_IntFree( vTemp );
+ }
+}
+void Rtl_NtkBlast2_rec( Rtl_Ntk_t * p, int iBit, int * pDriver )
+{
+ //char * pName = Rtl_NtkName(p);
+ assert( pDriver[0] != -1 );
+ if ( pDriver[0] == -3 )
+ {
+ int * pDriver1 = Vec_IntEntryP( &p->vDrivers, 2*pDriver[1] );
+ if ( Vec_IntEntry(&p->vLits, pDriver[1]) == -1 )
+ Rtl_NtkBlast2_rec( p, pDriver[1], pDriver1 );
+ assert( Vec_IntEntry(&p->vLits, pDriver[1]) >= 0 );
+ Vec_IntWriteEntry( &p->vLits, iBit, Vec_IntEntry(&p->vLits, pDriver[1]) );
+ return;
+ }
+ if ( pDriver[0] == -2 )
+ {
+ Vec_IntWriteEntry( &p->vLits, iBit, pDriver[1] );
+ return;
+ }
+ else
+ {
+ int * pCell = Rtl_NtkCell(p, pDriver[0]);
+ assert( pDriver[0] >= 0 );
+ if ( Rtl_CellModule(pCell) == ABC_OPER_SEL_NMUX ) // special case
+ {
+ int iLit = Rtl_NtkBlast2Spec( p, pCell, pDriver[1] );
+ Vec_IntWriteEntry( &p->vLits, iBit, iLit );
+ return;
+ }
+ Rtl_NtkBlastPrepareInputs( p, pCell );
+ if ( Rtl_CellModule(pCell) >= ABC_INFINITY )
+ Rtl_NtkBlastHierarchy( p->pGia, p, pCell );
+ else if ( Rtl_CellModule(pCell) < ABC_OPER_LAST )
+ Rtl_NtkBlastOperator( p->pGia, p, pCell );
+ else
+ printf( "Cannot blast black box %s in module %s.\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkName(p) );
+ }
+}
+Gia_Man_t * Rtl_NtkBlast2( Rtl_Ntk_t * p )
+{
+ Gia_Man_t * pTemp;
+ int i, b, nBits = Rtl_NtkRangeWires( p );
+ char Buffer[100]; static int counter = 0;
+ Vec_IntFill( &p->vLits, nBits, -1 );
+printf( "Blasting %s...\r", Rtl_NtkName(p) );
+ Rtl_NtkMapWires( p, 0 );
+ Rtl_NtkBlastMap( p, nBits );
+ assert( p->pGia == NULL );
+ p->pGia = Gia_ManStart( 1000 );
+ Rtl_NtkBlastInputs( p->pGia, p );
+ Gia_ManHashAlloc( p->pGia );
+ for ( i = 0; i < p->nOutputs; i++ )
+ {
+ int First = Rtl_WireBitStart( p, p->nInputs + i );
+ int Width = Rtl_WireWidth( p, p->nInputs + i );
+ for ( b = 0; b < Width; b++ )
+ Rtl_NtkCollectOrComputeBit( p, First+b );
+ }
+ Gia_ManHashStop( p->pGia );
+ Rtl_NtkBlastOutputs( p->pGia, p );
+ Rtl_NtkMapWires( p, 1 );
+ p->pGia = Gia_ManCleanup( pTemp = p->pGia );
+ Gia_ManStop( pTemp );
+
+sprintf( Buffer, "new%02d.aig", counter++ );
+Gia_AigerWrite( p->pGia, Buffer, 0, 0, 0 );
+printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) );
+Gia_ManPrintStats( p->pGia, NULL );
+ return p->pGia;
+}
+void Rtl_LibMark_rec( Rtl_Ntk_t * pNtk )
+{
+ int i, * pCell;
+ if ( pNtk->iCopy == -1 )
+ return;
+ Rtl_NtkForEachCell( pNtk, pCell, i )
+ {
+ Rtl_Ntk_t * pMod = Rtl_CellNtk( pNtk, pCell );
+ if ( pMod )
+ Rtl_LibMark_rec( pMod );
+ }
+ assert( pNtk->iCopy == -2 );
+ pNtk->iCopy = -1;
+}
+void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots )
+{
+ Rtl_Ntk_t * pNtk; int i, iNtk;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+ if ( vRoots )
+ {
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+ pNtk->iCopy = -2;
+ Vec_IntForEachEntry( vRoots, iNtk, i )
+ Rtl_LibMark_rec( Rtl_LibNtk(pLib, iNtk) );
+ }
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+ if ( pNtk->iCopy == -1 && pNtk->pGia == NULL )
+ pNtk->pGia = Rtl_NtkBlast2( pNtk );
+// Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+// if ( pNtk->iCopy == -2 )
+// printf( "Skipping network \"%s\" during bit-blasting.\n", Rtl_NtkName(pNtk) );
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+}
+void Rtl_LibBlastClean( Rtl_Lib_t * p )
+{
+ Rtl_Ntk_t * pNtk; int i;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ Gia_ManStopP( &pNtk->pGia );
+}
+void Rtl_LibSetReplace( Rtl_Lib_t * p, Vec_Wec_t * vGuide )
+{
+ Vec_Int_t * vLevel; int i, iNtk1, iNtk2;
+ Rtl_Ntk_t * pNtk, * pNtk1, * pNtk2;
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i )
+ pNtk->iCopy = -1;
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ {
+ int Type = Vec_IntEntry( vLevel, 1 );
+ int Name1 = Vec_IntEntry( vLevel, 2 );
+ int Name2 = Vec_IntEntry( vLevel, 3 );
+ int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 );
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) );
+ break;
+ }
+ if ( Type != Rtl_LibStrId(p, "equal") )
+ continue;
+ iNtk1 = iNtk >> 16;
+ iNtk2 = iNtk & 0xFFFF;
+ pNtk1 = Rtl_LibNtk(p, iNtk1);
+ pNtk2 = Rtl_LibNtk(p, iNtk2);
+ pNtk1->iCopy = iNtk2;
+ if ( iNtk1 == iNtk2 )
+ printf( "Preparing to prove \"%s\".\n", Rtl_NtkName(pNtk1) );
+ else
+ printf( "Preparing to replace \"%s\" by \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) );
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_LibPreprocess( Rtl_Lib_t * pLib )
+{
+ abctime clk = Abc_Clock();
+ Rtl_Ntk_t * p1 = NULL, * p2 = NULL, * p;
+ int i, k, Status, fFound = 0;
+ printf( "Performing preprocessing for verification.\n" );
+ // find similar modules
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p1, i )
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p2, k )
+ {
+ if ( i >= k )
+ continue;
+ if ( Gia_ManCiNum(p1->pGia) != Gia_ManCiNum(p2->pGia) ||
+ Gia_ManCoNum(p1->pGia) != Gia_ManCoNum(p2->pGia) )
+ continue;
+ // two similar modules
+ Status = Cec_ManVerifyTwo( p1->pGia, p2->pGia, 0 );
+ if ( Status != 1 )
+ continue;
+ printf( "Proved equivalent modules: %s == %s\n", Rtl_NtkName(p1), Rtl_NtkName(p2) );
+ // inline
+ if ( Gia_ManAndNum(p1->pGia) > Gia_ManAndNum(p2->pGia) )
+ ABC_SWAP( Gia_Man_t *, p1->pGia, p2->pGia );
+ assert( Gia_ManAndNum(p1->pGia) <= Gia_ManAndNum(p2->pGia) );
+ Gia_ManStopP( &p2->pGia );
+ p2->pGia = Gia_ManDup( p1->pGia );
+ fFound = 1;
+ goto finish;
+ }
+finish:
+ if ( fFound == 0 )
+ printf( "Preprocessing not succeded.\n" );
+ Abc_PrintTime( 1, "Preprocessing time", Abc_Clock() - clk );
+ // blast AIGs again
+ Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i )
+ if ( p != p1 && p != p2 )
+ Gia_ManStopP( &p->pGia );
+ //Rtl_LibBlast( pLib );
+ Rtl_LibBlast2( pLib, NULL );
+}
+void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk )
+{
+ abctime clk = Abc_Clock(); int Status;
+ Rtl_Ntk_t * pTop = pNtk ? (Rtl_Ntk_t *)pNtk : Rtl_LibTop( pLib );
+ Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pTop->pGia, 1000000, 0 );
+ int RetValue = Gia_ManAndNum(pSwp);
+ Gia_ManStop( pSwp );
+ if ( RetValue == 0 )
+ printf( "Verification problem solved after SAT sweeping! " );
+ else
+ {
+ Gia_Man_t * pCopy = Gia_ManDup( pTop->pGia );
+ Gia_ManInvertPos( pCopy );
+ Gia_ManAppendCo( pCopy, 0 );
+ Status = Cec_ManVerifySimple( pCopy );
+ Gia_ManStop( pCopy );
+ if ( Status == 1 )
+ printf( "Verification problem solved after CEC! " );
+ else
+ printf( "Verification problem is NOT solved (miter has %d nodes)! ", RetValue );
+ }
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_SolveEqual( Rtl_Lib_t * p, int iNtk1, int iNtk2 )
+{
+ abctime clk = Abc_Clock();
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 );
+ printf( "\nProving equivalence of \"%s\" and \"%s\"...\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) );
+ if ( Gia_ManCiNum(pNtk1->pGia) != Gia_ManCiNum(pNtk2->pGia) ||
+ Gia_ManCoNum(pNtk1->pGia) != Gia_ManCoNum(pNtk2->pGia) )
+ {
+ printf( "The number of inputs/outputs does not match.\n" );
+ }
+ else if ( 1 )
+ {
+ Gia_Man_t * pGia = Gia_ManMiter( pNtk1->pGia, pNtk2->pGia, 0, 0, 0, 0, 0 );
+ Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, 10000000, 0 );
+ //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) );
+ if ( Gia_ManAndNum(pNew) == 0 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Gia_ManStopP( &pNew );
+ Gia_ManStopP( &pGia );
+ }
+ else
+ {
+ int Status = Cec_ManVerifyTwo( pNtk1->pGia, pNtk2->pGia, 0 );
+ if ( Status == 1 )
+ printf( "The networks are equivalent. " );
+ else
+ printf( "The networks are NOT equivalent. " );
+ }
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts )
+{
+ int i, * pWire, iFirst = -1, Counts[4] = {0}, nBits = 0;
+ assert( p->nOutputs == 1 );
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ if ( pWire[0] & 1 ) // PI
+ Counts[0]++, Counts[1] += pWire[1];
+ if ( pWire[0] & 2 ) // PO
+ Counts[2]++, Counts[3] += pWire[1];
+ }
+ assert( p->nInputs == Counts[0] );
+ assert( p->nOutputs == Counts[2] );
+ *pnOuts = Counts[3];
+ Rtl_NtkForEachWire( p, pWire, i )
+ {
+ if ( pWire[0] & 1 ) // PI
+ {
+ if ( pWire[1] == Counts[3] )
+ return nBits;
+ nBits += pWire[1];
+ }
+ }
+ return -1;
+}
+Gia_Man_t * Gia_ManMoveSharedFirst( Gia_Man_t * pGia, int iFirst, int nBits )
+{
+ Vec_Int_t * vPiPerm = Vec_IntAlloc( Gia_ManPiNum(pGia) );
+ Gia_Man_t * pTemp; int i, n;
+ for ( n = 0; n < 2; n++ )
+ for ( i = 0; i < Gia_ManPiNum(pGia); i++ )
+ if ( n == (i >= iFirst && i < iFirst + nBits) )
+ Vec_IntPush( vPiPerm, i );
+ pTemp = Gia_ManDupPerm( pGia, vPiPerm );
+ Vec_IntFree( vPiPerm );
+ return pTemp;
+}
+void Wln_SolveInverse( Rtl_Lib_t * p, int iNtk1, int iNtk2 )
+{
+ abctime clk = Abc_Clock();
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 );
+ int Res = printf( "\nProving inverse equivalence of \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) );
+ int nOuts1, iFirst1 = Gia_ManFindFirst( pNtk1, &nOuts1 );
+ int nOuts2, iFirst2 = Gia_ManFindFirst( pNtk2, &nOuts2 );
+ Gia_Man_t * pGia1 = Gia_ManMoveSharedFirst( pNtk1->pGia, iFirst1, nOuts1 );
+ Gia_Man_t * pGia2 = Gia_ManMoveSharedFirst( pNtk2->pGia, iFirst2, nOuts2 );
+ if ( 1 )
+ {
+ Gia_Man_t * pGia = Gia_ManMiterInverse( pGia1, pGia2, 0, 0 );
+ Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, 10000000, 0 );
+ //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) );
+ if ( Gia_ManAndNum(pNew) == 0 )
+ Abc_Print( 1, "Networks are equivalent. " );
+ else
+ Abc_Print( 1, "Networks are UNDECIDED. " );
+ Gia_ManStopP( &pNew );
+ Gia_ManStopP( &pGia );
+ }
+ else
+ {
+ int Status = Cec_ManVerifyTwoInv( pGia1, pGia2, 0 );
+ if ( Status == 1 )
+ printf( "The networks are equivalent. " );
+ else
+ printf( "The networks are NOT equivalent. " );
+ }
+ Res = 0;
+ Gia_ManStopP( &pGia1 );
+ Gia_ManStopP( &pGia2 );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+void Wln_SolveProperty( Rtl_Lib_t * p, int iNtk )
+{
+ Rtl_Ntk_t * pNtk = Rtl_LibNtk( p, iNtk );
+ printf( "\nProving property \"%s\".\n", Rtl_NtkName(pNtk) );
+ Rtl_LibSolve( p, pNtk );
+}
+Vec_Int_t * Wln_ReadNtkRoots( Rtl_Lib_t * p, Vec_Wec_t * vGuide )
+{
+ Vec_Int_t * vLevel; int i;
+ Vec_Int_t * vRoots = Vec_IntAlloc( 100 );
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ {
+ int Name1 = Vec_IntEntry( vLevel, 2 );
+ int Name2 = Vec_IntEntry( vLevel, 3 );
+ int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 );
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) );
+ break;
+ }
+/*
+ else
+ {
+ Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk >> 16 );
+ Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk & 0xFFFF );
+ printf( "Matching \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) );
+ }
+*/
+ Vec_IntPushTwo( vRoots, iNtk >> 16, iNtk & 0xFFFF );
+ }
+ return vRoots;
+}
+void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p )
+{
+ extern Vec_Wec_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p );
+ Vec_Wec_t * vGuide = Wln_ReadGuidance( pFileName, p->pManName );
+ Vec_Int_t * vRoots, * vLevel; int i, iNtk1, iNtk2;
+ Vec_IntFillExtra( p->vMap, Abc_NamObjNumMax(p->pManName), -1 );
+ Rtl_LibSetReplace( p, vGuide );
+ Rtl_LibUpdateBoxes( p );
+ Rtl_LibReorderModules( p );
+ vRoots = Wln_ReadNtkRoots( p, vGuide );
+ Rtl_LibBlast2( p, vRoots );
+ Vec_WecForEachLevel( vGuide, vLevel, i )
+ {
+ int Prove = Vec_IntEntry( vLevel, 0 );
+ int Type = Vec_IntEntry( vLevel, 1 );
+ int Name1 = Vec_IntEntry( vLevel, 2 );
+ int Name2 = Vec_IntEntry( vLevel, 3 );
+ int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 );
+ if ( iNtk == -1 )
+ {
+ printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) );
+ break;
+ }
+ iNtk1 = iNtk >> 16;
+ iNtk2 = iNtk & 0xFFFF;
+ if ( Prove != Rtl_LibStrId(p, "prove") )
+ printf( "Unknown task in line %d.\n", i );
+ //else if ( iNtk1 == -1 )
+ // printf( "Network %s cannot be found in this design.\n", Rtl_LibStr(p, Name1) );
+ else
+ {
+ if ( Type == Rtl_LibStrId(p, "equal") )
+ Wln_SolveEqual( p, iNtk1, iNtk2 );
+ else if ( Type == Rtl_LibStrId(p, "inverse") )
+ Wln_SolveInverse( p, iNtk1, iNtk2 );
+ else if ( Type == Rtl_LibStrId(p, "property") )
+ Wln_SolveProperty( p, iNtk1 );
+ continue;
+ }
+ break;
+ }
+ Rtl_LibBlastClean( p );
+ Vec_WecFree( vGuide );
+ Vec_IntFree( vRoots );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c
index aff88af9..fa0f0cd5 100644
--- a/src/base/wln/wlnRtl.c
+++ b/src/base/wln/wlnRtl.c
@@ -37,6 +37,7 @@ ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
+
/**Function*************************************************************
Synopsis []
@@ -48,22 +49,60 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-Wln_Ntk_t * Wln_ReadRtl( char * pFileName )
+#define MAX_LINE 1000000
+
+void Rtl_NtkCleanFile( char * pFileName )
{
- return NULL;
+ char * pBuffer, * pFileName2 = "_temp__.rtlil";
+ FILE * pFile = fopen( pFileName, "rb" );
+ FILE * pFile2;
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ pFile2 = fopen( pFileName2, "wb" );
+ if ( pFile2 == NULL )
+ {
+ fclose( pFile );
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName2 );
+ return;
+ }
+ pBuffer = ABC_ALLOC( char, MAX_LINE );
+ while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL )
+ if ( !strstr(pBuffer, "attribute \\src") )
+ fputs( pBuffer, pFile2 );
+ ABC_FREE( pBuffer );
+ fclose( pFile );
+ fclose( pFile2 );
}
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
+void Rtl_NtkCleanFile2( char * pFileName )
+{
+ char * pBuffer, * pFileName2 = "_temp__.v";
+ FILE * pFile = fopen( pFileName, "rb" );
+ FILE * pFile2;
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ pFile2 = fopen( pFileName2, "wb" );
+ if ( pFile2 == NULL )
+ {
+ fclose( pFile );
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName2 );
+ return;
+ }
+ pBuffer = ABC_ALLOC( char, MAX_LINE );
+ while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL )
+ if ( !strstr(pBuffer, "//") )
+ fputs( pBuffer, pFile2 );
+ ABC_FREE( pBuffer );
+ fclose( pFile );
+ fclose( pFile2 );
+}
-***********************************************************************/
char * Wln_GetYosysName()
{
char * pYosysName = NULL;
@@ -96,27 +135,31 @@ int Wln_ConvertToRtl( char * pCommand, char * pFileTemp )
fclose( pFile );
return 1;
}
-Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose )
+Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose )
{
- Wln_Ntk_t * pNtk = NULL;
+ Rtl_Lib_t * pNtk = NULL;
char Command[1000];
char * pFileTemp = "_temp_.rtlil";
int fSVlog = strstr(pFileName, ".sv") != NULL;
- sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; write_rtlil %s\"",
+ if ( strstr(pFileName, ".rtl") )
+ return Rtl_LibReadFile( pFileName, pFileName );
+ sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; %sproc; write_rtlil %s\"",
Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName,
- pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", pFileTemp );
+ pTopModule ? "-top " : "",
+ pTopModule ? pTopModule : "",
+ fCollapse ? "flatten; " : "",
+ pFileTemp );
if ( fVerbose )
printf( "%s\n", Command );
if ( !Wln_ConvertToRtl(Command, pFileTemp) )
- {
return NULL;
- }
- pNtk = Wln_ReadRtl( pFileTemp );
+ pNtk = Rtl_LibReadFile( pFileTemp, pFileName );
if ( pNtk == NULL )
{
printf( "Dumped the design into file \"%s\".\n", pFileTemp );
return NULL;
}
+ Rtl_NtkCleanFile( pFileTemp );
unlink( pFileTemp );
return pNtk;
}
@@ -125,10 +168,16 @@ Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSk
Gia_Man_t * pGia = NULL;
char Command[1000];
char * pFileTemp = "_temp_.aig";
- int fSVlog = strstr(pFileName, ".sv") != NULL;
- sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s\"",
- Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName,
- pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", fTechMap ? "techmap; setundef -zero; " : "", pFileTemp );
+ int fRtlil = strstr(pFileName, ".rtl") != NULL;
+ int fSVlog = strstr(pFileName, ".sv") != NULL;
+ sprintf( Command, "%s -qp \"%s%s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s\"",
+ Wln_GetYosysName(),
+ fRtlil ? "read_rtlil" : "read_verilog",
+ fSVlog ? " -sv ":" ",
+ pFileName,
+ pTopModule ? "-top " : "-auto-top",
+ pTopModule ? pTopModule : "",
+ fTechMap ? "techmap; setundef -zero; " : "", pFileTemp );
if ( fVerbose )
printf( "%s\n", Command );
if ( !Wln_ConvertToRtl(Command, pFileTemp) )
diff --git a/src/bool/dec/decAbc.c b/src/bool/dec/decAbc.c
index 6602702c..e440a652 100644
--- a/src/bool/dec/decAbc.c
+++ b/src/bool/dec/decAbc.c
@@ -237,20 +237,21 @@ int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa
SeeAlso []
***********************************************************************/
-void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
+int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
{
extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph );
Abc_Obj_t * pRootNew;
Abc_Ntk_t * pNtk = pRoot->pNtk;
- int nNodesNew, nNodesOld;
+ int nNodesNew, nNodesOld, RetValue;
nNodesOld = Abc_NtkNodeNum(pNtk);
// create the new structure of nodes
pRootNew = Dec_GraphToNetwork( pNtk, pGraph );
// remove the old nodes
- Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel );
+ RetValue = Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel );
// compare the gains
nNodesNew = Abc_NtkNodeNum(pNtk);
//assert( nGain <= nNodesOld - nNodesNew );
+ return RetValue;
}
diff --git a/src/map/amap/amapRead.c b/src/map/amap/amapRead.c
index 3ccfc011..9e6ee21c 100644
--- a/src/map/amap/amapRead.c
+++ b/src/map/amap/amapRead.c
@@ -126,41 +126,52 @@ void Amap_RemoveComments( char * pBuffer, int * pnDots, int * pnLines )
// (in the BLIF file, comments are lines starting with "#")
nDots = nLines = 0;
for ( pCur = pBuffer; *pCur; pCur++ )
- {
+ {
// if this is the beginning of comment
// clean it with spaces until the new line statement
- if ( *pCur == '#' )
- while ( *pCur != '\n' )
- *pCur++ = ' ';
-
+ if ( *pCur == '#' ) {
+ while ( *pCur != '\n' ) {
+ *pCur++ = ' ';
+ }
+ }
// count the number of new lines and dots
if ( *pCur == '\n' ) {
- if (*(pCur-1)=='\r') {
- // DOS(R) file support
- if (*(pCur-2)!='\\') nLines++;
- else {
- // rewind to backslash and overwrite with a space
- *(pCur-2) = ' ';
- *(pCur-1) = ' ';
- *pCur = ' ';
- }
- } else {
- // UNIX(TM) file support
- if (*(pCur-1)!='\\') nLines++;
- else {
- // rewind to backslash and overwrite with a space
- *(pCur-1) = ' ';
- *pCur = ' ';
+ if (pCur > pBuffer) {
+ if (*(pCur - 1) == '\r') {
+ // DOS(R) file support
+ if (pCur > (pBuffer + 1)) {
+ if (*(pCur - 2)!='\\') {
+ nLines++;
+ }
+ else {
+ // rewind to backslash and overwrite with a space
+ *(pCur - 2) = ' ';
+ *(pCur - 1) = ' ';
+ *pCur = ' ';
+ }
+ }
+ } else {
+ // UNIX(TM) file support
+ if (*(pCur - 1) != '\\') {
+ nLines++;
+ }
+ else {
+ // rewind to backslash and overwrite with a space
+ *(pCur-1) = ' ';
+ *pCur = ' ';
+ }
+ }
+ }
}
+ else if ( *pCur == '.' ) {
+ nDots++;
}
- }
- else if ( *pCur == '.' )
- nDots++;
- }
+ }
+
if ( pnDots )
- *pnDots = nDots;
+ *pnDots = nDots;
if ( pnLines )
- *pnLines = nLines;
+ *pnLines = nLines;
}
/**Function*************************************************************
@@ -491,4 +502,3 @@ Amap_Lib_t * Amap_LibReadFile( char * pFileName, int fVerbose )
ABC_NAMESPACE_IMPL_END
-
diff --git a/src/map/amap/amapUniq.c b/src/map/amap/amapUniq.c
index dd858c96..e2be4343 100644
--- a/src/map/amap/amapUniq.c
+++ b/src/map/amap/amapUniq.c
@@ -278,15 +278,14 @@ Abc_Lit2Var(iFan2), (Abc_LitIsCompl(iFan2)?'-':'+') );
int ** Amap_LibLookupTableAlloc( Vec_Ptr_t * vVec, int fVerbose )
{
Vec_Int_t * vOne;
- int ** pRes, * pBuffer;
+ int ** pRes;
int i, k, nTotal, nSize, nEntries, Value;
// count the total size
nEntries = nSize = Vec_PtrSize( vVec );
Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i )
nEntries += Vec_IntSize(vOne);
- pBuffer = ABC_ALLOC( int, nSize * sizeof(void *) + nEntries );
- pRes = (int **)pBuffer;
- pRes[0] = pBuffer + nSize * sizeof(void *);
+ pRes = (int **)ABC_ALLOC( char, nSize * sizeof(void *) + nEntries * sizeof(int) );
+ pRes[0] = (int *)((char *)pRes + nSize * sizeof(void *));
nTotal = 0;
Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i )
{
diff --git a/src/map/mio/mioRead.c b/src/map/mio/mioRead.c
index c0a83cfd..c19c07d4 100644
--- a/src/map/mio/mioRead.c
+++ b/src/map/mio/mioRead.c
@@ -734,37 +734,48 @@ void Io_ReadFileRemoveComments( char * pBuffer, int * pnDots, int * pnLines )
// (in the BLIF file, comments are lines starting with "#")
nDots = nLines = 0;
for ( pCur = pBuffer; *pCur; pCur++ )
- {
+ {
// if this is the beginning of comment
// clean it with spaces until the new line statement
- if ( *pCur == '#' )
- while ( *pCur != '\n' )
- *pCur++ = ' ';
-
+ if ( *pCur == '#' ) {
+ while ( *pCur != '\n' ) {
+ *pCur++ = ' ';
+ }
+ }
// count the number of new lines and dots
if ( *pCur == '\n' ) {
- if (*(pCur-1)=='\r') {
- // DOS(R) file support
- if (*(pCur-2)!='\\') nLines++;
- else {
- // rewind to backslash and overwrite with a space
- *(pCur-2) = ' ';
- *(pCur-1) = ' ';
- *pCur = ' ';
- }
- } else {
- // UNIX(TM) file support
- if (*(pCur-1)!='\\') nLines++;
- else {
- // rewind to backslash and overwrite with a space
- *(pCur-1) = ' ';
- *pCur = ' ';
+ if (pCur > pBuffer) {
+ if (*(pCur - 1) == '\r') {
+ // DOS(R) file support
+ if (pCur > (pBuffer + 1)) {
+ if (*(pCur - 2) != '\\') {
+ nLines++;
+ }
+ else {
+ // rewind to backslash and overwrite with a space
+ *(pCur - 2) = ' ';
+ *(pCur - 1) = ' ';
+ *pCur = ' ';
+ }
+ }
+ } else {
+ // UNIX(TM) file support
+ if (*(pCur - 1) != '\\') {
+ nLines++;
+ }
+ else {
+ // rewind to backslash and overwrite with a space
+ *(pCur - 1) = ' ';
+ *pCur = ' ';
+ }
+ }
+ }
}
+ else if ( *pCur == '.' ) {
+ nDots++;
}
- }
- else if ( *pCur == '.' )
- nDots++;
- }
+ }
+
if ( pnDots )
*pnDots = nDots;
if ( pnLines )
diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h
index 7c101570..40aa9799 100644
--- a/src/proof/cec/cec.h
+++ b/src/proof/cec/cec.h
@@ -206,6 +206,7 @@ struct Cec_ParSeq_t_
/*=== cecCec.c ==========================================================*/
extern int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars );
extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose );
+extern int Cec_ManVerifyTwoInv( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose );
extern int Cec_ManVerifySimple( Gia_Man_t * p );
/*=== cecChoice.c ==========================================================*/
extern Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars );
diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c
index cfa07ff8..f6a1ab52 100644
--- a/src/proof/cec/cecCec.c
+++ b/src/proof/cec/cecCec.c
@@ -465,6 +465,21 @@ int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose )
Gia_ManStop( pMiter );
return RetValue;
}
+int Cec_ManVerifyTwoInv( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose )
+{
+ Cec_ParCec_t ParsCec, * pPars = &ParsCec;
+ Gia_Man_t * pMiter;
+ int RetValue;
+ Cec_ManCecSetDefaultParams( pPars );
+ pPars->fVerbose = fVerbose;
+ pMiter = Gia_ManMiterInverse( p0, p1, 1, pPars->fVerbose );
+ if ( pMiter == NULL )
+ return -1;
+ RetValue = Cec_ManVerify( pMiter, pPars );
+ p0->pCexComb = pMiter->pCexComb; pMiter->pCexComb = NULL;
+ Gia_ManStop( pMiter );
+ return RetValue;
+}
/**Function*************************************************************
diff --git a/src/proof/cec/cecSolveG.c b/src/proof/cec/cecSolveG.c
index 0bb68a7f..c4b01b50 100644
--- a/src/proof/cec/cecSolveG.c
+++ b/src/proof/cec/cecSolveG.c
@@ -445,7 +445,7 @@ void CecG_ManSatSolverRecycle( Cec_ManSat_t * p )
// memset( p->pSatVars, 0, sizeof(int) * Gia_ManObjNumMax(p->pAigTotal) );
sat_solver_stop( p->pSat );
}
- p->pSat = sat_solver_start();
+ p->pSat = (struct sat_solver_t*)sat_solver_start();
assert( 0 <= p->pPars->SolverType && p->pPars->SolverType <= 2 );
sat_solver_set_jftr( p->pSat, p->pPars->SolverType );
//sat_solver_setnvars( p->pSat, 1000 ); // minisat only
diff --git a/src/sat/bsat2/Solver.cpp b/src/sat/bsat2/Solver.cpp
index 451beed8..0f8b415a 100644
--- a/src/sat/bsat2/Solver.cpp
+++ b/src/sat/bsat2/Solver.cpp
@@ -820,7 +820,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
{
- FILE* f = fopen(file, "wr");
+ FILE* f = fopen(file, "wb");
if (f == NULL)
fprintf(stderr, "could not open file %s\n", file), exit(1);
toDimacs(f, assumps);
diff --git a/src/sat/glucose/AbcGlucose.cpp b/src/sat/glucose/AbcGlucose.cpp
index ad595ab9..9c23e0d0 100644
--- a/src/sat/glucose/AbcGlucose.cpp
+++ b/src/sat/glucose/AbcGlucose.cpp
@@ -818,7 +818,7 @@ void Glucose_ReadDimacs( char * pFileName, SimpSolver& s )
SeeAlso []
***********************************************************************/
-void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars )
+void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars, int fDumpCnf )
{
abctime clk = Abc_Clock();
@@ -844,6 +844,15 @@ void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars )
S.eliminate(true);
printf( "c Simplication removed %d variables and %d clauses. ", S.eliminated_vars, S.eliminated_clauses );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ if ( fDumpCnf )
+ {
+ char * pFileCnf = Extra_FileNameGenericAppend( pFileName, "_out.cnf" );
+ S.toDimacs(pFileCnf);
+ printf( "Finished dumping CNF after preprocessing into file \"%s\".\n", pFileCnf );
+ printf( "SAT solving is not performed.\n" );
+ return;
+ }
}
vec<Lit> dummy;
diff --git a/src/sat/glucose/AbcGlucose.h b/src/sat/glucose/AbcGlucose.h
index 89a3652f..c73f9918 100644
--- a/src/sat/glucose/AbcGlucose.h
+++ b/src/sat/glucose/AbcGlucose.h
@@ -105,7 +105,7 @@ extern void bmcg_sat_solver_start_new_round( bmcg_sat_solver * s );
extern void bmcg_sat_solver_mark_cone( bmcg_sat_solver * s, int var );
-extern void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars );
+extern void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars, int fDumpCnf );
extern int Glucose_SolveAig( Gia_Man_t * p, Glucose_Pars * pPars );
ABC_NAMESPACE_HEADER_END
diff --git a/src/sat/glucose/AbcGlucoseCmd.cpp b/src/sat/glucose/AbcGlucoseCmd.cpp
index 2e819e49..bb957547 100644
--- a/src/sat/glucose/AbcGlucoseCmd.cpp
+++ b/src/sat/glucose/AbcGlucoseCmd.cpp
@@ -81,10 +81,11 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
int pre = 1;
int verb = 0;
int nConfls = 0;
+ int fDumpCnf = 0;
Glucose_Pars pPars;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Cpvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Cpdvh" ) ) != EOF )
{
switch ( c )
{
@@ -102,6 +103,9 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'p':
pre ^= 1;
break;
+ case 'd':
+ fDumpCnf ^= 1;
+ break;
case 'v':
verb ^= 1;
break;
@@ -116,7 +120,7 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( argc == globalUtilOptind + 1 )
{
- Glucose_SolveCnf( argv[globalUtilOptind], &pPars );
+ Glucose_SolveCnf( argv[globalUtilOptind], &pPars, fDumpCnf );
return 0;
}
@@ -132,10 +136,11 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &glucose [-C num] [-pvh] <file.cnf>\n" );
+ Abc_Print( -2, "usage: &glucose [-C num] [-pdvh] <file.cnf>\n" );
Abc_Print( -2, "\t run Glucose 3.0 by Gilles Audemard and Laurent Simon\n" );
Abc_Print( -2, "\t-C num : conflict limit [default = %d]\n", nConfls );
Abc_Print( -2, "\t-p : enable preprocessing [default = %d]\n",pre);
+ Abc_Print( -2, "\t-d : enable dumping CNF after proprocessing [default = %d]\n",fDumpCnf);
Abc_Print( -2, "\t-v : verbosity [default = %d]\n",verb);
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t<file.cnf> : (optional) CNF file to solve\n");
diff --git a/src/sat/glucose/Glucose.cpp b/src/sat/glucose/Glucose.cpp
index c975c6ca..cfb388de 100644
--- a/src/sat/glucose/Glucose.cpp
+++ b/src/sat/glucose/Glucose.cpp
@@ -1330,7 +1330,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
{
- FILE* f = fopen(file, "wr");
+ FILE* f = fopen(file, "wb");
if (f == NULL)
fprintf(stderr, "could not open file %s\n", file), exit(1);
toDimacs(f, assumps);
diff --git a/src/sat/glucose/System.cpp b/src/sat/glucose/System.cpp
index 18f2d656..276eddb8 100644
--- a/src/sat/glucose/System.cpp
+++ b/src/sat/glucose/System.cpp
@@ -86,7 +86,7 @@ double Gluco::memUsed(void) {
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
return (double)ru.ru_maxrss / 1024; }
-double memUsedPeak(void) { return memUsed(); }
+double Gluco::memUsedPeak(void) { return memUsed(); }
ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/glucose2/Glucose2.cpp b/src/sat/glucose2/Glucose2.cpp
index 7a8b265b..4b4c28e7 100644
--- a/src/sat/glucose2/Glucose2.cpp
+++ b/src/sat/glucose2/Glucose2.cpp
@@ -1535,7 +1535,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
{
- FILE* f = fopen(file, "wr");
+ FILE* f = fopen(file, "wb");
if (f == NULL)
fprintf(stderr, "could not open file %s\n", file), exit(1);
toDimacs(f, assumps);
diff --git a/src/sat/glucose2/System2.cpp b/src/sat/glucose2/System2.cpp
index 844220a0..bf16dcd1 100644
--- a/src/sat/glucose2/System2.cpp
+++ b/src/sat/glucose2/System2.cpp
@@ -86,7 +86,7 @@ double Gluco2::memUsed(void) {
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
return (double)ru.ru_maxrss / 1024; }
-double memUsedPeak(void) { return memUsed(); }
+double Gluco2::memUsedPeak(void) { return memUsed(); }
ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/msat/msatClause.c b/src/sat/msat/msatClause.c
index 6b1b9e98..3d1fa2fc 100644
--- a/src/sat/msat/msatClause.c
+++ b/src/sat/msat/msatClause.c
@@ -522,7 +522,7 @@ void Msat_ClausePrintSymbols( Msat_Clause_t * pC )
// if ( pC->fLearned )
// printf( "Act = %.4f ", Msat_ClauseReadActivity(pC) );
for ( i = 0; i < (int)pC->nSize; i++ )
- printf(" "L_LIT, L_lit(pC->pData[i]));
+ printf(" " L_LIT, L_lit(pC->pData[i]));
}
printf( "\n" );
}
diff --git a/src/sat/msat/msatSolverSearch.c b/src/sat/msat/msatSolverSearch.c
index b3190e39..2eda5038 100644
--- a/src/sat/msat/msatSolverSearch.c
+++ b/src/sat/msat/msatSolverSearch.c
@@ -52,7 +52,7 @@ int Msat_SolverAssume( Msat_Solver_t * p, Msat_Lit_t Lit )
{
assert( Msat_QueueReadSize(p->pQueue) == 0 );
if ( p->fVerbose )
- printf(L_IND"assume("L_LIT")\n", L_ind, L_lit(Lit));
+ printf(L_IND "assume(" L_LIT ")\n", L_ind, L_lit(Lit));
Msat_IntVecPush( p->vTrailLim, Msat_IntVecReadSize(p->vTrail) );
// assert( Msat_IntVecReadSize(p->vTrailLim) <= Msat_IntVecReadSize(p->vTrail) + 1 );
// assert( Msat_IntVecReadSize( p->vTrailLim ) < p->nVars );
@@ -83,7 +83,7 @@ void Msat_SolverUndoOne( Msat_Solver_t * p )
Msat_OrderVarUnassigned( p->pOrder, Var );
if ( p->fVerbose )
- printf(L_IND"unbind("L_LIT")\n", L_ind, L_lit(Lit));
+ printf(L_IND "unbind(" L_LIT")\n", L_ind, L_lit(Lit));
}
/**Function*************************************************************
@@ -107,7 +107,7 @@ void Msat_SolverCancel( Msat_Solver_t * p )
{
Msat_Lit_t Lit;
Lit = Msat_IntVecReadEntry( p->vTrail, Msat_IntVecReadEntryLast(p->vTrailLim) );
- printf(L_IND"cancel("L_LIT")\n", L_ind, L_lit(Lit));
+ printf(L_IND "cancel(" L_LIT ")\n", L_ind, L_lit(Lit));
}
}
for ( c = Msat_IntVecReadSize(p->vTrail) - Msat_IntVecPop( p->vTrailLim ); c != 0; c-- )
@@ -188,7 +188,7 @@ int Msat_SolverEnqueue( Msat_Solver_t * p, Msat_Lit_t Lit, Msat_Clause_t * pC )
if ( p->fVerbose )
{
// printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(Lit));
- printf(L_IND"bind("L_LIT") ", L_ind, L_lit(Lit));
+ printf(L_IND "bind(" L_LIT ") ", L_ind, L_lit(Lit));
Msat_ClausePrintSymbols( pC );
}
p->pAssigns[Var] = Lit;
@@ -513,7 +513,7 @@ void Msat_SolverAnalyze( Msat_Solver_t * p, Msat_Clause_t * pC, Msat_IntVec_t *
nReasonSize = Msat_IntVecReadSize( vLits_out );
pReasonArray = Msat_IntVecReadArray( vLits_out );
for ( j = 0; j < nReasonSize; j++ )
- printf(" "L_LIT, L_lit(pReasonArray[j]));
+ printf(" " L_LIT, L_lit(pReasonArray[j]));
printf(" } at level %d\n", *pLevel_out);
}
}