日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FPGA学习之路—应用程序—原码二位乘法器及Verilog代码分析

發布時間:2023/12/19 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FPGA学习之路—应用程序—原码二位乘法器及Verilog代码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

FPGA學習之路——原碼二位乘法器及Verilog代碼分析

原理

原碼乘法可以分為原碼一位乘和原碼二位乘,兩者在實現規則上大同小異。原碼一位乘每次判斷乘數的最低位,對被乘數和部分積進行相應操作。而原碼二位乘則是對乘數的低二位進行判斷,并執行相關操作。
兩位乘數的取值可以有四種可能組合,每種組合對應于以下操作:

00相當于0×X,部分積Dresult右移2位,不進行其他運算;
01相當于1×X,部分積Dresult+x之后再右移兩位;
10相當于2×X,部分積Dresult+2x后再右移兩位;
11相當于3×X,部分積Dresult+3x后再右移兩位;

上述過程出現了+x,+2x,+3x三種情況,+x容易實現,+2x可以將x左移一位,但是+3x一般不能在一個時鐘周期完成,分兩個時鐘完成又降低運算速度。所以解決方法是:以+(4x-x)來代替+3x運算,在本次運算中執行-x,將+4x歸并到下一步執行。因為下一步運算時,前一次的部分積已經右移了兩位,所以上一步欠下的+4x在現在已經變成了+x。實際實現中用觸發器C來記錄是否有欠下的+4x操作尚未執行,若有,則C<=1。所以實際操作要用乘數的低兩位和C三位的組合值來控制乘法運算操作,運算規則如下圖所示。

計算過程

1、求乘數、被乘數的絕對值,對被乘數絕對值的相反數求補;初始化部分積為000.0000000(本文以8位數據為例,數點左邊為3位符號位,右邊7位為絕對值的數值位)
2、對乘數最高位補0,引入標志位C,C初始化為0。
3、根據表格判斷相應操作,移位時先將乘數右移兩位,高兩位由部分積的低兩位來補。
4、乘數移動完畢后,被乘數用補碼三位符號位移位規則進行右移兩位。
5、重復3、4步驟直到移位次數為乘數位數/2。
6、此時還不能得出結果,需要再次對乘數低兩位和標志位C進行判斷,執行最后一次操作,但乘數不進行移位。
7、結果組成為{乘數和被乘數符號位進行異或(1位),部分積的低6位,乘數8位(絕對值為7位,補完0后變8位)}共15位。

注意事項:
1、步驟2中,乘數位數是奇數位則補1位0即可;若乘數位數是偶數則最高位補2個0。
2、對部分積右移時,采用3位符號的補碼形式移位,即最高位符號位不動,正數在最高位添0,負數在最高位添1。
3、表格中的-|x|操作即加上x絕對值相反數的補碼。

舉例:

Verilog源碼分析(完整項目鏈接見文末)

input clk,en; //取en對應的上升沿時刻對原碼形式的dataA和dataB進行乘法運算 input [7:0] dataA,dataB; //被乘數與乘數 output dataO; //結果輸出reg [10:0]dataAreg; //寄存器存放取樣時刻dataA的值 被乘數 reg [7:0]dataBreg; //寄存器存放取樣時刻dataB的值 乘數 reg [10:0]negdataAreg; //存放被乘數絕對值的相反數的補碼 -|x|的補碼 reg [10:0]twodataAreg; //存放被乘數絕對值的兩倍 2|x| reg [10:0]Dresult; //部分積 reg [10:0]Dresult1; //部分積+\x\ reg [10:0]Dresult2; //部分積+2\x\ reg [10:0]Dresult3; //部分積-|x| reg [2:0]cnt; //計數子,記錄移位次數 reg C; //標志位C reg [14:0]dataO; //輸出結果 reg sig=1'b0; //標志位,標志該時鐘周期更新Dresult或是Dresult1、2、3//Dresult和Dresult1、2、3不可同時更新,他們互為基礎,需按序更新 always @(posedge clk)beginif(en)begindataAreg<={1'b0,1'b0,1'b0,dataA[6:0]}; //|x|negdataAreg<={1'b1,~{1'b0,1'b0,1'b0,dataA[6:0]}}+1'b1; //-|x|的補碼twodataAreg<={1'b0,1'b0,dataA[6:0],1'b0}; //2|x|dataBreg<={1'b0,dataB[6:0]}; //乘數Dresult<=11'b0; Dresult1<={1'b0,1'b0,1'b0,dataA[6:0]}; //Dresult1、2、3賦初值Dresult2<={1'b0,1'b0,dataA[6:0],1'b0};Dresult3<={1'b1,~{1'b0,1'b0,1'b0,dataA[6:0]}}+1'b1;C<=1'b0;cnt<=3'd1;end end always @(posedge clk)beginif(!en&sig)begin //未使能且是更新Dresult1、2、3的時鐘周期Dresult1=Dresult+dataAreg;Dresult2=Dresult+twodataAreg;Dresult3=Dresult+negdataAreg;endif(!sig && (cnt!=3'b0))begin //周期開始時,計數子從1記到5,記到5時乘數不進行移位操作。//且是更新Dresult1、2、3的時鐘周期……//查表對部分積Dresult和乘數dataBreg進行更新endif(cnt==3'd5)begin //進行數據輸出cnt<=3'd0;dataO<={(dataA[7]^dataB[7]),Dresult[5:0],dataBreg[7:0]};endsig<=~sig; end

仿真結果:

其中dataA,dataB和dataO的數據格式選擇Signed Magnitude,原碼格式。

實驗心得

1、編寫Verilog代碼前先進行數據流程的分析,分析在每個時鐘周期下數據的預期結果,再與波形圖對比是否符合預期,如果不符,觀察數據是否在緊接著的時鐘周期出現。
2、擯棄C語言的順序思維,好好分析數據的時序。可以引入標志位實現按序更新數據。如本例中引入sig標志位對Dresult和Dresult1、2、3依次進行更新。

項目鏈接

總結

以上是生活随笔為你收集整理的FPGA学习之路—应用程序—原码二位乘法器及Verilog代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。