Skip to content

Instantly share code, notes, and snippets.

@inkwisit
Last active April 4, 2018 12:09
Show Gist options
  • Save inkwisit/112005b3ca8908137fb1bac68d099177 to your computer and use it in GitHub Desktop.
Save inkwisit/112005b3ca8908137fb1bac68d099177 to your computer and use it in GitHub Desktop.
module fpr_add(A,B,C);
input [31:0]A;
input [31:0]B;
output [31:0]C;
reg diff_sign;
wire [8:0]AgB; // exponential for A greater than B
wire [8:0]BgA; // exponential for B greater than A
wire [7:0]exp_diff; // difference of the exponentials
wire [31:0]result_sum;
reg [30:0]result_diff;
wire [31:0]result_diff_final;
wire [23:0]Am; // A mantissa
wire [23:0]Bm; // B mantissa
reg [23:0]Ams; // A mantissa shifted
reg [23:0]Bms; // B mantissa shifted
wire [24:0]msum; // mantissa sum , requires extra bit
wire [24:0]mdiff; //mantissa difference , does not require extra bit but extra bit is added to detect incase of equal expo and different mantisa
wire add_or_sub; // checks whether sum or difference has to be taken , for addition 1 , for subtraction 0
wire [24:0]mdiff_final;//2[25]x1 MUX sends the actual mdiff if man A is greater than man B mdiff[24]=1 else
assign mdiff_final = mdiff[24]?(mdiff):({1'b0,~mdiff[23:0]+1'b1});
assign AgB = {1'b0,A[30:23]}+{1'b0,~B[30:23]}+1'b1;
assign BgA = {1'b0,B[30:23]}+{1'b0,~A[30:23]}+1'b1;
assign exp_diff = AgB[8]?(AgB[7:0]):(BgA[7:0]);
assign add_or_sub = ~(A[31]^B[31]);
assign Am = {1'b1,A[22:0]};
assign Bm = {1'b1,B[22:0]};
assign mdiff = AgB[8]?({1'b0,Am}+{1'b0,~Bms}+24'b1):({1'b0,Bm}+{1'b0,~Ams}+24'b1); //sub is performed parallel , AgB gives A greater or equal to B exponent
assign msum = (AgB[8])?({1'b0,Am}+{1'b0,Bms}):({1'b0,Bm}+{1'b0,Ams});
assign result_diff_final = {diff_sign,result_diff}; //diff_sign can be decided using various cases like , same exponent with different mantissa and different exponent
assign C = (add_or_sub)?(result_sum):(result_diff_final); // test
assign result_sum = msum[24]?(AgB[8]?({A[31:23]+1'b1,msum[23:1]}):({B[31:23]+1'b1,msum[23:1]})):(AgB[8]?({A[31:23],msum[22:0]}):({B[31:23],msum[22:0]}));
//converting the performed operation in algebra and converting it into fpr
always@(Am or Bm or exp_diff or AgB[8]) // single cycle shifter..
begin
case(exp_diff)
8'b00000000:Ams = Am;
8'b00000001:Ams = {1'b0,Am[23:1]};
8'b00000010:Ams = {2'b0,Am[23:2]};
8'b00000011:Ams = {3'b0,Am[23:3]};
8'b00000100:Ams = {4'b0,Am[23:4]};
8'b00000101:Ams = {5'b0,Am[23:5]};
8'b00000110:Ams = {6'b0,Am[23:6]};
8'b00000111:Ams = {7'b0,Am[23:7]};
8'b00001000:Ams = {8'b0,Am[23:8]};
8'b00001001:Ams = {9'b0,Am[23:9]};
8'b00001010:Ams = {10'b0,Am[23:10]};
8'b00001011:Ams = {11'b0,Am[23:11]};
8'b00001100:Ams = {12'b0,Am[23:12]};
8'b00001101:Ams = {13'b0,Am[23:13]};
8'b00001110:Ams = {14'b0,Am[23:14]};
8'b00001111:Ams = {15'b0,Am[23:15]};
8'b00010000:Ams = {16'b0,Am[23:16]};
8'b00010001:Ams = {17'b0,Am[23:17]};
8'b00010010:Ams = {18'b0,Am[23:18]};
8'b00010011:Ams = {31'b0,Am[23:19]};
8'b00010100:Ams = {20'b0,Am[23:20]};
8'b00010101:Ams = {21'b0,Am[23:21]};
8'b00010110:Ams = {22'b0,Am[23:22]};
8'b00010111:Ams = {23'b0,Am[23]}; // maximum exp diff can be 23 ..
default:Ams = 24'b0;
endcase
end
always@(Am or Bm or exp_diff or AgB[8]) // single cycle shifter
begin
case(exp_diff)
8'b00000000:Bms = Bm;
8'b00000001:Bms = {1'b0,Bm[23:1]};
8'b00000010:Bms = {2'b0,Bm[23:2]};
8'b00000011:Bms = {3'b0,Bm[23:3]};
8'b00000100:Bms = {4'b0,Bm[23:4]};
8'b00000101:Bms = {5'b0,Bm[23:5]};
8'b00000110:Bms = {6'b0,Bm[23:6]};
8'b00000111:Bms = {7'b0,Bm[23:7]};
8'b00001000:Bms = {8'b0,Bm[23:8]};
8'b00001001:Bms = {9'b0,Bm[23:9]};
8'b00001010:Bms = {10'b0,Bm[23:10]};
8'b00001011:Bms = {11'b0,Bm[23:11]};
8'b00001100:Bms = {12'b0,Bm[23:12]};
8'b00001101:Bms = {13'b0,Bm[23:13]};
8'b00001110:Bms = {14'b0,Bm[23:14]};
8'b00001111:Bms = {15'b0,Bm[23:15]};
8'b00010000:Bms = {16'b0,Bm[23:16]};
8'b00010001:Bms = {17'b0,Bm[23:17]};
8'b00010010:Bms = {18'b0,Bm[23:18]};
8'b00010011:Bms = {31'b0,Bm[23:19]};
8'b00010100:Bms = {20'b0,Bm[23:20]};
8'b00010101:Bms = {21'b0,Bm[23:21]};
8'b00010110:Bms = {22'b0,Bm[23:22]};
8'b00010111:Bms = {23'b0,Bm[23]};
default : Bms = 24'b0;
endcase
end
always@(mdiff_final or AgB or BgA or diff_sign) // creating the final FPR number .. exponent would be less than the lesser in 2 numbers.
begin
casex({~AgB[8],mdiff_final})
26'b01000000000000000000000000:result_diff = {30'b0};
26'b011xxxxxxxxxxxxxxxxxxxxxxx:result_diff = {A[30:23]-2'b0,mdiff_final[22:0]};
26'b0101xxxxxxxxxxxxxxxxxxxxxx:result_diff = {A[30:23]-2'b01,mdiff_final[21:0],1'b0};
26'b01001xxxxxxxxxxxxxxxxxxxxx:result_diff = {A[30:23]-2'b10,mdiff_final[20:0],2'b0};
26'b010001xxxxxxxxxxxxxxxxxxxx:result_diff = {A[30:23]-2'b11,mdiff_final[19:0],3'b0};
26'b0100001xxxxxxxxxxxxxxxxxxx:result_diff = {A[30:23]-3'b100,mdiff_final[18:0],4'b0};
26'b01000001xxxxxxxxxxxxxxxxxx:result_diff = {A[30:23]-3'b101,mdiff_final[17:0],5'b0};
26'b010000001xxxxxxxxxxxxxxxxx:result_diff = {A[30:23]-3'b110,mdiff_final[16:0],6'b0};
26'b0100000001xxxxxxxxxxxxxxxx:result_diff = {A[30:23]-3'b111,mdiff_final[15:0],7'b0};
26'b01000000001xxxxxxxxxxxxxxx:result_diff = {A[30:23]-4'b1000,mdiff_final[14:0],8'b0};
26'b010000000001xxxxxxxxxxxxxx:result_diff = {A[30:23]-4'b1001,mdiff_final[13:0],9'b0};
26'b0100000000001xxxxxxxxxxxxx:result_diff = {A[30:23]-4'b1010,mdiff_final[12:0],10'b0};
26'b01000000000001xxxxxxxxxxxx:result_diff = {A[30:23]-4'b1011,mdiff_final[11:0],11'b0};
26'b010000000000001xxxxxxxxxxx:result_diff = {A[30:23]-4'b1100,mdiff_final[10:0],12'b0};
26'b0100000000000001xxxxxxxxxx:result_diff = {A[30:23]-4'b1101,mdiff_final[9:0],13'b0};
26'b01000000000000001xxxxxxxxx:result_diff = {A[30:23]-4'b1110,mdiff_final[8:0],14'b0};
26'b010000000000000001xxxxxxxx:result_diff = {A[30:23]-4'b1111,mdiff_final[7:0],15'b0};
26'b0100000000000000001xxxxxxx:result_diff = {A[30:23]-5'b10000,mdiff_final[6:0],16'b0};
26'b01000000000000000001xxxxxx:result_diff = {A[30:23]-5'b10001,mdiff_final[5:0],17'b0};
26'b010000000000000000001xxxxx:result_diff = {A[30:23]-5'b10010,mdiff_final[4:0],18'b0};
26'b0100000000000000000001xxxx:result_diff = {A[30:23]-5'b10011,mdiff_final[3:0],19'b0};
26'b01000000000000000000001xxx:result_diff = {A[30:23]-5'b10100,mdiff_final[2:0],20'b0};
26'b010000000000000000000001xx:result_diff = {A[30:23]-5'b10101,mdiff_final[1:0],21'b0};
26'b0100000000000000000000001x:result_diff = {A[30:23]-5'b10110,mdiff_final[0],22'b0};
26'b01000000000000000000000001:result_diff = {A[30:23]-5'b10111,23'b0};
26'b001xxxxxxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-2'b0,mdiff_final[22:0]};
26'b0001xxxxxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-2'b01,mdiff_final[21:0],1'b0};
26'b00001xxxxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-2'b10,mdiff_final[20:0],2'b0};
26'b000001xxxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-2'b11,mdiff_final[19:0],3'b0};
26'b0000001xxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-3'b100,mdiff_final[18:0],4'b0};
26'b00000001xxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-3'b101,mdiff_final[17:0],5'b0};
26'b000000001xxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-3'b110,mdiff_final[16:0],6'b0};
26'b0000000001xxxxxxxxxxxxxxxx:result_diff = {B[30:23]-3'b111,mdiff_final[15:0],7'b0};
26'b00000000001xxxxxxxxxxxxxxx:result_diff = {B[30:23]-4'b1000,mdiff_final[14:0],8'b0};
26'b000000000001xxxxxxxxxxxxxx:result_diff = {B[30:23]-4'b1001,mdiff_final[13:0],9'b0};
26'b0000000000001xxxxxxxxxxxxx:result_diff = {B[30:23]-4'b1010,mdiff_final[12:0],10'b0};
26'b00000000000001xxxxxxxxxxxx:result_diff = {B[30:23]-4'b1011,mdiff_final[11:0],11'b0};
26'b000000000000001xxxxxxxxxxx:result_diff = {B[30:23]-4'b1100,mdiff_final[10:0],12'b0};
26'b0000000000000001xxxxxxxxxx:result_diff = {B[30:23]-4'b1101,mdiff_final[9:0],13'b0};
26'b00000000000000001xxxxxxxxx:result_diff = {B[30:23]-4'b1110,mdiff_final[8:0],14'b0};
26'b000000000000000001xxxxxxxx:result_diff = {B[30:23]-4'b1111,mdiff_final[7:0],15'b0};
26'b0000000000000000001xxxxxxx:result_diff = {B[30:23]-5'b10000,mdiff_final[6:0],16'b0};
26'b00000000000000000001xxxxxx:result_diff = {B[30:23]-5'b10001,mdiff_final[5:0],17'b0};
26'b000000000000000000001xxxxx:result_diff = {B[30:23]-5'b10010,mdiff_final[4:0],18'b0};
26'b0000000000000000000001xxxx:result_diff = {B[30:23]-5'b10011,mdiff_final[3:0],19'b0};
26'b00000000000000000000001xxx:result_diff = {B[30:23]-5'b10100,mdiff_final[2:0],20'b0};
26'b000000000000000000000001xx:result_diff = {B[30:23]-5'b10101,mdiff_final[1:0],21'b0};
26'b0000000000000000000000001x:result_diff = {B[30:23]-5'b10110,mdiff_final[0],22'b0};
26'b00000000000000000000000001:result_diff = {B[30:23]-5'b10111,23'b0};
26'b111xxxxxxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-2'b0,mdiff_final[22:0]};
26'b1101xxxxxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-2'b01,mdiff_final[21:0],1'b0};
26'b11001xxxxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-2'b10,mdiff_final[20:0],2'b0};
26'b110001xxxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-2'b11,mdiff_final[19:0],3'b0};
26'b1100001xxxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-3'b100,mdiff_final[18:0],4'b0};
26'b11000001xxxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-3'b101,mdiff_final[17:0],5'b0};
26'b110000001xxxxxxxxxxxxxxxxx:result_diff = {B[30:23]-3'b110,mdiff_final[16:0],6'b0};
26'b1100000001xxxxxxxxxxxxxxxx:result_diff = {B[30:23]-3'b111,mdiff_final[15:0],7'b0};
26'b11000000001xxxxxxxxxxxxxxx:result_diff = {B[30:23]-4'b1000,mdiff_final[14:0],8'b0};
26'b110000000001xxxxxxxxxxxxxx:result_diff = {B[30:23]-4'b1001,mdiff_final[13:0],9'b0};
26'b1100000000001xxxxxxxxxxxxx:result_diff = {B[30:23]-4'b1010,mdiff_final[12:0],10'b0};
26'b11000000000001xxxxxxxxxxxx:result_diff = {B[30:23]-4'b1011,mdiff_final[11:0],11'b0};
26'b110000000000001xxxxxxxxxxx:result_diff = {B[30:23]-4'b1100,mdiff_final[10:0],12'b0};
26'b1100000000000001xxxxxxxxxx:result_diff = {B[30:23]-4'b1101,mdiff_final[9:0],13'b0};
26'b11000000000000001xxxxxxxxx:result_diff = {B[30:23]-4'b1110,mdiff_final[8:0],14'b0};
26'b110000000000000001xxxxxxxx:result_diff = {B[30:23]-4'b1111,mdiff_final[7:0],15'b0};
26'b1100000000000000001xxxxxxx:result_diff = {B[30:23]-5'b10000,mdiff_final[6:0],16'b0};
26'b11000000000000000001xxxxxx:result_diff = {B[30:23]-5'b10001,mdiff_final[5:0],17'b0};
26'b110000000000000000001xxxxx:result_diff = {B[30:23]-5'b10010,mdiff_final[4:0],18'b0};
26'b1100000000000000000001xxxx:result_diff = {B[30:23]-5'b10011,mdiff_final[3:0],19'b0};
26'b11000000000000000000001xxx:result_diff = {B[30:23]-5'b10100,mdiff_final[2:0],20'b0};
26'b110000000000000000000001xx:result_diff = {B[30:23]-5'b10101,mdiff_final[1:0],21'b0};
26'b1100000000000000000000001x:result_diff = {B[30:23]-5'b10110,mdiff_final[0],22'b0};
26'b11000000000000000000000001:result_diff = {B[30:23]-5'b10111,23'b0};
endcase
end
always@(AgB[8] or BgA[8] or mdiff[24] or B[31] or A[31]) // deciding the sign bit.
begin
case({AgB[8],BgA[8]})
2'b00:diff_sign = 1'b0;
2'b01:diff_sign = B[31];
2'b10:diff_sign = A[31];
2'b11:diff_sign = (mdiff[24])?(A[31]):(B[31]);
endcase
end
endmodule
module fpr_multiply(A,B,C);
input [31:0]A;
input [31:0]B;
output [31:0]C;
wire [23:0]Am;
wire [23:0]Bm;
wire [8:0]Cet;
wire [47:0]mresult; // multiplication result
wire [8:0]Cef;
wire [22:0]result;
assign Am = {1'b1,A[22:0]};
assign Bm = {1'b1,B[22:0]};
assign Cet = {1'b0,A[30:23]}+{1'b0,B[30:23]}+9'b010000001; // C exponential temporary.
assign Cef = mresult[47]?(Cet+9'b1):(Cet); // C exponential final
assign mresult = Am*Bm;
assign result = mresult[47]?(mresult[46:24]):(mresult[45:23]);
assign C = {A[31]^B[31],Cef[7:0],result};
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment