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