From fe5c4df0790cdfcec93cdfb4cc8e0c0068950a43 Mon Sep 17 00:00:00 2001 From: Patrick Stewart Date: Mon, 26 Feb 2018 04:25:07 -0500 Subject: [PATCH] Support trig functions (() etc), bug1281. Signed-off-by: Wilson Snyder --- Changes | 2 + src/V3AstNodes.h | 248 +++++++++++++++++++++++++---------- src/V3Width.cpp | 8 +- src/verilog.l | 38 ++++-- src/verilog.y | 28 ++++ test_regress/t/t_math_trig.v | 11 +- 6 files changed, 242 insertions(+), 93 deletions(-) diff --git a/Changes b/Changes index 0b71f4d7d..31f18ab39 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,8 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.921 devel +*** Support trig functions ($sin() etc), bug1281. [Patrick Stewart] + **** Fix GCC 8.0 issues, bug1273. **** Fix pullup/pulldowns on bit selects, bug1274. [Rob Stoddard] diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 7abdefd14..be0745701 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -3947,94 +3947,175 @@ public: AstNode* filep() const { return lhsp(); } }; -class AstCeilD : public AstNodeUniop { +class AstNodeSystemUniop : public AstNodeUniop { public: - AstCeilD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { - dtypeSetDouble(); } - ASTNODE_NODE_FUNCS(CeilD) - virtual void numberOperate(V3Number& out, const V3Number& lhs) { - out.setDouble(ceil(lhs.toDouble())); } - virtual string emitVerilog() { return "%f$ceil(%l)"; } - virtual string emitC() { return "ceil(%li)"; } + AstNodeSystemUniop(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { + dtypeSetDouble(); } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} - virtual int instrCount() const { return instrCountDoubleTrig(); } + virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; -class AstExpD : public AstNodeUniop { +class AstLogD : public AstNodeSystemUniop { public: - AstExpD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { - dtypeSetDouble(); } - ASTNODE_NODE_FUNCS(ExpD) - virtual void numberOperate(V3Number& out, const V3Number& lhs) { - out.setDouble(exp(lhs.toDouble())); } - virtual string emitVerilog() { return "%f$exp(%l)"; } - virtual string emitC() { return "exp(%li)"; } - virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} - virtual bool sizeMattersLhs() {return false;} - virtual int instrCount() const { return instrCountDoubleTrig(); } - virtual bool doubleFlavor() const { return true; } -}; - -class AstFloorD : public AstNodeUniop { -public: - AstFloorD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { - dtypeSetDouble(); } - ASTNODE_NODE_FUNCS(FloorD) - virtual void numberOperate(V3Number& out, const V3Number& lhs) { - out.setDouble(floor(lhs.toDouble())); } - virtual string emitVerilog() { return "%f$floor(%l)"; } - virtual string emitC() { return "floor(%li)"; } - virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} - virtual bool sizeMattersLhs() {return false;} - virtual int instrCount() const { return instrCountDoubleTrig(); } - virtual bool doubleFlavor() const { return true; } -}; - -class AstLogD : public AstNodeUniop { -public: - AstLogD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { - dtypeSetDouble(); } + AstLogD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(LogD) - virtual void numberOperate(V3Number& out, const V3Number& lhs) { - out.setDouble(log(lhs.toDouble())); } + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(log(lhs.toDouble())); } virtual string emitVerilog() { return "%f$ln(%l)"; } virtual string emitC() { return "log(%li)"; } - virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} - virtual bool sizeMattersLhs() {return false;} - virtual int instrCount() const { return instrCountDoubleTrig(); } - virtual bool doubleFlavor() const { return true; } }; - -class AstLog10D : public AstNodeUniop { +class AstLog10D : public AstNodeSystemUniop { public: - AstLog10D(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { - dtypeSetDouble(); } + AstLog10D(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(Log10D) - virtual void numberOperate(V3Number& out, const V3Number& lhs) { - out.setDouble(log10(lhs.toDouble())); } + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(log10(lhs.toDouble())); } virtual string emitVerilog() { return "%f$log10(%l)"; } virtual string emitC() { return "log10(%li)"; } - virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} - virtual bool sizeMattersLhs() {return false;} - virtual int instrCount() const { return instrCountDoubleTrig(); } - virtual bool doubleFlavor() const { return true; } }; -class AstSqrtD : public AstNodeUniop { +class AstExpD : public AstNodeSystemUniop { public: - AstSqrtD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { - dtypeSetDouble(); } + AstExpD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(ExpD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(exp(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$exp(%l)"; } + virtual string emitC() { return "exp(%li)"; } +}; + +class AstSqrtD : public AstNodeSystemUniop { +public: + AstSqrtD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(SqrtD) - virtual void numberOperate(V3Number& out, const V3Number& lhs) { - out.setDouble(sqrt(lhs.toDouble())); } + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(sqrt(lhs.toDouble())); } virtual string emitVerilog() { return "%f$sqrt(%l)"; } virtual string emitC() { return "sqrt(%li)"; } - virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} - virtual bool sizeMattersLhs() {return false;} - virtual int instrCount() const { return instrCountDoubleTrig(); } - virtual bool doubleFlavor() const { return true; } +}; + +class AstFloorD : public AstNodeSystemUniop { +public: + AstFloorD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(FloorD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(floor(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$floor(%l)"; } + virtual string emitC() { return "floor(%li)"; } +}; + +class AstCeilD : public AstNodeSystemUniop { +public: + AstCeilD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(CeilD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(ceil(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$ceil(%l)"; } + virtual string emitC() { return "ceil(%li)"; } +}; + +class AstSinD : public AstNodeSystemUniop { +public: + AstSinD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(SinD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(sin(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$sin(%l)"; } + virtual string emitC() { return "sin(%li)"; } +}; + +class AstCosD : public AstNodeSystemUniop { +public: + AstCosD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(CosD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(cos(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$cos(%l)"; } + virtual string emitC() { return "cos(%li)"; } +}; + +class AstTanD : public AstNodeSystemUniop { +public: + AstTanD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(TanD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(tan(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$tan(%l)"; } + virtual string emitC() { return "tan(%li)"; } +}; + +class AstAsinD : public AstNodeSystemUniop { +public: + AstAsinD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(AsinD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(asin(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$asin(%l)"; } + virtual string emitC() { return "asin(%li)"; } +}; + +class AstAcosD : public AstNodeSystemUniop { +public: + AstAcosD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(AcosD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(acos(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$acos(%l)"; } + virtual string emitC() { return "acos(%li)"; } +}; + +class AstAtanD : public AstNodeSystemUniop { +public: + AstAtanD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(AtanD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(atan(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$atan(%l)"; } + virtual string emitC() { return "atan(%li)"; } +}; + +class AstSinhD : public AstNodeSystemUniop { +public: + AstSinhD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(SinhD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(sinh(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$sinh(%l)"; } + virtual string emitC() { return "sinh(%li)"; } +}; + +class AstCoshD : public AstNodeSystemUniop { +public: + AstCoshD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(CoshD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(cosh(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$cosh(%l)"; } + virtual string emitC() { return "cosh(%li)"; } +}; + +class AstTanhD : public AstNodeSystemUniop { +public: + AstTanhD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(TanhD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(tanh(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$tanh(%l)"; } + virtual string emitC() { return "tanh(%li)"; } +}; + +class AstAsinhD : public AstNodeSystemUniop { +public: + AstAsinhD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(AsinhD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(asinh(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$asinh(%l)"; } + virtual string emitC() { return "asinh(%li)"; } +}; + +class AstAcoshD : public AstNodeSystemUniop { +public: + AstAcoshD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(AcoshD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(acosh(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$acosh(%l)"; } + virtual string emitC() { return "acosh(%li)"; } +}; + +class AstAtanhD : public AstNodeSystemUniop { +public: + AstAtanhD(FileLine* fl, AstNode* lhsp) : AstNodeSystemUniop(fl, lhsp) {} + ASTNODE_NODE_FUNCS(AtanhD) + virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(atanh(lhs.toDouble())); } + virtual string emitVerilog() { return "%f$atanh(%l)"; } + virtual string emitC() { return "atanh(%li)"; } }; //====================================================================== @@ -5004,6 +5085,39 @@ public: AstNode* filep() const { return rhsp(); } }; +class AstNodeSystemBiop : public AstNodeBiop { +public: + AstNodeSystemBiop(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { + dtypeSetDouble(); } + virtual bool cleanOut() {return false;} + virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} + virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} + virtual int instrCount() const { return instrCountDoubleTrig(); } + virtual bool doubleFlavor() const { return true; } +}; + +class AstAtan2D : public AstNodeSystemBiop { +public: + AstAtan2D(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeSystemBiop(fl, lhsp, rhsp) {} + ASTNODE_NODE_FUNCS(Atan2D) + virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAtan2D(this->fileline(), lhsp, rhsp); } + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { + out.setDouble(atan2(lhs.toDouble(), rhs.toDouble())); } + virtual string emitVerilog() { return "%f$atan2(%l,%r)"; } + virtual string emitC() { return "atan2(%li,%ri)"; } +}; + +class AstHypotD : public AstNodeSystemBiop { +public: + AstHypotD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeSystemBiop(fl, lhsp, rhsp) {} + ASTNODE_NODE_FUNCS(HypotD) + virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstHypotD(this->fileline(), lhsp, rhsp); } + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { + out.setDouble(hypot(lhs.toDouble(), rhs.toDouble())); } + virtual string emitVerilog() { return "%f$hypot(%l,%r)"; } + virtual string emitC() { return "hypot(%li,%ri)"; } +}; + class AstPattern : public AstNodeMath { // Verilog '{a,b,c,d...} // Parents: AstNodeAssign, AstPattern, ... diff --git a/src/V3Width.cpp b/src/V3Width.cpp index ff23cfe1f..0dd48eaa6 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -299,14 +299,10 @@ private: virtual void visit(AstDivD* nodep) { visit_real_add_sub(nodep); } virtual void visit(AstMulD* nodep) { visit_real_add_sub(nodep); } virtual void visit(AstPowD* nodep) { visit_real_add_sub(nodep); } + virtual void visit(AstNodeSystemBiop* nodep) { visit_real_add_sub(nodep); } // Real: Output real virtual void visit(AstNegateD* nodep) { visit_real_neg_ceil(nodep); } - virtual void visit(AstCeilD* nodep) { visit_real_neg_ceil(nodep); } - virtual void visit(AstExpD* nodep) { visit_real_neg_ceil(nodep); } - virtual void visit(AstFloorD* nodep) { visit_real_neg_ceil(nodep); } - virtual void visit(AstLogD* nodep) { visit_real_neg_ceil(nodep); } - virtual void visit(AstLog10D* nodep) { visit_real_neg_ceil(nodep); } - virtual void visit(AstSqrtD* nodep) { visit_real_neg_ceil(nodep); } + virtual void visit(AstNodeSystemUniop* nodep) { visit_real_neg_ceil(nodep); } // Widths: out signed/unsigned width = lhs width, input un|signed virtual void visit(AstSigned* nodep) { visit_signed_unsigned(nodep, AstNumeric::SIGNED); } diff --git a/src/verilog.l b/src/verilog.l index 8b9ea5540..f4f2c5cce 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -206,8 +206,17 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} /* Extensions to Verilog set, some specified by PSL */ "$c"[0-9]* { FL; return yD_C; } /*Verilator only*/ /* System Tasks */ + "$acos" { FL; return yD_ACOS; } + "$acosh" { FL; return yD_ACOSH; } + "$asin" { FL; return yD_ASIN; } + "$asinh" { FL; return yD_ASINH; } + "$atan" { FL; return yD_ATAN; } + "$atan2" { FL; return yD_ATAN2; } + "$atanh" { FL; return yD_ATANH; } "$bitstoreal" { FL; return yD_BITSTOREAL; } "$ceil" { FL; return yD_CEIL; } + "$cos" { FL; return yD_COS; } + "$cosh" { FL; return yD_COSH; } "$display" { FL; return yD_DISPLAY; } "$exp" { FL; return yD_EXP; } "$fclose" { FL; return yD_FCLOSE; } @@ -223,6 +232,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "$fullskew" { FL; return yaTIMINGSPEC; } "$fwrite" { FL; return yD_FWRITE; } "$hold" { FL; return yaTIMINGSPEC; } + "$hypot" { FL; return yD_HYPOT; } "$itor" { FL; return yD_ITOR; } "$ln" { FL; return yD_LN; } "$log10" { FL; return yD_LOG10; } @@ -242,6 +252,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "$setuphold" { FL; return yaTIMINGSPEC; } "$sformat" { FL; return yD_SFORMAT; } "$sformatf" { FL; return yD_SFORMATF; } + "$sin" { FL; return yD_SIN; } + "$sinh" { FL; return yD_SINH; } "$skew" { FL; return yaTIMINGSPEC; } "$sqrt" { FL; return yD_SQRT; } "$sscanf" { FL; return yD_SSCANF; } @@ -249,6 +261,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "$stop" { FL; return yD_STOP; } "$swrite" { FL; return yD_SWRITE; } "$system" { FL; return yD_SYSTEM; } + "$tan" { FL; return yD_TAN; } + "$tanh" { FL; return yD_TANH; } "$test$plusargs" { FL; return yD_TESTPLUSARGS; } "$time" { FL; return yD_TIME; } "$timeskew" { FL; return yaTIMINGSPEC; } @@ -601,20 +615,20 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "aliasparam" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "analog" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "analysis" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "asin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "asinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } + "asin" { FL; return yD_ASIN; } + "asinh" { FL; return yD_ASINH; } "assert" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "atan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "atan2" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "atanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } + "atan" { FL; return yD_ATAN; } + "atan2" { FL; return yD_ATAN2; } + "atanh" { FL; return yD_ATANH; } "branch" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ceil" { FL; return yD_CEIL; } "connect" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "connectmodule" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "connectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "continuous" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "cos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "cosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } + "cos" { FL; return yD_COS; } + "cosh" { FL; return yD_COSH; } "cross" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ddt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ddt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } @@ -635,7 +649,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "flow" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "from" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ground" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "hypot" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } + "hypot" { FL; return yD_HYPOT; } "idt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "idt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "idtmod" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } @@ -659,14 +673,14 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "potential" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "pow" { FL; return yD_POW; } "resolveto" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "sin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "sinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } + "sin" { FL; return yD_SIN; } + "sinh" { FL; return yD_SINH; } "slew" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "split" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "sqrt" { FL; return yD_SQRT; } "string" { FL; return ySTRING; } - "tan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } - "tanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } + "tan" { FL; return yD_TAN; } + "tanh" { FL; return yD_TANH; } "timer" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "transition" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "units" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } diff --git a/src/verilog.y b/src/verilog.y index 31a374b14..a45928dca 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -442,11 +442,20 @@ class AstSenTree; %token yXNOR "xnor" %token yXOR "xor" +%token yD_ACOS "$acos" +%token yD_ACOSH "$acosh" +%token yD_ASIN "$asin" +%token yD_ASINH "$asinh" +%token yD_ATAN "$atan" +%token yD_ATAN2 "$atan2" +%token yD_ATANH "$atanh" %token yD_BITS "$bits" %token yD_BITSTOREAL "$bitstoreal" %token yD_C "$c" %token yD_CEIL "$ceil" %token yD_CLOG2 "$clog2" +%token yD_COS "$cos" +%token yD_COSH "$cosh" %token yD_COUNTONES "$countones" %token yD_DIMENSIONS "$dimensions" %token yD_DISPLAY "$display" @@ -465,6 +474,7 @@ class AstSenTree; %token yD_FSCANF "$fscanf" %token yD_FWRITE "$fwrite" %token yD_HIGH "$high" +%token yD_HYPOT "$hypot" %token yD_INCREMENT "$increment" %token yD_INFO "$info" %token yD_ISUNKNOWN "$isunknown" @@ -486,6 +496,8 @@ class AstSenTree; %token yD_SFORMAT "$sformat" %token yD_SFORMATF "$sformatf" %token yD_SIGNED "$signed" +%token yD_SIN "$sin" +%token yD_SINH "$sinh" %token yD_SIZE "$size" %token yD_SQRT "$sqrt" %token yD_SSCANF "$sscanf" @@ -493,6 +505,8 @@ class AstSenTree; %token yD_STOP "$stop" %token yD_SWRITE "$swrite" %token yD_SYSTEM "$system" +%token yD_TAN "$tan" +%token yD_TANH "$tanh" %token yD_TESTPLUSARGS "$test$plusargs" %token yD_TIME "$time" %token yD_UNIT "$unit" @@ -2693,12 +2707,21 @@ system_f_call: // IEEE: system_tf_call (as func) | yaD_DPI parenE { $$ = new AstFuncRef($1,*$1,NULL); } | yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList($$->castFuncRef()); } // + | yD_ACOS '(' expr ')' { $$ = new AstAcosD($1,$3); } + | yD_ACOSH '(' expr ')' { $$ = new AstAcoshD($1,$3); } + | yD_ASIN '(' expr ')' { $$ = new AstAsinD($1,$3); } + | yD_ASINH '(' expr ')' { $$ = new AstAsinhD($1,$3); } + | yD_ATAN '(' expr ')' { $$ = new AstAtanD($1,$3); } + | yD_ATAN2 '(' expr ',' expr ')' { $$ = new AstAtan2D($1,$3,$5); } + | yD_ATANH '(' expr ')' { $$ = new AstAtanhD($1,$3); } | yD_BITS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); } | yD_BITS '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); } | yD_BITSTOREAL '(' expr ')' { $$ = new AstBitsToRealD($1,$3); } | yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); } | yD_CEIL '(' expr ')' { $$ = new AstCeilD($1,$3); } | yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); } + | yD_COS '(' expr ')' { $$ = new AstCosD($1,$3); } + | yD_COSH '(' expr ')' { $$ = new AstCoshD($1,$3); } | yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); } | yD_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_DIMENSIONS,$3); } | yD_EXP '(' expr ')' { $$ = new AstExpD($1,$3); } @@ -2709,6 +2732,7 @@ system_f_call: // IEEE: system_tf_call (as func) | yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF($1,*$5,$3,$6); } | yD_HIGH '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,NULL); } | yD_HIGH '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,$5); } + | yD_HYPOT '(' expr ',' expr ')' { $$ = new AstHypotD($1,$3,$5); } | yD_INCREMENT '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,NULL); } | yD_INCREMENT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,$5); } | yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); } @@ -2731,12 +2755,16 @@ system_f_call: // IEEE: system_tf_call (as func) | yD_RTOI '(' expr ')' { $$ = new AstRToIS($1,$3); } | yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,false,$4); } | yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); } + | yD_SIN '(' expr ')' { $$ = new AstSinD($1,$3); } + | yD_SINH '(' expr ')' { $$ = new AstSinhD($1,$3); } | yD_SIZE '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,NULL); } | yD_SIZE '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,$5); } | yD_SQRT '(' expr ')' { $$ = new AstSqrtD($1,$3); } | yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); } | yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); } | yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); } + | yD_TAN '(' expr ')' { $$ = new AstTanD($1,$3); } + | yD_TANH '(' expr ')' { $$ = new AstTanhD($1,$3); } | yD_TESTPLUSARGS '(' str ')' { $$ = new AstTestPlusArgs($1,*$3); } | yD_TIME parenE { $$ = new AstTime($1); } | yD_UNPACKED_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_UNPK_DIMENSIONS,$3); } diff --git a/test_regress/t/t_math_trig.v b/test_regress/t/t_math_trig.v index 6d6040364..2fa5815d0 100644 --- a/test_regress/t/t_math_trig.v +++ b/test_regress/t/t_math_trig.v @@ -16,7 +16,7 @@ module t (/*AUTOARG*/ task check(integer line, real got, real ex); if (got != ex) begin - if ((got - ex) > 0.000001) begin + if ((got > ex ? got - ex : ex - got) > 0.000001) begin $display("%%Error: Line %0d: Bad result, got=%0.99g expect=%0.99g",line,got,ex); $stop; end @@ -45,7 +45,6 @@ module t (/*AUTOARG*/ check(`__LINE__, $sqrt(1.2), 1.095445115010332148841598609578795731067657470703125); //check(`__LINE__, $sqrt(-1.2), 0); // Bad value check(`__LINE__, ((1.5)**(1.25)), 1.660023); -`ifndef VERILATOR check(`__LINE__, $acos (0.2), 1.369438406); // Arg1 is -1..1 check(`__LINE__, $acosh(1.2), 0.622362503); check(`__LINE__, $asin (0.2), 0.201357920); // Arg1 is -1..1 @@ -60,7 +59,6 @@ module t (/*AUTOARG*/ check(`__LINE__, $sinh (1.2), 1.509461355); check(`__LINE__, $tan (1.2), 2.572151622); check(`__LINE__, $tanh (1.2), 0.833654607); -`endif end real sum_ceil; @@ -108,7 +106,6 @@ module t (/*AUTOARG*/ if (r >= 0.0) sum_pow2 += 1.0+$pow(r,2.3); if (r >= 0.0) sum_sqrt += 1.0+$sqrt(r); -`ifndef VERILATOR if (r>=-1.0 && r<=1.0) sum_acos += 1.0+$acos (r); if (r>=1.0) sum_acosh += 1.0+$acosh(r); if (r>=-1.0 && r<=1.0) sum_asin += 1.0+$asin (r); @@ -123,7 +120,6 @@ module t (/*AUTOARG*/ sum_sinh += 1.0+$sinh (r); sum_tan += 1.0+$tan (r); sum_tanh += 1.0+$tanh (r); -`endif end else if (cyc==99) begin check (`__LINE__, sum_ceil, 85); @@ -134,7 +130,6 @@ module t (/*AUTOARG*/ check (`__LINE__, sum_pow1, 410.98798177); check (`__LINE__, sum_pow2, 321.94765689); check (`__LINE__, sum_sqrt, 92.269677253); -`ifndef VERILATOR check (`__LINE__, sum_acos, 53.986722862); check (`__LINE__, sum_acosh, 72.685208498); check (`__LINE__, sum_asin, 21); @@ -146,10 +141,10 @@ module t (/*AUTOARG*/ check (`__LINE__, sum_cosh, 1054.0178222); check (`__LINE__, sum_hypot, 388.92858406); check (`__LINE__, sum_sin, 98.264184989); - check (`__LINE__, sum_sinh, 0); + check (`__LINE__, sum_sinh, -356.9512927); check (`__LINE__, sum_tan, 1.7007946043); check (`__LINE__, sum_tanh, 79.003199681); -`endif + $write("*-* All Finished *-*\n"); $finish; end