├── Posit-Adder ├── add_N.v ├── sub_N.v ├── add_mantovf.v ├── posit_adder_8bit.sh ├── DSR_left_N_S.v ├── DSR_right_N_S.v ├── julia_posit8_add.sh ├── data_extract.v ├── LOD_N.v ├── LZD_N.v ├── Readme.md ├── posit_adder_8bit_tb.v └── posit_adder.v ├── Posit-Multiplier ├── posit_mult_8bit.sh ├── DSR_left_N_S.v ├── DSR_right_N_S.v ├── julia_posit8_mult.sh ├── data_extract.v ├── LOD_N.v ├── LZD_N.v ├── posit_mult_8bit_tb.v ├── Readme.md └── posit_mult.v ├── Posit_to_Floating-Point_Convertor ├── Posit_to_FP.sh ├── DSR_left_N_S.v ├── DSR_right_N_S.v ├── julia_convert_Posit-to-FP.sh ├── data_extract.v ├── Posit_to_FP_tb.v ├── LOD_N.v ├── Posit_to_FP.v ├── README.md └── LZD_N.v ├── Floating-Point_to_Posit_Convertor ├── FP_to_Posit.sh ├── DSR_left_N_S.v ├── DSR_right_N_S.v ├── julia_convert_FP-to-Posit.sh ├── FP_to_Posit_tb.v ├── README.txt ├── LOD_N.v └── FP_to_Posit.v ├── LICENSE └── README.md /Posit-Adder/add_N.v: -------------------------------------------------------------------------------- 1 | module add_N (a,b,c); 2 | parameter N=10; 3 | input [N-1:0] a,b; 4 | output [N:0] c; 5 | assign c = {1'b0,a} + {1'b0,b}; 6 | endmodule 7 | 8 | -------------------------------------------------------------------------------- /Posit-Adder/sub_N.v: -------------------------------------------------------------------------------- 1 | module sub_N (a,b,c); 2 | parameter N=10; 3 | input [N-1:0] a,b; 4 | output [N:0] c; 5 | assign c = {1'b0,a} - {1'b0,b}; 6 | endmodule 7 | 8 | 9 | -------------------------------------------------------------------------------- /Posit-Adder/add_mantovf.v: -------------------------------------------------------------------------------- 1 | module add_mantovf (a,mant_ovf,c); 2 | parameter N=10; 3 | input [N:0] a; 4 | input mant_ovf; 5 | output [N:0] c; 6 | assign c = a + mant_ovf; 7 | endmodule 8 | -------------------------------------------------------------------------------- /Posit-Multiplier/posit_mult_8bit.sh: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | vlog "posit_mult.v" 4 | vlog "posit_mult_8bit_tb.v" 5 | vlog "DSR_right_N_S.v" 6 | vlog "LOD_N.v" 7 | vlog "LZD_N.v" 8 | vlog "DSR_left_N_S.v" 9 | vlog "data_extract.v" 10 | 11 | vsim -t ps work.posit_mult_8bit_tb_v 12 | view wave 13 | add wave * 14 | run -all 15 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/Posit_to_FP.sh: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | #All Verilog files 4 | vlog "Posit_to_FP.v" 5 | vlog "Posit_to_FP_tb.v" 6 | vlog "data_extract.v" 7 | vlog "DSR_left_N_S.v" 8 | vlog "DSR_right_N_S.v" 9 | vlog "LOD_N.v" 10 | vlog "LZD_N.v" 11 | 12 | vsim -t ps work.Posit_to_FP_tb_v 13 | view wave 14 | add wave * 15 | run -all 16 | -------------------------------------------------------------------------------- /Floating-Point_to_Posit_Convertor/FP_to_Posit.sh: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | #Path to Xilinx glbl.v file" 4 | vlog "/opt/Xilinx13.2/ISE_DS/ISE/verilog/src/glbl.v" 5 | 6 | #List of Verilog files 7 | vlog "FP_to_posit.v" 8 | vlog "FP_to_posit_tb.v" 9 | vlog "DSR_right_N_S.v" 10 | vlog "LOD_N.v" 11 | vlog "DSR_left_N_S.v" 12 | 13 | vsim -t ps work.FP_to_posit_tb_v work.glbl 14 | view wave 15 | add wave * 16 | run -all 17 | -------------------------------------------------------------------------------- /Posit-Adder/posit_adder_8bit.sh: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | #PATH for Xilinx glbl.v file. Edit it for correct location in your system. 4 | vlog "/opt/Xilinx13.2/ISE_DS/ISE/verilog/src/glbl.v" 5 | 6 | #All the verilog modules 7 | vlog "posit_adder_8bit_tb.v" 8 | vlog "posit_adder.v" 9 | vlog "DSR_right_N_S.v" 10 | vlog "LOD_N.v" 11 | vlog "LZD_N.v" 12 | vlog "DSR_left_N_S.v" 13 | 14 | vsim -t ps work.posit_adder_8bit_tb_v work.glbl 15 | view wave 16 | add wave * 17 | run -all 18 | -------------------------------------------------------------------------------- /Posit-Adder/DSR_left_N_S.v: -------------------------------------------------------------------------------- 1 | module DSR_left_N_S(a,b,c); 2 | parameter N=16; 3 | parameter S=4; 4 | input [N-1:0] a; 5 | input [S-1:0] b; 6 | output [N-1:0] c; 7 | 8 | wire [N-1:0] tmp [S-1:0]; 9 | assign tmp[0] = b[0] ? a << 7'd1 : a; 10 | genvar i; 11 | generate 12 | for (i=1; i> 7'd1 : a; 10 | genvar i; 11 | generate 12 | for (i=1; i> 2**i : tmp[i-1]; 14 | end 15 | endgenerate 16 | assign c = tmp[S-1]; 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /Posit-Multiplier/DSR_left_N_S.v: -------------------------------------------------------------------------------- 1 | module DSR_left_N_S(a,b,c); 2 | parameter N=16; 3 | parameter S=4; 4 | input [N-1:0] a; 5 | input [S-1:0] b; 6 | output [N-1:0] c; 7 | 8 | wire [N-1:0] tmp [S-1:0]; 9 | assign tmp[0] = b[0] ? a << 7'd1 : a; 10 | genvar i; 11 | generate 12 | for (i=1; i> 7'd1 : a; 10 | genvar i; 11 | generate 12 | for (i=1; i> 2**i : tmp[i-1]; 14 | end 15 | endgenerate 16 | assign c = tmp[S-1]; 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /Floating-Point_to_Posit_Convertor/DSR_left_N_S.v: -------------------------------------------------------------------------------- 1 | module DSR_left_N_S(a,b,c); 2 | parameter N=16; 3 | parameter S=4; 4 | input [N-1:0] a; 5 | input [S-1:0] b; 6 | output [N-1:0] c; 7 | 8 | wire [N-1:0] tmp [S-1:0]; 9 | assign tmp[0] = b[0] ? a << 7'd1 : a; 10 | genvar i; 11 | generate 12 | for (i=1; i> 7'd1 : a; 10 | genvar i; 11 | generate 12 | for (i=1; i> 2**i : tmp[i-1]; 14 | end 15 | endgenerate 16 | assign c = tmp[S-1]; 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/DSR_right_N_S.v: -------------------------------------------------------------------------------- 1 | module DSR_right_N_S(a,b,c); 2 | parameter N=16; 3 | parameter S=4; 4 | input [N-1:0] a; 5 | input [S-1:0] b; 6 | output [N-1:0] c; 7 | 8 | wire [N-1:0] tmp [S-1:0]; 9 | assign tmp[0] = b[0] ? a >> 7'd1 : a; 10 | genvar i; 11 | generate 12 | for (i=1; i> 2**i : tmp[i-1]; 14 | end 15 | endgenerate 16 | assign c = tmp[S-1]; 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/julia_convert_Posit-to-FP.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ARGS[1] == "--help" 4 | println("Usgae: julia julia_convert_Posit-to-FP.sh N es") 5 | else 6 | using SigmoidNumbers 7 | N = parse(ARGS[1]) 8 | es = parse(ARGS[2]) 9 | PS=Posit{N,es} 10 | f=open("Posit32_in.txt") 11 | lines = readlines(f) 12 | for l = 1:65536 13 | x="0x"lines[l] 14 | y=parse(x) 15 | P=PS(y) 16 | F=Float32(P) 17 | println(num2hex(F)) 18 | end 19 | end 20 | 21 | 22 | -------------------------------------------------------------------------------- /Floating-Point_to_Posit_Convertor/julia_convert_FP-to-Posit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Convert Single Precision Floating Point to Posit 4 | #Usage: julia julia_convert_FP-to-Posit.sh N es 5 | 6 | function FP_to_posit(y) 7 | z1=hex2num(y) 8 | z2=Float32(z1) 9 | println(PS(z2)) 10 | end 11 | 12 | typealias Float Float32 13 | using SigmoidNumbers 14 | N = parse(ARGS[1]) 15 | es = parse(ARGS[2]) 16 | PS = Posit{N,es} 17 | f=open("FP32_in.txt") 18 | lines = readlines(f) 19 | for l = 1:32512 20 | x1="0x"lines[l] 21 | x2=parse(UInt32, x1) 22 | FP_to_posit(hex(x2)) 23 | end 24 | 25 | 26 | -------------------------------------------------------------------------------- /Posit-Adder/julia_posit8_add.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function posit_add(y1,y2) 4 | P=PS(y1)+PS(y2) 5 | print(PS(y1),"\t") 6 | print(PS(y2),"\t") 7 | println(P) 8 | end 9 | 10 | if ARGS[1] == "--help" 11 | println("Usgae: julia julia_posit8_add.sh N es") 12 | else 13 | using SigmoidNumbers 14 | N = parse(ARGS[1]) 15 | es = parse(ARGS[2]) 16 | PS=Posit{N,es} 17 | f1=open("Pin1_8bit.txt") 18 | f2=open("Pin2_8bit.txt") 19 | lines1 = readlines(f1) 20 | lines2 = readlines(f2) 21 | for l = 1:65536 22 | x1="0b"lines1[l] 23 | x2="0b"lines2[l] 24 | y1=parse(x1) 25 | y2=parse(x2) 26 | posit_add(y1,y2) 27 | end 28 | end 29 | 30 | 31 | -------------------------------------------------------------------------------- /Posit-Multiplier/julia_posit8_mult.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function posit_mult(y1,y2) 4 | print(PS(y1),"\t") 5 | print(PS(y2),"\t") 6 | println(PS(y1)*PS(y2)) 7 | end 8 | 9 | if ARGS[1] == "--help" 10 | println("Usgae: julia julia_posit8_mult.sh N es") 11 | else 12 | using SigmoidNumbers 13 | N = parse(ARGS[1]) 14 | es = parse(ARGS[2]) 15 | PS=Posit{N,es} 16 | f1=open("Pin1_8bit.txt") 17 | f2=open("Pin2_8bit.txt") 18 | lines1 = readlines(f1) 19 | lines2 = readlines(f2) 20 | for l = 1:65536 21 | x1="0b"lines1[l] 22 | x2="0b"lines2[l] 23 | y1=parse(x1) 24 | y2=parse(x2) 25 | posit_arith(y1,y2) 26 | end 27 | end 28 | 29 | 30 | -------------------------------------------------------------------------------- /Posit-Adder/data_extract.v: -------------------------------------------------------------------------------- 1 | module data_extract(in, rc, regime, exp, mant, Lshift); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N=16; 13 | parameter Bs=log2(N); 14 | parameter es = 2; 15 | input [N-1:0] in; 16 | output rc; 17 | output [Bs-1:0] regime, Lshift; 18 | output [es-1:0] exp; 19 | output [N-es-1:0] mant; 20 | 21 | wire [N-1:0] xin = in; 22 | assign rc = xin[N-2]; 23 | wire [Bs-1:0] k0, k1; 24 | LOD_N #(.N(N)) xinst_k0(.in({xin[N-2:0],1'b0}), .out(k0)); 25 | LZD_N #(.N(N)) xinst_k1(.in({xin[N-3:0],2'b0}), .out(k1)); 26 | 27 | assign regime = xin[N-2] ? k1 : k0; 28 | assign Lshift = xin[N-2] ? k1+1 : k0; 29 | 30 | wire [N-1:0] xin_tmp; 31 | DSR_left_N_S #(.N(N), .S(Bs)) ls (.a({xin[N-3:0],2'b0}),.b(Lshift),.c(xin_tmp)); 32 | 33 | assign exp= xin_tmp[N-1:N-es]; 34 | assign mant= xin_tmp[N-es-1:0]; 35 | 36 | endmodule 37 | 38 | -------------------------------------------------------------------------------- /Posit-Multiplier/data_extract.v: -------------------------------------------------------------------------------- 1 | module data_extract(in, rc, regime, exp, mant, Lshift); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N=16; 13 | parameter Bs=log2(N); 14 | parameter es = 2; 15 | input [N-1:0] in; 16 | output rc; 17 | output [Bs-1:0] regime, Lshift; 18 | output [es-1:0] exp; 19 | output [N-es-1:0] mant; 20 | 21 | wire [N-1:0] xin = in; 22 | assign rc = xin[N-2]; 23 | wire [Bs-1:0] k0, k1; 24 | LOD_N #(.N(N)) xinst_k0(.in({xin[N-2:0],1'b0}), .out(k0)); 25 | LZD_N #(.N(N)) xinst_k1(.in({xin[N-3:0],2'b0}), .out(k1)); 26 | 27 | assign regime = xin[N-2] ? k1 : k0; 28 | assign Lshift = xin[N-2] ? k1+1 : k0; 29 | 30 | wire [N-1:0] xin_tmp; 31 | DSR_left_N_S #(.N(N), .S(Bs)) ls (.a({xin[N-3:0],2'b0}),.b(Lshift),.c(xin_tmp)); 32 | 33 | assign exp= xin_tmp[N-1:N-es]; 34 | assign mant= xin_tmp[N-es-1:0]; 35 | 36 | endmodule 37 | 38 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/data_extract.v: -------------------------------------------------------------------------------- 1 | module data_extract(in, rc, regime, exp, mant, Lshift); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N=16; 13 | parameter Bs=log2(N); 14 | parameter es = 2; 15 | input [N-1:0] in; 16 | output rc; 17 | output [Bs-1:0] regime, Lshift; 18 | output [es-1:0] exp; 19 | output [N-es-1:0] mant; 20 | 21 | wire [N-1:0] xin = in; 22 | assign rc = xin[N-2]; 23 | wire [Bs-1:0] k0, k1; 24 | LOD_N #(.N(N)) xinst_k0(.in({xin[N-2:0],1'b0}), .out(k0)); 25 | LZD_N #(.N(N)) xinst_k1(.in({xin[N-3:0],2'b0}), .out(k1)); 26 | 27 | assign regime = xin[N-2] ? k1 : k0; 28 | assign Lshift = xin[N-2] ? k1+1 : k0; 29 | 30 | wire [N-1:0] xin_tmp; 31 | DSR_left_N_S #(.N(N), .S(Bs)) ls (.a({xin[N-3:0],2'b0}),.b(Lshift),.c(xin_tmp)); 32 | 33 | assign exp= xin_tmp[N-1:N-es]; 34 | assign mant= xin_tmp[N-es-1:0]; 35 | 36 | endmodule 37 | 38 | -------------------------------------------------------------------------------- /Floating-Point_to_Posit_Convertor/FP_to_Posit_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module FP_to_posit_tb_v; 3 | 4 | function [31:0] log2; 5 | input reg [31:0] value; 6 | begin 7 | value = value-1; 8 | for (log2=0; value>0; log2=log2+1) 9 | value = value>>1; 10 | end 11 | endfunction 12 | 13 | parameter N=32; 14 | parameter E=8; 15 | parameter Bs=log2(N); 16 | parameter es = 4; 17 | 18 | reg [N-1:0] in; 19 | reg clk; 20 | 21 | wire [N-1:0] out; 22 | 23 | // Instantiate the Unit Under Test (UUT) 24 | FP_to_posit #(.N(N), .E(E), .es(es)) d1 ( 25 | .in(in), 26 | .out(out) 27 | ); 28 | 29 | 30 | initial begin 31 | // Initialize Inputs 32 | clk = 1; 33 | // Wait 100 ns for global reset to finish 34 | #101 in = 32'h0080ffff; 35 | #325150 36 | $fclose(outfile); 37 | $finish; 38 | end 39 | 40 | always #5 clk=~clk; 41 | always @(posedge clk) begin 42 | if (in < 32'h7f7fffff) 43 | in <= in + 65535; 44 | end 45 | 46 | integer outfile; 47 | initial outfile = $fopen("FP_to_posit_out.txt", "wb"); 48 | always @(negedge clk) begin 49 | $fwrite(outfile, "%h\t%h\n",in,out); 50 | end 51 | 52 | endmodule 53 | 54 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/Posit_to_FP_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module Posit_to_FP_tb_v; 3 | 4 | function [31:0] log2; 5 | input reg [31:0] value; 6 | begin 7 | value = value-1; 8 | for (log2=0; value>0; log2=log2+1) 9 | value = value>>1; 10 | end 11 | endfunction 12 | 13 | parameter N=32; 14 | parameter E=8; 15 | parameter Bs=log2(N); 16 | parameter es = 3; 17 | 18 | reg [N-1:0] in; 19 | reg clk; 20 | 21 | wire [N-1:0] out; 22 | 23 | // Instantiate the Unit Under Test (UUT) 24 | Posit_to_FP #(.N(N), .E(E), .es(es)) d1 ( 25 | .in(in), 26 | .out(out) 27 | ); 28 | 29 | 30 | initial begin 31 | // Initialize Inputs 32 | clk = 1; 33 | // Wait 100 ns for global reset to finish 34 | #101 in = 65535; 35 | 36 | #655360 37 | 38 | $fclose(outfile); 39 | $finish; 40 | end 41 | 42 | always #5 clk=~clk; 43 | always @(posedge clk) begin 44 | if (in < 32'hffffffff) 45 | in <= in + 65535; 46 | end 47 | 48 | integer outfile; 49 | initial outfile = $fopen("Posit_to_FP_out.txt", "wb"); 50 | always @(negedge clk) begin 51 | $fwrite(outfile, "%h\t%h\n",in,out); 52 | end 53 | 54 | endmodule 55 | 56 | -------------------------------------------------------------------------------- /Floating-Point_to_Posit_Convertor/README.txt: -------------------------------------------------------------------------------- 1 | Here, we can find the Floating-Point to Posit converter module. It includes following files. 2 | 3 | 1. FP_to_Posit.v : Top-module which takes N (posit word size), E (FP exponent size) and es (posit exponent size) as parameter. 4 | 2. DSR_right_N_S.v : Dynamic right shifter sub-module. 5 | 3. DSR_left_N_S.v : Dynamic left shifter sub-module. 6 | 4. LOD_N.v : Leading-One-Detector sub-module. 7 | 8 | Below are the files for test-module with N=32, E=8 and es=4 (User can test for other options). 9 | 5. FP_to_Posit_tb.v : Test-bench module. (Input range is selected to avoid julia exceptional interupt) 10 | 6. FP_to_Posit.sh : A bash script to invoke and run modelsim simulator to run the test-bench. 11 | *. FP_to_posit_out.txt : It will be generated after simlulation which contains FP input and corresponding Posit output. 12 | 13 | 14 | 7. julia_convert_FP-to-Posit.sh : This is a bash shell script for FP to posit conversion using julia posit package which currently takes FP32_in.txt as input file. 15 | Modify accordingly for specific parameters. 16 | Julia posit package can be downloaded from https://github.com/interplanetary-robot/SigmoidNumbers 17 | 8. FP32_in.txt : 32-bit FP Input 18 | -------------------------------------------------------------------------------- /Posit-Adder/LOD_N.v: -------------------------------------------------------------------------------- 1 | module LOD_N (in, out); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N = 64; 13 | parameter S = log2(N); 14 | input [N-1:0] in; 15 | output [S-1:0] out; 16 | 17 | wire vld; 18 | LOD #(.N(N)) l1 (in, out, vld); 19 | endmodule 20 | 21 | 22 | module LOD (in, out, vld); 23 | 24 | function [31:0] log2; 25 | input reg [31:0] value; 26 | begin 27 | value = value-1; 28 | for (log2=0; value>0; log2=log2+1) 29 | value = value>>1; 30 | end 31 | endfunction 32 | 33 | 34 | parameter N = 64; 35 | parameter S = log2(N); 36 | 37 | input [N-1:0] in; 38 | output [S-1:0] out; 39 | output vld; 40 | 41 | generate 42 | if (N == 2) 43 | begin 44 | assign vld = |in; 45 | assign out = ~in[1] & in[0]; 46 | end 47 | else if (N & (N-1)) 48 | LOD #(1<>1) l(in[(N>>1)-1:0],out_l,out_vl); 54 | LOD #(N>>1) h(in[N-1:N>>1],out_h,out_vh); 55 | assign vld = out_vl | out_vh; 56 | assign out = out_vh ? {1'b0,out_h} : {out_vl,out_l}; 57 | end 58 | endgenerate 59 | endmodule 60 | -------------------------------------------------------------------------------- /Posit-Multiplier/LOD_N.v: -------------------------------------------------------------------------------- 1 | module LOD_N (in, out); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N = 64; 13 | parameter S = log2(N); 14 | input [N-1:0] in; 15 | output [S-1:0] out; 16 | 17 | wire vld; 18 | LOD #(.N(N)) l1 (in, out, vld); 19 | endmodule 20 | 21 | 22 | module LOD (in, out, vld); 23 | 24 | function [31:0] log2; 25 | input reg [31:0] value; 26 | begin 27 | value = value-1; 28 | for (log2=0; value>0; log2=log2+1) 29 | value = value>>1; 30 | end 31 | endfunction 32 | 33 | 34 | parameter N = 64; 35 | parameter S = log2(N); 36 | 37 | input [N-1:0] in; 38 | output [S-1:0] out; 39 | output vld; 40 | 41 | generate 42 | if (N == 2) 43 | begin 44 | assign vld = |in; 45 | assign out = ~in[1] & in[0]; 46 | end 47 | else if (N & (N-1)) 48 | LOD #(1<>1) l(in[(N>>1)-1:0],out_l,out_vl); 54 | LOD #(N>>1) h(in[N-1:N>>1],out_h,out_vh); 55 | assign vld = out_vl | out_vh; 56 | assign out = out_vh ? {1'b0,out_h} : {out_vl,out_l}; 57 | end 58 | endgenerate 59 | endmodule 60 | -------------------------------------------------------------------------------- /Floating-Point_to_Posit_Convertor/LOD_N.v: -------------------------------------------------------------------------------- 1 | module LOD_N (in, out); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N = 64; 13 | parameter S = log2(N); 14 | input [N-1:0] in; 15 | output [S-1:0] out; 16 | 17 | wire vld; 18 | LOD #(.N(N)) l1 (in, out, vld); 19 | endmodule 20 | 21 | 22 | module LOD (in, out, vld); 23 | 24 | function [31:0] log2; 25 | input reg [31:0] value; 26 | begin 27 | value = value-1; 28 | for (log2=0; value>0; log2=log2+1) 29 | value = value>>1; 30 | end 31 | endfunction 32 | 33 | 34 | parameter N = 64; 35 | parameter S = log2(N); 36 | 37 | input [N-1:0] in; 38 | output [S-1:0] out; 39 | output vld; 40 | 41 | generate 42 | if (N == 2) 43 | begin 44 | assign vld = |in; 45 | assign out = ~in[1] & in[0]; 46 | end 47 | else if (N & (N-1)) 48 | LOD #(1<>1) l(in[(N>>1)-1:0],out_l,out_vl); 54 | LOD #(N>>1) h(in[N-1:N>>1],out_h,out_vh); 55 | assign vld = out_vl | out_vh; 56 | assign out = out_vh ? {1'b0,out_h} : {out_vl,out_l}; 57 | end 58 | endgenerate 59 | endmodule 60 | -------------------------------------------------------------------------------- /Posit-Adder/LZD_N.v: -------------------------------------------------------------------------------- 1 | module LZD_N (in, out); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N = 64; 13 | parameter S = log2(N); 14 | input [N-1:0] in; 15 | output [S-1:0] out; 16 | 17 | wire vld; 18 | LZD #(.N(N)) l1 (in, out, vld); 19 | endmodule 20 | 21 | 22 | module LZD (in, out, vld); 23 | 24 | function [31:0] log2; 25 | input reg [31:0] value; 26 | begin 27 | value = value-1; 28 | for (log2=0; value>0; log2=log2+1) 29 | value = value>>1; 30 | end 31 | endfunction 32 | 33 | 34 | parameter N = 64; 35 | parameter S = log2(N); 36 | 37 | input [N-1:0] in; 38 | output [S-1:0] out; 39 | output vld; 40 | 41 | generate 42 | if (N == 2) 43 | begin 44 | assign vld = ~∈ 45 | assign out = in[1] & ~in[0]; 46 | end 47 | else if (N & (N-1)) 48 | LZD #(1<>1) l(in[(N>>1)-1:0],out_l,out_vl); 55 | LZD #(N>>1) h(in[N-1:N>>1],out_h,out_vh); 56 | assign vld = out_vl | out_vh; 57 | assign out = out_vh ? {1'b0,out_h} : {out_vl,out_l}; 58 | end 59 | endgenerate 60 | endmodule 61 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/LOD_N.v: -------------------------------------------------------------------------------- 1 | module LOD_N (in, out); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N = 64; 13 | parameter S = log2(N); 14 | input [N-1:0] in; 15 | output [S-1:0] out; 16 | 17 | wire vld; 18 | LOD #(.N(N)) l1 (in, out, vld); 19 | endmodule 20 | 21 | 22 | module LOD (in, out, vld); 23 | 24 | function [31:0] log2; 25 | input reg [31:0] value; 26 | begin 27 | value = value-1; 28 | for (log2=0; value>0; log2=log2+1) 29 | value = value>>1; 30 | end 31 | endfunction 32 | 33 | 34 | parameter N = 64; 35 | parameter S = log2(N); 36 | 37 | input [N-1:0] in; 38 | output [S-1:0] out; 39 | output vld; 40 | 41 | generate 42 | if (N == 2) 43 | begin 44 | assign vld = |in; 45 | assign out = ~in[1] & in[0]; 46 | end 47 | else if (N & (N-1)) 48 | LOD #(1<>1) l(in[(N>>1)-1:0],out_l,out_vl); 54 | LOD #(N>>1) h(in[N-1:N>>1],out_h,out_vh); 55 | assign vld = out_vl | out_vh; 56 | assign out = out_vh ? {1'b0,out_h} : {out_vl,out_l}; 57 | end 58 | endgenerate 59 | endmodule 60 | -------------------------------------------------------------------------------- /Posit-Multiplier/LZD_N.v: -------------------------------------------------------------------------------- 1 | module LZD_N (in, out); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N = 64; 13 | parameter S = log2(N); 14 | input [N-1:0] in; 15 | output [S-1:0] out; 16 | 17 | wire vld; 18 | LZD #(.N(N)) l1 (in, out, vld); 19 | endmodule 20 | 21 | 22 | module LZD (in, out, vld); 23 | 24 | function [31:0] log2; 25 | input reg [31:0] value; 26 | begin 27 | value = value-1; 28 | for (log2=0; value>0; log2=log2+1) 29 | value = value>>1; 30 | end 31 | endfunction 32 | 33 | 34 | parameter N = 64; 35 | parameter S = log2(N); 36 | 37 | input [N-1:0] in; 38 | output [S-1:0] out; 39 | output vld; 40 | 41 | generate 42 | if (N == 2) 43 | begin 44 | assign vld = ~∈ 45 | assign out = in[1] & ~in[0]; 46 | end 47 | else if (N & (N-1)) 48 | LZD #(1<>1) l(in[(N>>1)-1:0],out_l,out_vl); 55 | LZD #(N>>1) h(in[N-1:N>>1],out_h,out_vh); 56 | assign vld = out_vl | out_vh; 57 | assign out = out_vh ? {1'b0,out_h} : {out_vl,out_l}; 58 | end 59 | endgenerate 60 | endmodule 61 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/Posit_to_FP.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module Posit_to_FP (in, out); 3 | 4 | function [31:0] log2; 5 | input reg [31:0] value; 6 | begin 7 | value = value-1; 8 | for (log2=0; value>0; log2=log2+1) 9 | value = value>>1; 10 | end 11 | endfunction 12 | 13 | parameter N = 16; 14 | parameter E = 5; 15 | parameter es = 2; 16 | 17 | parameter M = N-E-1; 18 | parameter BIAS = (2**(E-1))-1; 19 | parameter Bs = log2(N); 20 | parameter EO = E > es+Bs ? E : es+Bs; 21 | 22 | input [N-1:0] in; 23 | output [N-1:0] out; 24 | 25 | wire s = in[N-1]; 26 | wire zero_tmp = |in[N-2:0]; 27 | wire inf_in = in[N-1] & (~zero_tmp); 28 | wire zero_in = ~(in[N-1] | zero_tmp); 29 | 30 | //Data Extraction 31 | wire rc; 32 | wire [Bs-1:0] rgm, Lshift; 33 | wire [es-1:0] e; 34 | wire [N-es-1:0] mant; 35 | wire [N-1:0] xin = s ? -in : in; 36 | data_extract #(.N(N),.es(es)) uut_de1(.in(xin), .rc(rc), .regime(rgm), .exp(e), .mant(mant), .Lshift(Lshift)); 37 | 38 | wire [N-1:0] m = {zero_tmp,mant,{es-1{1'b0}}}; 39 | 40 | //Exponent and Regime Computation 41 | wire [EO+1:0] e_o; 42 | assign e_o = {(rc ? {{EO-es-Bs+1{1'b0}},rgm} : -{{EO-es-Bs+1{1'b0}},rgm}),e} + BIAS; 43 | //Final Output 44 | assign out = inf_in|e_o[EO:E]|&e_o[E-1:0] ? {s,{E-1{1'b1}},{M{1'b0}}} : (zero_in|(~m[N-1]) ? {s,{E-1{1'b0}},m[N-2:E]} : { s, e_o[E-1:0], m[N-2:E]} ); 45 | 46 | 47 | endmodule 48 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/README.md: -------------------------------------------------------------------------------- 1 | Here, we can find the Posit to Floating-Point converter module. It includes following files. 2 | 3 | 1. Posit_to_FP.v : Top-module which takes N (posit word size), E (FP exponent size) and es (posit exponent size) as parameter. 4 | 2. DSR_right_N_S.v : Dynamic right shifter sub-module. 5 | 3. DSR_left_N_S.v : Dynamic left shifter sub-module. 6 | 4. LOD_N.v : Leading-One-Detector sub-module. 7 | 4. LZD_N.v : Leading-One-Detector sub-module. 8 | 5. data_extract.v : Posit data extraction sub-module. 9 | 10 | Below are the files for test-module with N=32, E=8 and es=3 (User can test for other options). 11 | 5. Posit_to_FP_tb.v : Test-bench module. (Input range is selected to avoid julia exceptional interupt) 12 | 6. Posit_to_FP.sh : A bash script to invoke and run modelsim simulator to run the test-bench. 13 | *. Posit_to_FP_out.txt : It will be generated after simlulation which contains 32-bit Posit input and corresponding 32-bit Floating-Point output. 14 | 15 | 16 | 7. julia_convert_Posit-to-FP.sh : This is a bash shell script for FP to posit conversion using julia posit package which currently takes "Posit32_in.txt" as posit input file. 17 | Modify accordingly for specific parameters. 18 | Julia posit package can be downloaded from https://github.com/interplanetary-robot/SigmoidNumbers 19 | 8. Posit32_in.txt : 32-bit Posit Inputs 20 | -------------------------------------------------------------------------------- /Posit_to_Floating-Point_Convertor/LZD_N.v: -------------------------------------------------------------------------------- 1 | module LZD_N (in, out); 2 | 3 | function [31:0] log2; 4 | input reg [31:0] value; 5 | begin 6 | value = value-1; 7 | for (log2=0; value>0; log2=log2+1) 8 | value = value>>1; 9 | end 10 | endfunction 11 | 12 | parameter N = 64; 13 | parameter S = log2(N); 14 | input [N-1:0] in; 15 | output [S-1:0] out; 16 | 17 | wire vld; 18 | LZD #(.N(N)) l1 (in, out, vld); 19 | endmodule 20 | 21 | 22 | module LZD (in, out, vld); 23 | 24 | function [31:0] log2; 25 | input reg [31:0] value; 26 | begin 27 | value = value-1; 28 | for (log2=0; value>0; log2=log2+1) 29 | value = value>>1; 30 | end 31 | endfunction 32 | 33 | 34 | parameter N = 64; 35 | parameter S = log2(N); 36 | 37 | input [N-1:0] in; 38 | output [S-1:0] out; 39 | output vld; 40 | 41 | generate 42 | if (N == 2) 43 | begin 44 | assign vld = ~∈ 45 | assign out = in[1] & ~in[0]; 46 | end 47 | else if (N & (N-1)) 48 | LZD #(1<>1) l(in[(N>>1)-1:0],out_l,out_vl); 55 | LZD #(N>>1) h(in[N-1:N>>1],out_h,out_vh); 56 | assign vld = out_vl | out_vh; 57 | assign out = out_vh ? {1'b0,out_h} : {out_vl,out_l}; 58 | end 59 | endgenerate 60 | endmodule 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Manish Kumar Jaiswal 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Posit-Multiplier/posit_mult_8bit_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module posit_mult_8bit_tb_v; 3 | 4 | function [31:0] log2; 5 | input reg [31:0] value; 6 | begin 7 | value = value-1; 8 | for (log2=0; value>0; log2=log2+1) 9 | value = value>>1; 10 | end 11 | endfunction 12 | 13 | parameter N=8; 14 | parameter Bs=log2(N); 15 | parameter es=4; 16 | 17 | reg [N-1:0] in1, in2; 18 | reg start; 19 | wire [N-1:0] out; 20 | wire done; 21 | 22 | reg clk; 23 | integer outfile; 24 | 25 | 26 | // Instantiate the Unit Under Test (UUT) 27 | posit_mult #(.N(N), .es(es)) uut (in1, in2, start, out, inf, zero, done); 28 | 29 | reg [N-1:0] data1 [1:65534]; 30 | reg [N-1:0] data2 [1:65534]; 31 | initial $readmemb("Pin1_8bit.txt",data1); 32 | initial $readmemb("Pin2_8bit.txt",data2); 33 | 34 | reg [15:0] i; 35 | 36 | initial begin 37 | // Initialize Inputs 38 | in1 = 0; 39 | in2 = 0; 40 | clk = 0; 41 | start = 0; 42 | 43 | 44 | // Wait 100 ns for global reset to finish 45 | #100 i=0; 46 | #20 start = 1; 47 | #652790 start = 0; 48 | #100; 49 | 50 | $fclose(outfile); 51 | $finish; 52 | end 53 | 54 | always #5 clk=~clk; 55 | 56 | always @(posedge clk) begin 57 | in1=data1[i]; 58 | in2=data2[i]; 59 | if(i==16'hffff) 60 | $finish; 61 | else i = i + 1; 62 | end 63 | 64 | initial outfile = $fopen("error_8bit.txt", "wb"); 65 | 66 | reg [N-1:0] result [1:65534]; 67 | initial $readmemb("Pout_8bit_ES4.txt",result); 68 | reg [N-1:0] diff; 69 | always @(negedge clk) begin 70 | if(start)begin 71 | diff = (result[i-1] > out) ? result[i-1]-out : out-result[i-1]; 72 | $fwrite(outfile, "%d\n",diff); 73 | end 74 | end 75 | endmodule 76 | 77 | -------------------------------------------------------------------------------- /Posit-Adder/Readme.md: -------------------------------------------------------------------------------- 1 | # Posit Adder HDL Arithmetic: 2 | 3 | Here, we can find the Posit Adder module. It includes following files. 4 | 5 | 1. posit_adder.v : Top-module which takes N (posit word size) and es (posit exponent size). 6 | 2. data_extract.v : Posit data extract sub-module. 7 | 3. DSR_right_N_S.v : Dynamic right shifter sub-module. 8 | 4. DSR_left_N_S.v : Dynamic left shifter sub-module. 9 | 5. LOD_N.v : Leading-One-Detector sub-module. 10 | 6. LZD_N.v : Leading-Zero-Detector sub-module. 11 | 7. add_N.v : Two N-bit integer adder sub-module. 12 | 8. sub_N.v : Two N-bit integer subtract sub-module. 13 | 9. add_mantovf.v : Integer Adder sub-module for mantissa overflow addition. 14 | 15 | Below are the files for test-module for posit adder with N=8, ES=4 (User can test for other options). 16 | It is an all exhaustive test for 8-bit operands. 17 | 18 | 10. posit_adder_8bit_tb.v : Test-bench module. 19 | 11. posit_adder_8bit.sh : A bash script to invoke and run modelsim simulator to run the test-bench. 20 | 12. Pin1_8bit.txt : Input-1 8-bit 21 | 13. Pin2_8bit.txt : Input-2 8-bit 22 | 14. Pout_8bit_ES4.txt : Pre-stored posit addition results for comparison purpose. 23 | 24 | **. error_8bit.txt : File will be generated during simulation which contains the difference of 25 | result produce by the Verilog module with pre-stored posit addition results. 26 | 27 | 28 | 15. julia_posit8_add.sh : This is a bash shell script for posit addition using julia posit package. It is currently using 8-bit inputs. 29 | Julia posit package can be downloaded from https://github.com/interplanetary-robot/SigmoidNumbers 30 | -------------------------------------------------------------------------------- /Posit-Adder/posit_adder_8bit_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module posit_adder_8bit_tb_v; 3 | 4 | function [31:0] log2; 5 | input reg [31:0] value; 6 | begin 7 | value = value-1; 8 | for (log2=0; value>0; log2=log2+1) 9 | value = value>>1; 10 | end 11 | endfunction 12 | 13 | parameter N=8; 14 | parameter Bs=log2(N); 15 | parameter es=4; 16 | 17 | reg [N-1:0] in1, in2; 18 | reg start; 19 | wire out_s; 20 | wire [Bs-1:0] out_r; 21 | wire [Bs+es-1:0]out_e; 22 | wire [N-1:0] out_m, out; 23 | wire done; 24 | 25 | reg clk; 26 | integer outfile; 27 | 28 | 29 | // Instantiate the Unit Under Test (UUT) 30 | posit_adder #(.N(N), .es(es)) uut (in1, in2, start, out, inf, zero, done); 31 | 32 | reg [N-1:0] data1 [1:65536]; 33 | reg [N-1:0] data2 [1:65536]; 34 | initial $readmemb("Pin1_8bit.txt",data1); 35 | initial $readmemb("Pin2_8bit.txt",data2); 36 | 37 | reg [15:0] i; 38 | 39 | initial begin 40 | // Initialize Inputs 41 | in1 = 0; 42 | in2 = 0; 43 | clk = 0; 44 | start = 0; 45 | 46 | 47 | // Wait 100 ns for global reset to finish 48 | #100 i=0; 49 | #20 start = 1; 50 | #655500 start = 0; 51 | #100; 52 | 53 | $fclose(outfile); 54 | $finish; 55 | end 56 | 57 | always #5 clk=~clk; 58 | 59 | always @(posedge clk) begin 60 | in1=data1[i]; 61 | in2=data2[i]; 62 | if(i==16'hffff) 63 | $finish; 64 | else i = i + 1; 65 | end 66 | 67 | initial outfile = $fopen("error_8bit.txt", "wb"); 68 | 69 | reg [N-1:0] result [1:65536]; 70 | initial $readmemb("Pout_8bit_ES4.txt",result); 71 | reg [N-1:0] diff; 72 | always @(negedge clk) begin 73 | if(start)begin 74 | diff = (result[i-1] > out) ? result[i-1]-out : out-result[i-1]; 75 | //$fwrite(outfile, "%h\t%h\t%h\t%h\t%d\n",in1, in2, out,result[i-1],diff); 76 | $fwrite(outfile, "%d\n",diff); 77 | end 78 | end 79 | endmodule 80 | 81 | -------------------------------------------------------------------------------- /Posit-Multiplier/Readme.md: -------------------------------------------------------------------------------- 1 | # Posit Multiplier HDL Arithmetic: 2 | 3 | Here, we can find the Posit Multiplier module. It includes following files. 4 | 5 | 1. posit_mult.v : Top-module which takes N (posit word size) and es (posit exponent size). 6 | 2. data_extract.v : Posit data extract sub-module. 7 | 3. DSR_right_N_S.v : Dynamic right shifter sub-module. 8 | 4. DSR_left_N_S.v : Dynamic left shifter sub-module. 9 | 5. LOD_N.v : Leading-One-Detector sub-module. 10 | 6. LZD_N.v : Leading-Zero-Detector sub-module. 11 | 12 | Below are the files for test-module for posit mult with N=8, ES=4 (User can test for other options). 13 | It is an all exhaustive test for 8-bit operands (excluding Infinity multiplications to avoid comparision with julia pachage interupts for them). 14 | 15 | 7. posit_mult_8bit_tb.v : Test-bench module. 16 | 8. posit_mult_8bit.sh : A bash script to invoke and run modelsim simulator to run the test-bench. 17 | 9. Pin1_8bit.txt : Input-1 8-bit (Infinity multiplications are removed to avoid interupt from corresponding julia result comparisions) 18 | 10. Pin2_8bit.txt : Input-2 8-bit (Infinity multiplications are removed to avoid interupt from corresponding julia result comparisions) 19 | 11. Pout_8bit_ES4.txt : Pre-stored posit multiplication results for comparison purpose. 20 | 21 | **. error_8bit.txt : File will be generated during simulation which contains the difference of 22 | result produce by the Verilog module with pre-stored posit addition results. 23 | 24 | 25 | 12. julia_posit8_mult.sh : This is a bash shell script for posit addition using julia posit package. It is currently using 8-bit inputs. 26 | Julia posit package can be downloaded from https://github.com/interplanetary-robot/SigmoidNumbers 27 | -------------------------------------------------------------------------------- /Floating-Point_to_Posit_Convertor/FP_to_Posit.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module FP_to_posit(in, out); 3 | 4 | function [31:0] log2; 5 | input reg [31:0] value; 6 | begin 7 | value = value-1; 8 | for (log2=0; value>0; log2=log2+1) 9 | value = value>>1; 10 | end 11 | endfunction 12 | 13 | parameter N = 16; 14 | parameter E = 5; 15 | parameter es = 2; //ES_max = E-1 16 | parameter M = N-E-1; 17 | parameter BIAS = (2**(E-1))-1; 18 | 19 | parameter Bs = log2(N); 20 | 21 | input [N-1:0] in; 22 | output [N-1:0] out; 23 | 24 | wire s_in = in[N-1]; 25 | wire [E-1:0] exp_in = in[N-2:N-1-E]; 26 | wire [M-1:0] mant_in = in[M-1:0]; 27 | wire zero_in = ~|{exp_in,mant_in}; 28 | wire inf_in = &exp_in; 29 | 30 | wire [M:0] mant = {|exp_in, mant_in}; 31 | 32 | wire [N-1:0] LOD_in = {mant,{E{1'b0}}}; 33 | wire[Bs-1:0] Lshift; 34 | LOD_N #(.N(N)) uut (.in(LOD_in), .out(Lshift)); 35 | 36 | wire[N-1:0] mant_tmp; 37 | DSR_left_N_S #(.N(N), .S(Bs)) ls (.a(LOD_in),.b(Lshift),.c(mant_tmp)); 38 | 39 | wire [E:0] exp = {exp_in[E-1:1], exp_in[0] | (~|exp_in)} - BIAS - Lshift; 40 | 41 | //Exponent and Regime Computation 42 | wire [E:0] exp_N = exp[E] ? -exp : exp; 43 | wire [es-1:0] e_o = (exp[E] & |exp_N[es-1:0]) ? exp[es-1:0] : exp_N[es-1:0]; 44 | wire [E-es-1:0] r_o = (~exp[E] || (exp[E] & |exp_N[es-1:0])) ? {{Bs{1'b0}},exp_N[E-1:es]} + 1'b1 : {{Bs{1'b0}},exp_N[E-1:es]}; 45 | 46 | //Exponent and Mantissa Packing 47 | wire [2*N-1:0]tmp_o = { {N{~exp[E]}}, exp[E], e_o, mant_tmp[N-2:es]}; 48 | 49 | //Including Regime bits in Exponent-Mantissa Packing 50 | wire [2*N-1:0] tmp1_o; 51 | wire [Bs-1:0] diff_b; 52 | generate 53 | if(E-es > Bs) assign diff_b = |r_o[E-es-1:Bs] ? {{(Bs-2){1'b1}},2'b01} : r_o[Bs-1:0]; 54 | else assign diff_b = r_o; 55 | endgenerate 56 | DSR_right_N_S #(.N(2*N), .S(Bs)) dsr2 (.a(tmp_o), .b(diff_b), .c(tmp1_o)); 57 | 58 | //Final Output 59 | wire [N-1:0] tmp1_oN = s_in ? -tmp1_o[N-1:0] : tmp1_o[N-1:0]; 60 | assign out = inf_in|zero_in|(~mant_tmp[N-1]) ? {inf_in,{N-1{1'b0}}} : {s_in, tmp1_oN[N-1:1]}; 61 | 62 | endmodule 63 | 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ******************************************** 2 | **IMPORTANT NOTE: 3 | An improved version of "Posit Adder and Multiplier" HDL Generator is provided 4 | at https://github.com/manish-kj/PACoGen . It also supports "rounding to nearest" method 5 | along with some other hardware optimizations. It also inlcudes a "posit division generator" 6 | using Newton-Raphson method. It also provide a set of pipelined architecture HDL code 7 | for posit adder, multiplier and division.** 8 | ******************************************** 9 | 10 | 11 | # Posit-HDL-Arithmetic 12 | "Universal number (Unum) Posit HDL Arithmetic Architecture Generator" 13 | 14 | Universal number system is proposed by Prof. Gustafson, which gone through 15 | a set of advancement as type-1, type-2 and type-3 unum. Posit is proposed 16 | under type-3 unum system. 17 | 18 | More details on Unum can be sought from http://www.johngustafson.net/unums.html 19 | 20 | Here, a parameterized Verilog HDL for Unum Posit number system arithmetic is 21 | under progress. At present, it includes the basic arithmetic of Floating-Point 22 | to Posit conversion, Posit to Floating-Point conversion, Posit addition/subtraction, 23 | Posit Multiplication. Addition module can also be used for subtraction, just by 24 | negating second operand. 25 | 26 | At current, round-to-zero rounding method is incorporated in these units, which 27 | will be updated for other rounding methods soon. 28 | 29 | The Infinity and Not-A-Number (NaN) cases are handled as per the exact Posit 30 | standards as provided in its original paper. According to it, Posit format does 31 | not support/include NaN, which is considered as Infinity in current HDL 32 | generation. 33 | 34 | Posit standards are followed from the developer's paper which can be find at 35 | http://www.johngustafson.net/pdfs/BeatingFloatingPoint.pdf 36 | 37 | 38 | This work is based on following papers. Please refer/cite them if you find this work useful for your research. 39 | 1. Manish Kumar Jaiswal and Hayden K.-H. So, "Architecture Generator for Type-3 Unum Posit Adder/Subtractor", IEEE International Symposium on Circuits and Systems (ISCAS 2018), pp. 1-5, Florence, Italy, May 2018. 40 | 2. Manish Kumar Jaiswal and Hayden K.-H. So, "Universal Number Posit Arithmetic Generator on FPGA", Design Automation and Test (DATE 2018), pp. 1159-1162, Dresden, Germany, Mar 2018. 41 | -------------------------------------------------------------------------------- /Posit-Multiplier/posit_mult.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module posit_mult (in1, in2, start, out, inf, zero, done); 4 | 5 | function [31:0] log2; 6 | input reg [31:0] value; 7 | begin 8 | value = value-1; 9 | for (log2=0; value>0; log2=log2+1) 10 | value = value>>1; 11 | end 12 | endfunction 13 | 14 | parameter N = 16; 15 | parameter Bs = log2(N); 16 | parameter es = 3; 17 | 18 | input [N-1:0] in1, in2; 19 | input start; 20 | output [N-1:0] out; 21 | output inf, zero; 22 | output done; 23 | 24 | wire start0= start; 25 | wire s1 = in1[N-1]; 26 | wire s2 = in2[N-1]; 27 | wire zero_tmp1 = |in1[N-2:0]; 28 | wire zero_tmp2 = |in2[N-2:0]; 29 | wire inf1 = in1[N-1] & (~zero_tmp1), 30 | inf2 = in2[N-1] & (~zero_tmp2); 31 | wire zero1 = ~(in1[N-1] | zero_tmp1), 32 | zero2 = ~(in2[N-1] | zero_tmp2); 33 | assign inf = inf1 | inf2, 34 | zero = zero1 & zero2; 35 | 36 | //Data Extraction 37 | wire rc1, rc2; 38 | wire [Bs-1:0] regime1, regime2, Lshift1, Lshift2; 39 | wire [es-1:0] e1, e2; 40 | wire [N-es-1:0] mant1, mant2; 41 | wire [N-1:0] xin1 = s1 ? -in1 : in1; 42 | wire [N-1:0] xin2 = s2 ? -in2 : in2; 43 | data_extract #(.N(N),.es(es)) uut_de1(.in(xin1), .rc(rc1), .regime(regime1), .exp(e1), .mant(mant1), .Lshift(Lshift1)); 44 | data_extract #(.N(N),.es(es)) uut_de2(.in(xin2), .rc(rc2), .regime(regime2), .exp(e2), .mant(mant2), .Lshift(Lshift2)); 45 | 46 | wire [N-es:0] m1 = {zero_tmp1,mant1}, 47 | m2 = {zero_tmp2,mant2}; 48 | 49 | //Sign, Exponent and Mantissa Computation 50 | wire mult_s = s1 ^ s2; 51 | 52 | wire [2*(N-es)+1:0] mult_m = m1*m2; 53 | wire mult_m_ovf = mult_m[2*(N-es)+1]; 54 | wire [2*(N-es)+1:0] mult_mN = ~mult_m_ovf ? mult_m << 1'b1 : mult_m; 55 | 56 | wire [Bs+1:0] r1 = rc1 ? {2'b0,regime1} : -regime1; 57 | wire [Bs+1:0] r2 = rc2 ? {2'b0,regime2} : -regime2; 58 | wire [Bs+es+1:0] mult_e = {r1, e1} + {r2, e2} + mult_m_ovf; 59 | 60 | //Exponent and Regime Computation 61 | wire [es+Bs:0] mult_eN = mult_e[es+Bs+1] ? -mult_e : mult_e; 62 | wire [es-1:0] e_o = (mult_e[es+Bs+1] & |mult_eN[es-1:0]) ? mult_e[es-1:0] : mult_eN[es-1:0]; 63 | wire [Bs:0] r_o = (~mult_e[es+Bs+1] || (mult_e[es+Bs+1] & |mult_eN[es-1:0])) ? mult_eN[es+Bs:es] + 1'b1 : mult_eN[es+Bs:es]; 64 | 65 | //Exponent and Mantissa Packing 66 | wire [2*N-1:0]tmp_o = {{N{~mult_e[es+Bs+1]}},mult_e[es+Bs+1],e_o,mult_mN[2*(N-es):N-es+2]}; 67 | 68 | 69 | //Including Regime bits in Exponent-Mantissa Packing 70 | wire [2*N-1:0] tmp1_o; 71 | DSR_right_N_S #(.N(2*N), .S(Bs+1)) dsr2 (.a(tmp_o), .b(r_o[Bs] ? {Bs{1'b1}} : r_o), .c(tmp1_o)); 72 | 73 | 74 | //Final Output 75 | wire [2*N-1:0] tmp1_oN = mult_s ? -tmp1_o : tmp1_o; 76 | assign out = inf|zero|(~mult_mN[2*(N-es)+1]) ? {inf,{N-1{1'b0}}} : {mult_s, tmp1_oN[N-1:1]}, 77 | done = start0; 78 | 79 | endmodule 80 | 81 | -------------------------------------------------------------------------------- /Posit-Adder/posit_adder.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "DSR_right_N_S.v" 3 | `include "LOD_N.v" 4 | `include "LZD_N.v" 5 | `include "DSR_left_N_S.v" 6 | `include "add_N.v" 7 | `include "sub_N.v" 8 | `include "data_extract.v" 9 | `include "add_mantovf.v" 10 | 11 | module posit_adder (in1, in2, start, out, inf, zero, done); 12 | 13 | function [31:0] log2; 14 | input reg [31:0] value; 15 | begin 16 | value = value-1; 17 | for (log2=0; value>0; log2=log2+1) 18 | value = value>>1; 19 | end 20 | endfunction 21 | 22 | parameter N = 16; //Posit Word Size 23 | parameter Bs = log2(N); 24 | parameter es = 2; //Posit Exponent Size 25 | 26 | input [N-1:0] in1, in2; 27 | input start; 28 | output [N-1:0] out; 29 | output inf, zero; 30 | output done; 31 | 32 | wire start0= start; 33 | wire s1 = in1[N-1]; 34 | wire s2 = in2[N-1]; 35 | wire zero_tmp1 = |in1[N-2:0]; 36 | wire zero_tmp2 = |in2[N-2:0]; 37 | wire inf1 = in1[N-1] & (~zero_tmp1), 38 | inf2 = in2[N-1] & (~zero_tmp2); 39 | wire zero1 = ~(in1[N-1] | zero_tmp1), 40 | zero2 = ~(in2[N-1] | zero_tmp2); 41 | assign inf = inf1 | inf2, 42 | zero = zero1 & zero2; 43 | 44 | //Data Extraction 45 | wire rc1, rc2; 46 | wire [Bs-1:0] regime1, regime2, Lshift1, Lshift2; 47 | wire [es-1:0] e1, e2; 48 | wire [N-es-1:0] mant1, mant2; 49 | wire [N-1:0] xin1 = s1 ? -in1 : in1; 50 | wire [N-1:0] xin2 = s2 ? -in2 : in2; 51 | data_extract #(.N(N),.es(es)) uut_de1(.in(xin1), .rc(rc1), .regime(regime1), .exp(e1), .mant(mant1), .Lshift(Lshift1)); 52 | data_extract #(.N(N),.es(es)) uut_de2(.in(xin2), .rc(rc2), .regime(regime2), .exp(e2), .mant(mant2), .Lshift(Lshift2)); 53 | 54 | wire [N-es:0] m1 = {zero_tmp1,mant1}, 55 | m2 = {zero_tmp2,mant2}; 56 | 57 | //Large Checking and Assignment 58 | wire in1_gt_in2 = xin1[N-2:0] >= xin2[N-2:0] ? 1'b1 : 1'b0; 59 | 60 | wire ls = in1_gt_in2 ? s1 : s2; 61 | wire op = s1 ~^ s2; 62 | 63 | wire lrc = in1_gt_in2 ? rc1 : rc2; 64 | wire src = in1_gt_in2 ? rc2 : rc1; 65 | 66 | wire [Bs-1:0] lr = in1_gt_in2 ? regime1 : regime2; 67 | wire [Bs-1:0] sr = in1_gt_in2 ? regime2 : regime1; 68 | 69 | wire [es-1:0] le = in1_gt_in2 ? e1 : e2; 70 | wire [es-1:0] se = in1_gt_in2 ? e2 : e1; 71 | 72 | wire [N-es:0] lm = in1_gt_in2 ? m1 : m2; 73 | wire [N-es:0] sm = in1_gt_in2 ? m2 : m1; 74 | 75 | //Exponent Difference: Lower Mantissa Right Shift Amount 76 | wire [Bs:0] r_diff11, r_diff12, r_diff2; 77 | sub_N #(.N(Bs)) uut_sub1 (lr, sr, r_diff11); 78 | add_N #(.N(Bs)) uut_add1 (lr, sr, r_diff12); 79 | sub_N #(.N(Bs)) uut_sub2 (sr, lr, r_diff2); 80 | wire [Bs:0] r_diff = lrc ? (src ? r_diff11 : r_diff12) : r_diff2; 81 | 82 | wire [es+Bs+1:0] diff; 83 | sub_N #(.N(es+Bs+1)) uut_sub_diff ({r_diff,le}, {{Bs+1{1'b0}},se}, diff); 84 | wire [Bs-1:0] exp_diff = (|diff[es+Bs:Bs]) ? {Bs{1'b1}} : diff[Bs-1:0]; 85 | 86 | //DSR Right Shifting of Small Mantissa 87 | wire [N-1:0] DSR_right_in; 88 | generate 89 | if (es >= 2) 90 | assign DSR_right_in = {sm,{es-1{1'b0}}}; 91 | else 92 | assign DSR_right_in = sm; 93 | endgenerate 94 | 95 | wire [N-1:0] DSR_right_out; 96 | wire [Bs-1:0] DSR_e_diff = exp_diff; 97 | DSR_right_N_S #(.N(N), .S(Bs)) dsr1(.a(DSR_right_in), .b(DSR_e_diff), .c(DSR_right_out)); 98 | 99 | //Mantissa Addition 100 | wire [N-1:0] add_m_in1; 101 | generate 102 | if (es >= 2) 103 | assign add_m_in1 = {lm,{es-1{1'b0}}}; 104 | else 105 | assign add_m_in1 = lm; 106 | endgenerate 107 | 108 | wire [N:0] add_m1, add_m2; 109 | add_N #(.N(N)) uut_add_m1 (add_m_in1, DSR_right_out, add_m1); 110 | sub_N #(.N(N)) uut_sub_m2 (add_m_in1, DSR_right_out, add_m2); 111 | wire [N:0] add_m = op ? add_m1 : add_m2; 112 | wire [1:0] mant_ovf = add_m[N:N-1]; 113 | 114 | //LOD of mantissa addition result 115 | wire [N-1:0] LOD_in = {(add_m[N] | add_m[N-1]), add_m[N-2:0]}; 116 | wire [Bs-1:0] left_shift; 117 | LOD_N #(.N(N)) l2(.in(LOD_in), .out(left_shift)); 118 | 119 | //DSR Left Shifting of mantissa result 120 | wire [N-1:0] DSR_left_out_t; 121 | DSR_left_N_S #(.N(N), .S(Bs)) dsl1(.a(add_m[N:1]), .b(left_shift), .c(DSR_left_out_t)); 122 | wire [N-1:0] DSR_left_out = DSR_left_out_t[N-1] ? DSR_left_out_t[N-1:0] : {DSR_left_out_t[N-2:0],1'b0}; 123 | 124 | 125 | //Exponent and Regime Computation 126 | wire [Bs:0] lr_N = lrc ? {1'b0,lr} : -{1'b0,lr}; 127 | wire [es+Bs+1:0] le_o_tmp, le_o; 128 | sub_N #(.N(es+Bs+1)) sub3 ({lr_N,le}, {{es+1{1'b0}},left_shift}, le_o_tmp); 129 | add_mantovf #(es+Bs+1) uut_add_mantovf (le_o_tmp, mant_ovf[1], le_o); 130 | 131 | wire [es+Bs:0] le_oN = le_o[es+Bs] ? -le_o : le_o; 132 | wire [es-1:0] e_o = (le_o[es+Bs] & |le_oN[es-1:0]) ? le_o[es-1:0] : le_oN[es-1:0]; 133 | wire [Bs-1:0] r_o = (~le_o[es+Bs] || (le_o[es+Bs] & |le_oN[es-1:0])) ? le_oN[es+Bs-1:es] + 1'b1 : le_oN[es+Bs-1:es]; 134 | 135 | //Exponent and Mantissa Packing 136 | wire [2*N-1:0]tmp_o = { {N{~le_o[es+Bs]}}, le_o[es+Bs], e_o, DSR_left_out[N-2:es]}; 137 | wire [2*N-1:0] tmp1_o; 138 | DSR_right_N_S #(.N(2*N), .S(Bs)) dsr2 (.a(tmp_o), .b(r_o), .c(tmp1_o)); 139 | 140 | //Final Output 141 | wire [2*N-1:0] tmp1_oN = ls ? -tmp1_o : tmp1_o; 142 | assign out = inf|zero|(~DSR_left_out[N-1]) ? {inf,{N-1{1'b0}}} : {ls, tmp1_oN[N-1:1]}, 143 | done = start0; 144 | 145 | endmodule 146 | 147 | 148 | 149 | --------------------------------------------------------------------------------