mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	mod 2 of fpdivsqrt update
This commit is contained in:
		
							parent
							
								
									8382a17969
								
							
						
					
					
						commit
						46001fef27
					
				
							
								
								
									
										151
									
								
								wally-pipelined/src/fpu/fpdiv.sv
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										151
									
								
								wally-pipelined/src/fpu/fpdiv.sv
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,151 @@ | ||||
| //
 | ||||
| // File name : fpdiv
 | ||||
| // Title     : Floating-Point Divider/Square-Root
 | ||||
| // project   : FPU
 | ||||
| // Library   : fpdiv
 | ||||
| // Author(s) : James E. Stine, Jr.
 | ||||
| // Purpose   : definition of main unit to floating-point div/sqrt
 | ||||
| // notes :   
 | ||||
| //
 | ||||
| // Copyright Oklahoma State University
 | ||||
| //
 | ||||
| // Basic Operations
 | ||||
| //
 | ||||
| // Step 1: Load operands, set flags, and convert SP to DP
 | ||||
| // Step 2: Check for special inputs ( +/- Infinity,  NaN)
 | ||||
| // Step 3: Exponent Logic
 | ||||
| // Step 4: Divide/Sqrt using Goldschmidt
 | ||||
| // Step 5: Normalize the result.//
 | ||||
| //   Shift left until normalized.  Normalized when the value to the 
 | ||||
| //   left of the binrary point is 1.
 | ||||
| // Step 6: Round the result.// 
 | ||||
| // Step 7: Put quotient/remainder onto output.
 | ||||
| //
 | ||||
| 
 | ||||
| `timescale 1ps/1ps | ||||
| module fpdiv (done, AS_Result, Flags, Denorm, op1, op2, rm, op_type, P, OvEn, UnEn, | ||||
| 	      start, reset, clk); | ||||
| 
 | ||||
|    input [63:0] op1;		// 1st input operand (A)
 | ||||
|    input [63:0] op2;		// 2nd input operand (B)
 | ||||
|    input [1:0] 	rm;		// Rounding mode - specify values 
 | ||||
|    input 	op_type;	// Function opcode
 | ||||
|    input 	P;   		// Result Precision (0 for double, 1 for single)
 | ||||
|    input 	OvEn;		// Overflow trap enabled
 | ||||
|    input 	UnEn;   	// Underflow trap enabled
 | ||||
|    input 	start; | ||||
|    input 	reset; | ||||
|    input 	clk;    | ||||
| 
 | ||||
|    output [63:0] AS_Result;	// Result of operation
 | ||||
|    output [4:0]  Flags;   	// IEEE exception flags 
 | ||||
|    output 	 Denorm;   	// Denorm on input or output
 | ||||
|    output 	 done; | ||||
| 
 | ||||
|    supply1 	  vdd; | ||||
|    supply0 	  vss;    | ||||
| 
 | ||||
|    wire [63:0] 	 Float1;  | ||||
|    wire [63:0] 	 Float2; | ||||
|    wire [63:0] 	 IntValue; | ||||
|     | ||||
|    wire [12:0] 	 exp1, exp2, expF; | ||||
|    wire [12:0] 	 exp_diff, bias; | ||||
|    wire [13:0] 	 exp_sqrt; | ||||
|    wire [12:0] 	 exp_s; | ||||
|    wire [12:0] 	 exp_c; | ||||
|     | ||||
|    wire [10:0] 	 exponent, exp_pre; | ||||
|    wire [63:0] 	 Result;    | ||||
|    wire [52:0] 	 mantissaA; | ||||
|    wire [52:0] 	 mantissaB;  | ||||
|    wire [63:0] 	 sum, sum_tc, sum_corr, sum_norm; | ||||
|     | ||||
|    wire [5:0] 	 align_shift; | ||||
|    wire [5:0] 	 norm_shift; | ||||
|    wire [2:0] 	 sel_inv; | ||||
|    wire		 op1_Norm, op2_Norm; | ||||
|    wire		 opA_Norm, opB_Norm; | ||||
|    wire		 Invalid; | ||||
|    wire 	 DenormIn, DenormIO; | ||||
|    wire [4:0] 	 FlagsIn;   	 | ||||
|    wire 	 exp_gt63; | ||||
|    wire 	 Sticky_out; | ||||
|    wire 	 signResult, sign_corr; | ||||
|    wire          corr_sign; | ||||
|    wire 	 zeroB;          | ||||
|    wire 	 convert; | ||||
|    wire          swap; | ||||
|    wire          sub; | ||||
|     | ||||
|    wire [63:0] 	 q1, qm1, qp1, q0, qm0, qp0; | ||||
|    wire [63:0] 	 rega_out, regb_out, regc_out, regd_out; | ||||
|    wire [127:0]  regr_out; | ||||
|    wire [2:0] 	 sel_muxa, sel_muxb; | ||||
|    wire 	 sel_muxr;    | ||||
|    wire 	 load_rega, load_regb, load_regc, load_regd, load_regr; | ||||
| 
 | ||||
|    wire 	 donev, sel_muxrv, sel_muxsv; | ||||
|    wire [1:0] 	 sel_muxav, sel_muxbv;    | ||||
|    wire 	 load_regav, load_regbv, load_regcv; | ||||
|    wire 	 load_regrv, load_regsv; | ||||
|     | ||||
|    // Convert the input operands to their appropriate forms based on 
 | ||||
|    // the orignal operands, the op_type , and their precision P. 
 | ||||
|    // Single precision inputs are converted to double precision 
 | ||||
|    // and the sign of the first operand is set appropratiately based on
 | ||||
|    // if the operation is absolute value or negation.   
 | ||||
|    convert_inputs_div conv1 (Float1, Float2, op1, op2, op_type, P); | ||||
| 
 | ||||
|    // Test for exceptions and return the "Invalid Operation" and
 | ||||
|    // "Denormalized" Input Flags. The "sel_inv" is used in
 | ||||
|    // the third pipeline stage to select the result. Also, op1_Norm
 | ||||
|    // and op2_Norm are one if op1 and op2 are not zero or denormalized.
 | ||||
|    // sub is one if the effective operation is subtaction.   
 | ||||
|    exception_div exc1 (sel_inv, Invalid, DenormIn, op1_Norm, op2_Norm,  | ||||
| 		       Float1, Float2, op_type); | ||||
| 
 | ||||
|    // Determine Sign/Mantissa
 | ||||
|    assign signResult = ((Float1[63]^Float2[63])&~op_type) | Float1[63]&op_type; | ||||
|    assign mantissaA = {vdd, Float1[51:0]}; | ||||
|    assign mantissaB = {vdd, Float2[51:0]}; | ||||
|    // Perform Exponent Subtraction - expA - expB + Bias   
 | ||||
|    assign exp1 = {2'b0, Float1[62:52]}; | ||||
|    assign exp2 = {2'b0, Float2[62:52]}; | ||||
|    // bias : DP = 2^{11-1}-1 = 1023
 | ||||
|    assign bias = {3'h0, 10'h3FF}; | ||||
|    // Divide exponent
 | ||||
|    csa #(13) csa1 (exp1, ~exp2, bias, exp_s, exp_c); | ||||
|    adder #(14) explogic1 ({vss, exp_s}, {vss, exp_c}, 1'b1, {open, exp_diff}, exp_cout1); | ||||
|     | ||||
|    // Sqrt exponent (check if exponent is odd)
 | ||||
|    assign exp_odd = Float1[52] ? vss : vdd; | ||||
|    adder #(14) explogic2 ({vss, exp1}, {4'h0, 10'h3ff}, exp_odd, exp_sqrt, exp_cout2); | ||||
|    // Choose correct exponent
 | ||||
|    assign expF = op_type ? exp_sqrt[13:1] : exp_diff;    | ||||
| 
 | ||||
|    // Main Goldschmidt/Division Routine   
 | ||||
|    divconv goldy (q1, qm1, qp1, q0, qm0, qp0, rega_out, regb_out, regc_out, regd_out, | ||||
| 		  regr_out, mantissaB, mantissaA, sel_muxa, sel_muxb, sel_muxr,  | ||||
| 		  reset, clk,  load_rega, load_regb, load_regc, load_regd, | ||||
| 		  load_regr, load_regs, P, op_type, exp_odd); | ||||
| 
 | ||||
|    // FSM : control divider   
 | ||||
|    fsm_div control (done, load_rega, load_regb, load_regc, load_regd,  | ||||
| 		    load_regr, load_regs, sel_muxa, sel_muxb, sel_muxr,  | ||||
| 		    clk, reset, start, error, op_type); | ||||
|     | ||||
|    // Round the mantissa to a 52-bit value, with the leading one
 | ||||
|    // removed. The rounding units also handles special cases and 
 | ||||
|    // set the exception flags.   
 | ||||
|    rounder_div round1 (Result, DenormIO, FlagsIn,  | ||||
| 		   rm, P, OvEn, UnEn, expF,  | ||||
|    		   sel_inv, Invalid, DenormIn, signResult,  | ||||
| 		   q1, qm1, qp1, q0, qm0, qp0, regr_out); | ||||
| 
 | ||||
|    // Store the final result and the exception flags in registers.
 | ||||
|    flopenr #(64) rega (clk, reset, done, Result, AS_Result); | ||||
|    flopenr #(1) regb (clk, reset, done, DenormIO, Denorm);    | ||||
|    flopenr #(5) regc (clk, reset, done, FlagsIn, Flags);    | ||||
|     | ||||
| endmodule // fpadd
 | ||||
| @ -109,16 +109,8 @@ module fpu ( | ||||
|       logic [4:0] 	FPUFlagsW; | ||||
|        | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|       //DECODE STAGE
 | ||||
|        | ||||
|        | ||||
|       // top-level controller for FPU
 | ||||
|       fctrl fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]),  | ||||
|                   .FRM_REGW, .IllegalFPUInstrD, .FRegWriteD, .FDivStartD, .FResultSelD, .FOpCtrlD, .FResSelD,  | ||||
| @ -130,14 +122,6 @@ module fpu ( | ||||
|             FPUResultW, | ||||
|             FRD1D, FRD2D, FRD3D);	 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|       //*****************
 | ||||
|       // D/E pipe registers
 | ||||
|       //*****************
 | ||||
| @ -152,18 +136,6 @@ module fpu ( | ||||
|                            {FRegWriteE, FResultSelE, FResSelE, FIntResSelE, FrmE, FmtE, RdE,          FOpCtrlE, FWriteIntE}); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|       //EXECUTION STAGE
 | ||||
|        | ||||
|       // Hazard unit for FPU
 | ||||
| @ -198,12 +170,10 @@ module fpu ( | ||||
|                   .en(~HoldInputs), .clear(FDivSqrtDoneE), | ||||
|                   .reset(reset),  .clk(clk)); | ||||
| 
 | ||||
|       fdivsqrt fdivsqrt (.DivOpType(FOpCtrlE[0]), .clk(fpdivClk), .FmtE(~FmtE), .DivInput1E, .DivInput2E,  | ||||
|       fpdiv fdivsqrt (.DivOpType(FOpCtrlE[0]), .clk(fpdivClk), .FmtE(~FmtE), .DivInput1E, .DivInput2E,  | ||||
|                         .FrmE, .DivOvEn(1'b1), .DivUnEn(1'b1), .FDivStartE, .FDivResultM, .FDivSqrtFlgM,  | ||||
|                         .FDivSqrtDoneE, .FDivBusyE, .HoldInputs, .reset); | ||||
|        | ||||
| 
 | ||||
| 
 | ||||
|       // first of two-stage instance of floating-point add/cvt unit
 | ||||
|       faddcvt faddcvt (.clk, .reset, .FlushM, .StallM, .FrmM, .FOpCtrlM, .FmtE, .FmtM, | ||||
|                         .SrcXE, .SrcYE, .FOpCtrlE, .FAddResM, .FAddFlgM); | ||||
| @ -224,15 +194,6 @@ module fpu ( | ||||
|       // mux2  #(`XLEN)  FWriteDataMux({{`XLEN-32{1'b0}}, SrcYE[63:32]}, SrcYE[63:64-`XLEN], FmtE, FWriteDataE);
 | ||||
|       assign FWriteDataE = SrcYE[`XLEN-1:0]; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|       //*****************
 | ||||
|       // E/M pipe registers
 | ||||
|       //*****************
 | ||||
| @ -256,35 +217,17 @@ module fpu ( | ||||
| 
 | ||||
|       flopenrc #(64) EMRegClass(clk, reset, FlushM, ~StallM, ClassResE, ClassResM); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|       //BEGIN MEMORY STAGE
 | ||||
|        | ||||
|       mux4  #(64)  FResMux(AlignedSrcAM, SgnResM, CmpResM, CvtResM, FResSelM, FResM); | ||||
|       mux4  #(5)  FFlgMux(5'b0, {4'b0, SgnNVM}, {4'b0, CmpNVM}, CvtFlgM, FResSelM, FFlgM); | ||||
| 
 | ||||
|       // mux2  #(`XLEN)  SrcXAlignedMux({{`XLEN-32{1'b0}}, SrcXM[63:32]}, SrcXM[63:64-`XLEN], FmtM, SrcXMAligned);
 | ||||
|       mux4  #(`XLEN)  IntResMux(CmpResM[`XLEN-1:0], SrcXM[`XLEN-1:0], ClassResM[`XLEN-1:0], CvtResM[`XLEN-1:0], FIntResSelM, FIntResM); | ||||
|        | ||||
|        | ||||
|       // Align SrcA to MSB when single precicion
 | ||||
|       mux2  #(64)  SrcAMux({{32{1'b1}}, SrcAM[31:0]}, {{64-`XLEN{1'b1}}, SrcAM}, FmtM, AlignedSrcAM); | ||||
|           | ||||
|           | ||||
|       mux5  #(5)  FPUFlgMux(5'b0, FMAFlgM, FAddFlgM, FDivSqrtFlgM, FFlgM, FResultSelW, SetFflagsM); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|              | ||||
|       //*****************
 | ||||
|       // M/W pipe registers
 | ||||
|       //*****************
 | ||||
| @ -302,16 +245,10 @@ module fpu ( | ||||
|                            {FRegWriteM, FResultSelM, RdM, FmtM, FWriteIntM}, | ||||
|                            {FRegWriteW, FResultSelW, RdW, FmtW, FWriteIntW}); | ||||
|        | ||||
|        | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|    //#########################################
 | ||||
|    // BEGIN WRITEBACK STAGE
 | ||||
|    //#########################################
 | ||||
| 
 | ||||
| 
 | ||||
|       mux2  #(64)  ReadResMux({{32{1'b1}}, ReadDataW[31:0]}, {{64-`XLEN{1'b1}}, ReadDataW}, FmtW, ReadResW); | ||||
|       mux5  #(64)  FPUResultMux(ReadResW, FMAResW, FAddResW, FDivResultW, FResW, FResultSelW, FPUResultW); | ||||
|        | ||||
| @ -330,4 +267,3 @@ module fpu ( | ||||
|   endgenerate  | ||||
|    | ||||
| endmodule // fpu
 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user