diff options
Diffstat (limited to 'src/base')
35 files changed, 5395 insertions, 135 deletions
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/abcCheck.c b/src/base/abc/abcCheck.c index a7448530..c492b709 100644 --- a/src/base/abc/abcCheck.c +++ b/src/base/abc/abcCheck.c @@ -177,7 +177,10 @@ int Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) // check the nodes if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigCheck( (Abc_Aig_t *)pNtk->pManFunc ); + { + if ( !Abc_AigCheck( (Abc_Aig_t *)pNtk->pManFunc ) ) + return 0; + } else { Abc_NtkForEachNode( pNtk, pNode, i ) diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c index 3f441e99..92dbd0c9 100644 --- a/src/base/abc/abcMinBase.c +++ b/src/base/abc/abcMinBase.c @@ -113,6 +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 ddSize, fDupFanins = 0; assert( Abc_NtkIsBddLogic(pNode->pNtk) ); assert( Abc_ObjIsNode(pNode) ); @@ -126,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 ); @@ -140,19 +147,29 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) Vec_IntForEachEntryStop( &pNode->vFanins, iFanin2, j, k ) if ( iFanin == iFanin2 ) break; + fDupFanins |= (int)(j < k); if ( j == k ) 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 ); + + // try again if node had duplicated fanins + if ( fDupFanins ) + Abc_NodeMinimumBase( pNode ); return 1; } 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 29732bc6..33a8315c 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -146,6 +146,7 @@ static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRestructure ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandResubstitute ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandResubCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCascade ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandExtract ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -337,6 +338,7 @@ static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Satoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sat3 ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Kissat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -469,6 +471,7 @@ static int Abc_CommandAbc9Reduce ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9EquivMark ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9EquivFilter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Cec ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9ICec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Verify ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Force ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -482,6 +485,7 @@ static int Abc_CommandAbc9If ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Iff ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Iiff ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9If2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Sif ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Jf ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Kf ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Lf ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -518,6 +522,8 @@ static int Abc_CommandAbc9Iso ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9IsoNpn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9IsoSt ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Compare ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9RevEng ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Uif ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9CexInfo ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Cycle ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Cone ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -890,6 +896,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 ); // Cmd_CommandAdd( pAbc, "Synthesis", "restructure", Abc_CommandRestructure, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "resub", Abc_CommandResubstitute, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 ); // Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "extract", Abc_CommandExtract, 1 ); @@ -1081,6 +1088,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "&satoko", Abc_CommandAbc9Satoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "&sat3", Abc_CommandAbc9Sat3, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "&kissat", Abc_CommandAbc9Kissat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -1212,6 +1220,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&equiv_mark", Abc_CommandAbc9EquivMark, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&equiv_filter", Abc_CommandAbc9EquivFilter, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cec", Abc_CommandAbc9Cec, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&icec", Abc_CommandAbc9ICec, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&verify", Abc_CommandAbc9Verify, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&sweep", Abc_CommandAbc9Sweep, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&force", Abc_CommandAbc9Force, 0 ); @@ -1225,6 +1234,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&iff", Abc_CommandAbc9Iff, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&iiff", Abc_CommandAbc9Iiff, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&if2", Abc_CommandAbc9If2, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&sif", Abc_CommandAbc9Sif, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&jf", Abc_CommandAbc9Jf, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&kf", Abc_CommandAbc9Kf, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&lf", Abc_CommandAbc9Lf, 0 ); @@ -1261,6 +1271,8 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&isonpn", Abc_CommandAbc9IsoNpn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&isost", Abc_CommandAbc9IsoSt, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&compare", Abc_CommandAbc9Compare, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&reveng", Abc_CommandAbc9RevEng, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&uif", Abc_CommandAbc9Uif, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cexinfo", Abc_CommandAbc9CexInfo, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cycle", Abc_CommandAbc9Cycle, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cone", Abc_CommandAbc9Cone, 0 ); @@ -6961,6 +6973,7 @@ usage: Abc_Print( -2, "\t 9: adjustable algorithm (heuristic) by XueGong Zhou at Fudan University, Shanghai\n" ); Abc_Print( -2, "\t 10: adjustable algorithm (exact) by XueGong Zhou at Fudan University, Shanghai\n" ); Abc_Print( -2, "\t 11: new cost-aware exact algorithm by XueGong Zhou at Fudan University, Shanghai\n" ); + Abc_Print( -2, "\t 12: new fast hybrid semi-canonical form (permutation only)\n" ); Abc_Print( -2, "\t-N <num> : the number of support variables (binary files only) [default = unused]\n" ); Abc_Print( -2, "\t-d : toggle dumping resulting functions into a file [default = %s]\n", fDumpRes? "yes": "no" ); Abc_Print( -2, "\t-b : toggle dumping in binary format [default = %s]\n", fBinary? "yes": "no" ); @@ -7309,8 +7322,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; @@ -7380,10 +7393,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; @@ -7412,8 +7436,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; @@ -7503,10 +7527,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; @@ -7771,6 +7806,64 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandResubCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose ); + char * pFileR = NULL, * pFileS = NULL; + int fVerbose = 0, c; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc == globalUtilOptind + 2 ) + { + pFileR = argv[globalUtilOptind]; + pFileS = argv[globalUtilOptind+1]; + } + else if ( argc == globalUtilOptind + 1 ) + { + pFileR = argv[globalUtilOptind]; + pFileS = NULL; + } + else + { + Abc_Print( -1, "Incorrect number of command line arguments.\n" ); + return 1; + } + Res6_ManResubCheck( pFileR, pFileS, fVerbose ); + return 0; + +usage: + Abc_Print( -2, "usage: resub_check [-vh] <file1> <file2>\n" ); + Abc_Print( -2, "\t checks solution to a resub problem\n" ); + Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t<file1> : resub problem file name\n"); + Abc_Print( -2, "\t<file2> : (optional) solution file name\n"); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandRr( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); @@ -13971,6 +14064,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) //Dau_NetworkEnumTest(); //Extra_SimulationTest( nDivMax, nNumOnes, fNewOrder ); //Mnist_ExperimentWithScaling( nDecMax ); + //Gyx_ProblemSolveTest(); return 0; usage: Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] <file_name>\n" ); @@ -19674,10 +19768,10 @@ usage: int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv ) { char * pStruct = NULL; - int c, fVerbose = 0, fFast = 0, fAdd = 0, fSpec = 0, LutSize = 0, nConfls = 10000, nProcs = 1; + int c, fVerbose = 0, fFast = 0, fAdd = 0, fSpec = 0, LutSize = 0, nConfls = 10000, nProcs = 1, nInputs = 0; If_DsdMan_t * pDsdMan = (If_DsdMan_t *)Abc_FrameReadManDsd(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCPSfasvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCPISfasvh" ) ) != EOF ) { switch ( c ) { @@ -19710,6 +19804,15 @@ int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv ) nProcs = atoi(argv[globalUtilOptind]); globalUtilOptind++; break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by a floating point number.\n" ); + goto usage; + } + nInputs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; case 'S': if ( globalUtilOptind >= argc ) { @@ -19750,18 +19853,19 @@ int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "DSD manager matched with cell %s should be cleaned by \"dsd_filter -m\" before matching with cell %s.\n", pStructCur, pStruct ); return 0; } - Id_DsdManTuneStr( pDsdMan, pStruct, nConfls, nProcs, fVerbose ); + Id_DsdManTuneStr( pDsdMan, pStruct, nConfls, nProcs, nInputs, fVerbose ); } else If_DsdManTune( pDsdMan, LutSize, fFast, fAdd, fSpec, fVerbose ); return 0; usage: - Abc_Print( -2, "usage: dsd_match [-KCP num] [-fasvh] [-S str]\n" ); + Abc_Print( -2, "usage: dsd_match [-KCPI num] [-fasvh] [-S str]\n" ); Abc_Print( -2, "\t matches DSD structures with the given cell\n" ); Abc_Print( -2, "\t-K num : LUT size used for tuning [default = %d]\n", LutSize ); Abc_Print( -2, "\t-C num : the maximum number of conflicts [default = %d]\n", nConfls ); Abc_Print( -2, "\t-P num : the maximum number of processes [default = %d]\n", nProcs ); + Abc_Print( -2, "\t-I num : skip checking if support is less than this [default = %d]\n", nInputs ); Abc_Print( -2, "\t-f : toggles using fast check [default = %s]\n", fFast? "yes": "no" ); Abc_Print( -2, "\t-a : toggles adding tuning to the current one [default = %s]\n", fAdd? "yes": "no" ); Abc_Print( -2, "\t-s : toggles using specialized check [default = %s]\n", fSpec? "yes": "no" ); @@ -21522,15 +21626,14 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk, * pNtkRes; Ssw_Pars_t Pars, * pPars = &Pars; - int nConstrs = 0; - int c; + int c, nConstrs = 0; extern Abc_Ntk_t * Abc_NtkDarSeqSweep2( Abc_Ntk_t * pNtk, Ssw_Pars_t * pPars ); pNtk = Abc_FrameReadNtk(pAbc); // set defaults Ssw_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLSIVMNcmplkodsefqvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLSIVMNXcmplkodsefqvwh" ) ) != EOF ) { switch ( c ) { @@ -21644,6 +21747,17 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nConstrs < 0 ) goto usage; break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLimitMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLimitMax < 0 ) + goto usage; + break; case 'c': pPars->fConstrs ^= 1; break; @@ -21765,7 +21879,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: scorr [-PQFCLSIVMN <num>] [-cmplkodsefqvwh]\n" ); + Abc_Print( -2, "usage: scorr [-PQFCLSIVMNX <num>] [-cmplkodsefqvwh]\n" ); Abc_Print( -2, "\t performs sequential sweep using K-step induction\n" ); Abc_Print( -2, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize ); Abc_Print( -2, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize ); @@ -21778,6 +21892,7 @@ usage: Abc_Print( -2, "\t-V num : min var num needed to recycle the SAT solver [default = %d]\n", pPars->nSatVarMax2 ); Abc_Print( -2, "\t-M num : min call num needed to recycle the SAT solver [default = %d]\n", pPars->nRecycleCalls2 ); Abc_Print( -2, "\t-N num : set last <num> POs to be constraints (use with -c) [default = %d]\n", nConstrs ); + Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax ); Abc_Print( -2, "\t-c : toggle using explicit constraints [default = %s]\n", pPars->fConstrs? "yes": "no" ); Abc_Print( -2, "\t-m : toggle full merge if constraints are present [default = %s]\n", pPars->fMergeFull? "yes": "no" ); Abc_Print( -2, "\t-p : toggle aligning polarity of SAT variables [default = %s]\n", pPars->fPolarFlip? "yes": "no" ); @@ -22088,10 +22203,11 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) int nFramesP; int nConfMax; int nVarsMax; + int nLimitMax; int fNewAlgor; int fVerbose; extern Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int fVerbose ); - extern Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int fVerbose ); + extern Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int nLimitMax, int fVerbose ); pNtk = Abc_FrameReadNtk(pAbc); @@ -22101,10 +22217,11 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) nFramesP = 0; nConfMax = 1000; nVarsMax = 1000; + nLimitMax = 0; fNewAlgor = 1; fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "PCSnvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "PCSXnvh" ) ) != EOF ) { switch ( c ) { @@ -22141,6 +22258,17 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nVarsMax < 0 ) goto usage; break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + nLimitMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLimitMax < 0 ) + goto usage; + break; case 'n': fNewAlgor ^= 1; break; @@ -22174,7 +22302,7 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) // get the new network if ( fNewAlgor ) - pNtkRes = Abc_NtkDarLcorrNew( pNtk, nVarsMax, nConfMax, fVerbose ); + pNtkRes = Abc_NtkDarLcorrNew( pNtk, nVarsMax, nConfMax, nLimitMax, fVerbose ); else pNtkRes = Abc_NtkDarLcorr( pNtk, nFramesP, nConfMax, fVerbose ); if ( pNtkRes == NULL ) @@ -22187,11 +22315,12 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: lcorr [-PCS num] [-nvh]\n" ); + Abc_Print( -2, "usage: lcorr [-PCSX num] [-nvh]\n" ); Abc_Print( -2, "\t computes latch correspondence using 1-step induction\n" ); Abc_Print( -2, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP ); Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfMax ); Abc_Print( -2, "\t-S num : the max number of SAT variables [default = %d]\n", nVarsMax ); + Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", nLimitMax ); Abc_Print( -2, "\t-n : toggle using new algorithm [default = %s]\n", fNewAlgor? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); @@ -25822,6 +25951,117 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9Kissat( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + extern void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int nConfs, int nTimeLimit, int fSat, int fUnsat, int fPrintCex, int fVerbose ); + int c, nConfs = 0, nTimeLimit = 0, fSat = 0, fUnsat = 0, fPrintCex = 0, fVerbose = 0; + char * pArgs = NULL; + + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CTAsucvh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + nConfs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nConfs < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + nTimeLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nTimeLimit < 0 ) + goto usage; + break; + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by a file name.\n" ); + goto usage; + } + pArgs = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 's': + fSat ^= 1; + break; + case 'u': + fUnsat ^= 1; + break; + case 'c': + fPrintCex ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + + default: + goto usage; + } + } + if ( argc == globalUtilOptind + 1 ) + { + Gia_ManKissatCall( pAbc, argv[globalUtilOptind], pArgs, nConfs, nTimeLimit, fSat, fUnsat, fPrintCex, fVerbose ); + return 0; + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" ); + return 1; + } + else + { + int nLutSize = 8; + int fCnfObjIds = 0; + int fAddOrCla = 1; + char * pFileName = "_temp_.cnf"; + Mf_ManDumpCnf( pAbc->pGia, pFileName, nLutSize, fCnfObjIds, fAddOrCla, fVerbose ); + Gia_ManKissatCall( pAbc, pFileName, pArgs, nConfs, nTimeLimit, fSat, fUnsat, fPrintCex, fVerbose ); + unlink( pFileName ); + } + return 0; + +usage: + Abc_Print( -2, "usage: &kissat [-CT num] [-sucvh] [-A string] <file.cnf>\n" ); + Abc_Print( -2, "\t run SAT solver Kissat, by Armin Biere (https://github.com/arminbiere/kissat)\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfs ); + Abc_Print( -2, "\t-T num : runtime limit in seconds [default = %d]\n", nTimeLimit ); + Abc_Print( -2, "\t-s : expect a satisfiable problem [default = %s]\n", fSat ? "yes": "no" ); + Abc_Print( -2, "\t-u : expect an unsatisfiable problem [default = %s]\n", fUnsat ? "yes": "no" ); + Abc_Print( -2, "\t-c : prints satisfying assignment if satisfiable [default = %s]\n", fPrintCex ? "yes": "no" ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", fVerbose ? "yes": "no" ); + Abc_Print( -2, "\t-A num : string containing additional command-line args for the Kissat binary [default = %s]\n", pArgs ? pArgs : "unused" ); + Abc_Print( -2, "\t (in particular, <&kissat -A \"--help\"> prints all command-line args of Kissat)\n" ); + Abc_Print( -2, "\t<file.cnf> : (optional) CNF file to solve\n"); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandPSat( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); @@ -29960,6 +30200,7 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc3_ReadShowHie( char * pFileName, int fFlat ); extern Gia_Man_t * Gia_MiniAigSuperDerive( char * pFileName, int fVerbose ); extern Gia_Man_t * Gia_FileSimpleRead( char * pFileName, int fNames, char * pFileW ); + extern Gia_Man_t * Gia_ManCreateXors( Gia_Man_t * p ); Gia_Man_t * pAig = NULL; FILE * pFile; char ** pArgvNew; @@ -29972,8 +30213,9 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) int fGiaSimple = 0; int fSkipStrash = 0; int fNewReader = 0; + int fDetectXors = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "csmnlpvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "csxmnlpvh" ) ) != EOF ) { switch ( c ) { @@ -29983,6 +30225,9 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) case 's': fSkipStrash ^= 1; break; + case 'x': + fDetectXors ^= 1; + break; case 'm': fMiniAig ^= 1; break; @@ -30037,16 +30282,25 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) // else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) ) // Abc3_ReadShowHie( FileName, fSkipStrash ); else + { pAig = Gia_AigerRead( FileName, fGiaSimple, fSkipStrash, 0 ); + if ( fDetectXors ) + { + Gia_Man_t * pTemp; + pAig = Gia_ManCreateXors( pTemp = pAig ); + Gia_ManStop( pTemp ); + } + } if ( pAig ) Abc_FrameUpdateGia( pAbc, pAig ); return 0; usage: - Abc_Print( -2, "usage: &r [-csmnlvh] <file>\n" ); + Abc_Print( -2, "usage: &r [-csxmnlvh] <file>\n" ); Abc_Print( -2, "\t reads the current AIG from the AIGER file\n" ); Abc_Print( -2, "\t-c : toggles reading simple AIG [default = %s]\n", fGiaSimple? "yes": "no" ); Abc_Print( -2, "\t-s : toggles structural hashing while reading [default = %s]\n", !fSkipStrash? "yes": "no" ); + Abc_Print( -2, "\t-x : toggles detecting XORs while reading [default = %s]\n", fDetectXors? "yes": "no" ); Abc_Print( -2, "\t-m : toggles reading MiniAIG rather than AIGER file [default = %s]\n", fMiniAig? "yes": "no" ); Abc_Print( -2, "\t-n : toggles reading MiniAIG as a set of supergates [default = %s]\n", fMiniAig2? "yes": "no" ); Abc_Print( -2, "\t-l : toggles reading MiniLUT rather than AIGER file [default = %s]\n", fMiniLut? "yes": "no" ); @@ -32598,9 +32852,10 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) int fNormal = 0; int fRevFans = 0; int fRevOuts = 0; + int fLeveled = 0; int fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "nfovh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "nfolvh" ) ) != EOF ) { switch ( c ) { @@ -32613,6 +32868,9 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'o': fRevOuts ^= 1; break; + case 'l': + fLeveled ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -32627,7 +32885,9 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Dfs(): There is no AIG.\n" ); return 1; } - if ( fNormal ) + if ( fLeveled ) + pTemp = Gia_ManDupLevelized( pAbc->pGia ); + else if ( fNormal ) pTemp = Gia_ManDupOrderAiger( pAbc->pGia ); else pTemp = Gia_ManDupOrderDfsReverse( pAbc->pGia, fRevFans, fRevOuts ); @@ -32635,12 +32895,13 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &dfs [-nfovh]\n" ); + Abc_Print( -2, "usage: &dfs [-nfolvh]\n" ); Abc_Print( -2, "\t orders objects in the DFS order\n" ); - Abc_Print( -2, "\t-n : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle using reverse fanin traversal order [default = %s]\n", fRevFans? "yes": "no" ); + Abc_Print( -2, "\t-n : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle using reverse fanin traversal order [default = %s]\n", fRevFans? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using reverse output traversal order [default = %s]\n", fRevOuts? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-l : toggle using levelized order [default = %s]\n", fLeveled? "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; } @@ -32794,7 +33055,7 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Sim2( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose ); + extern int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int TimeLimit, int fVerbose ); Gia_Man_t * pGias[2]; FILE * pFile; char ** pArgvNew; int nArgcNew; int c, RetValue = 0, fVerbose = 0, nWords = 16, nRounds = 10, RandSeed = 1, TimeLimit = 0; @@ -32941,7 +33202,7 @@ int Abc_CommandAbc9Sim2( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "The number of COs does not match.\n" ); return 1; } - RetValue = Gia_ManSimTwo( pGias[0], pGias[1], nWords, nRounds, fVerbose ); + RetValue = Gia_ManSimTwo( pGias[0], pGias[1], nWords, nRounds, TimeLimit, fVerbose ); if ( pGias[0] != pAbc->pGia ) Gia_ManStopP( &pGias[0] ); Gia_ManStopP( &pGias[1] ); @@ -36374,7 +36635,7 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) Cec_ManCorSetDefaultParams( pPars ); pPars->fLatchCorr = 1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "FCPrcvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "FCPXrcvwh" ) ) != EOF ) { switch ( c ) { @@ -36411,6 +36672,17 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nPrefix < 0 ) goto usage; break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLimitMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLimitMax < 0 ) + goto usage; + break; case 'r': pPars->fUseRings ^= 1; break; @@ -36453,11 +36725,12 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &lcorr [-FCP num] [-rcvwh]\n" ); + Abc_Print( -2, "usage: &lcorr [-FCPX num] [-rcvwh]\n" ); Abc_Print( -2, "\t performs latch correpondence computation\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); Abc_Print( -2, "\t-P num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix ); + Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax ); Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); @@ -36486,7 +36759,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Cec_ManCorSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "FCPpkrecqwvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "FCPXpkrecqwvh" ) ) != EOF ) { switch ( c ) { @@ -36523,6 +36796,17 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nPrefix < 0 ) goto usage; break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLimitMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLimitMax < 0 ) + goto usage; + break; case 'p': fPartition ^= 1; break; @@ -36580,11 +36864,12 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &scorr [-FCP num] [-pkrecqwvh]\n" ); + Abc_Print( -2, "usage: &scorr [-FCPX num] [-pkrecqwvh]\n" ); Abc_Print( -2, "\t performs signal correpondence computation\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); Abc_Print( -2, "\t-P num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix ); + Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax ); Abc_Print( -2, "\t-p : toggle using partitioning for the input AIG [default = %s]\n", fPartition? "yes": "no" ); Abc_Print( -2, "\t-k : toggle using constant correspondence [default = %s]\n", pPars->fConstCorr? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" ); @@ -36910,11 +37195,14 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Gia_Man_t * Cec2_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec3_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); + extern void Cec4_ManSimulateTest5( Gia_Man_t * p, int nConfs, int fVerbose ); + extern Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars, int fCbs, int approxLim, int subBatchSz, int adaRecycle ); Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp; - int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoG2 = 0; + int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoX = 0, fUseAlgoY = 0, fUseSave = 0; + int fCbs = 1, approxLim = 600, subBatchSz = 1, adaRecycle = 500; Cec4_ManSetParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxwvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxyswvh" ) ) != EOF ) { switch ( c ) { @@ -37039,7 +37327,13 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) fUseAlgoG ^= 1; break; case 'x': - fUseAlgoG2 ^= 1; + fUseAlgoX ^= 1; + break; + case 'y': + fUseAlgoY ^= 1; + break; + case 's': + fUseSave ^= 1; break; case 'w': pPars->fVeryVerbose ^= 1; @@ -37056,19 +37350,32 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Fraig(): There is no AIG.\n" ); return 1; } - if ( fUseAlgo ) + if ( fUseSave ) + { + Cec4_ManSimulateTest5( pAbc->pGia, pPars->nBTLimit, pPars->fVerbose ); + return 0; + } + else if ( fUseAlgo ) pTemp = Cec2_ManSimulateTest( pAbc->pGia, pPars ); else if ( fUseAlgoG ) pTemp = Cec3_ManSimulateTest( pAbc->pGia, pPars ); - else if ( fUseAlgoG2 ) + else if ( fUseAlgoX ) pTemp = Cec4_ManSimulateTest( pAbc->pGia, pPars ); - else + else if ( fUseAlgoY ) + pTemp = Cec5_ManSimulateTest( pAbc->pGia, pPars, fCbs, approxLim, subBatchSz, adaRecycle ); + else pTemp = Cec_ManSatSweeping( pAbc->pGia, pPars, 0 ); + if ( pAbc->pGia->pCexSeq != NULL ) + { + pAbc->Status = 0; + pAbc->nFrames = 0; + Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); + } Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &fraig [-JWRILDCNP <num>] [-rmdckngwvh]\n" ); + Abc_Print( -2, "usage: &fraig [-JWRILDCNP <num>] [-rmdckngxyswvh]\n" ); Abc_Print( -2, "\t performs combinational SAT sweeping\n" ); Abc_Print( -2, "\t-J num : the solver type [default = %d]\n", pPars->jType ); Abc_Print( -2, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords ); @@ -37086,6 +37393,9 @@ usage: Abc_Print( -2, "\t-k : toggle using logic cones in the SAT solver [default = %s]\n", pPars->fUseCones? "yes": "no" ); Abc_Print( -2, "\t-n : toggle using new implementation [default = %s]\n", fUseAlgo? "yes": "no" ); Abc_Print( -2, "\t-g : toggle using another new implementation [default = %s]\n", fUseAlgoG? "yes": "no" ); + Abc_Print( -2, "\t-x : toggle using another new implementation [default = %s]\n", fUseAlgoX? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle using another new implementation [default = %s]\n", fUseAlgoY? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle dumping equivalences into a file [default = %s]\n", fUseSave? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing even more verbose information [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); @@ -37663,10 +37973,10 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) FILE * pFile; Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; char ** pArgvNew; - int c, nArgcNew, fUseSim = 0, fUseNew = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; + int c, nArgcNew, fUseSim = 0, fUseNewX = 0, fUseNewY = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; Cec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxtvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxytvwh" ) ) != EOF ) { switch ( c ) { @@ -37708,7 +38018,10 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->fSilent ^= 1; break; case 'x': - fUseNew ^= 1; + fUseNewX ^= 1; + break; + case 'y': + fUseNewY ^= 1; break; case 't': fUseSim ^= 1; @@ -37865,7 +38178,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, !fUseNewX && !fUseNewY, 0, 0, pPars->fVerbose ); + Gia_ManStop( pGias0 ); + Gia_ManStop( pGias1 ); + } + else + pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNewX && !fUseNewY, 0, 0, pPars->fVerbose ); + if ( pMiter ) { if ( fDumpMiter ) @@ -37896,7 +38224,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Networks are UNDECIDED. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } - else if ( fUseNew ) + else if ( fUseNewX ) { abctime clk = Abc_Clock(); extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); @@ -37908,6 +38236,18 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Gia_ManStop( pNew ); } + else if ( fUseNewY ) + { + abctime clk = Abc_Clock(); + extern Gia_Man_t * Cec5_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); + Gia_Man_t * pNew = Cec5_ManSimulateTest3( pMiter, pPars->nBTLimit, pPars->fVerbose ); + if ( Gia_ManAndNum(pNew) == 0 ) + Abc_Print( 1, "Networks are equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Gia_ManStop( pNew ); + } else { pAbc->Status = Cec_ManVerify( pMiter, pPars ); @@ -37921,7 +38261,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxtvwh]\n" ); + Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxytvwh]\n" ); Abc_Print( -2, "\t new combinational equivalence checker\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); @@ -37930,7 +38270,8 @@ usage: Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no"); Abc_Print( -2, "\t-a : toggle writing dual-output miter [default = %s]\n", fDumpMiter? "yes":"no"); Abc_Print( -2, "\t-s : toggle silent operation [default = %s]\n", pPars->fSilent ? "yes":"no"); - Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNew? "yes":"no"); + Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNewX? "yes":"no"); + Abc_Print( -2, "\t-y : toggle using new solver [default = %s]\n", fUseNewY? "yes":"no"); Abc_Print( -2, "\t-t : toggle using simulation [default = %s]\n", fUseSim? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-w : toggle printing SAT solver statistics [default = %s]\n", pPars->fVeryVerbose? "yes":"no"); @@ -37949,6 +38290,191 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9ICec( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Cec_ParCec_t ParsCec, * pPars = &ParsCec; + FILE * pFile; + Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; + char ** pArgvNew; + int c, nArgcNew, fUseNew = 0, fDumpMiter = 0; + Cec_ManCecSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CTaxvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBTLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBTLimit < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->TimeLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->TimeLimit < 0 ) + goto usage; + break; + case 'a': + fDumpMiter ^= 1; + break; + case 'x': + fUseNew ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fVeryVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew > 2 ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" ); + return 1; + } + if ( nArgcNew == 2 ) + { + char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp; + int n; + for ( n = 0; n < 2; n++ ) + { + // fix the wrong symbol + for ( pTemp = pFileNames[n]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( pFileNames[n], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] ); + if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 ); + if ( pGias[n] == NULL ) + { + Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] ); + return 0; + } + } + } + else + { + char * FileName, * pTemp; + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" ); + return 1; + } + pGias[0] = pAbc->pGia; + if ( nArgcNew == 1 ) + FileName = pArgvNew[0]; + else + { + assert( nArgcNew == 0 ); + if ( pAbc->pGia->pSpec == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } + FileName = pAbc->pGia->pSpec; + } + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pGias[1] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + } + // compute the miter + pMiter = Gia_ManMiterInverse( pGias[0], pGias[1], !fUseNew, pPars->fVerbose ); + if ( pMiter ) + { + if ( fDumpMiter ) + { + Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "cec_miter.aig" ); + Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0, 0 ); + } + if ( fUseNew ) + { + abctime clk = Abc_Clock(); + extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); + Gia_Man_t * pNew = Cec4_ManSimulateTest3( pMiter, pPars->nBTLimit, pPars->fVerbose ); + if ( Gia_ManAndNum(pNew) == 0 ) + Abc_Print( 1, "Networks are equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Gia_ManStop( pNew ); + } + else + { + pAbc->Status = Cec_ManVerify( pMiter, pPars ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); + } + Gia_ManStop( pMiter ); + } + if ( pGias[0] != pAbc->pGia ) + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); + return 0; + +usage: + Abc_Print( -2, "usage: &icec [-CT num] [-axvwh]\n" ); + Abc_Print( -2, "\t combinational equivalence checker for inverse circuits\n" ); + Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); + Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); + Abc_Print( -2, "\t-a : toggle writing the miter [default = %s]\n", fDumpMiter? "yes":"no"); + Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNew? "yes":"no"); + Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); + Abc_Print( -2, "\t-w : toggle printing SAT solver statistics [default = %s]\n", pPars->fVeryVerbose? "yes":"no"); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Verify( Abc_Frame_t * pAbc, int argc, char ** argv ) { char * pFileSpec = NULL; @@ -39699,6 +40225,68 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9Sif( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_ManTestSif( Gia_Man_t * p, int nLutSize, int fVerbose ); + Gia_Man_t * pNew; + int c, nLutSize = 6, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by a positive integer.\n" ); + goto usage; + } + nLutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLutSize < 2 || nLutSize > 16 ) + { + Abc_Print( -1, "LUT size %d is not supported.\n", nLutSize ); + goto usage; + } + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Empty GIA network.\n" ); + return 1; + } + pNew = Gia_ManTestSif( pAbc->pGia, nLutSize, fVerbose ); + if ( pNew != NULL ) + Abc_FrameUpdateGia( pAbc, pNew ); + return 0; + +usage: + Abc_Print( -2, "usage: &sif [-K num] [-vh]\n" ); + Abc_Print( -2, "\t performs technology mapping\n" ); + Abc_Print( -2, "\t-K num : sets the LUT size for the mapping [default = %d]\n", nLutSize ); + Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : prints the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Jf( Abc_Frame_t * pAbc, int argc, char ** argv ) { char Buffer[200]; @@ -43491,6 +44079,144 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9RevEng( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManCompareSims( Gia_Man_t * pHie, Gia_Man_t * pFlat, int nWords, int fVerbose ); + Gia_Man_t * pGia0, * pGia1; + char ** pArgvNew; int nArgcNew; + int c, nWords = 4, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Wvh" ) ) != EOF ) + { + switch ( c ) + { + case 'W': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); + goto usage; + } + nWords = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nWords < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9RevEng(): There is no AIG.\n" ); + return 1; + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew != 1 ) + { + Abc_Print( -1, "Abc_CommandAbc9RevEng(): This command expects one AIG file name on the command line.\n" ); + return 1; + } + pGia0 = pAbc->pGia; + pGia1 = Gia_AigerRead( pArgvNew[0], 0, 0, 0 ); + if ( pGia0 == NULL || pGia1 == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9RevEng(): Reading input files did not work.\n" ); + return 1; + } + Gia_ManCompareSims( pGia0, pGia1, nWords, fVerbose ); + Gia_ManStop( pGia1 ); + return 0; + +usage: + Abc_Print( -2, "usage: &reveng [-W num] [-vh] <file>\n" ); + Abc_Print( -2, "\t compares two AIGs for structural similarity\n" ); + Abc_Print( -2, "\t the current AIG is expected to contain some hierarchy\n" ); + Abc_Print( -2, "\t the given AIG from <file> is expected to be flat\n" ); + Abc_Print( -2, "\t-W num : the number of 64-bit words of simulation info [default = %d]\n", nWords ); + 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_CommandAbc9Uif( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_ManDupUif( Gia_Man_t * p ); + extern Gia_Man_t * Gia_ManDupBlackBox( Gia_Man_t * p ); + Gia_Man_t * pNew = NULL, * pTemp = NULL; + int c, fBlackBox = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fBlackBox ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Uif(): There is no AIG.\n" ); + return 1; + } + if ( pAbc->pGia->vBarBufs == NULL || Vec_IntSize(pAbc->pGia->vBarBufs) == 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9Uif(): Hierarchy is not defined.\n" ); + return 1; + } + pNew = Gia_ManDupUif( pAbc->pGia ); + if ( fBlackBox ) + { + pNew = Gia_ManDupBlackBox( pTemp = pNew ); + Gia_ManStop( pTemp ); + } + Abc_FrameUpdateGia( pAbc, pNew ); + return 0; + +usage: + Abc_Print( -2, "usage: &uif [-bvh]\n" ); + Abc_Print( -2, "\t eagerly adds UIF constraints when hierarchy is present\n" ); + Abc_Print( -2, "\t-b : toggle blackboxing while adding constraints [default = %s]\n", fBlackBox? "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_CommandAbc9CexInfo( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern void Bmc_CexTest( Gia_Man_t * p, Abc_Cex_t * pCex, int fVerbose ); @@ -43612,9 +44338,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; Vec_Int_t * vPos; - int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fVerbose = 0; + int c, nRegs = 0, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fComb = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaevh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaecvh" ) ) != EOF ) { switch ( c ) { @@ -43679,6 +44405,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'e': fExtractAll ^= 1; break; + case 'c': + fComb ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -43742,20 +44471,27 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameUpdateGia( pAbc, pTemp ); return 0; } + nRegs = Gia_ManRegNum( pAbc->pGia ); + if ( fComb ) + pAbc->pGia->nRegs = 0; if ( iOutNum < 0 || iOutNum + nOutRange > Gia_ManPoNum(pAbc->pGia) ) { Abc_Print( -1, "Abc_CommandAbc9Cone(): Range of outputs to extract is incorrect.\n" ); + if ( fComb ) + Gia_ManSetRegNum( pAbc->pGia, nRegs ); return 1; } vPos = Vec_IntStartRange( iOutNum, nOutRange ); pTemp = Gia_ManDupCones( pAbc->pGia, Vec_IntArray(vPos), nOutRange, !fUseAllCis ); + if ( fComb ) + Gia_ManSetRegNum( pAbc->pGia, nRegs ); Vec_IntFree( vPos ); if ( pTemp ) Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &cone [-ORPLW num] [-aevh]\n" ); + Abc_Print( -2, "usage: &cone [-ORPLW num] [-aecvh]\n" ); Abc_Print( -2, "\t extracting multi-output sequential logic cones\n" ); Abc_Print( -2, "\t-O num : the index of first PO to extract [default = %d]\n", iOutNum ); Abc_Print( -2, "\t-R num : (optional) the number of outputs to extract [default = %d]\n", nOutRange ); @@ -43764,6 +44500,7 @@ usage: Abc_Print( -2, "\t-W num : (optional) extract cones falling into this window [default = %d]\n", nTimeWindow ); Abc_Print( -2, "\t-a : toggle keeping all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" ); Abc_Print( -2, "\t-e : toggle writing all outputs into individual files [default = %s]\n", fExtractAll? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle performing cone extraction combinationally [default = %s]\n", fComb? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 483f65b9..76c7cf54 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -658,6 +658,33 @@ Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkFromGiaCollapse( Gia_Man_t * pGia ) +{ + Aig_Man_t * pMan = Gia_ManToAig( pGia, 0 ); int Res; + Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan ), * pTemp; + //pNtk->pName = Extra_UtilStrsav(pGia->pName); + Aig_ManStop( pMan ); + // collapse the network + pNtk = Abc_NtkCollapse( pTemp = pNtk, 10000, 0, 1, 0, 0, 0 ); + Abc_NtkDelete( pTemp ); + if ( pNtk == NULL ) + return 0; + Res = Abc_NtkGetBddNodeNum( pNtk ); + Abc_NtkDelete( pNtk ); + return Res == 0; +} + /**Function************************************************************* @@ -1204,7 +1231,11 @@ Abc_Ntk_t * Abc_NtkFromDarChoices( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) Aig_ManForEachCo( pMan, pObj, i ) Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) ); if ( !Abc_NtkCheck( pNtkNew ) ) - Abc_Print( 1, "Abc_NtkFromDar(): Network check has failed.\n" ); + { + Abc_Print( 1, "Abc_NtkFromDar(): Network check has failed. Returning original network.\n" ); + Abc_NtkDelete( pNtkNew ); + pNtkNew = Abc_NtkDup( pNtkOld ); + } // verify topological order if ( 0 ) @@ -2271,7 +2302,7 @@ Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int f SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int fVerbose ) +Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int nLimitMax, int fVerbose ) { Ssw_Pars_t Pars, * pPars = &Pars; Aig_Man_t * pMan, * pTemp; @@ -2283,6 +2314,7 @@ Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, in pPars->fLatchCorrOpt = 1; pPars->nBTLimit = nConfMax; pPars->nSatVarMax = nVarsMax; + pPars->nLimitMax = nLimitMax; pPars->fVerbose = fVerbose; pMan = Ssw_SignalCorrespondence( pTemp = pMan, pPars ); Aig_ManStop( pTemp ); 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/abcNpn.c b/src/base/abci/abcNpn.c index e109a9cf..92b47c17 100644 --- a/src/base/abci/abcNpn.c +++ b/src/base/abci/abcNpn.c @@ -208,6 +208,8 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) pAlgoName = "adjustable algorithm (exact) "; else if ( NpnType == 11 ) pAlgoName = "new cost-aware exact algorithm "; + else if ( NpnType == 12 ) + pAlgoName = "new hybrid fast (P) "; assert( p->nVars <= 16 ); if ( pAlgoName ) @@ -356,6 +358,17 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) } Abc_TtHieManStop(pMan); } + else if ( NpnType == 12 ) + { + for ( i = 0; i < p->nFuncs; i++ ) + { + if ( fVerbose ) + printf( "%7d : ", i ); + uCanonPhase = Abc_TtCanonicizePerm( p->pFuncs[i], p->nVars, pCanonPerm ); + if ( fVerbose ) + Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" ); + } + } else assert( 0 ); clk = Abc_Clock() - clk; printf( "Classes =%9d ", Abc_TruthNpnCountUnique(p) ); @@ -419,7 +432,7 @@ int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int f { if ( fVerbose ) printf( "Using truth tables from file \"%s\"...\n", pFileName ); - if ( NpnType >= 0 && NpnType <= 11 ) + if ( NpnType >= 0 && NpnType <= 12 ) Abc_TruthNpnTest( pFileName, NpnType, nVarNum, fDumpRes, fBinary, fVerbose ); else printf( "Unknown canonical form value (%d).\n", NpnType ); diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c index cbf4bbb8..9de88980 100644 --- a/src/base/abci/abcNtbdd.c +++ b/src/base/abci/abcNtbdd.c @@ -237,7 +237,8 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * { Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC; assert( !Cudd_IsComplement(bFunc) ); - if ( bFunc == b1 || bFunc == a1 ) + assert( b1 == a1 ); + if ( bFunc == a1 ) return Abc_NtkCreateNodeConst1(pNtkNew); if ( bFunc == a0 ) return Abc_NtkCreateNodeConst0(pNtkNew); 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/abci/abcTiming.c b/src/base/abci/abcTiming.c index 84cda931..1341630b 100644 --- a/src/base/abci/abcTiming.c +++ b/src/base/abci/abcTiming.c @@ -608,7 +608,7 @@ void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew ) } if ( pNtkOld->pManTime->tOutLoad ) { - pNtkNew->pManTime->tOutLoad = ABC_ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtkOld) ); + pNtkNew->pManTime->tOutLoad = ABC_ALLOC( Abc_Time_t, Abc_NtkCoNum(pNtkOld) ); memcpy( pNtkNew->pManTime->tOutLoad, pNtkOld->pManTime->tOutLoad, sizeof(Abc_Time_t) * Abc_NtkCoNum(pNtkOld) ); } 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 259c9d78..98368ef8 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/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c index c10e9134..0759ca9c 100644 --- a/src/base/cmd/cmdUtils.c +++ b/src/base/cmd/cmdUtils.c @@ -20,6 +20,7 @@ #include "base/abc/abc.h" #include "base/main/mainInt.h" +#include "misc/util/utilSignal.h" #include "cmdInt.h" #include <ctype.h> @@ -462,7 +463,7 @@ FILE * CmdFileOpen( Abc_Frame_t * pAbc, char *sFileName, char *sMode, char **pFi else { // print the path/name of the resource file 'abc.rc' that is being loaded - if ( !silent && strlen(sRealName) >= 6 && strcmp( sRealName + strlen(sRealName) - 6, "abc.rc" ) == 0 ) + if ( !silent && strlen(sRealName) >= 6 && strcmp( sRealName + strlen(sRealName) - 6, "abc.rc" ) == 0 ) Abc_Print( 1, "Loading resource file \"%s\".\n", sRealName ); } } @@ -752,6 +753,90 @@ void CmdPrintTable( st__table * tTable, int fAliases ) ABC_FREE( ppNames ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int nConfs, int nTimeLimit, int fSat, int fUnsat, int fPrintCex, int fVerbose ) +{ + char Command[1000], Buffer[100]; + char * pNameWin = "kissat.exe"; + char * pNameUnix = "kissat"; + char * pKissatName = NULL; + //FILE * pFile = NULL; + + // get the names from the resource file + if ( Cmd_FlagReadByName(pAbc, "kissatwin") ) + pNameWin = Cmd_FlagReadByName(pAbc, "kissatwin"); + if ( Cmd_FlagReadByName(pAbc, "kissatunix") ) + pNameUnix = Cmd_FlagReadByName(pAbc, "kissatunix"); +/* + // check if the binary is available + if ( (pFile = fopen( pNameWin, "r" )) ) + pKissatName = pNameWin; + else if ( (pFile = fopen( pNameUnix, "r" )) ) + pKissatName = pNameUnix; + else if ( pFile == NULL ) + { + fprintf( stdout, "Cannot find Kissat binary \"%s\" or \"%s\" in the current directory.\n", pNameWin, pNameUnix ); + return; + } + fclose( pFile ); +*/ + +#ifdef _WIN32 + pKissatName = pNameWin; +#else + pKissatName = pNameUnix; +#endif + + sprintf( Command, "%s", pKissatName ); + if ( pArgs ) + { + strcat( Command, " " ); + strcat( Command, pArgs ); + } + if ( !pArgs || (strcmp(pArgs, "-h") && strcmp(pArgs, "--help")) ) + { + if ( !fVerbose ) + strcat( Command, " -q" ); + if ( !fPrintCex ) + strcat( Command, " -n" ); + if ( fSat ) + strcat( Command, " --sat" ); + if ( fUnsat ) + strcat( Command, " --unsat" ); + if ( nConfs ) + { + sprintf( Buffer, " --conflicts=%d", nConfs ); + strcat( Command, Buffer ); + } + if ( nTimeLimit ) + { + sprintf( Buffer, " --time=%d", nTimeLimit ); + strcat( Command, Buffer ); + } + strcat( Command, " " ); + strcat( Command, pFileName ); + } + if ( fVerbose ) + printf( "Running command: %s\n", Command ); + if ( Util_SignalSystem( Command ) == -1 ) + { + fprintf( stdout, "The following command has returned a strange exit status:\n" ); + fprintf( stdout, "\"%s\"\n", Command ); + } +} + + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/io/io.c b/src/base/io/io.c index 5408ccba..b8d1d7db 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -85,6 +85,7 @@ static int IoCommandWriteTruths ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteStatus ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteSmv ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteJson ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandWriteResub ( Abc_Frame_t * pAbc, int argc, char **argv ); extern void Abc_FrameCopyLTLDataBase( Abc_Frame_t *pAbc, Abc_Ntk_t * pNtk ); @@ -157,6 +158,7 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "write_status", IoCommandWriteStatus, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_smv", IoCommandWriteSmv, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_json", IoCommandWriteJson, 0 ); + Cmd_CommandAdd( pAbc, "I/O", "&write_resub", IoCommandWriteResub, 0 ); } /**Function************************************************************* @@ -1402,7 +1404,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; @@ -1429,28 +1431,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" ); @@ -1463,9 +1473,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" ); @@ -3582,19 +3592,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; @@ -3632,19 +3646,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; @@ -3797,6 +3814,57 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IoCommandWriteResub( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + extern void Gia_ManWriteResub( Gia_Man_t * p, char * pFileName ); + char * pFileName; + int c; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + goto usage; + pFileName = argv[globalUtilOptind]; + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "IoCommandWriteResub(): There is no AIG.\n" ); + return 1; + } + if ( Gia_ManCiNum(pAbc->pGia) > 20 ) + { + Abc_Print( -1, "IoCommandWriteResub(): The number of inputs is wrong.\n" ); + return 1; + } + Gia_ManWriteResub( pAbc->pGia, pFileName ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: &write_resub [-ch] <file>\n" ); + fprintf( pAbc->Err, "\t write the network in resub format\n" ); + fprintf( pAbc->Err, "\t-h : print the help message\n" ); + fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .json)\n" ); + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/io/ioWriteGml.c b/src/base/io/ioWriteGml.c index 49a90d9c..1164188f 100644 --- a/src/base/io/ioWriteGml.c +++ b/src/base/io/ioWriteGml.c @@ -61,6 +61,18 @@ void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName ) fprintf( pFile, "# GML for \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); fprintf( pFile, "graph [\n" ); + // output constant node in the AIG if it has fanouts + if ( Abc_NtkIsStrash(pNtk) ) + { + pObj = Abc_AigConst1( pNtk ); + if ( Abc_ObjFanoutNum(pObj) > 0 ) + { + fprintf( pFile, "\n" ); + fprintf( pFile, " node [ id %5d label \"%s\"\n", pObj->Id, Abc_ObjName(pObj) ); + fprintf( pFile, " graphics [ type \"ellipse\" fill \"#CCCCFF\" ]\n" ); // grey + fprintf( pFile, " ]\n" ); + } + } // output the POs fprintf( pFile, "\n" ); Abc_NtkForEachPo( pNtk, pObj, i ) 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 6e910cd8..cf7ae5df 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1930,9 +1930,9 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) // create combinational outputs in the normal manager pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL; - pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL; - pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL; - pFans3 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; + pFans1 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,2)) ) : NULL; // reset + pFans2 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; // set + pFans3 = Wlc_ObjFaninNum(pObj) > 4 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,4)) ) : NULL; // enable for ( k = 0; k < nRange; k++ ) Gia_ManAppendCo( pNew, pFans0[k] ); Gia_ManAppendCo( pNew, pFans1[0] ); @@ -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 39f1bebd..e981e0fa 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 @@ -88,7 +88,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%memabs2", Abc_CommandMemAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blastmem", Abc_CommandBlastMem, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 ); +// Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%retime", Abc_CommandRetime, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); @@ -295,7 +295,6 @@ usage: return 1; } - /**Function******************************************************************** Synopsis [] @@ -1032,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 ) { @@ -1119,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; @@ -1198,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 ); @@ -1218,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 748c104c..c1939126 100644 --- a/src/base/wln/module.make +++ b/src/base/wln/module.make @@ -1,8 +1,13 @@ 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 \ src/base/wln/wlnWriteVer.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..eb96132b --- /dev/null +++ b/src/base/wln/wlnCom.c @@ -0,0 +1,532 @@ +/**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_CommandGraft ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandHierarchy ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCollapse ( 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", "%graft", Abc_CommandGraft, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%hierarchy", Abc_CommandHierarchy, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%collapse", Abc_CommandCollapse, 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_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wln_LibGraftOne( Rtl_Lib_t * p, char ** pModules, int nModules, int fInv, int fVerbose ); + Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); + char ** pArgvNew; int nArgcNew; + int c, fInv = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "ivh" ) ) != EOF ) + { + switch ( c ) + { + case 'i': + fInv ^= 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; + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew != 0 && nArgcNew != 2 ) + { + Abc_Print( -1, "Abc_CommandGraft(): This command expects one AIG file name on the command line.\n" ); + return 1; + } + Wln_LibGraftOne( pLib, pArgvNew, nArgcNew, fInv, fVerbose ); + return 0; +usage: + Abc_Print( -2, "usage: %%graft [-ivh] <module1_name> <module2_name>\n" ); + Abc_Print( -2, "\t replace instances of module1 by those of module2\n" ); + Abc_Print( -2, "\t-i : toggle using inverse grafting [default = %s]\n", fInv? "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_CommandHierarchy( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wln_LibMarkHierarchy( Rtl_Lib_t * p, char ** ppModule, int nModules, int fVerbose ); + Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); + char ** pArgvNew; int nArgcNew; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pLib == NULL ) + { + printf( "The design is not entered.\n" ); + return 1; + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew < 0 ) + { + Abc_Print( -1, "Abc_CommandHierarchy(): This command expects one AIG file name on the command line.\n" ); + return 1; + } + Wln_LibMarkHierarchy( pLib, pArgvNew, nArgcNew, fVerbose ); + return 0; +usage: + Abc_Print( -2, "usage: %%hierarchy [-vh] <module_name>\n" ); + Abc_Print( -2, "\t marks the module whose instances may later be treated as black boxes\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose ); + Gia_Man_t * pNew = NULL; + Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); + char * pTopModule = NULL; + int c, fInv = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Tcvh" ) ) != 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': + fInv ^= 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; + } + pNew = Rtl_LibCollapse( pLib, pTopModule, fVerbose ); + if ( fInv ) + Gia_ManInvertPos( pNew ); + Abc_FrameUpdateGia( pAbc, pNew ); + return 0; +usage: + Abc_Print( -2, "usage: %%collapse [-T <module>] [-cvh] <file_name>\n" ); + Abc_Print( -2, "\t collapse hierarchical design into an AIG\n" ); + Abc_Print( -2, "\t-T : specify the top module of the design [default = none]\n" ); + Abc_Print( -2, "\t-c : toggle complementing miter outputs after collapsing [default = %s]\n", fInv? "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, int fInv ); + 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, 0 ); + 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..a27d38d2 --- /dev/null +++ b/src/base/wln/wlnRead.c @@ -0,0 +1,2866 @@ +/**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 * vDirects; // direct equivalences + Vec_Int_t * vInverses; // inverse equivalences + 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 + int fRoot; // denote root network +}; + +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 ); +extern int Abc_NtkFromGiaCollapse( Gia_Man_t * pGia ); +extern int Wln_ReadFindToken( char * pToken, Abc_Nam_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// 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->vDirects ); + Vec_IntFreeP( &p->vInverses ); + 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 if ( iNtk1 == -1 ) + return -1; + else + { + int Counts1[4] = {0}, Counts2[4] = {0}; + int iNtk2 = Rtl_LibFindModule( p, Name2 ); + if ( iNtk2 == -1 ) + return -1; + else + { + 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 ); +} +int Rtl_LibCountInsts( Rtl_Lib_t * p, Rtl_Ntk_t * pOne ) +{ + Rtl_Ntk_t * pNtk; int n, i, * pCell, Count = 0; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, n ) + Rtl_NtkForEachCell( pNtk, pCell, i ) + { + Rtl_Ntk_t * pMod = Rtl_CellNtk( pNtk, pCell ); + if ( pMod && pMod == pOne ) + Count++; + } + return Count; +} +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 void Rtl_NtkPrintBufs( Rtl_Ntk_t * p, Vec_Int_t * vBufs ); + 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, int fBufs ); + extern int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts ); + Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); + int nIns = 0, nOuts = 0, nOuts1, iFirst1 = Gia_ManFindFirst( pModel, &nOuts1 ); + int k, Par, Val, iThis = -1, nBits = 0; + //int fFound = 0; + int fFound = p->pLib->vInverses && (iThis = Vec_IntFind(p->pLib->vInverses, pModel->NameId)) >= 0; + //int iThat = fFound ? Vec_IntEntry( p->pLib->vInverses, iThis ^ 1 ) : -1; + Vec_IntClear( &p->vBitTemp ); + Rtl_CellForEachInput( p, pCell, Par, Val, k ) + Rtl_NtkCollectSignalRange( p, Val ); + assert( pModel->pGia ); + if ( fFound ) + { + nIns = nOuts1; + Vec_IntForEachEntry( &p->vBitTemp, Val, k ) + Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val ); + Vec_IntPush( pNew->vBarBufs, (nIns << 16) | Abc_Var2Lit(pModel->NameId, 0) ); + } + else if ( pModel->fRoot ) + { + nIns = Vec_IntSize(&p->vBitTemp); + Vec_IntForEachEntry( &p->vBitTemp, Val, k ) + //Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val ); + Vec_IntWriteEntry( &p->vBitTemp, k, Gia_ManAppendBuf(pNew, Val) ); + Vec_IntPush( pNew->vBarBufs, (nIns << 16) | Abc_Var2Lit(pModel->NameId, 0) ); + } + if ( fFound || pModel->fRoot ) + Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, 0 ); + else + { + Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, 1 ); + Vec_IntAppend( pNew->vBarBufs, pModel->pGia->vBarBufs ); + } + if ( pModel->fRoot || fFound ) + { + nOuts = Vec_IntSize(&p->vBitTemp); + Vec_IntForEachEntry( &p->vBitTemp, Val, k ) + Vec_IntWriteEntry( &p->vBitTemp, k, Gia_ManAppendBuf(pNew, Val) ); + Vec_IntPush( pNew->vBarBufs, (nOuts << 16) | Abc_Var2Lit(pModel->NameId, 1) ); + printf( "Added %d input buffers and %d output buffers for module %s.\n", nIns, nOuts, Rtl_NtkName(pModel) ); + } + 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; +} +void Rtl_NtkPrintBufOne( Rtl_Lib_t * p, int Lit ) +{ + printf( "%s (%c%d) ", Rtl_LibStr(p, Abc_Lit2Var(Lit&0xFFFF)), Abc_LitIsCompl(Lit)? 'o' : 'i', Lit >> 16 ); +} +void Rtl_NtkPrintBufs( Rtl_Ntk_t * p, Vec_Int_t * vBufs ) +{ + int i, Lit; + if ( Vec_IntSize(vBufs) ) + printf( "Found %d buffers (%d groups): ", p->pGia->nBufs, Vec_IntSize(vBufs) ); + Vec_IntForEachEntry( vBufs, Lit, i ) + Rtl_NtkPrintBufOne( p->pLib, Lit ); + if ( Vec_IntSize(vBufs) ) + printf( "\n" ); +} +Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ) +{ + int fDump = 0; + Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 ); + int i, iObj, * pCell, nBits = Rtl_NtkRangeWires( p ); + 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 ); + if ( fDump ) + { + char Buffer[100]; static int counter = 0; + 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) ); + } + else + printf( "Derived AIG for module %-20s : ", 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 ) +{ + int fDump = 0; + Gia_Man_t * pTemp; + int i, b, nBits = Rtl_NtkRangeWires( p ); + 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 ); + p->pGia->vBarBufs = Vec_IntAlloc( 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 ); + ABC_SWAP( Vec_Int_t *, p->pGia->vBarBufs, pTemp->vBarBufs ); + Gia_ManStop( pTemp ); +// if ( p->fRoot ) +// Rtl_NtkPrintBufs( p, p->pGia->vBarBufs ); + if ( fDump ) + { + char Buffer[100]; static int counter = 0; + sprintf( Buffer, "old%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) ); + } + else + printf( "Derived AIG for module %-20s : ", 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, int fInv ) +{ + 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;//, pNtk->fRoot = 0; + Vec_IntForEachEntry( vRoots, iNtk, i ) + { + Rtl_Ntk_t * pNtk = Rtl_LibNtk(pLib, iNtk); + //pNtk->fRoot = fInv; + Rtl_LibMark_rec( pNtk ); + } + } + 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, 0 ); +} +void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) +{ + extern Gia_Man_t * Gia_ManReduceBuffers( Rtl_Lib_t * pLib, Gia_Man_t * p ); + abctime clk = Abc_Clock(); int Status; + Rtl_Ntk_t * pTop = pNtk ? (Rtl_Ntk_t *)pNtk : Rtl_LibTop( pLib ); + Gia_Man_t * pGia2 = Gia_ManReduceBuffers( pLib, pTop->pGia ); + Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pGia2, 1000000, 0 ); + int RetValue = Gia_ManAndNum(pSwp); + char * pFileName = "miter_to_solve.aig"; + printf( "Dumped the miter into file \"%s\".\n", pFileName ); + Gia_AigerWrite( pGia2, pFileName, 0, 0, 0 ); + Gia_ManStop( pSwp ); + Gia_ManStop( pGia2 ); + 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 ); + if ( Abc_NtkFromGiaCollapse( pGia ) ) + Abc_Print( 1, "Networks are equivalent after collapsing. " ); + else + { + 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, 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 ); + if ( pGia->vBarBufs ) + pTemp->vBarBufs = Vec_IntDup( pGia->vBarBufs ); + Vec_IntFree( vPiPerm ); + return pTemp; +} +Vec_Int_t * Gia_ManCollectBufs( Gia_Man_t * p, int iFirst, int nBufs ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Gia_Obj_t * pObj; int i, iBuf = 0; + assert( iFirst >= 0 && iFirst + nBufs < p->nBufs ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) && iBuf >= iFirst && iBuf < iFirst + nBufs ) + Vec_IntPush( vRes, i ); + iBuf += Gia_ObjIsBuf(pObj); + } + assert( iBuf == p->nBufs ); + return vRes; +} +Gia_Man_t * Gia_ManReduceBuffers( Rtl_Lib_t * pLib, Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vOne = Gia_ManCollectBufs( p, 0, 64 ); + Vec_Int_t * vTwo = Gia_ManCollectBufs( p, 1280-64, 64 ); + //Vec_Int_t * vOne = Gia_ManCollectBufs( p, 0, 1280/2 ); + //Vec_Int_t * vTwo = Gia_ManCollectBufs( p, 1280/2, 1280/2 ); + int i, One, Two; + printf( "Reducing %d buffers... Size(vOne) = %d. Size(vTwo) = %d. \n", p->nBufs, Vec_IntSize(vOne), Vec_IntSize(vTwo) ); + assert( p->nBufs == 1280 ); + Vec_IntForEachEntryTwo( vOne, vTwo, One, Two, i ) + Vec_IntWriteEntry( vMap, Two, One ); + Vec_IntFree( vOne ); + Vec_IntFree( vTwo ); +Gia_ManPrintStats( p, NULL ); + //pNew = Gia_ManDupNoBuf( p ); + pNew = Gia_ManDupMap( p, vMap ); +Gia_ManPrintStats( pNew, NULL ); + Vec_IntFree( vMap ); + //Rtl_NtkPrintBufs( pNtk1, pGia->vBarBufs ); + //printf( "Found %d buffers.\n", p->nBufs ); + return pNew; +} +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 ) + { + char * pFileName = "inv_miter.aig"; + Gia_Man_t * pGia = Gia_ManMiterInverse( pGia1, pGia2, 0, 0 ); + //Gia_Man_t * pGia2 = Gia_ManReduceBuffers( p, pGia ); + Gia_Man_t * pGia2 = Gia_ManDupNoBuf( pGia ); + printf( "Dumping inverse miter into file \"%s\".\n", pFileName ); + Gia_AigerWrite( pGia2, pFileName, 0, 0, 0 ); + printf( "Dumped the miter into file \"%s\".\n", pFileName ); + if ( Abc_NtkFromGiaCollapse( pGia2 ) ) + Abc_Print( 1, "Networks are equivalent after collapsing. " ); + else + { + Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia2, 10000000, 0 ); + Rtl_NtkPrintBufs( pNtk1, pGia->vBarBufs ); + //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( &pGia2 ); + 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_NtkPrintBufs( pNtk, pNtk->pGia->vBarBufs ); + 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, fInv = 0; + Vec_WecForEachLevel( vGuide, vLevel, i ) + if ( Vec_IntEntry( vLevel, 1 ) == Rtl_LibStrId(p, "inverse") ) + fInv = 1; + 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, fInv ); + 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 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +static inline void Gia_ManPatchBufDriver( Gia_Man_t * p, int iObj, int iLit0 ) +{ + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + assert( iObj > Abc_Lit2Var(iLit0) ); + pObj->iDiff0 = pObj->iDiff1 = iObj - Abc_Lit2Var(iLit0); + pObj->fCompl0 = pObj->fCompl1 = Abc_LitIsCompl(iLit0); +} + +Gia_Man_t * Rtl_ReduceInverse( Rtl_Lib_t * pLib, Gia_Man_t * p ) +{ + int fVerbose = 1; + Gia_Man_t * pNew = NULL; + Vec_Wec_t * vBufs = Vec_WecStart( Vec_IntSize(p->vBarBufs) ); + Vec_Int_t * vPairs = Vec_IntAlloc( 10 ); + Vec_Int_t * vTypes = Vec_IntAlloc( p->nBufs ); + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj; int i, k = 0, Entry, Buf0, Buf1, fChange = 1; + Vec_IntForEachEntry( p->vBarBufs, Entry, i ) + Vec_IntFillExtra( vTypes, Vec_IntSize(vTypes) + (Entry >> 16), i ); + assert( Vec_IntSize(vTypes) == p->nBufs ); + Gia_ManForEachAnd( p, pObj, i ) + if ( Gia_ObjIsBuf(pObj) ) + { + Vec_WecPush( vBufs, Vec_IntEntry(vTypes, k), i ); + Vec_IntWriteEntry( vMap, i, Vec_IntEntry(vTypes, k++) ); + } + assert( k == p->nBufs ); + Gia_ManForEachAnd( p, pObj, i ) + if ( Gia_ObjIsBuf(pObj) && Gia_ObjIsBuf(Gia_ObjFanin0(pObj)) ) + Vec_IntPushUnique( vPairs, (Vec_IntEntry(vMap, Gia_ObjFaninId0(pObj, i)) << 16) | (Vec_IntEntry(vMap, i) & 0xFFFF) ); + if ( fVerbose ) + { + printf( "Connected boundaries:\n" ); + Vec_IntForEachEntry( vPairs, Entry, i ) + { + printf( "%2d -> %2d : ", Entry >> 16, Entry & 0xFFFF ); + Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry >> 16) ); + printf( " -> " ); + Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry & 0xFFFF) ); + printf( "\n" ); + } + } + while ( fChange ) + { + int Entry1, Entry2, j; + fChange = 0; + Vec_IntForEachEntryDouble( vPairs, Entry1, Entry2, j ) + if ( (Entry1 & 0xFFFF) + 1 == (Entry2 >> 16) ) + { + Vec_IntWriteEntry( vPairs, j, ((Entry1 >> 16) << 16) | (Entry2 & 0xFFFF) ); + Vec_IntDrop( vPairs, j+1 ); + fChange = 1; + break; + } + } +// printf( "Before:\n" ); +// Vec_IntForEachEntry( vPairs, Entry, i ) +// printf( "%d %d\n", Entry >> 16, Entry & 0xFFFF ); + Vec_IntForEachEntry( vPairs, Entry, i ) + Vec_IntWriteEntry( vPairs, i, (((Entry >> 16) - 1) << 16) | ((Entry & 0xFFFF) + 1) ); +// printf( "After:\n" ); +// Vec_IntForEachEntry( vPairs, Entry, i ) +// printf( "%d %d\n", Entry >> 16, Entry & 0xFFFF ); + if ( fVerbose ) + { + printf( "Transformed boundaries:\n" ); + Vec_IntForEachEntry( vPairs, Entry, i ) + { + printf( "%2d -> %2d : ", Entry >> 16, Entry & 0xFFFF ); + Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry >> 16) ); + printf( " -> " ); + Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry & 0xFFFF) ); + printf( "\n" ); + } + } + Vec_IntForEachEntry( vPairs, Entry, i ) + { + Vec_Int_t * vLevel0 = Vec_WecEntry( vBufs, Entry >> 16 ); + Vec_Int_t * vLevel1 = Vec_WecEntry( vBufs, Entry & 0xFFFF ); + Vec_IntForEachEntryTwo( vLevel0, vLevel1, Buf0, Buf1, k ) + Gia_ManPatchBufDriver( p, Buf1, Gia_ObjFaninLit0(Gia_ManObj(p, Buf0), Buf0) ); + } + pNew = Gia_ManRehash( p, 0 ); + Vec_IntFree( vPairs ); + Vec_IntFree( vTypes ); + Vec_IntFree( vMap ); + Vec_WecFree( vBufs ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rtl_LibReturnNtk( Rtl_Lib_t * p, char * pModule ) +{ + int NameId = Wln_ReadFindToken( pModule, p->pManName ); + int iNtk = NameId ? Rtl_LibFindModule( p, NameId ) : -1; + if ( iNtk == -1 ) + { + printf( "Cannot find module \"%s\" in the current design.\n", pModule ); + return -1; + } + return iNtk; +} +Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose ) +{ + Gia_Man_t * pGia = NULL; + int NameId = Wln_ReadFindToken( pTopModule, p->pManName ); + int iNtk = NameId ? Rtl_LibFindModule( p, NameId ) : -1; + if ( iNtk == -1 ) + { + printf( "Cannot find top module \"%s\".\n", pTopModule ); + return NULL; + } + else + { + abctime clk = Abc_Clock(); + Rtl_Ntk_t * pTop = Rtl_LibNtk(p, iNtk); + Vec_Int_t * vRoots = Vec_IntAlloc( 1 ); + Vec_IntPush( vRoots, iNtk ); + Rtl_LibBlast2( p, vRoots, 1 ); + pGia = Gia_ManDup( pTop->pGia ); + //Gia_AigerWrite( pGia, "temp_miter.aig", 0, 0, 0 ); + if ( pTop->pGia->vBarBufs ) + pGia->vBarBufs = Vec_IntDup( pTop->pGia->vBarBufs ); + printf( "Derived global AIG for the top module \"%s\". ", Rtl_NtkStr(pTop, NameId) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Rtl_NtkPrintBufs( pTop, pGia->vBarBufs ); + Rtl_LibBlastClean( p ); + Vec_IntFree( vRoots ); + if ( p->vInverses ) + { + Gia_Man_t * pTemp; + pGia = Rtl_ReduceInverse( p, pTemp = pGia ); + Gia_ManStop( pTemp ); + } + } + return pGia; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_LibGraftOne( Rtl_Lib_t * p, char ** pModules, int nModules, int fInv, int fVerbose ) +{ + if ( nModules == 0 ) + { + Rtl_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + pNtk->iCopy = -1; + Vec_IntFreeP( &p->vInverses ); + if ( p->vDirects ) + { + int iName1, iName2; + Vec_IntForEachEntryDouble( p->vDirects, iName1, iName2, i ) + { + int iNtk1 = Rtl_LibFindModule(p, iName1); + int iNtk2 = Rtl_LibFindModule(p, iName2); + //Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); + pNtk2->iCopy = iNtk1; + } + Rtl_LibUpdateBoxes( p ); + Rtl_LibReorderModules( p ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + pNtk->iCopy = -1; + Vec_IntFreeP( &p->vDirects ); + } + } + else + { + int Name1 = Wln_ReadFindToken( pModules[0], p->pManName ); + int Name2 = Wln_ReadFindToken( pModules[1], p->pManName ); + 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) ); + return; + } + else + { + int iNtk1 = iNtk >> 16; + int iNtk2 = iNtk & 0xFFFF; + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk(p, iNtk1); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk(p, iNtk2); + assert( iNtk1 != iNtk2 ); + if ( fInv ) + { + printf( "Setting \"%s\" (appearing %d times) and \"%s\" (appearing %d times) as inverse-equivalent.\n", + Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); + if ( p->vInverses == NULL ) + p->vInverses = Vec_IntAlloc( 10 ); + Vec_IntPushTwo( p->vInverses, pNtk1->NameId, pNtk2->NameId ); + } + else + { + printf( "Replacing \"%s\" (appearing %d times) by \"%s\" (appearing %d times).\n", + Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); + pNtk1->iCopy = iNtk2; + // Rtl_LibSetReplace( p, vGuide ); + Rtl_LibUpdateBoxes( p ); + Rtl_LibReorderModules( p ); + if ( p->vDirects == NULL ) + p->vDirects = Vec_IntAlloc( 10 ); + Vec_IntPushTwo( p->vDirects, pNtk1->NameId, pNtk2->NameId ); + } + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_LibMarkHierarchy( Rtl_Lib_t * p, char ** ppModule, int nModules, int fVerbose ) +{ + Rtl_Ntk_t * pNtk; int i; + if ( nModules == 0 ) // clean labels + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + pNtk->fRoot = 0; + for ( i = 0; i < nModules; i++ ) + { + int iNtk = Rtl_LibReturnNtk( p, ppModule[i] ); + if ( iNtk == -1 ) + continue; + pNtk = Rtl_LibNtk( p, iNtk ); + pNtk->fRoot = 1; + printf( "Marking module \"%s\" (appearing %d times in the hierarchy).\n", ppModule[i], Rtl_LibCountInsts(p, pNtk) ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c new file mode 100644 index 00000000..fa0f0cd5 --- /dev/null +++ b/src/base/wln/wlnRtl.c @@ -0,0 +1,211 @@ +/**CFile**************************************************************** + + FileName [wlnRtl.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [Constructing WLN network from Rtl data structure.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnRtl.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "base/main/main.h" + +#ifdef WIN32 +#include <process.h> +#define unlink _unlink +#else +#include <unistd.h> +#endif + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#define MAX_LINE 1000000 + +void Rtl_NtkCleanFile( char * pFileName ) +{ + 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 ); +} + +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; + char * pYosysNameWin = "yosys.exe"; + char * pYosysNameUnix = "yosys"; + if ( Abc_FrameReadFlag("yosyswin") ) + pYosysNameWin = Abc_FrameReadFlag("yosyswin"); + if ( Abc_FrameReadFlag("yosysunix") ) + pYosysNameUnix = Abc_FrameReadFlag("yosysunix"); +#ifdef WIN32 + pYosysName = pYosysNameWin; +#else + pYosysName = pYosysNameUnix; +#endif + return pYosysName; +} +int Wln_ConvertToRtl( char * pCommand, char * pFileTemp ) +{ + FILE * pFile; + if ( system( pCommand ) == -1 ) + { + fprintf( stdout, "Cannot execute \"%s\".\n", pCommand ); + return 0; + } + if ( (pFile = fopen(pFileTemp, "r")) == NULL ) + { + fprintf( stdout, "Cannot open intermediate file \"%s\".\n", pFileTemp ); + return 0; + } + fclose( pFile ); + return 1; +} +Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose ) +{ + Rtl_Lib_t * pNtk = NULL; + char Command[1000]; + char * pFileTemp = "_temp_.rtlil"; + int fSVlog = strstr(pFileName, ".sv") != NULL; + 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 " : "", + pTopModule ? pTopModule : "", + fCollapse ? "flatten; " : "", + pFileTemp ); + if ( fVerbose ) + printf( "%s\n", Command ); + if ( !Wln_ConvertToRtl(Command, pFileTemp) ) + return NULL; + 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; +} +Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ) +{ + Gia_Man_t * pGia = NULL; + char Command[1000]; + char * pFileTemp = "_temp_.aig"; + 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) ) + return NULL; + pGia = Gia_AigerRead( pFileTemp, 0, fSkipStrash, 0 ); + if ( pGia == NULL ) + { + printf( "Converting to AIG has failed.\n" ); + return NULL; + } + ABC_FREE( pGia->pName ); + pGia->pName = pTopModule ? Abc_UtilStrsav(pTopModule) : + Extra_FileNameGeneric( Extra_FileNameWithoutPath(pFileName) ); + unlink( pFileTemp ); + // complement the outputs + if ( fInvert ) + { + Gia_Obj_t * pObj; int i; + Gia_ManForEachPo( pGia, pObj, i ) + Gia_ObjFlipFaninC0( pObj ); + } + return pGia; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + |