Commit a2258f5e by Alan Mishchenko

Support for flops with complex controls.

parent 53ba2877
......@@ -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++ )
......
......@@ -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 )
......
......@@ -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 )
{
......
......@@ -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 );
}
......
......@@ -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 )
......
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