1. 程式人生 > >FPGA基於Verilog的有符號加法及有符號乘法運算

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