Y / D =Q……….R
Y:被除數
D:除數
Q:商
R:余數
對於一個n位的被除數Y,m位的除數D,若想求出余數,可通過恢復余數算法實現,個人的理解是這個求商貌似不太好用,求余數倒是好用的很!
其實現方式是,將除數左移到與被除數位寬相同,將移位的結果與被除數進行比較,如果被除數大於等於移位結果,說明商的對應位為1,將被除數減去移位結果得到新一輪的被除數,之后除數繼續移位,移位到與新的被除數位寬相同…..當被除數小於D時候即為余數,解釋起來有點麻煩,上代碼。
以一個被除數位寬為4,除數位寬為2的輸入為例:
工程代碼:
module chufa( clk, rst_n, en, //計算使能信號 Y, //被除數 D, //除數 R //余數 ); input clk; input rst_n; input en; input [3:0]Y; input [1:0]D; output reg[3:0]R; reg [3:0]state; parameter S0=4'b0001; parameter S1=4'b0010; parameter S2=4'b0100; parameter S3=4'b1000; reg [3:0]Y2,Y3,Y4; reg [3:0]D1,D2; reg o_en; always@(posedge clk or negedge rst_n) if(!rst_n) begin state<=S0; o_en<=1'b0; end else begin case (state) S0:begin o_en<=1'b0; //余數輸出不使能 if(en)begin state<=S1; D1<=(D<<2); //移位至與被除數位寬相同,第一次移位操作 end end S1: begin D2=(D<<1); //除數左移一位,第二次移位操作 if(Y>=D1) Y2<=Y-D1; //下一次迭代的被除數 else Y2<=Y; state<=S2; end S2: begin if(Y2>=D2) Y3<=Y2-D2; else //最高位沒有被整除 Y3<=Y2; state<=S3; end S3: begin if(Y3>=D) //最后一輪的迭代比較 Y4<=Y3-D; else Y4<=Y3; o_en<=1'b1; state<=S0; end endcase end always@(posedge clk or negedge rst_n) if(!rst_n) R<=4'd0; else if(o_en) R<=Y4; endmodule
仿真代碼:
`timescale 1ns / 1ps module tb(); reg clk; reg rst_n; reg en; reg [3:0]Y; reg [1:0]D; wire[3:0]R; chufa cf( .clk(clk), .rst_n(rst_n), .en(en), //計算使能信號 .Y(Y), //被除數 .D(D), //除數 .R(R) //余數 ); initial clk=0; always #5 clk=~clk; initial begin rst_n=0; Y=13; en=0; D=3; #100; rst_n=1; #100; en=1; #100; end endmodule
仿真結果