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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [DP_FPU.v] - Diff between revs 11 and 23

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

Rev 11 Rev 23
Line 2... Line 2...
//
//
// This file is part of the M32632 project
// This file is part of the M32632 project
// http://opencores.org/project,m32632
// http://opencores.org/project,m32632
//
//
// Filename: DP_FPU.v
// Filename: DP_FPU.v
// Version:  1.0
//      Version:        2.0
// Date:     30 May 2015
//      History:        1.0 first release of 30 Mai 2015
 
//      Date:           14 August 2016
//
//
// Copyright (C) 2015 Udo Moeller
// Copyright (C) 2016 Udo Moeller
// 
// 
// This source file may be used and distributed without 
// This source file may be used and distributed without 
// restriction provided that this copyright statement is not 
// restriction provided that this copyright statement is not 
// removed from the file and that any derivative work contains 
// removed from the file and that any derivative work contains 
// the original copyright notice and the associated disclaimer.
// the original copyright notice and the associated disclaimer.
Line 37... Line 38...
//      2. BCDADDER     4 bit BCD adder
//      2. BCDADDER     4 bit BCD adder
//      3. DFPU_BCD             Binary coded decimal (BCD) adder and subtractor
//      3. DFPU_BCD             Binary coded decimal (BCD) adder and subtractor
//      4. DFPU_ADDSUB  Double precision floating point adder and subtractor
//      4. DFPU_ADDSUB  Double precision floating point adder and subtractor
//      5. DFPU_MISC    Double precision floating point miscellaneous operations 
//      5. DFPU_MISC    Double precision floating point miscellaneous operations 
//      6. DFPU_MUL             Double precision floating point multiplier
//      6. DFPU_MUL             Double precision floating point multiplier
//      7. DIVI_PREP    Prepare data for the divider
//      7. SCANDIG              Scan digit for leading one
//      8. DFPU_DIV             The divider for all divide opcodes : double, single and integer
//      8. DIVI_PREP    Prepare data for the divider
//      9. DP_LOGIK             Control logic and result path for different functions
//      9. DFPU_DIV             The divider for all divide opcodes : double, single and integer
// 10. DP_FPU           Top level of long operations datapath
// 10. DP_LOGIK         Control logic and result path for different functions
 
// 11. DP_FPU           Top level of long operations datapath
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
Line 100... Line 102...
        input                   SUBP;
        input                   SUBP;
 
 
        output   [3:0]   OUT;
        output   [3:0]   OUT;
        output                  CY_OUT;
        output                  CY_OUT;
 
 
 
        reg              [4:0]   data;
        wire     [4:0]   result;
        wire     [4:0]   result;
        wire                    over;
        wire                    over;
 
 
        assign result = SUBP ? ({1'b0,A_IN} - {1'b0,B_IN} - {4'b0,CY_IN})
        always @(B_IN)
                                                 : ({1'b0,A_IN} + {1'b0,B_IN} + {4'b0,CY_IN});
                case (B_IN)
 
                        4'h0 : data = 5'h00;
 
                        4'h1 : data = 5'h1F;
 
                        4'h2 : data = 5'h1E;
 
                        4'h3 : data = 5'h1D;
 
                        4'h4 : data = 5'h1C;
 
                        4'h5 : data = 5'h1B;
 
                        4'h6 : data = 5'h1A;
 
                        4'h7 : data = 5'h19;
 
                        4'h8 : data = 5'h18;
 
                        4'h9 : data = 5'h17;
 
                 default : data = 5'hxx;
 
                endcase
 
 
 
        assign result = {1'b0,A_IN} + (SUBP ? data : {1'b0,B_IN}) + {{4{SUBP & CY_IN}},CY_IN};
 
 
        assign over = result[4] | (result[3] & (result[2] | result[1]));
        assign over = result[4] | (result[3] & (result[2] | result[1]));
 
 
                                                                //              if result<0 : -6                                if result>9 : -10
                                                                //              if result<0 : -6                                if result>9 : -10
        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
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Line 149... Line 167...
        // BCD_DONE :  _____/---\____________  if BWD = Byte
        // BCD_DONE :  _____/---\____________  if BWD = Byte
 
 
        always @(posedge BCLK or negedge BRESET)
        always @(posedge BCLK or negedge BRESET)
                if (!BRESET) run_bcd <= 1'b0;
                if (!BRESET) run_bcd <= 1'b0;
                  else
                  else
                        run_bcd <= (START & DO_BCD) | (run_bcd & (BWD != byte_cou));
                        run_bcd <= (START & DO_BCD & (BWD != 2'd0)) | (run_bcd & (BWD != byte_cou));
 
 
        always @(posedge BCLK) byte_cou <= START ? 2'd0 : byte_cou + {1'b0,run_bcd};
        always @(posedge BCLK) byte_cou <= START ? 2'd1 : byte_cou + {1'b0,run_bcd};
 
 
        always @(*)
        always @(*)
                casex ({START,byte_cou})
                casex ({START,byte_cou})
                  3'b1_xx : datain = {SRC1[7:0],  SRC2[7:0]};
                  3'b1_xx : datain = {SRC1[7:0],  SRC2[7:0]};
                  3'b0_00 : datain = {SRC1[15:8], SRC2[15:8]};
                  3'b0_0x : datain = {SRC1[15:8], SRC2[15:8]};
                  3'b0_01 : datain = {SRC1[23:16],SRC2[23:16]};
                  3'b0_10 : datain = {SRC1[23:16],SRC2[23:16]};
                  3'b0_1x : datain = {SRC1[31:24],SRC2[31:24]};
                  3'b0_11 : datain = {SRC1[31:24],SRC2[31:24]};
                endcase
                endcase
 
 
        assign carry = START ? CY_IN : CY_OUT;
        assign carry = START ? CY_IN : CY_OUT;
 
 
        BCDADDER        lsd_inst ( .A_IN(datain[3:0]), .B_IN(datain[11:8]), .CY_IN(carry), .SUBP(SUBP),
        BCDADDER        lsd_inst ( .A_IN(datain[3:0]), .B_IN(datain[11:8]), .CY_IN(carry), .SUBP(SUBP),
Line 172... Line 190...
                                                   .OUT(result[7:4]), .CY_OUT(carry_msd) );
                                                   .OUT(result[7:4]), .CY_OUT(carry_msd) );
 
 
        always @(posedge BCLK) CY_OUT <= carry_msd;
        always @(posedge BCLK) CY_OUT <= carry_msd;
 
 
        always @(posedge BCLK) if (START)                        BCD_Q[7:0]   <= result;
        always @(posedge BCLK) if (START)                        BCD_Q[7:0]   <= result;
        always @(posedge BCLK) if (byte_cou == 2'd0) BCD_Q[15:8]  <= result;
        always @(posedge BCLK) if (~byte_cou[1])         BCD_Q[15:8]  <= result;
        always @(posedge BCLK) if (byte_cou == 2'd1) BCD_Q[23:16] <= result;
        always @(posedge BCLK) if (byte_cou == 2'd2) BCD_Q[23:16] <= result;
        always @(posedge BCLK) if (byte_cou[1])          BCD_Q[31:24] <= result;
        always @(posedge BCLK) if (byte_cou == 2'd3) BCD_Q[31:24] <= result;
 
 
        assign BCD_DONE = run_bcd & (BWD == byte_cou);
        assign BCD_DONE = (START & DO_BCD & (BWD == 2'd0)) | (run_bcd & (BWD == byte_cou));
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
Line 210... Line 228...
        // CMP     : 2 cycles
        // CMP     : 2 cycles
 
 
        // ++++++++++++++++++++++++++++++++++
        // ++++++++++++++++++++++++++++++++++
        // MOViL : 1. Pipeline stage : needs 3 cycles
        // MOViL : 1. Pipeline stage : needs 3 cycles
 
 
        reg  [31:8]     movdat;
        reg  [31:0]      movdat;
        reg      [31:0]  movif;
        reg      [31:0]  movif;
        reg                     sign_movif;
        reg                     sign_movif;
 
 
        always @(BWD or SRC1)
        always @(BWD or SRC1)
                casex({BWD,SRC1[15],SRC1[7]})
                casex(BWD)
                  4'b00x0 : movdat =  24'h0000_00;                              // Byte
                  2'b00 : movdat = {{24{SRC1[7]}}, SRC1[7:0]};   // Byte
                  4'b00x1 : movdat =  24'hFFFF_FF;
                  2'b01 : movdat = {{16{SRC1[15]}},SRC1[15:0]};  // Word
                  4'b010x : movdat = {16'h0000,SRC1[15:8]};             // Word
                default : movdat =              SRC1[31:0];                              // Double
                  4'b011x : movdat = {16'hFFFF,SRC1[15:8]};
 
                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]};   // -2^31 is kept !
        always @(posedge BCLK) movif <= ({32{movdat[31]}} ^ movdat) + {31'h0,movdat[31]};       // -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 operand ? From register "yes"
        // ROUNDLi/TRUNCLi/FLOORLi : 1. pipeline stage : can Opcode-Decoder deliver direct the 64 bit operand ? From register "yes"
 
 
Line 270... Line 286...
        wire                    switch,nan,sign,sign1,sign2;
        wire                    switch,nan,sign,sign1,sign2;
        reg              [5:0]   shift1,shift2;
        reg              [5:0]   shift1,shift2;
 
 
                // Pipeline register :
                // Pipeline register :
        reg             [63:0]   muxsrc2;
        reg             [63:0]   muxsrc2;
        reg             [55:3]  pipe1;  // Nummbers for right shifter
        wire    [55:3]  pipe1;  // Nummbers for right shifter
        reg      [5:0]   shift;
        wire     [5:0]   shift;
 
        reg              [2:0]   pshift;
        reg                             vorz,addflag;
        reg                             vorz,addflag;
 
 
        wire    [52:0]   muxsrc1;
        wire    [52:0]   muxsrc1;
        wire    [32:0]   lowdiff;
        wire    [32:0]   lowdiff;
 
 
Line 302... Line 319...
 
 
        assign switch = ex_msb | (ex_null & (ma_msb | (ma_null & lowdiff[32])));        // exchange ?
        assign switch = ex_msb | (ex_null & (ma_msb | (ma_null & lowdiff[32])));        // exchange ?
 
 
        assign muxsrc1 = switch ? {MAN2,SRC2} : {MAN1,SRC1};
        assign muxsrc1 = switch ? {MAN2,SRC2} : {MAN1,SRC1};
 
 
 
        assign pipe1 = SELECT[1] ? (ganzklein ? 53'd0  : {1'b1,SRC1[19:0],SRC2}) : muxsrc1;      // feeding of R.T.F.
 
        assign shift = SELECT[1] ? {1'b0,rexdiff[4:0]} : (switch ? shift2 : shift1);
 
 
        always @(posedge BCLK)  // Pipeline Reg
        always @(posedge BCLK)  // Pipeline Reg
          begin
          begin
                muxsrc2 <= switch  ? {expo1,MAN1,SRC1}   : {expo2,MAN2,SRC2};   // Incl. Exponent & "1" of mantissa
                muxsrc2 <= switch  ? {expo1,MAN1,SRC1}   : {expo2,MAN2,SRC2};   // Incl. Exponent & "1" of mantisse
                pipe1 <= SELECT[1] ? (ganzklein ? 53'd0  : {1'b1,SRC1[19:0],SRC2}) : muxsrc1;    // Feeding of R.T.F.
                pshift  <= shift[2:0];
                shift <= SELECT[1] ? {1'b0,rexdiff[4:0]} : (switch ? shift2 : shift1);
 
          end
          end
 
 
        //      SRC2   SRC1     : switch = 0            SRC2   SRC1 : switch = 1
        //      SRC2   SRC1     : switch = 0            SRC2   SRC1 : switch = 1
        //        5  +   3  : +(5 + 3) =  8               3  +   5  : +(5 + 3) =  8             SELECT[0] = 0
        //        5  +   3  : +(5 + 3) =  8               3  +   5  : +(5 + 3) =  8             SELECT[0] = 0
        //        5  + (-3) : +(5 - 3) =  2               3  + (-5) : -(5 - 3) = -2
        //        5  + (-3) : +(5 - 3) =  2               3  + (-5) : -(5 - 3) = -2
Line 336... Line 355...
        assign CMPRES[0] = (ex_null & ma_null & (sign1 == sign2) & (lowdiff == 33'h0)) | (SRCFLAGS[2] & SRCFLAGS[0]);
        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,brshiftd,brshifte,brshiftf;
 
        reg      [55:0] brshiftc;
 
 
        // 5..33322222222221111111111   is this picture still correct ? Took over from Single FP
        // 5..33322222222221111111111   is this picture still correct ? Took over from Single FP
        // 5..2109876543210987654321098765432-10
        // 5..2109876543210987654321098765432-10
        // 1..VVVVVVVVVVVVVVVVVVVVVVVV0000000-00        // last 2 bit for rounding
        // 1..VVVVVVVVVVVVVVVVVVVVVVVV0000000-00        // last 2 bit for rounding
 
 
        assign brshifta = shift[5] ? {32'h0,   pipe1[55:33],   (pipe1[32:3] != 30'h0)} : {pipe1,3'h0};
        assign brshifta = shift[5] ? {32'h0,   pipe1[55:33],   (pipe1[32:3] != 30'h0)} : {pipe1,3'h0};
        assign brshiftb = shift[4] ? {16'h0,brshifta[55:17],(brshifta[16:0] != 17'h0)} : brshifta;
        assign brshiftb = shift[4] ? {16'h0,brshifta[55:17],(brshifta[16:0] != 17'h0)} : brshifta;
        assign brshiftc = shift[3] ? { 8'h0, brshiftb[55:9], (brshiftb[8:0] !=  9'h0)} : brshiftb;
        always @(posedge BCLK)
        assign brshiftd = shift[2] ? { 4'h0, brshiftc[55:5], (brshiftc[4:0] !=  5'h0)} : brshiftc;
                   brshiftc <=  shift[3] ? { 8'h0, brshiftb[55:9], (brshiftb[8:0] !=  9'h0)} : brshiftb;
        assign brshifte = shift[1] ? { 2'h0, brshiftd[55:3], (brshiftd[2:0] !=  3'h0)} : brshiftd;
        assign brshiftd  = pshift[2] ? { 4'h0, brshiftc[55:5], (brshiftc[4:0] !=  5'h0)} : brshiftc;
        assign brshiftf = shift[0] ? { 1'b0, brshifte[55:2], (brshifte[1:0] !=  2'h0)} : brshifte;
        assign brshifte  = pshift[1] ? { 2'h0, brshiftd[55:3], (brshiftd[2:0] !=  3'h0)} : brshiftd;
 
        assign brshiftf  = pshift[0] ? { 1'b0, brshifte[55:2], (brshifte[1:0] !=  2'h0)} : brshifte;
 
 
        // ++++++++++++++++++++++++++++++++++
        // ++++++++++++++++++++++++++++++++++
        // ROUNDLi/TRUNCLi/FLOORLi : 3. Step : round to Integer
        // ROUNDLi/TRUNCLi/FLOORLi : 3. Step : round to Integer
 
 
        reg                     car_ry;
        reg                     car_ry;
        wire  [1:0] inex;
        wire  [1:0] inex;
        wire [30:0] compl;
        wire [32: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 end
        assign inex     = {brshiftf[24],restbits};              // Inexact-Flag-Data transfered to multiplexer at the end
 
 
Line 368... Line 388...
                    2'b00 : car_ry = sign1 ^ (((brshiftf[25:24] == 2'b11) & ~restbits) | (inex == 2'b11));      // ROUNDLi
                    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, -numbers to "-infinity" round
                    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 iadder = (sign1 ? {2'b11,~brshiftf[55:25]} : {2'b0,brshiftf[55:25]}) + {32'h0,car_ry};
 
 
        assign iadder = {sign1,compl} + {31'h0,car_ry};
 
 
 
        always @(posedge BCLK) IOUT <= minint ? 32'h8000_0000 : iadder;
        always @(posedge BCLK) IOUT <= minint ? 32'h8000_0000 : iadder[31:0];
 
 
        always @(iadder or BWD or sign1)        // special overflow detection i.e. -129 to -255 at Byte
        always @(iadder or BWD or sign1)        // special overflow detection i.e. -129 to -255 at Byte
                casex (BWD)                                             // or 127.9 -> 128 = error !
                casex (BWD)                                             // or 127.9 -> 128 = error !
                  2'b00 : ovflag2 = (iadder[8]  != iadder[7]);  // Byte
                  2'b00 : ovflag2 = (iadder[8]  != iadder[7]);  // Byte
                  2'b01 : ovflag2 = (iadder[16] != iadder[15]); // Word
                  2'b01 : ovflag2 = (iadder[16] != iadder[15]); // Word
                default : ovflag2 = 1'b0;
                default : ovflag2 = (iadder[32] != iadder[31]); // Double
                endcase
                endcase
 
 
        // ++++++++++++++++++++++++++++++++++
        // ++++++++++++++++++++++++++++++++++
        // ADD/SUB : 3. Step : Addition or Subtraction
        // ADD/SUB : 3. Step : Addition or Subtraction
 
 
Line 450... Line 468...
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      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, MAN2, SRCFLAGS, MODE, OUT );
 
 
        input                   BCLK;
        input                   BCLK;
        input                   START;
        input    [1:0]   START;
        input   [31:0]   SRC1,SRC2;
        input   [31:0]   SRC1,SRC2;
        input                   SRCFLAG;
        input   [19:0]   MAN2;
        input                   MIMUX;
        input    [5:0]   SRCFLAGS;
        input    [3:0]   MODE;
        input    [3:0]   MODE;
        output  [69:0]   OUT;
        output  [69:0]   OUT;
 
 
        reg             [69:0]   OUT;
        reg             [69:0]   OUT;
        reg             [63:0]   daten;
        reg             [63:0]   daten;
 
 
        wire    [10:0]   scalb_l;
        wire                    sign;
        wire                    nan,zero,sign;
 
        wire    [12:0]   lexpo,sexpo;
        wire    [12:0]   lexpo,sexpo;
        wire    [69:0]   scalb_res,logb_res,fl_lf;
        wire    [69:0]   scalb_res,logb_res,fl_lf;
 
 
        always @(posedge BCLK) if (START) daten <= {(MIMUX ? {daten[31],scalb_l,daten[19:0]}: SRC1),SRC2};
        always @(posedge BCLK) if (START[1]) daten <= {SRC1,SRC2};
 
        assign sign = daten[63];
 
 
        assign nan  = MODE[0] ? (daten[62:55] == 8'hFF) : (daten[62:52] == 11'h7FF);
        // +++++++++++++++++++++++++++ MOVFL and MOVLF +++++++++++++++++++++++++++++++++++
        assign zero = MODE[0] ? (daten[62:55] == 8'h00) : (daten[62:52] == 11'h000);
 
        assign sign = daten[63] & ~zero;
 
 
 
        assign lexpo = {5'b0,daten[62:55]} + 13'h0380;  // -7F + 3FF
        assign lexpo = {5'b0,daten[62:55]} + 13'h0380;  // -7F + 3FF
 
 
        assign sexpo = (daten[62:52] > 11'h47E) ? 13'h0FFF
        assign sexpo = (daten[62:52] > 11'h47E) ? 13'h0FFF
                                                                                        : ((daten[62:52] < 11'h381) ? 13'h0 : {2'b0,{4{daten[62]}},daten[58:52]});
                                                                                        : ((daten[62:52] < 11'h381) ? 13'h0 : {2'b0,{4{daten[62]}},daten[58:52]});
 
 
        assign fl_lf = MODE[0] ? {nan,zero,sign,lexpo,daten[54:32],31'h0}                                                                                // MOVFL
        assign fl_lf = MODE[0] ? {SRCFLAGS[1:0],sign,lexpo,daten[54:32],31'h0}                                                                            // MOVFL
                                                   : {nan,zero,sign,sexpo,daten[51:29],28'h0,daten[29:28],(daten[27:0] != 28'h0)};       // MOVLF
                                                   : {SRCFLAGS[1:0],sign,sexpo,daten[51:29],28'h0,daten[29:28],(daten[27:0] != 28'h0)};   // MOVLF
 
 
        // +++++++++++++++++++++++++++  LOGBf  +++++++++++++++++++++++++++++++++++
        // +++++++++++++++++++++++++++  LOGBf  +++++++++++++++++++++++++++++++++++
 
 
        wire                    logb_null;
 
        wire     [9:0]   sel_data,unbiased,shift_l8,shift_l4,shift_l2;
        wire     [9:0]   sel_data,unbiased,shift_l8,shift_l4,shift_l2;
        wire     [8:0]   shift_l;
        wire     [8:0]   shift_l;
        wire                    posi_8,posi_4,posi_2,posi_1;
        wire                    posi_8,posi_4,posi_2,posi_1;
        wire     [4:0]   calc_exp;
        wire     [4:0]   calc_exp;
        wire     [6:0]   logb_exp;
        wire     [6:0]   logb_exp;
 
 
        assign logb_null = MODE[1] ? (daten[62:55] == 8'h7F) : (daten[62:52] == 11'h3FF);
 
 
 
        assign sel_data  = MODE[1] ? {{3{~daten[62]}},daten[61:55]} : daten[61:52];
        assign sel_data  = MODE[1] ? {{3{~daten[62]}},daten[61:55]} : daten[61:52];
        assign unbiased  = daten[62] ? (sel_data + 10'h001) : ~sel_data;
        assign unbiased  = daten[62] ? (sel_data + 10'h001) : ~sel_data;
 
 
        // detection of leading "1"
        // detection of leading "1"
        assign posi_8   = (unbiased[9:2] == 8'h00);
        assign posi_8   = (unbiased[9:2] == 8'h00);
Line 511... Line 524...
        assign calc_exp = 5'h08 - {1'b0,posi_8,posi_4,posi_2,posi_1};   // Minimum is "F" = for exponent +/-1 <=> 2^0
        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_exp[3:0],shift_l,45'h0};
        assign logb_res = {SRCFLAGS[1],1'b0,~daten[62],2'b00,logb_exp,calc_exp[3:0],shift_l,45'h0};
 
 
        // ++++++++++++++++++++++++  SCALBf  ++++++++++++++++++++++++++++++++++
        // ++++++++++++++++++++++++  SCALBf  ++++++++++++++++++++++++++++++++++
 
 
        wire     [7:0]   scalb_f;
        reg              [3:0]   rshift;
 
        reg             [10:0]   shf_r0,dexpo;   // dexpo = Exponent Destination
 
        reg                             huge;
 
        reg                             svorz,dvorz;
 
 
 
        wire    [10:0]   shf_r1,shf_r2,shf_r4,shf_r8;
 
        wire    [12:0]   addexp,newexp,finexp;
 
        wire                    nan;
 
 
        assign scalb_f = SRCFLAG ?  8'h00  : (daten[39:32] + daten[30:23]);
        always @(posedge BCLK)  // 2**0,9.. is transformed to 2**0 = 1 -> no change at SRC2
        assign scalb_l = SRCFLAG ? 11'h000 : (daten[42:32] + daten[30:20]);
                if (START[0])
 
                        begin
 
                                shf_r0 <= ( SRC1[30] | ((SRC1[29:23] ==  7'h7F) & (MODE[1] | (SRC1[22:20] == 3'd7))) ) ?
 
                                                                (MODE[1] ? {4'd1,SRC1[22:16]} : {1'b1,SRC1[19:10]}) : 11'd0;
 
                                rshift <= MODE[1] ? 4'd6 - SRC1[26:23] : 4'd9 - SRC1[23:20];
 
                                huge   <= MODE[1] ? ( SRC1[30] & ((SRC1[29:26] != 4'd0) | (SRC1[25:23] == 3'h7)) )      // >406 in Double Style
 
                                                                  : ( SRC1[30] & ((SRC1[29:24] != 6'd0) | (SRC1[23] & (SRC1[22] | SRC1[21]))) );        // >409
 
                                svorz  <= SRC1[31];
 
                                dvorz  <= SRC2[31];
 
                                dexpo  <= MODE[1] ? {3'd0,SRC2[30:23]} : SRC2[30:20];
 
                        end
 
 
 
        assign shf_r1 = rshift[0] ? {1'b0,shf_r0[10:1]} : shf_r0;        // a mini-TRUNC of 11 Bits
 
        assign shf_r2 = rshift[1] ? {2'd0,shf_r1[10:2]} : shf_r1;
 
        assign shf_r4 = rshift[2] ? {4'd0,shf_r2[10:4]} : shf_r2;
 
        assign shf_r8 = rshift[3] ? {8'd0,shf_r4[10:8]} : shf_r4;
 
 
 
        assign addexp = svorz ? {2'd0,dexpo} - {2'd0,shf_r8} : {2'd0,dexpo} + {2'd0,shf_r8};
 
 
        assign scalb_res = MODE[1] ?    // no rounding of Single Data
        assign newexp = MODE[1] ? {addexp[9:8],{3{addexp[7]}},addexp[7:0]} : addexp[12:0];
                                           {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};
        assign finexp = SRCFLAGS[2] ? {3'd0,newexp[9:0]} // never an Overflow if SRC2 = 0.0 !
 
                                                                : {(huge ? {svorz,1'b1} : newexp[12:11]),newexp[10:0]};  // Overflow or Underflow
 
 
 
        assign nan = SRCFLAGS[3] | SRCFLAGS[1];
 
 
 
        assign scalb_res = MODE[1] ?    // Mantisse doesn't change !
 
                                           {nan,SRCFLAGS[2],daten[31],finexp,daten[22:0],daten[28:0],2'b00}
 
                                         : {nan,SRCFLAGS[2],dvorz,finexp,MAN2,daten[31:0],2'b00};
 
 
        // ++++++++++++++++++++++++  Output  ++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // ++++++++++++++++++++++++  Output  ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
        always @(posedge BCLK) OUT <= MODE[3] ? (MODE[2] ? logb_res : scalb_res) : fl_lf ;      // LOGB/SCALB : MOVLF/MOVFL
        always @(posedge BCLK) OUT <= MODE[3] ? (MODE[2] ? logb_res : scalb_res) : fl_lf ;      // LOGB/SCALB : MOVLF/MOVFL
 
 
Line 573... Line 617...
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      7. DIVI_PREP    Prepare data for the divider
//      7. SCANDIG              Scan digit for leading one
 
//
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
module SCANDIG (DIN, MBIT, LBIT, NONZ);
 
 
 
        input   [3:0]    DIN;
 
        output                  MBIT,LBIT,NONZ;
 
 
 
        assign MBIT = DIN[3] | DIN[2];                                  // 1xxx = 11
 
        assign LBIT = DIN[3] | (DIN[3:1] == 3'b001);    // 01xx = 10
 
        assign NONZ = (DIN != 4'd0);                                    // 001x = 01
 
 
 
endmodule
 
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
//
 
//      8. 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;
Line 589... Line 649...
        output   [4:0]   MSB;
        output   [4:0]   MSB;
        output                  NULL;
        output                  NULL;
        output                  MINUS;
        output                  MINUS;
 
 
        reg             [31:0]   double;
        reg             [31:0]   double;
 
        reg              [2:0]   select;
 
 
        wire    [15:0]   test_16;
 
        wire     [7:0]   test_8;
 
        wire     [3:0]   test_4;
 
        wire     [1:0]   test_2;
 
        wire                    bit_4,bit_3,bit_2,bit_1,bit_0;
 
        wire     [1:0]   modus;
        wire     [1:0]   modus;
 
        wire     [7:0]   mbits,lbits,dnonz;
 
 
        assign modus = (NOT_DEI | EXTDATA) ? BWD : {(BWD[1] | BWD[0]),1'b1};
        assign modus = (NOT_DEI | EXTDATA) ? BWD : {(BWD[1] | BWD[0]),1'b1};
 
 
        always @(modus or SRC or NOT_DEI)
        always @(modus or SRC or NOT_DEI)
                casex (modus)
                casex (modus)
Line 612... Line 669...
 
 
        assign DOUT = ({32{MINUS}} ^ double) + {31'h0,MINUS};   //      assign DOUT = MINUS ? (32'd0 - double) : double;
        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);
        SCANDIG digit_0 (.DIN(DOUT[3:0]),   .MBIT(mbits[0]), .LBIT(lbits[0]), .NONZ(dnonz[0]) );
        assign test_16 = bit_4 ? DOUT[31:16]   : DOUT[15:0];
        SCANDIG digit_1 (.DIN(DOUT[7:4]),   .MBIT(mbits[1]), .LBIT(lbits[1]), .NONZ(dnonz[1]) );
        assign bit_3   = (test_16[15:8] != 8'h0);
        SCANDIG digit_2 (.DIN(DOUT[11:8]),  .MBIT(mbits[2]), .LBIT(lbits[2]), .NONZ(dnonz[2]) );
        assign test_8  = bit_3 ? test_16[15:8] : test_16[7:0];
        SCANDIG digit_3 (.DIN(DOUT[15:12]), .MBIT(mbits[3]), .LBIT(lbits[3]), .NONZ(dnonz[3]) );
        assign bit_2   = (test_8[7:4] != 4'h0);
        SCANDIG digit_4 (.DIN(DOUT[19:16]), .MBIT(mbits[4]), .LBIT(lbits[4]), .NONZ(dnonz[4]) );
        assign test_4  = bit_2 ? test_8[7:4]   : test_8[3:0];
        SCANDIG digit_5 (.DIN(DOUT[23:20]), .MBIT(mbits[5]), .LBIT(lbits[5]), .NONZ(dnonz[5]) );
        assign bit_1   = (test_4[3:2] != 2'b0);
        SCANDIG digit_6 (.DIN(DOUT[27:24]), .MBIT(mbits[6]), .LBIT(lbits[6]), .NONZ(dnonz[6]) );
        assign test_2  = bit_1 ? test_4[3:2]   : test_4[1:0];
        SCANDIG digit_7 (.DIN(DOUT[31:28]), .MBIT(mbits[7]), .LBIT(lbits[7]), .NONZ(dnonz[7]) );
        assign bit_0   =  test_2[1];
 
        assign NULL    = (test_2 == 2'b00);
        always @(dnonz)
 
                casex (dnonz[7:1])
 
                  7'b1xxx_xxx : select = 3'b111;
 
                  7'b01xx_xxx : select = 3'b110;
 
                  7'b001x_xxx : select = 3'b101;
 
                  7'b0001_xxx : select = 3'b100;
 
                  7'b0000_1xx : select = 3'b011;
 
                  7'b0000_01x : select = 3'b010;
 
                  7'b0000_001 : select = 3'b001;
 
                  default     : select = 3'b000;
 
                endcase
 
 
 
        assign NULL = (dnonz == 8'd0);
 
 
        assign MSB = {bit_4,bit_3,bit_2,bit_1,bit_0};
        assign MSB = {select,mbits[select],lbits[select]};
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      8. DFPU_DIV             The divider for all divide opcodes : double, single and integer
//      9. 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, DIVI_OUT, DVZ_TRAP, DEI_OVF );
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.
Line 933... Line 1002...
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      9. DP_LOGIK             Control logic and result path for different functions
//      10. 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, CY_IN,
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, COP_GO );
                                  DOUT, TT_DP, DP_CMP, OVF_BCD, MEI, DFLOAT, DONE, UP_DP, CLR_LSB, WREN_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 978... Line 1047...
        output  [63:0]   DOUT;
        output  [63:0]   DOUT;
        output   [4:0]   TT_DP;          // Trap-Info to FSR
        output   [4:0]   TT_DP;          // Trap-Info to FSR
        output   [2:0]   DP_CMP;         // CMPL result
        output   [2:0]   DP_CMP;         // CMPL result
        output   [3:0]   OVF_BCD;        // Integer Division Overflow + BCD Carry update
        output   [3:0]   OVF_BCD;        // Integer Division Overflow + BCD Carry update
        output                  MEI,DFLOAT;
        output                  MEI,DFLOAT;
        output                  DONE,UP_DP;
        output                  DONE,UP_DP,WREN_L;
        output                  CLR_LSB,WREN_L,LD_OUT_L;
        output  reg             CLR_LSB;
        output                  DVZ_TRAP;
        output                  DVZ_TRAP;
        output  reg             COP_GO;
        output  reg             COP_GO;
 
 
        reg             [63:0]   DOUT;
        reg             [63:0]   DOUT;
        reg                             CLR_LSB;
 
        reg              [2:0]   DP_CMP;
        reg              [2:0]   DP_CMP;
        reg              [5:0]   preflags;
        reg              [5:0]   preflags;
        reg              [5:0]   srcflags;
        reg              [5:0]   srcflags;
        reg             [69:0]   fpout;
        reg             [69:0]   fpout;
        reg              [2:0]   tt;
        reg              [2:0]   tt;
        reg              [6:0]   select;
        reg              [7:0]   select;
        reg              [4:0]   wctrl;
        reg              [5:0]   wctrl;
        reg              [2:1]  sequ;
        reg              [2:1]  sequ;
        reg                             misc_op;
        reg                             misc_op;
        reg                             misc_mux;
 
        reg                     car_ry;
        reg                     car_ry;
        reg                             wr_part2;
        reg                             wr_part2;
        reg                             up_flag;
        reg                             up_flag;
        reg                             ovf_div;
        reg                             ovf_div;
 
        reg                             late_bcd_done;
 
 
        wire                    zexp2,zman2,zexp1,zman1,znan1;
        wire                    zexp2,zman2,zexp1,zman1,znan1;
        wire                    make_i;
        wire                    make_i;
        wire                    scalbl,go_misc;
 
        wire                    op_cmp;
        wire                    op_cmp;
        wire    [69:0]   mulout,addout,divout,miscout;
        wire    [69:0]   mulout,addout,divout,miscout;
        wire                    go_divf,go_divi,divi_ops,div_done;
        wire                    go_divf,go_divi,divi_ops,div_done;
        wire                    bcd_ops,man_ops;
        wire                    bcd_ops,man_ops;
        wire    [31:0]   i_out;
        wire    [31:0]   i_out;
Line 1015... Line 1082...
        wire                    div_zero,overflow,underflow,inexact;
        wire                    div_zero,overflow,underflow,inexact;
        wire     [1:0]   cmpres;
        wire     [1:0]   cmpres;
        wire    [63:0]   fp_out,fp_res;
        wire    [63:0]   fp_out,fp_res;
        wire                    wr_part1;
        wire                    wr_part1;
        wire                    done_i;
        wire                    done_i;
 
        wire                    later;
        wire    [31:0]   bcd_q;
        wire    [31:0]   bcd_q;
        wire                    bcd_done;
        wire                    bcd_done;
        wire                    bcd_carry;
        wire                    bcd_carry;
        wire     [1:0]   dei_ovf;
        wire     [1:0]   dei_ovf;
        wire                    quo_div;
        wire                    quo_div;
Line 1027... Line 1095...
 
 
        // Control of datapath : together with START the Double Unit becomes activ 
        // Control of datapath : together with START the Double Unit becomes activ 
 
 
        always @(OPCODE or FL)
        always @(OPCODE or FL)
                casex (OPCODE)
                casex (OPCODE)
                  8'b1001_000x : select = 7'b00_01010;  // 0 1 0 :      MOViL
                  8'b1001_000x : select = {5'b0000_0,                   ~FL ,2'b10};    // 0 1 0 :      MOViL
                  8'b1001_010x : select = 7'b10_11000;  // MOVLF
                  8'b1001_010x : select = {5'b0001_1,                   1'b1,2'b00};    // MOVLF
                  8'b1001_011x : select = 7'b01_11000;  // MOVFL
                  8'b1001_011x : select = {5'b0011_1,                   1'b1,2'b00};    // MOVFL
                  8'b1001_100x : select = 7'b10_01011;  // 0 1 1 :      ROUNDLi
                  8'b1001_100x : select = {5'b0001_0,                   ~FL ,2'b11};    // 0 1 1 :      ROUNDLi
                  8'b1001_101x : select = 7'b10_01011;  // 0 1 1 :  TRUNCLi
                  8'b1001_101x : select = {5'b0001_0,                   ~FL ,2'b11};    // 0 1 1 :  TRUNCLi
                  8'b1001_111x : select = 7'b10_01011;  // 0 1 1 :      FLOORLi
                  8'b1001_111x : select = {5'b0001_0,                   ~FL ,2'b11};    // 0 1 1 :      FLOORLi
                  8'b1011_0000 : select = 7'bxx_01000;  // 0 0 0 :      ADDL
                  8'b1011_0000 : select = {5'b1010_0,                   ~FL ,2'b00};    // 0 0 0 :      ADDL    Es werden Shifter wiederverwendet...
                  8'b1011_0010 : select = 7'bxx_01001;  // 0 0 1 :      CMPL
                  8'b1011_0010 : select = {5'b1010_0,                   ~FL ,2'b01};    // 0 0 1 :      CMPL
                  8'b1011_0100 : select = 7'bxx_01001;  // 0 0 1 :      SUBL
                  8'b1011_0100 : select = {5'b1010_0,                   ~FL ,2'b01};    // 0 0 1 :      SUBL
                  8'b1011_1000 : select = 7'b11_01100;  // 1 0 1 :  DIVf , Default Float for srcflags
                  8'b1011_1000 : select = {1'b1,FL,1'b1,FL,1'b0,1'b1,2'b00};    // 1 0 1 :  DIVf , Default Float fuer srcflags
                  8'b1011_1100 : select = 7'bxx_01100;  // 1 0 0 :      MULL
                  8'b1011_1100 : select = {5'b1010_0,                   ~FL ,2'b00};    // 1 0 0 :      MULL
                  8'b1011_0110 : select = 7'b11_11000;  // SCALBf , Default Float for srcflags
                  8'b1011_0110 : select = {1'b1,FL,1'b1,FL,1'b1,1'b1,2'b00};    // SCALBf
                  8'b1011_0111 : select = {~FL,FL,5'b11000};    // LOGBf
                  8'b1011_0111 : select = {2'b00,FL,2'b1_1,             1'b1,2'b00};    // LOGBf
                  default      : select = 7'b0;
                  default      : select = 8'b0;
                endcase
                endcase
 
 
        assign MEI      = (OPCODE == 8'h79);
        assign MEI      = (OPCODE == 8'h79);
        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'h71) | (OPCODE == 8'h70);        // ADDP , SUBP
 
 
        assign man_ops  = (OPCODE == 8'hB1) | (OPCODE == 8'hB5) | (OPCODE == 8'hB9) | (OPCODE == 8'hBD);        // MOVf,NEGf,XXXf,ABSf
        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[2] | 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 multiplexer
        assign make_i   = (select[1:0] == 2'b11) | 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[3];    // 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);        // Custom Convert
        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
 
        assign scalbl   = START[0] & ~FL & (OPCODE == 8'hB6);
 
        assign go_misc  = START[1] | scalbl;
 
        always @(posedge BCLK) misc_mux <= scalbl;      // switches at START[1] the input multiplexer
 
 
 
        // SRCFLAGS : special handling for operands is done locally
        // SRCFLAGS : special handling for operands is done locally
 
 
        assign zexp2 = (SRC2[30:20] == 11'd0);
        assign zexp2 = (SRC2[30:20] == 11'd0);
        assign zman2 = (SRC2[19:0] == 20'd0);
        assign zman2 = (SRC2[19:0] == 20'd0);
        assign zexp1 = (SRC1[30:20] == 11'd0);
        assign zexp1 = (SRC1[30:20] == 11'd0);
Line 1087... Line 1150...
        //                                       10 : 1 Long Operand SRC1+SRC2
        //                                       10 : 1 Long Operand SRC1+SRC2
        //                                       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]})
                        case (select[7:6])
                           3'b0xx : srcflags[3] <= preflags[5] | (preflags[4] & (~preflags[3] | SRC2[31] | ~zexp2 | ~zman2));
                          2'b10 : 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'd0) | ~zman2)); // F:SRC2 = NaN
                          2'b11 : 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[1])
                        casex ({START[1],select[6:5]})
                        case (select[7:6])
                           3'b0xx : srcflags[2] <= zexp2;       // L:(SRC1,SRC2) = Zero , SRC1 = MSB
                          2'b10 : srcflags[2] <= preflags[4];   // L:SRC2 = Zero , 2*SRC2
                           3'b111 : srcflags[2] <= (SRC2[30:23] == 8'd0);       // F:SRC2 = Zero
                          2'b11 : srcflags[2] <= (SRC2[30:23] == 8'd0); // F:SRC2 = Zero
                          default : srcflags[2] <= 1'b0;
                          default : srcflags[2] <= 1'b0;
                        endcase
                        endcase
 
 
        always @(posedge BCLK)  // NaN 
        always @(posedge BCLK)  // NaN 
                if (START[1])
                if (START[1])
                        casex ({START[0],select[6:5]})
                        case (select[5:4])
                           3'b0xx : srcflags[1] <= preflags[2] | (preflags[1] & (~preflags[0] | SRC1[31] | ~zexp1 | ~zman1));
                          2'b01 : srcflags[1] <= znan1 | (zexp1 & (~zman1 | SRC2[31] | ~zexp2 | ~zman2));       // L:(SRC1,SRC2) = NaN , SRC1 = MSB
                           3'b1x1 : srcflags[1] <= (SRC1[30:23] == 8'hFF) | ((SRC1[30:23] == 8'd0) & ((SRC1[22:20] != 3'd0) | ~zman1)); // F:SRC1 = NaN
                          2'b10 : srcflags[1] <= preflags[2] | (preflags[1] & (~preflags[0] | SRC1[31] | ~zexp1 | ~zman1));
                           3'b110 : srcflags[1] <= znan1 | (zexp1 & (~zman1 | SRC2[31] | ~zexp2 | ~zman2));     // L:(SRC1,SRC2) = NaN , SRC1 = MSB
                          2'b11 : srcflags[1] <= (SRC1[30:23] == 8'hFF) | ((SRC1[30:23] == 8'd0) & ((SRC1[22:20] != 3'd0) | ~zman1));   // F:SRC1 = NaN
                          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[1])
                        casex ({START[1],select[6:5]})
                        case (select[5:4])
                           3'b0xx : srcflags[0] <= zexp1;        // L:(SRC1,SRC2) = Zero , SRC1 = MSB
                          2'b01 : srcflags[0] <= zexp1;  // L:(SRC1,SRC2) = Zero , SRC1 = MSB, Special Case ROUNDL,etc.
                           3'b1x1 : srcflags[0] <= (SRC1[30:23] == 8'd0);        // F:SRC1 = Zero
                          2'b10 : srcflags[0] <= preflags[1];    // L:SRC1 = Zero , 2*SRC1
                           3'b110 : srcflags[0] <= zexp1;        // L:(SRC1,SRC2) = Zero , SRC1 = MSB
                          2'b11 : srcflags[0] <= (SRC1[30:23] == 8'd0);  // F:SRC1 = Zero
                          default : srcflags[0] <= 1'b0;
                          default : srcflags[0] <= 1'b0;
                        endcase
                        endcase
 
 
                        // The Sub-moduls : 
                        // The Sub-moduls : 
 
 
        DFPU_ADDSUB as_inst     ( .BCLK(BCLK), .START(START), .SRC1(SRC1), .SRC2(SRC2),
        DFPU_ADDSUB as_inst     ( .BCLK(BCLK), .START(START), .SRC1(SRC1), .SRC2(SRC2),
                                                  .MAN1({~srcflags[0],MAN1[19:0]}), .MAN2({~srcflags[2],MAN2[19:0]}),
                                                  .MAN1({~preflags[1],MAN1[19:0]}), .MAN2({~preflags[4],MAN2[19:0]}),
                                                  .SRCFLAGS(srcflags), .BWD(BWD), .SELECT({OPCODE[2:1],select[1:0]}),
                                                  .SRCFLAGS(srcflags), .BWD(BWD), .SELECT({OPCODE[2:1],select[1:0]}),
                                                  .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(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(START), .SRC1(SRC1), .SRC2(SRC2), .MAN2(MAN2[19:0]), .SRCFLAGS(srcflags),
                                                  .MIMUX(misc_mux), .MODE({OPCODE[5],OPCODE[0],FL,OPCODE[1]}), .OUT(miscout) );
                                                  .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), .SRC1(SRC1), .SRC2(SRC2),
        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[0]), .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)
                casex ({misc_op,OPCODE[5],OPCODE[3:2]}) //OPCODE[5] only for Flags i.e. NAN 
                casex ({misc_op,OPCODE[5],OPCODE[3:2]}) //OPCODE[5] only for Flags i.e. NAN 
Line 1162... Line 1225...
        assign cy_val = {35'h0,(FL & car_ry),28'h0,(~FL & car_ry)};
        assign cy_val = {35'h0,(FL & car_ry),28'h0,(~FL & car_ry)};
 
 
        assign rund = {fpout[66:2]} + cy_val;
        assign rund = {fpout[66:2]} + cy_val;
 
 
        // Detection of Div-by-0, Overflow, Underflow and Inexact : Epxonent from [66:54] = 13 Bits
        // Detection of Div-by-0, Overflow, Underflow and Inexact : Epxonent from [66:54] = 13 Bits
        assign div_zero  = (srcflags[3:0] == 4'h1) & (OPCODE == 8'hB8);  // true FPU Divide by Zero
        assign div_zero  = (srcflags[3:0] == 4'h1) & ((OPCODE == 8'hB8) | (OPCODE == 8'hB7));    // true FPU Divide by Zero also for LOGBf
        assign overflow  = ~rund[66] & (rund[65] | (rund[64:54] == 11'h7FF));
        assign overflow  = ~rund[66] & (rund[65] | (rund[64:54] == 11'h7FF));
        assign underflow = (rund[66] | (rund[65:54] == 12'h0)) & ~fpout[68];    // Zero-Flag
        assign underflow = (rund[66] | (rund[65:54] == 12'h0)) & ~fpout[68];    // Zero-Flag
        assign inexact   = (fpout[1:0] != 2'b00);
        assign inexact   = (fpout[1:0] != 2'b00);
 
 
        always @(fpout or op_cmp or div_zero or overflow or underflow or inexact or FSR)
        always @(fpout or op_cmp or div_zero or overflow or underflow or inexact or FSR)
Line 1204... Line 1267...
        // Pipeline Control + Registerfile write control
        // Pipeline Control + Registerfile write control
 
 
        always @(posedge BCLK or negedge BRESET)
        always @(posedge BCLK or negedge BRESET)
                if (!BRESET) sequ <= 2'b00;
                if (!BRESET) sequ <= 2'b00;
                  else
                  else
                        sequ <= {(sequ[1] & ~DONE),START[1]};
                        sequ <= {(sequ[1] & ~DONE),(START[1] & ~wctrl[5])};
 
 
        always @(FL or OPCODE or copwr)
        always @(FL or OPCODE or copwr)
                casex ({FL,OPCODE})     // WRITE Control : [2] = clr_lsb, [1] = wr_part2, [0] = wr_part1
                casex ({FL,OPCODE})     // WRITE Control : [2] = clr_lsb, [1] = wr_part2, [0] = wr_part1
                  9'bx_1001_000x : wctrl = 5'b01_111;   // MOViL
                  9'b0_1001_000x : wctrl = 6'b001_111;  // MOViL
                  9'bx_1001_010x : wctrl = 5'b00_010;   // MOVLF
                  9'b1_1001_000x : wctrl = 6'b100_010;  // MOViF  <= SFPU
                  9'bx_1001_011x : wctrl = 5'b01_111;   // MOVFL
                  9'bx_1001_010x : wctrl = 6'b000_010;  // MOVLF
                  9'bx_1001_100x : wctrl = 5'b00_010;   // ROUNDLi      - DONE is one cycle earlier for this opcodes
                  9'bx_1001_011x : wctrl = 6'b001_111;  // MOVFL
                  9'bx_1001_101x : wctrl = 5'b00_010;   // TRUNCLi      
                  9'b0_1001_100x : wctrl = 6'b000_010;  // ROUNDLi
                  9'bx_1001_111x : wctrl = 5'b00_010;   // FLOORLi
                  9'b0_1001_101x : wctrl = 6'b000_010;  // TRUNCLi
                  9'bx_1011_0000 : wctrl = 5'b01_111;   // ADDL
                  9'b0_1001_111x : wctrl = 6'b000_010;  // FLOORLi
                  9'bx_1011_0010 : wctrl = 5'b00_000;   // CMPL - via LD one cycle later in PSR
                  9'b1_1001_100x : wctrl = 6'b100_010;  // ROUNDFi
                  9'bx_1011_0100 : wctrl = 5'b01_111;   // SUBL
                  9'b1_1001_101x : wctrl = 6'b100_010;  // TRUNCFi
                  9'b1_1011_1000 : wctrl = 5'b10_001;   // DIVF - measured 18 cycles Reg-Reg
                  9'b1_1001_111x : wctrl = 6'b100_010;  // FLOORFi
                  9'b0_1011_1000 : wctrl = 5'b10_111;   // DIVL - measured 34 cycles Reg-Reg
                  9'b0_1011_0000 : wctrl = 6'b001_111;  // ADDL
                  9'bx_1011_1100 : wctrl = 5'b01_111;   // MULL
                  9'b1_1011_0000 : wctrl = 6'b100_010;  // ADDF   <= SFPU
                  9'bx_0110_1x11 : wctrl = 5'b10_001;   // ADDP,SUBP
                  9'b0_1011_0010 : wctrl = 6'b000_000;  // CMPL
                  9'bx_0111_1001 : wctrl = 5'b00_111;   // MEIi
                  9'b1_1011_0010 : wctrl = 6'b100_000;  // CMPF
                  9'bx_0111_1011 : wctrl = 5'b10_111;   // DEIi
                  9'b0_1011_0100 : wctrl = 6'b001_111;  // SUBL
                  9'bx_0111_11xx : wctrl = 5'b10_001;   // QUOi,REMi,MODi,DIVi
                  9'b1_1011_0100 : wctrl = 6'b100_010;  // SUBF   <= SFPU
                  9'b1_1011_011x : wctrl = 5'b00_010;   // SCALBF/LOGBF
                  9'b1_1011_1000 : wctrl = 6'b010_001;  // DIVF - measured 18 clocks Reg-Reg
                  9'b0_1011_011x : wctrl = 5'b01_111;   // SCALBL/LOGBL
                  9'b0_1011_1000 : wctrl = 6'b010_111;  // DIVL - measured 34 clocks Reg-Reg
                  9'bx_1101_1101 : wctrl = {4'b10_00,copwr};    // execute coprocessor opcode
                  9'b0_1011_1100 : wctrl = 6'b001_111;  // MULL
                  default        : wctrl = 5'b0;
                  9'b1_1011_1100 : wctrl = 6'b100_010;  // MULF   <= SFPU
                endcase
                  9'bx_0111_000x : wctrl = 6'b100_010;  // ADDP,SUBP
 
                  9'bx_0111_1001 : wctrl = 6'b000_111;  // MEIi
        assign done_i = wctrl[4] ? (div_done | bcd_done | COP_DONE) : ( (wctrl[3] | ~WR_REG) ? sequ[2] : sequ[1] );
                  9'bx_0111_1011 : wctrl = 6'b010_111;  // DEIi
        assign DONE = ~START[1] & done_i;       // DONE is valid for all opcodes
                  9'bx_0111_11xx : wctrl = 6'b010_001;  // QUOi,REMi,MODi,DIVi
 
                  9'b1_1011_011x : wctrl = 6'b000_010;  // SCALBF/LOGBF
 
                  9'b0_1011_011x : wctrl = 6'b001_111;  // SCALBL/LOGBL
 
                  9'bx_1101_1101 : wctrl = {5'b010_00,copwr};   // Coprocessor opcode
 
                  default        : wctrl = 6'b00;
 
                endcase
 
 
 
        assign later = wctrl[3] & WR_REG;       // if DEST = Reg and 64 bit of data then DONE comes 1 clock later
 
        assign done_i = wctrl[4] ? (div_done | COP_DONE) : ( later ? sequ[2] : sequ[1] );
 
        assign DONE = wctrl[5] ? (bcd_ops ? bcd_done : START[1]) : ~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];
        always @(posedge BCLK) wr_part2 <= DONE & WR_REG & wctrl[1];
        always @(posedge BCLK) wr_part2 <= DONE & WR_REG & wctrl[1];
 
 
        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"
 
 
 
        always @(posedge BCLK) up_flag <= DONE & ~wctrl[0];              // DONE one cycle later
        always @(posedge BCLK) up_flag <= DONE & ~later;                // DONE one cycle later
        assign UP_DP    = (select[3] & (wctrl[0] ? DONE : up_flag)) | man_ops;   // Update FSR Trap etc. : all FPU opcodes of DP_FPU
        assign UP_DP    = (select[2] & (later ? 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 1254... Line 1325...
                   3'b101 : ovf_div = (divi_out[47] & SRC1[15] & SRC2[15]) & quo_div;
                   3'b101 : ovf_div = (divi_out[47] & SRC1[15] & SRC2[15]) & quo_div;
                   3'b11x : ovf_div = (divi_out[63] & SRC1[31] & SRC2[31]) & quo_div;
                   3'b11x : ovf_div = (divi_out[63] & SRC1[31] & SRC2[31]) & quo_div;
                  default : ovf_div = dei_ovf[0] & (OPCODE == 8'h7B);    // DEI
                  default : ovf_div = dei_ovf[0] & (OPCODE == 8'h7B);    // DEI
                endcase
                endcase
 
 
        assign OVF_BCD = {dei_ovf[1],ovf_div,bcd_done,bcd_carry};       // to I_PFAD
        always @(posedge BCLK) late_bcd_done <= bcd_done;       // parallel to data write
 
 
 
        assign OVF_BCD = {dei_ovf[1],ovf_div,late_bcd_done,bcd_carry};  // to I_PFAD
 
 
        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
// 11. 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, WREN_L,
module DP_FPU( BCLK, FL, BRESET, LD_OUT, WR_REG, BWD, FSR, OPCODE, SRC1, SRC2, START, CY_IN, COP_DONE, COP_OP, COP_IN,
                           CLR_LSB, LD_OUT_L, DVZ_TRAP, DP_CMP, DP_OUT, DP_Q, TT_DP, CY_IN, OVF_BCD, COP_GO, COP_OP,
                           DONE, UP_DP, WREN_L, CLR_LSB, DVZ_TRAP, DP_CMP, DP_OUT, DP_Q, TT_DP, OVF_BCD, COP_GO, COP_OUT );
                           COP_IN, COP_DONE, COP_OUT );
 
 
 
input                   BCLK;
input                   BCLK;
input                   FL;
input                   FL;
input                   BRESET;
input                   BRESET;
input                   LD_LDQ;
input    [1:0]   LD_OUT;
input                   WR_REG;
input                   WR_REG;
input    [1:0]   BWD;
input    [1:0]   BWD;
input    [8:3]  FSR;
input    [8:3]  FSR;
input    [7:0]   OPCODE;
input    [7:0]   OPCODE;
input   [31:0]   SRC1;
input   [31:0]   SRC1;
Line 1289... Line 1361...
 
 
output                  DONE;
output                  DONE;
output                  UP_DP;
output                  UP_DP;
output                  WREN_L;
output                  WREN_L;
output                  CLR_LSB;
output                  CLR_LSB;
output                  LD_OUT_L;
 
output                  DVZ_TRAP;
output                  DVZ_TRAP;
output   [2:0]   DP_CMP;
output   [2:0]   DP_CMP;
output  [31:0]   DP_OUT;
output  [31:0]   DP_OUT;
output  [31:0]   DP_Q;
output  [31:0]   DP_Q;
output   [4:0]   TT_DP;
output   [4:0]   TT_DP;
Line 1337... Line 1408...
        .DFLOAT(DFLOAT),
        .DFLOAT(DFLOAT),
        .DONE(DONE),
        .DONE(DONE),
        .UP_DP(UP_DP),
        .UP_DP(UP_DP),
        .CLR_LSB(CLR_LSB),
        .CLR_LSB(CLR_LSB),
        .WREN_L(WREN_L),
        .WREN_L(WREN_L),
        .LD_OUT_L(LD_OUT_L),
 
        .DVZ_TRAP(DVZ_TRAP),
        .DVZ_TRAP(DVZ_TRAP),
        .DOUT(DOUT),
        .DOUT(DOUT),
        .DP_CMP(DP_CMP),
        .DP_CMP(DP_CMP),
        .TT_DP(TT_DP),
        .TT_DP(TT_DP),
        .CY_IN(CY_IN),
        .CY_IN(CY_IN),
Line 1368... Line 1438...
 
 
        assign MRESULT = MDA * MDB;     // unsigned multiplier 53 * 53 bits = 106 bits
        assign MRESULT = MDA * MDB;     // unsigned multiplier 53 * 53 bits = 106 bits
 
 
        assign DP_OUT = CLR_LSB ? DP_Q : DOUT[63:32];
        assign DP_OUT = CLR_LSB ? DP_Q : DOUT[63:32];
 
 
        always@(posedge BCLK) if (LD_OUT_L || LD_LDQ || WREN_L) DP_Q <= LD_LDQ ? SRC2 : DOUT[31:0];
        always@(posedge BCLK) if (LD_OUT[1] || LD_OUT[0] || WREN_L) DP_Q <= LD_OUT[0] ? SRC2 : DOUT[31:0];
 
 
        always@(posedge BCLK) if (LOAD_LSD1) MDA[31:0] <= LSD_1;
        always@(posedge BCLK) if (LOAD_LSD1) MDA[31:0] <= LSD_1;
 
 
        always@(posedge BCLK) if (LOAD_LSD2) MDB[31:0] <= LSD_2;
        always@(posedge BCLK) if (LOAD_LSD2) MDB[31:0] <= LSD_2;
 
 

powered by: WebSVN 2.1.0

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