除法器电路的设计思路,列出数学计算的步骤即可进行类比推导(这里以27除5作为示例),分为以下4步:
- 取被除数的高几位数据,位宽需要与除数相同。
- 将被除数高位数据与除数作比较,若前者大于后者,则对应商为1。两者作差得到第一步余数。否则得0,将前者作为余数。
- 将上一步的余数与被除数剩余最高位1bit数据拼接成新的数据,再与除数作比较。可得新的商和余数。
- 重复步骤3,直到被除数最低位数据也参与计算。
以下是一个基于减法的除法器verilog代码。设16bit的A除以8bit的B,求出商与余数。
module division( input wire [15:0] A, input wire [7:0] B, output wire [15:0] result, output wire [15:0] odd ); reg [15:0] a_reg; reg [15:0] b_reg; reg [31:0] tmp_a; reg [31:0] tmp_b; integer i; always@(*) begin a_reg = A; b_reg = B; end always@(*) begin begin tmp_a = {16'b0,a_reg}; tmp_b = {b_reg,16'b0}; for(i=0;i<16;i++)begin tmp_a = tmp_a << 1; if (tmp_a >= tmp_b) begin tmp_a = tmp_a - tmp_b + 1; end else begin tmp_a = tmp_a; end end end end assign odd = tmp_a[31:16]; assign result = tmp_a[15:0]; endmodule
对于16位的无符号除法运算,其商和余数不会超过16bit。因此tmp_a中的高16位为余数,低16位为商。
testbench代码如下:
`timescale 1ns/1ps module tb_division(); reg clk; reg [15:0] A; reg [7:0] B; wire [15:0] result; wire [15:0] odd; initial begin A = 0; B = 0; #100; A = 27; B = 5; end division inst_division (.A(A), .B(B), .result(result), .odd(odd)); endmodule
modelsim仿真结果: