Verilog无符号除法器-流水线实现


 在前一篇文章中提到了除法器模块的状态机实现,状态机实现可以使用最少的资源实现除法功能,随之带来的是每次只能运算一次结果,下一次除法运算需要等上一个运算结束后进行,而流水线模式则很好的避免了这个问题,可以连续输入需要运算的数据,运算结果流水输出,缺点是需要大量的逻辑资源,也就是所谓的面积换速度,运算原理相同,无符号除法器减法实现方式,流水线实现的模块如下

1、运算模块

/*******************************************************************
* -------------------  Module Specification ------------------------
    *
    *  * Name     :divider_pipe
    *
    *  * Function :无符号除法,流水线实现,延迟(N+9)个单元后输出
    优点:适用于大量的除法运算,且速度快,面积换速度,
    缺点:占用大量内存。
    *
    *  * Input    :
    *
    *  * Output   :
    *
    *  * author   :彧芯
    *
    *  * Edit time:2021/04/25/17:01:56
    *
    *  *************************************************************/
module divider_pipe#( 	
    parameter  	   DATA_W = 8
    )(
input  wire             clk,
input  wire             enable,
input  wire[DATA_W-1:0] a,
input  wire[DATA_W-1:0] b,
output reg [DATA_W-1:0] yshang,
output reg [DATA_W-1:0] yyushu,
output wire             done
);

//Define local parameters(localparam)

//Output signal reg definition

//Intermediate signal definition
reg[DATA_W-1:0] tempa = 0;
reg[DATA_W-1:0] tempb = 0;
reg[2*DATA_W-1:0] temp_a[2*DATA_W-1:0];
reg[2*DATA_W-1:0] temp_b[2*DATA_W-1:0];
reg[2*DATA_W+1:0] done_fifo = 0;
//Combinatorial logic

//Sequential logic

always@(posedge clk) begin
    if(enable)begin
      tempa <= a;
      tempb <= b;
    end
end

generate
    genvar i;
    for(i=0;i<2*DATA_W-1;i=i+2)begin:u_div
        always@(posedge clk) begin
            if(i==0)begin
                temp_a[i][2*DATA_W-1:0] <= {{(DATA_W-1){1'b0}},tempa,1'b0};
                temp_b[i][2*DATA_W-1:0] <= {tempb,{DATA_W{1'b0}}};
            end
            else begin
                temp_a[i][2*DATA_W-1:0] <= {temp_a[i-1][2*DATA_W-2:0],1'b0};
                temp_b[i][2*DATA_W-1:0] <= temp_b[i-1][2*DATA_W-1:0];
            end
            
        end

        always@(posedge clk) begin
            temp_b[i+1][2*DATA_W-1:0] <= temp_b[i][2*DATA_W-1:0];
            if(temp_a[i][2*DATA_W-1:DATA_W] >= temp_b[i][2*DATA_W-1:DATA_W]) temp_a[i+1][2*DATA_W-1:0] <= temp_a[i][2*DATA_W-1:0] - temp_b[i][2*DATA_W-1:0] + 1'b1;
            else temp_a[i+1][2*DATA_W-1:0] <= temp_a[i][2*DATA_W-1:0];
        end
    end
endgenerate

always@(posedge clk) begin
    yshang <= temp_a[2*DATA_W-1][DATA_W-1:0];
    yyushu <= temp_a[2*DATA_W-1][2*DATA_W-1:DATA_W];
end

always@(posedge clk) begin
    done_fifo <= {done_fifo[2*DATA_W:0],enable};
end

assign done = done_fifo[2*DATA_W+1];

endmodule

2、测试模块

`timescale 1 ns/1 ns
module tb_pipe();

//parameters
parameter CYCLE    = 20; //!Clock cycle, 20ns, where the clock cycle can be modified
parameter RST_TIME = 3 ; //Reset time, at this point represents the reset time of 3 clock cycles
localparam N = 10;

//Clock and reset signals
reg clk  ;
reg rst_n;

//The input signal of the instantiate module
reg enable; 
reg [N-1:0] a;
reg [N-1:0] b;

//The output signal of the instantiate module
wire [N-1:0] yshang;
wire [N-1:0] yyushu; 
wire done;

//Instantiate the modules to be tested
divider_pipe #(
    .DATA_W ( N )
)u_divider_pipe(
    .clk    ( clk    ),
    .enable ( enable ),
    .a      ( a      ),
    .b      ( b      ),
    .yshang ( yshang ),
    .yyushu ( yyushu ),
    .done   ( done   )
);

//Generate the local clock, at 50MHz here
initial begin
    clk = 0;
    forever
    #(CYCLE/2)
    clk=~clk;
end

//Generate the reset signal
initial begin
    rst_n = 1;
    #2;
    rst_n = 0;
    #(CYCLE*RST_TIME);
    rst_n = 1;
end

//Assign a value to the input signal din0
integer i;
initial begin
    #1;
    //initialise
    #(10.5*CYCLE);
    #(CYCLE*RST_TIME);
    //Start the assignment

    for(i=0;i<10;i=i+1)begin
      a = {$random()}%(1<<N);
      b = {$random()}%(1<<N);
      enable =1;
      #(CYCLE);
    end
    #(100*CYCLE);
    $stop();
end

endmodule

3、仿真结果

在这里插入图片描述

4、总结

 可以发现,运算结果正确,除数和被除数流水输入,结果流水输出。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值