diff --git a/.gitignore b/.gitignore index c745dfb57..cbb424152 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,4 @@ tags /cmake /cscope +abc.history diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index d4edc1237..dab6770bb 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -241,6 +241,9 @@ struct Gia_Man_t_ Vec_Int_t vSuppVars; // used variables Vec_Int_t vVarMap; // used variables Gia_Dat_t * pUData; + // retiming data + Vec_Str_t * vStopsF; + Vec_Str_t * vStopsB; }; @@ -1527,7 +1530,7 @@ extern void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose ) extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew ); extern void Gia_ManPrintNpnClasses( Gia_Man_t * p ); -extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter ); +extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter, int fInterComb ); /*=== giaMem.c ===========================================================*/ extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax ); extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 6dee2c26f..db4072d71 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -5708,8 +5708,8 @@ Gia_Man_t * Gia_ManBoundaryMiter( Gia_Man_t * p1, Gia_Man_t * p2, int fVerbose ) } Gia_ManForEachCo( p2, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - Gia_ManForEachCo( p1, pObj, i ) - Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + //Gia_ManForEachCo( p1, pObj, i ) + // Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Vec_IntForEachEntry( vLits, iLit, i ) Gia_ManAppendCo( pNew, iLit ); Vec_IntFree( vLits ); diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index e8f9bca32..2449b5df7 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -156,6 +156,8 @@ void Gia_ManStop( Gia_Man_t * p ) Vec_IntErase( &p->vHash ); Vec_IntErase( &p->vHTable ); Vec_IntErase( &p->vRefs ); + Vec_StrFreeP( &p->vStopsF ); + Vec_StrFreeP( &p->vStopsB ); ABC_FREE( p->pData2 ); ABC_FREE( p->pTravIds ); ABC_FREE( p->pPlacement ); @@ -1291,7 +1293,7 @@ void Gia_ManDumpModuleName( FILE * pFile, char * pName ) else fprintf( pFile, "_" ); } -void Gia_ManDumpInterface( Gia_Man_t * p, FILE * pFile ) +void Gia_ManDumpInterface2( Gia_Man_t * p, FILE * pFile ) { int fPrintClk = 0; fprintf( pFile, "module " ); @@ -1324,7 +1326,6 @@ void Gia_ManDumpInterface( Gia_Man_t * p, FILE * pFile ) fprintf( pFile, "endmodule\n\n" ); } - /**Function************************************************************* Synopsis [Compute arrival/required times.] @@ -1407,7 +1408,7 @@ void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Sta fFirst = 0; } } -void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter ) +void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter, int fInterComb ) { Gia_Obj_t * pObj; Vec_Bit_t * vInvs, * vUsed; @@ -1415,6 +1416,13 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) ); int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) ); int i, k, iObj, nRegs = Gia_ManRegNum(p); + if ( fInterComb ) + { + extern void Gia_ManDumpInterface( Gia_Man_t * p, char * pFileName ); + Gia_ManDumpInterface( p, pFileName ); + return; + } + FILE * pFile = fopen( pFileName, "wb" ); if ( pFile == NULL ) { @@ -1423,7 +1431,7 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int } if ( fInter || nRegs ) - Gia_ManDumpInterface( p, pFile ); + Gia_ManDumpInterface2( p, pFile ); //Gia_ManSetRegNum( p, 0 ); p->nRegs = 0; @@ -1588,6 +1596,200 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int Gia_ManSetRegNum( p, nRegs ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDumpInterface( Gia_Man_t * p, char * pFileName ) +{ + Gia_Obj_t * pObj; + Vec_Bit_t * vInvs, * vUsed; + int nDigits = Abc_Base10Log( Gia_ManObjNum(p) ); + int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) ); + int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) ); + int i; + + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Cannot open output file \"%s\".\n", pFileName ); + return; + } + + vInvs = Gia_ManGenUsed( p, 0 ); + vUsed = Gia_ManGenUsed( p, 1 ); + + fprintf( pFile, "module " ); + Gia_ManDumpModuleName( pFile, p->pName ); + fprintf( pFile, "_wrapper" ); + fprintf( pFile, " ( _i_, _o_ );\n\n" ); + fprintf( pFile, " input [%d:0] _i_;\n", Gia_ManCiNum(p)-1 ); + fprintf( pFile, " output [%d:0] _o_;\n\n", Gia_ManCoNum(p)-1 ); + + fprintf( pFile, " wire " ); + Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL ); + fprintf( pFile, ";\n\n" ); + + fprintf( pFile, " wire " ); + Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL ); + fprintf( pFile, ";\n\n" ); + + fprintf( pFile, " assign { " ); + Gia_ManWriteNames( pFile, 'x', Gia_ManCiNum(p), p->vNamesIn, 8, 4, NULL ); + fprintf( pFile, " } = _i_;\n\n" ); + + fprintf( pFile, " assign _o_ = { " ); + Gia_ManWriteNames( pFile, 'z', Gia_ManCoNum(p), p->vNamesOut, 9, 4, NULL ); + fprintf( pFile, " };\n\n" ); + + if ( Vec_BitCount(vUsed) ) + { + fprintf( pFile, " wire " ); + Gia_ManWriteNames( pFile, 'n', Gia_ManObjNum(p), NULL, 7, 4, vUsed ); + fprintf( pFile, ";\n\n" ); + } + + if ( Vec_BitCount(vInvs) ) + { + fprintf( pFile, " wire " ); + Gia_ManWriteNames( pFile, 'i', Gia_ManObjNum(p), NULL, 7, 4, vInvs ); + fprintf( pFile, ";\n\n" ); + } + + // input inverters + Gia_ManForEachCi( p, pObj, i ) + { + if ( Vec_BitEntry(vUsed, Gia_ObjId(p, pObj)) ) + { + fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) ); + fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) ); + } + if ( Vec_BitEntry(vInvs, Gia_ObjId(p, pObj)) ) + { + fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) ); + fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) ); + } + } + + // internal nodes and their inverters + fprintf( pFile, "\n" ); + Gia_ManForEachAnd( p, pObj, i ) + { + fprintf( pFile, " and ( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) ); + fprintf( pFile, " %s,", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0(pObj, i), nDigits) ); + fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC1(pObj)? 'i':'n'), Gia_ObjFaninId1(pObj, i), nDigits) ); + if ( Vec_BitEntry(vInvs, i) ) + { + fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) ); + fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) ); + } + } + + // output drivers + fprintf( pFile, "\n" ); + Gia_ManForEachCo( p, pObj, i ) + { + fprintf( pFile, " buf ( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) ) + fprintf( pFile, "1\'b%d );\n", Gia_ObjFaninC0(pObj) ); + else + fprintf( pFile, "%s );\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) ); + } + + fprintf( pFile, "\nendmodule\n\n" ); + fclose( pFile ); + + Vec_BitFree( vInvs ); + Vec_BitFree( vUsed ); +} + + +/**Function************************************************************* + + Synopsis [Generate hierarchical design.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_FreeMany( Gia_Man_t ** pGias, int nGias ) +{ + int i; + for ( i = 0; i < nGias; i++ ) + Gia_ManStopP( &pGias[i] ); +} +void Gia_GenSandwich( char ** pFNames, int nFNames, char * pFileName ) +{ + FILE * pFile = NULL; + Gia_Man_t * pGias[16] = {0}; + int i, k; + assert( nFNames <= 16 ); + for ( i = 0; i < nFNames; i++ ) + { + FILE * pFile = fopen( pFNames[i], "rb" ); + if ( pFile == NULL ) { + printf( "Cannot open input file \"%s\".\n", pFNames[i] ); + Gia_FreeMany( pGias, nFNames ); + return; + } + fclose( pFile ); + pGias[i] = Gia_AigerRead( pFNames[i], 0, 0, 0 ); + if ( pGias[i] == NULL ) { + printf( "Failed to read an AIG from file \"%s\".\n", pFNames[i] ); + Gia_FreeMany( pGias, nFNames ); + return; + } + } + for ( i = 0; i < nFNames-1; i++ ) + if ( Gia_ManPoNum(pGias[i]) < Gia_ManPiNum(pGias[i+1]) ) { + printf( "AIG in file \"%s\" has fewer outputs than inputs of AIG in file \"%s\".\n", pFNames[i], pFNames[i+1] ); + Gia_FreeMany( pGias, nFNames ); + return; + } + pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Cannot open output file \"%s\".\n", pFileName ); + Gia_FreeMany( pGias, nFNames ); + return; + } + fprintf( pFile, "\n" ); + for ( i = 0; i < nFNames; i++ ) + fprintf( pFile, "`include \"%s\"\n", Extra_FileNameGenericAppend(pGias[i]->pSpec, ".v") ); + fprintf( pFile, "\n" ); + fprintf( pFile, "module sandwich ( in, out );\n" ); + fprintf( pFile, " input [%3d:0] in;\n", Gia_ManPiNum(pGias[0])-1 ); + fprintf( pFile, " output [%3d:0] out;\n", Gia_ManPoNum(pGias[nFNames-1])-1 ); + fprintf( pFile, " wire [%3d:0] tmp0 = in;\n", Gia_ManPiNum(pGias[0])-1 ); + for ( i = 0; i < nFNames; i++ ) { + fprintf( pFile, " wire [%3d:0] tmp%d; ", Gia_ManPoNum(pGias[i])-1, i+1 ); + Gia_ManDumpModuleName( pFile, pGias[i]->pName ); + fprintf( pFile, "_wrapper" ); + for ( k = strlen(pGias[i]->pName); k < 24; k++ ) + fprintf( pFile, " " ); + fprintf( pFile, " i%d ( tmp%d, tmp%d );\n", i+1, i, i+1 ); + } + fprintf( pFile, " assign out = tmp%d;\n", nFNames ); + fprintf( pFile, "endmodule\n" ); + fclose( pFile ); + for ( i = 0; i < nFNames; i++ ) { + Gia_ManDumpVerilog( pGias[i], Extra_FileNameGenericAppend(pGias[i]->pSpec, ".v"), NULL, 0, 0, 1 ); + printf( "Dumped Verilog file \"%s\"\n", Extra_FileNameGenericAppend(pGias[i]->pSpec, ".v") ); + } + Gia_FreeMany( pGias, nFNames ); + printf( "Dumped hierarchical design into file \"%s\"\n", pFileName ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index c0473fea3..85647eac5 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -1228,6 +1228,98 @@ void Gia_MiniAigGenerateFromFile() Mini_AigStop( p ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Gia_ManRetimableF( Gia_Man_t * p, int * pRst, int * pSet, int * pEna ) +{ + Vec_Str_t * vStops = Vec_StrStart( Gia_ManObjNum(p) ); + Vec_Int_t * vTemps = Vec_IntStartFull( 3*Gia_ManObjNum(p) ); + Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i; + char * pStops = Vec_StrArray(vStops); + assert( Gia_ManRegNum(p) > 0 ); + Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) { + Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 0, pRst[i] ); + Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 1, pSet[i] ); + Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 2, pEna[i] ); + } + Gia_ManForEachAnd( p, pObj, i ) { + int * pFan0 = Vec_IntEntryP( vTemps, 3*Gia_ObjFaninId0(pObj, i) ); + int * pFan1 = Vec_IntEntryP( vTemps, 3*Gia_ObjFaninId1(pObj, i) ); + int * pNode = Vec_IntEntryP( vTemps, 3*i ); + pStops[i] = (char)1; + if ( pFan0[0] != -1 && pFan0[0] == pFan1[0] && pFan0[1] == pFan1[1] && pFan0[2] == pFan1[2] ) + pStops[i] = (char)0, pNode[0] = pFan0[0], pNode[1] = pFan0[1], pNode[2] = pFan0[2]; + } + Vec_IntFree( vTemps ); + return vStops; +} +Vec_Str_t * Gia_ManRetimableB( Gia_Man_t * p, int * pRst, int * pSet, int * pEna ) +{ + Vec_Str_t * vStops = Vec_StrStart( Gia_ManObjNum(p) ); + Vec_Int_t * vTemps = Vec_IntStartFull( 3*Gia_ManObjNum(p) ); + Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i, n; + char * pStops = Vec_StrArray(vStops); + assert( Gia_ManRegNum(p) > 0 ); + Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) { + Vec_IntWriteEntry( vTemps, 3*Gia_ObjFaninId0p(p, pObjRi) + 0, pRst[i] ); + Vec_IntWriteEntry( vTemps, 3*Gia_ObjFaninId0p(p, pObjRi) + 1, pSet[i] ); + Vec_IntWriteEntry( vTemps, 3*Gia_ObjFaninId0p(p, pObjRi) + 2, pEna[i] ); + } + Gia_ManForEachAndReverse( p, pObj, i ) { + int iFans[2] = { Gia_ObjFaninId0(pObj, i), Gia_ObjFaninId1(pObj, i) }; + int * pFans[2] = { Vec_IntEntryP( vTemps, 3*iFans[0] ), Vec_IntEntryP( vTemps, 3*iFans[1] ) }; + int * pNode = Vec_IntEntryP( vTemps, 3*i ); + if ( pNode[0] == -1 ) + continue; + for ( n = 0; n < 2; n++ ) + if ( pFans[n][0] == -1 ) + pStops[iFans[n]] = (char)1, pFans[n][0] = pNode[0], pFans[n][1] = pNode[1], pFans[n][2] = pNode[2]; + else if ( pFans[n][0] != pNode[0] || pFans[n][1] != pNode[1] || pFans[n][2] != pNode[2] ) + pStops[iFans[n]] = (char)0; + } + pStops[0] = (char)0; + Gia_ManForEachCi( p, pObj, i ) + pStops[Gia_ObjId(p, pObj)] = (char)0; + Gia_ManForEachAnd( p, pObj, i ) + pStops[i] = (char)!pStops[i]; + Vec_IntFree( vTemps ); + return vStops; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_FrameSetRetimingData( Abc_Frame_t * pAbc, int * pRst, int * pSet, int * pEna ) +{ + Gia_Man_t * pGia; + if ( pAbc == NULL ) + printf( "ABC framework is not initialized by calling Abc_Start()\n" ); + pGia = Abc_FrameReadGia( pAbc ); + if ( pGia == NULL ) + printf( "Current network in ABC framework is not defined.\n" ); + assert( pGia->vStopsF == NULL ); + assert( pGia->vStopsB == NULL ); + pGia->vStopsF = Gia_ManRetimableF( pGia, pRst, pSet, pEna ); + pGia->vStopsB = Gia_ManRetimableB( pGia, pRst, pSet, pEna ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaSif.c b/src/aig/gia/giaSif.c index db7629fb3..c52ab4dd9 100644 --- a/src/aig/gia/giaSif.c +++ b/src/aig/gia/giaSif.c @@ -490,13 +490,16 @@ int Gia_ManSifCheckIter( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, i } int Gia_ManSifCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int * pIters ) { - Gia_Obj_t * pObj; int i, Id, nSize = nLutSize+1; + Gia_Obj_t * pObj; int i, Id, Stop, nSize = nLutSize+1; assert( Gia_ManRegNum(p) > 0 ); Gia_ManForEachCiId( p, Id, i ) Vec_IntWriteEntry( vCuts, Id*nSize, 1 ); Gia_ManForEachCiId( p, Id, i ) Vec_IntWriteEntry( vCuts, Id*nSize+1, Id << 8 ); Vec_IntFill( vTimes, Gia_ManObjNum(p), -Period ); + if ( p->vStopsF ) + Vec_StrForEachEntry( p->vStopsF, Stop, i ) + if ( Stop ) Vec_IntWriteEntry( vTimes, i, 0 ); Vec_IntWriteEntry( vTimes, 0, 0 ); Gia_ManForEachPi( p, pObj, i ) Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), 0 ); @@ -510,6 +513,10 @@ int Gia_ManSifCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, Gia_ManForEachObj( p, pObj, i ) if ( Vec_IntEntry(vTimes, Gia_ObjId(p, pObj)) > 2*Period ) return 0; + if ( p->vStopsB ) + Vec_StrForEachEntry( p->vStopsB, Stop, i ) + if ( Stop && Vec_IntEntry(vTimes, i) > Period ) + return 0; } return 0; } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index e86667882..4bb3a4344 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -164,6 +164,7 @@ static int Abc_CommandAllExact ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandTestExact ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMajGen ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandOrchestrate ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAIGAugmentation ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandComb ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -595,6 +596,7 @@ static int Abc_CommandAbc9Cfs ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9ProdAdd ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9AddFlop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9BMiter ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9GenHie ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -919,6 +921,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Synthesis", "faultclasses", Abc_CommandFaultClasses, 0 ); Cmd_CommandAdd( pAbc, "Synthesis", "exact", Abc_CommandExact, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "orchestrate", Abc_CommandOrchestrate, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "aigaug", Abc_CommandAIGAugmentation, 1 ); Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_start", Abc_CommandBmsStart, 0 ); Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_stop", Abc_CommandBmsStop, 0 ); @@ -1364,6 +1367,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&prodadd", Abc_CommandAbc9ProdAdd, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&addflop", Abc_CommandAbc9AddFlop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&bmiter", Abc_CommandAbc9BMiter, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&gen_hie", Abc_CommandAbc9GenHie, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 ); { @@ -7538,6 +7542,169 @@ usage: } +/**Function************************************************************* + + Synopsis [] + + Description [AIG RTL Augmentation] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAIGAugmentation( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup; + int c, RetValue; + int nNodeSizeMax; + int nConeSizeMax; + int fUpdateLevel; + int fUseZeros_rwr; + int fUseZeros_ref; + int fUseDcs; + int fVerbose; + int RS_CUT_MIN = 4; + int RS_CUT_MAX = 16; + + int fPrecompute; + int fPlaceEnable; + int nNodesMax; + int nCutsMax; + int nLevelsOdc; + int fVeryVerbose; + int Rand_Seed; + //int sOpsOrder; + size_t NtkSize; + char *DecisionFile = NULL; + Vec_Int_t *DecisionMask; + Vec_Int_t *pGain_rwr; + Vec_Int_t *pGain_res; + Vec_Int_t *pGain_ref; + //FILE *maskFile; + extern void Rwr_Precompute(); + extern int Abc_NtkOrchRand( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, Vec_Int_t **DecisionMask, char *DecisionFile, int Rand_Seed, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutsMax, int nNodesMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ); + // set defaults + nNodeSizeMax = 10; + nConeSizeMax = 16; + fUpdateLevel = 1; + fUseZeros_rwr = 0; + fUseZeros_ref = 0; + fUseDcs = 0; + fVerbose = 0; + fVeryVerbose = 0; + fPlaceEnable = 0; + fPrecompute = 0; + nCutsMax = 8; + nNodesMax = 1; + nLevelsOdc = 0; + Rand_Seed = 1; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "zZdsh" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + break; + case 'z': + fUseZeros_rwr ^= 1; + break; + case 'Z': + fUseZeros_ref ^= 1; + break; + case 'd': + if ( globalUtilOptind >= argc ) + { + goto usage; + } + DecisionFile = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 's': + if ( globalUtilOptind >= argc ) + { + goto usage; + } + Rand_Seed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + } + } + if ( fPrecompute ) + { + Rwr_Precompute(); + return 0; + } + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + if ( nCutsMax < RS_CUT_MIN || nCutsMax > RS_CUT_MAX ) + { + Abc_Print( -1, "Can only compute cuts for %d <= K <= %d.\n", RS_CUT_MIN, RS_CUT_MAX ); + return 1; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + Abc_Print( -1, "This command can only be applied to an AIG (run \"strash\").\n" ); + return 1; + } + if ( Abc_NtkGetChoiceNum(pNtk) ) + { + Abc_Print( -1, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" ); + return 1; + } + if ( nNodeSizeMax > 15 ) + { + Abc_Print( -1, "The cone size cannot exceed 15.\n" ); + return 1; + } + + if ( fUseDcs && nNodeSizeMax >= nConeSizeMax ) + { + Abc_Print( -1, "For don't-care to work, containing cone should be larger than collapsed node.\n" ); + return 1; + } + NtkSize = Abc_NtkObjNumMax(pNtk); + + DecisionMask = Vec_IntAlloc(1); + for (int i=0; inSize, DecisionList->pArray[0]); + if ( RetValue == -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, "Orchestration evaluation for RL has failed.\n" ); + return 1; + } + } + // Vec_IntPrint(pGain_rwr); + return 0; + +usage: + Abc_Print( -2, "usage: aigaug [-s ] [-d ][-zZdsh]\n" ); + Abc_Print( -2, "\t performs technology-independent AIG random synthesis (node level) for RTL augmentation\n" ); + Abc_Print( -2, "\t-z : toggle using zero-cost replacements for rwr for aigaug [default = %s]\n", fUseZeros_rwr? "yes": "no" ); + Abc_Print( -2, "\t-Z : toggle using zero-cost replacements for ref for aigaug [default = %s]\n", fUseZeros_ref? "yes": "no" ); + Abc_Print( -2, "\t-d : record random synthesis decision made during augmentation [required filename; e.g., test.csv]\n"); + Abc_Print( -2, "\t-s : set the random seed for random augmentation\n"); + Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\tExample : read i10.aig;st;aigaug -s 1 -d test.csv;write i10_arg_1.aig;cec i10.aig i10_arg_1.aig\n"); + return 1; +} @@ -31762,13 +31929,14 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv ) int fUnique = 0; int fVerilog = 0; int fInter = 0; + int fInterComb = 0; int fVerBufs = 0; int fMiniAig = 0; int fMiniLut = 0; int fWriteNewLine = 0; int fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "upibmlnvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "upicbmlnvh" ) ) != EOF ) { switch ( c ) { @@ -31781,6 +31949,9 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'i': fInter ^= 1; break; + case 'c': + fInterComb ^= 1; + break; case 'b': fVerBufs ^= 1; break; @@ -31822,7 +31993,7 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManStop( pGia ); } else if ( fVerilog ) - Gia_ManDumpVerilog( pAbc->pGia, pFileName, NULL, fVerBufs, fInter ); + Gia_ManDumpVerilog( pAbc->pGia, pFileName, NULL, fVerBufs, fInter, fInterComb ); else if ( fMiniAig ) Gia_ManWriteMiniAig( pAbc->pGia, pFileName ); else if ( fMiniLut ) @@ -31832,11 +32003,12 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &w [-upibmlnvh] \n" ); + Abc_Print( -2, "usage: &w [-upicbmlnvh] \n" ); Abc_Print( -2, "\t writes the current AIG into the AIGER file\n" ); Abc_Print( -2, "\t-u : toggle writing canonical AIG structure [default = %s]\n", fUnique? "yes" : "no" ); Abc_Print( -2, "\t-p : toggle writing Verilog with 'and' and 'not' [default = %s]\n", fVerilog? "yes" : "no" ); Abc_Print( -2, "\t-i : toggle writing the interface module in Verilog [default = %s]\n", fInter? "yes" : "no" ); + Abc_Print( -2, "\t-c : toggle writing the interface module in Verilog [default = %s]\n", fInterComb? "yes" : "no" ); Abc_Print( -2, "\t-b : toggle writing additional buffers in Verilog [default = %s]\n", fVerBufs? "yes" : "no" ); Abc_Print( -2, "\t-m : toggle writing MiniAIG rather than AIGER [default = %s]\n", fMiniAig? "yes" : "no" ); Abc_Print( -2, "\t-l : toggle writing MiniLUT rather than AIGER [default = %s]\n", fMiniLut? "yes" : "no" ); @@ -51569,6 +51741,67 @@ usage: return 1; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9GenHie( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_GenSandwich( char ** pFNames, int nFNames, char * pFileName ); + char * pFileName = (char *)"sandwich.v"; + int c, fVerbose = 0; + char ** pArgvNew; + int nArgcNew; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Fvh" ) ) != EOF ) + { + switch ( c ) + { + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by a file name.\n" ); + goto usage; + } + pFileName = argv[globalUtilOptind++]; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew < 1 ) + { + Abc_Print( -1, "Abc_CommandAbc9GenHie(): At least one AIG file should be given on the command line.\n" ); + return 0; + } + Gia_GenSandwich( pArgvNew, nArgcNew, pFileName ); + return 0; +usage: + Abc_Print( -2, "usage: &gen_hie [-F ] [-vh] ... \n" ); + Abc_Print( -2, "\t generates a hierarchical design in Verilog\n" ); + Abc_Print( -2, "\t-F : the output file name (optional) [default = \"sandwich.v\"]\n" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t : the AIG files for the instance modules\n"); + Abc_Print( -2, "\t (the PO count of should not be less than the PI count of )\n"); + return 1;} + + /**Function************************************************************* Synopsis [] diff --git a/src/base/abci/abcOrchestration.c b/src/base/abci/abcOrchestration.c index fe83891ec..af36939dd 100644 --- a/src/base/abci/abcOrchestration.c +++ b/src/base/abci/abcOrchestration.c @@ -198,7 +198,7 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); nNodes = Abc_NtkObjNumMax(pNtk); - printf("nNodes: %d\n", nNodes); + //printf("nNodes: %d\n", nNodes); if ( pGain_rw ) *pGain_rw = Vec_IntAlloc(1); pProgress = Extra_ProgressBarStart( stdout, nNodes ); @@ -489,7 +489,7 @@ int Abc_NtkRefactor3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_ref, int nNodeSizeMax, Abc_NtkStartReverseLevels( pNtk, 0 ); pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); nNodes = Abc_NtkObjNumMax(pNtk); - printf("nNodes: %d\n", nNodes); + //printf("nNodes: %d\n", nNodes); if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); pProgress = Extra_ProgressBarStart( stdout, nNodes ); @@ -605,7 +605,7 @@ int Abc_NtkResubstitute3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_res, int nCutMax, // resynthesize each node once pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); nNodes = Abc_NtkObjNumMax(pNtk); - printf("nNodes: %d\n", nNodes); + //printf("nNodes: %d\n", nNodes); if (pGain_res) *pGain_res = Vec_IntAlloc(1); pProgress = Extra_ProgressBarStart( stdout, nNodes ); @@ -2732,7 +2732,7 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); nNodes = Abc_NtkObjNumMax(pNtk); - printf("nNodes: %d\n", nNodes); + //printf("nNodes: %d\n", nNodes); if (pGain_res) *pGain_res = Vec_IntAlloc(1); if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1); @@ -5318,6 +5318,319 @@ s_ResubTime = Abc_Clock() - clkStart; return 1; } +// orchestration with sudo random decision list +int Abc_NtkOrchRand( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, Vec_Int_t **DecisionMask, char * DecisionFile, int Rand_Seed, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) +{ + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + ProgressBar * pProgress; + // For resub + Abc_ManRes_t * pManRes; + Abc_ManCut_t * pManCutRes; + Odc_Man_t * pManOdc = NULL; + Dec_Graph_t * pFFormRes; + Vec_Ptr_t * vLeaves; + // For rewrite + Cut_Man_t * pManCutRwr; + Rwr_Man_t * pManRwr; + Dec_Graph_t * pGraph; + // For refactor + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCutRef; + Dec_Graph_t * pFFormRef; + Vec_Ptr_t * vFanins; + + Abc_Obj_t * pNode; + FILE *fpt; + abctime clk, clkStart = Abc_Clock(); + int i, nNodes, nNodes_after, nGain, fCompl; + int RetValue = 1; + int ops_rwr = 0; + int ops_res = 0; + int ops_ref = 0; + int ops_null = 0; + int Valid_Len = 0; + //Vec_Int_t *Valid_Ops; + + //clock_t begin= clock(); + assert( Abc_NtkIsStrash(pNtk) ); + + // cleanup the AIG + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + + // start the managers resub + pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 ); + pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX ); + if ( nLevelsOdc > 0 ) + pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose ); + // start the managers refactor + pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef ); + // start the managers rewrite + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + + // compute the reverse levels if level update is requested + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + + // 'Resub only' + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pNext = (Abc_Obj_t *)pNode->pData; + } + + // cut manager for rewrite +clk = Abc_Clock(); + pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk ); +Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); + pNtk->pManCut = pManCutRwr; + + if ( fVeryVerbose ) + Rwr_ScoresClean( pManRwr ); + + // resynthesize each node once + // resub + pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); + // rewrite + pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); + // refactor + pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); + +//clock_t resyn_end=clock(); +//double resyn_time_spent = (double)(resyn_end-begin)/CLOCKS_PER_SEC; +//printf("time %f\n", resyn_time_spent); + nNodes = Abc_NtkObjNumMax(pNtk); + //printf("nNodes: %d\n", nNodes); + //for(int i=0; i < nNodes; i++){printf("mask check: %d\n", (*DecisionMask)->pArray[i]);} + //printf("mask size:%d", (**DecisionMask).nSize); + if (pGain_res) *pGain_res = Vec_IntAlloc(1); + if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); + if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1); + Vec_Int_t *Valid_Ops = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + fpt = fopen(DecisionFile, "w"); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + //printf("Ochestration id: %d\n", pNode->Id); + int iterNode = pNode->Id; + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the constant node +// if ( Abc_NodeIsConst(pNode) ) +// continue; + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + { + //fprintf(fpt, "%d, %s, %d\n", pNode->Id, "None" , -99); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } + // skip the nodes with many fanouts + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + //fprintf(fpt, "%d, %s, %d\n", pNode->Id,"None", -99); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } +clk = Abc_Clock(); + +// Generate random operation +// check transformability of all three operations + Vec_IntPush( (Valid_Ops), -1); + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { + Vec_IntPush( (Valid_Ops), 0); + } + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); + pManRes->timeCut += Abc_Clock() - clk; + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +pManRes->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_res), pManRes->nLastGain); + if (pManRes->nLastGain > 0) + { + if ( pFFormRes != NULL ){ + Vec_IntPush( (Valid_Ops), 1); + } + } + + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { + if ( pFFormRef != NULL ){ + Vec_IntPush( (Valid_Ops), 2); + } + } + Valid_Len = (Valid_Ops)->nSize; + //printf("The length of valid operations: %d\n", Valid_Len); + +//Pick a random operations from valid ones +if (Rand_Seed == -1) +{ + srand(time(NULL)); +} +else +{ + srand(Rand_Seed); +} + +int r = rand() % Valid_Len; + + if ((Valid_Ops)->pArray[r] == -1){ + (*DecisionMask)->pArray[iterNode] = -1; + ops_null++; + Vec_IntZero(Valid_Ops); // reset updates + continue; + } + else if ((Valid_Ops->pArray[r]) == 0){ + // apply rewrite + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + (*DecisionMask)->pArray[iterNode] = 0; + ops_rwr++; + Vec_IntZero(Valid_Ops); // reset updates + continue; + } + else if ((Valid_Ops->pArray[r] == 1)){ + // apply res + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + (*DecisionMask)->pArray[iterNode] = 1; + ops_res++; + Vec_IntZero(Valid_Ops); // reset updates + continue; + } + else if ((Valid_Ops->pArray[r] == 2)){ +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + (*DecisionMask)->pArray[iterNode] = 2; + ops_ref++; + Vec_IntZero(Valid_Ops); // reset updates + continue; + } + } + //fwrite((**DecisionMask).pArray, sizeof(int), sizeof((**DecisionMask).pArray), fpt); + for (int i = 0; i < (nNodes); i++){ + fprintf(fpt, "%d\n", (*DecisionMask)->pArray[i]);} + fclose(fpt); +/* + printf("size of vector %d\n", Valid_Len); + printf("Nodes with rewrite: %d\n", ops_rwr); + printf("Nodes with resub: %d\n", ops_res); + printf("Nodes with refactor: %d\n", ops_ref); + printf("Nodes without updates: %d\n", ops_null); +*/ + Extra_ProgressBarStop( pProgress ); +// Rewrite +Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); + pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Resub +pManRes->timeTotal = Abc_Clock() - clkStart; + pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Refactor +pManRef->timeTotal = Abc_Clock() - clkStart; + pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk); + + // print statistics + if ( fVerbose ){ + Abc_ManResubPrint( pManRes ); + Rwr_ManPrintStats( pManRwr ); + Abc_NtkManRefPrintStats_1( pManRef ); + } + if ( fVeryVerbose ) + Rwr_ScoresReport( pManRwr ); + // delete the managers + // resub + Abc_ManResubStop( pManRes ); + Abc_NtkManCutStop( pManCutRes ); + // rewrite + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCutRwr ); + pNtk->pManCut = NULL; + // refactor + Abc_NtkManCutStop( pManCutRef ); + Abc_NtkManRefStop_1( pManRef ); + + if ( pManOdc ) Abc_NtkDontCareFree( pManOdc ); + + // clean the data field + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->pData = NULL; + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pData = pNode->pNext, pNode->pNext = NULL; + } + + // 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 ) ) + { + printf( "Abc_NtkOchestraction: The network check has failed.\n" ); + return 0; + } + nNodes_after = Abc_NtkObjNumMax(pNtk); + //printf("nNodes after optimization: %d\n", nNodes_after); +//s_ResubTime = Abc_Clock() - clkStart; +//clock_t end=clock(); +//double time_spent = (double)(end-begin)/CLOCKS_PER_SEC; +//printf("time %f\n", time_spent); + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/main/abcapis.h b/src/base/main/abcapis.h index d34306baf..e1e05f4c7 100644 --- a/src/base/main/abcapis.h +++ b/src/base/main/abcapis.h @@ -106,6 +106,9 @@ extern ABC_DLL int * Abc_FrameReadBoxes( Abc_Frame_t * pAbc ); extern ABC_DLL int Abc_FrameReadProbStatus( Abc_Frame_t * pAbc ); extern ABC_DLL void * Abc_FrameReadCex( Abc_Frame_t * pAbc ); +// procedure to set retiming data +extern ABC_DLL void Abc_FrameSetRetimingData( Abc_Frame_t * pAbc, int * pRst, int * pSet, int * pEna ); + // procedure to return sequential equivalences extern ABC_DLL int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc );