关于fpga实现有符号的加减乘
摘要:测试环境: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系列的,其他⼚家或情况未知。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论