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;
|