赞
踩
除法器的计算过程如下图所示。
假设数值的位宽为N。
Step1:分别将被除数和除数扩展至原来2倍位宽(2N),被除数在其左边补N位0,除数在其右边补N位0;
Step2:将被除数依次左移(每次左移1位),末位补数值(该数值为被除数高N位与除数高N位的商),高N位为被除数高N位与除数高N位的余数。移位执行N次,执行N次后,进入Step3;
Step3:此时被除数的低N位为计算得到的商,被除数的高N位为计算得到的余数。
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
这里简单的写个测试文件对流水线除法器进行功能测试,判断是否符合预期的计算结果。
`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,仿真所得计算结果正确,验证通过。
注:本博客仅为个人学习笔记,如有错误之处,请指正,如有转载请备注出处,谢谢。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。