乘法器的設計

原文鏈接:https://blog.csdn.net/yf210yf/article/details/70156855

乘法算是基本運算之一,廣泛應用在數字信號處理中,濾波器中乘法運算必不可少,實現乘法器的方法很多,各有各的優缺點,常見的有移位相加法,加法樹法,查表法,混合法……

在我們用語言設計電路時,初學時在實現乘法運算時通常很簡單的用*號操作,但是這種方法談不上設計乘法器,其最終的硬件實現要根據綜合器綜合的結果,好的綜合器可以綜合出想要的結果,但是實際上這種粗放的設計通常得到的都是劣等的乘法運算,無法滿足對乘法速率的要求,在濾波電路中要求數據串行進入接着進行大量的乘法運算,當所設計的乘法器其的速度小於數據進入的速度的時候就會導致結果錯……

1   移位相加乘法器,對兩個二進制數進行相乘運算,運用列式求法我們可以得知,乘法最終就是由加法和移位運算構成的,由此可以用高速度的加法和移位實現乘法操作,具體代碼如下:

begin
dout=0;
for(i=0;i<WIGTH;i=i+1)
dout=dout+((din_a_buf[i]==1)?(din_b_buf<<i):0);//移位相加邏輯

end

2  上面的設計中,由於產生了大量的組合邏輯,這就帶來了大量的延遲從而使乘法器的速率受到限制,爲了提高速度,可以採用流水線的方法,將組合邏輯分割成一個一個小的組合邏輯,中間加上觸發器用來鎖存數據,這樣就可以大大提高頻率,引入觸發器僅僅是帶來了延遲而已,具體代碼實現如下 :

begin//流水線實現
din_a_buf<=din_a;
din_b_buf<=din_b;
buf0<=din_b_buf[0]?din_a_buf:0;
buf1<=din_b_buf[1]?din_a_buf<<1:0;
buf2<=din_b_buf[2]?din_a_buf<<2:0;
buf3<=din_b_buf[3]?din_a_buf<<3:0;
buf4<=din_b_buf[4]?din_a_buf<<4:0;
buf5<=din_b_buf[5]?din_a_buf<<5:0;
buf6<=din_b_buf[6]?din_a_buf<<6:0;
buf7<=din_b_buf[7]?din_a_buf<<7:0;

buf01<=buf0+buf1;
buf23<=buf2+buf3;
buf45<=buf4+buf5;
buf67<=buf6+buf7;

buf02<=buf01+buf23;
buf46<=buf45+buf67;

dout<=buf02+buf46;
end

此種乘法器叫做加法樹式乘法器,此方法被廣泛使用 

 3   查表法,就是建一個表,裏面存放了所有的乘法結果,乘數和被乘數用來作爲地址去裏面的乘積,此種方法可以大大提高乘法的速率,但是當乘法位數很大時會要求產生很大的表格,所以此種方法適合位數較小的乘法,特別適合有一個乘數爲固定的乘法,如濾波器中的乘法就可以採用此種方法設計

4  混合,顧名思義就是結合以上各種方法的乘法器

舉個簡單的例子,比如有兩個32bit的數據X[31:0]與Y[31:0]相乘。當然,無論Altera還是Xilinx都有現成的乘法器IP核可以調用,這也是最簡單的方法,但是兩個32bit的乘法器將耗費大量的資源。那麼有沒有節省資源,又不太複雜的方式來實現呢?我們可以稍做修改:

 將X[31:0]拆成兩部分X1[15:0]和X2[15:0],令X1[15:0]=X[31:16],X2[15:0]=X[15:0],則X1左移16位後與X2相加可以得到X;同樣將Y[31:0]拆成兩部分Y1[15:0]和Y2[15:0],令 Y1[15:0]=Y[31:16],Y2[15:0]=Y[15:0],則Y1左移16位後與Y2相加可以得到Y;則X與Y的相乘可以轉化爲X1和X2 分別與Y1和Y2相乘,這樣一個32bit*32bit的乘法運算轉換成了四個16bit*16bit的乘法運算和三個32bit的加法運算。轉換後的佔用資源將會減少很多

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章