summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2015-08-30 21:59:11 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2015-08-30 21:59:11 -0700
commitbb7837ff8690be1571527e00c39bcd0cd5e698d1 (patch)
treeb5bdb1a64aa43786a4753403cce7da146e4362b0 /src
parent4530ef6444e8525d88218a00d11e209e124d66a4 (diff)
downloadabc-bb7837ff8690be1571527e00c39bcd0cd5e698d1.tar.gz
abc-bb7837ff8690be1571527e00c39bcd0cd5e698d1.tar.bz2
abc-bb7837ff8690be1571527e00c39bcd0cd5e698d1.zip
Improvements to Cba data-structure.
Diffstat (limited to 'src')
-rw-r--r--src/base/cba/cba.h61
-rw-r--r--src/base/cba/cbaCom.c5
-rw-r--r--src/base/cba/cbaPrs.h29
-rw-r--r--src/base/cba/cbaReadVer.c553
-rw-r--r--src/base/cba/cbaWriteVer.c307
5 files changed, 763 insertions, 192 deletions
diff --git a/src/base/cba/cba.h b/src/base/cba/cba.h
index a23c2bc7..c0e0d91d 100644
--- a/src/base/cba/cba.h
+++ b/src/base/cba/cba.h
@@ -109,6 +109,7 @@ typedef enum {
CBA_BOX_REM,
CBA_BOX_POW,
CBA_BOX_MIN,
+ CBA_BOX_SQRT,
CBA_BOX_ABS,
CBA_BOX_SLTHAN,
@@ -121,6 +122,7 @@ typedef enum {
CBA_BOX_SHIL,
CBA_BOX_SHIR,
+ CBA_BOX_SHILA,
CBA_BOX_SHIRA,
CBA_BOX_ROTL,
CBA_BOX_ROTR,
@@ -142,6 +144,7 @@ typedef enum {
CBA_BOX_LATCH,
CBA_BOX_LATCHRS,
CBA_BOX_DFF,
+ CBA_BOX_DFFCPL,
CBA_BOX_DFFRS,
CBA_BOX_LAST // 67
@@ -278,29 +281,29 @@ static inline int Cba_NtkBoxUserNum( Cba_Ntk_t * p ) { r
static inline int Cba_NtkBoxPrimNum( Cba_Ntk_t * p ) { return Vec_StrCountLarger(&p->vObjType, (char)CBA_OBJ_BOX); }
static inline int Cba_NtkBoxSeqNum( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vSeq); }
-static inline void Cba_NtkCleanObjCopies( Cba_Ntk_t * p ) { Vec_IntFill(&p->vObjCopy, Vec_StrCap(&p->vObjType), -1); }
-static inline void Cba_NtkCleanObjFuncs( Cba_Ntk_t * p ) { Vec_IntFill(&p->vObjFunc, Vec_StrCap(&p->vObjType), 0); }
-static inline void Cba_NtkCleanObjNames( Cba_Ntk_t * p ) { Vec_IntFill(&p->vObjName, Vec_StrCap(&p->vObjType), 0); }
-static inline void Cba_NtkCleanObjAttrs( Cba_Ntk_t * p ) { Vec_IntFill(&p->vObjAttr, Vec_StrCap(&p->vObjType), 0); Vec_IntFill(&p->vAttrSto, 1, -1); }
-static inline void Cba_NtkCleanFonCopies( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonCopy, Vec_IntCap(&p->vFonObj), 0); }
-static inline void Cba_NtkCleanFonNames( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonName, Vec_IntCap(&p->vFonObj), 0); }
-static inline void Cba_NtkCleanFonRanges( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonRange,Vec_IntCap(&p->vFonObj), 0); }
-static inline void Cba_NtkCleanFonPrevs( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonPrev, Vec_IntCap(&p->vFonObj), 0); }
-static inline void Cba_NtkCleanFonNexts( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonNext, Vec_IntCap(&p->vFonObj), 0); }
-static inline void Cba_NtkCleanFinFon0( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFinFon0, Vec_IntCap(&p->vFinFon), 0); }
-static inline void Cba_NtkCleanFinObjs( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFinObj, Vec_IntCap(&p->vFinFon), 0); }
-
-static inline int Cba_NtkHasObjCopies( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vObjCopy) > 0; }
-static inline int Cba_NtkHasObjFuncs( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vObjFunc) > 0; }
-static inline int Cba_NtkHasObjNames( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vObjName) > 0; }
-static inline int Cba_NtkHasObjAttrs( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vObjAttr) > 0; }
-static inline int Cba_NtkHasFonCopies( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonCopy) > 0; }
-static inline int Cba_NtkHasFonNames( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonName) > 0; }
-static inline int Cba_NtkHasFonRanges( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonRange)> 0; }
-static inline int Cba_NtkHasFonPrevs( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonPrev) > 0; }
-static inline int Cba_NtkHasFonNexts( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonNext) > 0; }
-static inline int Cba_NtkHasFinFon0( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFinFon0) > 0; }
-static inline int Cba_NtkHasFinObjs( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFinObj) > 0; }
+static inline void Cba_NtkCleanObjCopies( Cba_Ntk_t * p ) { Vec_IntFill(&p->vObjCopy, Vec_StrCap(&p->vObjType), -1); }
+static inline void Cba_NtkCleanObjFuncs( Cba_Ntk_t * p ) { Vec_IntFill(&p->vObjFunc, Vec_StrCap(&p->vObjType), 0); }
+static inline void Cba_NtkCleanObjNames( Cba_Ntk_t * p ) { Vec_IntFill(&p->vObjName, Vec_StrCap(&p->vObjType), 0); }
+static inline void Cba_NtkCleanObjAttrs( Cba_Ntk_t * p ) { Vec_IntFill(&p->vObjAttr, Vec_StrCap(&p->vObjType), 0); Vec_IntFill(&p->vAttrSto, 1, -1); }
+static inline void Cba_NtkCleanFonCopies( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonCopy, Vec_IntCap(&p->vFonObj), 0); }
+static inline void Cba_NtkCleanFonNames( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonName, Vec_IntCap(&p->vFonObj), 0); }
+static inline void Cba_NtkCleanFonRanges( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonRange, Vec_IntCap(&p->vFonObj), 0); }
+static inline void Cba_NtkCleanFonPrevs( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonPrev, Vec_IntCap(&p->vFonObj), 0); }
+static inline void Cba_NtkCleanFonNexts( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFonNext, Vec_IntCap(&p->vFonObj), 0); }
+static inline void Cba_NtkCleanFinFon0( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFinFon0, Vec_IntCap(&p->vFinFon), 0); }
+static inline void Cba_NtkCleanFinObjs( Cba_Ntk_t * p ) { Vec_IntFill(&p->vFinObj, Vec_IntCap(&p->vFinFon), 0); }
+
+static inline int Cba_NtkHasObjCopies( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vObjCopy) > 0; }
+static inline int Cba_NtkHasObjFuncs( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vObjFunc) > 0; }
+static inline int Cba_NtkHasObjNames( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vObjName) > 0; }
+static inline int Cba_NtkHasObjAttrs( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vObjAttr) > 0; }
+static inline int Cba_NtkHasFonCopies( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonCopy) > 0; }
+static inline int Cba_NtkHasFonNames( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonName) > 0; }
+static inline int Cba_NtkHasFonRanges( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonRange) > 0; }
+static inline int Cba_NtkHasFonPrevs( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonPrev) > 0; }
+static inline int Cba_NtkHasFonNexts( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFonNext) > 0; }
+static inline int Cba_NtkHasFinFon0( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFinFon0) > 0; }
+static inline int Cba_NtkHasFinObjs( Cba_Ntk_t * p ) { return Vec_IntSize(&p->vFinObj) > 0; }
static inline void Cba_NtkFreeObjCopies( Cba_Ntk_t * p ) { Vec_IntErase(&p->vObjCopy); }
static inline void Cba_NtkFreeObjFuncs( Cba_Ntk_t * p ) { Vec_IntErase(&p->vObjFunc); }
@@ -318,7 +321,7 @@ static inline Cba_ObjType_t Cba_ObjType( Cba_Ntk_t * p, int i ) { a
static inline void Cba_ObjCleanType( Cba_Ntk_t * p, int i ) { assert(i>0); Vec_StrWriteEntry( &p->vObjType, i, (char)CBA_OBJ_NONE ); }
static inline int Cba_TypeIsBox( Cba_ObjType_t Type ) { return Type >= CBA_OBJ_BOX && Type < CBA_BOX_LAST; }
static inline int Cba_TypeIsSeq( Cba_ObjType_t Type ) { return Type >= CBA_BOX_RAM && Type <= CBA_BOX_DFFRS; }
-static inline int Cba_TypeIsUnary( Cba_ObjType_t Type ) { return Type == CBA_BOX_BUF || Type == CBA_BOX_INV || Type == CBA_BOX_LNOT || Type == CBA_BOX_MIN || Type == CBA_BOX_ABS || (Type >= CBA_BOX_RAND && Type <= CBA_BOX_RXNOR); }
+static inline int Cba_TypeIsUnary( Cba_ObjType_t Type ) { return Type == CBA_BOX_BUF || Type == CBA_BOX_INV || Type == CBA_BOX_LNOT || Type == CBA_BOX_MIN || Type == CBA_BOX_SQRT || Type == CBA_BOX_ABS || (Type >= CBA_BOX_RAND && Type <= CBA_BOX_RXNOR); }
static inline int Cba_TypeIsMux( Cba_ObjType_t Type ) { return Type == CBA_BOX_MUX || Type == CBA_BOX_NMUX || Type == CBA_BOX_SEL || Type == CBA_BOX_PSEL; }
static inline int Cba_ObjIsPi( Cba_Ntk_t * p, int i ) { return Cba_ObjType(p, i) == CBA_OBJ_PI; }
@@ -375,18 +378,20 @@ static inline int Cba_FonFromConst( int c ) { a
static inline int Cba_FonConstRange( Cba_Ntk_t * p, int f ) { assert(Cba_FonIsConst(f)); return atoi(Cba_NtkConst(p, Cba_FonConst(f))); }
static inline int Cba_FonObj( Cba_Ntk_t * p, int f ) { return Cba_FonIsReal(f) ? Vec_IntEntry(&p->vFonObj, f) : 0; }
-static inline int Cba_FonRange( Cba_Ntk_t * p, int f ) { assert(Cba_FonIsReal(f)); return Cba_NtkHasFonRanges(p)?Vec_IntGetEntry(&p->vFonRange, f):0;}
+static inline int Cba_FonRange( Cba_Ntk_t * p, int f ) { assert(Cba_FonIsReal(f)); return Cba_NtkHasFonRanges(p)?Abc_Lit2Var(Vec_IntGetEntry(&p->vFonRange, f)):0; }
+static inline int Cba_FonSigned( Cba_Ntk_t * p, int f ) { assert(Cba_FonIsReal(f)); return Cba_NtkHasFonRanges(p)?Abc_LitIsCompl(Vec_IntGetEntry(&p->vFonRange, f)):0; }
static inline int Cba_FonLeft( Cba_Ntk_t * p, int f ) { return Cba_NtkRangeLeft(p, Cba_FonRange(p, f)); }
static inline int Cba_FonRight( Cba_Ntk_t * p, int f ) { return Cba_NtkRangeRight(p, Cba_FonRange(p, f)); }
static inline int Cba_FonRangeSize( Cba_Ntk_t * p, int f ) { return Cba_FonIsConst(f) ? Cba_FonConstRange(p, f):Cba_NtkRangeSize(p, Cba_FonRange(p, f)); }
-static inline void Cba_FonSetRange( Cba_Ntk_t * p, int f, int x ) { assert(Cba_NtkHasFonRanges(p)); Vec_IntSetEntry(&p->vFonRange, f, x); }
+static inline void Cba_FonSetRangeSign( Cba_Ntk_t * p, int f, int x ) { assert(Cba_NtkHasFonRanges(p)); Vec_IntSetEntry(&p->vFonRange, f, x); }
+static inline void Cba_FonSetRange( Cba_Ntk_t * p, int f, int x ) { assert(Cba_NtkHasFonRanges(p)); Vec_IntSetEntry(&p->vFonRange, Abc_Var2Lit(f,0), x); }
static inline void Cba_FonHashRange( Cba_Ntk_t * p, int f, int l, int r ) { Cba_FonSetRange( p, f, Cba_NtkHashRange(p, l, r) ); }
static inline int Cba_FonCopy( Cba_Ntk_t * p, int f ) { return Cba_FonIsReal(f) ? Vec_IntEntry(&p->vFonCopy, f) : f; }
static inline void Cba_FonSetCopy( Cba_Ntk_t * p, int f, int x ) { assert(Cba_FonIsReal(f)); assert(Cba_FonCopy(p, f) == 0); Vec_IntWriteEntry(&p->vFonCopy, f, x); }
static inline int Cba_FonName( Cba_Ntk_t * p, int f ) { assert(Cba_NtkHasFonNames(p)); assert(Cba_FonIsReal(f)); return Vec_IntGetEntry( &p->vFonName, f ); }
static inline char * Cba_FonNameStr( Cba_Ntk_t * p, int f ) { assert(Cba_NtkHasFonNames(p)); assert(Cba_FonIsReal(f)); return Cba_NtkStr(p, Cba_FonName(p, f)); }
-static inline void Cba_FonSetName( Cba_Ntk_t * p, int f, int x ) { assert(Cba_NtkHasFonNames(p)); assert(Cba_FonIsReal(f)); assert(Cba_FonName(p, f) == 0); Vec_IntSetEntry(&p->vFonName, f, x); }
-static inline void Cba_FonCleanName( Cba_Ntk_t * p, int f ) { assert(Cba_NtkHasFonNames(p)); assert(Cba_FonIsReal(f)); assert(Cba_FonName(p, f) != 0); Vec_IntSetEntry(&p->vFonName, f, 0); }
+static inline void Cba_FonSetName( Cba_Ntk_t * p, int f, int x ) { assert(Cba_NtkHasFonNames(p)); assert(Cba_FonIsReal(f)); assert(Cba_FonName(p, f) == 0); Vec_IntSetEntry(&p->vFonName, f, x); }
+static inline void Cba_FonCleanName( Cba_Ntk_t * p, int f ) { assert(Cba_NtkHasFonNames(p)); assert(Cba_FonIsReal(f)); assert(Cba_FonName(p, f) != 0); Vec_IntSetEntry(&p->vFonName, f, 0); }
static inline void Cba_FonPatchName( Cba_Ntk_t * p, int f, int x) { assert(Cba_NtkHasFonNames(p)); assert(Cba_FonIsReal(f)); Cba_FonCleanName(p, f); Cba_FonSetName(p, f, x); }
static inline int Cba_FonIndex( Cba_Ntk_t * p, int f ) { assert(Cba_FonIsReal(f)); return f - Cba_ObjFon0( p, Cba_FonObj(p, f) ); }
static inline int Cba_FonNtkId( Cba_Ntk_t * p, int f ) { assert(Cba_FonIsReal(f)); return Cba_ObjNtkId( p, Cba_FonObj(p, f) ); }
diff --git a/src/base/cba/cbaCom.c b/src/base/cba/cbaCom.c
index ca86766e..b01f0d4e 100644
--- a/src/base/cba/cbaCom.c
+++ b/src/base/cba/cbaCom.c
@@ -213,7 +213,10 @@ int Cba_CommandWrite( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( argc == globalUtilOptind + 1 )
pFileName = argv[globalUtilOptind];
else if ( argc == globalUtilOptind && p )
- pFileName = Extra_FileNameGenericAppend( Cba_ManName(p), "_out.v" );
+ {
+ pFileName = Extra_FileNameGenericAppend( Cba_ManSpec(p) ? Cba_ManSpec(p) : Cba_ManName(p), "_out.v" );
+ printf( "Generated output file name \"%s\".\n", pFileName );
+ }
else
{
printf( "Output file name should be given on the command line.\n" );
diff --git a/src/base/cba/cbaPrs.h b/src/base/cba/cbaPrs.h
index 2f5220d3..5183762d 100644
--- a/src/base/cba/cbaPrs.h
+++ b/src/base/cba/cbaPrs.h
@@ -42,15 +42,19 @@ typedef enum {
PRS_VER_OUTPUT, // 2: output
PRS_VER_INOUT, // 3: inout
PRS_VER_WIRE, // 4: wire
- PRS_VER_MODULE, // 5: module
- PRS_VER_ASSIGN, // 6: assign
- PRS_VER_REG, // 7: reg
+ PRS_VER_REG, // 5: reg
+ PRS_VER_MODULE, // 6: module
+ PRS_VER_ASSIGN, // 7: assign
PRS_VER_ALWAYS, // 8: always
- PRS_VER_DEFPARAM, // 9: always
- PRS_VER_BEGIN, // 10: begin
- PRS_VER_END, // 11: end
- PRS_VER_ENDMODULE, // 12: endmodule
- PRS_VER_UNKNOWN // 13: unknown
+ PRS_VER_FUNCTION, // 9: function
+ PRS_VER_DEFPARAM, // 10: defparam
+ PRS_VER_BEGIN, // 11: begin
+ PRS_VER_END, // 12: end
+ PRS_VER_CASE, // 13: case
+ PRS_VER_ENDCASE, // 14: endcase
+ PRS_VER_SIGNED, // 15: signed
+ PRS_VER_ENDMODULE, // 16: endmodule
+ PRS_VER_UNKNOWN // 17: unknown
} Cba_VerType_t;
// parser name types
@@ -117,13 +121,17 @@ struct Prs_Man_t_
Vec_Str_t vCover; // one SOP cover
Vec_Int_t vTemp; // array of tokens
Vec_Int_t vTemp2; // array of tokens
+ Vec_Int_t vTemp3; // array of tokens
+ Vec_Int_t vTemp4; // array of tokens
// statistics
Vec_Int_t vKnown;
Vec_Int_t vFailed;
Vec_Int_t vSucceeded;
// error handling
int fUsingTemp2; // vTemp2 is in use
- char ErrorStr[1000]; // error
+ int FuncNameId; // temp value
+ int FuncRangeId; // temp value
+ char ErrorStr[1000]; // error
};
static inline Prs_Ntk_t * Prs_ManNtk( Vec_Ptr_t * vPrs, int i ) { return i >= 0 && i < Vec_PtrSize(vPrs) ? (Prs_Ntk_t *)Vec_PtrEntry(vPrs, i) : NULL; }
@@ -142,6 +150,7 @@ static inline char * Prs_NtkSop( Prs_Ntk_t * p, int h ) { return
static inline char * Prs_NtkConst( Prs_Ntk_t * p, int h ) { return Abc_NamStr(p->pFuns, h); }
static inline char * Prs_NtkName( Prs_Ntk_t * p ) { return Prs_NtkStr(p, Prs_NtkId(p)); }
static inline int Prs_NtkSigName( Prs_Ntk_t * p, int i ) { if (!p->fSlices) return i; assert(Abc_Lit2Att2(i) == CBA_PRS_NAME); return Abc_Lit2Var2(i); }
+static inline int Ptr_NtkRangeSize( Prs_Ntk_t * p, int h ) { int l = Hash_IntObjData0(p->vHash, h), r = Hash_IntObjData1(p->vHash, h); return 1 + (l > r ? l-r : r-l); }
static inline int Prs_SliceName( Prs_Ntk_t * p, int h ) { return Vec_IntEntry(&p->vSlices, h); }
static inline int Prs_SliceRange( Prs_Ntk_t * p, int h ) { return Vec_IntEntry(&p->vSlices, h+1); }
@@ -353,6 +362,8 @@ static inline void Prs_ManFree( Prs_Man_t * p )
Vec_StrErase( &p->vCover );
Vec_IntErase( &p->vTemp );
Vec_IntErase( &p->vTemp2 );
+ Vec_IntErase( &p->vTemp3 );
+ Vec_IntErase( &p->vTemp4 );
Vec_IntErase( &p->vKnown );
Vec_IntErase( &p->vFailed );
Vec_IntErase( &p->vSucceeded );
diff --git a/src/base/cba/cbaReadVer.c b/src/base/cba/cbaReadVer.c
index 3e78e5f9..a5bdb219 100644
--- a/src/base/cba/cbaReadVer.c
+++ b/src/base/cba/cbaReadVer.c
@@ -33,15 +33,19 @@ static const char * s_VerTypes[PRS_VER_UNKNOWN+1] = {
"output", // 2: output
"inout", // 3: inout
"wire", // 4: wire
- "module", // 5: module
- "assign", // 6: assign
- "reg", // 7: reg
+ "reg", // 5: reg
+ "module", // 6: module
+ "assign", // 7: assign
"always", // 8: always
- "defparam", // 9: defparam
- "begin", // 10: begin
- "end", // 11: end
- "endmodule", // 12: endmodule
- NULL // 13: unknown
+ "function", // 9: function
+ "defparam", // 10: defparam
+ "begin", // 11: begin
+ "end", // 12: end
+ "case", // 13: case
+ "endcase", // 14: endcase
+ "signed", // 15: signed
+ "endmodule", // 16: endmodule
+ NULL // 17: unknown
};
void Prs_NtkAddVerilogDirectives( Prs_Man_t * p )
@@ -157,7 +161,10 @@ static const char * s_VerNames[100] =
"wide_prio_select_",
"pow_",
"PrioEncoder_",
- "abs_",
+ "abs_",
+ "CPL_NMACROFF",
+ "CPL_MACROFF",
+ "CPL_FF",
NULL
};
@@ -252,6 +259,7 @@ static const Prs_VerInfo_t s_VerInfo[100] =
{CBA_BOX_POW, 2, "pow_", /* "OPER_POW" */ {"a","b","o"}},
{CBA_BOX_PENC, 1, "PrioEncoder_", /* "OPER_PRIO_ENCODER" */ {"sel","o"}},
{CBA_BOX_ABS, 1, "abs_", /* "OPER_ABS" */ {"i","o"}},
+ {CBA_BOX_DFFCPL, 4, "CPL_FF", /* "OPER_WIDE_DFF - 2" */ {"d","arstval","arst","clk","q","qbar"}},
{-1, 0, NULL, /* "PRIM_END" */ {NULL}}
};
@@ -374,6 +382,40 @@ static inline int Prs_ManUtilSkipUntilWord( Prs_Man_t * p, char * pWord )
p->pCur = pPlace + strlen(pWord);
return 0;
}
+// detect two symbols on the same line
+static inline int Prs_ManUtilDetectTwo( Prs_Man_t * p, char Sym1, char Sym2 )
+{
+ char * pTemp;
+ for ( pTemp = p->pCur; *pTemp != ';'; pTemp++ )
+ if ( *pTemp == Sym1 && *pTemp == Sym2 )
+ return 1;
+ return 0;
+}
+// find closing paren
+static inline char * Prs_ManFindClosingParenthesis( Prs_Man_t * p, char Open, char Close )
+{
+ char * pTemp;
+ int Counter = 0;
+ int fNotName = 1;
+ assert( Prs_ManIsChar(p, Open) );
+ for ( pTemp = p->pCur; *pTemp; pTemp++ )
+ {
+ if ( fNotName )
+ {
+ if ( *pTemp == Open )
+ Counter++;
+ if ( *pTemp == Close )
+ Counter--;
+ if ( Counter == 0 )
+ return pTemp;
+ }
+ if ( *pTemp == '\\' )
+ fNotName = 0;
+ else if ( !fNotName && *pTemp == ' ' )
+ fNotName = 1;
+ }
+ return NULL;
+}
/**Function*************************************************************
@@ -429,8 +471,11 @@ static inline int Prs_ManReadConstant( Prs_Man_t * p )
assert( Prs_ManIsDigit(p) );
while ( Prs_ManIsDigit(p) )
p->pCur++;
- if ( !Prs_ManIsChar(p, '\'') ) return Prs_ManErrorSet(p, "Cannot read constant.", 0);
+ if ( !Prs_ManIsChar(p, '\'') )
+ return Abc_NamStrFindOrAddLim( p->pFuns, pStart, p->pCur, NULL );
p->pCur++;
+ if ( Prs_ManIsChar(p, 's') )
+ p->pCur++;
if ( Prs_ManIsChar(p, 'b') )
{
p->pCur++;
@@ -520,24 +565,51 @@ static inline int Prs_ManReadSignal( Prs_Man_t * p )
if ( Prs_ManIsDigit(p) )
{
Item = Prs_ManReadConstant(p);
- if ( Item == 0 ) return Prs_ManErrorSet(p, "Error number 9.", 0);
+ if ( Item == 0 ) return 0;
if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 10.", 0);
return Abc_Var2Lit2( Item, CBA_PRS_CONST );
}
if ( Prs_ManIsChar(p, '{') )
{
+ if ( Prs_CharIsDigit(p->pCur[1]) )
+ {
+ p->pCur++;
+ if ( Prs_ManIsDigit(p) )
+ {
+ int i, Num = atoi(p->pCur);
+ while ( Prs_ManIsDigit(p) )
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 10.", 0);
+ assert( Prs_ManIsChar(p, '{') );
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 10.", 0);
+ Item = Prs_ManReadSignal( p );
+ assert( Prs_ManIsChar(p, '}') );
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 10.", 0);
+ // add to concat all, expect the last one
+ assert( p->fUsingTemp2 );
+ for ( i = 0; i < Num-1; i++ )
+ Vec_IntPush( &p->vTemp2, Item );
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 10.", 0);
+ assert( Prs_ManIsChar(p, '}') );
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 10.", 0);
+ return Item;
+ }
+ }
if ( p->fUsingTemp2 ) return Prs_ManErrorSet(p, "Cannot read nested concatenations.", 0);
p->fUsingTemp2 = 1;
Item = Prs_ManReadConcat(p, &p->vTemp2);
p->fUsingTemp2 = 0;
- if ( Item == 0 ) return Prs_ManErrorSet(p, "Error number 11.", 0);
+ if ( Item == 0 ) return 0;
if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 12.", 0);
return Item;
}
else
{
Item = Prs_ManReadName( p );
- if ( Item == 0 ) return Prs_ManErrorSet(p, "Error number 13.", 0); // was return 1;
+ if ( Item == 0 ) return 1; // no actual name
if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 14.", 0);
if ( Prs_ManIsChar(p, '[') )
{
@@ -580,10 +652,11 @@ static inline int Prs_ManReadSignalList2( Prs_Man_t * p, Vec_Int_t * vTemp )
p->pCur++;
if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 17.", 0);
ActItem = Prs_ManReadSignal( p );
- if ( ActItem == 0 ) return Prs_ManErrorSet(p, "Cannot read actual name of the instance.", 0);
+ if ( ActItem == 0 ) return Prs_ManErrorSet(p, "Cannot read actual name of an instance.", 0);
if ( !Prs_ManIsChar(p, ')') ) return Prs_ManErrorSet(p, "Cannot read \")\" in the instance.", 0);
p->pCur++;
- Vec_IntPushTwo( vTemp, FormId, ActItem );
+ if ( ActItem != 1 )
+ Vec_IntPushTwo( vTemp, FormId, ActItem );
if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 18.", 0);
if ( Prs_ManIsChar(p, ')') ) break;
if ( !Prs_ManIsChar(p, ',') ) return Prs_ManErrorSet(p, "Expecting comma in the instance.", 0);
@@ -606,33 +679,111 @@ static inline int Prs_ManReadSignalList2( Prs_Man_t * p, Vec_Int_t * vTemp )
SeeAlso []
***********************************************************************/
-static inline int Prs_ManReadDeclaration( Prs_Man_t * p, int Type )
+static inline int Prs_ManReadFunction( Prs_Man_t * p )
{
- int i, NameId, RangeId = 0;
- Vec_Int_t * vNames[4] = { &p->pNtk->vInputs, &p->pNtk->vOutputs, &p->pNtk->vInouts, &p->pNtk->vWires };
- Vec_Int_t * vNamesR[4] = { &p->pNtk->vInputsR, &p->pNtk->vOutputsR, &p->pNtk->vInoutsR, &p->pNtk->vWiresR };
- assert( Type >= PRS_VER_INPUT && Type <= PRS_VER_WIRE );
- if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 20.", 0);
- if ( Prs_ManIsChar(p, '[') && !(RangeId = Prs_ManReadRange(p)) ) return Prs_ManErrorSet(p, "Error number 21.", 0);
- if ( !Prs_ManReadNameList( p, &p->vTemp, ';' ) ) return Prs_ManErrorSet(p, "Error number 22.", 0);
- Vec_IntForEachEntry( &p->vTemp, NameId, i )
+ // this is a hack to read functions produced by ABC Verilog writer
+ p->FuncNameId = p->FuncRangeId = 0;
+ if ( Prs_ManUtilSkipUntilWord( p, "_func_" ) ) return Prs_ManErrorSet(p, "Cannot find \"_func_\" keyword.", 0);
+ p->pCur -= 6;
+ p->FuncNameId = Prs_ManReadName( p );
+ if ( p->FuncNameId == 0 ) return Prs_ManErrorSet(p, "Error number 30a.", 0);
+ if ( Prs_ManUtilSkipUntilWord( p, "input" ) ) return Prs_ManErrorSet(p, "Cannot find \"input\" keyword.", 0);
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 30b.", 0);
+ if ( Prs_ManIsChar(p, '[') )
+ p->FuncRangeId = Prs_ManReadRange(p);
+ else if ( Prs_ManReadName(p) == PRS_VER_SIGNED )
{
- Vec_IntPush( vNames[Type - PRS_VER_INPUT], NameId );
- Vec_IntPush( vNamesR[Type - PRS_VER_INPUT], RangeId );
- if ( Type < PRS_VER_WIRE )
- Vec_IntPush( &p->pNtk->vOrder, Abc_Var2Lit2(NameId, Type) );
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 30c.", 0);
+ if ( Prs_ManIsChar(p, '[') )
+ p->FuncRangeId = Prs_ManReadRange(p);
}
+ if ( Prs_ManUtilSkipUntilWord( p, "endfunction" ) ) return Prs_ManErrorSet(p, "Cannot find \"endfunction\" keyword.", 0);
return 1;
}
-static inline int Prs_ManReadAssign( Prs_Man_t * p )
+static inline int Prs_ManReadAlways( Prs_Man_t * p )
{
- int OutItem, InItem, fCompl = 0, fCompl2 = 0, Oper = 0;
- // read output name
- OutItem = Prs_ManReadSignal( p );
- if ( OutItem == 0 ) return Prs_ManErrorSet(p, "Cannot read output in assign-statement.", 0);
- if ( !Prs_ManIsChar(p, '=') ) return Prs_ManErrorSet(p, "Expecting \"=\" in assign-statement.", 0);
- p->pCur++;
+ // this is a hack to read always-statement representing case-statement
+ int iToken;
+ char * pClose;
if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23.", 0);
+ if ( !Prs_ManIsChar(p, '@') ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ if ( !Prs_ManIsChar(p, '(') ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ pClose = Prs_ManFindClosingParenthesis( p, '(', ')' );
+ if ( pClose == NULL )
+ return Prs_ManErrorSet(p, "Expecting closing parenthesis 1.", 0);
+ p->pCur = pClose;
+ if ( !Prs_ManIsChar(p, ')') ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ p->pCur++;
+ // read begin
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ iToken = Prs_ManReadName( p );
+ if ( iToken != PRS_VER_BEGIN ) return Prs_ManErrorSet(p, "Cannot read \"begin\" keyword.", 0);
+ // read case
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ iToken = Prs_ManReadName( p );
+ if ( iToken != PRS_VER_CASE ) return Prs_ManErrorSet(p, "Cannot read \"case\" keyword.", 0);
+ // read control
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ if ( !Prs_ManIsChar(p, '(') ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ iToken = Prs_ManReadSignal( p );
+ if ( iToken == 0 ) return Prs_ManErrorSet(p, "Cannot read output in assign-statement.", 0);
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ if ( !Prs_ManIsChar(p, ')') ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ p->pCur++;
+ // save control
+ Vec_IntClear( &p->vTemp3 );
+ Vec_IntPushTwo( &p->vTemp3, 0, 0 ); // output will go here
+ Vec_IntPushTwo( &p->vTemp3, 0, iToken );
+ // read conditions
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ if ( !Prs_ManIsDigit(p) ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ while ( Prs_ManIsDigit(p) )
+ {
+ while ( Prs_ManIsDigit(p) )
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ if ( !Prs_ManIsChar(p, ':') ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ // read output
+ iToken = Prs_ManReadSignal( p );
+ if ( iToken == 0 ) return Prs_ManErrorSet(p, "Cannot read output in assign-statement.", 0);
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ if ( !Prs_ManIsChar(p, '=') ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ p->pCur++;
+ // save output
+ Vec_IntWriteEntry( &p->vTemp3, 1, iToken );
+ // read input
+ iToken = Prs_ManReadSignal( p );
+ if ( iToken == 0 ) return Prs_ManErrorSet(p, "Cannot read output in assign-statement.", 0);
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ if ( !Prs_ManIsChar(p, ';') ) return Prs_ManErrorSet(p, "Cannot parse always statement.", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ // save input
+ Vec_IntPushTwo( &p->vTemp3, 0, iToken );
+ }
+ // read endcase
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ iToken = Prs_ManReadName( p );
+ if ( iToken != PRS_VER_ENDCASE ) return Prs_ManErrorSet(p, "Cannot read \"endcase\" keyword.", 0);
+ // read end
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ iToken = Prs_ManReadName( p );
+ if ( iToken != PRS_VER_END ) return Prs_ManErrorSet(p, "Cannot read \"end\" keyword.", 0);
+ // save binary operator
+ Prs_NtkAddBox( p->pNtk, CBA_BOX_NMUX, 0, &p->vTemp3 );
+ return 1;
+}
+/*
+static inline int Prs_ManReadExpression( Prs_Man_t * p, int OutItem )
+{
+ int InItem, fCompl = 0, fCompl2 = 0, Oper = 0;
+ // read output name
if ( Prs_ManIsChar(p, '~') )
{
fCompl = 1;
@@ -717,17 +868,248 @@ static inline int Prs_ManReadAssign( Prs_Man_t * p )
Prs_NtkAddBox( p->pNtk, Oper, 0, &p->vTemp );
return 1;
}
+*/
+static inline int Prs_ManReadExpression( Prs_Man_t * p, int OutItem )
+{
+ char * pClose;
+ int Item, Type = CBA_OBJ_NONE;
+ int fRotating = 0;
+
+ // write output name
+ Vec_IntClear( &p->vTemp );
+ Vec_IntPush( &p->vTemp, 0 );
+ Vec_IntPush( &p->vTemp, OutItem );
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ if ( Prs_ManIsChar(p, '(') )
+ {
+ // THIS IS A HACK TO DETECT rotating shifters: try to find both << and >> on the same line
+ if ( Prs_ManUtilDetectTwo(p, '>', '>') && Prs_ManUtilDetectTwo(p, '<', '<') )
+ fRotating = 1;
+ pClose = Prs_ManFindClosingParenthesis( p, '(', ')' );
+ if ( pClose == NULL )
+ return Prs_ManErrorSet(p, "Expecting closing parenthesis 1.", 0);
+ *p->pCur = *pClose = ' ';
+ }
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ // read constant or concatenation
+ if ( Prs_ManIsDigit(p) || Prs_ManIsChar(p, '{') )
+ {
+ Item = Prs_ManReadSignal( p );
+ // write constant
+ Vec_IntPush( &p->vTemp, 0 );
+ Vec_IntPush( &p->vTemp, Item );
+ Type = CBA_BOX_BUF;
+ }
+ else if ( Prs_ManIsChar(p, '!') || Prs_ManIsChar(p, '~') || Prs_ManIsChar(p, '@') ||
+ Prs_ManIsChar(p, '&') || Prs_ManIsChar(p, '|') || Prs_ManIsChar(p, '^') || Prs_ManIsChar(p, '-') )
+ {
+ if ( Prs_ManIsChar(p, '!') )
+ Type = CBA_BOX_LNOT;
+ else if ( Prs_ManIsChar(p, '~') )
+ Type = CBA_BOX_INV;
+ else if ( Prs_ManIsChar(p, '@') )
+ Type = CBA_BOX_SQRT;
+ else if ( Prs_ManIsChar(p, '&') )
+ Type = CBA_BOX_RAND;
+ else if ( Prs_ManIsChar(p, '|') )
+ Type = CBA_BOX_ROR;
+ else if ( Prs_ManIsChar(p, '^') )
+ Type = CBA_BOX_RXOR;
+ else if ( Prs_ManIsChar(p, '-') )
+ Type = CBA_BOX_MIN;
+ else assert( 0 );
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ // skip parentheses
+ if ( Prs_ManIsChar(p, '(') )
+ {
+ pClose = Prs_ManFindClosingParenthesis( p, '(', ')' );
+ if ( pClose == NULL )
+ return Prs_ManErrorSet(p, "Expecting closing parenthesis 2.", 0);
+ *p->pCur = *pClose = ' ';
+ }
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ // read first name
+ Item = Prs_ManReadSignal( p );
+ if ( Item == 0 ) return Prs_ManErrorSet(p, "Cannot read name after a unary operator.", 0);
+ Vec_IntPush( &p->vTemp, 0 );
+ Vec_IntPush( &p->vTemp, Item );
+ }
+ else
+ {
+ // read first name
+ Item = Prs_ManReadSignal( p );
+ if ( Item == 0 ) return Prs_ManErrorSet(p, "Cannot read name after a binary operator.", 0);
+ // check if this is a recent function
+ if ( Abc_Lit2Var2(Item) == p->FuncNameId )
+ {
+ int Status, nInputs, RangeSize;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ if ( !Prs_ManIsChar(p, '(') ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ p->pCur++;
+ Status = Prs_ManReadSignalList( p, &p->vTemp, ')', 1 );
+ nInputs = Vec_IntSize(&p->vTemp)/2;
+ RangeSize = p->FuncRangeId ? Ptr_NtkRangeSize(p->pNtk, p->FuncRangeId) : 1;
+ p->FuncNameId = p->FuncRangeId = 0;
+ if ( Status == 0 ) return 0;
+ if ( nInputs == 1 )
+ Type = CBA_BOX_DEC;
+ else if ( nInputs == RangeSize + 1 )
+ Type = CBA_BOX_SEL;
+ else if ( nInputs == (1 << RangeSize) + 1 )
+ Type = CBA_BOX_NMUX;
+ else return Prs_ManErrorSet(p, "Cannot determine word-level operator.", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ // save word-level operator
+ Vec_IntInsert( &p->vTemp, 0, 0 );
+ Vec_IntInsert( &p->vTemp, 1, OutItem );
+ Prs_NtkAddBox( p->pNtk, Type, 0, &p->vTemp );
+ return 1;
+ }
+ Vec_IntPush( &p->vTemp, 0 );
+ Vec_IntPush( &p->vTemp, Item );
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ assert( !Prs_ManIsChar(p, '[') );
+
+ // get the next symbol
+ if ( Prs_ManIsChar(p, ',') || Prs_ManIsChar(p, ';') )
+ Type = CBA_BOX_BUF;
+ else if ( Prs_ManIsChar(p, '?') )
+ {
+ p->pCur++;
+ Item = Prs_ManReadSignal( p );
+ if ( Item == 0 ) return 0;
+ Vec_IntPush( &p->vTemp, 0 );
+ Vec_IntPush( &p->vTemp, Item );
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ if ( !Prs_ManIsChar(p, ':') ) return Prs_ManErrorSet(p, "MUX lacks the colon symbol (:).", 0);
+
+ p->pCur++;
+ Item = Prs_ManReadSignal( p );
+ if ( Item == 0 ) return 0;
+ Vec_IntPush( &p->vTemp, 0 );
+ Vec_IntPush( &p->vTemp, Item );
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ assert( Vec_IntSize(&p->vTemp) == 8 );
+ //ABC_SWAP( int, Vec_IntArray(&p->vTemp)[3], Vec_IntArray(&p->vTemp)[5] );
+ Type = CBA_BOX_MUX;
+ }
+ else
+ {
+ if ( p->pCur[0] == '>' && p->pCur[1] == '>' && p->pCur[2] != '>' ) p->pCur += 2, Type = fRotating ? CBA_BOX_ROTR : CBA_BOX_SHIR;
+ else if ( p->pCur[0] == '>' && p->pCur[1] == '>' && p->pCur[2] == '>' ) p->pCur += 3, Type = CBA_BOX_SHIRA;
+ else if ( p->pCur[0] == '<' && p->pCur[1] == '<' && p->pCur[2] != '<' ) p->pCur += 2, Type = fRotating ? CBA_BOX_ROTL : CBA_BOX_SHIL;
+ else if ( p->pCur[0] == '<' && p->pCur[1] == '<' && p->pCur[2] == '<' ) p->pCur += 3, Type = CBA_BOX_SHILA;
+ else if ( p->pCur[0] == '&' && p->pCur[1] != '&' ) p->pCur += 1, Type = CBA_BOX_AND;
+ else if ( p->pCur[0] == '|' && p->pCur[1] != '|' ) p->pCur += 1, Type = CBA_BOX_OR;
+ else if ( p->pCur[0] == '^' && p->pCur[1] != '^' ) p->pCur += 1, Type = CBA_BOX_XOR;
+ else if ( p->pCur[0] == '&' && p->pCur[1] == '&' ) p->pCur += 2, Type = CBA_BOX_LAND;
+ else if ( p->pCur[0] == '|' && p->pCur[1] == '|' ) p->pCur += 2, Type = CBA_BOX_LOR;
+ else if ( p->pCur[0] == '=' && p->pCur[1] == '=' ) p->pCur += 2, Type = CBA_BOX_EQU;
+ else if ( p->pCur[0] == '!' && p->pCur[1] == '=' ) p->pCur += 2, Type = CBA_BOX_NEQU;
+ else if ( p->pCur[0] == '<' && p->pCur[1] != '=' ) p->pCur += 1, Type = CBA_BOX_LTHAN;
+ else if ( p->pCur[0] == '>' && p->pCur[1] != '=' ) p->pCur += 1, Type = CBA_BOX_MTHAN;
+ else if ( p->pCur[0] == '<' && p->pCur[1] == '=' ) p->pCur += 2, Type = CBA_BOX_LETHAN;
+ else if ( p->pCur[0] == '>' && p->pCur[1] == '=' ) p->pCur += 2, Type = CBA_BOX_METHAN;
+ else if ( p->pCur[0] == '+' ) p->pCur += 1, Type = CBA_BOX_ADD;
+ else if ( p->pCur[0] == '-' ) p->pCur += 1, Type = CBA_BOX_SUB;
+ else if ( p->pCur[0] == '*' && p->pCur[1] != '*' ) p->pCur += 1, Type = CBA_BOX_MUL;
+ else if ( p->pCur[0] == '/' ) p->pCur += 1, Type = CBA_BOX_DIV;
+ else if ( p->pCur[0] == '%' ) p->pCur += 1, Type = CBA_BOX_MOD;
+ else if ( p->pCur[0] == '*' && p->pCur[1] == '*' ) p->pCur += 2, Type = CBA_BOX_POW;
+ else return Prs_ManErrorSet(p, "Unsupported operation.", 0);
+
+ Item = Prs_ManReadSignal( p );
+ if ( Item == 0 ) return 0;
+ Vec_IntPush( &p->vTemp, 0 );
+ Vec_IntPush( &p->vTemp, Item );
+ // for adder insert carry-in
+ if ( Type == CBA_BOX_ADD )
+ Vec_IntInsert( &p->vTemp, 2, 0 );
+ if ( Type == CBA_BOX_ADD )
+ Vec_IntInsert( &p->vTemp, 3, 0 );
+ }
+ }
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 24.", 0);
+ // make sure there is nothing left there
+ if ( fRotating )
+ {
+ Prs_ManUtilSkipUntilWord(p, ";");
+ p->pCur--;
+ }
+ else if ( !Prs_ManIsChar(p, ',') && !Prs_ManIsChar(p, ';') ) return Prs_ManErrorSet(p, "Trailing symbols on this line.", 0);
+ // save binary operator
+ Prs_NtkAddBox( p->pNtk, Type, 0, &p->vTemp );
+ return 1;
+}
+static inline int Prs_ManReadDeclaration( Prs_Man_t * p, int Type )
+{
+ int i, Item = 0, NameId, RangeId = 0, fSigned = 0;
+ Vec_Int_t * vNames[4] = { &p->pNtk->vInputs, &p->pNtk->vOutputs, &p->pNtk->vInouts, &p->pNtk->vWires };
+ Vec_Int_t * vNamesR[4] = { &p->pNtk->vInputsR, &p->pNtk->vOutputsR, &p->pNtk->vInoutsR, &p->pNtk->vWiresR };
+ assert( Type >= PRS_VER_INPUT && Type <= PRS_VER_WIRE );
+ // read first word
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 20.", 0);
+ if ( Prs_ManIsChar(p, '[') && !(RangeId = Prs_ManReadRange(p)) ) return Prs_ManErrorSet(p, "Error number 21.", 0);
+ Item = Prs_ManReadName(p);
+ if ( Item == PRS_VER_SIGNED )
+ {
+ fSigned = 1;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 20.", 0);
+ if ( Prs_ManIsChar(p, '[') && !(RangeId = Prs_ManReadRange(p)) ) return Prs_ManErrorSet(p, "Error number 21.", 0);
+ Item = Prs_ManReadName(p);
+ }
+ if ( Item == PRS_VER_WIRE )
+ {
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 20.", 0);
+ if ( Prs_ManIsChar(p, '[') && !(RangeId = Prs_ManReadRange(p)) ) return Prs_ManErrorSet(p, "Error number 21.", 0);
+ Item = Prs_ManReadName(p);
+ }
+ // read variable names
+ Vec_IntClear( &p->vTemp3 );
+ while ( 1 )
+ {
+ if ( Item == 0 ) return Prs_ManErrorSet(p, "Cannot read name in the list.", 0);
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 22a", 0);
+ if ( Item == PRS_VER_WIRE )
+ continue;
+ Vec_IntPush( &p->vTemp3, Item );
+ if ( Prs_ManIsChar(p, '=') )
+ {
+ if ( Type == PRS_VER_INPUT ) return Prs_ManErrorSet(p, "Input cannot be defined", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23.", 0);
+ if ( !Prs_ManReadExpression(p, Abc_Var2Lit2(Item, CBA_PRS_NAME)) )
+ return 0;
+ }
+ if ( Prs_ManIsChar(p, ';') )
+ break;
+ if ( !Prs_ManIsChar(p, ',') ) return Prs_ManErrorSet(p, "Expecting comma in the list.", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 22b.", 0);
+ Item = Prs_ManReadName(p);
+ }
+ Vec_IntForEachEntry( &p->vTemp3, NameId, i )
+ {
+ Vec_IntPush( vNames[Type - PRS_VER_INPUT], NameId );
+ Vec_IntPush( vNamesR[Type - PRS_VER_INPUT], Abc_Var2Lit(RangeId, fSigned) );
+ if ( Type < PRS_VER_WIRE )
+ Vec_IntPush( &p->pNtk->vOrder, Abc_Var2Lit2(NameId, Type) );
+ }
+ return 1;
+}
static inline int Prs_ManReadInstance( Prs_Man_t * p, int Func )
{
int InstId, Status;
-/*
- static Counter = 0;
- if ( ++Counter == 7 )
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 25.", 0);
+ if ( Prs_ManIsChar(p, '#') )
{
- int s=0;
+ p->pCur++;
+ while ( Prs_ManIsDigit(p) )
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 25.", 0);
}
-*/
- if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 25.", 0);
if ( (InstId = Prs_ManReadName(p)) )
if (Prs_ManUtilSkipSpaces(p)) return Prs_ManErrorSet(p, "Error number 26.", 0);
if ( !Prs_ManIsChar(p, '(') ) return Prs_ManErrorSet(p, "Expecting \"(\" in module instantiation.", 0);
@@ -767,6 +1149,7 @@ static inline int Prs_ManReadArguments( Prs_Man_t * p )
{
int fEscape = Prs_ManIsChar(p, '\\');
int iName = Prs_ManReadName( p );
+ int fSigned = 0;
if ( iName == 0 ) return Prs_ManErrorSet(p, "Error number 31.", 0);
if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 32.", 0);
if ( iName >= PRS_VER_INPUT && iName <= PRS_VER_INOUT && !fEscape ) // declaration
@@ -780,13 +1163,27 @@ static inline int Prs_ManReadArguments( Prs_Man_t * p )
}
iName = Prs_ManReadName( p );
if ( iName == 0 ) return Prs_ManErrorSet(p, "Error number 35.", 0);
+ if ( iName == PRS_VER_SIGNED )
+ {
+ fSigned = 1;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 32.", 0);
+ if ( Prs_ManIsChar(p, '[') )
+ {
+ iRange = Prs_ManReadRange(p);
+ if ( iRange == 0 ) return Prs_ManErrorSet(p, "Error number 33.", 0);
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 34.", 0);
+ }
+ iName = Prs_ManReadName( p );
+ if ( iName == 0 ) return Prs_ManErrorSet(p, "Error number 35.", 0);
+ }
}
if ( iType > 0 )
{
Vec_IntPush( vSigs[iType - PRS_VER_INPUT], iName );
- Vec_IntPush( vSigsR[iType - PRS_VER_INPUT], iRange );
+ Vec_IntPush( vSigsR[iType - PRS_VER_INPUT], Abc_Var2Lit(iRange, fSigned) );
Vec_IntPush( &p->pNtk->vOrder, Abc_Var2Lit2(iName, iType) );
}
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 36.", 0);
if ( Prs_ManIsChar(p, ')') )
break;
if ( !Prs_ManIsChar(p, ',') ) return Prs_ManErrorSet(p, "Expecting comma in the instance.", 0);
@@ -801,7 +1198,7 @@ static inline int Prs_ManReadArguments( Prs_Man_t * p )
// 0 = reached end-of-file; 1 = successfully parsed; 2 = recognized as primitive; 3 = failed and skipped; 4 = error (failed and could not skip)
static inline int Prs_ManReadModule( Prs_Man_t * p )
{
- int iToken, Status;
+ int iToken, Status, fAlways = 0;
if ( p->pNtk != NULL ) return Prs_ManErrorSet(p, "Parsing previous module is unfinished.", 4);
if ( Prs_ManUtilSkipSpaces(p) )
{
@@ -809,6 +1206,15 @@ static inline int Prs_ManReadModule( Prs_Man_t * p )
return 0;
}
// read keyword
+ while ( Prs_ManIsChar(p, '`') )
+ {
+ Prs_ManUtilSkipUntilWord(p, "\n");
+ if ( Prs_ManUtilSkipSpaces(p) )
+ {
+ Prs_ManErrorClear( p );
+ return 0;
+ }
+ }
iToken = Prs_ManReadName( p );
if ( iToken != PRS_VER_MODULE ) return Prs_ManErrorSet(p, "Cannot read \"module\" keyword.", 4);
if ( Prs_ManUtilSkipSpaces(p) ) return 4;
@@ -831,9 +1237,10 @@ static inline int Prs_ManReadModule( Prs_Man_t * p )
p->pCur++;
if ( Prs_ManUtilSkipSpaces(p) ) return 4;
// read declarations and instances
- while ( Prs_ManIsChar(p, ';') )
+ while ( Prs_ManIsChar(p, ';') || fAlways )
{
- p->pCur++;
+ if ( !fAlways ) p->pCur++;
+ fAlways = 0;
if ( Prs_ManUtilSkipSpaces(p) ) return 4;
iToken = Prs_ManReadName( p );
if ( iToken == PRS_VER_ENDMODULE )
@@ -842,18 +1249,47 @@ static inline int Prs_ManReadModule( Prs_Man_t * p )
Prs_ManFinalizeNtk( p );
return 1;
}
- if ( iToken >= PRS_VER_INPUT && iToken <= PRS_VER_WIRE ) // declaration
- Status = Prs_ManReadDeclaration( p, iToken );
+ if ( iToken >= PRS_VER_INPUT && iToken <= PRS_VER_REG ) // declaration
+ Status = Prs_ManReadDeclaration( p, iToken == PRS_VER_REG ? PRS_VER_WIRE : iToken );
else if ( iToken == PRS_VER_REG || iToken == PRS_VER_DEFPARAM ) // unsupported keywords
Status = Prs_ManUtilSkipUntil( p, ';' );
else // read instance
{
if ( iToken == PRS_VER_ASSIGN )
- Status = Prs_ManReadAssign( p );
+ {
+ // read output name
+ int OutItem = Prs_ManReadSignal( p );
+ if ( OutItem == 0 ) return Prs_ManErrorSet(p, "Cannot read output in assign-statement.", 0);
+ if ( !Prs_ManIsChar(p, '=') ) return Prs_ManErrorSet(p, "Expecting \"=\" in assign-statement.", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23.", 0);
+ // read expression
+ while ( 1 )
+ {
+ if ( !Prs_ManReadExpression(p, OutItem) ) return 0;
+ if ( Prs_ManIsChar(p, ';') )
+ break;
+ assert( Prs_ManIsChar(p, ',') );
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23a.", 0);
+ // read output name
+ OutItem = Prs_ManReadSignal( p );
+ if ( OutItem == 0 ) return Prs_ManErrorSet(p, "Cannot read output in assign-statement.", 0);
+ if ( !Prs_ManIsChar(p, '=') ) return Prs_ManErrorSet(p, "Expecting \"=\" in assign-statement.", 0);
+ p->pCur++;
+ if ( Prs_ManUtilSkipSpaces(p) ) return Prs_ManErrorSet(p, "Error number 23.", 0);
+ }
+ }
+ else if ( iToken == PRS_VER_ALWAYS )
+ Status = Prs_ManReadAlways(p), fAlways = 1;
+ else if ( iToken == PRS_VER_FUNCTION )
+ Status = Prs_ManReadFunction(p), fAlways = 1;
else
Status = Prs_ManReadInstance( p, iToken );
if ( Status == 0 )
{
+ return 4;
+
if ( Prs_ManUtilSkipUntilWord( p, "endmodule" ) ) return Prs_ManErrorSet(p, "Cannot find \"endmodule\" keyword.", 4);
//printf( "Warning! Failed to parse \"%s\". Adding module \"%s\" as blackbox.\n",
// Abc_NamStr(p->pStrs, iToken), Abc_NamStr(p->pStrs, p->pNtk->iModuleName) );
@@ -1062,7 +1498,7 @@ int Prs_CreateRange( Cba_Ntk_t * p, int iFon, int NameId )
if ( RangeId == 0 )
return 1;
assert( RangeId > 0 );
- Cba_FonSetRange( p, iFon, RangeId );
+ Cba_FonSetRangeSign( p, iFon, RangeId );
return Cba_FonRangeSize( p, iFon );
}
/*
@@ -1396,7 +1832,7 @@ void Prs_CreateVerilogPio( Cba_Ntk_t * p, Prs_Ntk_t * pNtk )
iObj = Cba_ObjAlloc( p, CBA_OBJ_PI, 0, 1 );
Cba_ObjSetName( p, iObj, NameId ); // direct name
iFon = Cba_ObjFon0(p, iObj);
- Cba_FonSetRange( p, iFon, RangeId );
+ Cba_FonSetRangeSign( p, iFon, RangeId );
Cba_FonSetName( p, iFon, NameId );
Cba_NtkSetMap( p, NameId, iObj );
}
@@ -1482,8 +1918,17 @@ int Prs_CreateVerilogNtk( Cba_Ntk_t * p, Prs_Ntk_t * pNtk )
{
if ( Prs_BoxIsNode(pNtk, i) ) // node
{
+ int Type = Prs_BoxNtk(pNtk, i);
int nSigs = Prs_BoxIONum( pNtk, i );
- iObj = Cba_ObjAlloc( p, Prs_BoxNtk(pNtk, i), nSigs-1, 1 );
+/*
+ int NameId = Abc_Lit2Var2(Vec_IntEntry(vBox, 1));
+ char * pName = Cba_NtkStr( p, NameId );
+ if ( !strcmp(pName, "E_336717") )
+ {
+ int s = 0;
+ }
+*/
+ iObj = Cba_ObjAlloc( p, Type, nSigs-1, Type == CBA_BOX_ADD ? 2 : 1 );
Prs_CreateSignalOut( p, Cba_ObjFon0(p, iObj), pNtk, Vec_IntEntry(vBox, 1) ); // node output
//Cba_ObjSetFunc( p, iObj, FuncId );
}
@@ -1505,7 +1950,7 @@ int Prs_CreateVerilogNtk( Cba_Ntk_t * p, Prs_Ntk_t * pNtk )
nInputs = Cba_NtkPiNum(pBox);
nOutputs = Cba_NtkPoNum(pBox);
}
- else if ( Type == CBA_BOX_ADD )
+ else if ( Type == CBA_BOX_ADD || Type == CBA_BOX_DFFCPL )
nOutputs = 2;
else if ( Type == CBA_BOX_NMUX )
{
@@ -1717,8 +2162,8 @@ int Prs_CreateVerilogNtk( Cba_Ntk_t * p, Prs_Ntk_t * pNtk )
Cba_ObjSetFinFon( p, iObj, 0, iFon );
if ( RangeId )
{
- assert( Cba_NtkRangeLeft(p, RangeId) == Cba_FonLeft(p, iFon) );
- assert( Cba_NtkRangeRight(p, RangeId) == Cba_FonRight(p, iFon) );
+ assert( Cba_NtkRangeLeft(p, Abc_Lit2Var(RangeId)) == Cba_FonLeft(p, iFon) );
+ assert( Cba_NtkRangeRight(p, Abc_Lit2Var(RangeId)) == Cba_FonRight(p, iFon) );
}
}
return 0;
diff --git a/src/base/cba/cbaWriteVer.c b/src/base/cba/cbaWriteVer.c
index b21b9f7e..cabc8111 100644
--- a/src/base/cba/cbaWriteVer.c
+++ b/src/base/cba/cbaWriteVer.c
@@ -34,6 +34,93 @@ ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cba_ManCreatePrimMap( char ** pMap )
+{
+ memset( pMap, 0, sizeof(char *) * CBA_BOX_LAST );
+
+ pMap[ CBA_BOX_SLICE ] = "sli";
+ pMap[ CBA_BOX_CATIN ] = "icc";
+ pMap[ CBA_BOX_CATOUT ] = "occ";
+
+ pMap[ CBA_BOX_BUF ] = "";
+ pMap[ CBA_BOX_INV ] = "~";
+ pMap[ CBA_BOX_AND ] = "&";
+ pMap[ CBA_BOX_NAND ] = "&";
+ pMap[ CBA_BOX_OR ] = "|";
+ pMap[ CBA_BOX_NOR ] = "|";
+ pMap[ CBA_BOX_XOR ] = "^";
+ pMap[ CBA_BOX_XNOR ] = "^";
+ pMap[ CBA_BOX_SHARP ] = "&";
+ pMap[ CBA_BOX_SHARPL ] = "&";
+ pMap[ CBA_BOX_MUX ] = "?";
+ pMap[ CBA_BOX_MAJ ] = NULL;
+ pMap[ CBA_BOX_RAND ] = "&";
+ pMap[ CBA_BOX_RNAND ] = "~&";
+ pMap[ CBA_BOX_ROR ] = "|";
+ pMap[ CBA_BOX_RNOR ] = "~|";
+ pMap[ CBA_BOX_RXOR ] = "^";
+ pMap[ CBA_BOX_RXNOR ] = "~^";
+ pMap[ CBA_BOX_LNOT ] = "!";
+ pMap[ CBA_BOX_LAND ] = "&&";
+ pMap[ CBA_BOX_LNAND ] = NULL;
+ pMap[ CBA_BOX_LOR ] = "||";
+ pMap[ CBA_BOX_LNOR ] = NULL;
+ pMap[ CBA_BOX_LXOR ] = "^^";
+ pMap[ CBA_BOX_LXNOR ] = NULL;
+ pMap[ CBA_BOX_NMUX ] = "nmux";
+ pMap[ CBA_BOX_SEL ] = "sel";
+ pMap[ CBA_BOX_PSEL ] = NULL;
+ pMap[ CBA_BOX_ENC ] = NULL;
+ pMap[ CBA_BOX_PENC ] = NULL;
+ pMap[ CBA_BOX_DEC ] = "dec";
+ pMap[ CBA_BOX_EDEC ] = NULL;
+ pMap[ CBA_BOX_ADD ] = "+";
+ pMap[ CBA_BOX_SUB ] = "-";
+ pMap[ CBA_BOX_MUL ] = "*";
+ pMap[ CBA_BOX_DIV ] = "/";
+ pMap[ CBA_BOX_MOD ] = "%";
+ pMap[ CBA_BOX_REM ] = "%";
+ pMap[ CBA_BOX_POW ] = "**";
+ pMap[ CBA_BOX_MIN ] = "-";
+ pMap[ CBA_BOX_SQRT ] = "@";
+ pMap[ CBA_BOX_ABS ] = NULL;
+ pMap[ CBA_BOX_LTHAN ] = "<";
+ pMap[ CBA_BOX_LETHAN ] = "<=";
+ pMap[ CBA_BOX_METHAN ] = ">=";
+ pMap[ CBA_BOX_MTHAN ] = ">";
+ pMap[ CBA_BOX_EQU ] = "==";
+ pMap[ CBA_BOX_NEQU ] = "!=";
+ pMap[ CBA_BOX_SHIL ] = "<<";
+ pMap[ CBA_BOX_SHIR ] = ">>";
+ pMap[ CBA_BOX_SHILA ] = "<<<";
+ pMap[ CBA_BOX_SHIRA ] = ">>>";
+ pMap[ CBA_BOX_ROTL ] = "rotL";
+ pMap[ CBA_BOX_ROTR ] = "rotR";
+
+ pMap[ CBA_BOX_TRI ] = "tri";
+ pMap[ CBA_BOX_RAM ] = "ram";
+ pMap[ CBA_BOX_RAMR ] = "ramR";
+ pMap[ CBA_BOX_RAMW ] = "ramW";
+ pMap[ CBA_BOX_RAMWC ] = "ramWC";
+ pMap[ CBA_BOX_RAMBOX ] = "ramBox";
+
+ pMap[ CBA_BOX_LATCH ] = "lat";
+ pMap[ CBA_BOX_LATCHRS] = "latrs";
+ pMap[ CBA_BOX_DFF ] = "dff";
+ pMap[ CBA_BOX_DFFRS ] = "dffrs";
+}
+
+/**Function*************************************************************
Synopsis [Writing parser state into a file.]
@@ -115,26 +202,59 @@ static void Prs_ManWriteVerilogMux( FILE * pFile, Prs_Ntk_t * p, Vec_Int_t * vSi
fprintf( pFile, "%s", pStrs[i/2] );
}
}
-static void Prs_ManWriteVerilogBoxes( FILE * pFile, Prs_Ntk_t * p )
+static void Prs_ManWriteVerilogBoxes( FILE * pFile, Prs_Ntk_t * p, char ** pTypeNames )
{
- Vec_Int_t * vBox; int i;
+ Vec_Int_t * vBox; int i, k;
Prs_NtkForEachBox( p, vBox, i )
{
Cba_ObjType_t NtkId = Prs_BoxNtk(p, i);
//char * pNtkName = Prs_NtkStr(p, Prs_BoxName(p, i));
if ( NtkId == CBA_BOX_MUX )
Prs_ManWriteVerilogMux( pFile, p, vBox );
- else if ( Prs_BoxIsNode(p, i) ) // node ------- check order of fanins
+ else if ( Prs_BoxIsNode(p, i) ) // node
{
- fprintf( pFile, " %s (", Ptr_TypeToName(NtkId) );
- Prs_ManWriteVerilogArray( pFile, p, vBox, 1 );
- fprintf( pFile, ");\n" );
+ fprintf( pFile, " assign " );
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, 1) );
+ fprintf( pFile, " = " );
+ if ( Cba_TypeIsUnary(NtkId) )
+ {
+ fprintf( pFile, "%s", pTypeNames[NtkId] );
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, 3) );
+ }
+ else if ( NtkId == CBA_BOX_NMUX )
+ {
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, 3) );
+ fprintf( pFile, " ? " );
+ for ( k = 5; k < Vec_IntSize(vBox); k += 2 )
+ {
+ if ( k > 5 ) fprintf( pFile, " : " );
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, k) );
+ }
+ }
+ else if ( NtkId == CBA_BOX_ADD )
+ {
+ if ( Vec_IntEntry(vBox, 3) )
+ {
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, 3) );
+ fprintf( pFile, " %s ", pTypeNames[NtkId] );
+ }
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, 5) );
+ fprintf( pFile, " %s ", pTypeNames[NtkId] );
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, 7) );
+ }
+ else
+ {
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, 3) );
+ fprintf( pFile, " %s ", pTypeNames[NtkId] );
+ Prs_ManWriteVerilogSignal( pFile, p, Vec_IntEntry(vBox, 5) );
+ }
+ fprintf( pFile, ";\n" );
}
else // box
{
- fprintf( pFile, " %s %s (", Prs_NtkStr(p, NtkId), Prs_BoxName(p, i) ? Prs_NtkStr(p, Prs_BoxName(p, i)) : "" );
+ fprintf( pFile, " %s %s ( ", Prs_NtkStr(p, NtkId), Prs_BoxName(p, i) ? Prs_NtkStr(p, Prs_BoxName(p, i)) : "" );
Prs_ManWriteVerilogArray2( pFile, p, vBox );
- fprintf( pFile, ");\n" );
+ fprintf( pFile, " );\n" );
}
}
}
@@ -147,7 +267,7 @@ static void Prs_ManWriteVerilogIos( FILE * pFile, Prs_Ntk_t * p, int SigType )
if ( SigType == 3 )
fprintf( pFile, "\n" );
Vec_IntForEachEntryTwo( vSigs[SigType], vSigsR[SigType], NameId, RangeId, i )
- fprintf( pFile, " %s %s%s;\n", pSigNames[SigType], RangeId ? Prs_ManWriteRange(p, RangeId, 0) : "", Prs_NtkStr(p, NameId) );
+ fprintf( pFile, " %s %s%s%s;\n", pSigNames[SigType], Abc_LitIsCompl(RangeId) ? "signed " : "", RangeId ? Prs_ManWriteRange(p, Abc_Lit2Var(RangeId), 0) : "", Prs_NtkStr(p, NameId) );
}
static void Prs_ManWriteVerilogIoOrder( FILE * pFile, Prs_Ntk_t * p, Vec_Int_t * vOrder )
{
@@ -155,7 +275,7 @@ static void Prs_ManWriteVerilogIoOrder( FILE * pFile, Prs_Ntk_t * p, Vec_Int_t *
Vec_IntForEachEntry( vOrder, NameId, i )
fprintf( pFile, "%s%s", Prs_NtkStr(p, Abc_Lit2Var2(NameId)), i == Vec_IntSize(vOrder) - 1 ? "" : ", " );
}
-static void Prs_ManWriteVerilogNtk( FILE * pFile, Prs_Ntk_t * p )
+static void Prs_ManWriteVerilogNtk( FILE * pFile, Prs_Ntk_t * p, char ** pTypeNames )
{
int s;
// write header
@@ -167,11 +287,12 @@ static void Prs_ManWriteVerilogNtk( FILE * pFile, Prs_Ntk_t * p )
Prs_ManWriteVerilogIos( pFile, p, s );
fprintf( pFile, "\n" );
// write objects
- Prs_ManWriteVerilogBoxes( pFile, p );
+ Prs_ManWriteVerilogBoxes( pFile, p, pTypeNames );
fprintf( pFile, "endmodule\n\n" );
}
void Prs_ManWriteVerilog( char * pFileName, Vec_Ptr_t * vPrs )
{
+ char * pTypeNames[CBA_BOX_LAST];
Prs_Ntk_t * pNtk = Prs_ManRoot(vPrs); int i;
FILE * pFile = fopen( pFileName, "wb" );
if ( pFile == NULL )
@@ -179,99 +300,16 @@ void Prs_ManWriteVerilog( char * pFileName, Vec_Ptr_t * vPrs )
printf( "Cannot open output file \"%s\".\n", pFileName );
return;
}
+ Cba_ManCreatePrimMap( pTypeNames );
fprintf( pFile, "// Design \"%s\" written by ABC on %s\n\n", Prs_NtkStr(pNtk, pNtk->iModuleName), Extra_TimeStamp() );
Vec_PtrForEachEntry( Prs_Ntk_t *, vPrs, pNtk, i )
- Prs_ManWriteVerilogNtk( pFile, pNtk );
+ Prs_ManWriteVerilogNtk( pFile, pNtk, pTypeNames );
fclose( pFile );
}
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cba_ManCreatePrimMap( char ** pMap )
-{
- memset( pMap, 0, sizeof(char *) * CBA_BOX_LAST );
-
- pMap[ CBA_BOX_SLICE ] = "sli";
- pMap[ CBA_BOX_CATIN ] = "icc";
- pMap[ CBA_BOX_CATOUT ] = "occ";
-
- pMap[ CBA_BOX_BUF ] = "";
- pMap[ CBA_BOX_INV ] = "~";
- pMap[ CBA_BOX_AND ] = "&";
- pMap[ CBA_BOX_NAND ] = "&";
- pMap[ CBA_BOX_OR ] = "|";
- pMap[ CBA_BOX_NOR ] = "|";
- pMap[ CBA_BOX_XOR ] = "^";
- pMap[ CBA_BOX_XNOR ] = "^";
- pMap[ CBA_BOX_SHARP ] = "&";
- pMap[ CBA_BOX_SHARPL ] = "&";
- pMap[ CBA_BOX_MUX ] = "?";
- pMap[ CBA_BOX_MAJ ] = NULL;
- pMap[ CBA_BOX_RAND ] = "&";
- pMap[ CBA_BOX_RNAND ] = "~&";
- pMap[ CBA_BOX_ROR ] = "|";
- pMap[ CBA_BOX_RNOR ] = "~|";
- pMap[ CBA_BOX_RXOR ] = "^";
- pMap[ CBA_BOX_RXNOR ] = "~^";
- pMap[ CBA_BOX_LNOT ] = "!";
- pMap[ CBA_BOX_LAND ] = "&&";
- pMap[ CBA_BOX_LNAND ] = NULL;
- pMap[ CBA_BOX_LOR ] = "||";
- pMap[ CBA_BOX_LNOR ] = NULL;
- pMap[ CBA_BOX_LXOR ] = "^^";
- pMap[ CBA_BOX_LXNOR ] = NULL;
- pMap[ CBA_BOX_NMUX ] = "nmux";
- pMap[ CBA_BOX_SEL ] = "sel";
- pMap[ CBA_BOX_PSEL ] = NULL;
- pMap[ CBA_BOX_ENC ] = NULL;
- pMap[ CBA_BOX_PENC ] = NULL;
- pMap[ CBA_BOX_DEC ] = "dec";
- pMap[ CBA_BOX_EDEC ] = NULL;
- pMap[ CBA_BOX_ADD ] = "+";
- pMap[ CBA_BOX_SUB ] = "-";
- pMap[ CBA_BOX_MUL ] = "*";
- pMap[ CBA_BOX_DIV ] = "/";
- pMap[ CBA_BOX_MOD ] = NULL;
- pMap[ CBA_BOX_REM ] = "%%";
- pMap[ CBA_BOX_POW ] = "**";
- pMap[ CBA_BOX_MIN ] = "-";
- pMap[ CBA_BOX_ABS ] = NULL;
- pMap[ CBA_BOX_LTHAN ] = "<";
- pMap[ CBA_BOX_LETHAN ] = "<=";
- pMap[ CBA_BOX_METHAN ] = ">=";
- pMap[ CBA_BOX_MTHAN ] = ">";
- pMap[ CBA_BOX_EQU ] = "==";
- pMap[ CBA_BOX_NEQU ] = "!=";
- pMap[ CBA_BOX_SHIL ] = "<<";
- pMap[ CBA_BOX_SHIR ] = ">>";
- pMap[ CBA_BOX_ROTL ] = "rotL";
- pMap[ CBA_BOX_ROTR ] = "rotR";
-
- pMap[ CBA_BOX_TRI ] = "tri";
- pMap[ CBA_BOX_RAM ] = "ram";
- pMap[ CBA_BOX_RAMR ] = "ramR";
- pMap[ CBA_BOX_RAMW ] = "ramW";
- pMap[ CBA_BOX_RAMWC ] = "ramWC";
- pMap[ CBA_BOX_RAMBOX ] = "ramBox";
-
- pMap[ CBA_BOX_LATCH ] = "lat";
- pMap[ CBA_BOX_LATCHRS] = "latrs";
- pMap[ CBA_BOX_DFF ] = "dff";
- pMap[ CBA_BOX_DFFRS ] = "dffrs";
-}
-
static inline int Cba_NameIsLegalInVerilog( char * pName, int NameId )
{
@@ -333,8 +371,9 @@ void Cba_ManWriteFonRange( Cba_Ntk_t * p, int iFon )
Vec_Str_t * vStr = &p->pDesign->vOut;
if ( !iFon || Cba_FonIsConst(iFon) || (Cba_FonRangeSize(p, iFon) == 1 && Cba_FonRight(p, iFon) == 0) )
return;
+ if ( Cba_FonSigned(p, iFon) )
+ Vec_StrPrintF( vStr, "signed " );
Vec_StrPrintF( vStr, "[%d:%d] ", Cba_FonLeft(p, iFon), Cba_FonRight(p, iFon) );
-
}
void Cba_ManWriteFonName( Cba_Ntk_t * p, int iFon, int fInlineConcat, int fInput )
{
@@ -732,6 +771,47 @@ void Cba_ManWriteVerilogNtk( Cba_Ntk_t * p, int fInlineConcat )
Cba_ManWriteFonName( p, iFonD, fInlineConcat, 0 );
Vec_StrPrintStr( vStr, ";" );
}
+ else if ( Type == CBA_BOX_DFFCPL )
+ {
+ // CPL_FF#32 inst_reg( .d(s1), .arstval(s2), .arst(s3), .clk(s4), .q(s5), .qbar(s6) );
+ int iFon0 = Cba_ObjFon0(p, iObj);
+ int iFon1 = Cba_ObjFon(p, iObj, 1);
+ int Range = Cba_FonRangeSize( p, iFon0 );
+ if ( !Vec_BitEntry(vPoFons, iFon0) )
+ {
+ Vec_StrPrintStr( vStr, " wire " );
+ Cba_ManWriteFonRange( p, iFon0 );
+ Cba_ManWriteFonName( p, iFon0, 0, 0 );
+ Vec_StrPrintStr( vStr, ";\n" );
+ }
+ if ( !Vec_BitEntry(vPoFons, iFon1) && Cba_FonName(p, iFon1) )
+ {
+ Vec_StrPrintStr( vStr, " wire " );
+ Cba_ManWriteFonRange( p, iFon1 );
+ Cba_ManWriteFonName( p, iFon1, 0, 0 );
+ Vec_StrPrintStr( vStr, ";\n" );
+ }
+ Vec_StrPrintStr( vStr, " CPL_FF" );
+ if ( Range > 1 )
+ Vec_StrPrintF( vStr, "#%d", Range );
+ Vec_StrPrintStr( vStr, " " );
+ if ( Cba_ObjName(p, iObj) )
+ Vec_StrPrintStr( vStr, Cba_ObjGetName(p, iObj) );
+ Vec_StrPrintStr( vStr, " ( .d(" );
+ Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 0), fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, "), .arstval(" );
+ Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 1), fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, "), .arst(" );
+ Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 2), fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, "), .clk(" );
+ Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 3), fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, "), .q(" );
+ Cba_ManWriteFonName( p, iFon0, fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, "), .qbar(" );
+ if ( Cba_FonName(p, iFon1) )
+ Cba_ManWriteFonName( p, iFon1, fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, ") );" );
+ }
else if ( Type == CBA_BOX_ADD )
{
int iFon0 = Cba_ObjFon0(p, iObj);
@@ -772,7 +852,7 @@ void Cba_ManWriteVerilogNtk( Cba_Ntk_t * p, int fInlineConcat )
Vec_StrPrintStr( vStr, " = " );
}
// write carry-in
- if ( Cba_ObjFinFon(p, iObj, 0) != Cba_FonFromConst(1) )
+ if ( Cba_ObjFinFon(p, iObj, 0) && Cba_ObjFinFon(p, iObj, 0) != Cba_FonFromConst(1) )
{
Vec_StrPush( vStr, ' ' );
Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 0), fInlineConcat, 0 );
@@ -808,6 +888,33 @@ void Cba_ManWriteVerilogNtk( Cba_Ntk_t * p, int fInlineConcat )
Vec_StrPrintStr( vStr, " : " );
Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 2), fInlineConcat, 0 );
}
+ else if ( Type == CBA_BOX_ROTL || Type == CBA_BOX_ROTR )
+ {
+ // wire [27:0] s4960 = (s57 >> 17) | (s57 << 11);
+ int Range = Cba_FonRangeSize( p, Cba_ObjFon0(p, iObj) );
+ int iFinFon1 = Cba_ObjFinFon(p, iObj, 1);
+ Vec_StrPush( vStr, '(' );
+ Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 0), fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, Type == CBA_BOX_ROTL ? " << " : " >> " );
+ if ( Cba_FonIsConst(iFinFon1) )
+ Vec_StrPrintNum( vStr, Cba_FonConst(iFinFon1) );
+ else
+ Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 1), fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, ") | (" );
+ Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 0), fInlineConcat, 0 );
+ Vec_StrPrintStr( vStr, Type == CBA_BOX_ROTL ? " >> " : " << " );
+ if ( Cba_FonIsConst(iFinFon1) )
+ Vec_StrPrintNum( vStr, Range - Cba_FonConst(iFinFon1) );
+ else
+ {
+ Vec_StrPush( vStr, '(' );
+ Vec_StrPrintNum( vStr, Range );
+ Vec_StrPrintStr( vStr, " - " );
+ Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 1), fInlineConcat, 0 );
+ Vec_StrPush( vStr, ')' );
+ }
+ Vec_StrPush( vStr, ')' );
+ }
else if ( Type == CBA_BOX_LTHAN )
{
int fLessThan = (Cba_ObjFinFon(p, iObj, 0) == Cba_FonFromConst(1)); // const0
@@ -826,7 +933,6 @@ void Cba_ManWriteVerilogNtk( Cba_Ntk_t * p, int fInlineConcat )
else if ( Cba_NtkTypeName(p, Type) ) // binary operation
{
int fCompl = (Type == CBA_BOX_NAND || Type == CBA_BOX_NOR || Type == CBA_BOX_XNOR);
- Vec_StrPush( vStr, ' ' );
if ( fCompl )
Vec_StrPrintStr( vStr, "!(" );
Cba_ManWriteFonName( p, Cba_ObjFinFon(p, iObj, 0), fInlineConcat, 0 );
@@ -839,8 +945,9 @@ void Cba_ManWriteVerilogNtk( Cba_Ntk_t * p, int fInlineConcat )
}
else // unknown
{
+ char * pName = Cba_FonGetName(p, Cba_ObjFon0(p, iObj));
Vec_StrPrintStr( vStr, "<unknown operator>" );
- printf( "Cba_ManWriteVerilog(): In module \"%s\", cannot write object \"%s\".\n", Cba_NtkName(p), Cba_ObjGetName(p, iObj) );
+ printf( "Cba_ManWriteVerilog(): In module \"%s\", cannot write object \"%s\" with output name \"%s\".\n", Cba_NtkName(p), Cba_ObjGetName(p, iObj), pName );
}
Vec_StrPush( vStr, ';' );
}