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
*** Support power operator with real, bug809. [Jonathon Donaldson]
**** Improve verilator_profcfunc time attributions. [Jonathon Donaldson]
**** 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
// 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;

View File

@ -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

View File

@ -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);