Support power operator with real, bug809.

This commit is contained in:
Wilson Snyder 2014-09-21 08:20:38 -04:00
parent 27af9b6b06
commit 6e476255ca
4 changed files with 16 additions and 3 deletions

View File

@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.863 devel * Verilator 3.863 devel
*** Support power operator with real, bug809. [Jonathon Donaldson]
**** Improve verilator_profcfunc time attributions. [Jonathon Donaldson] **** Improve verilator_profcfunc time attributions. [Jonathon Donaldson]
**** Fix duplicate anonymous structures in $root, bug788. [Bob Newgard] **** Fix duplicate anonymous structures in $root, bug788. [Bob Newgard]

View File

@ -690,15 +690,21 @@ private:
// Pow is special, output sign only depends on LHS sign, but function result depends on both signs // Pow is special, output sign only depends on LHS sign, but function result depends on both signs
// RHS is self-determined (IEEE) // RHS is self-determined (IEEE)
// Real if either side is real (as with AstAdd) // Real if either side is real (as with AstAdd)
iterate_shift_prelim(nodep, vup); // Iterate rhsp() as self-determined
if (vup->c()->prelim()) { 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()) { if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) {
spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->lhsp());
spliceCvtD(nodep->rhsp()); spliceCvtD(nodep->rhsp());
replaceWithDVersion(nodep); nodep=NULL; replaceWithDVersion(nodep); nodep=NULL;
return;
} }
checkCvtUS(nodep->lhsp());
iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
nodep->dtypeFrom(nodep->lhsp());
} }
if (vup->c()->final()) { if (vup->c()->final()) {
AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep());
nodep->dtypeFrom(expDTypep); nodep->dtypeFrom(expDTypep);
@ -2297,7 +2303,7 @@ private:
if (newp) {} // Ununused if (newp) {} // Ununused
} }
void iterate_shift_prelim(AstNodeBiop* nodep, AstNUser* vup) { void iterate_shift_prelim(AstNodeBiop* nodep, AstNUser* vup) {
// Shifts, Pow // Shifts
// See IEEE-2012 11.4.10 and Table 11-21. // 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. // RHS is self-determined. RHS is always treated as unsigned, has no effect on result.
if (vup->c()->prelim()) { if (vup->c()->prelim()) {
@ -2885,6 +2891,7 @@ private:
switch (nodep->type()) { switch (nodep->type()) {
case AstType::atADD: newp = new AstAddD (fl,lhsp,rhsp); break; case AstType::atADD: newp = new AstAddD (fl,lhsp,rhsp); break;
case AstType::atSUB: newp = new AstSubD (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::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::atNEQ: case AstType::atNEQCASE: newp = new AstNeqD (fl,lhsp,rhsp); break;
case AstType::atGT: case AstType::atGTS: newp = new AstGtD (fl,lhsp,rhsp); break; case AstType::atGT: case AstType::atGTS: newp = new AstGtD (fl,lhsp,rhsp); break;

View File

@ -5,6 +5,8 @@
// Lesser General Public License Version 3 or the Perl Artistic License // Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0. // Version 2.0.
`define is_near_real(a,b) ($abs((a)-(b)) < (((a)/(b))*0.0001))
module t (/*AUTOARG*/ module t (/*AUTOARG*/
// Inputs // Inputs
clk clk

View File

@ -25,6 +25,7 @@ module t (/*AUTOARG*/
initial begin initial begin
// Check constant propagation // Check constant propagation
// Note $abs is not defined in SystemVerilog (as of 2012)
check(`__LINE__, $ceil(-1.2), -1); check(`__LINE__, $ceil(-1.2), -1);
check(`__LINE__, $ceil(1.2), 2); check(`__LINE__, $ceil(1.2), 2);
check(`__LINE__, $exp(1.2), 3.3201169227365472380597566370852291584014892578125); 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__, $pow(-2.3,1.2),0); // Bad value
check(`__LINE__, $sqrt(1.2), 1.095445115010332148841598609578795731067657470703125); check(`__LINE__, $sqrt(1.2), 1.095445115010332148841598609578795731067657470703125);
//check(`__LINE__, $sqrt(-1.2), 0); // Bad value //check(`__LINE__, $sqrt(-1.2), 0); // Bad value
check(`__LINE__, ((1.5)**(1.25)), 1.660023);
`ifndef VERILATOR `ifndef VERILATOR
check(`__LINE__, $acos (0.2), 1.369438406); // Arg1 is -1..1 check(`__LINE__, $acos (0.2), 1.369438406); // Arg1 is -1..1
check(`__LINE__, $acosh(1.2), 0.622362503); check(`__LINE__, $acosh(1.2), 0.622362503);