Why isn't my addition in Verilog overflowing?

I'm testing a basic ALU in Vivado using a testbench.

One of my tests checks that overflow works correctly. The test has the following form:

0000 0001 + ffff ffff = 0000 0001


But, I'm getting 0000 0000 instead. My arithmetic module is defined as follows:

module arithmetic(
input [3:0] aluOp,
input [31:0] a,
input [31:0] b,
output reg [31:0] result
);

reg [31:0] temp;

always @(*) begin
case (aluOp)
4'b0000: result = a + b;
4'b0010: result = a - b;
4'b1010: begin
temp = a-b;
result = {temp[31], 31'b0};
end
endcase
end
endmodule


It works for the other test cases but not for this one. Does anyone know why Verilog isn't overflowing as expected?

• Why do you expect 0000 0001 + ffff ffff to overflow to 0000 0001 and not 0000 0000? 0000 0001 doesn't make sense. Commented Sep 4, 2023 at 10:28
• Because your expectations are wrong. 0000 0000 is the correct answer, with an overflow to bit 32. Commented Sep 4, 2023 at 10:33
• @SpehroPefhany So Verilog doesn't automatically handle overflow then? Commented Sep 4, 2023 at 13:59
• It handles the overflow by ignoring it since you have not defined a wide enough word to hold it (MSB+1). Putting it into the LSB would just be wrong. Commented Sep 4, 2023 at 16:36
• My apologies. I meant wraparound, here's a better question: electronics.stackexchange.com/questions/680283/… Commented Sep 5, 2023 at 14:56

The problem is in the arithmetic module, not the testbench. When you add 2 32-bit numbers, the full result requires 33 bits. Generally, when you add 2 N-bit numbers, the result requires (N+1) bits.

However, you declared result as a 32-bit Verilog signal. When you add 1 and ffff ffff, the 32 LSBs are 0, and the 33rd bit (the MSB) is 1.

In your Verilog code, there are ways to handle this. You could declare result as a 33-bit signal:

output reg [32:0] result


If you are instead looking for an overflow bit, you could also do something like:

output reg [31:0] result

...

reg overflow;

always @(*) begin
case (aluOp)
4'b0000: {overflow, result} = a + b;