Verilog Coding Tips and Tricks: Synthesisable Verilog code for Division of two binary numbers

Tuesday, November 17, 2015

Synthesisable Verilog code for Division of two binary numbers

For doing division, Verilog has an operator, '/' defined. But this operator has some limitation when it comes to certain synthesis tools such as Xilinx XST. The '/' operator is synthesisable only when the second operand is a power of 2. 

For division of generic numbers Xilinx returns the following error message during synthesis:
Can not simplify operator DIV
 Few year back, I wrote a VHDL function for implementing division which was synthesisable. The design was based on Restoring Division algorithmIn this article, I have converted the same design into Verilog.

Division code:

The size of operands to the division module are defined through a parameter named WIDTH. This way you can use the same code for implementing 8 or 16 or 32 or any sized division. Note that, both the input operands and output have the same size.

module division(A,B,Res);

    //the size of input and output ports of the division module is generic.
    parameter WIDTH = 8;
    //input and output ports.
    input [WIDTH-1:0] A;
    input [WIDTH-1:0] B;
    output [WIDTH-1:0] Res;
    //internal variables    
    reg [WIDTH-1:0] Res = 0;
    reg [WIDTH-1:0] a1,b1;
    reg [WIDTH:0] p1;   
    integer i;

    always@ (or B)
    begin
        //initialize the variables.
        a1 = A;
        b1 = B;
        p1= 0;
        for(i=0;< WIDTH;i=i+1)    begin //start the for loop
            p1 = {p1[WIDTH-2:0],a1[WIDTH-1]};
            a1[WIDTH-1:1] = a1[WIDTH-2:0];
            p1 = p1-b1;
            if(p1[WIDTH-1] == 1)    begin
                a1[0] = 0;
                p1 = p1 + b1;   end
            else
                a1[0] = 1;
        end
        Res = a1;   
    end 

endmodule

Testbench code:

module tb_division;
    parameter WIDTH = 8;
    // Inputs
    reg [WIDTH-1:0] A;
    reg [WIDTH-1:0] B;
    // Outputs
    wire [WIDTH-1:0] Res;

    // Instantiate the division module (UUT)
    division #(WIDTH) uut (
        .A(A), 
        .B(B), 
        .Res(Res)
    );

    initial begin
        // Initialize Inputs and wait for 100 ns
        A = 0;  B = 0;  #100;  //Undefined inputs
        //Apply each set of inputs and wait for 100 ns.
        A = 100;    B = 10; #100;
        A = 200;    B = 40; #100;
        A = 90; B = 9;  #100;
        A = 70; B = 10; #100;
        A = 16; B = 3;  #100;
        A = 255;    B = 5;  #100;
    end
      
endmodule

Simulation Waveform:

The codes were simulated in Xilinx ISE 13.1 to get the following waveform.



Synthesis Results:

The design was synthesised for Virtex 4 fpga and a maximum combinational path delay of 20 ns was obtained for 8 bit division.


6 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. the testbech simulation is not happening for this code , what to be done???

    ReplyDelete
  4. is this code only for A > B ?

    ReplyDelete
  5. Hi, what if we increase the bit width of input to 32 bits.. in your opinion what will be the new propagation delay of the circuit, roughly.

    ReplyDelete