问题
给定8bit无符号整数a,b,求a除以b(b不为0)的商q和余数r。
方法
第一种能够想到的方法,就是a一直减去b,一直减到差小于b为止,此时,这个最终的差即为余数,而减去b的次数即为商。然而,这个方法在商比较大的时候需要许多个周期才能得到结果,因此并不吸引人。
另一种方法如下图所示
步骤如下:
1.令a_r={N’d0,a},b_r={b,N’d0}
2.在每个时钟周期,将a_r左移一位,末尾补0,然后与b_r比较;若大于b_r,则a_r=a_r-b_r+1,否则继续比较
3.移位N次后,a_r的高N位为余数,低N位为商。
可以看到,该方法在求商和余数时,所需的时钟周期数恒为N(N为a,b的位宽),因此,相对于前一种方法,在商比较大的时候,具有明显的优势。
RTL代码实现
设计文件(以8bit无符号整数除法为例)
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/03/18 21:37:17
// Design Name:
// Module Name: demo
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module demo
(
input logic clk,
input logic rst_n,
input logic [7:0] a,
input logic [7:0] b,
input logic valid,
output logic [7:0] q,
output logic [7:0] r,
output logic ready
);
logic [15:0] a_r;
logic [15:0] b_r;
logic [31:0] cnt; //计数器
logic busy;
logic [15:0] a_shift;
assign a_shift={a_r[14:0],1'b0}; //a_r左移一位
//
always_ff@(posedge clk,negedge rst_n)
if(~rst_n)
a_r<=0;
else if(valid)
a_r<={8'd0,a};
else if(busy)
begin
if(a_shift>b_r)
a_r<=a_shift-b_r+1;
else
a_r<=a_shift;
end
//busy
always_ff@(posedge clk,negedge rst_n)
if(~rst_n)
busy<=0;
else if(valid)
busy<=1;
else if(cnt==8-1)
busy<=0;
//cnt
always_ff@(posedge clk,negedge rst_n)
if(~rst_n)
cnt<=0;
else if(busy)
cnt<=cnt+1;
else
cnt<=0;
//b_r
always_ff@(posedge clk,negedge rst_n)
if(~rst_n)
b_r<=0;
else if(valid)
b_r<={b,8'd0};
//ready
always_ff@(posedge clk,negedge rst_n)
if(~rst_n)
ready<=0;
else if(valid)
ready<=0;
else if(cnt==8-1&&busy)
ready<=1;
//
assign r=a_r[15:8];
assign q=a_r[7:0];
endmodule
测试平台文件:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/03/18 21:45:51
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module test;
logic clk;
logic rst_n;
logic [7:0] a;
logic [7:0] b;
logic valid;
logic [7:0] q;
logic [7:0] r;
logic ready;
initial begin
clk=0;
forever begin
#5 clk=~clk;
end
end
initial
begin
rst_n=0;
#100
rst_n=1;
end
//
initial
begin
a=0;
b=0;
valid=0;
#100
a=125;
b=23;
valid=1;
#10
valid=0;
end
demo U
(
.*
// input logic clk,
// input logic rst_n,
// input logic [7:0] a,
// input logic [7:0] b,
// input logic valid,
// output logic [7:0] q,
// output logic [7:0] r,
// output logic ready
);
endmodule
仿真结果
如图所示 ,a为8bit的125,b为8bit的23,a除以b,商为5,余数为10,仿真波形和正确结果一致,功能正确!