Commit ee17cbbf by Alan Mishchenko

Supporting negative and reverse ranges of word-level variables in Wlc.

parent ac7a7990
......@@ -61,38 +61,38 @@ typedef enum {
WLC_OBJ_BIT_AND, // 16: bitwise AND
WLC_OBJ_BIT_OR, // 17: bitwise OR
WLC_OBJ_BIT_XOR, // 18: bitwise XOR
WLC_OBJ_BIT_NXOR, // 18: bitwise NXOR
WLC_OBJ_BIT_SELECT, // 19: bit selection
WLC_OBJ_BIT_CONCAT, // 20: bit concatenation
WLC_OBJ_BIT_ZEROPAD, // 21: zero padding
WLC_OBJ_BIT_SIGNEXT, // 22: sign extension
WLC_OBJ_LOGIC_NOT, // 23: logic NOT
WLC_OBJ_LOGIC_AND, // 24: logic AND
WLC_OBJ_LOGIC_OR, // 25: logic OR
WLC_OBJ_LOGIC_XOR, // 27: logic XOR
WLC_OBJ_COMP_EQU, // 28: compare equal
WLC_OBJ_COMP_NOTEQU, // 29: compare not equal
WLC_OBJ_COMP_LESS, // 30: compare less
WLC_OBJ_COMP_MORE, // 31: compare more
WLC_OBJ_COMP_LESSEQU, // 32: compare less or equal
WLC_OBJ_COMP_MOREEQU, // 33: compare more or equal
WLC_OBJ_REDUCT_AND, // 34: reduction AND
WLC_OBJ_REDUCT_OR, // 35: reduction OR
WLC_OBJ_REDUCT_XOR, // 36: reduction XOR
WLC_OBJ_REDUCT_NAND, // 34: reduction NAND
WLC_OBJ_REDUCT_NOR, // 35: reduction NOR
WLC_OBJ_REDUCT_NXOR, // 36: reduction NXOR
WLC_OBJ_ARI_ADD, // 37: arithmetic addition
WLC_OBJ_ARI_SUB, // 38: arithmetic subtraction
WLC_OBJ_ARI_MULTI, // 39: arithmetic multiplier
WLC_OBJ_ARI_DIVIDE, // 40: arithmetic division
WLC_OBJ_ARI_MODULUS, // 41: arithmetic modulus
WLC_OBJ_ARI_POWER, // 42: arithmetic power
WLC_OBJ_ARI_MINUS, // 43: arithmetic minus
WLC_OBJ_ARI_SQRT, // 44: integer square root
WLC_OBJ_ARI_SQUARE, // 45: integer square root
WLC_OBJ_TABLE, // 46: bit table
WLC_OBJ_NUMBER // 47: unused
WLC_OBJ_BIT_NXOR, // 19: bitwise NXOR
WLC_OBJ_BIT_SELECT, // 20: bit selection
WLC_OBJ_BIT_CONCAT, // 21: bit concatenation
WLC_OBJ_BIT_ZEROPAD, // 22: zero padding
WLC_OBJ_BIT_SIGNEXT, // 23: sign extension
WLC_OBJ_LOGIC_NOT, // 24: logic NOT
WLC_OBJ_LOGIC_AND, // 25: logic AND
WLC_OBJ_LOGIC_OR, // 27: logic OR
WLC_OBJ_LOGIC_XOR, // 28: logic XOR
WLC_OBJ_COMP_EQU, // 29: compare equal
WLC_OBJ_COMP_NOTEQU, // 30: compare not equal
WLC_OBJ_COMP_LESS, // 31: compare less
WLC_OBJ_COMP_MORE, // 32: compare more
WLC_OBJ_COMP_LESSEQU, // 33: compare less or equal
WLC_OBJ_COMP_MOREEQU, // 34: compare more or equal
WLC_OBJ_REDUCT_AND, // 35: reduction AND
WLC_OBJ_REDUCT_OR, // 36: reduction OR
WLC_OBJ_REDUCT_XOR, // 37: reduction XOR
WLC_OBJ_REDUCT_NAND, // 38: reduction NAND
WLC_OBJ_REDUCT_NOR, // 39: reduction NOR
WLC_OBJ_REDUCT_NXOR, // 40: reduction NXOR
WLC_OBJ_ARI_ADD, // 41: arithmetic addition
WLC_OBJ_ARI_SUB, // 42: arithmetic subtraction
WLC_OBJ_ARI_MULTI, // 43: arithmetic multiplier
WLC_OBJ_ARI_DIVIDE, // 44: arithmetic division
WLC_OBJ_ARI_MODULUS, // 45: arithmetic modulus
WLC_OBJ_ARI_POWER, // 46: arithmetic power
WLC_OBJ_ARI_MINUS, // 47: arithmetic minus
WLC_OBJ_ARI_SQRT, // 48: integer square root
WLC_OBJ_ARI_SQUARE, // 49: integer square
WLC_OBJ_TABLE, // 50: bit table
WLC_OBJ_NUMBER // 51: unused
} Wlc_ObjType_t;
// when adding new types, remember to update table Wlc_Names in "wlcNtk.c"
......@@ -115,8 +115,8 @@ struct Wlc_Obj_t_ // 24 bytes
unsigned fIsFi : 1; // this is FI
unsigned fXConst : 1; // this is X-valued constant
unsigned nFanins; // fanin count
unsigned End; // range end
unsigned Beg; // range begin
int End; // range end
int Beg; // range begin
union { int Fanins[2]; // fanin IDs
int * pFanins[1]; };
};
......@@ -175,7 +175,7 @@ static inline int Wlc_ObjIsCo( Wlc_Obj_t * p )
static inline int Wlc_ObjId( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return pObj - p->pObjs; }
static inline int Wlc_ObjCiId( Wlc_Obj_t * p ) { assert( Wlc_ObjIsCi(p) ); return p->Fanins[1]; }
static inline int Wlc_ObjFaninNum( Wlc_Obj_t * p ) { return p->nFanins; }
static inline int Wlc_ObjHasArray( Wlc_Obj_t * p ) { return p->nFanins > 2 || p->Type == WLC_OBJ_CONST; }
static inline int Wlc_ObjHasArray( Wlc_Obj_t * p ) { return p->nFanins > 2 || p->Type == WLC_OBJ_CONST || p->Type == WLC_OBJ_BIT_SELECT; }
static inline int * Wlc_ObjFanins( Wlc_Obj_t * p ) { return Wlc_ObjHasArray(p) ? p->pFanins[0] : p->Fanins; }
static inline int Wlc_ObjFaninId( Wlc_Obj_t * p, int i ) { return Wlc_ObjFanins(p)[i]; }
static inline int Wlc_ObjFaninId0( Wlc_Obj_t * p ) { return Wlc_ObjFanins(p)[0]; }
......@@ -186,9 +186,11 @@ static inline Wlc_Obj_t * Wlc_ObjFanin0( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
static inline Wlc_Obj_t * Wlc_ObjFanin1( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_NtkObj( p, Wlc_ObjFaninId(pObj, 1) ); }
static inline Wlc_Obj_t * Wlc_ObjFanin2( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_NtkObj( p, Wlc_ObjFaninId(pObj, 2) ); }
static inline int Wlc_ObjRange( Wlc_Obj_t * p ) { return p->End - p->Beg + 1; }
static inline int Wlc_ObjRangeEnd( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_BIT_SELECT); return p->Fanins[1] >> 16; }
static inline int Wlc_ObjRangeBeg( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_BIT_SELECT); return p->Fanins[1] & 0xFFFF; }
static inline int Wlc_ObjRange( Wlc_Obj_t * p ) { return 1 + (p->End >= p->Beg ? p->End - p->Beg : p->Beg - p->End); }
static inline int Wlc_ObjRangeEnd( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_BIT_SELECT); return p->pFanins[0][1]; }
static inline int Wlc_ObjRangeBeg( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_BIT_SELECT); return p->pFanins[0][2]; }
static inline int Wlc_ObjRangeIsReversed( Wlc_Obj_t * p ) { return p->End < p->Beg; }
static inline int Wlc_ObjIsSigned( Wlc_Obj_t * p ) { return p->Signed; }
static inline int Wlc_ObjIsSignedFanin01( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ){ return Wlc_ObjFanin0(p, pObj)->Signed && Wlc_ObjFanin1(p, pObj)->Signed; }
static inline int Wlc_ObjSign( Wlc_Obj_t * p ) { return Abc_Var2Lit( Wlc_ObjRange(p), Wlc_ObjIsSigned(p) ); }
......
......@@ -846,8 +846,18 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds )
}
else if ( Wlc_ObjIsCi(pObj) )
{
for ( k = 0; k < nRange; k++ )
Vec_IntPush( vRes, Gia_ManAppendCi(pNew) );
if ( Wlc_ObjRangeIsReversed(pObj) )
{
for ( k = 0; k < nRange; k++ )
Vec_IntPush( vRes, -1 );
for ( k = 0; k < nRange; k++ )
Vec_IntWriteEntry( vRes, Vec_IntSize(vRes)-1-k, Gia_ManAppendCi(pNew) );
}
else
{
for ( k = 0; k < nRange; k++ )
Vec_IntPush( vRes, Gia_ManAppendCi(pNew) );
}
if ( pObj->Type == WLC_OBJ_FO )
nFFouts += Vec_IntSize(vRes);
}
......@@ -962,10 +972,20 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds )
Wlc_Obj_t * pFanin = Wlc_ObjFanin0(p, pObj);
int End = Wlc_ObjRangeEnd(pObj);
int Beg = Wlc_ObjRangeBeg(pObj);
assert( nRange == End - Beg + 1 );
assert( (int)pFanin->Beg <= Beg && End <= (int)pFanin->End );
for ( k = Beg; k <= End; k++ )
Vec_IntPush( vRes, pFans0[k - pFanin->Beg] );
if ( End >= Beg )
{
assert( nRange == End - Beg + 1 );
assert( pFanin->Beg <= Beg && End <= pFanin->End );
for ( k = Beg; k <= End; k++ )
Vec_IntPush( vRes, pFans0[k - pFanin->Beg] );
}
else
{
assert( nRange == Beg - End + 1 );
assert( pFanin->End <= End && Beg <= pFanin->Beg );
for ( k = End; k <= Beg; k++ )
Vec_IntPush( vRes, pFans0[k - pFanin->End] );
}
}
else if ( pObj->Type == WLC_OBJ_BIT_CONCAT )
{
......@@ -1165,8 +1185,16 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds )
pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) );
if ( fVerbose )
printf( "%s(%d) ", Wlc_ObjName(p, Wlc_ObjId(p, pObj)), Gia_ManCoNum(pNew) );
for ( k = 0; k < nRange; k++ )
Gia_ManAppendCo( pNew, pFans0[k] );
if ( Wlc_ObjRangeIsReversed(pObj) )
{
for ( k = 0; k < nRange; k++ )
Gia_ManAppendCo( pNew, pFans0[nRange-1-k] );
}
else
{
for ( k = 0; k < nRange; k++ )
Gia_ManAppendCo( pNew, pFans0[k] );
}
if ( pObj->fIsFi )
nFFins += nRange;
}
......
......@@ -33,10 +33,10 @@ ABC_NAMESPACE_IMPL_START
static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
NULL, // 00: unknown
"pi", // 01: primary input
"po", // 02: primary output
"ff", // 03: box output
"bi", // 04: box input
"ff", // 05: flop
"po", // 02: primary output (unused)
"ff", // 03: flop output
"bi", // 04: flop input (unused)
"ff", // 05: flop (unused)
"const", // 06: constant
"buf", // 07: buffer
"mux", // 08: multiplexer
......@@ -44,46 +44,46 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
">>>", // 10: shift right (arithmetic)
"<<", // 11: shift left
"<<<", // 12: shift left (arithmetic)
"rotateR", // 13: shift left (arithmetic)
"rotateL", // 14: shift left (arithmetic)
"rotateR", // 13: rotate right
"rotateL", // 14: rotate left
"~", // 15: bitwise NOT
"&", // 16: bitwise AND
"|", // 17: bitwise OR
"^", // 18: bitwise XOR
"~^", // 18: bitwise NXOR
"[:]", // 19: bit selection
"{,}", // 20: bit concatenation
"zeroPad", // 21: zero padding
"signExt", // 22: sign extension
"!", // 23: logic NOT
"&&", // 24: logic AND
"||", // 25: logic OR
"^^", // 27: logic XOR
"==", // 28: compare equal
"!=", // 29: compare not equal
"<", // 30: compare less
">", // 31: compare more
"<=", // 32: compare less or equal
">=", // 33: compare more or equal
"&", // 34: reduction AND
"|", // 35: reduction OR
"^", // 36: reduction XOR
"~&", // 34: reduction NAND
"~|", // 35: reduction NOR
"~^", // 36: reduction NXOR
"+", // 37: arithmetic addition
"-", // 38: arithmetic subtraction
"*", // 39: arithmetic multiplier
"/", // 40: arithmetic division
"%", // 41: arithmetic modulus
"**", // 42: arithmetic power
"-", // 43: arithmetic minus
"sqrt", // 44: integer square root
"table", // 45: bit table
NULL // 46: unused
"~^", // 19: bitwise NXOR
"[:]", // 20: bit selection
"{,}", // 21: bit concatenation
"zeroPad", // 22: zero padding
"signExt", // 23: sign extension
"!", // 24: logic NOT
"&&", // 25: logic AND
"||", // 27: logic OR
"^^", // 28: logic XOR
"==", // 29: compare equal
"!=", // 30: compare not equal
"<", // 31: compare less
">", // 32: compare more
"<=", // 33: compare less or equal
">=", // 34: compare more or equal
"&", // 35: reduction AND
"|", // 36: reduction OR
"^", // 37: reduction XOR
"~&", // 38: reduction NAND
"~|", // 39: reduction NOR
"~^", // 40: reduction NXOR
"+", // 41: arithmetic addition
"-", // 42: arithmetic subtraction
"*", // 43: arithmetic multiplier
"/", // 44: arithmetic division
"%", // 45: arithmetic modulus
"**", // 46: arithmetic power
"-", // 47: arithmetic minus
"sqrt", // 48: integer square root
"square", // 49: integer square
"table", // 50: bit table
NULL // 51: unused
};
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -534,7 +534,12 @@ void Wlc_ObjCollectCopyFanins( Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins )
for ( i = 0; i < nInts; i++ )
Vec_IntPush( vFanins, pInts[i] );
}
else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE )
else if ( pObj->Type == WLC_OBJ_BIT_SELECT )
{
assert( Vec_IntSize(vFanins) == 1 );
Vec_IntPushTwo( vFanins, Wlc_ObjRangeEnd(pObj), Wlc_ObjRangeBeg(pObj) );
}
else if ( pObj->Type == WLC_OBJ_TABLE )
{
assert( Vec_IntSize(vFanins) == 1 );
Vec_IntPush( vFanins, pObj->Fanins[1] );
......
......@@ -409,7 +409,7 @@ int Smt_PrsBuildNode( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int RangeOut,
if ( Type == WLC_OBJ_BIT_SELECT )
{
assert( Value1 >= 0 && Value2 >= 0 && Value1 >= Value2 );
Vec_IntPush( vFanins, (Value1 << 16) | Value2 );
Vec_IntPushTwo( vFanins, Value1, Value2 );
}
else if ( Type == WLC_OBJ_ROTATE_R || Type == WLC_OBJ_ROTATE_L )
{
......
......@@ -43,10 +43,9 @@ struct Wlc_Prs_t_
Mem_Flex_t * pMemTable;
Vec_Ptr_t * vTables;
int nConsts;
int nNonZeroCount;
int nNonZeroEnd;
int nNonZeroBeg;
int nNonZeroLine;
int nNonZero[4];
int nNegative[4];
int nReverse[4];
char sError[WLV_PRS_MAX_LINE];
};
......@@ -473,7 +472,7 @@ static inline char * Wlc_PrsFindRange( char * pStr, int * End, int * Beg )
if ( pStr[0] != '[' )
return pStr;
pStr = Wlc_PrsSkipSpaces( pStr+1 );
if ( !Wlc_PrsIsDigit(pStr) )
if ( !Wlc_PrsIsDigit(pStr) && pStr[0] != '-' )
return NULL;
*End = *Beg = atoi( pStr );
if ( Wlc_PrsFindSymbol( pStr, ':' ) == NULL )
......@@ -486,16 +485,13 @@ static inline char * Wlc_PrsFindRange( char * pStr, int * End, int * Beg )
{
pStr = Wlc_PrsFindSymbol( pStr, ':' );
pStr = Wlc_PrsSkipSpaces( pStr+1 );
if ( !Wlc_PrsIsDigit(pStr) )
if ( !Wlc_PrsIsDigit(pStr) && pStr[0] != '-' )
return NULL;
*Beg = atoi( pStr );
pStr = Wlc_PrsFindSymbol( pStr, ']' );
if ( pStr == NULL )
return NULL;
}
if ( *End < *Beg )
return NULL;
assert( *End >= *Beg );
return pStr + 1;
}
static inline char * Wlc_PrsFindWord( char * pStr, char * pWord, int * fFound )
......@@ -770,7 +766,7 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t *
pStr = Wlc_PrsFindRange( pStr, &End, &Beg );
if ( pStr == NULL )
return Wlc_PrsWriteErrorMessage( p, pLine, "Non-standard range." );
Vec_IntPush( vFanins, (End << 16) | Beg );
Vec_IntPushTwo( vFanins, End, Beg );
Type = WLC_OBJ_BIT_SELECT;
}
else
......@@ -834,13 +830,31 @@ int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart )
pStart = Wlc_PrsFindRange( pStart, &End, &Beg );
if ( pStart == NULL )
return Wlc_PrsWriteErrorMessage( p, pLine, "Non-standard range." );
if ( Beg != 0 )
if ( End != 0 && Beg != 0 )
{
if ( p->nNonZero[0]++ == 0 )
{
p->nNonZero[1] = End;
p->nNonZero[2] = Beg;
p->nNonZero[3] = Wlc_PrsFindLine(p, pStart);
}
}
if ( End < 0 || Beg < 0 )
{
if ( p->nNonZeroCount++ == 0 )
if ( p->nNegative[0]++ == 0 )
{
p->nNonZeroEnd = End;
p->nNonZeroBeg = Beg;
p->nNonZeroLine = Wlc_PrsFindLine(p, pStart);
p->nNegative[1] = End;
p->nNegative[2] = Beg;
p->nNegative[3] = Wlc_PrsFindLine(p, pStart);
}
}
if ( End < Beg )
{
if ( p->nReverse[0]++ == 0 )
{
p->nReverse[1] = End;
p->nReverse[2] = Beg;
p->nReverse[3] = Wlc_PrsFindLine(p, pStart);
}
}
while ( 1 )
......@@ -1140,7 +1154,10 @@ startword:
if ( nValues != Vec_IntSize(p->vFanins) - 1 )
return Wlc_PrsWriteErrorMessage( p, pStart, "The number of values in the case statement is wrong.", pName );
if ( Wlc_ObjRange(pObj) == 1 )
return Wlc_PrsWriteErrorMessage( p, pStart, "Always-statement with 1-bit control is not bit-blasted correctly.", pName );
{
// return Wlc_PrsWriteErrorMessage( p, pStart, "Always-statement with 1-bit control is not bit-blasted correctly.", pName );
printf( "Warning: Case-statement with 1-bit control is treated as a 2:1 MUX (correct for unsigned signals only).\n" );
}
pObj = Wlc_NtkObj( p->pNtk, NameIdOut );
Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_MUX );
Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
......@@ -1210,10 +1227,20 @@ startword:
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read line beginning with %s.", pName );
}
}
if ( p->nNonZeroCount )
if ( p->nNonZero[0] )
{
printf( "Warning: Input file contains %d objects with non-zero-based ranges.\n", p->nNonZero[0] );
printf( "For example, signal with range [%d:%d] is declared in line %d.\n", p->nNonZero[1], p->nNonZero[2], p->nNonZero[3] );
}
if ( p->nNegative[0] )
{
printf( "Warning: Input file contains %d objects with negative ranges.\n", p->nNegative[0] );
printf( "For example, signal with range [%d:%d] is declared in line %d.\n", p->nNegative[1], p->nNegative[2], p->nNegative[3] );
}
if ( p->nReverse[0] )
{
printf( "Warning: %d objects in the input file have non-zero-based ranges.\n", p->nNonZeroCount );
printf( "In particular, a signal with range [%d:%d] is declared in line %d.\n", p->nNonZeroEnd, p->nNonZeroBeg, p->nNonZeroLine );
printf( "Warning: Input file contains %d objects with reversed ranges.\n", p->nReverse[0] );
printf( "For example, signal with range [%d:%d] is declared in line %d.\n", p->nReverse[1], p->nReverse[2], p->nReverse[3] );
}
return 1;
}
......
......@@ -165,7 +165,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
Wlc_ObjFanin1(p, pObj)->Mark = 1;
Wlc_NtkForEachObj( p, pObj, i )
{
int nDigits = Abc_Base10Log(pObj->End+1) + Abc_Base10Log(pObj->Beg+1);
int nDigits = Abc_Base10Log(Abc_AbsInt(pObj->End)+1) + Abc_Base10Log(Abc_AbsInt(pObj->Beg)+1) + (int)(pObj->End < 0) + (int)(pObj->Beg < 0);
if ( pObj->Mark )
{
pObj->Mark = 0;
......
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