Add Verilog floating point multiplication

This commit is contained in:
Imants Pulkstenis
2019-07-23 16:28:59 +03:00
parent 033bb04bf6
commit 343026c418
3 changed files with 163 additions and 2 deletions
+2 -2
View File
@@ -9,7 +9,7 @@
%
%
clear all;
x = 4/320 ; % number to convert
x = -780*680 * 0.5^1; % number to convert
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
exponent = 127;
%
@@ -57,7 +57,7 @@ end
% Mantissa
x_ufi = ufi(x_new,19,18);
temp = [x_ufi.bin];
for n=18:-1:0
for n=17:-1:0
string_bin = [string_bin, temp(end-n)];
end
string_hex = dec2hex(bin2dec(string_bin),7);
+69
View File
@@ -0,0 +1,69 @@
////////////////////////////////////////////
//
// | Sign | Exponent | Mantissa |
// | 1bit | 8bits | 18bits |
//
// 2^0 => Exponent = 'd127 = 'h7f
//
// Mantissa = [ ( 1-2^(-126) ) ; 0.5 ]
//
////////////////////////////////////////////
module multiply #(
parameter
SIGN_WIDTH = 1,
EXPONENT_WIDTH = 8,
MANTISSA_WIDTH = 18
)
(
input clk,
input [ 26 :0] input_a,
input [ 26 :0] input_b,
output [ 26 :0] output_q,
output underflow
);
reg [35 : 0 ] reg_multiply = 0; // for mantissa
reg [8 : 0 ] reg_summ1 = 0; // for exponent
reg [8 : 0 ] reg_summ2 = 0; // for exponent if reg_multiply smaler then 0.5(decimal)
reg reg_sign = 0; // for sign
reg [17 : 0 ] reg_mantissa1 = 0;
reg [17 : 0 ] reg_mantissa2 = 0; // if reg_multiply smaler then 0.5(decimal)
reg [8 : 0 ] reg_summ3 = 0; // use in comarison and testbench
always@(posedge clk) begin
if (input_a[17:0] == 0 || input_b[17:0] == 0) begin
reg_multiply <= 0;
reg_summ1 <= 0 ;
reg_summ2 <= 0 ;
reg_sign <= 0;
end
else begin
reg_multiply <= input_a[17:0] * input_b[17:0];
reg_summ1 <= input_a[25:18] + input_b[25:18] - 8'h7F ;
reg_summ2 <= input_a[25:18] + input_b[25:18] - 8'h80 ;
reg_sign <= input_a[26] ^ input_b[26];
end
end
always@* begin
reg_mantissa1 <= reg_multiply >> 18 ;
reg_mantissa2 <= reg_multiply >> 17 ; // if reg_multiply smaler then 0.5(decimal)
reg_summ3 <= input_a[25:18] + input_b[25:18]; // use in comarison and testbench
end
assign underflow = reg_summ3
//(input_a[25:18] + input_b[25:18])
< 8'h7F
? 1'b1 : 1'b0
;
assign output_q = reg_multiply[35] ?
{ reg_sign , reg_summ1[7:0] , reg_mantissa1[17:0] }
:
{ reg_sign , reg_summ2[7:0] , reg_mantissa2[17:0] }
;
endmodule
+92
View File
@@ -0,0 +1,92 @@
////////////////////////////////////////////
//
// | Sign | Exponent | Mantissa |
// | 1bit | 8bits | 18bits |
//
// 2^0 => Exponent = 'd127 = 'h7f
//
// Mantissa = [ ( 1-2^(-126) ) ; 0.5 ]
//
////////////////////////////////////////////
// 100MHz clock on Basys3 -> 10ns period
// 50% duty cycle 5ns HIGH and 5ns LOW
//`timescale [time unit] / [time precision]
`timescale 10 ns / 1ns
`include "multiply.v"
module multiply_tb ();
// 50% duty cycle clock
reg clk = 1'b1;
always #0.5 clk <= ~clk;
reg [26 : 0 ] reg_input_a = 0;
reg [26 : 0 ] reg_input_b = 0;
initial begin
#100
reg_input_a = 27'h5FE0000;
reg_input_b = 27'h1FE0000;
#100
reg_input_a = 27'h13E8083;
reg_input_b = 27'h13E8083;
#100
reg_input_a = 27'h0E2194D;
reg_input_b = 27'h0E2194D;
#100
reg_input_a = 27'h20A0000;
reg_input_b = 27'h0E2194D;
#100
reg_input_a = 27'h20A0000;
reg_input_b = 27'h2020000;
#100
reg_input_a = 27'h226A800;
reg_input_b = 27'h6270C00;
#100
reg_input_a = 27'h64E05F8;
reg_input_b = 27'h1FE0000;
#100
reg_input_a = 27'h64A05F8;
#100
reg_input_b = 27'h64A05F8;
#1000
$display(" ");
$display("Use this command to open timing diagram:");
$display("gtkwave -f wave.vcd");
$display("----------------------------------------------");
$finish();
end
initial
begin
$display(" ");
$display("----------------------------------------------");
$display(" Starting Testbench...");
$dumpfile("wave.vcd");
$dumpvars(0);
end
multiply Test_Unit(
.clk(clk),
.input_a(reg_input_a),
.input_b(reg_input_b),
.output_q(),
.underflow()
);
endmodule