diff --git a/Changes b/Changes index 38d6f7306..665a8f9b1 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.863 devel +*** Support power operator with real, bug809. [Jonathon Donaldson] + **** Improve verilator_profcfunc time attributions. [Jonathon Donaldson] **** Fix duplicate anonymous structures in $root, bug788. [Bob Newgard] diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 0d51ec65c..62bdb3e40 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -690,15 +690,21 @@ private: // Pow is special, output sign only depends on LHS sign, but function result depends on both signs // RHS is self-determined (IEEE) // Real if either side is real (as with AstAdd) - iterate_shift_prelim(nodep, vup); // Iterate rhsp() as self-determined - if (vup->c()->prelim()) { + nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->rhsp()); replaceWithDVersion(nodep); nodep=NULL; + return; } + + checkCvtUS(nodep->lhsp()); + iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); + nodep->dtypeFrom(nodep->lhsp()); } + if (vup->c()->final()) { AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); nodep->dtypeFrom(expDTypep); @@ -2297,7 +2303,7 @@ private: if (newp) {} // Ununused } void iterate_shift_prelim(AstNodeBiop* nodep, AstNUser* vup) { - // Shifts, Pow + // Shifts // See IEEE-2012 11.4.10 and Table 11-21. // RHS is self-determined. RHS is always treated as unsigned, has no effect on result. if (vup->c()->prelim()) { @@ -2885,6 +2891,7 @@ private: switch (nodep->type()) { case AstType::atADD: newp = new AstAddD (fl,lhsp,rhsp); break; case AstType::atSUB: newp = new AstSubD (fl,lhsp,rhsp); break; + case AstType::atPOW: newp = new AstPowD (fl,lhsp,rhsp); break; case AstType::atEQ: case AstType::atEQCASE: newp = new AstEqD (fl,lhsp,rhsp); break; case AstType::atNEQ: case AstType::atNEQCASE: newp = new AstNeqD (fl,lhsp,rhsp); break; case AstType::atGT: case AstType::atGTS: newp = new AstGtD (fl,lhsp,rhsp); break; diff --git a/test_regress/t/t_math_real.v b/test_regress/t/t_math_real.v index 9fc2c7749..dcb19a0ef 100644 --- a/test_regress/t/t_math_real.v +++ b/test_regress/t/t_math_real.v @@ -5,6 +5,8 @@ // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. +`define is_near_real(a,b) ($abs((a)-(b)) < (((a)/(b))*0.0001)) + module t (/*AUTOARG*/ // Inputs clk diff --git a/test_regress/t/t_math_trig.v b/test_regress/t/t_math_trig.v index 3b2c549a6..6d6040364 100644 --- a/test_regress/t/t_math_trig.v +++ b/test_regress/t/t_math_trig.v @@ -25,6 +25,7 @@ module t (/*AUTOARG*/ initial begin // Check constant propagation + // Note $abs is not defined in SystemVerilog (as of 2012) check(`__LINE__, $ceil(-1.2), -1); check(`__LINE__, $ceil(1.2), 2); check(`__LINE__, $exp(1.2), 3.3201169227365472380597566370852291584014892578125); @@ -43,6 +44,7 @@ module t (/*AUTOARG*/ //check(`__LINE__, $pow(-2.3,1.2),0); // Bad value 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);