FPGA流水线除法器(Verilog)原理及实现
流水线除法器原理
除法器的计算过程如下图所示。
计算步骤
假设数值的位宽为N。
Step1:分别将被除数和除数扩展至原来2倍位宽(2N),被除数在其左边补N位0,除数在其右边补N位0;
Step2:将被除数依次左移(每次左移1位),末位补数值(该数值为被除数高N位与除数高N位的商),高N位为被除数高N位与除数高N位的余数。移位执行N次,执行N次后,进入Step3;
Step3:此时被除数的低N位为计算得到的商,被除数的高N位为计算得到的余数。
流水线除法器Verilog代码
module pipeline_divider
#(
parameter N = 8
)
(
input clk , //时钟信号
input rst_n , //复位信号
input start , //开始信号
input [N-1:0] dividend, //被除数
input [N-1:0] divisor , //除数
output [N-1:0] quotient , //商
output [N-1:0] remainder , //余数
output finish //计算结束信号
);
//============================================
// 变量声明
//============================================
//------------------内部变量------------------
reg [2*N-1:0] dividend_temp ;
reg [2*N-1:0] divisor_temp;
reg finish_temp;
reg state;
reg [$clog2(N):0] cnt;
//-----------------状态机状态-----------------
parameter Init = 'd0;
parameter Calc = 'd1;
//============================================
// 流水线除法器
//============================================
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
dividend_temp <= 0;
divisor_temp <= 0;
finish_temp <= 0;
cnt <= 0;
state <= Init;
end
else begin
case(state)
Init:
begin
if(start) begin
cnt <= 0;
finish_temp <= 0;
dividend_temp <= {{N{1'b0}},dividend};
divisor_temp <= {divisor,{N{1'b0}}};
state <= Calc;
end
end
Calc:
begin
if(cnt == N) begin
finish_temp <= 1'b1;
state <= Init;
end
else begin
if(dividend_temp[2*N-2:N-1] >= divisor_temp[2*N-1:N]) begin
dividend_temp <= {dividend_temp[2*N-2:0],1'b0} - divisor_temp + 1'b1;
end
else begin
dividend_temp <= {dividend_temp[2*N-2:0],1'b0};
end
cnt <= cnt + 1'b1;
end
end
endcase
end
end
//============================================
// 模块输出
//============================================
assign finish = finish_temp;
assign quotient = finish ? dividend_temp[N-1:0] : 0;
assign remainder = finish ? dividend_temp[2*N-1:N] : 0;
endmodule
Test_Bench
这里简单的写个测试文件对流水线除法器进行功能测试,判断是否符合预期的计算结果。
`timescale 1ns/1ps
module tb_pipeline_divider();
parameter N = 8;
reg clk,rst_n,start;
reg [N-1:0] dividend; //被除数
reg [N-1:0] divisor ; //除数
wire [N-1:0] quotient;
wire [N-1:0] remainder;
wire finish;
initial begin
clk = 1'b0;
rst_n = 1'b0;
start = 1'b0;
dividend = 'd23;
divisor = 'd3;
#20
rst_n = 1'b1;
#100
start = 1'b1;
end
always #10 clk = ~clk;
pipeline_divider
#(
.N(N)
)
pipeline_divider_inst
(
.clk (clk ), //时钟信号
.rst_n (rst_n ), //复位信号
.start (start ), //开始信号
.dividend (dividend ), //被除数
.divisor (divisor ), //除数
.quotient (quotient ), //商
.remainder (remainder ), //余数
.finish (finish ) //结束信号
);
endmodule
仿真结果
这里被除数为23,除数为3,得到商为7,余数为2,仿真所得计算结果正确,验证通过。文章来源:https://www.toymoban.com/news/detail-505758.html
注:本博客仅为个人学习笔记,如有错误之处,请指正,如有转载请备注出处,谢谢。文章来源地址https://www.toymoban.com/news/detail-505758.html
到了这里,关于FPGA流水线除法器(Verilog)原理及实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!