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

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/;



  • 8
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值