您的位置:首页 > 其它

FPGA基于Verilog的有符号加法及有符号乘法运算

2018-03-19 18:09 337 查看
0 背景
    最近所做的工作涉及到有符号数、无符号数之间的加法运算和乘法运算。例如:有些输入数据是有符号数据,有些参数为无符号数据,它们之间进行算术运算,就会涉及到符号位的变化及运算结果位宽的变化,如果没有总结出规律,很容易得不到正确的结果,下文将对有符号数加法及乘法的运算规律进行详述。

1  有符号数加法运算
    假设定义两个8位数据,[7 : 0] A,B,其中A为无符号数,B为有符号数据;则A + B进行有符号加法运算的结果有4种可能;常见的编程思路是:通过比较|A|和|B|值大小,然后判定符号位及对应的编程,如|A| > |B|,则结果为A的符号位,结果为|A| - |B|;该思路在处理两个数据运算尚可应对,例如当A、B、C、D等多个有符号数据进行同时运算时,该方法就会捉襟见肘了。

改进方案:将上述所有数据均扩展为有符号数据,然后就可以一起进行有符号数加法,得到正确的结果。因为当前FPGA的设计软件均支持有符号数的加法和乘法运算,从而可以降低开发难度。具体程序见下文。
reg        [7 : 0] din0, din1, din2;
reg signed [8 : 0] din0_buf, din1_buf, din2_buf;
reg signed [10 : 0] add_rslt;
reg signed [26 : 0] mult_rslt;

////--------------------------------------------------------------
always@(posedge clk)
if(en) begin
en0  <= 1;
din0 <= din0 + 1;
din1 <= din1 + 1;
din2 <= din2 + 1;
end
else begin
en0  <= 0;
din0 <= -15;
din1 <= 4;
din2 <= -9;
end

always@(posedge clk)
if(en0) begin
din0_buf <= {din0[7],din0};
din1_buf <= {din1[7],din1};
din2_buf <= {din2[7],din2};
en1  <= 1;
end
else begin
din0_buf <= 0;
din1_buf <= 0;
din2_buf <= 0;
en1  <= 0;
end

always@(posedge clk)
if(en1) begin
rslt_en <= 1;
add_rslt <= din0_buf + din1_buf + din2_buf;
mult_rslt <= din0_buf * din1_buf * din2_buf;;
end
else begin
rslt_en <= 0;
add_rslt <= 0;
mult_rslt <= 0;
end




结论: 由上述运算结果可知,该运算结果满足设计要求。

2  有符号数乘法运算

   有符号数和无符号数进行乘法混合运算,设计思路与加法运算相一致。主要是对无符号数进行有符号处理,即进行位扩展来添加符号位。 例如: input [7 : 0] din; 可以扩展为reg signed  [8 : 0] din_buf,将所有待运算数据转换后,即可进行乘法运算。



综上所述:  通过添加符号位,进行位扩展,同时注意运算结果的最大位宽,则该方法均能得到正确的运算结果。
参考博文:
1.   http://blog.sina.com.cn/s/blog_4b1046f80102wlf4.html;
2.  http://blog.163.com/gcs_gcs/blog/static/1744860662010102082310910/;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息