Verilog无符号除法器-流水线实现
Posted 芯青年0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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、总结
可以发现,运算结果正确,除数和被除数流水输入,结果流水输出。
以上是关于Verilog无符号除法器-流水线实现的主要内容,如果未能解决你的问题,请参考以下文章