📄 post_norm.v
字号:
///////////////////////////////////////////////////////////////////////// //////// Post Norm //////// Floating Point Post Normalisation Unit //////// //////// Author: Rudolf Usselmann //////// rudi@asics.ws //////// ///////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2000 Rudolf Usselmann //////// rudi@asics.ws //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer.//////// //////// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //////// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //////// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //////// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //////// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //////// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //////// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //////// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //////// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //////// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //////// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //////// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //////// POSSIBILITY OF SUCH DAMAGE. //////// /////////////////////////////////////////////////////////////////////////`timescale 1ns / 100psmodule post_norm( clk, fpu_op, opas, sign, rmode, fract_in, exp_in, exp_ovf, opa_dn, opb_dn, rem_00, div_opa_ldz, output_zero, out, ine, overflow, underflow, f2i_out_sign);input clk;input [2:0] fpu_op;input opas;input sign;input [1:0] rmode;input [47:0] fract_in;input [1:0] exp_ovf;input [7:0] exp_in;input opa_dn, opb_dn;input rem_00;input [4:0] div_opa_ldz;input output_zero;output [30:0] out;output ine;output overflow, underflow;output f2i_out_sign;//////////////////////////////////////////////////////////////////////////// Local Wires and registers//wire [22:0] fract_out;wire [7:0] exp_out;wire [30:0] out;wire exp_out1_co, overflow, underflow;wire [22:0] fract_out_final;reg [22:0] fract_out_rnd;wire [8:0] exp_next_mi;wire dn;wire exp_rnd_adj;wire [7:0] exp_out_final;reg [7:0] exp_out_rnd;wire op_dn = opa_dn | opb_dn;wire op_mul = fpu_op[2:0]==3'b010;wire op_div = fpu_op[2:0]==3'b011;wire op_i2f = fpu_op[2:0]==3'b100;wire op_f2i = fpu_op[2:0]==3'b101;reg [5:0] fi_ldz;wire g, r, s;wire round, round2, round2a, round2_fasu, round2_fmul;wire [7:0] exp_out_rnd0, exp_out_rnd1, exp_out_rnd2, exp_out_rnd2a;wire [22:0] fract_out_rnd0, fract_out_rnd1, fract_out_rnd2, fract_out_rnd2a;wire exp_rnd_adj0, exp_rnd_adj2a;wire r_sign;wire ovf0, ovf1;wire [23:0] fract_out_pl1;wire [7:0] exp_out_pl1, exp_out_mi1;wire exp_out_00, exp_out_fe, exp_out_ff, exp_in_00, exp_in_ff;wire exp_out_final_ff, fract_out_7fffff;wire [24:0] fract_trunc;wire [7:0] exp_out1;wire grs_sel;wire fract_out_00, fract_in_00;wire shft_co;wire [8:0] exp_in_pl1, exp_in_mi1;wire [47:0] fract_in_shftr;wire [47:0] fract_in_shftl;wire [7:0] exp_div;wire [7:0] shft2;wire [7:0] exp_out1_mi1;wire div_dn;wire div_nr;wire grs_sel_div;wire div_inf;wire [6:0] fi_ldz_2a;wire [7:0] fi_ldz_2;wire [7:0] div_shft1, div_shft2, div_shft3, div_shft4;wire div_shft1_co;wire [8:0] div_exp1;wire [7:0] div_exp2, div_exp3;wire left_right, lr_mul, lr_div;wire [7:0] shift_right, shftr_mul, shftr_div;wire [7:0] shift_left, shftl_mul, shftl_div;wire [7:0] fasu_shift;wire [7:0] exp_fix_div;wire [7:0] exp_fix_diva, exp_fix_divb;wire [5:0] fi_ldz_mi1;wire [5:0] fi_ldz_mi22;wire exp_zero;wire [6:0] ldz_all;wire [7:0] ldz_dif;wire [8:0] div_scht1a;wire [7:0] f2i_shft;wire [55:0] exp_f2i_1;wire f2i_zero, f2i_max;wire [7:0] f2i_emin;wire [7:0] conv_shft;wire [7:0] exp_i2f, exp_f2i, conv_exp;wire round2_f2i;//////////////////////////////////////////////////////////////////////////// Normalize and Round Logic//// ---------------------------------------------------------------------// Count Leading zeros in fractionalways @(fract_in) casex(fract_in) // synopsys full_case parallel_case 48'b1???????????????????????????????????????????????: fi_ldz = 1; 48'b01??????????????????????????????????????????????: fi_ldz = 2; 48'b001?????????????????????????????????????????????: fi_ldz = 3; 48'b0001????????????????????????????????????????????: fi_ldz = 4; 48'b00001???????????????????????????????????????????: fi_ldz = 5; 48'b000001??????????????????????????????????????????: fi_ldz = 6; 48'b0000001?????????????????????????????????????????: fi_ldz = 7; 48'b00000001????????????????????????????????????????: fi_ldz = 8; 48'b000000001???????????????????????????????????????: fi_ldz = 9; 48'b0000000001??????????????????????????????????????: fi_ldz = 10; 48'b00000000001?????????????????????????????????????: fi_ldz = 11; 48'b000000000001????????????????????????????????????: fi_ldz = 12; 48'b0000000000001???????????????????????????????????: fi_ldz = 13; 48'b00000000000001??????????????????????????????????: fi_ldz = 14; 48'b000000000000001?????????????????????????????????: fi_ldz = 15; 48'b0000000000000001????????????????????????????????: fi_ldz = 16; 48'b00000000000000001???????????????????????????????: fi_ldz = 17; 48'b000000000000000001??????????????????????????????: fi_ldz = 18; 48'b0000000000000000001?????????????????????????????: fi_ldz = 19; 48'b00000000000000000001????????????????????????????: fi_ldz = 20; 48'b000000000000000000001???????????????????????????: fi_ldz = 21; 48'b0000000000000000000001??????????????????????????: fi_ldz = 22; 48'b00000000000000000000001?????????????????????????: fi_ldz = 23; 48'b000000000000000000000001????????????????????????: fi_ldz = 24; 48'b0000000000000000000000001???????????????????????: fi_ldz = 25; 48'b00000000000000000000000001??????????????????????: fi_ldz = 26; 48'b000000000000000000000000001?????????????????????: fi_ldz = 27; 48'b0000000000000000000000000001????????????????????: fi_ldz = 28; 48'b00000000000000000000000000001???????????????????: fi_ldz = 29; 48'b000000000000000000000000000001??????????????????: fi_ldz = 30; 48'b0000000000000000000000000000001?????????????????: fi_ldz = 31; 48'b00000000000000000000000000000001????????????????: fi_ldz = 32; 48'b000000000000000000000000000000001???????????????: fi_ldz = 33; 48'b0000000000000000000000000000000001??????????????: fi_ldz = 34; 48'b00000000000000000000000000000000001?????????????: fi_ldz = 35; 48'b000000000000000000000000000000000001????????????: fi_ldz = 36; 48'b0000000000000000000000000000000000001???????????: fi_ldz = 37; 48'b00000000000000000000000000000000000001??????????: fi_ldz = 38; 48'b000000000000000000000000000000000000001?????????: fi_ldz = 39; 48'b0000000000000000000000000000000000000001????????: fi_ldz = 40; 48'b00000000000000000000000000000000000000001???????: fi_ldz = 41; 48'b000000000000000000000000000000000000000001??????: fi_ldz = 42; 48'b0000000000000000000000000000000000000000001?????: fi_ldz = 43; 48'b00000000000000000000000000000000000000000001????: fi_ldz = 44; 48'b000000000000000000000000000000000000000000001???: fi_ldz = 45; 48'b0000000000000000000000000000000000000000000001??: fi_ldz = 46; 48'b00000000000000000000000000000000000000000000001?: fi_ldz = 47; 48'b00000000000000000000000000000000000000000000000?: fi_ldz = 48; endcase// ---------------------------------------------------------------------// Normalizewire exp_in_80;wire rmode_00, rmode_01, rmode_10, rmode_11;// Misc common signalsassign exp_in_ff = &exp_in;assign exp_in_00 = !(|exp_in);assign exp_in_80 = exp_in[7] & !(|exp_in[6:0]);assign exp_out_ff = &exp_out;assign exp_out_00 = !(|exp_out);assign exp_out_fe = &exp_out[7:1] & !exp_out[0];assign exp_out_final_ff = &exp_out_final;assign fract_out_7fffff = &fract_out;assign fract_out_00 = !(|fract_out);assign fract_in_00 = !(|fract_in);assign rmode_00 = (rmode==2'b00);assign rmode_01 = (rmode==2'b01);assign rmode_10 = (rmode==2'b10);assign rmode_11 = (rmode==2'b11);// Fasu Output will be denormalized ...assign dn = !op_mul & !op_div & (exp_in_00 | (exp_next_mi[8] & !fract_in[47]) );// ---------------------------------------------------------------------// Fraction Normalizationparameter f2i_emax = 8'h9d;// Incremented fraction for roundingassign fract_out_pl1 = fract_out + 1;// Special Signals for f2iassign f2i_emin = rmode_00 ? 8'h7e : 8'h7f;assign f2i_zero = (!opas & (exp_in<f2i_emin)) | (opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & (fract_in_00 | !rmode_11));assign f2i_max = (!opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & !fract_in_00 & rmode_11);// Claculate various shifting optionsassign {shft_co,shftr_mul} = (!exp_ovf[1] & exp_in_00) ? {1'b0, exp_out} : exp_in_mi1 ;assign {div_shft1_co, div_shft1} = exp_in_00 ? {1'b0, div_opa_ldz} : div_scht1a;assign div_scht1a = exp_in-div_opa_ldz; // 9 bits - includes carry outassign div_shft2 = exp_in+2;assign div_shft3 = div_opa_ldz+exp_in;assign div_shft4 = div_opa_ldz-exp_in;assign div_dn = op_dn & div_shft1_co;assign div_nr = op_dn & exp_ovf[1] & !(|fract_in[46:23]) & (div_shft3>8'h16);assign f2i_shft = exp_in-8'h7d;// Select shifting directionassign left_right = op_div ? lr_div : op_mul ? lr_mul : 1;assign lr_div = (op_dn & !exp_ovf[1] & exp_ovf[0]) ? 1 : (op_dn & exp_ovf[1]) ? 0 : (op_dn & div_shft1_co) ? 0 : (op_dn & exp_out_00) ? 1 : (!op_dn & exp_out_00 & !exp_ovf[1]) ? 1 : exp_ovf[1] ? 0 : 1;assign lr_mul = (shft_co | (!exp_ovf[1] & exp_in_00) | (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00) )) ? 1 : ( exp_ovf[1] | exp_in_00 ) ? 0 : 1;// Select Left and Right shift valueassign fasu_shift = (dn | exp_out_00) ? (exp_in_00 ? 8'h2 : exp_in_pl1[7:0]) : {2'h0, fi_ldz};assign shift_right = op_div ? shftr_div : shftr_mul;assign conv_shft = op_f2i ? f2i_shft : {2'h0, fi_ldz};assign shift_left = op_div ? shftl_div : op_mul ? shftl_mul : (op_f2i | op_i2f) ? conv_shft : fasu_shift;assign shftl_mul = (shft_co | (!exp_ovf[1] & exp_in_00) | (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00))) ? exp_in_pl1[7:0] : {2'h0, fi_ldz};assign shftl_div = ( op_dn & exp_out_00 & !(!exp_ovf[1] & exp_ovf[0])) ? div_shft1[7:0] : (!op_dn & exp_out_00 & !exp_ovf[1]) ? exp_in[7:0] : {2'h0, fi_ldz};assign shftr_div = (op_dn & exp_ovf[1]) ? div_shft3 : (op_dn & div_shft1_co) ? div_shft4 : div_shft2;// Do the actual shiftingassign fract_in_shftr = (|shift_right[7:6]) ? 0 : fract_in>>shift_right[5:0];assign fract_in_shftl = (|shift_left[7:6] | (f2i_zero & op_f2i)) ? 0 : fract_in<<shift_left[5:0];// Chose final fraction outputassign {fract_out,fract_trunc} = left_right ? fract_in_shftl : fract_in_shftr;// ---------------------------------------------------------------------// Exponent Normalizationassign fi_ldz_mi1 = fi_ldz - 1;assign fi_ldz_mi22 = fi_ldz - 22;assign exp_out_pl1 = exp_out + 1;assign exp_out_mi1 = exp_out - 1;assign exp_in_pl1 = exp_in + 1; // 9 bits - includes carry outassign exp_in_mi1 = exp_in - 1; // 9 bits - includes carry outassign exp_out1_mi1 = exp_out1 - 1;assign exp_next_mi = exp_in_pl1 - fi_ldz_mi1; // 9 bits - includes carry outassign exp_fix_diva = exp_in - fi_ldz_mi22;assign exp_fix_divb = exp_in - fi_ldz_mi1;assign exp_zero = (exp_ovf[1] & !exp_ovf[0] & op_mul & (!exp_rnd_adj2a | !rmode[1])) | (op_mul & exp_out1_co);assign {exp_out1_co, exp_out1} = fract_in[47] ? exp_in_pl1 : exp_next_mi;assign f2i_out_sign = !opas ? ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 0 : opas) : ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 1 : opas);assign exp_i2f = fract_in_00 ? (opas ? 8'h9e : 0) : (8'h9e-fi_ldz);assign exp_f2i_1 = {{8{fract_in[47]}}, fract_in }<<f2i_shft;assign exp_f2i = f2i_zero ? 0 : f2i_max ? 8'hff : exp_f2i_1[55:48];assign conv_exp = op_f2i ? exp_f2i : exp_i2f;assign exp_out = op_div ? exp_div : (op_f2i | op_i2f) ? conv_exp : exp_zero ? 8'h0 : dn ? {6'h0, fract_in[47:46]} : exp_out1;assign ldz_all = div_opa_ldz + fi_ldz;assign ldz_dif = fi_ldz_2 - div_opa_ldz;assign fi_ldz_2a = 6'd23 - fi_ldz;assign fi_ldz_2 = {fi_ldz_2a[6], fi_ldz_2a[6:0]};assign div_exp1 = exp_in_mi1 + fi_ldz_2; // 9 bits - includes carry outassign div_exp2 = exp_in_pl1 - ldz_all;assign div_exp3 = exp_in + ldz_dif;assign exp_div =(opa_dn & opb_dn) ? div_exp3 : opb_dn ? div_exp1[7:0] : (opa_dn & !( (exp_in<div_opa_ldz) | (div_exp2>9'hfe) )) ? div_exp2 : (opa_dn | (exp_in_00 & !exp_ovf[1]) ) ? 0 : exp_out1_mi1;assign div_inf = opb_dn & !opa_dn & (div_exp1[7:0] < 8'h7f);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -