Variable bit shift

Guest
Hi,
I'm trying to code a variable shift of signed values in Verilog - and
simulate with icarus's iverilog.

I find that this works as I expect:
Give these variables,
wire signed [5:0] GAIN //amount to shift by
wire signed [23:0] iir //the signed value to be shifted
wire signed [23:0] iir_shift //the result of the shift

assign iir_shift = iir >>> 2;
iir_shift is correctly sign extended (MSBs filled with 1's if it's
negative, filled with 0's if its positive)

assign iir_shift = iir >>> GAIN;
iir_shift is not correctly sign extended - the MSBs are filled with '0'
when iir is a negative number.

Am I doing something wrong? Why this discrepancy? How to fix it?
Could it be a bug in icarus's program? Thanks for your time. Russell
 
palmerm...@gmail.com wrote:
wire signed [5:0] GAIN //amount to shift by
wire signed [23:0] iir //the signed value to be shifted

assign iir_shift = iir >>> GAIN;
iir_shift is not correctly sign extended - the MSBs are filled with '0'
when iir is a negative number.

Could it be a bug in icarus's program?
Sounds like it. It shouldn't even matter whether GAIN is signed or
not. The signedness of the shift count has no effect on the signedness
of the result, and will be treated as an unsigned count regardless
(i.e. if GAIN is -1, you don't get a shift left by 1, you get a shift
right by 6'b111111). All that matters is that iir is signed and you
are using the >>> shift operator. You should get an arithmetic right
shift.
 
<sharp@cadence.com> wrote in message
news:1152829693.561174.281740@h48g2000cwc.googlegroups.com...
Sounds like it. It shouldn't even matter whether GAIN is signed or
not. The signedness of the shift count has no effect on the signedness
of the result, and will be treated as an unsigned count regardless
(i.e. if GAIN is -1, you don't get a shift left by 1, you get a shift
right by 6'b111111). All that matters is that iir is signed and you
are using the >>> shift operator. You should get an arithmetic right
shift.

This was a clarification from Verilog-1995 that applied to the new
arithmetic shift, wasn't it? Specifically, some synthesizers may have
permitted negative shifts; the clarification was that a shift in one
direction will only shift in that direction, there is no reversal. Hence,
your comment about the unsigned shift.
 
On Thu, 13 Jul 2006 23:23:20 GMT, "John_H" <johnhandwork@mail.com>
wrote:

sharp@cadence.com> wrote in message
news:1152829693.561174.281740@h48g2000cwc.googlegroups.com...

Sounds like it. It shouldn't even matter whether GAIN is signed or
not. The signedness of the shift count has no effect on the signedness
of the result, and will be treated as an unsigned count regardless
(i.e. if GAIN is -1, you don't get a shift left by 1, you get a shift
right by 6'b111111). All that matters is that iir is signed and you
are using the >>> shift operator. You should get an arithmetic right
shift.

This was a clarification from Verilog-1995 that applied to the new
arithmetic shift, wasn't it? Specifically, some synthesizers may have
permitted negative shifts; the clarification was that a shift in one
direction will only shift in that direction, there is no reversal. Hence,
your comment about the unsigned shift.
To me a clarification happens after a standard is out in usually a
newer revision. As there was no arithmetic shift, nor signed in
1364-1995, I wouldn't call it a clarification. 1364-2001 specifically
says "The right operand is always treated as an unsigned number and
has no effect on the signedness of the result." so this is how it was
specified to begin with. On the other hand it this sentence weren't in
1364-2001 and were added to 1364-2005(7?) then it would be a
clarification.JMHO.
 
mk wrote:
On Thu, 13 Jul 2006 23:23:20 GMT, "John_H" <johnhandwork@mail.com
wrote:

sharp@cadence.com> wrote in message
news:1152829693.561174.281740@h48g2000cwc.googlegroups.com...
Sounds like it. It shouldn't even matter whether GAIN is signed or
not. The signedness of the shift count has no effect on the signedness
of the result, and will be treated as an unsigned count regardless
(i.e. if GAIN is -1, you don't get a shift left by 1, you get a shift
right by 6'b111111). All that matters is that iir is signed and you
are using the >>> shift operator. You should get an arithmetic right
shift.

This was a clarification from Verilog-1995 that applied to the new
arithmetic shift, wasn't it? Specifically, some synthesizers may have
permitted negative shifts; the clarification was that a shift in one
direction will only shift in that direction, there is no reversal. Hence,
your comment about the unsigned shift.


To me a clarification happens after a standard is out in usually a
newer revision. As there was no arithmetic shift, nor signed in
1364-1995, I wouldn't call it a clarification. 1364-2001 specifically
says "The right operand is always treated as an unsigned number and
has no effect on the signedness of the result." so this is how it was
specified to begin with. On the other hand it this sentence weren't in
1364-2001 and were added to 1364-2005(7?) then it would be a
clarification.JMHO.
I realized after I wrote that my diction didn't clearly indicate that
this was a "clarification to shift operators in general, in this case
applying to the aritmetic shift operator as well." I believe some
synthesizers treated the simple shift (not arithmetic shift) with a
reversal in direction if the value was negative; that's what needed
clarification.
 
John_H wrote:
I realized after I wrote that my diction didn't clearly indicate that
this was a "clarification to shift operators in general, in this case
applying to the aritmetic shift operator as well." I believe some
synthesizers treated the simple shift (not arithmetic shift) with a
reversal in direction if the value was negative; that's what needed
clarification.
Oh, and I realize there were no signed values in Verilog-1995 but there
were results that were "obviously negative" on some designers' minds
such as in the shift of 8'h80 >> 5-go[2:0];
 
John_H wrote:
This was a clarification from Verilog-1995 that applied to the new
arithmetic shift, wasn't it?
No. IEEE Std 1364-1995 clause 4.1.12 titled "Shift operators" says

"The right operand is always treated as an unsigned number."

So this rule was already present for the old shift operator in
Verilog-1995. This sentence was not in the Verilog-XL manual, though,
unlike the rest of the section. I do believe that Verilog-XL would
treat negative shifts as shifts in the opposite direction, though this
may have depended on the optimization level being used. So it is
unclear whether adding this sentence to the standard was a deliberate
deviation from Verilog-XL, or an attempt to clarify the behavior in a
mistaken belief that XL behaved this way. But at this point it is
generally being treated as a deliberate decision in the standard, and
therefore correct.
 
Thanks for your comments.

So in summary, # of shifts is always treated as unsigned integer -
makes sense since if I wanted to shift left it is clearer to use <<<
(positve #) rather than >>> (negative #).

Icarus iverilog simulates the code incorrectly. The code simulates
correctly in Verilog-XL.

Thanks again.


sharp@cadence.com wrote:
John_H wrote:
This was a clarification from Verilog-1995 that applied to the new
arithmetic shift, wasn't it?

No. IEEE Std 1364-1995 clause 4.1.12 titled "Shift operators" says

"The right operand is always treated as an unsigned number."

So this rule was already present for the old shift operator in
Verilog-1995. This sentence was not in the Verilog-XL manual, though,
unlike the rest of the section. I do believe that Verilog-XL would
treat negative shifts as shifts in the opposite direction, though this
may have depended on the optimization level being used. So it is
unclear whether adding this sentence to the standard was a deliberate
deviation from Verilog-XL, or an attempt to clarify the behavior in a
mistaken belief that XL behaved this way. But at this point it is
generally being treated as a deliberate decision in the standard, and
therefore correct.
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

sharp@cadence.com wrote:
palmerm...@gmail.com wrote:
wire signed [5:0] GAIN //amount to shift by
wire signed [23:0] iir //the signed value to be shifted

assign iir_shift = iir >>> GAIN;
iir_shift is not correctly sign extended - the MSBs are filled with '0'
when iir is a negative number.

Could it be a bug in icarus's program?

Sounds like it. It shouldn't even matter whether GAIN is signed or
not. The signedness of the shift count has no effect on the signedness
of the result, and will be treated as an unsigned count regardless
(i.e. if GAIN is -1, you don't get a shift left by 1, you get a shift
right by 6'b111111). All that matters is that iir is signed and you
are using the >>> shift operator. You should get an arithmetic right
shift.
I agree, this is a bug in Icarus Verilog, both the 0.8 release
and the devel trunk. I'd be a great help if this can be filed
in the Bugs database so that I can remember to fix it.

- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEu/09rPt1Sc2b3ikRAuG0AKCpPrAaV4OYqatS5nn3osdJAbdhIACfaCF/
A7njQTxGtXrUMjxlaysU++0=
=vvk7
-----END PGP SIGNATURE-----
 

Welcome to EDABoard.com

Sponsor

Back
Top