summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2018-09-22 17:40:41 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2018-09-22 17:40:41 -0700
commita2258f5ee65db6c6002b29a795eb0d0bdb881172 (patch)
tree4199803e4c2637e8bb9ebac5b52f8e56fe8457a6
parent53ba28772ebd7d4540f0d259422275493044b834 (diff)
downloadabc-a2258f5ee65db6c6002b29a795eb0d0bdb881172.tar.gz
abc-a2258f5ee65db6c6002b29a795eb0d0bdb881172.tar.bz2
abc-a2258f5ee65db6c6002b29a795eb0d0bdb881172.zip
Support for flops with complex controls.
-rw-r--r--src/base/wlc/wlc.h4
-rw-r--r--src/base/wlc/wlcNdr.c2
-rw-r--r--src/base/wlc/wlcNtk.c23
-rw-r--r--src/base/wlc/wlcReadVer.c22
-rw-r--r--src/base/wlc/wlcWriteVer.c20
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 )