Question:
I need a Verilog behavioral model (verilog behavioral code) for:
(1) signed and Unsigned 32-bit multiplication
(2) signed and unsigned 32-bit division
(3) It should have two 32bit inputs and the result should be 64bits. Both the multiply and divide need to handle signed numbers as well as unsigned.
Solution:
OK, as promised, here it is. The "sign" input determines whether signs should be taken into consideration. The rest is straightforward-- loops 32
times to do the shift and addition/subtraction in order to perform the multiply/division. Two's complement is assumed(ie, to negate a number, invert
all bits and add 1).
You may tailor it as needed for your own use.
--- CUT HERE ---
// Unsigned/Signed multiplication based on Patterson and Hennessy's algorithm.
// Copyrighted 2002 by studboy-ga / Google Answers. All rights reserved.
// Description: Calculates product. The "sign" input determines whether
// signs (two's complement) should be taken into consideration.
module multiply(ready,product,multiplier,multiplicand,sign,clk);
input clk;
input sign;
input [31:0] multiplier, multiplicand;
output [63:0] product;
output ready;
reg [63:0] product, product_temp;
reg [31:0] multiplier_copy;
reg [63:0] multiplicand_copy;
reg negative_output;
reg [5:0] bit;
wire ready = !bit;
initial bit = 0;
initial negative_output = 0;
always @( posedge clk )
if( ready ) begin
bit = 6'd32;
product = 0;
product_temp = 0;
multiplicand_copy = (!sign || !multiplicand[31]) ? { 32'd0, multiplicand } : { 32'd0, ~multiplicand + 1'b1};
multiplier_copy = (!sign || !multiplier[31]) ? multiplier : ~multiplier + 1'b1;
negative_output = sign && ((multiplier[31] && !multiplicand[31]) || (!multiplier[31] && multiplicand[31]));
end
else if ( bit > 0 ) begin
if( multiplier_copy[0] == 1'b1 ) product_temp = product_temp +
multiplicand_copy;
product = (!negative_output) ? product_temp : ~product_temp + 1'b1;
multiplier_copy = multiplier_copy >> 1;
multiplicand_copy = multiplicand_copy << 1;
bit = bit - 1'b1;
end
endmodule
// Unsigned/Signed division based on Patterson and Hennessy's algorithm.
// Copyrighted 2002 by studboy-ga / Google Answers. All rights reserved.
// Description: Calculates quotient. The "sign" input determines whether
// signs (two's complement) should be taken into consideration.
module divide(ready,quotient,remainder,dividend,divider,sign,clk);
input clk;
input sign;
input [31:0] dividend, divider;
output [31:0] quotient, remainder;
output ready;
reg [31:0] quotient, quotient_temp;
reg [63:0] dividend_copy, divider_copy, diff;
reg negative_output;
wire [31:0] remainder = (!negative_output) ? dividend_copy[31:0] : ~dividend_copy[31:0] + 1'b1;
reg [5:0] bit;
wire ready = !bit;
initial bit = 0;
initial negative_output = 0;
always @( posedge clk )
if( ready ) begin
bit = 6'd32;
quotient = 0;
quotient_temp = 0;
dividend_copy = (!sign || !dividend[31]) ? {32'd0,dividend} : {32'd0,~dividend + 1'b1};
divider_copy = (!sign || !divider[31]) ? {1'b0,divider,31'd0} : {1'b0,~divider + 1'b1,31'd0};
negative_output = sign && ((divider[31] && !dividend[31]) || (!divider[31] && dividend[31]));
end
else if ( bit > 0 ) begin
diff = dividend_copy - divider_copy;
quotient_temp = quotient_temp << 1;
if( !diff[63] ) begin
dividend_copy = diff;
quotient_temp[0] = 1'd1;
end
quotient = (!negative_output) ? quotient_temp : ~quotient_temp + 1'b1;
divider_copy = divider_copy >> 1;
bit = bit - 1'b1;
end
endmodule
Result for divider.v module:
I test the module "divide.v", the wave as follows:
NOTE : Look at the picture, you will find that "dividend / divider" uses the timer equaled to 32*clk; so, I think, the codes as below is not good for
the high-perfermance design.
--------------------------------------------------------------------------------------------------------
(codes Link From : http://answers.google.com/answers/threadview/id/109219.html)
Also, Please take a look at:
http://www.ece.lsu.edu/ee3755/2002/l07.html
and
http://www.cecs.csulb.edu/~rallison/pdf/440pdf/440_Verilog_Lab2_Fa02.pdf