From 271f19f13fb69f48cd8ead479fe76579ac63034b Mon Sep 17 00:00:00 2001 From: Imants Pulkstenis Date: Wed, 31 Jul 2019 01:09:40 +0300 Subject: [PATCH] add save file(unfinished) need to rewrite FSM to Pipeline --- multiply.v | 31 +++++----- summ.v | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++ summ_tb.v | 113 ++++++++++++++++++++++++++++++++++ 3 files changed, 302 insertions(+), 17 deletions(-) create mode 100644 summ.v create mode 100644 summ_tb.v diff --git a/multiply.v b/multiply.v index 1569d9c..3871e87 100644 --- a/multiply.v +++ b/multiply.v @@ -19,45 +19,42 @@ module multiply #( 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 [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 [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 + if (input_a[17:0] == 0 || input_b[17:0] == 0) begin // if one of numbers are 0 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_multiply <= input_a[17:0] * input_b[17:0]; // multiply mantisa + reg_summ1 <= input_a[25:18] + input_b[25:18] - 8'h7F ; // add exponents reg_summ2 <= input_a[25:18] + input_b[25:18] - 8'h80 ; - reg_sign <= input_a[26] ^ input_b[26]; + reg_sign <= input_a[26] ^ input_b[26]; // determine sign of resulting number 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 + 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 comparison and testbench end -assign underflow = reg_summ3 - //(input_a[25:18] + input_b[25:18]) - < 8'h7F - ? 1'b1 : 1'b0 - ; +assign underflow = reg_summ3 < 8'h7F + ? 1'b1 : 1'b0 ; assign output_q = reg_multiply[35] ? diff --git a/summ.v b/summ.v new file mode 100644 index 0000000..6a6d2d3 --- /dev/null +++ b/summ.v @@ -0,0 +1,175 @@ +//////////////////////////////////////////// +// +// | Sign | Exponent | Mantissa | +// | 1bit | 8bits | 18bits | +// +// 2^0 => Exponent = 'd127 = 'h7f +// +// Mantissa = [ ( 1-2^(-126) ) ; 0.5 ] +// +//////////////////////////////////////////// + +module summ #( + parameter + SIGN_WIDTH = 1, + EXPONENT_WIDTH = 8, + MANTISSA_WIDTH = 18, + SIZE = 2 // size for for registers FSM +) +( + input clk, + input [ 26 :0] input_a, + input [ 26 :0] input_b, + input start, + + output [ 26 :0] output_q, + output done, + output overflow, + output underflow +); + +//-------------Internal Constants--------------------------- + +localparam [SIZE-1 :0] IDLE = 'h0, + SHIFT = 'h1, + SUMM = 'h2, + NORM = 'h3; + +reg [SIZE-1:0] r_state=IDLE, + r_next=IDLE; + +reg [ 18 :0 ] r_large_mantissa1 = 'b0, + r_small_mantissa1 = 'b0, + r_large_mantissa2 = 'b0, + r_small_mantissa2 = 'b0, + r_large_mantissa3 = 'b0, + r_small_mantissa3 = 'b0, + r_large_mantissa4 = 'b0, + r_small_mantissa4 = 'b0; + +reg [ 7 :0 ] r_large_exponent1 = 'b0, + r_large_exponent2 = 'b0, + r_large_exponent3 = 'b0, + r_large_exponent4 = 'b0; + +reg r_large_sign = 'b0, + r_small_sign = 'b0; + +reg [ 7 :0 ] r_delta_exponent = 'b0; + +reg r_done = 'b0; +reg r_overflow = 'b0; +reg r_underflow = 'b0; + +//---------state register sequential always block----------- + +always @(posedge clk ) begin + r_state <= r_next; +end + +//----next state & outputs, combinational always block------ + +always@(posedge clk) begin + case(r_state) + IDLE : + begin + r_done <= 'b0; + if (start == 1'b1) + begin + if (input_a[25:18] > input_b[25:18]) + begin + r_large_mantissa1 <= input_a[17:0]; + r_small_mantissa1 <= input_b[17:0]; + r_large_exponent1 <= input_a[25:18]; + //r_small_exponent <= input_b[25:18]; + r_large_sign <= input_a[26]; + r_small_sign <= input_a[26]; + r_delta_exponent <= input_a[25:18] - input_b[25:18]; + r_next <= SHIFT; + end + else if (input_a[25:18] < input_b[25:18]) + begin + r_large_mantissa1 <= input_b[17:0]; + r_small_mantissa1 <= input_a[17:0]; + r_large_exponent1 <= input_b[25:18]; + //r_small_exponent <= input_a[25:18]; + r_large_sign <= input_b[26]; + r_small_sign <= input_a[26]; + r_delta_exponent <= input_b[25:18] - input_a[25:18]; + r_next <= SHIFT; + end + else if (input_a[25:18] == input_b[25:18]) + begin + r_large_mantissa1 <= input_a[17:0]; + r_small_mantissa1 <= input_b[17:0]; + r_large_exponent1 <= input_a[25:18]; + //r_small_exponent <= input_b[25:18]; + r_large_sign <= input_a[26]; + r_small_sign <= input_a[26]; + r_next <= SUMM; + end + end + end + SHIFT : + begin + r_next <= SUMM; + case(r_delta_exponent) + 'd1 : r_small_mantissa2 <= r_small_mantissa1 >> 1; + 'd2 : r_small_mantissa2 <= r_small_mantissa1 >> 2; + 'd3 : r_small_mantissa2 <= r_small_mantissa1 >> 3; + 'd4 : r_small_mantissa2 <= r_small_mantissa1 >> 4; + 'd5 : r_small_mantissa2 <= r_small_mantissa1 >> 5; + 'd6 : r_small_mantissa2 <= r_small_mantissa1 >> 6; + 'd7 : r_small_mantissa2 <= r_small_mantissa1 >> 7; + 'd8 : r_small_mantissa2 <= r_small_mantissa1 >> 8; + 'd9 : r_small_mantissa2 <= r_small_mantissa1 >> 9; + 'd10 : r_small_mantissa2 <= r_small_mantissa1 >> 10; + 'd11 : r_small_mantissa2 <= r_small_mantissa1 >> 11; + 'd12 : r_small_mantissa2 <= r_small_mantissa1 >> 12; + 'd13 : r_small_mantissa2 <= r_small_mantissa1 >> 13; + 'd14 : r_small_mantissa2 <= r_small_mantissa1 >> 14; + 'd15 : r_small_mantissa2 <= r_small_mantissa1 >> 15; + 'd16 : r_small_mantissa2 <= r_small_mantissa1 >> 16; + 'd17 : r_small_mantissa2 <= r_small_mantissa1 >> 17; + default : r_small_mantissa2 <= 0; // if number is to small result is larger number + endcase + end + SUMM : + begin + r_next <= NORM; + case(r_large_sign == r_small_sign) + 1'b1 : r_large_mantissa3 <= r_large_mantissa2 + r_small_mantissa2; + 1'b0 : r_large_mantissa3 <= r_large_mantissa2 - r_small_mantissa2; + endcase + end + NORM : + begin + r_next <= IDLE; + r_done <= 'b1; + if (r_large_mantissa[18]) + begin + r_large_mantissa4 <= r_large_mantissa3 >> 1; + if (r_large_exponent < 255) + begin r_large_exponent <= r_large_exponent + 1; end + else + begin r_overflow <= 1; end + end + else if (r_large_mantissa[17]) + begin + r_large_mantissa4 <= r_large_mantissa3 << 1; + if (r_large_exponent > 0) + begin r_large_exponent <= r_large_exponent - 1; end + else + begin r_underflow <= 1; end + end + end + default : r_next <= IDLE; // on error + endcase +end + +//-------------------- assignning combionational logic---------------------------- + +assign done = r_done; +assign output_q = { r_large_sign, r_large_exponent4[7:0], r_large_mantissa4[17:0] }; + +endmodule \ No newline at end of file diff --git a/summ_tb.v b/summ_tb.v new file mode 100644 index 0000000..cf90fe6 --- /dev/null +++ b/summ_tb.v @@ -0,0 +1,113 @@ +//////////////////////////////////////////// +// +// | 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 "summ.v" + +module summ_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; + +reg r_start = 0; + + +initial begin + + #100 + reg_input_a = 27'h5FE0000; + reg_input_b = 27'h1FE0000; + r_start = 1; + #1 r_start = 0; + + #100 + reg_input_a = 27'h13E8083; + reg_input_b = 27'h13E8083; + r_start = 1; + #1 r_start = 0; + + #100 + reg_input_a = 27'h0E2194D; + reg_input_b = 27'h0E2194D; + r_start = 1; + #1 r_start = 0; + + #100 + reg_input_a = 27'h20A0000; + reg_input_b = 27'h0E2194D; + r_start = 1; + #1 r_start = 0; + + #100 + reg_input_a = 27'h20A0000; + reg_input_b = 27'h2020000; + r_start = 1; + #1 r_start = 0; + + #100 + reg_input_a = 27'h226A800; + reg_input_b = 27'h6270C00; + r_start = 1; + #1 r_start = 0; + + #100 + reg_input_a = 27'h64E05F8; + reg_input_b = 27'h1FE0000; + r_start = 1; + #1 r_start = 0; + + #100 + reg_input_a = 27'h64A05F8; + r_start = 1; + #1 r_start = 0; + + #100 + reg_input_b = 27'h64A05F8; + r_start = 1; + #1 r_start = 0; + + + #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 + +summ Test_Unit( + .clk(clk), + .input_a(reg_input_a), + .input_b(reg_input_b), + .start(r_start), + .output_q(), + .underflow() +); + + +endmodule \ No newline at end of file