/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// or1200_fpu_post_norm_intfloat_conv ////
|
//// or1200_fpu_post_norm_intfloat_conv ////
|
//// Floating Point Post Normalisation Unit ////
|
//// Floating Point Post Normalisation Unit ////
|
//// ////
|
//// ////
|
//// Author: Rudolf Usselmann ////
|
//// Author: Rudolf Usselmann ////
|
//// rudi@asics.ws ////
|
//// rudi@asics.ws ////
|
//// Modified by Julius Baxter, July, 2010 ////
|
//// Modified by Julius Baxter, July, 2010 ////
|
//// julius.baxter@orsoc.se ////
|
//// julius.baxter@orsoc.se ////
|
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2000 Rudolf Usselmann ////
|
//// Copyright (C) 2000 Rudolf Usselmann ////
|
//// rudi@asics.ws ////
|
//// rudi@asics.ws ////
|
//// ////
|
//// ////
|
//// 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.////
|
//// ////
|
//// ////
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
`timescale 1ns / 100ps
|
`timescale 1ns / 100ps
|
|
|
module or1200_fpu_post_norm_intfloat_conv
|
module or1200_fpu_post_norm_intfloat_conv
|
(
|
(
|
clk, fpu_op, opas, sign, rmode, fract_in,
|
clk, fpu_op, opas, sign, rmode, fract_in,
|
exp_in, opa_dn, opa_nan, opa_inf, opb_dn, out,
|
exp_in, opa_dn, opa_nan, opa_inf, opb_dn, out,
|
ine, inv, overflow, underflow, f2i_out_sign
|
ine, inv, overflow, underflow, f2i_out_sign
|
);
|
);
|
input clk;
|
input clk;
|
input [2:0] fpu_op;
|
input [2:0] fpu_op;
|
input opas;
|
input opas;
|
input sign;
|
input sign;
|
input [1:0] rmode;
|
input [1:0] rmode;
|
input [47:0] fract_in;
|
input [47:0] fract_in;
|
input [7:0] exp_in;
|
input [7:0] exp_in;
|
input opa_dn, opb_dn;
|
input opa_dn, opb_dn;
|
input opa_nan, opa_inf;
|
input opa_nan, opa_inf;
|
|
|
output [30:0] out;
|
output [30:0] out;
|
output ine, inv;
|
output ine, inv;
|
output overflow, underflow;
|
output overflow, underflow;
|
output f2i_out_sign;
|
output f2i_out_sign;
|
|
|
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Local Wires and registers
|
// Local Wires and registers
|
//
|
//
|
|
|
/*wire*/ reg [22:0] fract_out;
|
/*wire*/ reg [22:0] fract_out;
|
/*wire*/reg [7:0] exp_out;
|
/*wire*/reg [7:0] exp_out;
|
wire [30:0] out;
|
wire [30:0] out;
|
wire exp_out1_co, overflow, underflow;
|
wire exp_out1_co, overflow, underflow;
|
wire [22:0] fract_out_final;
|
wire [22:0] fract_out_final;
|
reg [22:0] fract_out_rnd;
|
reg [22:0] fract_out_rnd;
|
wire [8:0] exp_next_mi;
|
wire [8:0] exp_next_mi;
|
wire dn;
|
wire dn;
|
wire exp_rnd_adj;
|
wire exp_rnd_adj;
|
wire [7:0] exp_out_final;
|
wire [7:0] exp_out_final;
|
reg [7:0] exp_out_rnd;
|
reg [7:0] exp_out_rnd;
|
wire op_dn = opa_dn | opb_dn;
|
wire op_dn = opa_dn | opb_dn;
|
wire op_mul = fpu_op[2:0]==3'b010;
|
wire op_mul = fpu_op[2:0]==3'b010;
|
wire op_div = fpu_op[2:0]==3'b011;
|
wire op_div = fpu_op[2:0]==3'b011;
|
wire op_i2f = fpu_op[2:0]==3'b100;
|
wire op_i2f = fpu_op[2:0]==3'b100;
|
wire op_f2i = fpu_op[2:0]==3'b101;
|
wire op_f2i = fpu_op[2:0]==3'b101;
|
reg [5:0] fi_ldz;
|
reg [5:0] fi_ldz;
|
|
|
wire g, r, s;
|
wire g, r, s;
|
wire round, round2, round2a, round2_fasu, round2_fmul;
|
wire round, round2, round2a, round2_fasu, round2_fmul;
|
wire [7:0] exp_out_rnd0, exp_out_rnd1, exp_out_rnd2, exp_out_rnd2a;
|
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,
|
wire [22:0] fract_out_rnd0, fract_out_rnd1, fract_out_rnd2,
|
fract_out_rnd2a;
|
fract_out_rnd2a;
|
wire exp_rnd_adj0, exp_rnd_adj2a;
|
wire exp_rnd_adj0, exp_rnd_adj2a;
|
wire r_sign;
|
wire r_sign;
|
wire ovf0, ovf1;
|
wire ovf0, ovf1;
|
wire [23:0] fract_out_pl1;
|
wire [23:0] fract_out_pl1;
|
wire [7:0] exp_out_pl1, exp_out_mi1;
|
wire [7:0] exp_out_pl1, exp_out_mi1;
|
wire exp_out_00, exp_out_fe, exp_out_ff, exp_in_00,
|
wire exp_out_00, exp_out_fe, exp_out_ff, exp_in_00,
|
exp_in_ff;
|
exp_in_ff;
|
wire exp_out_final_ff, fract_out_7fffff;
|
wire exp_out_final_ff, fract_out_7fffff;
|
/*wire*/reg [24:0] fract_trunc;
|
/*wire*/reg [24:0] fract_trunc;
|
wire [7:0] exp_out1;
|
wire [7:0] exp_out1;
|
wire grs_sel;
|
wire grs_sel;
|
wire fract_out_00;
|
wire fract_out_00;
|
reg fract_in_00;
|
reg fract_in_00;
|
wire shft_co;
|
wire shft_co;
|
wire [8:0] exp_in_pl1, exp_in_mi1;
|
wire [8:0] exp_in_pl1, exp_in_mi1;
|
wire [47:0] fract_in_shftr;
|
wire [47:0] fract_in_shftr;
|
wire [47:0] fract_in_shftl;
|
wire [47:0] fract_in_shftl;
|
|
|
wire [7:0] shft2;
|
wire [7:0] shft2;
|
wire [7:0] exp_out1_mi1;
|
wire [7:0] exp_out1_mi1;
|
|
|
wire [6:0] fi_ldz_2a;
|
wire [6:0] fi_ldz_2a;
|
wire [7:0] fi_ldz_2;
|
wire [7:0] fi_ldz_2;
|
|
|
wire left_right;
|
wire left_right;
|
wire [7:0] shift_right;
|
wire [7:0] shift_right;
|
wire [7:0] shift_left;
|
wire [7:0] shift_left;
|
wire [7:0] fasu_shift;
|
wire [7:0] fasu_shift;
|
|
|
wire [5:0] fi_ldz_mi1;
|
wire [5:0] fi_ldz_mi1;
|
wire [5:0] fi_ldz_mi22;
|
wire [5:0] fi_ldz_mi22;
|
wire [6:0] ldz_all;
|
wire [6:0] ldz_all;
|
|
|
wire [7:0] f2i_shft;
|
wire [7:0] f2i_shft;
|
wire [55:0] exp_f2i_1;
|
wire [55:0] exp_f2i_1;
|
wire f2i_zero, f2i_max;
|
wire f2i_zero, f2i_max;
|
wire [7:0] f2i_emin;
|
wire [7:0] f2i_emin;
|
wire f2i_exp_gt_max ,f2i_exp_lt_min;
|
wire f2i_exp_gt_max ,f2i_exp_lt_min;
|
wire [7:0] conv_shft;
|
wire [7:0] conv_shft;
|
wire [7:0] exp_i2f, exp_f2i, conv_exp;
|
wire [7:0] exp_i2f, exp_f2i, conv_exp;
|
wire round2_f2i;
|
wire round2_f2i;
|
|
|
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Normalize and Round Logic
|
// Normalize and Round Logic
|
//
|
//
|
|
|
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
// Count Leading zeros in fraction
|
// Count Leading zeros in fraction
|
|
|
always @(/*fract_in*/ posedge clk)
|
always @(/*fract_in*/ posedge clk)
|
casex(fract_in) // synopsys full_case parallel_case
|
casez(fract_in) // synopsys full_case parallel_case
|
48'b1???????????????????????????????????????????????: fi_ldz <= 1;
|
48'b1???????????????????????????????????????????????: fi_ldz <= 1;
|
48'b01??????????????????????????????????????????????: fi_ldz <= 2;
|
48'b01??????????????????????????????????????????????: fi_ldz <= 2;
|
48'b001?????????????????????????????????????????????: fi_ldz <= 3;
|
48'b001?????????????????????????????????????????????: fi_ldz <= 3;
|
48'b0001????????????????????????????????????????????: fi_ldz <= 4;
|
48'b0001????????????????????????????????????????????: fi_ldz <= 4;
|
48'b00001???????????????????????????????????????????: fi_ldz <= 5;
|
48'b00001???????????????????????????????????????????: fi_ldz <= 5;
|
48'b000001??????????????????????????????????????????: fi_ldz <= 6;
|
48'b000001??????????????????????????????????????????: fi_ldz <= 6;
|
48'b0000001?????????????????????????????????????????: fi_ldz <= 7;
|
48'b0000001?????????????????????????????????????????: fi_ldz <= 7;
|
48'b00000001????????????????????????????????????????: fi_ldz <= 8;
|
48'b00000001????????????????????????????????????????: fi_ldz <= 8;
|
48'b000000001???????????????????????????????????????: fi_ldz <= 9;
|
48'b000000001???????????????????????????????????????: fi_ldz <= 9;
|
48'b0000000001??????????????????????????????????????: fi_ldz <= 10;
|
48'b0000000001??????????????????????????????????????: fi_ldz <= 10;
|
48'b00000000001?????????????????????????????????????: fi_ldz <= 11;
|
48'b00000000001?????????????????????????????????????: fi_ldz <= 11;
|
48'b000000000001????????????????????????????????????: fi_ldz <= 12;
|
48'b000000000001????????????????????????????????????: fi_ldz <= 12;
|
48'b0000000000001???????????????????????????????????: fi_ldz <= 13;
|
48'b0000000000001???????????????????????????????????: fi_ldz <= 13;
|
48'b00000000000001??????????????????????????????????: fi_ldz <= 14;
|
48'b00000000000001??????????????????????????????????: fi_ldz <= 14;
|
48'b000000000000001?????????????????????????????????: fi_ldz <= 15;
|
48'b000000000000001?????????????????????????????????: fi_ldz <= 15;
|
48'b0000000000000001????????????????????????????????: fi_ldz <= 16;
|
48'b0000000000000001????????????????????????????????: fi_ldz <= 16;
|
48'b00000000000000001???????????????????????????????: fi_ldz <= 17;
|
48'b00000000000000001???????????????????????????????: fi_ldz <= 17;
|
48'b000000000000000001??????????????????????????????: fi_ldz <= 18;
|
48'b000000000000000001??????????????????????????????: fi_ldz <= 18;
|
48'b0000000000000000001?????????????????????????????: fi_ldz <= 19;
|
48'b0000000000000000001?????????????????????????????: fi_ldz <= 19;
|
48'b00000000000000000001????????????????????????????: fi_ldz <= 20;
|
48'b00000000000000000001????????????????????????????: fi_ldz <= 20;
|
48'b000000000000000000001???????????????????????????: fi_ldz <= 21;
|
48'b000000000000000000001???????????????????????????: fi_ldz <= 21;
|
48'b0000000000000000000001??????????????????????????: fi_ldz <= 22;
|
48'b0000000000000000000001??????????????????????????: fi_ldz <= 22;
|
48'b00000000000000000000001?????????????????????????: fi_ldz <= 23;
|
48'b00000000000000000000001?????????????????????????: fi_ldz <= 23;
|
48'b000000000000000000000001????????????????????????: fi_ldz <= 24;
|
48'b000000000000000000000001????????????????????????: fi_ldz <= 24;
|
48'b0000000000000000000000001???????????????????????: fi_ldz <= 25;
|
48'b0000000000000000000000001???????????????????????: fi_ldz <= 25;
|
48'b00000000000000000000000001??????????????????????: fi_ldz <= 26;
|
48'b00000000000000000000000001??????????????????????: fi_ldz <= 26;
|
48'b000000000000000000000000001?????????????????????: fi_ldz <= 27;
|
48'b000000000000000000000000001?????????????????????: fi_ldz <= 27;
|
48'b0000000000000000000000000001????????????????????: fi_ldz <= 28;
|
48'b0000000000000000000000000001????????????????????: fi_ldz <= 28;
|
48'b00000000000000000000000000001???????????????????: fi_ldz <= 29;
|
48'b00000000000000000000000000001???????????????????: fi_ldz <= 29;
|
48'b000000000000000000000000000001??????????????????: fi_ldz <= 30;
|
48'b000000000000000000000000000001??????????????????: fi_ldz <= 30;
|
48'b0000000000000000000000000000001?????????????????: fi_ldz <= 31;
|
48'b0000000000000000000000000000001?????????????????: fi_ldz <= 31;
|
48'b00000000000000000000000000000001????????????????: fi_ldz <= 32;
|
48'b00000000000000000000000000000001????????????????: fi_ldz <= 32;
|
48'b000000000000000000000000000000001???????????????: fi_ldz <= 33;
|
48'b000000000000000000000000000000001???????????????: fi_ldz <= 33;
|
48'b0000000000000000000000000000000001??????????????: fi_ldz <= 34;
|
48'b0000000000000000000000000000000001??????????????: fi_ldz <= 34;
|
48'b00000000000000000000000000000000001?????????????: fi_ldz <= 35;
|
48'b00000000000000000000000000000000001?????????????: fi_ldz <= 35;
|
48'b000000000000000000000000000000000001????????????: fi_ldz <= 36;
|
48'b000000000000000000000000000000000001????????????: fi_ldz <= 36;
|
48'b0000000000000000000000000000000000001???????????: fi_ldz <= 37;
|
48'b0000000000000000000000000000000000001???????????: fi_ldz <= 37;
|
48'b00000000000000000000000000000000000001??????????: fi_ldz <= 38;
|
48'b00000000000000000000000000000000000001??????????: fi_ldz <= 38;
|
48'b000000000000000000000000000000000000001?????????: fi_ldz <= 39;
|
48'b000000000000000000000000000000000000001?????????: fi_ldz <= 39;
|
48'b0000000000000000000000000000000000000001????????: fi_ldz <= 40;
|
48'b0000000000000000000000000000000000000001????????: fi_ldz <= 40;
|
48'b00000000000000000000000000000000000000001???????: fi_ldz <= 41;
|
48'b00000000000000000000000000000000000000001???????: fi_ldz <= 41;
|
48'b000000000000000000000000000000000000000001??????: fi_ldz <= 42;
|
48'b000000000000000000000000000000000000000001??????: fi_ldz <= 42;
|
48'b0000000000000000000000000000000000000000001?????: fi_ldz <= 43;
|
48'b0000000000000000000000000000000000000000001?????: fi_ldz <= 43;
|
48'b00000000000000000000000000000000000000000001????: fi_ldz <= 44;
|
48'b00000000000000000000000000000000000000000001????: fi_ldz <= 44;
|
48'b000000000000000000000000000000000000000000001???: fi_ldz <= 45;
|
48'b000000000000000000000000000000000000000000001???: fi_ldz <= 45;
|
48'b0000000000000000000000000000000000000000000001??: fi_ldz <= 46;
|
48'b0000000000000000000000000000000000000000000001??: fi_ldz <= 46;
|
48'b00000000000000000000000000000000000000000000001?: fi_ldz <= 47;
|
48'b00000000000000000000000000000000000000000000001?: fi_ldz <= 47;
|
48'b00000000000000000000000000000000000000000000000?: fi_ldz <= 48;
|
48'b00000000000000000000000000000000000000000000000?: fi_ldz <= 48;
|
endcase
|
endcase
|
|
|
|
|
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
// Normalize
|
// Normalize
|
|
|
wire exp_in_80;
|
wire exp_in_80;
|
wire rmode_00, rmode_01, rmode_10, rmode_11;
|
wire rmode_00, rmode_01, rmode_10, rmode_11;
|
|
|
// Misc common signals
|
// Misc common signals
|
assign exp_in_ff = &exp_in;
|
assign exp_in_ff = &exp_in;
|
assign exp_in_00 = !(|exp_in);
|
assign exp_in_00 = !(|exp_in);
|
assign exp_in_80 = exp_in[7] & !(|exp_in[6:0]);
|
assign exp_in_80 = exp_in[7] & !(|exp_in[6:0]);
|
assign exp_out_ff = &exp_out;
|
assign exp_out_ff = &exp_out;
|
assign exp_out_00 = !(|exp_out);
|
assign exp_out_00 = !(|exp_out);
|
assign exp_out_fe = &exp_out[7:1] & !exp_out[0];
|
assign exp_out_fe = &exp_out[7:1] & !exp_out[0];
|
assign exp_out_final_ff = &exp_out_final;
|
assign exp_out_final_ff = &exp_out_final;
|
|
|
assign fract_out_7fffff = &fract_out;
|
assign fract_out_7fffff = &fract_out;
|
assign fract_out_00 = !(|fract_out);
|
assign fract_out_00 = !(|fract_out);
|
//assign fract_in_00 = !(|fract_in);
|
//assign fract_in_00 = !(|fract_in);
|
always @(posedge clk)
|
always @(posedge clk)
|
fract_in_00 <= !(|fract_in);
|
fract_in_00 <= !(|fract_in);
|
|
|
assign rmode_00 = (rmode==2'b00);
|
assign rmode_00 = (rmode==2'b00);
|
assign rmode_01 = (rmode==2'b01);
|
assign rmode_01 = (rmode==2'b01);
|
assign rmode_10 = (rmode==2'b10);
|
assign rmode_10 = (rmode==2'b10);
|
assign rmode_11 = (rmode==2'b11);
|
assign rmode_11 = (rmode==2'b11);
|
|
|
// Fasu Output will be denormalized ...
|
// Fasu Output will be denormalized ...
|
assign dn = !op_mul & !op_div &
|
assign dn = !op_mul & !op_div &
|
(exp_in_00 | (exp_next_mi[8] & !fract_in[47]) );
|
(exp_in_00 | (exp_next_mi[8] & !fract_in[47]) );
|
|
|
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
// Fraction Normalization
|
// Fraction Normalization
|
parameter f2i_emax = 8'h9d;
|
parameter f2i_emax = 8'h9d;
|
|
|
// Special Signals for f2i
|
// Special Signals for f2i
|
assign f2i_emin = rmode_00 ? 8'h7e : 8'h7f;
|
assign f2i_emin = rmode_00 ? 8'h7e : 8'h7f;
|
|
|
assign f2i_exp_gt_max = (exp_in > f2i_emax);
|
assign f2i_exp_gt_max = (exp_in > f2i_emax);
|
assign f2i_exp_lt_min = (exp_in < f2i_emin);
|
assign f2i_exp_lt_min = (exp_in < f2i_emin);
|
|
|
// Incremented fraction for rounding
|
// Incremented fraction for rounding
|
assign fract_out_pl1 = fract_out + 1;
|
assign fract_out_pl1 = fract_out + 1;
|
|
|
/*
|
/*
|
assign f2i_zero = (!opas & (exp_in<f2i_emin)) |
|
assign f2i_zero = (!opas & (exp_in<f2i_emin)) |
|
(opas & (exp_in>f2i_emax)) |
|
(opas & (exp_in>f2i_emax)) |
|
(opas & (exp_in<f2i_emin) & (fract_in_00 | !rmode_11));
|
(opas & (exp_in<f2i_emin) & (fract_in_00 | !rmode_11));
|
|
|
assign f2i_max = (!opas & (exp_in>f2i_emax)) |
|
assign f2i_max = (!opas & (exp_in>f2i_emax)) |
|
(opas & (exp_in<f2i_emin) & !fract_in_00 & rmode_11);
|
(opas & (exp_in<f2i_emin) & !fract_in_00 & rmode_11);
|
*/
|
*/
|
// Zero when :
|
// Zero when :
|
// a) too small exp. and positive sign - result will be 0
|
// a) too small exp. and positive sign - result will be 0
|
// b) too big exp. and negative sign - result will be largest possible -int
|
// b) too big exp. and negative sign - result will be largest possible -int
|
// c) -infinity: largest possible -int
|
// c) -infinity: largest possible -int
|
// d) -0.0: give positive 0
|
// d) -0.0: give positive 0
|
assign f2i_zero = (
|
assign f2i_zero = (
|
( (f2i_exp_lt_min & (opas & (!rmode_11 | fract_in_00))) |
|
( (f2i_exp_lt_min & (opas & (!rmode_11 | fract_in_00))) |
|
(f2i_exp_lt_min & !opas) |
|
(f2i_exp_lt_min & !opas) |
|
(f2i_exp_gt_max & opas) )
|
(f2i_exp_gt_max & opas) )
|
& !(&exp_in)
|
& !(&exp_in)
|
) |
|
) |
|
// -inf case
|
// -inf case
|
(opa_inf & opas) |
|
(opa_inf & opas) |
|
// -0.0 case
|
// -0.0 case
|
(fract_in_00 & exp_in_00);
|
(fract_in_00 & exp_in_00);
|
|
|
// Maximum :
|
// Maximum :
|
// a) too big exp and positive sign - result will be maximum int.
|
// a) too big exp and positive sign - result will be maximum int.
|
// b) rounding negative down and less than minimum expon. for int = -1
|
// b) rounding negative down and less than minimum expon. for int = -1
|
// c) +/- NaN or +inf - result will be maximum int
|
// c) +/- NaN or +inf - result will be maximum int
|
// d) disabled when the -0.0 case comes up
|
// d) disabled when the -0.0 case comes up
|
assign f2i_max = (
|
assign f2i_max = (
|
( ((!opas & f2i_exp_gt_max) |
|
( ((!opas & f2i_exp_gt_max) |
|
(f2i_exp_lt_min & !fract_in_00 & rmode_11 & opas))
|
(f2i_exp_lt_min & !fract_in_00 & rmode_11 & opas))
|
& !(&exp_in)) |
|
& !(&exp_in)) |
|
// Either +/- NaN, or +inf
|
// Either +/- NaN, or +inf
|
(opa_nan | (opa_inf & !opas))) &
|
(opa_nan | (opa_inf & !opas))) &
|
// .. and NOT -0.0( 0x80000000)
|
// .. and NOT -0.0( 0x80000000)
|
!(opas & fract_in_00 & exp_in_00);
|
!(opas & fract_in_00 & exp_in_00);
|
|
|
// Claculate various shifting options
|
// Claculate various shifting options
|
assign f2i_shft = exp_in-8'h7d;
|
assign f2i_shft = exp_in-8'h7d;
|
|
|
assign conv_shft = op_f2i ? f2i_shft : {2'h0, fi_ldz};
|
assign conv_shft = op_f2i ? f2i_shft : {2'h0, fi_ldz};
|
|
|
assign fract_in_shftl = (|conv_shft[7:6] | (f2i_zero & op_f2i)) ?
|
assign fract_in_shftl = (|conv_shft[7:6] | (f2i_zero & op_f2i)) ?
|
0 : fract_in<<conv_shft[5:0];
|
0 : fract_in<<conv_shft[5:0];
|
|
|
// Final fraction output
|
// Final fraction output
|
always @(posedge clk)
|
always @(posedge clk)
|
{fract_out,fract_trunc} <= fract_in_shftl;
|
{fract_out,fract_trunc} <= fract_in_shftl;
|
|
|
|
|
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
// Exponent Normalization
|
// Exponent Normalization
|
|
|
assign fi_ldz_mi1 = fi_ldz - 1;
|
assign fi_ldz_mi1 = fi_ldz - 1;
|
assign fi_ldz_mi22 = fi_ldz - 22;
|
assign fi_ldz_mi22 = fi_ldz - 22;
|
assign exp_out_pl1 = exp_out + 1;
|
assign exp_out_pl1 = exp_out + 1;
|
assign exp_out_mi1 = exp_out - 1;
|
assign exp_out_mi1 = exp_out - 1;
|
assign exp_in_pl1 = exp_in + 1; // 9 bits - includes carry out
|
assign exp_in_pl1 = exp_in + 1; // 9 bits - includes carry out
|
assign exp_in_mi1 = exp_in - 1; // 9 bits - includes carry out
|
assign exp_in_mi1 = exp_in - 1; // 9 bits - includes carry out
|
assign exp_out1_mi1 = exp_out1 - 1;
|
assign exp_out1_mi1 = exp_out1 - 1;
|
|
|
assign exp_next_mi = exp_in_pl1 - fi_ldz_mi1; // 9 bits - includes carry out
|
assign exp_next_mi = exp_in_pl1 -
|
|
{3'd0,fi_ldz_mi1}; // 9 bits - includes carry out
|
|
|
assign {exp_out1_co, exp_out1} = fract_in[47] ? exp_in_pl1 : exp_next_mi;
|
assign {exp_out1_co, exp_out1} = fract_in[47] ? exp_in_pl1 : exp_next_mi;
|
|
|
// Only ever force positive if:
|
// Only ever force positive if:
|
// i) It's a NaN
|
// i) It's a NaN
|
// ii) It's zero and not -inf
|
// ii) It's zero and not -inf
|
// iii) We've rounded to 0 (both fract and exp out are 0 and not forced)
|
// iii) We've rounded to 0 (both fract and exp out are 0 and not forced)
|
// Force to 1 (negative) when have negative sign with too big exponent
|
// Force to 1 (negative) when have negative sign with too big exponent
|
assign f2i_out_sign = (opas & (exp_in>f2i_emax) & f2i_zero) ?
|
assign f2i_out_sign = (opas & (exp_in>f2i_emax) & f2i_zero) ?
|
1 : opa_nan | (f2i_zero & !f2i_max & !(opa_inf & opas))
|
1 : opa_nan | (f2i_zero & !f2i_max & !(opa_inf & opas))
|
| (!(|out) & !f2i_zero)
|
| (!(|out) & !f2i_zero)
|
?
|
?
|
0 :opas;
|
0 :opas;
|
|
|
assign exp_i2f = fract_in_00 ? (opas ? 8'h9e : 0) : (8'h9e-fi_ldz);
|
assign exp_i2f = fract_in_00 ? (opas ? 8'h9e : 0) : (8'h9e-{2'd0,fi_ldz});
|
assign exp_f2i_1 = {{8{fract_in[47]}}, fract_in }<<f2i_shft;
|
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 exp_f2i = f2i_zero ? 0 : f2i_max ? 8'hff : exp_f2i_1[55:48];
|
assign conv_exp = op_f2i ? exp_f2i : exp_i2f;
|
assign conv_exp = op_f2i ? exp_f2i : exp_i2f;
|
|
|
//assign exp_out = conv_exp;
|
//assign exp_out = conv_exp;
|
always @(posedge clk)
|
always @(posedge clk)
|
exp_out <= conv_exp;
|
exp_out <= conv_exp;
|
|
|
|
|
assign ldz_all = fi_ldz;
|
assign ldz_all = {1'b0,fi_ldz};
|
assign fi_ldz_2a = 6'd23 - fi_ldz;
|
assign fi_ldz_2a = 6'd23 - fi_ldz;
|
assign fi_ldz_2 = {fi_ldz_2a[6], fi_ldz_2a[6:0]};
|
assign fi_ldz_2 = {fi_ldz_2a[6], fi_ldz_2a[6:0]};
|
|
|
|
|
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
// Round
|
// Round
|
|
|
// Extract rounding (GRS) bits
|
// Extract rounding (GRS) bits
|
assign g = fract_out[0];
|
assign g = fract_out[0];
|
assign r = fract_trunc[24];
|
assign r = fract_trunc[24];
|
assign s = |fract_trunc[23:0];
|
assign s = |fract_trunc[23:0];
|
|
|
// Round to nearest even
|
// Round to nearest even
|
assign round = (g & r) | (r & s) ;
|
assign round = (g & r) | (r & s) ;
|
assign {exp_rnd_adj0, fract_out_rnd0} = round ?
|
assign {exp_rnd_adj0, fract_out_rnd0} = round ?
|
fract_out_pl1 : {1'b0, fract_out};
|
fract_out_pl1 : {1'b0, fract_out};
|
|
|
assign exp_out_rnd0 = exp_rnd_adj0 ? exp_out_pl1 : exp_out;
|
assign exp_out_rnd0 = exp_rnd_adj0 ? exp_out_pl1 : exp_out;
|
|
|
assign ovf0 = exp_out_final_ff & !rmode_01 & !op_f2i;
|
assign ovf0 = exp_out_final_ff & !rmode_01 & !op_f2i;
|
|
|
// round to zero
|
// round to zero
|
// Added detection of sign and rounding up in case of negative ftoi! - JPB
|
// Added detection of sign and rounding up in case of negative ftoi! - JPB
|
assign fract_out_rnd1 = (exp_out_ff & !dn & !op_f2i) ?
|
assign fract_out_rnd1 = (exp_out_ff & !dn & !op_f2i) ?
|
23'h7fffff :
|
23'h7fffff :
|
(op_f2i & (|fract_trunc) & opas) ?
|
(op_f2i & (|fract_trunc) & opas) ?
|
fract_out_pl1[22:0] : fract_out ;
|
fract_out_pl1[22:0] : fract_out ;
|
|
|
assign exp_out_rnd1 = (g & r & s & exp_in_ff) ?
|
assign exp_out_rnd1 = (g & r & s & exp_in_ff) ?
|
exp_next_mi[7:0] : (exp_out_ff & !op_f2i) ?
|
exp_next_mi[7:0] : (exp_out_ff & !op_f2i) ?
|
exp_in :
|
exp_in :
|
(op_f2i & opas & (|fract_trunc) & fract_out_pl1[23]) ?
|
(op_f2i & opas & (|fract_trunc) & fract_out_pl1[23]) ?
|
exp_out_pl1: exp_out;
|
exp_out_pl1: exp_out;
|
|
|
assign ovf1 = exp_out_ff & !dn;
|
assign ovf1 = exp_out_ff & !dn;
|
|
|
// round to +inf (UP) and -inf (DOWN)
|
// round to +inf (UP) and -inf (DOWN)
|
assign r_sign = sign;
|
assign r_sign = sign;
|
|
|
assign round2a = !exp_out_fe | !fract_out_7fffff |
|
assign round2a = !exp_out_fe | !fract_out_7fffff |
|
(exp_out_fe & fract_out_7fffff);
|
(exp_out_fe & fract_out_7fffff);
|
|
|
assign round2_fasu = ((r | s) & !r_sign) & (!exp_out[7] |
|
assign round2_fasu = ((r | s) & !r_sign) & (!exp_out[7] |
|
(exp_out[7] & round2a));
|
(exp_out[7] & round2a));
|
|
|
assign round2_f2i = rmode_10 &
|
assign round2_f2i = rmode_10 &
|
(( |fract_in[23:0] & !opas & (exp_in<8'h80 )) |
|
(( |fract_in[23:0] & !opas & (exp_in<8'h80 )) |
|
(|fract_trunc));
|
(|fract_trunc));
|
|
|
assign round2 = op_f2i ? round2_f2i : round2_fasu;
|
assign round2 = op_f2i ? round2_f2i : round2_fasu;
|
|
|
assign {exp_rnd_adj2a, fract_out_rnd2a} = round2 ? fract_out_pl1 :
|
assign {exp_rnd_adj2a, fract_out_rnd2a} = round2 ? fract_out_pl1 :
|
{1'b0, fract_out};
|
{1'b0, fract_out};
|
|
|
assign exp_out_rnd2a = exp_rnd_adj2a ? exp_out_pl1 : exp_out;
|
assign exp_out_rnd2a = exp_rnd_adj2a ? exp_out_pl1 : exp_out;
|
|
|
assign fract_out_rnd2 = (r_sign & exp_out_ff & !op_div & !dn & !op_f2i) ?
|
assign fract_out_rnd2 = (r_sign & exp_out_ff & !op_div & !dn & !op_f2i) ?
|
23'h7fffff : fract_out_rnd2a;
|
23'h7fffff : fract_out_rnd2a;
|
|
|
assign exp_out_rnd2 = (r_sign & exp_out_ff & !op_f2i) ?
|
assign exp_out_rnd2 = (r_sign & exp_out_ff & !op_f2i) ?
|
8'hfe : exp_out_rnd2a;
|
8'hfe : exp_out_rnd2a;
|
|
|
|
|
// Choose rounding mode
|
// Choose rounding mode
|
always @(rmode or exp_out_rnd0 or exp_out_rnd1 or exp_out_rnd2)
|
always @(rmode or exp_out_rnd0 or exp_out_rnd1 or exp_out_rnd2)
|
case(rmode) // synopsys full_case parallel_case
|
case(rmode) // synopsys full_case parallel_case
|
0: exp_out_rnd = exp_out_rnd0;
|
0: exp_out_rnd = exp_out_rnd0;
|
1: exp_out_rnd = exp_out_rnd1;
|
1: exp_out_rnd = exp_out_rnd1;
|
2,3: exp_out_rnd = exp_out_rnd2;
|
2,3: exp_out_rnd = exp_out_rnd2;
|
endcase
|
endcase
|
|
|
always @(rmode or fract_out_rnd0 or fract_out_rnd1 or fract_out_rnd2)
|
always @(rmode or fract_out_rnd0 or fract_out_rnd1 or fract_out_rnd2)
|
case(rmode) // synopsys full_case parallel_case
|
case(rmode) // synopsys full_case parallel_case
|
0: fract_out_rnd = fract_out_rnd0;
|
0: fract_out_rnd = fract_out_rnd0;
|
1: fract_out_rnd = fract_out_rnd1;
|
1: fract_out_rnd = fract_out_rnd1;
|
2,3: fract_out_rnd = fract_out_rnd2;
|
2,3: fract_out_rnd = fract_out_rnd2;
|
endcase
|
endcase
|
|
|
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
// Final Output Mux
|
// Final Output Mux
|
// Fix Output for denormalized and special numbers
|
// Fix Output for denormalized and special numbers
|
|
|
assign fract_out_final = ovf0 ? 23'h0 :
|
assign fract_out_final = ovf0 ? 23'h0 :
|
(f2i_max & op_f2i) ? 23'h7fffff :
|
(f2i_max & op_f2i) ? 23'h7fffff :
|
fract_out_rnd;
|
fract_out_rnd;
|
|
|
assign exp_out_final = (f2i_max & op_f2i) ? 8'hff : exp_out_rnd;
|
assign exp_out_final = (f2i_max & op_f2i) ? 8'hff : exp_out_rnd;
|
|
|
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
// Pack Result
|
// Pack Result
|
|
|
assign out = {exp_out_final, fract_out_final};
|
assign out = {exp_out_final, fract_out_final};
|
|
|
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
// Exceptions
|
// Exceptions
|
|
|
|
|
assign underflow = (!fract_in[47] & exp_out1_co) & !dn;
|
assign underflow = (!fract_in[47] & exp_out1_co) & !dn;
|
|
|
|
|
assign overflow = ovf0 | ovf1;
|
assign overflow = ovf0 | ovf1;
|
|
|
wire f2i_ine;
|
wire f2i_ine;
|
wire exp_in_lt_half = (exp_in<8'h80);
|
wire exp_in_lt_half = (exp_in<8'h80);
|
|
|
assign f2i_ine = (f2i_zero & !fract_in_00 & !opas) |
|
assign f2i_ine = (f2i_zero & !fract_in_00 & !opas) |
|
(|fract_trunc) |
|
(|fract_trunc) |
|
(f2i_zero & exp_in_lt_half & opas & !fract_in_00) |
|
(f2i_zero & exp_in_lt_half & opas & !fract_in_00) |
|
(f2i_max & rmode_11 & (exp_in<8'h80));
|
(f2i_max & rmode_11 & (exp_in<8'h80));
|
|
|
assign ine = op_f2i ? f2i_ine :
|
assign ine = op_f2i ? f2i_ine :
|
op_i2f ? (|fract_trunc) :
|
op_i2f ? (|fract_trunc) :
|
((r & !dn) | (s & !dn) );
|
((r & !dn) | (s & !dn) );
|
|
|
assign inv = op_f2i & (exp_in > f2i_emax);
|
assign inv = op_f2i & (exp_in > f2i_emax);
|
|
|
|
|
|
|
endmodule // or1200_fpu_post_norm_intfloat_conv
|
endmodule // or1200_fpu_post_norm_intfloat_conv
|
|
|
|
|