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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [DP_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 42... Line 42...
//      7. DIVI_PREP    Prepare data for the divider
//      7. DIVI_PREP    Prepare data for the divider
//      8. DFPU_DIV             The divider for all divide opcodes : double, single and integer
//      8. DFPU_DIV             The divider for all divide opcodes : double, single and integer
//      9. DP_LOGIK             Control logic and result path for different functions
//      9. DP_LOGIK             Control logic and result path for different functions
// 10. DP_FPU           Top level of long operations datapath
// 10. DP_FPU           Top level of long operations datapath
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      1. PREPDATA     Prepare data for the big multiplier
//      1. PREPDATA     Prepare data for the big multiplier
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module PREPDATA ( START, MEI, DFLOAT, BWD, SRC1, SRC2,
module PREPDATA ( START, MEI, DFLOAT, BWD, SRC1, SRC2,
                                  MSD_1, MSD_2, LSD_1, LSD_2, LOAD_MSD, LOAD_LSD1, LOAD_LSD2 );
                                  MSD_1, MSD_2, LSD_1, LSD_2, LOAD_MSD, LOAD_LSD1, LOAD_LSD2 );
 
 
        input    [1:0]   START;
        input    [1:0]   START;
        input                   MEI,DFLOAT;
        input                   MEI,DFLOAT;
Line 86... Line 86...
        assign LOAD_LSD1 = (START[0] & MEI) | (START[1] & DFLOAT);       // 2. step execute at DFLOAT
        assign LOAD_LSD1 = (START[0] & MEI) | (START[1] & DFLOAT);       // 2. step execute at DFLOAT
        assign LOAD_LSD2 = (START[1] & MEI) | (START[1] & DFLOAT);      // 2. step execute at DFLOAT
        assign LOAD_LSD2 = (START[1] & MEI) | (START[1] & DFLOAT);      // 2. step execute at DFLOAT
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      2. BCDADDER     4 bit BCD adder
//      2. BCDADDER     4 bit BCD adder
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module BCDADDER ( A_IN, B_IN, CY_IN, SUBP, OUT, CY_OUT );
module BCDADDER ( A_IN, B_IN, CY_IN, SUBP, OUT, CY_OUT );
 
 
        input    [3:0]   A_IN,B_IN;
        input    [3:0]   A_IN,B_IN;
        input                   CY_IN;
        input                   CY_IN;
        input                   SUBP;
        input                   SUBP;
Line 114... Line 114...
        assign OUT = result[3:0] - (SUBP ? {1'b0,result[4],result[4],1'b0} : {over,1'b0,over,1'b0});
        assign OUT = result[3:0] - (SUBP ? {1'b0,result[4],result[4],1'b0} : {over,1'b0,over,1'b0});
        assign CY_OUT = SUBP ? result[4] : over;
        assign CY_OUT = SUBP ? result[4] : over;
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      3. DFPU_BCD             Binary coded decimal (BCD) adder and subtractor
//      3. DFPU_BCD             Binary coded decimal (BCD) adder and subtractor
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DFPU_BCD ( BCLK, BRESET, START, DO_BCD, BWD, SRC1, SRC2, CY_IN, SUBP, BCD_Q, CY_OUT, BCD_DONE
module DFPU_BCD ( BCLK, BRESET, START, DO_BCD, BWD, SRC1, SRC2, CY_IN, SUBP, BCD_Q, CY_OUT, BCD_DONE );
 
 
        // Byte : 3 cycles in shortest case REG-REG, Word : 4 cycles and Double : 6 cycles
        // Byte : 3 cycles in shortest case REG-REG, Word : 4 cycles and Double : 6 cycles
        input                   BCLK;
        input                   BCLK;
        input                   BRESET;
        input                   BRESET;
        input                   START;  // START[1]
        input                   START;  // START[1]
Line 180... Line 180...
 
 
        assign BCD_DONE = run_bcd & (BWD == byte_cou);
        assign BCD_DONE = run_bcd & (BWD == byte_cou);
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      4. DFPU_ADDSUB  Double precision floating point adder and subtractor
//      4. DFPU_ADDSUB  Double precision floating point adder and subtractor
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DFPU_ADDSUB ( BCLK, START, SRC1, SRC2, MAN1, MAN2, SRCFLAGS, BWD, SELECT, OUT, IOUT, CMPRES )
module DFPU_ADDSUB ( BCLK, START, SRC1, SRC2, MAN1, MAN2, SRCFLAGS, BWD, SELECT, OUT, IOUT, CMPRES );
 
 
        input                   BCLK;
        input                   BCLK;
        input    [1:0]   START;
        input    [1:0]   START;
        input   [31:0]   SRC1,SRC2;      // The input data
        input   [31:0]   SRC1,SRC2;      // The input data
        input   [20:0]   MAN1,MAN2;
        input   [20:0]   MAN1,MAN2;
Line 224... Line 224...
                  4'b011x : movdat = {16'hFFFF,SRC1[15:8]};
                  4'b011x : movdat = {16'hFFFF,SRC1[15:8]};
                default   : movdat = SRC1[31:8];                                // Double
                default   : movdat = SRC1[31:8];                                // Double
                endcase
                endcase
 
 
        // This  pipeline stage for better timing 
        // This  pipeline stage for better timing 
        always @(posedge BCLK) movif <= movdat[31] ? (32'h0 - {movdat,SRC1[7:0]}) : {movdat,SRC1[7:0]};   // 
        always @(posedge BCLK) movif <= movdat[31] ? (32'h0 - {movdat,SRC1[7:0]}) : {movdat,SRC1[7:0]};   // -2^31 is kept !
 
 
        always @(posedge BCLK) sign_movif <= movdat[31];
        always @(posedge BCLK) sign_movif <= movdat[31];
 
 
        // ROUNDLi/TRUNCLi/FLOORLi : 1. pipeline stage : can Opcode-Decoder deliver direct the 64 bit opera
        // ROUNDLi/TRUNCLi/FLOORLi : 1. pipeline stage : can Opcode-Decoder deliver direct the 64 bit operand ? From register "yes"
 
 
        reg                     ovflag,ovflag2;
        reg                     ovflag,ovflag2;
        reg                     rovfl;
        reg                     rovfl;
        reg                     minint;
        reg                     minint;
        wire [11:0]      rexdiff,rexo;
        wire [11:0]      rexdiff,rexo;
        wire            ganzklein;      // Flag for 0
        wire            ganzklein;      // Flag for 0
 
 
        assign rexdiff = 12'h41D - {1'b0,SRC1[30:20]};  // 4..0 is the right shift value : like Single FP sa
        assign rexdiff = 12'h41D - {1'b0,SRC1[30:20]};  // 4..0 is the right shift value : like Single FP same value space
 
 
        // ovflag2 at the end of rounding : Check for Overflow
        // ovflag2 at the end of rounding : Check for Overflow
        always @(posedge BCLK) rovfl <= (ovflag | ovflag2) & (SELECT[1:0] == 2'b11) & ~minint;
        always @(posedge BCLK) rovfl <= (ovflag | ovflag2) & (SELECT[1:0] == 2'b11) & ~minint;
 
 
        // a large positiv difference is a very small number :
        // a large positiv difference is a very small number :
Line 277... Line 277...
        reg                             vorz,addflag;
        reg                             vorz,addflag;
 
 
        wire    [52:0]   muxsrc1;
        wire    [52:0]   muxsrc1;
        wire    [32:0]   lowdiff;
        wire    [32:0]   lowdiff;
 
 
        assign nan = (SELECT[1:0] == 2'b11) ? SRCFLAGS[1] : (~SELECT[1] & (SRCFLAGS[3] | SRCFLAGS[1]));  // 
        assign nan = (SELECT[1:0] == 2'b11) ? SRCFLAGS[1] : (~SELECT[1] & (SRCFLAGS[3] | SRCFLAGS[1]));  // used at the end
 
 
        assign exdiff   = {1'b0,SRC2[30:20]} - {1'b0,SRC1[30:20]};      // Difference of Exponents
        assign exdiff   = {1'b0,SRC2[30:20]} - {1'b0,SRC1[30:20]};      // Difference of Exponents
        assign madiff   = {1'b0,SRC2[19:0]}  - {1'b0,SRC1[19:0]}; // Difference of Mantissa 
        assign madiff   = {1'b0,SRC2[19:0]}  - {1'b0,SRC1[19:0]}; // Difference of Mantissa 
        assign exdiff12 = {1'b0,SRC1[30:20]} - {1'b0,SRC2[30:20]};      // Diff. Exponents exchanged
        assign exdiff12 = {1'b0,SRC1[30:20]} - {1'b0,SRC2[30:20]};      // Diff. Exponents exchanged
 
 
Line 331... Line 331...
          end
          end
 
 
        // CMPF : 1. Pipeline Stage : first result : is stored one level higer in Reg
        // CMPF : 1. Pipeline Stage : first result : is stored one level higer in Reg
 
 
        assign CMPRES[1] = ~CMPRES[0] & (switch ? ~sign1 : sign2);       // look table above
        assign CMPRES[1] = ~CMPRES[0] & (switch ? ~sign1 : sign2);       // look table above
        assign CMPRES[0] = (ex_null & ma_null & (sign1 == sign2) & (lowdiff == 33'h0)) | (SRCFLAGS[2] & SRC
        assign CMPRES[0] = (ex_null & ma_null & (sign1 == sign2) & (lowdiff == 33'h0)) | (SRCFLAGS[2] & SRCFLAGS[0]);
 
 
        // ++++++++++++++++++++++++++++++++++
        // ++++++++++++++++++++++++++++++++++
        // ADD/SUB + ROUND/TRUNC : 2. Step : Barrelshifter to the right -->
        // ADD/SUB + ROUND/TRUNC : 2. Step : Barrelshifter to the right -->
 
 
        wire [55:0] brshifta,brshiftb,brshiftc,brshiftd,brshifte,brshiftf;
        wire [55:0] brshifta,brshiftb,brshiftc,brshiftd,brshifte,brshiftf;
Line 359... Line 359...
        wire [30:0] compl;
        wire [30:0] compl;
        wire [31:0] iadder;
        wire [31:0] iadder;
        wire            restbits;
        wire            restbits;
 
 
        assign restbits = (brshiftf[23:0] != 24'h0);
        assign restbits = (brshiftf[23:0] != 24'h0);
        assign inex     = {brshiftf[24],restbits};              // Inexact-Flag-Data transfered to multiplexer at the e
        assign inex     = {brshiftf[24],restbits};              // Inexact-Flag-Data transfered to multiplexer at the end
 
 
        always @(SELECT or sign1 or brshiftf or restbits or inex or ganzklein)
        always @(SELECT or sign1 or brshiftf or restbits or inex or ganzklein)
                casex (SELECT[3:2])
                casex (SELECT[3:2])
                    2'b00 : car_ry = sign1 ^ (((brshiftf[25:24] == 2'b11) & ~restbits) | (inex == 2'b11));      // ROUN
                    2'b00 : car_ry = sign1 ^ (((brshiftf[25:24] == 2'b11) & ~restbits) | (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 to "-infinity" round
                  default : car_ry = sign1;     // TRUNCLi , simple cut off
                  default : car_ry = sign1;     // TRUNCLi , simple cut off
                endcase
                endcase
 
 
        assign compl  = sign1 ? ~brshiftf[55:25] : brshiftf[55:25];
        assign compl  = sign1 ? ~brshiftf[55:25] : brshiftf[55:25];
 
 
Line 391... Line 391...
        wire    [12:0]   shiftl;
        wire    [12:0]   shiftl;
        wire                    shift_32;
        wire                    shift_32;
        wire    [65:0]   add_q;
        wire    [65:0]   add_q;
 
 
        // The central adder : the subtraction needs 3 Guard-Bits after LSB for correct rounding
        // The central adder : the subtraction needs 3 Guard-Bits after LSB for correct rounding
        assign result = {1'b0,muxsrc2,3'b000} + (addflag ? {12'h0,brshiftf} : {12'hFFF,~brshiftf}) + {67'd0
        assign result = {1'b0,muxsrc2,3'b000} + (addflag ? {12'h0,brshiftf} : {12'hFFF,~brshiftf}) + {67'd0,~addflag};
 
 
        assign blshifti = SELECT[1] ? {movif,24'h0} : result[55:0];      // Feeding of MOViL, comes from Registe
        assign blshifti = SELECT[1] ? {movif,24'h0} : result[55:0];      // Feeding of MOViL, comes from Register
 
 
        assign shiftl = SELECT[1] ? 13'h041E : {1'b0,result[67:56]};    // MOViL
        assign shiftl = SELECT[1] ? 13'h041E : {1'b0,result[67:56]};    // MOViL
 
 
        assign shift_32 = (blshifti[55:24] == 32'h0);
        assign shift_32 = (blshifti[55:24] == 32'h0);
 
 
Line 445... Line 445...
 
 
        assign OUT = {outreg[69:67],(rovfl ? 2'b01 : outreg[66:65]),outreg[64:0]};
        assign OUT = {outreg[69:67],(rovfl ? 2'b01 : outreg[66:65]),outreg[64:0]};
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      5. DFPU_MISC    Double precision floating point miscellaneous operations 
//      5. DFPU_MISC    Double precision floating point miscellaneous operations 
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DFPU_MISC ( BCLK, START, SRC1, SRC2, SRCFLAG, MIMUX, MODE, OUT );
module DFPU_MISC ( BCLK, START, SRC1, SRC2, SRCFLAG, MIMUX, MODE, OUT );
 
 
        input                   BCLK;
        input                   BCLK;
        input                   START;
        input                   START;
        input   [31:0]   SRC1,SRC2;
        input   [31:0]   SRC1,SRC2;
Line 506... Line 506...
        assign posi_2   = (shift_l4[9:8] == 2'b00);
        assign posi_2   = (shift_l4[9:8] == 2'b00);
        assign shift_l2 = posi_2 ? {shift_l4[7:0],2'b0}  : shift_l4;
        assign shift_l2 = posi_2 ? {shift_l4[7:0],2'b0}  : shift_l4;
        assign posi_1   = ~shift_l2[9];
        assign posi_1   = ~shift_l2[9];
        assign shift_l  = posi_1 ? {shift_l2[7:0],1'b0}  : shift_l2[8:0]; // top bit is hidden "1"
        assign shift_l  = posi_1 ? {shift_l2[7:0],1'b0}  : shift_l2[8:0]; // top bit is hidden "1"
 
 
        assign calc_exp = 5'h08 - {1'b0,posi_8,posi_4,posi_2,posi_1};   // Minimum is "F" = for exponent +/-1
        assign calc_exp = 5'h08 - {1'b0,posi_8,posi_4,posi_2,posi_1};   // Minimum is "F" = for exponent +/-1 <=> 2^0
 
 
        // exponent is set one level higher for F and L
        // exponent is set one level higher for F and L
        assign logb_exp = MODE[1] ? {{4{~calc_exp[4]}},{3{calc_exp[4]}}} : {~calc_exp[4],{6{calc_exp[4]}}};
        assign logb_exp = MODE[1] ? {{4{~calc_exp[4]}},{3{calc_exp[4]}}} : {~calc_exp[4],{6{calc_exp[4]}}};
 
 
        assign logb_res = logb_null ? {70'h10_0000_0000_0000_0000} : {2'b00,~daten[62],2'b00,logb_exp,calc_
        assign logb_res = logb_null ? {70'h10_0000_0000_0000_0000} : {2'b00,~daten[62],2'b00,logb_exp,calc_exp[3:0],shift_l,45'h0};
 
 
        // ++++++++++++++++++++++++  SCALBf  ++++++++++++++++++++++++++++++++++
        // ++++++++++++++++++++++++  SCALBf  ++++++++++++++++++++++++++++++++++
 
 
        wire     [7:0]   scalb_f;
        wire     [7:0]   scalb_f;
 
 
Line 526... Line 526...
                                           {2'b00,daten[31],5'b0,scalb_f,daten[22:0],daten[28:1],3'b000}
                                           {2'b00,daten[31],5'b0,scalb_f,daten[22:0],daten[28:1],3'b000}
                                         : {2'b00,daten[63],2'b0,daten[62:0],2'b00};
                                         : {2'b00,daten[63],2'b0,daten[62:0],2'b00};
 
 
        // ++++++++++++++++++++++++  Output  ++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // ++++++++++++++++++++++++  Output  ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
        always @(posedge BCLK) OUT <= MODE[3] ? (MODE[2] ? logb_res : scalb_res) : fl_lf ;      // LOGB/SCALB : 
        always @(posedge BCLK) OUT <= MODE[3] ? (MODE[2] ? logb_res : scalb_res) : fl_lf ;      // LOGB/SCALB : MOVLF/MOVFL
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      6. DFPU_MUL             Double precision floating point multiplier
//      6. DFPU_MUL             Double precision floating point multiplier
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DFPU_MUL ( BCLK, SRC1, SRC2, START, MRESULT, SRCFLAGS, OUT );
module DFPU_MUL ( BCLK, SRC1, SRC2, START, MRESULT, SRCFLAGS, OUT );
 
 
        input                   BCLK;
        input                   BCLK;
        input   [31:0]   SRC1,SRC2;
        input   [31:0]   SRC1,SRC2;
        input                   START;          // that is START[0]
        input                   START;          // that is START[0]
Line 571... Line 571...
                OUT <= MRESULT[105] ? {nan,zero,sign,expoh,MRESULT[104:53],resthigh}    // 52 Bit Mantissa
                OUT <= MRESULT[105] ? {nan,zero,sign,expoh,MRESULT[104:53],resthigh}    // 52 Bit Mantissa
                                                        : {nan,zero,sign,expol,MRESULT[103:52],restlow};
                                                        : {nan,zero,sign,expol,MRESULT[103:52],restlow};
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      7. DIVI_PREP    Prepare data for the divider
//      7. DIVI_PREP    Prepare data for the divider
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DIVI_PREP (SRC, BWD, NOT_DEI, EXTDATA, DOUT, MSB, NULL, MINUS);
module DIVI_PREP (SRC, BWD, NOT_DEI, EXTDATA, DOUT, MSB, NULL, MINUS);
 
 
        input   [31:0]   SRC;
        input   [31:0]   SRC;
        input    [1:0]   BWD;
        input    [1:0]   BWD;
        input                   NOT_DEI;
        input                   NOT_DEI;
Line 608... Line 608...
                  2'b1x : double = SRC;
                  2'b1x : double = SRC;
                endcase
                endcase
 
 
        assign MINUS = double[31] & NOT_DEI;
        assign MINUS = double[31] & NOT_DEI;
 
 
        assign DOUT = ({32{MINUS}} ^ double) + {31'h0,MINUS};   //      assign DOUT = MINUS ? (32'd0 - double) : d
        assign DOUT = ({32{MINUS}} ^ double) + {31'h0,MINUS};   //      assign DOUT = MINUS ? (32'd0 - double) : double;
 
 
        // now find most significant set bit : FFS
        // now find most significant set bit : FFS
 
 
        assign bit_4   = (DOUT[31:16] != 16'h0);
        assign bit_4   = (DOUT[31:16] != 16'h0);
        assign test_16 = bit_4 ? DOUT[31:16]   : DOUT[15:0];
        assign test_16 = bit_4 ? DOUT[31:16]   : DOUT[15:0];
Line 627... Line 627...
 
 
        assign MSB = {bit_4,bit_3,bit_2,bit_1,bit_0};
        assign MSB = {bit_4,bit_3,bit_2,bit_1,bit_0};
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      8. DFPU_DIV             The divider for all divide opcodes : double, single and integer
//      8. DFPU_DIV             The divider for all divide opcodes : double, single and integer
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DFPU_DIV ( BCLK, BRST, START, SRC1, SRC2, MAN1, MAN2, SRCFLAGS, FL, BWD, OPCODE, OUT, DONE, D
module DFPU_DIV ( BCLK, BRST, START, SRC1, SRC2, MAN1, MAN2, SRCFLAGS, FL, BWD, OPCODE, OUT, DONE, DIVI_OUT, DVZ_TRAP, DEI_OVF );
 
 
        // This version needs for Double 28+1 cycles if MAN1<MAN2 otherwise 28+2.
        // This version needs for Double 28+1 cycles if MAN1<MAN2 otherwise 28+2.
        // For Single it needs 13+1 cyckes or 13+2.
        // For Single it needs 13+1 cyckes or 13+2.
 
 
        input                   BCLK,BRST;
        input                   BCLK,BRST;
Line 759... Line 759...
                  2'b00   : addoff = {   1'b0,   1'b0,valdata};
                  2'b00   : addoff = {   1'b0,   1'b0,valdata};
                  2'b01   : addoff = {   1'b0,valdata,   1'b0};
                  2'b01   : addoff = {   1'b0,valdata,   1'b0};
                  default : addoff = {valdata,   1'b0,   1'b0};
                  default : addoff = {valdata,   1'b0,   1'b0};
                endcase
                endcase
 
 
        always @(posedge BCLK) next_msb2 <= extdata & ist_null & divi_pipe1;    // Special case at DEI : MSD =
        always @(posedge BCLK) next_msb2 <= extdata & ist_null & divi_pipe1;    // Special case at DEI : MSD = 0
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
                if (divi_pipe1) msb_src2 <= {addoff[2],(addoff[1:0] | i_out[36:35]),i_out[34:32]};
                if (divi_pipe1) msb_src2 <= {addoff[2],(addoff[1:0] | i_out[36:35]),i_out[34:32]};
                  else
                  else
                        if (next_msb2) msb_src2 <= {1'b0,i_out[36:32]};
                        if (next_msb2) msb_src2 <= {1'b0,i_out[36:32]};
Line 787... Line 787...
        assign shift_4  = shift_r[2] ? shift_2 : {shift_2[58:0], 4'b0};
        assign shift_4  = shift_r[2] ? shift_2 : {shift_2[58:0], 4'b0};
        assign shift_8  = shift_r[3] ? shift_4 : {shift_4[54:0], 8'b0};
        assign shift_8  = shift_r[3] ? shift_4 : {shift_4[54:0], 8'b0};
        assign shift_16 = shift_r[4] ? shift_8 : {shift_8[46:0],16'b0};  // Result is 63 Bit wide
        assign shift_16 = shift_r[4] ? shift_8 : {shift_8[46:0],16'b0};  // Result is 63 Bit wide
 
 
        // 65 Bit result because of DEI 
        // 65 Bit result because of DEI 
        assign shift_32 = shift_r[5] ? {1'b0,pipe_reg,ivalue} : {shift_16,2'b00};       // special case DEI : 32 
        assign shift_32 = shift_r[5] ? {1'b0,pipe_reg,ivalue} : {shift_16,2'b00};       // special case DEI : 32 times shift
 
 
        always @(posedge BCLK or negedge BRST)  // Flag for rounding, only if DEST <>0 
        always @(posedge BCLK or negedge BRST)  // Flag for rounding, only if DEST <>0 
                if (!BRST) divi_pipe3 <= 1'b0;
                if (!BRST) divi_pipe3 <= 1'b0;
                  else
                  else
                    divi_pipe3 <= divi_pipe2 | (divi_pipe3 & ~stop_divi);
                    divi_pipe3 <= divi_pipe2 | (divi_pipe3 & ~stop_divi);
Line 817... Line 817...
        //      -33  -13 :   2   -7  /   2   -7
        //      -33  -13 :   2   -7  /   2   -7
        always @(*)
        always @(*)
                case (OPCODE[1:0])
                case (OPCODE[1:0])
                  2'b00 : divi_result = {neg_flag,divsr[31:0]};          // QUO
                  2'b00 : divi_result = {neg_flag,divsr[31:0]};          // QUO
                  2'b01 : divi_result = {neg_src2,divreg[33:2]};        // REM
                  2'b01 : divi_result = {neg_src2,divreg[33:2]};        // REM
                  2'b10 : divi_result = {neg_src1,((sub_case & ~rest_null) ? (save1[31:0] - divreg[33:2]) : divreg
                  2'b10 : divi_result = {neg_src1,((sub_case & ~rest_null) ? (save1[31:0] - divreg[33:2]) : divreg[33:2])};      // MOD
                  2'b11 : divi_result = {neg_flag,divsr[31:0]};          // DIV
                  2'b11 : divi_result = {neg_flag,divsr[31:0]};          // DIV
                endcase
                endcase
 
 
        always @(posedge BCLK) negativ <= divi_result[32];
        always @(posedge BCLK) negativ <= divi_result[32];
 
 
        assign plus_1 = (OPCODE[1:0] == 2'b11) ? (negativ & rest_null) : negativ;        // Special case Rest=0 at
        assign plus_1 = (OPCODE[1:0] == 2'b11) ? (negativ & rest_null) : negativ;        // Special case Rest=0 at DIV
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
                if (divi_pipe4) DIVI_OUT[63:32] <= not_dei ? (({32{negativ}} ^ divi_result[31:0]) + {31'd0,plus_1}
                if (divi_pipe4) DIVI_OUT[63:32] <= not_dei ? (({32{negativ}} ^ divi_result[31:0]) + {31'd0,plus_1}) : dei_result;
 
 
        always @(posedge BCLK) if (divi_pipe4) DIVI_OUT[31:0] <= divreg[33:2];
        always @(posedge BCLK) if (divi_pipe4) DIVI_OUT[31:0] <= divreg[33:2];
 
 
        always @(extdata or BWD or divsr or divreg)
        always @(extdata or BWD or divsr or divreg)
                casex ({extdata,BWD})
                casex ({extdata,BWD})
Line 852... Line 852...
        assign src_1 = run_divi ? {1'b0,ivalue} : ( FL ? {10'h001,SRC1[22:0]} : {SRC1,1'b0});
        assign src_1 = run_divi ? {1'b0,ivalue} : ( FL ? {10'h001,SRC1[22:0]} : {SRC1,1'b0});
 
 
        assign load_src1 = START[2] | divi_pipe1;
        assign load_src1 = START[2] | divi_pipe1;
 
 
        //                                                                                                              *2                 +       *1   
        //                                                                                                              *2                 +       *1   
        always @(posedge BCLK) if (load_src1) dreimal <= {1'b0,man_1,src_1,1'b0} + {2'b00,man_1,src_1}; // 
        always @(posedge BCLK) if (load_src1) dreimal <= {1'b0,man_1,src_1,1'b0} + {2'b00,man_1,src_1}; // 54 Bit Reg
 
 
        always @(posedge BCLK) if (load_src1) save1 <= src_1;
        always @(posedge BCLK) if (load_src1) save1 <= src_1;
 
 
        assign sub1 = divreg - {3'b000, man_1,save1     };
        assign sub1 = divreg - {3'b000, man_1,save1     };
        assign sub2 = divreg - {2'b00 ,man_1,save1,1'b0};
        assign sub2 = divreg - {2'b00 ,man_1,save1,1'b0};
        assign sub3 = divreg - {1'b0, dreimal         };
        assign sub3 = divreg - {1'b0, dreimal         };
 
 
        assign load_src2 = START[2] | divi_pipe2;
        assign load_src2 = START[2] | divi_pipe2;
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
                if (load_src2) divreg <= divi_pipe2 ? {23'h0,shift_32[64:32]} : ( FL ? {34'h0_0000_0001,SRC2[22:0]
                if (load_src2) divreg <= divi_pipe2 ? {23'h0,shift_32[64:32]} : ( FL ? {34'h0_0000_0001,SRC2[22:0]} : {3'b0,MAN2,SRC2,1'b0});
                else
                else
                        begin
                        begin
                          casex ({sub3[56],sub2[56],sub1[56]})
                          casex ({sub3[56],sub2[56],sub1[56]})
                                3'b0xx : divreg <=   {sub3[54:0],divreg_ext[31:30]};
                                3'b0xx : divreg <=   {sub3[54:0],divreg_ext[31:30]};
                                3'b10x : divreg <=   {sub2[54:0],divreg_ext[31:30]};
                                3'b10x : divreg <=   {sub2[54:0],divreg_ext[31:30]};
Line 894... Line 894...
                        end
                        end
 
 
        // Overflow Detection for DEI : serial calculation
        // Overflow Detection for DEI : serial calculation
        always @(posedge BCLK)
        always @(posedge BCLK)
                if (load_src2) DEI_OVF[0] <= 1'b0;
                if (load_src2) DEI_OVF[0] <= 1'b0;
                  else DEI_OVF[0] <= DEI_OVF[0] | (BWD[1] ? |divsr[33:32] : (BWD[0] ? |divsr[17:16] : |divsr[9:8])
                  else DEI_OVF[0] <= DEI_OVF[0] | (BWD[1] ? |divsr[33:32] : (BWD[0] ? |divsr[17:16] : |divsr[9:8]));
 
 
        always @(posedge BCLK) DEI_OVF[1] <= divi_pipe4;        // Timing pulse for OVF inclusiv for DIV and QUO
        always @(posedge BCLK) DEI_OVF[1] <= divi_pipe4;        // Timing pulse for OVF inclusiv for DIV and QUO
 
 
        assign short = (SRCFLAGS[3:0] != 4'h0) & runflag;
        assign short = (SRCFLAGS[3:0] != 4'h0) & runflag;
 
 
Line 923... Line 923...
        assign expol    = exponent + offset;                            // in case of normalizing
        assign expol    = exponent + offset;                            // in case of normalizing
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
          if (ende && runflag)
          if (ende && runflag)
                casex ({FL,divsr[26],divsr[56]})
                casex ({FL,divsr[26],divsr[56]})
                  3'b11x : OUT <= {nan,zero,sign,expoh[9:8],expoh[7],expoh[7],expoh[7],expoh[7:0],divsr[25:3],28'b
                  3'b11x : OUT <= {nan,zero,sign,expoh[9:8],expoh[7],expoh[7],expoh[7],expoh[7:0],divsr[25:3],28'b0,divsr[3:2],restlow};
                  3'b10x : OUT <= {nan,zero,sign,expol[9:8],expol[7],expol[7],expol[7],expol[7:0],divsr[24:2],28'b
                  3'b10x : OUT <= {nan,zero,sign,expol[9:8],expol[7],expol[7],expol[7],expol[7:0],divsr[24:2],28'b0,divsr[2:1],restlsb};
                  3'b0x1 : OUT <= {nan,zero,sign,expoh,divsr[55:3],resthigh};
                  3'b0x1 : OUT <= {nan,zero,sign,expoh,divsr[55:3],resthigh};
                  3'b0x0 : OUT <= {nan,zero,sign,expol,divsr[54:2],restlow};
                  3'b0x0 : OUT <= {nan,zero,sign,expol,divsr[54:2],restlow};
                endcase
                endcase
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      9. DP_LOGIK             Control logic and result path for different functions
//      9. DP_LOGIK             Control logic and result path for different functions
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DP_LOGIK ( BCLK, BRESET, OPCODE, SRC1, SRC2, FSR, START, MRESULT, BWD, FL, MAN1, MAN2, WR_REG
module DP_LOGIK ( BCLK, BRESET, OPCODE, SRC1, SRC2, FSR, START, MRESULT, BWD, FL, MAN1, MAN2, WR_REG, CY_IN,
                                  COP_DONE, COP_OP, COP_IN,
                                  COP_DONE, COP_OP, COP_IN,
                                  DOUT, TT_DP, DP_CMP, OVF_BCD, MEI, DFLOAT, DONE, UP_DP, CLR_LSB, WREN_L, LD_OUT_L, DVZ_TRAP, C
                                  DOUT, TT_DP, DP_CMP, OVF_BCD, MEI, DFLOAT, DONE, UP_DP, CLR_LSB, WREN_L, LD_OUT_L, DVZ_TRAP, COP_GO );
 
 
// Definition of output word OUT of sub-moduls : the hidden-bit of the mantissa is already gone
// Definition of output word OUT of sub-moduls : the hidden-bit of the mantissa is already gone
//
//
//   N Z S   Exponent                   Mantissa                                                                                                 Round
//   N Z S   Exponent                   Mantissa                                                                                                 Round
//   A E I  Double : 13 Bit             52 Bit                                                                                                           2 Bit
//   A E I  Double : 13 Bit             52 Bit                                                                                                           2 Bit
Line 1049... Line 1049...
        assign divi_ops = (OPCODE[7:2] == 6'b0111_11) | (OPCODE == 8'h7B);      // QUO/REM/MOD/DIV & DEI
        assign divi_ops = (OPCODE[7:2] == 6'b0111_11) | (OPCODE == 8'h7B);      // QUO/REM/MOD/DIV & DEI
        assign go_divf  = (OPCODE == 8'hB8) & START[1];                                 // because of runflag in DIV Unit
        assign go_divf  = (OPCODE == 8'hB8) & START[1];                                 // because of runflag in DIV Unit
        assign go_divi  = divi_ops & (OPCODE[2] ? START[1] : START[0]);  // DEI starts with START[0]
        assign go_divi  = divi_ops & (OPCODE[2] ? START[1] : START[0]);  // DEI starts with START[0]
        assign bcd_ops  = (OPCODE == 8'h6F) | (OPCODE == 8'h6B);                // ADDP , SUBP
        assign bcd_ops  = (OPCODE == 8'h6F) | (OPCODE == 8'h6B);                // ADDP , SUBP
 
 
        assign man_ops  = (OPCODE == 8'hB1) | (OPCODE == 8'hB5) | (OPCODE == 8'hB9) | (OPCODE == 8'hBD);        //
        assign man_ops  = (OPCODE == 8'hB1) | (OPCODE == 8'hB5) | (OPCODE == 8'hB9) | (OPCODE == 8'hBD);        // MOVf,NEGf,XXXf,ABSf
 
 
        assign DFLOAT   = (select[3] | copop) & ~FL;    // all Double Floating Point Operations for PREPDATA
        assign DFLOAT   = (select[3] | copop) & ~FL;    // all Double Floating Point Operations for PREPDATA
        assign make_i   = (select[2:0] == 3'b011) | divi_ops | bcd_ops;  // ROUND/TRUNC/FLOOR for output mul
        assign make_i   = (select[2:0] == 3'b011) | divi_ops | bcd_ops;  // ROUND/TRUNC/FLOOR for output multiplexer
        assign op_cmp   = (OPCODE == 8'hB2) & ~FL;
        assign op_cmp   = (OPCODE == 8'hB2) & ~FL;
        always @(posedge BCLK) misc_op <= select[4];    // for OUT-Multiplexer
        always @(posedge BCLK) misc_op <= select[4];    // for OUT-Multiplexer
 
 
        assign copop    = (OPCODE == 8'hDD);
        assign copop    = (OPCODE == 8'hDD);
        assign copwr    = (COP_OP[18:17] == 2'd0) & (COP_OP[13:11] == 3'b111) & (COP_OP[7:5] == 3'b001);        // Cu
        assign copwr    = (COP_OP[18:17] == 2'd0) & (COP_OP[13:11] == 3'b111) & (COP_OP[7:5] == 3'b001);        // Custom Convert
 
 
        // very special solution for SCALBL
        // very special solution for SCALBL
        assign scalbl   = START[0] & ~FL & (OPCODE == 8'hB6);
        assign scalbl   = START[0] & ~FL & (OPCODE == 8'hB6);
        assign go_misc  = START[1] | scalbl;
        assign go_misc  = START[1] | scalbl;
        always @(posedge BCLK) misc_mux <= scalbl;      // switches at START[1] the input multiplexer
        always @(posedge BCLK) misc_mux <= scalbl;      // switches at START[1] the input multiplexer
Line 1088... Line 1088...
        //                                       11 : 2 Float Operands SRC1 , SRC2
        //                                       11 : 2 Float Operands SRC1 , SRC2
 
 
        always @(posedge BCLK)  // NaN 
        always @(posedge BCLK)  // NaN 
                if (START[1])
                if (START[1])
                        casex ({START[0],select[6:5]})
                        casex ({START[0],select[6:5]})
                           3'b0xx : srcflags[3] <= preflags[5] | (preflags[4] & (~preflags[3] | SRC2[31] | ~zexp2 | ~zman
                           3'b0xx : srcflags[3] <= preflags[5] | (preflags[4] & (~preflags[3] | SRC2[31] | ~zexp2 | ~zman2));
                           3'b111 : srcflags[3] <= (SRC2[30:23] == 8'hFF) | ((SRC2[30:23] == 8'd0) & ((SRC2[22:20] != 3'd
                           3'b111 : srcflags[3] <= (SRC2[30:23] == 8'hFF) | ((SRC2[30:23] == 8'd0) & ((SRC2[22:20] != 3'd0) | ~zman2)); // F:SRC2 = NaN
                          default : srcflags[3] <= 1'b0;
                          default : srcflags[3] <= 1'b0;
                        endcase
                        endcase
 
 
        always @(posedge BCLK)  // Zero : only exponent ! If denormalized => NaN !
        always @(posedge BCLK)  // Zero : only exponent ! If denormalized => NaN !
                if (START[0])
                if (START[0])
Line 1104... Line 1104...
                        endcase
                        endcase
 
 
        always @(posedge BCLK)  // NaN 
        always @(posedge BCLK)  // NaN 
                if (START[1])
                if (START[1])
                        casex ({START[0],select[6:5]})
                        casex ({START[0],select[6:5]})
                           3'b0xx : srcflags[1] <= preflags[2] | (preflags[1] & (~preflags[0] | SRC1[31] | ~zexp1 | ~zman
                           3'b0xx : srcflags[1] <= preflags[2] | (preflags[1] & (~preflags[0] | SRC1[31] | ~zexp1 | ~zman1));
                           3'b1x1 : srcflags[1] <= (SRC1[30:23] == 8'hFF) | ((SRC1[30:23] == 8'd0) & ((SRC1[22:20] != 3'd
                           3'b1x1 : srcflags[1] <= (SRC1[30:23] == 8'hFF) | ((SRC1[30:23] == 8'd0) & ((SRC1[22:20] != 3'd0) | ~zman1)); // F:SRC1 = NaN
                           3'b110 : srcflags[1] <= znan1 | (zexp1 & (~zman1 | SRC2[31] | ~zexp2 | ~zman2));     // L:(SRC1,SR
                           3'b110 : srcflags[1] <= znan1 | (zexp1 & (~zman1 | SRC2[31] | ~zexp2 | ~zman2));     // L:(SRC1,SRC2) = NaN , SRC1 = MSB
                          default : srcflags[1] <= 1'b0;
                          default : srcflags[1] <= 1'b0;
                        endcase
                        endcase
 
 
        always @(posedge BCLK)  // Zero : only exponent ! If denormalized => NaN !
        always @(posedge BCLK)  // Zero : only exponent ! If denormalized => NaN !
                if (START[0])
                if (START[0])
Line 1129... Line 1129...
                                                  .OUT(addout), .IOUT(i_out), .CMPRES(cmpres) );
                                                  .OUT(addout), .IOUT(i_out), .CMPRES(cmpres) );
 
 
        DFPU_MUL mul_inst       ( .BCLK(BCLK), .SRC1(SRC1), .SRC2(SRC2), .START(START[0]), .MRESULT(MRESULT),
        DFPU_MUL mul_inst       ( .BCLK(BCLK), .SRC1(SRC1), .SRC2(SRC2), .START(START[0]), .MRESULT(MRESULT),
                                                  .OUT(mulout), .SRCFLAGS(srcflags) );
                                                  .OUT(mulout), .SRCFLAGS(srcflags) );
 
 
        DFPU_DIV div_inst       ( .BCLK(BCLK), .BRST(BRESET), .START({go_divi,go_divf,START}), .SRC1(SRC1), .SRC2
        DFPU_DIV div_inst       ( .BCLK(BCLK), .BRST(BRESET), .START({go_divi,go_divf,START}), .SRC1(SRC1), .SRC2(SRC2),
                                                  .MAN1(MAN1), .MAN2(MAN2), .SRCFLAGS(srcflags), .FL(FL), .OUT(divout), .DONE(div_done),
                                                  .MAN1(MAN1), .MAN2(MAN2), .SRCFLAGS(srcflags), .FL(FL), .OUT(divout), .DONE(div_done),
                                                  .BWD(BWD), .OPCODE(OPCODE[2:0]), .DIVI_OUT(divi_out), .DVZ_TRAP(DVZ_TRAP), .DEI_OVF(dei_ovf)
                                                  .BWD(BWD), .OPCODE(OPCODE[2:0]), .DIVI_OUT(divi_out), .DVZ_TRAP(DVZ_TRAP), .DEI_OVF(dei_ovf) );
 
 
        DFPU_MISC misc_inst     ( .BCLK(BCLK), .START(go_misc), .SRC1(SRC1), .SRC2(SRC2), .SRCFLAG(srcflags[2])
        DFPU_MISC misc_inst     ( .BCLK(BCLK), .START(go_misc), .SRC1(SRC1), .SRC2(SRC2), .SRCFLAG(srcflags[2]),
                                                  .MIMUX(misc_mux), .MODE({OPCODE[5],OPCODE[0],FL,OPCODE[1]}), .OUT(miscout) );
                                                  .MIMUX(misc_mux), .MODE({OPCODE[5],OPCODE[0],FL,OPCODE[1]}), .OUT(miscout) );
 
 
        DFPU_BCD bcd_inst       ( .BCLK(BCLK), .BRESET(BRESET), .START(START[1]), .DO_BCD(bcd_ops), .BWD(BWD), .S
        DFPU_BCD bcd_inst       ( .BCLK(BCLK), .BRESET(BRESET), .START(START[1]), .DO_BCD(bcd_ops), .BWD(BWD), .SRC1(SRC1), .SRC2(SRC2),
                                                  .CY_IN(CY_IN), .SUBP(~OPCODE[2]), .BCD_Q(bcd_q), .CY_OUT(bcd_carry), .BCD_DONE(bcd_done) );
                                                  .CY_IN(CY_IN), .SUBP(~OPCODE[2]), .BCD_Q(bcd_q), .CY_OUT(bcd_carry), .BCD_DONE(bcd_done) );
 
 
        // FP - path : selection of result and rounding :
        // FP - path : selection of result and rounding :
 
 
        always @(misc_op or OPCODE or mulout or addout or divout or miscout)
        always @(misc_op or OPCODE or mulout or addout or divout or miscout)
Line 1177... Line 1177...
                        8'b000011xx : tt = 3'b001;      // Underflow
                        8'b000011xx : tt = 3'b001;      // Underflow
                        8'b00000011 : tt = 3'b110;      // Inexact Result
                        8'b00000011 : tt = 3'b110;      // Inexact Result
                        default         : tt = 3'b000;  // no error
                        default         : tt = 3'b000;  // no error
                endcase
                endcase
 
 
        assign TT_DP = man_ops ? 5'd0 : {(inexact & ~op_cmp),(underflow & ~op_cmp),tt}; // at ABSf/NEGf no 
        assign TT_DP = man_ops ? 5'd0 : {(inexact & ~op_cmp),(underflow & ~op_cmp),tt}; // at ABSf/NEGf no error : different to NS32381 !
 
 
        assign fp_res = FL ? {fpout[67],rund[61:31],rund[33:2]}
        assign fp_res = FL ? {fpout[67],rund[61:31],rund[33:2]}
                                           : {fpout[67],rund[64:2]};    // lower 32 bits identical
                                           : {fpout[67],rund[64:2]};    // lower 32 bits identical
 
 
        // Underflow special case and get ZERO
        // Underflow special case and get ZERO
        assign fp_out = (underflow | fpout[68]) ? 64'h0 : fp_res;
        assign fp_out = (underflow | fpout[68]) ? 64'h0 : fp_res;
 
 
        // 63..32 goes to memory if Word or Byte ! Also in ODD Register , 31..0 goes in EVEN Register
        // 63..32 goes to memory if Word or Byte ! Also in ODD Register , 31..0 goes in EVEN Register
        // DEI comes without WR_REG information
        // DEI comes without WR_REG information
        always @(make_i or copop or MEI or BWD or WR_REG or MRESULT or COP_IN or i_out or fp_out or divi_op
        always @(make_i or copop or MEI or BWD or WR_REG or MRESULT or COP_IN or i_out or fp_out or divi_ops or divi_out or bcd_ops or bcd_q)
                casex ({make_i,copop,MEI,BWD})
                casex ({make_i,copop,MEI,BWD})
                  5'b00100 : DOUT = {MRESULT[31:8], (WR_REG ? MRESULT[15:8]  : MRESULT[7:0]), MRESULT[31:0]};     // L
                  5'b00100 : DOUT = {MRESULT[31:8], (WR_REG ? MRESULT[15:8]  : MRESULT[7:0]), MRESULT[31:0]};     // LSD always the same
                  5'b00101 : DOUT = {MRESULT[31:16],(WR_REG ? MRESULT[31:16] : MRESULT[15:0]),MRESULT[31:0]};
                  5'b00101 : DOUT = {MRESULT[31:16],(WR_REG ? MRESULT[31:16] : MRESULT[15:0]),MRESULT[31:0]};
                  5'b0011x : DOUT =  MRESULT[63:0];
                  5'b0011x : DOUT =  MRESULT[63:0];
                  5'b01xxx : DOUT =  COP_IN;    // true alignment in Coprocessor
                  5'b01xxx : DOUT =  COP_IN;    // true alignment in Coprocessor
                  5'b1xxxx : DOUT = divi_ops ? divi_out : {(bcd_ops ? bcd_q : i_out),fp_out[31:0]};      // MSD is writ
                  5'b1xxxx : DOUT = divi_ops ? divi_out : {(bcd_ops ? bcd_q : i_out),fp_out[31:0]};      // MSD is written first
                  default  : DOUT = fp_out;
                  default  : DOUT = fp_out;
                endcase
                endcase
 
 
        always @(posedge BCLK) DP_CMP <= {(srcflags[3] | srcflags[1]),cmpres};  // Only valid if not NaN
        always @(posedge BCLK) DP_CMP <= {(srcflags[3] | srcflags[1]),cmpres};  // Only valid if not NaN
 
 
Line 1230... Line 1230...
                  9'b0_1011_011x : wctrl = 5'b01_111;   // SCALBL/LOGBL
                  9'b0_1011_011x : wctrl = 5'b01_111;   // SCALBL/LOGBL
                  9'bx_1101_1101 : wctrl = {4'b10_00,copwr};    // execute coprocessor opcode
                  9'bx_1101_1101 : wctrl = {4'b10_00,copwr};    // execute coprocessor opcode
                  default        : wctrl = 5'b0;
                  default        : wctrl = 5'b0;
                endcase
                endcase
 
 
        assign done_i = wctrl[4] ? (div_done | bcd_done | COP_DONE) : ( (wctrl[3] | ~WR_REG) ? sequ[2] : se
        assign done_i = wctrl[4] ? (div_done | bcd_done | COP_DONE) : ( (wctrl[3] | ~WR_REG) ? sequ[2] : sequ[1] );
        assign DONE = ~START[1] & done_i;       // DONE is valid for all opcodes
        assign DONE = ~START[1] & done_i;       // DONE is valid for all opcodes
 
 
        assign wr_part1 = DONE & WR_REG & wctrl[0];
        assign wr_part1 = DONE & WR_REG & wctrl[0];
 
 
        always @(posedge BCLK) CLR_LSB  <= DONE & WR_REG & wctrl[2];
        always @(posedge BCLK) CLR_LSB  <= DONE & WR_REG & wctrl[2];
Line 1242... Line 1242...
 
 
        assign WREN_L   = wr_part1 | wr_part2;
        assign WREN_L   = wr_part1 | wr_part2;
        assign LD_OUT_L = DONE & ~WR_REG;               // meaning is "Load Out-Reg from Long-Path"
        assign LD_OUT_L = DONE & ~WR_REG;               // meaning is "Load Out-Reg from Long-Path"
 
 
        always @(posedge BCLK) up_flag <= DONE & ~wctrl[0];              // DONE one cycle later
        always @(posedge BCLK) up_flag <= DONE & ~wctrl[0];              // DONE one cycle later
        assign UP_DP    = (select[3] & (wctrl[0] ? DONE : up_flag)) | man_ops;   // Update FSR Trap etc. : al
        assign UP_DP    = (select[3] & (wctrl[0] ? DONE : up_flag)) | man_ops;   // Update FSR Trap etc. : all FPU opcodes of DP_FPU
 
 
        // Overflow Trap for Division : DEI, QUO, DIV
        // Overflow Trap for Division : DEI, QUO, DIV
        assign quo_div = (OPCODE == 8'h7C) | (OPCODE == 8'h7F);
        assign quo_div = (OPCODE == 8'h7C) | (OPCODE == 8'h7F);
        always @(*)
        always @(*)
                casex ({OPCODE[2],BWD})
                casex ({OPCODE[2],BWD})
Line 1260... Line 1260...
 
 
        always @(posedge BCLK) COP_GO <= START[1] & copop;
        always @(posedge BCLK) COP_GO <= START[1] & copop;
 
 
endmodule
endmodule
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
// 10. DP_FPU           Top level of long operations datapath
// 10. DP_FPU           Top level of long operations datapath
//
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DP_FPU( BCLK, FL, BRESET, LD_LDQ, WR_REG, BWD, FSR, OPCODE, SRC1, SRC2, START, DONE, UP_DP, W
module DP_FPU( BCLK, FL, BRESET, LD_LDQ, WR_REG, BWD, FSR, OPCODE, SRC1, SRC2, START, DONE, UP_DP, WREN_L,
                           CLR_LSB, LD_OUT_L, DVZ_TRAP, DP_CMP, DP_OUT, DP_Q, TT_DP, CY_IN, OVF_BCD, COP_GO, COP_OP,
                           CLR_LSB, LD_OUT_L, DVZ_TRAP, DP_CMP, DP_OUT, DP_Q, TT_DP, CY_IN, OVF_BCD, COP_GO, COP_OP,
                           COP_IN, COP_DONE, COP_OUT );
                           COP_IN, COP_DONE, COP_OUT );
 
 
input                   BCLK;
input                   BCLK;
input                   FL;
input                   FL;

powered by: WebSVN 2.1.0

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