相比C/C++等语言,verilog在处理带符号运算时没有那么灵活。首先需要用语法申明是带符号数,其次要扩展符号位、对加法运算扩展后的参加运算的带符号数位宽要一样。
比如下面代码:
wire [7:0] a;
wire signed [15:0] b;
parameter WEIGHT = 8 ;
wire signed [8+15:0] pa;
wire signed [16+ 7:0] pb;
wire signed [23:0] pc; //相加后位宽仍为24bit
wire signed [23:0] pd; //相乘后位宽仍为24bit
符号位扩展:
assign pb = b[15] ? {{8{1'b1}},b} : {{8{1'b0}},b} ; //扩展8bit符号位
assign pa = {16'b0,a}; //无符号数直接扩展8bit的0
相加:
assign pc = $signed (pa) + $signed (pb) ;
2个带符号数如位宽不一致,会导致计算结果出错。
相乘:
8bit与16bit相乘,结果位宽需要24bit;符号位扩展方法仍然与上面一样,乘积结果仍然为24bit。(想想这是为什么?)
assign pd = $signed (pa) * $signed (pb) ;
有位操作,有符号数被视为无符号数;带符号数如果被列入拼接符号内,相当于位操作将被视为无符号数。比如:
wire signed [10:0] A0;
wire signed [10:0] A1;
wire signed [10:0] B;
wire signed [10:0] C;
assign A0 = B[10:1];
assign A1 = {C,2‘b0};