Skip to content
Snippets Groups Projects
Commit 8a103616 authored by XiaoanHe's avatar XiaoanHe
Browse files

Posit Multiplier

parent 27c37a57
No related branches found
No related tags found
No related merge requests found
/////////////////////////////////////////////////////////////////////
// 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
...@@ -16,31 +16,23 @@ ...@@ -16,31 +16,23 @@
// Revision : Version 1.0 21/11/2022 // 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, input logic signed [N-2:0] InRemain,
output logic signed [RS:0] EndPosition, output logic signed [RS:0] EndPosition,
output logic RegimeCheck 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; //logic RegimeCheck;
int i; int i;
logic signed [RS:0] EP;
always_comb always_comb
begin begin
RegimeCheck = InRemain[N-2]; //the MSB of InRemain (In[6])is the number to be checked RegimeCheck = InRemain[N-2]; //the MSB of InRemain (In[6])is the number to be checked
EndPosition = '0; EP = '0;
EndPosition = EndPosition + 1'b1; // initial EP starts from InRemain[1] as InRemain[0] is RC EndPosition = EP + 1'b1; // initial EP starts from InRemain[1] as InRemain[0] is RC
for(i = 1; i < (N-2); i++) for(i = 1; i < (N-2); i++)
begin begin
......
/////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////
// 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment