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

Posit Multiplier

parent 27c37a57
Branches wk9_23/11_01/12
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 @@
// 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
......
/////////////////////////////////////////////////////////////////////
// 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.
Finish editing this message first!
Please register or to comment