Commit a2258f5e by Alan Mishchenko

Support for flops with complex controls.

parent 53ba2877
...@@ -140,6 +140,7 @@ struct Wlc_Ntk_t_ ...@@ -140,6 +140,7 @@ struct Wlc_Ntk_t_
Vec_Int_t vCis; // combinational inputs Vec_Int_t vCis; // combinational inputs
Vec_Int_t vCos; // combinational outputs Vec_Int_t vCos; // combinational outputs
Vec_Int_t vFfs; // flops Vec_Int_t vFfs; // flops
Vec_Int_t vFfs2; // flops
Vec_Int_t * vInits; // initial values Vec_Int_t * vInits; // initial values
char * pInits; // initial values char * pInits; // initial values
int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type 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 ) ...@@ -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_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_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_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_ObjIsPi( Wlc_Obj_t * p ) { return p->Type == WLC_OBJ_PI; }
static inline int Wlc_ObjIsPo( Wlc_Obj_t * p ) { return p->fIsPo; } 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 ) ...@@ -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++ ) for ( i = 0; (i < Wlc_NtkCoNum(p)) && (((pCo) = Wlc_NtkCo(p, i)), 1); i++ )
#define Wlc_NtkForEachFf( p, pFf, i ) \ #define Wlc_NtkForEachFf( p, pFf, i ) \
for ( i = 0; (i < Vec_IntSize(&p->vFfs)) && (((pFf) = Wlc_NtkFf(p, i)), 1); 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 ) \ #define Wlc_ObjForEachFanin( pObj, iFanin, i ) \
for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ ) for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ )
......
...@@ -399,6 +399,8 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) ...@@ -399,6 +399,8 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
Vec_IntPush( &pNtk->vFfs, Vec_IntEntry(vFanins, 0) ); Vec_IntPush( &pNtk->vFfs, Vec_IntEntry(vFanins, 0) );
continue; continue;
} }
if ( Type == ABC_OPER_DFFRSE )
Vec_IntPush( &pNtk->vFfs2, iObj );
if ( Type == ABC_OPER_SLICE ) if ( Type == ABC_OPER_SLICE )
Vec_IntPushTwo( vFanins, End, Beg ); Vec_IntPushTwo( vFanins, End, Beg );
else if ( Type == ABC_OPER_CONST ) else if ( Type == ABC_OPER_CONST )
......
...@@ -264,6 +264,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ...@@ -264,6 +264,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p )
ABC_FREE( p->vCis.pArray ); ABC_FREE( p->vCis.pArray );
ABC_FREE( p->vCos.pArray ); ABC_FREE( p->vCos.pArray );
ABC_FREE( p->vFfs.pArray ); ABC_FREE( p->vFfs.pArray );
ABC_FREE( p->vFfs2.pArray );
Vec_IntFreeP( &p->vInits ); Vec_IntFreeP( &p->vInits );
ABC_FREE( p->vTravIds.pArray ); ABC_FREE( p->vTravIds.pArray );
ABC_FREE( p->vNameIds.pArray ); ABC_FREE( p->vNameIds.pArray );
...@@ -286,6 +287,7 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p ) ...@@ -286,6 +287,7 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p )
Mem += 4 * p->vCis.nCap; Mem += 4 * p->vCis.nCap;
Mem += 4 * p->vCos.nCap; Mem += 4 * p->vCos.nCap;
Mem += 4 * p->vFfs.nCap; Mem += 4 * p->vFfs.nCap;
Mem += 4 * p->vFfs2.nCap;
Mem += sizeof(Wlc_Obj_t) * p->nObjsAlloc; Mem += sizeof(Wlc_Obj_t) * p->nObjsAlloc;
Mem += Abc_NamMemUsed(p->pManName); Mem += Abc_NamMemUsed(p->pManName);
Mem += Mem_FlexReadMemUsage(p->pMemFanin); 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 ...@@ -872,6 +874,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v
return; return;
//printf( "Visiting node %d\n", iObj ); //printf( "Visiting node %d\n", iObj );
pObj = Wlc_NtkObj( p, iObj ); pObj = Wlc_NtkObj( p, iObj );
assert( pObj->Type != WLC_OBJ_FF );
Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_ObjForEachFanin( pObj, iFanin, i )
Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
Wlc_ObjDup( pNew, p, iObj, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins );
...@@ -908,9 +911,9 @@ Wlc_Ntk_t * Wlc_NtkDupDfsSimple( Wlc_Ntk_t * p ) ...@@ -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 * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq )
{ {
Wlc_Ntk_t * pNew; Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj; Wlc_Obj_t * pObj, * pObjNew;
Vec_Int_t * vFanins; Vec_Int_t * vFanins;
int i; int i, k, iObj, iFanin;
vFanins = Vec_IntAlloc( 100 ); vFanins = Vec_IntAlloc( 100 );
Wlc_NtkCleanCopy( p ); Wlc_NtkCleanCopy( p );
pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
...@@ -925,12 +928,28 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) ...@@ -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 ); Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
pObj->Type = Type; 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 ) Wlc_NtkForEachCo( p, pObj, i )
if ( !fMarked || pObj->Mark ) if ( !fMarked || pObj->Mark )
Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i ) Wlc_NtkForEachCo( p, pObj, i )
if ( !fMarked || pObj->Mark ) if ( !fMarked || pObj->Mark )
Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); 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 ); Vec_IntFree( vFanins );
if ( fSeq ) if ( fSeq )
{ {
......
...@@ -1277,7 +1277,7 @@ startword: ...@@ -1277,7 +1277,7 @@ startword:
} }
else if ( Wlc_PrsStrCmp( pStart, "ABC_DFFRSE" ) ) 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"); pStart += strlen("ABC_DFF");
while ( 1 ) while ( 1 )
{ {
...@@ -1286,13 +1286,14 @@ startword: ...@@ -1286,13 +1286,14 @@ startword:
break; break;
pStart = Wlc_PrsSkipSpaces( pStart+1 ); pStart = Wlc_PrsSkipSpaces( pStart+1 );
fFlopIn = (pStart[0] == 'd'); fFlopIn = (pStart[0] == 'd');
fFlopOut = (pStart[0] == 'q');
fFlopClk = (pStart[0] == 'c'); fFlopClk = (pStart[0] == 'c');
fFlopRst = (pStart[0] == 'r'); fFlopRst = (pStart[0] == 'r');
fFlopSet = (pStart[0] == 's'); fFlopSet = (pStart[0] == 's' && pStart[1] == 'e');
fFlopEna = (pStart[0] == 'e'); fFlopEna = (pStart[0] == 'e');
fFlopAsync = (pStart[0] == 'a'); fFlopAsync = (pStart[0] == 'a');
fFlopSre = (pStart[0] == 's' && pStart[1] == 'r');
fFlopInit = (pStart[0] == 'i'); fFlopInit = (pStart[0] == 'i');
fFlopOut = (pStart[0] == 'q');
pStart = Wlc_PrsFindSymbol( pStart, '(' ); pStart = Wlc_PrsFindSymbol( pStart, '(' );
if ( pStart == NULL ) if ( pStart == NULL )
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." ); return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
...@@ -1301,8 +1302,6 @@ startword: ...@@ -1301,8 +1302,6 @@ startword:
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." ); return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
if ( fFlopIn ) if ( fFlopIn )
NameId[0] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); NameId[0] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else if ( fFlopOut )
NameId[7] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else if ( fFlopClk ) else if ( fFlopClk )
NameId[1] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); NameId[1] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else if ( fFlopRst ) else if ( fFlopRst )
...@@ -1313,8 +1312,12 @@ startword: ...@@ -1313,8 +1312,12 @@ startword:
NameId[4] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); NameId[4] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else if ( fFlopAsync ) else if ( fFlopAsync )
NameId[5] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); NameId[5] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else if ( fFlopInit ) else if ( fFlopSre )
NameId[6] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); 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 else
assert( 0 ); assert( 0 );
if ( !fFound ) if ( !fFound )
...@@ -1323,7 +1326,7 @@ startword: ...@@ -1323,7 +1326,7 @@ startword:
if ( NameId[0] == -1 || NameId[7] == -1 ) if ( NameId[0] == -1 || NameId[7] == -1 )
return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." ); return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." );
// create output // create output
pObj = Wlc_NtkObj( p->pNtk, NameId[7] ); pObj = Wlc_NtkObj( p->pNtk, NameId[8] );
Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FF ); Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FF );
Vec_IntClear( p->vFanins ); Vec_IntClear( p->vFanins );
Vec_IntPush( p->vFanins, NameId[0] ); Vec_IntPush( p->vFanins, NameId[0] );
...@@ -1333,6 +1336,7 @@ startword: ...@@ -1333,6 +1336,7 @@ startword:
Vec_IntPush( p->vFanins, NameId[4] ); Vec_IntPush( p->vFanins, NameId[4] );
Vec_IntPush( p->vFanins, NameId[5] ); Vec_IntPush( p->vFanins, NameId[5] );
Vec_IntPush( p->vFanins, NameId[6] ); Vec_IntPush( p->vFanins, NameId[6] );
Vec_IntPush( p->vFanins, NameId[7] );
Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
} }
else if ( Wlc_PrsStrCmp( pStart, "ABC_DFF" ) ) else if ( Wlc_PrsStrCmp( pStart, "ABC_DFF" ) )
...@@ -1571,6 +1575,10 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) ...@@ -1571,6 +1575,10 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
// derive topological order // derive topological order
if ( p->pNtk ) 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 = Wlc_NtkDupDfs( p->pNtk, 0, 1 );
pNtk->pSpec = Abc_UtilStrsav( pFileName ); pNtk->pSpec = Abc_UtilStrsav( pFileName );
} }
......
...@@ -192,7 +192,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) ...@@ -192,7 +192,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
continue; continue;
fprintf( pFile, " assign " ); 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 ); fprintf( pFile, "reg %s ", Range );
else else
fprintf( pFile, "wire %s ", Range ); fprintf( pFile, "wire %s ", Range );
...@@ -361,13 +361,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) ...@@ -361,13 +361,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
} }
else if ( pObj->Type == WLC_OBJ_FF ) 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, "%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; continue;
} }
else else
...@@ -561,6 +555,18 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) ...@@ -561,6 +555,18 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
} }
assert( !p->vInits || iFanin == (int)strlen(p->pInits) ); 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" ); fprintf( pFile, "endmodule\n\n" );
} }
void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName, int fAddCos, int fNoFlops ) void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName, int fAddCos, int fNoFlops )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment