Verilog无符号除法器-状态机实现
Posted 芯青年0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Verilog无符号除法器-状态机实现相关的知识,希望对你有一定的参考价值。
在FPGA的开发过程当中,常见的加,减,乘都可以直接用对应的符号表示,用时序逻辑实现,而除法的运算不能直接使用" /" 符号,基于当除数为2的幂次方时,可以用简单的移位符号 " >>"实现,当除数任意时,就需要使用额外的IP模块,固定的算法实现了,除法算法分为两类,分别是基于减法操作和基于乘法操作的算法。此处使用基于减法操作实现除法。
1、除法原理
对于位宽为N位的无符号除法,被除数a除以除数b,他们的商和余数一定不会超过N位。除法计算的步骤如下:
- 当信号使能信号为高,将a转换成高N位为0,低N位为a的temp_a;把b转换成高N位为b,低N位为0的temp_b。初始化迭代次数i=0,进入步骤2。
- 当迭代次数i<N时,将temp_a左移一位,末尾补0;否则,结束迭代运算。
- 将左移后的temp_a与b比较,是否大于b,是则temp_a减去temp_b将且加上1,否则继续往下执行,回到步骤2,继续迭代。
- 将输出使能 信号置1,商为temp_a的高N位,余数为temp_a的低N位。
将上述的四个步骤分别用状态机实现。
2、除法代码
/*******************************************************************
* ------------------- Module Specification ------------------------
*
* * Name :divider
*
* * Function :无符号除法,状态机实现
优点:可以更给数据位宽来实现不同位宽的除法运算,代码复用性高
缺点,运算速度较慢,
*
* * Input :
*
* * Output :
*
* * author :彧芯
*
* * Edit time:2021/04/25/17:01:56
*
* *************************************************************/
module divider #(
parameter N=8
)(
input clk,
input rst,
input enable,
input [N-1:0] a,
input [N-1:0] b,
output reg [N-1:0] yshang,
output reg [N-1:0] yyushu,
output reg done
);
parameter S=(N<<1);
reg[N-1:0] tempa;
reg[N-1:0] tempb;
reg[S-1:0] temp_a;
reg[S-1:0] temp_b;
reg [5:0] status;
parameter s_idle = 6'b000000;
parameter s_init = 6'b000001;
parameter s_calc1 = 6'b000010;
parameter s_calc2 = 6'b000100;
parameter s_done = 6'b001000;
reg [N-1:0] i;
always @(posedge clk)
begin
if(rst)
begin
i <= 0;
tempa <= 0;
tempb <= 1;
yshang <= 0;
yyushu <= 1;
done <= 1'b0;
temp_a <= 0;
temp_b <= 0;
status <= s_idle;
end
else
begin
case (status)
s_idle:
begin
if(enable)
begin
tempa <= a;
tempb <= b;
status <= s_init;
end
else
begin
i <= 0;
tempa <= 0;
tempb <= 1;
yshang <= 0;
yyushu <= 1;
done <= 1'b0;
status <= s_idle;
end
end
s_init:
begin
temp_a <= {{N{1'b0}},tempa}; //此处0的个数和数据位宽一样
temp_b <= {tempb,{N{1'b0}}};
status <= s_calc1;
end
s_calc1:
begin
if(i < N)
begin
temp_a <= {temp_a[S-2:0],1'b0};
status <= s_calc2;
end
else
begin
status <= s_done;
end
end
s_calc2:
begin
if(temp_a[S-1:N] >= temp_b[S-1:N])
begin
temp_a <= temp_a - temp_b + 1'b1;
end
else
begin
temp_a <= temp_a;
end
i <= i + 1'b1;
status <= s_calc1;
end
s_done:
begin
yshang <= temp_a[N-1:0];
yyushu <= temp_a[S-1:N];
done <= 1'b1;
status <= s_idle;
end
default:
begin
status <= s_idle;
end
endcase
end
end
endmodule
3、测试代码及结果
`timescale 1 ns/1 ns
module tb();
//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 = 8;
//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#(
.N( N )
)u_divider(
.clk ( clk ),
.rst ( rst ),
.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,j;
integer wrong_timer=0;
integer txt_file;
initial begin
#1;
//initialise
enable =0;
a = 0;
b = 0;
#(10.5*CYCLE);
#(CYCLE*RST_TIME);
//Start the assignment
enable =1;
a = 201;
b = 20;
#(CYCLE);
enable =0;
#(30*CYCLE);
enable =1;
a = 101;
b = 13;
#(CYCLE);
enable =0;
#(30*CYCLE);
enable =1;
a = 34;
b = 3;
#(CYCLE);
enable =0;
#(30*CYCLE);
enable =1;
a = 34;
b = 100;
#(CYCLE);
enable =0;
#(30*CYCLE);
$stop();
end
endmodule
仿真结果如下:
4、总结
除法器模块是FPGA应用中应用最广泛之一,该本模块采用状态机实现了位宽可定义的除法器模块,通用性较好。缺点是采用状态机实现,速度较慢,算是面积换速度的一个例子,想要实现快速的除法器,可用流水线的方式实现,后续更新。
另外,就有无符号而言,实现的是无符号除法,有符号除法在获取到除数和被除数后,转化成无符号实现即可。
以上是关于Verilog无符号除法器-状态机实现的主要内容,如果未能解决你的问题,请参考以下文章