1. 明确规定结果位宽
在明确规定表达式的取值时,表达式的位宽已定,其值也容易确定。如dst的取值就只能是真实值的低3位,尽管其正确结果为4'b1110.
bit [2:0]dst, src1, src2;
bit [3:0]dst_0;
initial begin
src1 = 3'b111;
src2 = 3'b111;
dst = src1 + src2; // dst = 3'b110
dst_0 = src1 + src2; // dst = 4'b1110
end
2.不规定结果位宽
但是有时为了表达的简洁,而隐去了表达式取值信号的定义,此时表达式的取值取决于表达式中最大操作数的位宽。
2.1 默认为1
如果不声明就使用一个变量,那么在verilog或者sv中他应该是一个默认的1bit的net变量,但是在块语句中必须先声明,后使用。所以下面的写法是不行的,会报错。
bit [2:0]src1, src2
initial begin
src1 = 3'b111;
src2 = 3'b111;
dst = src1 + src2; // dst = 1'b0
end
2.2 默认和操作数的最大位宽相同
bit [2:0]src1, src2;
bit [3:0]src3;
initial begin
src1 = 3'b111;
src2 = 3'b111;
src3 = 4'b0111;
$display("src1 + src2 = %b", src1+src2); // 3'b110
$display("src1 + src3 = %b", src1+src3); // 4'b1110
$display("src1 + src2 = %b", {1'b0, src1} + {1'b0, src2}); // 4'b1110
if(src1+src2 > 3'b111)
$display("aaa");
if(src1+src2 > 4'b0111)
$display("bbb"); // will display bbb
$display("(src1+src2)>>2 = %b", (src1+src2)>>2); // 001 not 011
end
所以如果在代码中出现使用表达式去display,去移位,去判断一定要小心,由于结果不会自动扩展位宽,如果发生溢出了,得到的值很可能和你想要的值不同,从而导致错误。