R
Russell Fredrickson
Guest
Hi all,
I'm seeing some mismatching results for a Verilog 2001 arithmetic shift
operator in NCVerilog and since I don't have a Verilog 2001 LRM handy, I
thought I'd ask to experts to see if they knew what the LRM specified in
this regards. I originally found this when we had an RTL/gates simulation
mismatch, but have extracted the problem to the following Verilog code:
module ArithmeticShiftTest;
reg signed [31:0] in;
reg [5:0] shift;
reg signed [31:0] out;
//calculate arithmetic barrel shift right
always@(*) out = in >>> shift;
initial begin
//set up inputs for always block
in = 32'sh80000000;//set to highest value negative number(-2147483648)
shift = 6'd32; //shift the entire width of the word
#1; //allow time for inputs to propagate
//check output
if(out === (32'sh80000000 >>> 6'd32)) begin
$display("PASS: 32'sh80000000 >>> 6'd32 = 0x%h", in, shift, out);
end
else begin
$display("FAIL: 32'sh80000000 >>> 6'd32 != 0x%h,",
(32'sh80000000 >>> 6'd32), " actual = 0x%h.", out);
end
end // initial begin
endmodule // ArithmeticShiftTest
When I simulate with ncverilog (version 5.3-s005) I get the following
message:
FAIL: 32'sh80000000 >>> 6'd32 != 0xffffffff, actual = 0x00000000.
So in other words, the output of the always block is 0x00000000 when I would
expect it to be 0xffffffff (which is what the manual testbench calculation
and the synthesis come out to). Is this a bug in NCVerilog? What does the
Verilog 2001 LRM specify in this regards when the arithmetic shift is
greater or equal to the width of the operand? When one envisions how one
would implement an arithmetic shift in hardware (by left-filling with the
sign bit), I would expect the answer to be 0xffffffff.
Thanks in advance,
Russell
I'm seeing some mismatching results for a Verilog 2001 arithmetic shift
operator in NCVerilog and since I don't have a Verilog 2001 LRM handy, I
thought I'd ask to experts to see if they knew what the LRM specified in
this regards. I originally found this when we had an RTL/gates simulation
mismatch, but have extracted the problem to the following Verilog code:
module ArithmeticShiftTest;
reg signed [31:0] in;
reg [5:0] shift;
reg signed [31:0] out;
//calculate arithmetic barrel shift right
always@(*) out = in >>> shift;
initial begin
//set up inputs for always block
in = 32'sh80000000;//set to highest value negative number(-2147483648)
shift = 6'd32; //shift the entire width of the word
#1; //allow time for inputs to propagate
//check output
if(out === (32'sh80000000 >>> 6'd32)) begin
$display("PASS: 32'sh80000000 >>> 6'd32 = 0x%h", in, shift, out);
end
else begin
$display("FAIL: 32'sh80000000 >>> 6'd32 != 0x%h,",
(32'sh80000000 >>> 6'd32), " actual = 0x%h.", out);
end
end // initial begin
endmodule // ArithmeticShiftTest
When I simulate with ncverilog (version 5.3-s005) I get the following
message:
FAIL: 32'sh80000000 >>> 6'd32 != 0xffffffff, actual = 0x00000000.
So in other words, the output of the always block is 0x00000000 when I would
expect it to be 0xffffffff (which is what the manual testbench calculation
and the synthesis come out to). Is this a bug in NCVerilog? What does the
Verilog 2001 LRM specify in this regards when the arithmetic shift is
greater or equal to the width of the operand? When one envisions how one
would implement an arithmetic shift in hardware (by left-filling with the
sign bit), I would expect the answer to be 0xffffffff.
Thanks in advance,
Russell