OpenCores
URL https://opencores.org/ocsvn/m32632/m32632/trunk

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [SP_FPU.v] - Diff between revs 9 and 11

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 9 Rev 11
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
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.