From 8a1036169f1b169c9d61b2dfbbe821066c943725 Mon Sep 17 00:00:00 2001 From: XiaoanHe <118478606+XiaoanHe@users.noreply.github.com> Date: Tue, 14 Feb 2023 18:36:57 +0000 Subject: [PATCH] Posit Multiplier --- .../Core_Arithmetic/Arithmetic_tb.sv | 125 ++++++++++++++++++ Individual_Project/Leading_Bit_Detector.sv | 16 +-- .../Posit_Multiplier/Leading_Bit_Detector.sv | 60 +++++++++ .../Posit_Multiplier/Posit_Extraction.sv | 70 ++++++++++ .../Posit_Multiplier/Posit_Multiplier.sv | 99 ++++++++++++++ .../Posit_Multiplier/Posit_Multiplier_tb.sv | 120 +++++++++++++++++ 6 files changed, 478 insertions(+), 12 deletions(-) create mode 100644 Individual_Project/Core_Arithmetic/Arithmetic_tb.sv create mode 100644 Individual_Project/Posit_Multiplier/Leading_Bit_Detector.sv create mode 100644 Individual_Project/Posit_Multiplier/Posit_Extraction.sv create mode 100644 Individual_Project/Posit_Multiplier/Posit_Multiplier.sv create mode 100644 Individual_Project/Posit_Multiplier/Posit_Multiplier_tb.sv diff --git a/Individual_Project/Core_Arithmetic/Arithmetic_tb.sv b/Individual_Project/Core_Arithmetic/Arithmetic_tb.sv new file mode 100644 index 0000000..66c94da --- /dev/null +++ b/Individual_Project/Core_Arithmetic/Arithmetic_tb.sv @@ -0,0 +1,125 @@ +///////////////////////////////////////////////////////////////////// +// Design unit: Arithmetic Testbench +// : +// File name : Arithmetic_tb.sv +// : +// Description: Test Posit Adder Arithmetic +// : +// Limitations: None +// : +// System : SystemVerilog IEEE 1800-2005 +// : +// Author : Xiaoan He (Jasper) +// : xh2g20@ecs.soton.ac.uk +// +// Revision : Version 1.0 23/11/2022 +///////////////////////////////////////////////////////////////////// +function [31:0] log2; +input reg [31:0] value; + begin + value = value-1; + for (log2=0; value>0; log2=log2+1) + value = value>>1; + end +endfunction + +module Arithmetic_tb; +parameter N = 8, RS = log2(N), ES = 3; + +//input logic +logic signed [N-2:0] InRemain1, InRemain2; +logic Sign1, Sign2; +logic signed [RS:0] RegimeValue1, RegimeValue2; +logic [ES-1:0] Exponent1, Exponent2; +logic [N-ES+2:0] Mantissa1, Mantissa2; + +//output logic +logic [N-1:0] E_diff; +logic [N:0] Add_Mant; +logic signed [ES+RS:0] LE_O; +logic [ES-1:0] E_O; +logic signed [RS:0] R_O; +logic signed [N-1:0] Result; +logic signed [N-1:0] out; + +Alignment #(.N(N), .ES(ES)) alignment_tb (.*); + +initial + begin + #10ns + InRemain1 = 7'b0_0000000; + InRemain2 = 7'b0_0000000; + Sign1 = 0; + Sign2 = 0; + RegimeValue1 = '0; + RegimeValue2 = '0; + Exponent1 = '0; + Exponent2 = '0; + Mantissa1 = '0; + Mantissa2 = '0; + + #50ns // 1+0.625 ~= 1.5 + InRemain1 = 7'b10_000_00; + InRemain2 = 7'b01_111_01; + Sign1 = 0; + Sign2 = 0; + RegimeValue1 = 0; + RegimeValue2 = -1; + Exponent1 = 3'b000; + Exponent2 = 3'b111; + Mantissa1 = 8'b10000000; + Mantissa2 = 8'b10100000; + + + + #50ns // 1+ 0.875 ~= 2 + InRemain1 = 7'b10_000_00; + InRemain2 = 7'b01_111_11; + Sign1 = 0; + Sign2 = 0; + RegimeValue1 = 0; + RegimeValue2 = -1; + Exponent1 = 3'b000; + Exponent2 = 3'b111; + Mantissa1 = 8'b10000000; + Mantissa2 = 8'b11100000; + + #50ns // 524288 + 12288 ~= 524288 + InRemain1 = 7'b1110_011; + InRemain2 = 7'b110_101_1; + Sign1 = 0; + Sign2 = 0; + RegimeValue1 = 2; + RegimeValue2 = 1; + Exponent1 = 3'b011; + Exponent2 = 3'b101; + Mantissa1 = 8'b10000000; + Mantissa2 = 8'b11000000; + + #50ns // 1+(-0.25) + InRemain1 = 7'b10_000_00; + InRemain2 = 7'b01_110_00; + Sign1 = 0; + Sign2 = 1; + RegimeValue1 = 0; + RegimeValue2 = -1; + Exponent1 = 3'b000; + Exponent2 = 3'b110; + Mantissa1 = 8'b10000000; + Mantissa2 = 8'b10000000; + + #50ns // 32768-24576 + InRemain1 = 7'b110_111_0; + InRemain2 = 7'b110_110_1; + Sign1 = 0; + Sign2 = 1; + RegimeValue1 = 1; + RegimeValue2 = 1; + Exponent1 = 3'b111; + Exponent2 = 3'b110; + Mantissa1 = 8'b10000000; + Mantissa2 = 8'b11000000; + + + end +endmodule \ No newline at end of file diff --git a/Individual_Project/Leading_Bit_Detector.sv b/Individual_Project/Leading_Bit_Detector.sv index 807a5d0..75aee70 100644 --- a/Individual_Project/Leading_Bit_Detector.sv +++ b/Individual_Project/Leading_Bit_Detector.sv @@ -16,31 +16,23 @@ // Revision : Version 1.0 21/11/2022 ///////////////////////////////////////////////////////////////////// -module Leading_Bit_Detector #( parameter N = 8, parameter ES = 3, parameter RS = log2(N)) +module Leading_Bit_Detector #( parameter N = 8, parameter ES = 3, parameter RS = $clog2(N)) ( input logic signed [N-2:0] InRemain, output logic signed [RS:0] EndPosition, output logic RegimeCheck ); -function [31:0] log2; -input reg [31:0] value; - begin - value = value-1; - for (log2=0; value>0; log2=log2+1) - value = value>>1; - end -endfunction - //logic RegimeCheck; int i; +logic signed [RS:0] EP; always_comb begin RegimeCheck = InRemain[N-2]; //the MSB of InRemain (In[6])is the number to be checked - EndPosition = '0; - EndPosition = EndPosition + 1'b1; // initial EP starts from InRemain[1] as InRemain[0] is RC + EP = '0; + EndPosition = EP + 1'b1; // initial EP starts from InRemain[1] as InRemain[0] is RC for(i = 1; i < (N-2); i++) begin diff --git a/Individual_Project/Posit_Multiplier/Leading_Bit_Detector.sv b/Individual_Project/Posit_Multiplier/Leading_Bit_Detector.sv new file mode 100644 index 0000000..807a5d0 --- /dev/null +++ b/Individual_Project/Posit_Multiplier/Leading_Bit_Detector.sv @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////// +// Design unit: Leading Bit Detector +// : +// File name : Leading_Bit_Detector.sv +// : +// Description: Given the first bit of the regime bit +// find the first bit different from it +// : +// Limitations: None +// : +// System : SystemVerilog IEEE 1800-2005 +// : +// Author : Xiaoan He (Jasper) +// : xh2g20@ecs.soton.ac.uk +// +// Revision : Version 1.0 21/11/2022 +///////////////////////////////////////////////////////////////////// + +module Leading_Bit_Detector #( parameter N = 8, parameter ES = 3, parameter RS = log2(N)) +( + input logic signed [N-2:0] InRemain, + output logic signed [RS:0] EndPosition, + output logic RegimeCheck +); + +function [31:0] log2; +input reg [31:0] value; + begin + value = value-1; + for (log2=0; value>0; log2=log2+1) + value = value>>1; + end +endfunction + +//logic RegimeCheck; +int i; + +always_comb +begin + RegimeCheck = InRemain[N-2]; //the MSB of InRemain (In[6])is the number to be checked + + EndPosition = '0; + EndPosition = EndPosition + 1'b1; // initial EP starts from InRemain[1] as InRemain[0] is RC + + for(i = 1; i < (N-2); i++) + begin + /* + compareing MSB of InRemain to the follwing bits + until the different bit turns up + */ + if (RegimeCheck == InRemain[((N-2)-i)]) + //begin + EndPosition = EndPosition + 1'b1; + //end + else + break; + end + +end +endmodule \ No newline at end of file diff --git a/Individual_Project/Posit_Multiplier/Posit_Extraction.sv b/Individual_Project/Posit_Multiplier/Posit_Extraction.sv new file mode 100644 index 0000000..e673bf4 --- /dev/null +++ b/Individual_Project/Posit_Multiplier/Posit_Extraction.sv @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////// +// Design unit: DataExtraction +// : +// File name : Posit_Extraction.sv +// : +// Description: Extracting posit element from n bits binary number +// : +// Limitations: None +// : +// System : SystemVerilog IEEE 1800-2005 +// : +// Author : Xiaoan He (Jasper) +// : xh2g20@ecs.soton.ac.uk +// +// Revision : Version 1.0 22/11/2022 +///////////////////////////////////////////////////////////////////// + +// `ifndef log_2 +// `define log_2 +// `include "log_2.sv" + +module Data_Extraction #( parameter N = 8, parameter ES = 3, parameter RS = $clog2(N)) +( + input logic signed [N-1:0] In, + output logic signed Sign, + output logic signed [RS+1:0] RegimeValue, + output logic [ES-1:0] Exponent, + output logic [N-ES+2:0] Mantissa, + output logic signed [N-2:0] InRemain +); + + +logic RegimeCheck; +logic signed [RS:0] EndPosition; +logic signed [N-2:0] ShiftedRemain; +logic [(N-ES+2)-1-(N-ES-2)-1:0] ZERO = '0; +int i; +Leading_Bit_Detector #(.N(N), .ES(ES)) LBD1 (.*); + +always_comb +begin + // Sign Bit Extraction + Sign = In[N-1]; + + // if sign bit is 1, then 2's compliment + if (Sign) + InRemain = -In[N-2:0]; + else + InRemain = In[N-2:0]; + + + // Regime Bits Extraction + /* + There is a Leading_Bit_Detector defined before the always_comb block + which takes the input without sign bit as module input and outputs + EndPosition of Regime Bits and RegimeCheck which is the 1st bit of Regime bits + */ + if(RegimeCheck == 1'b1) + RegimeValue = EndPosition - 1'b1; + else if (RegimeCheck == 1'b0) + RegimeValue = -EndPosition; + + //Exponent Bits Extraction + ShiftedRemain = InRemain << (EndPosition + 1'b1 ); + Exponent = ShiftedRemain[N-2:((N-1)-ES)]; + + //Mantissa Bits Extraction + Mantissa = {1'b1, ShiftedRemain[N-ES-2:0], ZERO}; +end +endmodule \ No newline at end of file diff --git a/Individual_Project/Posit_Multiplier/Posit_Multiplier.sv b/Individual_Project/Posit_Multiplier/Posit_Multiplier.sv new file mode 100644 index 0000000..3b2b319 --- /dev/null +++ b/Individual_Project/Posit_Multiplier/Posit_Multiplier.sv @@ -0,0 +1,99 @@ +///////////////////////////////////////////////////////////////////// +// Design unit: Posit Multiplier +// : +// File name : Posit_Multiplier.sv +// : +// Description: +// : +// Limitations: None +// : +// System : SystemVerilog IEEE 1800-2005 +// : +// Author : Xiaoan(Jasper) He +// : xh2g20@soton.ac.uk +// +// Revision : Version 1.0 08/02/2023 +///////////////////////////////////////////////////////////////////// + +module Posit_Multiplier #(parameter N = 8, parameter ES = 3, parameter RS = $clog2(N)) +( + input logic[N-1:0] IN1, IN2, + output logic [N-1:0] OUT +); + +logic Sign1, Sign2; +logic signed [N-2:0] InRemain1, InRemain2; +logic signed [RS+1:0] RegimeValue1,RegimeValue2; +logic [ES-1:0] Exponent1, Exponent2; +logic [N-ES+2:0] Mantissa1, Mantissa2; + +Data_Extraction #(.N(N), .ES(ES)) Extract_IN1 (.In(IN1), .Sign(Sign1), .RegimeValue(RegimeValue1), .Exponent(Exponent1), .Mantissa(Mantissa1), .InRemain(InRemain1)); +Data_Extraction #(.N(N), .ES(ES)) Extract_IN2 (.In(IN2), .Sign(Sign2), .RegimeValue(RegimeValue2), .Exponent(Exponent2), .Mantissa(Mantissa2), .InRemain(InRemain2)); + +/* the output of multipilcation between 2 N-bit inputs is 2N bit long + '+1' is used for overflow check +*/ +logic Operation; +logic [2*N-1:0] Mult_Mant; +logic [2*N-1:0] Mult_Mant_N; +logic Mant_mult_Ovf; +logic [RS+ES+1:0]Total_EO, Total_EON; +logic [ES-1:0] E_O; +logic signed [RS:0] R_O; +logic [(2*N-1)+3:0] tmp_o; +logic [(3*N-1)+3:0] sft_tmp_o; +logic L,G,R,S,ulp; +logic [N-1:0] rnd_ulp; +logic [N:0] sft_tmp_o_rnd_ulp; +logic [N-1:0] sft_tmp_o_rnd; +logic [N-1:0] sft_tmp_oN; + +always_comb +begin + + Operation = Sign1 ^ Sign2; + // Mantissa Multiplication Handling + Mult_Mant = Mantissa1 * Mantissa2; + Mant_mult_Ovf = Mult_Mant[2*N-1]; + Mult_Mant_N = Mant_mult_Ovf ? Mult_Mant : (Mult_Mant << 1); + + // Exponent Handling + + /* + for multiplication, the total exponent is the sum of + the respective total exponent of each input + */ + + Total_EO = {RegimeValue1,Exponent1} + {RegimeValue2, Exponent2} + Mant_mult_Ovf; + + Total_EON = Total_EO[RS+ES+1] ? (-Total_EO) : Total_EO; + + E_O = Total_EO[ES-1:0]; + + R_O = (~Total_EO[ES+RS+1'b1] || |(Total_EON[ES-1:0])) ? Total_EON[ES+RS:ES] + 1'b1 : Total_EON[ES+RS:ES]; + + tmp_o = { {N{~Total_EO[ES+RS+1]}}, Total_EO[ES+RS+1], E_O, Mult_Mant_N[(2*N-1)-1:(((2*N-1)-1)-(N-1-ES))+1], Mult_Mant_N[(((2*N-1)-1)-(N-1-ES)):(((2*N-1)-1)-(N-1-ES))-1], |Mult_Mant_N[(((2*N-1)-1)-(N-1-ES))-2:0]}; + sft_tmp_o = {tmp_o, {N{1'b0}}}; + sft_tmp_o = sft_tmp_o >> R_O; + + L = sft_tmp_o[N+4]; + G = sft_tmp_o[N+3]; + R = sft_tmp_o[N+2]; + S = |sft_tmp_o[N+1:0]; + ulp = ((G & (R | S)) | (L & G & ~(R | S))); + + rnd_ulp= {{N-1{1'b0}},ulp}; + + + sft_tmp_o_rnd_ulp = sft_tmp_o[2*N-1+3:N+3] + rnd_ulp; + + + sft_tmp_o_rnd = (R_O < N-ES-2) ? sft_tmp_o_rnd_ulp[N-1:0] : sft_tmp_o[2*N-1+3:N+3]; + + + //Final Output + + sft_tmp_oN = Operation ? -sft_tmp_o_rnd : sft_tmp_o_rnd; + OUT = {Operation, sft_tmp_oN[N-1:1]}; +end +endmodule \ No newline at end of file diff --git a/Individual_Project/Posit_Multiplier/Posit_Multiplier_tb.sv b/Individual_Project/Posit_Multiplier/Posit_Multiplier_tb.sv new file mode 100644 index 0000000..5dfb048 --- /dev/null +++ b/Individual_Project/Posit_Multiplier/Posit_Multiplier_tb.sv @@ -0,0 +1,120 @@ +///////////////////////////////////////////////////////////////////// +// Design unit: Posit Multiplier Testbench +// : +// File name : Posit_Multiplier_tb.sv +// : +// Description: Test Posit Multiplier +// : +// Limitations: None +// : +// System : SystemVerilog IEEE 1800-2005 +// : +// Author : Xiaoan(Jasper) He +// : xh2g20@ecs.soton.ac.uk +// +// Revision : Version 1.0 08/02/2023 +///////////////////////////////////////////////////////////////////// +function [31:0] log2; +input reg [31:0] value; + begin + value = value-1; + for (log2=0; value>0; log2=log2+1) + value = value>>1; + end +endfunction + +module Posit_Multiplier_tb; +parameter N = 8, RS = log2(N), ES = 3; + +//input logic +logic signed [N-1:0] IN1, IN2; + +//output logic +logic signed [N-1:0] OUT; + +Posit_Multiplier #(.N(N), .ES(ES)) Posit_Adder_testing (.*); + +initial + begin + #10ns + IN1 = 8'b0_0000000; + IN2 = 8'b0_0000000; + OUT = 8'b0_0000000; + + #50ns // 65536 112 + IN1 = 8'b0_1110_000; + IN2 = 8'b0_10_110_11; + + #50ns // 524288 1024 + IN1 = 8'b0_1110_011; + IN2 = 8'b0_110_010_0; + + #50ns // 10 12 + IN1 = 8'b0_10_011_01; + IN2 = 8'b0_10_011_10; + + #50ns // 40 24 + IN1 = 8'b0_10_101_01; + IN2 = 8'b0_10_100_10; + + #50ns // 0.0234375 0.01953125 + IN1 = 8'b0_01_010_01; + IN2 = 8'b0_10_001_10; + + #50ns // 0.125 0.15625 + IN1 = 8'b0_01_101_00; + IN2 = 8'b0_01_101_01; + + + // -ve * +ve + #50ns // -0.0000152587890625 112 + IN1 = 8'b1_1110_000; + IN2 = 8'b0_10_110_11; + + #50ns // -0.0000019073486328125 1024 + IN1 = 8'b1_1110_011; + IN2 = 8'b0_110_010_0; + + #50ns // -0.109375 12 + IN1 = 8'b1_10_011_01; + IN2 = 8'b0_10_011_10; + + #50ns // -0.02734375 24 + IN1 = 8'b1_10_101_01; + IN2 = 8'b0_10_100_10; + + #50ns // -56 3 + IN1 = 8'b1_01_010_01; + IN2 = 8'b0_10_001_10; + + #50ns // -8 0.15625 + IN1 = 8'b1_01_101_00; + IN2 = 8'b0_01_101_01; + + + // -ve * -ve + #50ns // -0.0000152587890625 -0.009765625 + IN1 = 8'b1_1110_000; + IN2 = 8'b1_10_110_11; + + #50ns // -0.0000019073486328125 -0.0009765625 + IN1 = 8'b1_1110_011; + IN2 = 8'b1_110_010_0; + + #50ns // -0.109375 -0.09375 + IN1 = 8'b1_10_011_01; + IN2 = 8'b1_10_011_10; + + #50ns // -0.02734375 -0.046875 + IN1 = 8'b1_10_101_01; + IN2 = 8'b1_10_100_10; + + #50ns // -56 -0.375 + IN1 = 8'b1_01_010_01; + IN2 = 8'b1_10_001_10; + + #50ns // -8 -7 + IN1 = 8'b1_01_101_00; + IN2 = 8'b1_01_101_01; + end +endmodule \ No newline at end of file -- GitLab