From aa595d40de0b37a912cd974b5891fa1f2f638f91 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sat, 20 Jun 2020 04:16:07 +0100 Subject: [PATCH] Do not fold IF with 'bx condition before V3Unknown (#2438) Fixes #2425 --- src/V3Const.cpp | 5 ++- test_regress/t/t_x_assign.cpp | 53 +++++++++++++++++++++++++++ test_regress/t/t_x_assign.v | 16 ++++++++ test_regress/t/t_x_assign_0.pl | 26 +++++++++++++ test_regress/t/t_x_assign_1.pl | 26 +++++++++++++ test_regress/t/t_x_assign_unique_0.pl | 26 +++++++++++++ test_regress/t/t_x_assign_unique_1.pl | 26 +++++++++++++ 7 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 test_regress/t/t_x_assign.cpp create mode 100644 test_regress/t/t_x_assign.v create mode 100755 test_regress/t/t_x_assign_0.pl create mode 100755 test_regress/t/t_x_assign_1.pl create mode 100755 test_regress/t/t_x_assign_unique_0.pl create mode 100755 test_regress/t/t_x_assign_unique_1.pl diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 0a5af6ac0..44ae54ee2 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1935,9 +1935,12 @@ private: if (constp->isZero()) { UINFO(4, "IF(0,{any},{x}) => {x}: " << nodep << endl); keepp = nodep->elsesp(); - } else { + } else if (!m_doV || constp->isNeqZero()) { // Might be X in Verilog UINFO(4, "IF(!0,{x},{any}) => {x}: " << nodep << endl); keepp = nodep->ifsp(); + } else { + UINFO(4, "IF condition is X, retaining: " << nodep << endl); + return; } if (keepp) { keepp->unlinkFrBackWithNext(); diff --git a/test_regress/t/t_x_assign.cpp b/test_regress/t/t_x_assign.cpp new file mode 100644 index 000000000..760b6f7ec --- /dev/null +++ b/test_regress/t/t_x_assign.cpp @@ -0,0 +1,53 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2020 by Geza Lore. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include + +#include "verilated.h" +#include VM_PREFIX_INCLUDE + +// clang-format off +#if defined(T_X_ASSIGN_0) +# define EXPECTED 0 +#elif defined(T_X_ASSIGN_1) +# define EXPECTED 1 +#elif defined(T_X_ASSIGN_UNIQUE_0) +# define EXPECTED 0 +#elif defined(T_X_ASSIGN_UNIQUE_1) +# define EXPECTED 1 +#else +# error "Don't know expectd output for test" #TEST +#endif +// clang-format on + +int main(int argc, const char** argv) { + VM_PREFIX* top = new VM_PREFIX(); + +#if defined(T_X_ASSIGN_UNIQUE_0) + Verilated::randReset(0); +#elif defined(T_X_ASSIGN_UNIQUE_1) + Verilated::randReset(1); +#endif + + // Evaluate one clock posedge + top->clk = 0; + top->eval(); + top->clk = 1; + top->eval(); + + if (top->o != EXPECTED) { + vl_fatal(__FILE__, __LINE__, "TOP.t", "incorrect module output"); + exit(1); + } + + std::cout << "*-* All Finished *-*" << std::endl; + return 0; +} diff --git a/test_regress/t/t_x_assign.v b/test_regress/t/t_x_assign.v new file mode 100644 index 000000000..dd40e363f --- /dev/null +++ b/test_regress/t/t_x_assign.v @@ -0,0 +1,16 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 by Geza Lore. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +module t_x_assign( + input wire clk, + output reg o +); + always @(posedge clk) begin + if (1'bx) o <= 1'd1; else o <= 1'd0; + end +endmodule diff --git a/test_regress/t/t_x_assign_0.pl b/test_regress/t/t_x_assign_0.pl new file mode 100755 index 000000000..6f9e1347f --- /dev/null +++ b/test_regress/t/t_x_assign_0.pl @@ -0,0 +1,26 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt_all => 1); + +top_filename("t/t_x_assign.v"); + +compile( + make_top_shell => 0, + make_main => 0, + verilator_flags2 => ["--x-assign 0 --exe $Self->{t_dir}/t_x_assign.cpp"], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_x_assign_1.pl b/test_regress/t/t_x_assign_1.pl new file mode 100755 index 000000000..2a6ffe0a8 --- /dev/null +++ b/test_regress/t/t_x_assign_1.pl @@ -0,0 +1,26 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt_all => 1); + +top_filename("t/t_x_assign.v"); + +compile( + make_top_shell => 0, + make_main => 0, + verilator_flags2 => ["--x-assign 1 --exe $Self->{t_dir}/t_x_assign.cpp"], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_x_assign_unique_0.pl b/test_regress/t/t_x_assign_unique_0.pl new file mode 100755 index 000000000..bef9e2495 --- /dev/null +++ b/test_regress/t/t_x_assign_unique_0.pl @@ -0,0 +1,26 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt_all => 1); + +top_filename("t/t_x_assign.v"); + +compile( + make_top_shell => 0, + make_main => 0, + verilator_flags2 => ["--x-assign unique --exe $Self->{t_dir}/t_x_assign.cpp"], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_x_assign_unique_1.pl b/test_regress/t/t_x_assign_unique_1.pl new file mode 100755 index 000000000..bef9e2495 --- /dev/null +++ b/test_regress/t/t_x_assign_unique_1.pl @@ -0,0 +1,26 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt_all => 1); + +top_filename("t/t_x_assign.v"); + +compile( + make_top_shell => 0, + make_main => 0, + verilator_flags2 => ["--x-assign unique --exe $Self->{t_dir}/t_x_assign.cpp"], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1;