📄 fpu.v
字号:
assign fdiv_opa = !(|opa_r[30:23]) ? {(fracta_mul<<div_opa_ldz_d), 26'h0} : {fracta_mul, 26'h0};div_r2 u6(.clk(clk), .opa(fdiv_opa), .opb(fractb_mul), .quo(quo), .rem(remainder));assign remainder_00 = !(|remainder);always @(posedge clk) div_opa_ldz_r1 <= #1 div_opa_ldz_d;always @(posedge clk) div_opa_ldz_r2 <= #1 div_opa_ldz_r1;//////////////////////////////////////////////////////////////////////////// Normalize Result//wire ine_d;reg [47:0] fract_denorm;wire [47:0] fract_div;wire sign_d;reg sign;reg [30:0] opa_r1;reg [47:0] fract_i2f;reg opas_r1, opas_r2;wire f2i_out_sign;always @(posedge clk) // Exponent must be once cycle delayed case(fpu_op_r2) 0,1: exp_r <= #1 exp_fasu; 2,3: exp_r <= #1 exp_mul; 4: exp_r <= #1 0; 5: exp_r <= #1 opa_r1[30:23]; endcaseassign fract_div = (opb_dn ? quo[49:2] : {quo[26:0], 21'h0});always @(posedge clk) opa_r1 <= #1 opa_r[30:0];always @(posedge clk) fract_i2f <= #1 (fpu_op_r2==5) ? (sign_d ? 1-{24'h00, (|opa_r1[30:23]), opa_r1[22:0]}-1 : {24'h0, (|opa_r1[30:23]), opa_r1[22:0]}) : (sign_d ? 1 - {opa_r1, 17'h01} : {opa_r1, 17'h0});always @(fpu_op_r3 or fract_out_q or prod or fract_div or fract_i2f) case(fpu_op_r3) 0,1: fract_denorm = {fract_out_q, 20'h0}; 2: fract_denorm = prod; 3: fract_denorm = fract_div; 4,5: fract_denorm = fract_i2f; endcasealways @(posedge clk) opas_r1 <= #1 opa_r[31];always @(posedge clk) opas_r2 <= #1 opas_r1;assign sign_d = fpu_op_r2[1] ? sign_mul : sign_fasu;always @(posedge clk) sign <= #1 (rmode_r2==2'h3) ? !sign_d : sign_d;post_norm u4(.clk(clk), // System Clock .fpu_op(fpu_op_r3), // Floating Point Operation .opas(opas_r2), // OPA Sign .sign(sign), // Sign of the result .rmode(rmode_r3), // Rounding mode .fract_in(fract_denorm), // Fraction Input .exp_ovf(exp_ovf_r), // Exponent Overflow .exp_in(exp_r), // Exponent Input .opa_dn(opa_dn), // Operand A Denormalized .opb_dn(opb_dn), // Operand A Denormalized .rem_00(remainder_00), // Diveide Remainder is zero .div_opa_ldz(div_opa_ldz_r2), // Divide opa leading zeros count .output_zero(mul_00 | div_00), // Force output to Zero .out(out_d), // Normalized output (un-registered) .ine(ine_d), // Result Inexact output (un-registered) .overflow(overflow_d), // Overflow output (un-registered) .underflow(underflow_d), // Underflow output (un-registered) .f2i_out_sign(f2i_out_sign) // F2I Output Sign );//////////////////////////////////////////////////////////////////////////// FPU Outputs//reg fasu_op_r1, fasu_op_r2;wire [30:0] out_fixed;wire output_zero_fasu;wire output_zero_fdiv;wire output_zero_fmul;reg inf_mul2;wire overflow_fasu;wire overflow_fmul;wire overflow_fdiv;wire inf_fmul;wire sign_mul_final;wire out_d_00;wire sign_div_final;wire ine_mul, ine_mula, ine_div, ine_fasu;wire underflow_fasu, underflow_fmul, underflow_fdiv;wire underflow_fmul1;reg [2:0] underflow_fmul_r;reg opa_nan_r;always @(posedge clk) fasu_op_r1 <= #1 fasu_op;always @(posedge clk) fasu_op_r2 <= #1 fasu_op_r1;always @(posedge clk) inf_mul2 <= #1 exp_mul == 8'hff;// Force pre-set values for non numerical outputassign mul_inf = (fpu_op_r3==3'b010) & (inf_mul_r | inf_mul2) & (rmode_r3==2'h0);assign div_inf = (fpu_op_r3==3'b011) & (opb_00 | opa_inf);assign mul_00 = (fpu_op_r3==3'b010) & (opa_00 | opb_00);assign div_00 = (fpu_op_r3==3'b011) & (opa_00 | opb_inf);assign out_fixed = ( (qnan_d | snan_d) | (ind_d & !fasu_op_r2) | ((fpu_op_r3==3'b011) & opb_00 & opa_00) | (((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010) ) ? QNAN : INF;always @(posedge clk) out[30:0] <= #1 (mul_inf | div_inf | (inf_d & (fpu_op_r3!=3'b011) & (fpu_op_r3!=3'b101)) | snan_d | qnan_d) & fpu_op_r3!=3'b100 ? out_fixed : out_d;assign out_d_00 = !(|out_d);assign sign_mul_final = (sign_exe_r & ((opa_00 & opb_inf) | (opb_00 & opa_inf))) ? !sign_mul_r : sign_mul_r;assign sign_div_final = (sign_exe_r & (opa_inf & opb_inf)) ? !sign_mul_r : sign_mul_r | (opa_00 & opb_00);always @(posedge clk) out[31] <= #1 ((fpu_op_r3==3'b101) & out_d_00) ? (f2i_out_sign & !(qnan_d | snan_d) ) : ((fpu_op_r3==3'b010) & !(snan_d | qnan_d)) ? sign_mul_final : ((fpu_op_r3==3'b011) & !(snan_d | qnan_d)) ? sign_div_final : (snan_d | qnan_d | ind_d) ? nan_sign_d : output_zero_fasu ? result_zero_sign_d : sign_fasu_r;// Exception Outputsassign ine_mula = ((inf_mul_r | inf_mul2 | opa_inf | opb_inf) & (rmode_r3==2'h1) & !((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3[1]);assign ine_mul = (ine_mula | ine_d | inf_fmul | out_d_00 | overflow_d | underflow_d) & !opa_00 & !opb_00 & !(snan_d | qnan_d | inf_d);assign ine_div = (ine_d | overflow_d | underflow_d) & !(opb_00 | snan_d | qnan_d | inf_d);assign ine_fasu = (ine_d | overflow_d | underflow_d) & !(snan_d | qnan_d | inf_d);always @(posedge clk) ine <= #1 fpu_op_r3[2] ? ine_d : !fpu_op_r3[1] ? ine_fasu : fpu_op_r3[0] ? ine_div : ine_mul;assign overflow_fasu = overflow_d & !(snan_d | qnan_d | inf_d);assign overflow_fmul = !inf_d & (inf_mul_r | inf_mul2 | overflow_d) & !(snan_d | qnan_d);assign overflow_fdiv = (overflow_d & !(opb_00 | inf_d | snan_d | qnan_d));always @(posedge clk) overflow <= #1 fpu_op_r3[2] ? 0 : !fpu_op_r3[1] ? overflow_fasu : fpu_op_r3[0] ? overflow_fdiv : overflow_fmul;always @(posedge clk) underflow_fmul_r <= #1 underflow_fmul_d;assign underflow_fmul1 = underflow_fmul_r[0] | (underflow_fmul_r[1] & underflow_d ) | ((opa_dn | opb_dn) & out_d_00 & (prod!=0) & sign) | (underflow_fmul_r[2] & ((out_d[30:23]==0) | (out_d[22:0]==0)));assign underflow_fasu = underflow_d & !(inf_d | snan_d | qnan_d);assign underflow_fmul = underflow_fmul1 & !(snan_d | qnan_d | inf_mul_r);assign underflow_fdiv = underflow_fasu & !opb_00;always @(posedge clk) underflow <= #1 fpu_op_r3[2] ? 0 : !fpu_op_r3[1] ? underflow_fasu : fpu_op_r3[0] ? underflow_fdiv : underflow_fmul;always @(posedge clk) snan <= #1 snan_d;// synopsys translate_offwire mul_uf_del;wire uf2_del, ufb2_del, ufc2_del, underflow_d_del;wire co_del;wire [30:0] out_d_del;wire ov_fasu_del, ov_fmul_del;wire [2:0] fop;wire [4:0] ldza_del;wire [49:0] quo_del;delay1 #0 ud000(clk, underflow_fmul1, mul_uf_del);delay1 #0 ud001(clk, underflow_fmul_r[0], uf2_del);delay1 #0 ud002(clk, underflow_fmul_r[1], ufb2_del);delay1 #0 ud003(clk, underflow_d, underflow_d_del);delay1 #0 ud004(clk, test.u0.u4.exp_out1_co, co_del);delay1 #0 ud005(clk, underflow_fmul_r[2], ufc2_del);delay1 #30 ud006(clk, out_d, out_d_del);delay1 #0 ud007(clk, overflow_fasu, ov_fasu_del);delay1 #0 ud008(clk, overflow_fmul, ov_fmul_del);delay1 #2 ud009(clk, fpu_op_r3, fop);delay3 #4 ud010(clk, div_opa_ldz_d, ldza_del);delay1 #49 ud012(clk, quo, quo_del);always @(test.error_event) begin #0.2 $display("muf: %b uf0: %b uf1: %b uf2: %b, tx0: %b, co: %b, out_d: %h (%h %h), ov_fasu: %b, ov_fmul: %b, fop: %h", mul_uf_del, uf2_del, ufb2_del, ufc2_del, underflow_d_del, co_del, out_d_del, out_d_del[30:23], out_d_del[22:0], ov_fasu_del, ov_fmul_del, fop ); $display("ldza: %h, quo: %b", ldza_del, quo_del); end// synopsys translate_on// Status Outputsalways @(posedge clk) qnan <= #1 fpu_op_r3[2] ? 0 : ( snan_d | qnan_d | (ind_d & !fasu_op_r2) | (opa_00 & opb_00 & fpu_op_r3==3'b011) | (((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010) );assign inf_fmul = (((inf_mul_r | inf_mul2) & (rmode_r3==2'h0)) | opa_inf | opb_inf) & !((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010;always @(posedge clk) inf <= #1 fpu_op_r3[2] ? 0 : (!(qnan_d | snan_d) & ( ((&out_d[30:23]) & !(|out_d[22:0]) & !(opb_00 & fpu_op_r3==3'b011)) | (inf_d & !(ind_d & !fasu_op_r2) & !fpu_op_r3[1]) | inf_fmul | (!opa_00 & opb_00 & fpu_op_r3==3'b011) | (fpu_op_r3==3'b011 & opa_inf & !opb_inf) ) );assign output_zero_fasu = out_d_00 & !(inf_d | snan_d | qnan_d);assign output_zero_fdiv = (div_00 | (out_d_00 & !opb_00)) & !(opa_inf & opb_inf) & !(opa_00 & opb_00) & !(qnan_d | snan_d);assign output_zero_fmul = (out_d_00 | opa_00 | opb_00) & !(inf_mul_r | inf_mul2 | opa_inf | opb_inf | snan_d | qnan_d) & !(opa_inf & opb_00) & !(opb_inf & opa_00);always @(posedge clk) zero <= #1 fpu_op_r3==3'b101 ? out_d_00 & !(snan_d | qnan_d): fpu_op_r3==3'b011 ? output_zero_fdiv : fpu_op_r3==3'b010 ? output_zero_fmul : output_zero_fasu ;always @(posedge clk) opa_nan_r <= #1 !opa_nan & fpu_op_r2==3'b011;always @(posedge clk) div_by_zero <= #1 opa_nan_r & !opa_00 & !opa_inf & opb_00;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -