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.
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@ (A or B)
begin
//initialize the variables.
a1 = A;
b1 = B;
p1= 0;
for(i=0;i < 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.
For division of generic numbers Xilinx returns the following error message during synthesis:
Can not simplify operator DIVFew year back, I wrote a VHDL function for implementing division which was synthesisable. The design was based on Restoring Division algorithm. In 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@ (A or B)
begin
//initialize the variables.
a1 = A;
b1 = B;
p1= 0;
for(i=0;i < 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.
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeletethe testbech simulation is not happening for this code , what to be done???
ReplyDeleteis this code only for A > B ?
ReplyDeleteseems to be.
Delete