Fix shifts by more than 32-bit numbers, bug1174.
This commit is contained in:
parent
a01c96140b
commit
9b06178f35
2
Changes
2
Changes
|
|
@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
* Verilator 3.905 devel
|
* Verilator 3.905 devel
|
||||||
|
|
||||||
|
*** Fix shifts by more than 32-bit numbers, bug1174. [Clifford Wolf]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 3.904 2017-05-30
|
* Verilator 3.904 2017-05-30
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1585,6 +1585,22 @@ static inline WDataOutP VL_SHIFTL_WWI(int obits,int,int,WDataOutP owp,WDataInP l
|
||||||
}
|
}
|
||||||
return(owp);
|
return(owp);
|
||||||
}
|
}
|
||||||
|
static inline WDataOutP VL_SHIFTL_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) {
|
||||||
|
for (int i=1; i < VL_WORDS_I(rbits); i++) {
|
||||||
|
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||||
|
return VL_ZERO_RESET_W(obits, owp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VL_SHIFTL_WWI(obits,lbits,32,owp,lwp,rwp[0]);
|
||||||
|
}
|
||||||
|
static inline IData VL_SHIFTL_IIW(int obits,int,int rbits,IData lhs, WDataInP rwp) {
|
||||||
|
for (int i=1; i < VL_WORDS_I(rbits); i++) {
|
||||||
|
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VL_CLEAN_II(obits,obits,lhs<<rwp[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// EMIT_RULE: VL_SHIFTR: oclean=lclean; rclean==clean;
|
// EMIT_RULE: VL_SHIFTR: oclean=lclean; rclean==clean;
|
||||||
// Important: Unlike most other funcs, the shift might well be a computed
|
// Important: Unlike most other funcs, the shift might well be a computed
|
||||||
|
|
@ -1614,6 +1630,22 @@ static inline WDataOutP VL_SHIFTR_WWI(int obits,int,int,WDataOutP owp,WDataInP l
|
||||||
}
|
}
|
||||||
return(owp);
|
return(owp);
|
||||||
}
|
}
|
||||||
|
static inline WDataOutP VL_SHIFTR_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) {
|
||||||
|
for (int i=1; i < VL_WORDS_I(rbits); i++) {
|
||||||
|
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||||
|
return VL_ZERO_RESET_W(obits, owp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VL_SHIFTR_WWI(obits,lbits,32,owp,lwp,rwp[0]);
|
||||||
|
}
|
||||||
|
static inline IData VL_SHIFTR_IIW(int obits,int,int rbits,IData lhs, WDataInP rwp) {
|
||||||
|
for (int i=1; i < VL_WORDS_I(rbits); i++) {
|
||||||
|
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VL_CLEAN_II(obits,obits,lhs>>rwp[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// EMIT_RULE: VL_SHIFTRS: oclean=false; lclean=clean, rclean==clean;
|
// EMIT_RULE: VL_SHIFTRS: oclean=false; lclean=clean, rclean==clean;
|
||||||
static inline IData VL_SHIFTRS_III(int obits, int lbits, int, IData lhs, IData rhs) {
|
static inline IData VL_SHIFTRS_III(int obits, int lbits, int, IData lhs, IData rhs) {
|
||||||
|
|
@ -1665,6 +1697,44 @@ static inline WDataOutP VL_SHIFTRS_WWI(int obits,int lbits,int,WDataOutP owp,WDa
|
||||||
}
|
}
|
||||||
return(owp);
|
return(owp);
|
||||||
}
|
}
|
||||||
|
static inline WDataOutP VL_SHIFTRS_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) {
|
||||||
|
for (int i=1; i < VL_WORDS_I(rbits); i++) {
|
||||||
|
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||||
|
int lmsw = VL_WORDS_I(obits)-1;
|
||||||
|
IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]);
|
||||||
|
for (int i=0; i <= lmsw; i++) owp[i] = sign;
|
||||||
|
owp[lmsw] &= VL_MASK_I(lbits);
|
||||||
|
return owp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VL_SHIFTRS_WWI(obits,lbits,32,owp,lwp,rwp[0]);
|
||||||
|
}
|
||||||
|
static inline IData VL_SHIFTRS_IIW(int obits,int lbits,int rbits,IData lhs, WDataInP rwp) {
|
||||||
|
for (int i=1; i < VL_WORDS_I(rbits); i++) {
|
||||||
|
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||||
|
IData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative
|
||||||
|
return VL_CLEAN_II(obits,obits,sign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VL_SHIFTRS_III(obits,lbits,32,lhs,rwp[0]);
|
||||||
|
}
|
||||||
|
static inline QData VL_SHIFTRS_QQW(int obits,int lbits,int rbits,QData lhs, WDataInP rwp) {
|
||||||
|
for (int i=1; i < VL_WORDS_I(rbits); i++) {
|
||||||
|
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||||
|
QData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative
|
||||||
|
return VL_CLEAN_QQ(obits,obits,sign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VL_SHIFTRS_QQI(obits,lbits,32,lhs,rwp[0]);
|
||||||
|
}
|
||||||
|
static inline IData VL_SHIFTRS_IIQ(int obits,int lbits,int rbits,IData lhs, QData rhs) {
|
||||||
|
WData rwp[2]; VL_SET_WQ(rwp,rhs);
|
||||||
|
return VL_SHIFTRS_IIW(obits,lbits,rbits,lhs,rwp);
|
||||||
|
}
|
||||||
|
static inline QData VL_SHIFTRS_QQQ(int obits,int lbits,int rbits,QData lhs, QData rhs) {
|
||||||
|
WData rwp[2]; VL_SET_WQ(rwp,rhs);
|
||||||
|
return VL_SHIFTRS_QQW(obits,lbits,rbits,lhs,rwp);
|
||||||
|
}
|
||||||
|
|
||||||
//===================================================================
|
//===================================================================
|
||||||
// Bit selection
|
// Bit selection
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,15 @@
|
||||||
|
|
||||||
module t (/*AUTOARG*/
|
module t (/*AUTOARG*/
|
||||||
// Outputs
|
// Outputs
|
||||||
ign,
|
ign, ign2, ign3,
|
||||||
// Inputs
|
// Inputs
|
||||||
clk
|
clk
|
||||||
);
|
);
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
output [31:0] ign;
|
output [31:0] ign;
|
||||||
|
output [3:0] ign2;
|
||||||
|
output [11:0] ign3;
|
||||||
|
|
||||||
parameter [95:0] P6 = 6;
|
parameter [95:0] P6 = 6;
|
||||||
localparam P64 = (1 << P6);
|
localparam P64 = (1 << P6);
|
||||||
|
|
@ -23,6 +25,14 @@ module t (/*AUTOARG*/
|
||||||
reg [31:0] amt;
|
reg [31:0] amt;
|
||||||
|
|
||||||
assign ign = {31'h0, clk} >>> 4'bx; // bug760
|
assign ign = {31'h0, clk} >>> 4'bx; // bug760
|
||||||
|
assign ign2 = {amt[1:0] >> {22{amt[5:2]}}, amt[1:0] << (0 <<< amt[5:2])}; // bug1174
|
||||||
|
assign ign3 = {amt[1:0] >> {22{amt[5:2]}},
|
||||||
|
amt[1:0] >> {11{amt[5:2]}},
|
||||||
|
$signed(amt[1:0]) >>> {22{amt[5:2]}},
|
||||||
|
$signed(amt[1:0]) >>> {11{amt[5:2]}},
|
||||||
|
amt[1:0] << {22{amt[5:2]}},
|
||||||
|
amt[1:0] << {11{amt[5:2]}}};
|
||||||
|
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
right = 32'h819b018a >> amt;
|
right = 32'h819b018a >> amt;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue