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