From a2258f5ee65db6c6002b29a795eb0d0bdb881172 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 22 Sep 2018 17:40:41 -0700 Subject: Support for flops with complex controls. --- src/base/wlc/wlc.h | 4 ++++ src/base/wlc/wlcNdr.c | 2 ++ src/base/wlc/wlcNtk.c | 23 +++++++++++++++++++++-- src/base/wlc/wlcReadVer.c | 22 +++++++++++++++------- src/base/wlc/wlcWriteVer.c | 20 +++++++++++++------- 5 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index e947e36b..3a84031e 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -140,6 +140,7 @@ struct Wlc_Ntk_t_ Vec_Int_t vCis; // combinational inputs Vec_Int_t vCos; // combinational outputs Vec_Int_t vFfs; // flops + Vec_Int_t vFfs2; // flops Vec_Int_t * vInits; // initial values char * pInits; // initial values int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type @@ -275,6 +276,7 @@ static inline Wlc_Obj_t * Wlc_NtkPo( Wlc_Ntk_t * p, int i ) static inline Wlc_Obj_t * Wlc_NtkCi( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vCis, i) ); } static inline Wlc_Obj_t * Wlc_NtkCo( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vCos, i) ); } static inline Wlc_Obj_t * Wlc_NtkFf( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vFfs, i) ); } +static inline Wlc_Obj_t * Wlc_NtkFf2( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vFfs2, i) ); } static inline int Wlc_ObjIsPi( Wlc_Obj_t * p ) { return p->Type == WLC_OBJ_PI; } static inline int Wlc_ObjIsPo( Wlc_Obj_t * p ) { return p->fIsPo; } @@ -350,6 +352,8 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) for ( i = 0; (i < Wlc_NtkCoNum(p)) && (((pCo) = Wlc_NtkCo(p, i)), 1); i++ ) #define Wlc_NtkForEachFf( p, pFf, i ) \ for ( i = 0; (i < Vec_IntSize(&p->vFfs)) && (((pFf) = Wlc_NtkFf(p, i)), 1); i++ ) +#define Wlc_NtkForEachFf2( p, pFf, i ) \ + for ( i = 0; (i < Vec_IntSize(&p->vFfs2)) && (((pFf) = Wlc_NtkFf2(p, i)), 1); i++ ) #define Wlc_ObjForEachFanin( pObj, iFanin, i ) \ for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ ) diff --git a/src/base/wlc/wlcNdr.c b/src/base/wlc/wlcNdr.c index 42529a4b..16c7d778 100644 --- a/src/base/wlc/wlcNdr.c +++ b/src/base/wlc/wlcNdr.c @@ -399,6 +399,8 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) Vec_IntPush( &pNtk->vFfs, Vec_IntEntry(vFanins, 0) ); continue; } + if ( Type == ABC_OPER_DFFRSE ) + Vec_IntPush( &pNtk->vFfs2, iObj ); if ( Type == ABC_OPER_SLICE ) Vec_IntPushTwo( vFanins, End, Beg ); else if ( Type == ABC_OPER_CONST ) diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index f89bf3d1..4ac0c66c 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -264,6 +264,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vCis.pArray ); ABC_FREE( p->vCos.pArray ); ABC_FREE( p->vFfs.pArray ); + ABC_FREE( p->vFfs2.pArray ); Vec_IntFreeP( &p->vInits ); ABC_FREE( p->vTravIds.pArray ); ABC_FREE( p->vNameIds.pArray ); @@ -286,6 +287,7 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p ) Mem += 4 * p->vCis.nCap; Mem += 4 * p->vCos.nCap; Mem += 4 * p->vFfs.nCap; + Mem += 4 * p->vFfs2.nCap; Mem += sizeof(Wlc_Obj_t) * p->nObjsAlloc; Mem += Abc_NamMemUsed(p->pManName); Mem += Mem_FlexReadMemUsage(p->pMemFanin); @@ -872,6 +874,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v return; //printf( "Visiting node %d\n", iObj ); pObj = Wlc_NtkObj( p, iObj ); + assert( pObj->Type != WLC_OBJ_FF ); Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); @@ -908,9 +911,9 @@ Wlc_Ntk_t * Wlc_NtkDupDfsSimple( Wlc_Ntk_t * p ) Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) { Wlc_Ntk_t * pNew; - Wlc_Obj_t * pObj; + Wlc_Obj_t * pObj, * pObjNew; Vec_Int_t * vFanins; - int i; + int i, k, iObj, iFanin; vFanins = Vec_IntAlloc( 100 ); Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); @@ -925,12 +928,28 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); pObj->Type = Type; } + Wlc_NtkForEachFf2( p, pObj, i ) + { + int iObjNew = Wlc_ObjAlloc( pNew, pObj->Type, Wlc_ObjIsSigned(pObj), pObj->End, pObj->Beg ); + Wlc_ObjSetCopy( p, Wlc_ObjId(p, pObj), iObjNew ); + Vec_IntPush( &pNew->vFfs2, iObjNew ); + } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); + Wlc_NtkForEachFf2( p, pObj, i ) + { + iObj = Wlc_ObjId(p, pObj); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); + Wlc_ObjCollectCopyFanins( p, iObj, vFanins ); + pObjNew = Wlc_NtkObj( pNew, Wlc_ObjCopy(p, iObj) ); + Wlc_ObjAddFanins( pNew, pObjNew, vFanins ); + pObjNew->fXConst = pObj->fXConst; + } Vec_IntFree( vFanins ); if ( fSeq ) { diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index da7ccbac..34966777 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1277,7 +1277,7 @@ startword: } else if ( Wlc_PrsStrCmp( pStart, "ABC_DFFRSE" ) ) { - int NameId[8] = {0}, fFound, fFlopIn, fFlopOut, fFlopClk, fFlopRst, fFlopSet, fFlopEna, fFlopAsync, fFlopInit; + int NameId[10] = {0}, fFound, fFlopIn, fFlopClk, fFlopRst, fFlopSet, fFlopEna, fFlopAsync, fFlopSre, fFlopInit, fFlopOut; pStart += strlen("ABC_DFF"); while ( 1 ) { @@ -1286,13 +1286,14 @@ startword: break; pStart = Wlc_PrsSkipSpaces( pStart+1 ); fFlopIn = (pStart[0] == 'd'); - fFlopOut = (pStart[0] == 'q'); fFlopClk = (pStart[0] == 'c'); fFlopRst = (pStart[0] == 'r'); - fFlopSet = (pStart[0] == 's'); + fFlopSet = (pStart[0] == 's' && pStart[1] == 'e'); fFlopEna = (pStart[0] == 'e'); fFlopAsync = (pStart[0] == 'a'); + fFlopSre = (pStart[0] == 's' && pStart[1] == 'r'); fFlopInit = (pStart[0] == 'i'); + fFlopOut = (pStart[0] == 'q'); pStart = Wlc_PrsFindSymbol( pStart, '(' ); if ( pStart == NULL ) return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." ); @@ -1301,8 +1302,6 @@ startword: return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." ); if ( fFlopIn ) NameId[0] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); - else if ( fFlopOut ) - NameId[7] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); else if ( fFlopClk ) NameId[1] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); else if ( fFlopRst ) @@ -1313,8 +1312,12 @@ startword: NameId[4] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); else if ( fFlopAsync ) NameId[5] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); - else if ( fFlopInit ) + else if ( fFlopSre ) NameId[6] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); + else if ( fFlopInit ) + NameId[7] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); + else if ( fFlopOut ) + NameId[8] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); else assert( 0 ); if ( !fFound ) @@ -1323,7 +1326,7 @@ startword: if ( NameId[0] == -1 || NameId[7] == -1 ) return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." ); // create output - pObj = Wlc_NtkObj( p->pNtk, NameId[7] ); + pObj = Wlc_NtkObj( p->pNtk, NameId[8] ); Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FF ); Vec_IntClear( p->vFanins ); Vec_IntPush( p->vFanins, NameId[0] ); @@ -1333,6 +1336,7 @@ startword: Vec_IntPush( p->vFanins, NameId[4] ); Vec_IntPush( p->vFanins, NameId[5] ); Vec_IntPush( p->vFanins, NameId[6] ); + Vec_IntPush( p->vFanins, NameId[7] ); Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); } else if ( Wlc_PrsStrCmp( pStart, "ABC_DFF" ) ) @@ -1571,6 +1575,10 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) // derive topological order if ( p->pNtk ) { + Wlc_Obj_t * pObj; int i; + Wlc_NtkForEachObj( p->pNtk, pObj, i ) + if ( pObj->Type == WLC_OBJ_FF ) + Vec_IntPush( &p->pNtk->vFfs2, Wlc_ObjId(p->pNtk, pObj) ); pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); } diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index 3a7da5b1..30f10e14 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -192,7 +192,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) continue; fprintf( pFile, " assign " ); } - else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_FF || pObj->Type == WLC_OBJ_SEL ) + else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_SEL ) fprintf( pFile, "reg %s ", Range ); else fprintf( pFile, "wire %s ", Range ); @@ -361,13 +361,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) } else if ( pObj->Type == WLC_OBJ_FF ) { - char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"}; fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) ); - fprintf( pFile, " " ); - fprintf( pFile, "%s (", "ABC_DFFRSE" ); - Wlc_ObjForEachFanin( pObj, iFanin, k ) - if ( iFanin ) fprintf( pFile, " .%s(%s),", pInNames[k], Wlc_ObjName(p, iFanin) ); - fprintf( pFile, " .%s(%s) ) ;\n", "q", Wlc_ObjName(p, i) ); continue; } else @@ -561,6 +555,18 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) } assert( !p->vInits || iFanin == (int)strlen(p->pInits) ); } + // write DFFs in the end + fprintf( pFile, "\n" ); + Wlc_NtkForEachFf2( p, pObj, i ) + { + char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"}; + fprintf( pFile, " " ); + fprintf( pFile, "%s (", "ABC_DFFRSE" ); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + if ( iFanin ) fprintf( pFile, " .%s(%s),", pInNames[k], Wlc_ObjName(p, iFanin) ); + fprintf( pFile, " .%s(%s) ) ;\n", "q", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) ); + } + fprintf( pFile, "\n" ); fprintf( pFile, "endmodule\n\n" ); } void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName, int fAddCos, int fNoFlops ) -- cgit v1.2.3