From 28b46bd4b49a17976c754abc998a767c722910c5 Mon Sep 17 00:00:00 2001 From: Maurus Item Date: Fri, 14 Jun 2024 11:20:55 +0200 Subject: [PATCH] Fixed Various internals that caused problems when bitflips occur. - Removed recursive assignments that can cause trouble in simulation - Removed repeated assignments in always_comb of classifier that cause trouble in simulation - Fixed format selection can evaluate to X when faults are injected into Enum in simulation. --- src/fpnew_classifier.sv | 21 +++++++++++---------- src/fpnew_fma.sv | 18 ++++++++++++------ src/fpnew_fma_multi.sv | 17 ++++++++++++----- src/fpnew_opgroup_block.sv | 2 +- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/fpnew_classifier.sv b/src/fpnew_classifier.sv index a322946d..927cf051 100644 --- a/src/fpnew_classifier.sv +++ b/src/fpnew_classifier.sv @@ -55,20 +55,21 @@ module fpnew_classifier #( is_boxed = is_boxed_i[op]; is_normal = is_boxed && (value.exponent != '0) && (value.exponent != '1); is_zero = is_boxed && (value.exponent == '0) && (value.mantissa == '0); - is_subnormal = is_boxed && (value.exponent == '0) && !is_zero; is_inf = is_boxed && ((value.exponent == '1) && (value.mantissa == '0)); + is_subnormal = is_boxed && (value.exponent == '0) && !is_zero; is_nan = !is_boxed || ((value.exponent == '1) && (value.mantissa != '0)); is_signalling = is_boxed && is_nan && (value.mantissa[MAN_BITS-1] == 1'b0); is_quiet = is_nan && !is_signalling; - // Assign output for current input - info_o[op].is_normal = is_normal; - info_o[op].is_subnormal = is_subnormal; - info_o[op].is_zero = is_zero; - info_o[op].is_inf = is_inf; - info_o[op].is_nan = is_nan; - info_o[op].is_signalling = is_signalling; - info_o[op].is_quiet = is_quiet; - info_o[op].is_boxed = is_boxed; end + + // Assign output for current input + assign info_o[op].is_normal = is_normal; + assign info_o[op].is_subnormal = is_subnormal; + assign info_o[op].is_zero = is_zero; + assign info_o[op].is_inf = is_inf; + assign info_o[op].is_nan = is_nan; + assign info_o[op].is_signalling = is_signalling; + assign info_o[op].is_quiet = is_quiet; + assign info_o[op].is_boxed = is_boxed; end endmodule diff --git a/src/fpnew_fma.sv b/src/fpnew_fma.sv index c6ef899a..992dbadd 100644 --- a/src/fpnew_fma.sv +++ b/src/fpnew_fma.sv @@ -147,22 +147,28 @@ module fpnew_fma #( // | MUL | \c 0 | MUL: Set operand C to +0.0 or -0.0 depending on the rounding mode // | *others* | \c - | *invalid* // \note \c op_mod_q always inverts the sign of the addend. - always_comb begin : op_select + // Fix for InjectaFault + fp_t operand_a_base, operand_b_base, operand_c_base; + assign operand_a_base = inp_pipe_operands_q[NUM_INP_REGS][0]; + assign operand_b_base = inp_pipe_operands_q[NUM_INP_REGS][1]; + assign operand_c_base = inp_pipe_operands_q[NUM_INP_REGS][2]; + + always_comb begin : op_select // Default assignments - packing-order-agnostic - operand_a = inp_pipe_operands_q[NUM_INP_REGS][0]; - operand_b = inp_pipe_operands_q[NUM_INP_REGS][1]; - operand_c = inp_pipe_operands_q[NUM_INP_REGS][2]; + operand_a = operand_a_base; + operand_b = operand_b_base; + operand_c = operand_c_base; info_a = info_q[0]; info_b = info_q[1]; info_c = info_q[2]; // op_mod_q inverts sign of operand C - operand_c.sign = operand_c.sign ^ inp_pipe_op_mod_q[NUM_INP_REGS]; + operand_c.sign = operand_c_base.sign ^ inp_pipe_op_mod_q[NUM_INP_REGS]; unique case (inp_pipe_op_q[NUM_INP_REGS]) fpnew_pkg::FMADD: ; // do nothing - fpnew_pkg::FNMSUB: operand_a.sign = ~operand_a.sign; // invert sign of product + fpnew_pkg::FNMSUB: operand_a.sign = ~operand_a_base.sign; // invert sign of product fpnew_pkg::ADD: begin // Set multiplicand to +1 operand_a = '{sign: 1'b0, exponent: BIAS, mantissa: '0}; info_a = '{is_normal: 1'b1, is_boxed: 1'b1, default: 1'b0}; //normal, boxed value. diff --git a/src/fpnew_fma_multi.sv b/src/fpnew_fma_multi.sv index 77886424..89dce97f 100644 --- a/src/fpnew_fma_multi.sv +++ b/src/fpnew_fma_multi.sv @@ -196,22 +196,29 @@ module fpnew_fma_multi #( // | MUL | \c 0 | MUL: Set operand C to +0.0 or -0.0 depending on the rounding mode // | *others* | \c - | *invalid* // \note \c op_mod_q always inverts the sign of the addend. + + // Fix for InjectaFault + fp_t operand_a_base, operand_b_base, operand_c_base; + assign operand_a_base = {fmt_sign[src_fmt_q][0], fmt_exponent[src_fmt_q][0], fmt_mantissa[src_fmt_q][0]}; + assign operand_b_base = {fmt_sign[src_fmt_q][1], fmt_exponent[src_fmt_q][1], fmt_mantissa[src_fmt_q][1]}; + assign operand_c_base = {fmt_sign[dst_fmt_q][2], fmt_exponent[dst_fmt_q][2], fmt_mantissa[dst_fmt_q][2]}; + always_comb begin : op_select // Default assignments - packing-order-agnostic - operand_a = {fmt_sign[src_fmt_q][0], fmt_exponent[src_fmt_q][0], fmt_mantissa[src_fmt_q][0]}; - operand_b = {fmt_sign[src_fmt_q][1], fmt_exponent[src_fmt_q][1], fmt_mantissa[src_fmt_q][1]}; - operand_c = {fmt_sign[dst_fmt_q][2], fmt_exponent[dst_fmt_q][2], fmt_mantissa[dst_fmt_q][2]}; + operand_a = operand_a_base; + operand_b = operand_b_base; + operand_c = operand_c_base; info_a = info_q[src_fmt_q][0]; info_b = info_q[src_fmt_q][1]; info_c = info_q[dst_fmt_q][2]; // op_mod_q inverts sign of operand C - operand_c.sign = operand_c.sign ^ inp_pipe_op_mod_q[NUM_INP_REGS]; + operand_c.sign = operand_c_base.sign ^ inp_pipe_op_mod_q[NUM_INP_REGS]; unique case (inp_pipe_op_q[NUM_INP_REGS]) fpnew_pkg::FMADD: ; // do nothing - fpnew_pkg::FNMSUB: operand_a.sign = ~operand_a.sign; // invert sign of product + fpnew_pkg::FNMSUB: operand_a.sign = ~operand_a_base.sign; // invert sign of product fpnew_pkg::ADD: begin // Set multiplicand to +1 operand_a = '{sign: 1'b0, exponent: fpnew_pkg::bias(src_fmt_q), mantissa: '0}; info_a = '{is_normal: 1'b1, is_boxed: 1'b1, default: 1'b0}; //normal, boxed value. diff --git a/src/fpnew_opgroup_block.sv b/src/fpnew_opgroup_block.sv index 628beaa9..7d873a8f 100644 --- a/src/fpnew_opgroup_block.sv +++ b/src/fpnew_opgroup_block.sv @@ -176,7 +176,7 @@ module fpnew_opgroup_block #( logic in_valid; - assign in_valid = in_valid_i & (FmtUnitTypes[dst_fmt_i] == fpnew_pkg::MERGED); + assign in_valid = in_valid_i & (FmtUnitTypes[dst_fmt_i] == fpnew_pkg::MERGED && dst_fmt_i < dst_fmt_i.num()); fpnew_opgroup_multifmt_slice #( .OpGroup ( OpGroup ),