Line 36... |
Line 36... |
// 1. ADDSUB Adder and Subtractor for 36 bit
|
// 1. ADDSUB Adder and Subtractor for 36 bit
|
// 2. SFPU_ADDSUB Single Precision Floating Point Adder/Subtractor and Converter
|
// 2. SFPU_ADDSUB Single Precision Floating Point Adder/Subtractor and Converter
|
// 3. SFPU_MUL Single Precision Floating Point Multiplier
|
// 3. SFPU_MUL Single Precision Floating Point Multiplier
|
// 4. SP_FPU Top Level of Single Precision Floating Point Unit
|
// 4. SP_FPU Top Level of Single Precision Floating Point Unit
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 1. ADDSUB Adder and Subtractor for 36 bit
|
// 1. ADDSUB Adder and Subtractor for 36 bit
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module ADDSUB (dataa, datab, add_sub, result);
|
module ADDSUB (dataa, datab, add_sub, result);
|
|
|
input [35:0] dataa,datab;
|
input [35:0] dataa,datab;
|
input add_sub; // 1 = Addition , 0 = Subtraction
|
input add_sub; // 1 = Addition , 0 = Subtraction
|
output [35:0] result;
|
output [35:0] result;
|
|
|
assign result = dataa + (add_sub ? datab : ~datab) + {35'd0,~add_sub};
|
assign result = dataa + (add_sub ? datab : ~datab) + {35'd0,~add_sub};
|
|
|
endmodule
|
endmodule
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 2. SFPU_ADDSUB Single Precision Floating Point Adder/Subtractor and Converter
|
// 2. SFPU_ADDSUB Single Precision Floating Point Adder/Subtractor and Converter
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module SFPU_ADDSUB ( SRC1, SRC2, NZEXP, BWD, SELECT, OUT, IOUT, CMPRES );
|
module SFPU_ADDSUB ( SRC1, SRC2, NZEXP, BWD, SELECT, OUT, IOUT, CMPRES );
|
|
|
input [31:0] SRC1,SRC2; // Input data
|
input [31:0] SRC1,SRC2; // Input data
|
input [2:1] NZEXP;
|
input [2:1] NZEXP;
|
input [1:0] BWD; // size of integer
|
input [1:0] BWD; // size of integer
|
Line 128... |
Line 128... |
|
|
assign exdiff = {1'b0,SRC2[30:23]} - {1'b0,SRC1[30:23]}; // Difference of Exponents
|
assign exdiff = {1'b0,SRC2[30:23]} - {1'b0,SRC1[30:23]}; // Difference of Exponents
|
assign madiff = {1'b0,SRC2[22:0]} - {1'b0,SRC1[22:0]}; // Difference of Mantissas
|
assign madiff = {1'b0,SRC2[22:0]} - {1'b0,SRC1[22:0]}; // Difference of Mantissas
|
|
|
// if exdiff = 0 the shifter to the right is not needed !
|
// if exdiff = 0 the shifter to the right is not needed !
|
assign variante = (exdiff[8:1] == 8'h00) | (exdiff == 9'h1FF) | SELECT[1]; // MUX at the end, ROUND
|
assign variante = (exdiff[8:1] == 8'h00) | (exdiff == 9'h1FF) | SELECT[1]; // MUX at the end, ROUND/TRUNC/MOViF uses case 1
|
|
|
// ++++++++++++++++++++++++++ 1. case works on MOViF +++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++ 1. case works on MOViF +++++++++++++++++++++++++++++++++++++++
|
|
|
assign switch = exdiff[8] | ((exdiff[7:0] == 8'h0) & madiff[23]); // exchange ?
|
assign switch = exdiff[8] | ((exdiff[7:0] == 8'h0) & madiff[23]); // exchange ?
|
|
|
Line 167... |
Line 167... |
assign vorz = switch ? (SELECT[0] ^ sign1) : sign2;
|
assign vorz = switch ? (SELECT[0] ^ sign1) : sign2;
|
assign addflag = ~(SELECT[0] ^ (sign1 ^ sign2));
|
assign addflag = ~(SELECT[0] ^ (sign1 ^ sign2));
|
|
|
// CMPF : 1. step : what happend if Invalid Operand occurs - no Flag update !
|
// CMPF : 1. step : what happend if Invalid Operand occurs - no Flag update !
|
|
|
assign CMPRES[1] = ~CMPRES[0] & (switch ? ~sign1 : sign2); // see table above : N-Bit=1 if SRC1 >
|
assign CMPRES[1] = ~CMPRES[0] & (switch ? ~sign1 : sign2); // see table above : N-Bit=1 if SRC1 > SRC2
|
assign CMPRES[0] = (SRC1 == SRC2) | (~NZEXP[2] & ~NZEXP[1]); // Z-Bit : SRC1=SRC2, +0.0 = -0.0
|
assign CMPRES[0] = (SRC1 == SRC2) | (~NZEXP[2] & ~NZEXP[1]); // Z-Bit : SRC1=SRC2, +0.0 = -0.0
|
|
|
// ++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++
|
// ADD/SUB : 3. step : prepare of Barrelshifter Left
|
// ADD/SUB : 3. step : prepare of Barrelshifter Left
|
|
|
Line 232... |
Line 232... |
wire [8:0] exdiff12;
|
wire [8:0] exdiff12;
|
wire [23:0] muxsrc1;
|
wire [23:0] muxsrc1;
|
wire [32:9] pipe1; // numbering special for Right Shifter
|
wire [32:9] pipe1; // numbering special for Right Shifter
|
wire [4:0] shift;
|
wire [4:0] shift;
|
|
|
// the difference between SRC1 and SRC2 is bigger/equal 4:1 => no Barrelshifter after ADDSUB neccess
|
// the difference between SRC1 and SRC2 is bigger/equal 4:1 => no Barrelshifter after ADDSUB neccessary
|
|
|
assign vswitch = exdiff[8]; // exchange ?
|
assign vswitch = exdiff[8]; // exchange ?
|
|
|
assign shift1 = (exdiff[7:5] != 3'h0) ? 5'h1F : exdiff[4:0];
|
assign shift1 = (exdiff[7:5] != 3'h0) ? 5'h1F : exdiff[4:0];
|
assign exdiff12 = {1'b0,SRC1[30:23]} - {1'b0,SRC2[30:23]}; // caclulate already
|
assign exdiff12 = {1'b0,SRC1[30:23]} - {1'b0,SRC2[30:23]}; // caclulate already
|
assign shift2 = (exdiff12[7:5] != 3'h0) ? 5'h1F : exdiff12[4:0];
|
assign shift2 = (exdiff12[7:5] != 3'h0) ? 5'h1F : exdiff12[4:0];
|
|
|
assign muxsrc2 = vswitch ? {SRC1[30:23],1'b1,SRC1[22:0]} : {SRC2[30:23],1'b1,SRC2[22:0]}; // Includ
|
assign muxsrc2 = vswitch ? {SRC1[30:23],1'b1,SRC1[22:0]} : {SRC2[30:23],1'b1,SRC2[22:0]}; // Including exponent
|
assign muxsrc1 = vswitch ? {NZEXP[2],SRC2[22:0]} : {NZEXP[1],SRC1[22:0]};
|
assign muxsrc1 = vswitch ? {NZEXP[2],SRC2[22:0]} : {NZEXP[1],SRC1[22:0]};
|
|
|
assign pipe1 = SELECT[1] ? (ganzklein ? 24'h0 : {NZEXP[1],SRC1[22:0]}) : muxsrc1; // Feeding in R.T
|
assign pipe1 = SELECT[1] ? (ganzklein ? 24'h0 : {NZEXP[1],SRC1[22:0]}) : muxsrc1; // Feeding in R.T.F.
|
|
|
assign shift = SELECT[1] ? rexdiff[4:0] : (vswitch ? shift2 : shift1);
|
assign shift = SELECT[1] ? rexdiff[4:0] : (vswitch ? shift2 : shift1);
|
|
|
// ++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++
|
// ADD/SUB + ROUND/TRUNC/FLOOR : 2. step : Barrelshifter to right -->
|
// ADD/SUB + ROUND/TRUNC/FLOOR : 2. step : Barrelshifter to right -->
|
Line 275... |
Line 275... |
assign inex = brshifte[1:0]; // Inexact-Flag-Data via multiplexer at the end
|
assign inex = brshifte[1:0]; // Inexact-Flag-Data via multiplexer at the end
|
|
|
always @(SELECT or sign1 or brshifte or inex or ganzklein)
|
always @(SELECT or sign1 or brshifte or inex or ganzklein)
|
casex (SELECT[3:2])
|
casex (SELECT[3:2])
|
2'b00 : car_ry = sign1 ^ ((brshifte[2:0] == 3'b110) | (inex == 2'b11)); // ROUNDLi
|
2'b00 : car_ry = sign1 ^ ((brshifte[2:0] == 3'b110) | (inex == 2'b11)); // ROUNDLi
|
2'b1x : car_ry = sign1 ? (~ganzklein & (inex == 2'b00)) : 1'b0; // +numbers like TRUNCLi, -num
|
2'b1x : car_ry = sign1 ? (~ganzklein & (inex == 2'b00)) : 1'b0; // +numbers like TRUNCLi, -numbers round to "-infinity"
|
default : car_ry = sign1; // TRUNCLi , simple cut
|
default : car_ry = sign1; // TRUNCLi , simple cut
|
endcase
|
endcase
|
|
|
assign compl = sign1 ? ~brshifte[32:2] : brshifte[32:2];
|
assign compl = sign1 ? ~brshifte[32:2] : brshifte[32:2];
|
|
|
Line 311... |
Line 311... |
|
|
ADDSUB addsub_v (.dataa({1'b0,muxsrc2,3'b000}),
|
ADDSUB addsub_v (.dataa({1'b0,muxsrc2,3'b000}),
|
.datab({9'h0,brshifte[32:7],lsb}), .add_sub(addflag),
|
.datab({9'h0,brshifte[32:7],lsb}), .add_sub(addflag),
|
.result(vresult) );
|
.result(vresult) );
|
|
|
assign eminus1 = muxsrc2[31:24] - 8'h01; // a greater Underflow can not exist, because minimal Expo
|
assign eminus1 = muxsrc2[31:24] - 8'h01; // a greater Underflow can not exist, because minimal Exponent = 0..01
|
|
|
// Case ADD : Bit 23 : LSB of exponent
|
// Case ADD : Bit 23 : LSB of exponent
|
assign vadd_q = (muxsrc2[24] != vresult[27]) ? {vresult[35:3],(vresult[2:0] != 3'b000)}
|
assign vadd_q = (muxsrc2[24] != vresult[27]) ? {vresult[35:3],(vresult[2:0] != 3'b000)}
|
: {vresult[35:27],vresult[25:2],(vresult[1:0] != 2'b00)} ;
|
: {vresult[35:27],vresult[25:2],(vresult[1:0] != 2'b00)} ;
|
|
|
// Case SUB : Bit 26 : "hidden" MSB of mantissa
|
// Case SUB : Bit 26 : "hidden" MSB of mantissa
|
assign vsub_q = vresult[26] ? {vresult[35:27], vresult[25:2],(vresult[1:0] != 2'b00)} // like t
|
assign vsub_q = vresult[26] ? {vresult[35:27], vresult[25:2],(vresult[1:0] != 2'b00)} // like the vadd_q "0" case
|
: {vresult[35],eminus1,vresult[24:0]} ;
|
: {vresult[35],eminus1,vresult[24:0]} ;
|
|
|
// SELECT[1] has here no meaning
|
// SELECT[1] has here no meaning
|
assign vzero = (vresult[26:0] == 27'h0) & ~addflag; // only if "-" can be the result 0
|
assign vzero = (vresult[26:0] == 27'h0) & ~addflag; // only if "-" can be the result 0
|
|
|
Line 331... |
Line 331... |
|
|
assign OUT = variante ? out_v1 : out_v0; // Last multiplexer
|
assign OUT = variante ? out_v1 : out_v0; // Last multiplexer
|
|
|
endmodule
|
endmodule
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 3. SFPU_MUL Single Precision Floating Point Multiplier
|
// 3. SFPU_MUL Single Precision Floating Point Multiplier
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module SFPU_MUL ( SRC1, SRC2, MRESULT, NZEXP, OUT);
|
module SFPU_MUL ( SRC1, SRC2, MRESULT, NZEXP, OUT);
|
|
|
input [31:0] SRC1,SRC2; // only exponent of input data used
|
input [31:0] SRC1,SRC2; // only exponent of input data used
|
input [47:0] MRESULT;
|
input [47:0] MRESULT;
|
input [2:1] NZEXP; // Flags of input data
|
input [2:1] NZEXP; // Flags of input data
|
Line 364... |
Line 364... |
assign OUT = MRESULT[47] ? {zero,sign,expoh,MRESULT[46:24],resthigh}
|
assign OUT = MRESULT[47] ? {zero,sign,expoh,MRESULT[46:24],resthigh}
|
: {zero,sign,expol,MRESULT[45:23],restlow};
|
: {zero,sign,expol,MRESULT[45:23],restlow};
|
|
|
endmodule
|
endmodule
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 4. SP_FPU Top Level of Single Precision Floating Point Unit
|
// 4. SP_FPU Top Level of Single Precision Floating Point Unit
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module SP_FPU (BCLK, OPCODE, SRC1, SRC2, FSR, MRESULT, BWD, FL, FP_OUT, I_OUT, TT_SP, SP_CMP, SP_MUX
|
module SP_FPU (BCLK, OPCODE, SRC1, SRC2, FSR, MRESULT, BWD, FL, FP_OUT, I_OUT, TT_SP, SP_CMP, SP_MUX, LD_FSR, UP_SP);
|
|
|
input BCLK; // is not used !
|
input BCLK; // is not used !
|
input [7:0] OPCODE;
|
input [7:0] OPCODE;
|
input [31:0] SRC1,SRC2; // Input data
|
input [31:0] SRC1,SRC2; // Input data
|
input [8:3] FSR; // Floating Point Status Register
|
input [8:3] FSR; // Floating Point Status Register
|
Line 412... |
Line 412... |
default : select = 4'b0;
|
default : select = 4'b0;
|
endcase
|
endcase
|
|
|
assign SP_MUX = select[3] & (select[1:0] != 2'b11) & FL; // Output multiplexer
|
assign SP_MUX = select[3] & (select[1:0] != 2'b11) & FL; // Output multiplexer
|
|
|
assign LD_FSR = (OPCODE[7:4] == 4'h9) & (OPCODE[3:1] == 3'b001); // LFSR does only Double (accordin
|
assign LD_FSR = (OPCODE[7:4] == 4'h9) & (OPCODE[3:1] == 3'b001); // LFSR does only Double (according datasheet NS32016)
|
assign UP_SP = select[3] & FL; // All FPU opcodes of SP_FPU
|
assign UP_SP = select[3] & FL; // All FPU opcodes of SP_FPU
|
assign op_cmp = (OPCODE == 8'hB2) & FL;
|
assign op_cmp = (OPCODE == 8'hB2) & FL;
|
|
|
// SRCFLAGS
|
// SRCFLAGS
|
|
|