国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于FPGA的高效除法器設計

FPGA研究院 ? 來源:數字站 ? 2025-10-28 14:56 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

來源:數字站

FPGA可以通過除號直接實現除法,但是當除數或被除數位寬較大時,計算會變得緩慢,導致時序約束不能通過。此時可以通過在除法IP中加入流水線來提高最大時鐘頻率,這種方式提高時鐘頻率也很有限。如果還不能達到要求,就只能把除法器拆分,來提高系統時鐘頻率。

其實最簡單的方式是使用計數器對除數進行累加,并且把累加的次數寄存,當累加結果大于等于被除數時,此時寄存的累加次數就是商,而被除數減去累加結果就得到余數。

但這種方式存在一種弊端,當除數很小的時候,被除數特別大時,需要經過很多個時鐘周期才能計算除結果。比如被除數為100,除數為1,就需要100個時鐘左右才能計算出結果,效率無疑是低下的。因此一般不會使用這種方式實現除法器。

01除法器原理

首先觀察圖1中二進制數10011001除以1010的計算過程,除數與被除數位寬相差4,4位除數(1010)大于被除數的高4位(1001),小于被除數的高5位(10011),所以首先是被除數的高5位減去除數(如圖紫色數字),得到01001。然后被除數的第2位到6位數據依舊大于除數,則在次減去除數,就這樣依次相減,最后得到商為1111,余數為3。

034429c4-b069-11f0-8c8f-92fbcf53809c.png

03981052-b069-11f0-8c8f-92fbcf53809c.png

圖1 二進制除法

其實通過上面講述,就可以根據這個規律實現除法器了,每次從被除數高位取除數相同數據位寬的數據與除數進行比較,大于等于時直接做減法,商加1。小于時被除數數據位寬向低位移動,被除數每右移動1位,商左移1位,直到被除數移動到最低位時結束運算。

以上描述的方法在FPGA上不太好實現,最好是改進一下,將被除數和除數比較的位進行固定,那樣就會好實現很多。

如圖2所示,還是前文的8位10011001除以4位1010,通過一個9位的寄存器存儲8位被除數,始終比較被除數寄存器的第4到8位數據與除數的大小,如果大于除數,則進行減法運算,否則將被除數左移1位,然后在次進行判斷。

首先是5’b01001小于除數4’b1010,則將被除數左移1位。然后被除數高五位數據5’b10010大于除數,則商1,兩者相減得到01001。得到數據作為被除數運算位,此時被除數高5位還是比除數小,將被除數左移1位,相當于運算被除數的低位數據,同時也要把商左移1位。

03ebace4-b069-11f0-8c8f-92fbcf53809c.png

圖2 除法運算

就如同上圖循環判斷被除數高5位數據與除數的大小關系,然后對被除數進行移位和減法運算,就能夠計算出商和余數。當被除數的最低位數據被移入高5位時,在通過判斷被除數高5位數據與除數大小并進行相應減法后,運算結束。也就是說,這種情況下,被除數位寬為8,除數位寬為4,則被除數左移4次后計算結束,余數等于最后被除數的數值右移4位(被除數總共左移的次數)。

這種運算FPGA實現就較為簡單,例如被除數位寬為M,除數位寬為N,滿足M>=N,只需要比較被除數[M:M-N]與除數的大小,被除數左移M-N次后運算結束,將最終的被除數右移M-N位得到余數。

上述只適用于一般情況,還會出現圖3這種,被除數依舊是8位10000001,4位除數為0010,此時如果還拿被除數高5位減去除數,得到的結果仍然大于除數,會導致計算錯誤。

0445bcf2-b069-11f0-8c8f-92fbcf53809c.png

034429c4-b069-11f0-8c8f-92fbcf53809c.png

圖3 除法運算

此時可以把除數進行左移,直到除數的最高位為1或者除數左移后大于被除數的高5位為止,需要考慮除數左移1位,相當于增大2倍,要保持最終結果不變,被除數左移次數需要增加除數左移的次數,并且最后余數右移的次數也會相應增加。所以上述計算變為圖4所示。

04ea1716-b069-11f0-8c8f-92fbcf53809c.png

034429c4-b069-11f0-8c8f-92fbcf53809c.png

圖4 除法運算

首先除數根據條件需要左移2位都不會大于被除數的高5位,且不會溢出,所以除數就先左移2位,然后就是判斷被除數高5位是否大于除數,大于除數就進行減法運算且商加1,減法運算結果小于除數取代被除數參與運算的數據位。如果被除數高5位小于除數,則被除數和商一起左移,然后在次判斷。最終當被除數左移次數達到除數左移次數加被除數與除數位寬之差時計算結束。02除法器實現

經過上述分析,首先當輸入數據有效時,需要判斷除數和被除數是否為0,其中一個為0,則輸出均為0,且除數為0時,應該報錯。該模塊采用一個狀態機作為架構,包括空閑狀態,左移除數,除法運算三個狀態。假設除數位寬L_DIVR,被除數位寬L_DIVN,且L_DIVN>=L_DIVR。

模塊初始處于空閑狀態,只有上游模塊把開始計算信號拉高且被除數與除數均不為0時,狀態機跳轉到左移除數狀態。此時需要把除數和被除數存入對應寄存器,把除數左移次數計數器、被除數左移次數計數器、商和余數暫存器清零。

開始信號只有在狀態機處于空閑狀態下才會有效,其余時間不會接收上游模塊的除數、被除數等數據。

在左移除數的狀態下,如果除數最高位為0,且除數左移1位比被除數寄存器的高L_DIVR+1位小,那么將除數左移1位,除數左移次數計數器加1。否則狀態機跳轉到除法運算狀態。

狀態機處于除法運算狀態時,需要計算被除數高L_DIVR+1減去除數是否大于0。如果大于等于0,則將減法結果作為被除數的高L_DIVR+1位,商的最低位賦值為1,也就是加1。如果小于0且被除數左移次數小于除數左移次數加L_DIVN-L_DIVR時,把被除數和商均左移1位,被除數左移次數計數器加1。

如果被除數左移次數等于除數左移次數加L_DIVN-L_DIVR,則狀態機跳轉到空閑狀態,將被除數右移除數左移次數加L_DIVN-L_DIVR得到余數。

狀態機從除法狀態跳轉到空閑狀態時,把商、余數進行輸出。


以下代碼是模塊端口信號:

//當輸入除數為0時,error信號拉高,且商和余數為0;
//當ready信號為低電平時,不能將開始信號start拉高,此時拉高start信號會被忽略。
modulediv#(
 parameter    L_DIVN   = 8    ,//被除數的位寬;
 parameter    L_DIVR   = 4    //除數的位寬;
)(
input               clk    ,//時鐘信號;
input               rst_n   ,//復位信號,低電平有效;


inputstart    ,//開始計算信號,高電平有效,必須在ready信號為高電平時輸入才有效。
input    [L_DIVN -1:0]   dividend  ,//被除數輸入;
input    [L_DIVR -1:0]   divisor   ,//除數輸入;


 output reg            ready   ,//高電平表示此模塊空閑。
 output reg            error   ,//高電平表示輸入除數為0,輸入數據錯誤。
output reg            quotient_vld ,//商和余數輸出有效指示信號,高電平有效;
 output reg   [L_DIVR -1:0] remainder  ,//余數,余數的大小不會超過除數大小。
output reg   [L_DIVN -1:0] quotient   //商。
);

以下是狀態機狀態編碼和中間信號的定義,以及通過自動計算位寬函數取計算計數器的位寬。

 localparam     L_CNT    =  clogb2(L_DIVN) ;//利用函數自動計算移位次數計數器的位寬。
 localparam    IDLE    = 3'b001   ;//狀態機空閑狀態的編碼;
 localparam    ADIVR   = 3'b010   ;//狀態機移動除數狀態的編碼;
 localparam    DIV    = 3'b100   ;//狀態機進行減法計算和移動被除數狀態的編碼;


 reg          vld    ;//
 reg     [2:0]    state_c   ;//狀態機的現態;
 reg     [2:0]    state_n   ;//狀態機的次態;
 reg     [L_DIVN :0]  dividend_r  ;//保存被除數;
 reg     [L_DIVR -1:0] divisor_r   ;//保存除數。
 reg     [L_DIVN -1:0] quotient_r   ;//保存商。
 reg     [L_CNT -1:0]  shift_dividend ;//用于記錄被除數左移的次數。
 reg     [L_CNT -1:0]  shift_divisor ;//用于記錄除數左移的次數。


 wire     [L_DIVR :0]   comparison  ;//被除數的高位減去除數。
 wire           max    ;//高電平表示被除數左移次數已經用完,除法運算基本結束,可能還需要進行一次減法運算。


//自動計算計數器位寬函數。
function integerclogb2(input integer depth);begin
if(depth ==0)
   clogb2 =1;
elseif(depth !=0)
for(clogb2=0; depth>0; clogb2=clogb2+1)
    depth=depth >>1;
  end
 endfunction


max用來判斷被除數左移次數是否等于除數于被除數位寬差加除數左移次數。而comparison在除數左移狀態時,需要計算被除數高位與除數左移后相減的結果,在其余狀態下,計算被除數高位與除數相減的結果。

//max為高電平表示被除數左移的次數等于除數左移次數加上被除數與除數的位寬差;
 assign max = (shift_dividend == (L_DIVN - L_DIVR) + shift_divisor);


//用來判斷除數和被除數第一次做減法的高位兩者的大小,當被除數高位大于等于除數時,comparison最高位為0,反之為1。
//comparison的計算結果還能表示被除數高位與除數減法運算的結果。
//在移動除數時,判斷的是除數左移一位后與被除數高位的大小關系,進而判斷能不能把除數進行左移。
 assign comparison = ((divisor[L_DIVR-1] ==0) && ((state_c == ADIVR))) ?
    dividend_r[L_DIVN : L_DIVN - L_DIVR] - {divisor_r[L_DIVR-2:0],1'b0} :
    dividend_r[L_DIVN : L_DIVN - L_DIVR] - divisor_r;//計算被除數高位減去除數,如果計算結果最高位為0,表示被除數高位大于等于除數,如果等于1表示被除數高位小于除數。

下面是狀態機跳轉代碼。

//狀態機次態到現態的轉換;
 always@(posedge clkornegedge rst_n)begin
if(rst_n==1'b0)begin//初始值為空閑狀態;
   state_c <= IDLE;
? ? end
else?begin//狀態機次態到現態的轉換;
? ? ? state_c <= state_n;
? ? end
? end


//狀態機的次態變化。
? always@(*)begin
case(state_c)
IDLE : begin//如果開始計算信號為高電平且除數和被除數均不等于0。
if(start & (dividend !=?0) & (divisor !=?0))begin
? ? ? ? ? state_n = ADIVR;
? ? ? ? end
else?begin//如果開始條件無效或者除數、被除數為0,則繼續處于空閑狀態。
? ? ? ? ? state_n = state_c;
? ? ? ? end
? ? ? end
ADIVR : begin//如果除數的最高位為高電平或者除數左移一位大于被除數的高位,則跳轉到除法運算狀態;
if(divisor_r[L_DIVR-1] | comparison[L_DIVR])begin
? ? ? ? ? state_n = DIV;
? ? ? ? end
else?begin
? ? ? ? ? state_n = state_c;
? ? ? ? end
? ? ? end
DIV :?begin
if(max)begin//如果被除數移動次數達到最大值,則狀態機回到空閑狀態,計算完成。
? ? ? ? ? state_n = IDLE;
? ? ? ? end
else?begin
? ? ? ? ? state_n = state_c;
? ? ? ? end
? ? ? end
default?: begin//狀態機跳轉到空閑狀態;
? ? ? ? state_n = IDLE;
? ? ? end
? ? endcase
? end


下面是除數和被除數、商的計算過程,與前文描述一致,不再贅述。

//對被除數進行移位或進行減法運算。
//初始時需要加載除數和被除數,然后需要判斷除數和被除數的高位,確定除數是否需要移位。
//然后根據除數和被除數高位的大小,確認被除數是移位還是與除數進行減法運算,注意被除數移動時,為了保證結果不變,商也會左移一位。
//如果被除數高位與除數進行減法運算,則商的最低位變為1,好比此時商1進行的減法運算。經減法結果賦值到被除數對應位。
 always@(posedge clkornegedge rst_n)begin
if(rst_n==1'b0)begin//初始值為0;
   divisor_r <=?0;
? ? ? dividend_r <=?0;
? ? ? quotient_r <=?0;
? ? ? shift_divisor <=?0;
? ? ? shift_dividend <=?0;
? ? end//狀態機處于加載狀態時,將除數和被除數加載到對應寄存器,開始計算;
elseif(state_c == IDLE && start && (dividend !=?0) & (divisor !=?0))begin
? ? ? dividend_r <= dividend;//加載被除數到寄存器;
? ? ? divisor_r <= divisor;//加載除數到寄存器;
? ? ? quotient_r <=?0;//將商清零;
? ? ? shift_dividend <=?0;//將移位的被除數寄存器清零;
? ? ? shift_divisor <=?0;?//將移位的除數寄存器清零;
? ? end//狀態機處于除數左移狀態,且除數左移后小于等于被除數高位且除數最高位為0。
elseif(state_c == ADIVR && (~comparison[L_DIVR]) && (~divisor_r[L_DIVR-1]))begin
? ? ? divisor_r <= divisor_r <



參考代碼如下所示:

//注意此模塊默認被除數的位寬大于等于除數的位寬。
//當quotient_vld信號為高電平且error為低電平時,輸出的數據是除法計算的正確結果。
//當輸入除數為0時,error信號拉高,且商和余數為0;
//當ready信號為低電平時,不能將開始信號start拉高,此時拉高start信號會被忽略。
module div#(
 parameter    L_DIVN   = 8    ,//被除數的位寬;
 parameter    L_DIVR   = 4//除數的位寬;
)(
 input         clk    ,//時鐘信號;
 input          rst_n   ,//復位信號,低電平有效;


 input          start    ,//開始計算信號,高電平有效,必須在ready信號為高電平時輸入才有效。
 input    [L_DIVN -1:0] dividend  ,//被除數輸入;
 input    [L_DIVR -1:0] divisor   ,//除數輸入;


 output  reg        ready   ,//高電平表示此模塊空閑。
 output  reg        error   ,//高電平表示輸入除數為0,輸入數據錯誤。
 output reg        quotient_vld ,//商和余數輸出有效指示信號,高電平有效;
 output reg   [L_DIVR -1:0] remainder  ,//余數,余數的大小不會超過除數大小。
 output reg   [L_DIVN -1:0] quotient   //商。
); 
 localparam     L_CNT    =  clogb2(L_DIVN) ;//利用函數自動計算移位次數計數器的位寬。
 localparam    IDLE    = 3'b001   ;//狀態機空閑狀態的編碼;
 localparam    ADIVR   = 3'b010   ;//狀態機移動除數狀態的編碼;
 localparam    DIV    = 3'b100   ;//狀態機進行減法計算和移動被除數狀態的編碼;


 reg          vld    ;//
 reg     [2:0]    state_c   ;//狀態機的現態;
 reg     [2:0]    state_n   ;//狀態機的次態;
 reg     [L_DIVN :0]  dividend_r  ;//保存被除數;
 reg     [L_DIVR -1:0] divisor_r   ;//保存除數。
 reg     [L_DIVN -1:0] quotient_r   ;//保存商。
 reg     [L_CNT -1:0]  shift_dividend ;//用于記錄被除數左移的次數。
 reg     [L_CNT -1:0]  shift_divisor ;//用于記錄除數左移的次數。


 wire     [L_DIVR :0]   comparison  ;//被除數的高位減去除數。
 wire           max    ;//高電平表示被除數左移次數已經用完,除法運算基本結束,可能還需要進行一次減法運算。


//自動計算計數器位寬函數。
function integerclogb2(input integer depth);begin
if(depth ==0)
   clogb2 =1;
elseif(depth !=0)
for(clogb2=0; depth>0; clogb2=clogb2+1)
    depth=depth >>1;
  end
 endfunction


//max為高電平表示被除數左移的次數等于除數左移次數加上被除數與除數的位寬差;
 assign max = (shift_dividend == (L_DIVN - L_DIVR) + shift_divisor);


//用來判斷除數和被除數第一次做減法的高位兩者的大小,當被除數高位大于等于除數時,comparison最高位為0,反之為1。
//comparison的計算結果還能表示被除數高位與除數減法運算的結果。
//在移動除數時,判斷的是除數左移一位后與被除數高位的大小關系,進而判斷能不能把除數進行左移。
 assign comparison = ((divisor[L_DIVR-1] ==0) && ((state_c == ADIVR))) ?
    dividend_r[L_DIVN : L_DIVN - L_DIVR] - {divisor_r[L_DIVR-2:0],1'b0} :
    dividend_r[L_DIVN : L_DIVN - L_DIVR] - divisor_r;//計算被除數高位減去除數,如果計算結果最高位為0,表示被除數高位大于等于除數,如果等于1表示被除數高位小于除數。


//狀態機次態到現態的轉換;
 always@(posedge clkornegedge rst_n)begin
if(rst_n==1'b0)begin//初始值為空閑狀態;
   state_c <= IDLE;
? ? end
else?begin//狀態機次態到現態的轉換;
? ? ? state_c <= state_n;
? ? end
? end


//狀態機的次態變化。
? always@(*)begin
case(state_c)
IDLE : begin//如果開始計算信號為高電平且除數和被除數均不等于0。
if(start & (dividend !=?0) & (divisor !=?0))begin
? ? ? ? ? state_n = ADIVR;
? ? ? ? end
else?begin//如果開始條件無效或者除數、被除數為0,則繼續處于空閑狀態。
? ? ? ? ? state_n = state_c;
? ? ? ? end
? ? ? end
ADIVR : begin//如果除數的最高位為高電平或者除數左移一位大于被除數的高位,則跳轉到除法運算狀態;
if(divisor_r[L_DIVR-1] | comparison[L_DIVR])begin
? ? ? ? ? state_n = DIV;
? ? ? ? end
else?begin
? ? ? ? ? state_n = state_c;
? ? ? ? end
? ? ? end
DIV :?begin
if(max)begin//如果被除數移動次數達到最大值,則狀態機回到空閑狀態,計算完成。
? ? ? ? ? state_n = IDLE;
? ? ? ? end
else?begin
? ? ? ? ? state_n = state_c;
? ? ? ? end
? ? ? end
default?: begin//狀態機跳轉到空閑狀態;
? ? ? ? state_n = IDLE;
? ? ? end
? ? endcase
? end


//對被除數進行移位或進行減法運算。
//初始時需要加載除數和被除數,然后需要判斷除數和被除數的高位,確定除數是否需要移位。
//然后根據除數和被除數高位的大小,確認被除數是移位還是與除數進行減法運算,注意被除數移動時,為了保證結果不變,商也會左移一位。
//如果被除數高位與除數進行減法運算,則商的最低位變為1,好比此時商1進行的減法運算。經減法結果賦值到被除數對應位。
? always@(posedge clk?or?negedge rst_n)begin
if(rst_n==1'b0)begin//初始值為0;
? ? ? divisor_r <=?0;
? ? ? dividend_r <=?0;
? ? ? quotient_r <=?0;
? ? ? shift_divisor <=?0;
? ? ? shift_dividend <=?0;
? ? end//狀態機處于加載狀態時,將除數和被除數加載到對應寄存器,開始計算;
elseif(state_c == IDLE && start && (dividend !=?0) & (divisor !=?0))begin
? ? ? dividend_r <= dividend;//加載被除數到寄存器;
? ? ? divisor_r <= divisor;//加載除數到寄存器;
? ? ? quotient_r <=?0;//將商清零;
? ? ? shift_dividend <=?0;//將移位的被除數寄存器清零;
? ? ? shift_divisor <=?0;?//將移位的除數寄存器清零;
? ? end//狀態機處于除數左移狀態,且除數左移后小于等于被除數高位且除數最高位為0。
elseif(state_c == ADIVR && (~comparison[L_DIVR]) && (~divisor_r[L_DIVR-1]))begin
? ? ? divisor_r <= divisor_r <> shift_dividend;
  end
elsebegin
   quotient_vld <=?1'b0;
? ? end
? end


//當輸入除數為0時,將錯誤指示信號拉高,其余時間均為低電平。
? always@(posedge clk?or?negedge rst_n)begin
if(rst_n==1'b0)begin//初始值為0;
? ? ? error <=?1'b0;
? ??end
elseif(state_c == IDLE && start)begin
if(divisor==0)//開始計算時,如果除數為0,把錯誤指示信號拉高。
? ? ? ? error <=?1'b1;
else//開始計算時,如果除數不為0,把錯誤指示信號拉低。
? ? ? ? error <=?1'b0;
? ? end
? end


//狀態機處于空閑且不處于復位狀態;
? always@(*)begin
if(start || state_c != IDLE || vld)
? ? ? ready =?1'b0;
else
? ? ? ready =?1'b1;
? end


endmodule

03
除法器仿真


對應的TestBench文件如下所示:

`timescale1ns/1ns
moduletest();
  localparam L_DIVN     = 8       ;//被除數的位寬;
  localparam L_DIVR     = 4       ;//除數的位寬;
  localparam CYCLE      = 20       ;//時鐘周期;


  reg               clk       ;//時鐘信號;
  reg               rst_n      ;//復位信號,低電平有效;
  reg               start      ;//開始計算信號,高電平有效,
  reg     [L_DIVN -1:0]  dividend    ;//被除數輸入;
  reg     [L_DIVR -1:0]  divisor     ;//除數輸入;


  wire    [L_DIVN -1:0]  quotient    ;//商。
  wire    [L_DIVR -1:0]  remainder    ;//余數,余數的大小不會超過除數大小。
  wire              quotient_vld  ;//商和余數輸出有效指示信號,高電平有效;
  wire              ready      ;//高電平表示此模塊空閑。
  wire              error      ;//高電平表示輸入除數為0,輸入數據錯誤。


  reg               quotient_error ;
  reg               rem_error    ;


//例化待測試的除法器模塊;
  div#(
    .L_DIVN     ( L_DIVN    ),//被除數的位寬;
    .L_DIVR     ( L_DIVR    )//除數的位寬;
  )
  u_div(
    .clk      ( clk      ),//時鐘信號;
    .rst_n     ( rst_n     ),//復位信號,低電平有效;
    .start     ( start     ),//開始計算信號,高電平有效,
    .dividend    ( dividend   ),//被除數輸入;
    .divisor    ( divisor    ),//除數輸入;
    .quotient    ( quotient   ),//商。
    .remainder   ( remainder   ),//余數,余數的大小不會超過除數大小。
    .ready     ( ready     ),//高電平表示此模塊空閑。
    .error     ( error     ),//高電平表示輸入除數為0,輸入數據錯誤。
    .quotient_vld  ( quotient_vld )//商和余數輸出有效指示信號,高電平有效;
  );


//生成時鐘信號;
  initial begin
    clk =0;
    forever#(CYCLE/2) clk = ~clk;
  end


//生成復位信號;
  initial begin
    rst_n =1;
#2;
    rst_n =0;//開始時復位5個時鐘;
#(5*CYCLE);
    rst_n =1;
  end


  initial begin
#1;
    dividend =121; divisor =13;start=0;
#(8*CYCLE);
    repeat(20)begin//循環進行20次運算;
#(5*CYCLE);
      dividend = {$random};//產生隨機數作為被除數;
      divisor = {$random} ;//產生隨機數作為除數;
      start =1;
#(CYCLE);
      start =0;
      @(negedge quotient_vld);
#1;
#(3*CYCLE);
    end
#(5*CYCLE);
    $stop;//停止仿真;
  end


//對模塊輸出的數據進行判斷。
  always@(posedge clkornegedge rst_n)begin
if(rst_n==1'b0)begin//初始值為0;
      quotient_error <=?1'b0;
? ? ? ? ? ? rem_error <=?1'b0;
? ? ? ??end
? ? ? ??else?if(quotient_vld && (divisor!=0))begin
? ? ? ? ? ? quotient_error <= ((dividend / divisor) != quotient);
? ? ? ? ? ? rem_error <= ((dividend % divisor) != remainder);
? ? ? ? end
? ? end


endmodule



仿真結果如下所示,商和余數的錯誤指示信號均為低電平,表示除法運算的結果沒有什么問題。

058e6802-b069-11f0-8c8f-92fbcf53809c.png

圖5 仿真結果

模塊內部信號的詳細仿真如圖6、7所示,具體含義與前文介紹一致,就不再贅述了。

05eac66a-b069-11f0-8c8f-92fbcf53809c.png

圖6 除法模塊詳細仿真

063f32d6-b069-11f0-8c8f-92fbcf53809c.png

圖7 除法模塊詳細仿真

04總結

使用該模塊需要注意幾點:

1、被除數位寬必須大于等于除數位寬。

2、當error為高電平時,表示輸入除數為0,此時輸出的商和余數均為0且無效。 3、只有當quotient_vld為高電平時,模塊輸出的商和余數才是有效的。

4、只有當模塊處于空閑(ready為高電平)時,外部輸入的start和除數、被除數才能有效。 如果需要源文件,在公眾號后臺回復“基于FPGA的除法器”(不包括引號)即可。由于我只使用vscode和modelsim對工程進行仿真,所以沒有vivado和quartus工程。下面視頻就是通過vscode調用modelsim進行仿真的視頻。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1660

    文章

    22394

    瀏覽量

    635342
  • 計數器
    +關注

    關注

    32

    文章

    2313

    瀏覽量

    98044
  • 除法器
    +關注

    關注

    2

    文章

    15

    瀏覽量

    14123
  • 狀態機
    +關注

    關注

    2

    文章

    498

    瀏覽量

    29099

原文標題:基于FPGA的高效除法器

文章出處:【微信號:FPGA研究院,微信公眾號:FPGA研究院】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    基于FPGA除法器純邏輯設計案例

    除法運算。很多人覺得不就是除法嘛,直接打上/即可,但是,FPGA是不能正確綜合這個除法器的,綜合的結果只是一個固定數值,而不像其他微處理器。可以這么說,用
    的頭像 發表于 06-17 10:17 ?8360次閱讀
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>除法器</b>純邏輯設計案例

    除法器工作原理介紹

    二進制除法器的本質是多次減法,直到余數小于除數為止。對應的兩個N bit二進制數的除法算法如下。 1、設置2N bit寄存器A的低N位存放被除數,設置2N bit寄存器B的高N位存放除數,設置N
    發表于 10-21 08:32

    如何對蜂鳥e203內核乘除法器進行優化

    控制邏輯:除法器控制邏輯設計合理與否直接影響到除法器的性能表現,因此可以優化除法器控制邏輯,如增加硬件控制邏輯、優化狀態轉移邏輯等,可以有效提高除法器的效率。 采用更
    發表于 10-24 06:47

    AT32硬件除法器應用指南

    AT32硬件除法器應用指南 AT32F011 提供了 32 位硬件除法器,并且可以執行無符號及有符號運算,本應用指南將介紹基礎概念及實際案例。 支持型號: AT32F011 系列 1. AT32
    發表于 01-30 13:49

    基于FPGA除法器

    定點除法器的輸出是商和余數的形式,但是我想讓他表示成小數的形式(因為最后要送到數碼管顯示),該怎么裝換?求大神,給點思路也可以!總共是8位顯示,而整數部分和小數部分的位數不定?怎么設計
    發表于 05-15 20:01

    高速硬件除法器

    這是一個高速硬件除法器,要求畫出此硬件的除法器的工作流程圖。說明其工作原理特別是高速原理。要求有仿真時序波形圖并說出說明在fpga上驗證器硬件功能。
    發表于 12-17 09:10

    除法器的設計資料分享

    4.3 實例九 除法器設計4.3.1. 本章導讀要求掌握除法器原理,并根據原理設計除法器模塊以及設計對應的測試模塊,最后在 Robei可視化仿真軟件經行功能實現和仿真驗證。設計原理這個除法器
    發表于 11-12 07:03

    并行除法器 ,并行除法器結構原理是什么?

    并行除法器 ,并行除法器結構原理是什么?   1.可控加法/減法(CAS)單元    和陣列乘法器非常相似,陣列式除法器也是一種并行運算部件,采用大規模集成
    發表于 04-13 10:46 ?1.7w次閱讀

    除法器對數運算電路的應用

    除法器對數運算電路的應用 由對數電路實現除法運算的數學原理是:
    發表于 04-24 16:07 ?3119次閱讀
    <b class='flag-5'>除法器</b>對數運算電路的應用

    AD734:10 MHz四象限乘法器/除法器數據表

    AD734:10 MHz四象限乘法器/除法器數據表
    發表于 05-15 10:18 ?12次下載
    AD734:10 MHz四象限乘<b class='flag-5'>法器</b>/<b class='flag-5'>除法器</b>數據表

    簡化合成器的有源乘法器除法器

    簡化合成器的有源乘法器除法器
    發表于 05-16 17:15 ?9次下載
    簡化合成器的有源乘<b class='flag-5'>法器</b>和<b class='flag-5'>除法器</b>

    實例九— 除法器設計

    4.3 實例九 除法器設計4.3.1. 本章導讀要求掌握除法器原理,并根據原理設計除法器模塊以及設計對應的測試模塊,最后在 Robei可視化仿真軟件經行功能實現和仿真驗證。設計原理這個除法器
    發表于 11-07 10:51 ?18次下載
    實例九— <b class='flag-5'>除法器</b>設計

    FPGA常用運算模塊-除法器

    本文是本系列的第四篇,本文主要介紹FPGA常用運算模塊-除法器,xilinx提供了相關的IP以便于用戶進行開發使用。
    的頭像 發表于 05-22 16:20 ?5554次閱讀
    <b class='flag-5'>FPGA</b>常用運算模塊-<b class='flag-5'>除法器</b>

    FPGA基于線性迭代法的除法器設計

    FPGA實現除法的方法有幾種,比如直接用/來進行除法運算,調用IP核進行除法運算,但這兩種方式都有個共同的問題——都是黑盒子,在進行時序違例處理時,往往不好操作,比如想打打拍改善下時序
    的頭像 發表于 07-04 10:03 ?2339次閱讀
    <b class='flag-5'>FPGA</b>基于線性迭代法的<b class='flag-5'>除法器</b>設計

    使用IAR IDE仿真RL78內置硬件乘法器除法器注意事項

    使用IAR IDE仿真RL78內置硬件乘法器除法器注意事項
    的頭像 發表于 10-30 17:04 ?2435次閱讀
    使用IAR IDE仿真RL78內置硬件乘<b class='flag-5'>法器</b>和<b class='flag-5'>除法器</b>注意事項