求余算法的FPGA实现

2020-06-30 11:20:05 浏览数 (1)

遇到了一个输入的除数和被除数位宽(64~256)都很大,组合逻辑导致时序不满足要求的问题,根据恢复余数法想出这样一个解决方式:

Y / D =Q……….R

Y:被除数

D:除数

Q:商

R:余数

对于一个n位的被除数Y,m位的除数D,若想求出余数,可通过恢复余数算法实现,个人的理解是这个求商貌似不太好用,求余数倒是好用的很!

其实现方式是,将除数左移到与被除数位宽相同,将移位的结果与被除数进行比较,如果被除数大于等于移位结果,说明商的对应位为1,将被除数减去移位结果得到新一轮的被除数,之后除数继续移位,移位到与新的被除数位宽相同…..当被除数小于D时候即为余数,解释起来有点麻烦,上代码。

以一个被除数位宽为4,除数位宽为2的输入为例:

工程代码:

代码语言:javascript复制
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

仿真代码:

代码语言:javascript复制
`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

仿真结果:

0 人点赞