I have a basic module as follows to demonstrate something.
module tb();
reg [2:0] U;
reg [2:0] T;
reg [2:0] C;
reg E;
initial begin
U = 5;
T = 3;
{E, C} = U + ~T + 1'b1;
#1000;
end
endmodule
What I expect is E to be 1, because;
U
is 101
T
is 011
and U + ~T + 001
is,
101
100
001
+______
= 1010
So, C gets 010 part and E gets 1. This is the expected behaviour, however, I get C as same but E as 0. I think verilog is increasing sizes of RHS variables to 4 bits because the left hand side is 4 bits(1+3). However, for T, it appends leading 0 before complementing T, so T becomes 0011 and its complement happens to be 1100, instead of 0100, 4 bit version of T complement.
And this leads to,
0101
1100
0001
+______
= 10010
Which causes E to be 0 as seen.
I don't understand why this is so, and could not find a way to make complementing happen before adding a leading zero.
If I do the following instead, it works fine and E gets 1:
U = 5;
T = 3;
T = ~T;
{E, C} = U + T + 1'b1;
This confirms that my suspicion is right. So, I do have such a solution, yes. However, I am not really satisfied with it, I think there should be a way to prevent that behaviour.
Any help would be appreciated.
When you have operands of mixture of different widths, Verilog has rules for sizing each operand to the width of the largest operand based on the context of the expression. You correctly noted that the LHS is 4 bits, the operands on the RHS get extended to 4 bits. This happens before applying operation.
You can fix this by taking advantage of the fact that operands of a concatenation are self-determined contexts:
{E, C} = U + {~T} + 1'b1;
Now the width of ~T
is solely determined by the width of T
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.