From 48e128aa7213bfe0a0eb9b2468b96ff421424c4b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 3 Mar 2018 17:57:30 -0800 Subject: Extending primitives supported by WLC. --- src/base/wlc/wlc.h | 4 +++- src/base/wlc/wlcReadVer.c | 57 +++++++++++++++++++++++++++++++++++++++++++++- src/base/wlc/wlcWriteVer.c | 29 ++++++++++++++++++++--- 3 files changed, 85 insertions(+), 5 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index c00cd4d0..dc58cc64 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -96,7 +96,9 @@ typedef enum { WLC_OBJ_ARI_SQRT, // 51: integer square root WLC_OBJ_ARI_SQUARE, // 52: integer square WLC_OBJ_TABLE, // 53: bit table - WLC_OBJ_NUMBER // 54: unused + WLC_OBJ_READ, // 54: read port + WLC_OBJ_WRITE, // 55: write port + WLC_OBJ_NUMBER // 56: unused } Wlc_ObjType_t; // when adding new types, remember to update table Wlc_Names in "wlcNtk.c" diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index bc82fa3c..e1994794 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1231,10 +1231,65 @@ startword: p->pNtk->vInits = Vec_IntAlloc( 100 ); Vec_IntPush( p->pNtk->vInits, NameId > 0 ? NameId : -nBits ); } + else if ( Wlc_PrsStrCmp( pStart, "CPL_MEM_" ) ) + { + int * pNameId = NULL, NameOutput, NameMi = -1, NameMo = -1, NameAddr = -1, NameDi = -1, NameDo = -1, fFound, fRead = 1; + pStart += strlen("CPL_MEM_"); + if ( pStart[0] == 'W' ) + fRead = 0; + // read names + while ( 1 ) + { + pStart = Wlc_PrsFindSymbol( pStart, '.' ); + if ( pStart == NULL ) + break; + pStart = Wlc_PrsSkipSpaces( pStart+1 ); + if ( !strncmp(pStart, "mem_data_in", 11) ) + pNameId = &NameMi; + else if ( !strncmp(pStart, "data_in", 7) ) + pNameId = &NameDi; + else if ( !strncmp(pStart, "data_out", 8) ) + pNameId = fRead ? &NameDo : &NameMo; + else if ( !strncmp(pStart, "addr_in", 7) ) + pNameId = &NameAddr; + else + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name of the input/output port." ); + pStart = Wlc_PrsFindSymbol( pStart, '(' ); + if ( pStart == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." ); + pStart = Wlc_PrsFindName( pStart+1, &pName ); + if ( pStart == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." ); + *pNameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); + if ( !fFound ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName ); + } + if ( fRead && (NameMi == -1 || NameAddr == -1 || NameDo == -1) ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Name of one of signals of read port is missing." ); + if ( !fRead && (NameMi == -1 || NameAddr == -1 || NameDi == -1 || NameMo == -1) ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Name of one of signals of write port is missing." ); + // create output + NameOutput = fRead ? NameDo : NameMo; + pObj = Wlc_NtkObj( p->pNtk, NameOutput ); + Wlc_ObjUpdateType( p->pNtk, pObj, fRead ? WLC_OBJ_READ : WLC_OBJ_WRITE ); + Vec_IntClear( p->vFanins ); + Vec_IntPush( p->vFanins, NameMi ); + Vec_IntPush( p->vFanins, NameAddr ); + if ( !fRead ) + Vec_IntPush( p->vFanins, NameDi ); + Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); + } + else if ( pStart[0] == '(' && pStart[1] == '*' ) // skip comments + { + while ( *pStart++ != ')' ); + pStart = Wlc_PrsSkipSpaces( pStart ); + goto startword; + } else if ( pStart[0] != '`' ) { + int iLine = Wlc_PrsFindLine(p, pStart); pStart = Wlc_PrsFindName( pStart, &pName ); - return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read line beginning with %s.", pName ); + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read line %d beginning with %s.", iLine, (!pName || !pName[0]) ? "\"?\"" : pName ); } } if ( p->nNonZero[0] ) diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index b66c12d2..98d1b2dc 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -187,7 +187,11 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) Range[0] = 0; } if ( pObj->fIsPo || (fNoFlops && pObj->fIsFi) ) + { + if ( Wlc_ObjFaninNum(pObj) == 0 ) + continue; fprintf( pFile, " assign " ); + } else if ( pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3 ) fprintf( pFile, "reg %s ", Range ); else @@ -249,7 +253,22 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, "end\n" ); continue; } - else + else if ( pObj->Type == WLC_OBJ_READ || pObj->Type == WLC_OBJ_WRITE ) + { + int nBitsMem = Wlc_ObjRange( Wlc_ObjFanin(p, pObj, 0) ); + //int nBitsAddr = Wlc_ObjRange( Wlc_ObjFanin(p, pObj, 1) ); + int nBitsDat = pObj->Type == WLC_OBJ_READ ? Wlc_ObjRange(pObj) : Wlc_ObjRange(Wlc_ObjFanin(p, pObj, 2)); + int Depth = nBitsMem / nBitsDat; + assert( nBitsMem % nBitsDat == 0 ); + fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) ); + fprintf( pFile, " " ); + fprintf( pFile, "%s_%d (", pObj->Type == WLC_OBJ_READ ? "CPL_MEM_READ" : "CPL_MEM_WRITE", Depth ); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + fprintf( pFile, " .%s(%s)", k==0 ? "mem_data_in" : (k==1 ? "addr_in": "data_in"), Wlc_ObjName(p, iFanin) ); + fprintf( pFile, " .%s(%s) );\n", "data_out", Wlc_ObjName(p, i) ); + continue; + } + else { fprintf( pFile, "%-16s = ", Wlc_ObjName(p, i) ); if ( pObj->Type == WLC_OBJ_BUF ) @@ -352,8 +371,12 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, "@" ); else if ( pObj->Type == WLC_OBJ_ARI_SQUARE ) fprintf( pFile, "#" ); - else assert( 0 ); - //fprintf( pFile, "???" ); + else + { + assert( 0 ); + fprintf( pFile, "???\n" ); + continue; + } fprintf( pFile, " %s", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 1)) ); if ( Wlc_ObjFaninNum(pObj) == 3 && pObj->Type == WLC_OBJ_ARI_ADD ) fprintf( pFile, " + %s", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 2)) ); -- cgit v1.2.3