logical shift of signed values
|Assignee:||Wilson Snyder||% Done:|
reg [5:0] bob; reg signed [32:0] jim; jim = (1'sb1 << bob);when bob = 4 I would expect jim to equal 16, with Verilator 3.812 jim = -15.
Caveat - this code was not written with Verilator in mind, so I was using /* verilator lint_off WIDTH */ to get it to compile, as soon as you extend the lhs of the shift to 33 bits as requested by the warning, then obviously the problem goes away. So I can understand fixing it might be unimportant, however it was causing code that worked in another simulator to fail.
#1 Updated by Wilson Snyder over 2 years ago
- Status changed from New to AskedReporter
The following code shows identical results on Verilator and several other simulators. If you can show how to give different results I will fix it.
reg [5:0] b349a; reg signed [32:0] b349b; initial begin b349a = 6'd4; // verilator lint_off WIDTH b349b = (1'sb1 << b349a); // verilator lint_on WIDTH $display ("1'sb1<<%x %x", b349a, b349b ); end
1'sb1 << 04 1fffffff0
#2 Updated by Thomas Watts over 2 years ago
Sorry, I oversimplified my testcase. Take a look at this.
/* verilator lint_off WIDTH */ module test; reg signed [32:0] jim; initial begin jim = 4'sb1111 - 1'b1; $display("%x", jim); end endmodule
output from verilator 1fffffffe
output from another simulator 00000000e
So signed - unsigned is being treated as signed by verilator and unsigned by another tool. Hopefully you'll get the same results this time.
#3 Updated by Wilson Snyder over 2 years ago
- Status changed from AskedReporter to Assigned
- Assignee set to Wilson Snyder
- Priority changed from Normal to Low
The 000e result does not correspond to the width extension rules as I understand them, but that other simulators seems to agree means that my understanding is incorrect in some way. I'll need to do some research to figure out what the right rules are.