摘要:测试环境: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系列的,其他厂家或情况未知。

 

posted on 2019-01-04 16:38  洋葱洋葱  阅读(2967)  评论(2编辑  收藏  举报