摘要:测试环境:quartus 13.0,在多数情况下,我们需要通过扩展符号位来实现有符号数的+ - *,但是verilog 的语法中有关于有符号的修饰符:signed,对比,笔者做了简单的测试,现将过程记录如下:欢迎大家一起交流,Q群:912014800。
这里我测试了乘法,代码如下:
module mul_test( input clk , input sw0 , output reg signed [2:0] a , output reg signed [2:0] b , output reg signed [5:0] c ); reg sw0_ff0; reg sw0_ff1; reg sw0_ff2; reg [1:0] cnt; wire sw0_l2h ; always @(posedge clk)begin sw0_ff0 <= sw0; sw0_ff1 <= sw0_ff0; sw0_ff2 <= sw0_ff1; end assign sw0_l2h = sw0_ff2==0 && sw0_ff1==1; always @(posedge clk)begin if(sw0_l2h)begin cnt <= cnt+1; end end always@(*)begin if(cnt==0)begin a = -1; b = 2; end else if(cnt==1)begin a = -4; b = -4; end else if(cnt==2)begin a = 2; b = -1; end else begin a = -3; b = -2; end end always @(posedge clk)begin c <= a * b; end endmodule
代码解释:sw0是外部触发条件,可以是按键或者拨码开关,当触发的时候,cnt+1,而cnt的值又会影响reg a 和 b的值,这里直接写即可(verilog如果表示字符的话,可以这样子写:dat = "a"),最后c 等于a * b ,接下来上板用signal验证,如下所示:
如上所示,当a = -1, b = 2时,c = -2;当a = -4 b=-4,c=16。
分析:和实际预想的一样,也就是说在计算的时候自动扩展了符号位。
当去掉signed后,代码改为(其他不变):
去掉signed后,顶层如上所示:
signal tap 抓的波形如下:
如上所示:分析如下:
左边是-1 * 2 如果不扩展符号位 ,算出来的结果是8+4+2 = 14,右边算出来是16。(这里输出6bit)
结论:如果计算有符号数的+ - * /,笔者认为可以加上signed修饰即可,这样子就不用考虑要扩展几个符号位的问题了,以上测试的fpga是altera c4系列的,其他厂家或情况未知。