Fix undefined VL_POW_WWI.

This commit is contained in:
Wilson Snyder 2017-07-12 20:08:32 -04:00
parent 88cf5e5d98
commit ca26596695
5 changed files with 111 additions and 0 deletions

View File

@ -10,6 +10,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
**** Fix compile error on unused VL_VALUEPLUSARGS_IW, bug1181. [Thomas J Whatson]
**** Fix undefined VL_POW_WWI. [Clifford Wolf]
* Verilator 3.906 2017-06-22

View File

@ -283,6 +283,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
}
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp) {
// obits==lbits, rbits can be different
owp[0] = 1;
for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = 0;
// cppcheck-suppress variableScope
@ -303,8 +304,24 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDa
}
return owp;
}
WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs) {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
return VL_POW_WWW(obits,lbits,rbits,owp,lwp,rhsw);
}
QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp) {
// Skip check for rhs == 0, as short-circuit doesn't save time
if (VL_UNLIKELY(lhs==0)) return 0;
QData power = lhs;
QData out = VL_ULL(1);
for (int bit=0; bit<rbits; ++bit) {
if (bit>0) power = power*power;
if (VL_BITISSET_W(rwp,bit)) out *= power;
}
return out;
}
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign) {
// obits==lbits, rbits can be different
if (rsign && VL_SIGN_W(rbits, rwp)) {
int words = VL_WORDS_I(obits);
VL_ZERO_W(obits, owp);
@ -323,6 +340,23 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, W
}
return VL_POW_WWW(obits, rbits, rbits, owp, lwp, rwp);
}
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign) {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
return VL_POWSS_WWW(obits,lbits,rbits,owp,lwp,rhsw,lsign,rsign);
}
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign) {
// Skip check for rhs == 0, as short-circuit doesn't save time
if (rsign && VL_SIGN_W(rbits, rwp)) {
if (lhs==0) return 0; // "X"
else if (lhs==1) return 1;
else if (lsign && lhs==VL_MASK_I(obits)) { // -1
if (rwp[0] & 1) return VL_MASK_I(obits); // -1^odd=-1
else return 1; // -1^even=1
}
return 0;
}
return VL_POW_QQW(obits, rbits, rbits, lhs, rwp);
}
//===========================================================================
// Formatting

View File

@ -1191,7 +1191,10 @@ static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp,WDataInP lwp,WDa
}
}
#define VL_POW_IIQ(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
#define VL_POW_IIW(obits,lbits,rbits,lhs,rwp) VL_POW_QQW(obits,lbits,rbits,lhs,rwp)
#define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
#define VL_POW_WWI(obits,lbits,rbits,owp,lwp,rhs) VL_POW_WWQ(obits,lbits,rbits,owp,lwp,rhs)
static inline IData VL_POW_III(int, int, int rbits, IData lhs, IData rhs) {
if (VL_UNLIKELY(rhs==0)) return 1;
@ -1216,8 +1219,14 @@ static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
return out;
}
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp);
WDataOutP VL_POW_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, QData rhs);
QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp);
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_IIW(obits,lbits,rbits,lhs,rwp,lsign,rsign) VL_POWSS_QQW(obits,lbits,rbits,lhs,rwp,lsign,rsign)
#define VL_POWSS_QQI(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_WWI(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign) VL_POWSS_WWQ(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign)
static inline IData VL_POWSS_III(int obits, int, int rbits, IData lhs, IData rhs, bool lsign, bool rsign) {
if (VL_UNLIKELY(rhs==0)) return 1;
@ -1246,6 +1255,8 @@ static inline QData VL_POWSS_QQQ(int obits, int, int rbits, QData lhs, QData rhs
return VL_POW_QQQ(obits, rbits, rbits, lhs, rhs);
}
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign);
WDataOutP VL_POWSS_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign);
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign);
//===================================================================
// Concat/replication

18
test_regress/t/t_math_pow6.pl Executable file
View File

@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;

View File

@ -0,0 +1,46 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
i65, j65, i33, j33, i30, j30, q65, r65, q33, r33, q30, r30, w65, x65, w33,
x33, w30, x30,
// Inputs
a, a40, a70
);
input [3:0] a;
input [39:0] a40;
input [69:0] a70;
// -- Verilator 621c515 creates code that uses the undeclared function VL_POW_WWI()
// verilator lint_off WIDTH
output [3:0] i65 = 65'd3 ** a; // WWI
output [3:0] j65 = a ** 65'd3; // IIW
output [3:0] i33 = 33'd3 ** a; // QQI
output [3:0] j33 = a ** 33'd3; // IIQ
output [3:0] i30 = 30'd3 ** a; // III
output [3:0] j30 = a ** 30'd3; // III
output [39:0] q65 = 65'd3 ** a40; // WWQ
output [39:0] r65 = a40 ** 65'd3; // WWQ
output [39:0] q33 = 33'd3 ** a40; // QQQ
output [39:0] r33 = a40 ** 33'd3; // QQQ
output [39:0] q30 = 30'd3 ** a40; // QQI
output [39:0] r30 = a40 ** 30'd3; // QQI
output [69:0] w65 = 65'd3 ** a70; // WWW
output [69:0] x65 = a70 ** 65'd3; // WWW
output [69:0] w33 = 33'd3 ** a70; // WWW
output [69:0] x33 = a70 ** 33'd3; // WWW
output [69:0] w30 = 30'd3 ** a70; // WWW
output [69:0] x30 = a70 ** 30'd3; // WWW
// verilator lint_on WIDTH
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule