主題
使用Verilog HDL 實作最基本的除法運算。
問題分析
以32位除法器為例,介紹其verilog語言實作的原理
首先個人認為該方法是受到除法手工計算方法的啟發。對于32位的無符号數,其商和餘數的位數都不會超過32位,首先将被除數a擴充為64位的temp_a = {32'h0000,a},将除數b擴充為64位的temp_b ={b,32'h0000}。運算過程為:首先将temp_a左移一位,低位補零之後與temp_b比較大小,如果移位之後 temp_a < temp_b,則temp_a不變,進入下一輪的移位與比較;如果temp_a >= temp_b,則本次比較的結果應該是商為1(二進制),餘數為temp_a - temp_b,将商的值計錄到temp_a的第0位(此前temp_a左移了一位,第0位為0),更新temp_a 的值為 temp_a - temp_b + 1'b1。至此第一輪的移位與比較結束,由于是32位二進制數,需要進行32輪的移位與比較。最終的結果是temp_a的高32位是餘數,低32位是商。
代碼如下(示例):
module DIV_32(
input clk,rst_n,
input [31:0] a,
input [31:0] b,
output reg [31:0] yshang,
output reg [31:0] yyushu
);
reg[63:0] temp_a;
reg[63:0] temp_b;
integer i;
always @ (posedge clk or negedge rst_n)begin
if(!rst_n) begin
temp_a <= 64'h0;
temp_b <= 64'h0;
yshang <= 0;
yyushu <= 0;
end
else begin
temp_a = {32'h00000000,a};
temp_b = {b,32'h00000000};
for (i =0 ;i<32 ;i=i+1 ) begin
temp_a = temp_a << 1;
if(temp_a >= temp_b) temp_a = temp_a - temp_b + 1'b1;
else temp_a = temp_a;
end
yshang <= temp_a[31:0];
yyushu <= temp_a[63:32];
end
end
endmodule
總結
雖是最為基本的設計,但還是有很多錯誤的示例,本次旨在為初學者提供一篇正确的示例。另外,雖然思路明确,但是對這一計算方法的細節之處還有待考慮,比如将移位比較後的商放置到最低位參與temp_a的移位運算獲得最終結果,并且還不會影響到temp_a與temp_b的比較大小,這巧妙之處時常讓我犯迷糊。希望在以後的應用中慢慢加深了解。也非常歡迎交流指正。