From 9b06310cbeb59abf1af06cfd1cc3150b14e83cac Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 3 Dec 2016 14:49:51 -0500 Subject: [PATCH] Fix internal error on unique casez with --assert, bug1117. --- Changes | 2 ++ src/V3Assert.cpp | 23 ++++++++++++++++++++--- test_regress/t/t_assert_casez.pl | 19 +++++++++++++++++++ test_regress/t/t_assert_casez.v | 26 ++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_assert_casez.pl create mode 100644 test_regress/t/t_assert_casez.v diff --git a/Changes b/Changes index 7b91b9fb4..d64edbe9a 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix internal error on double-for loop unrolling, bug1044. [Jan Egil Ruud] +**** Fix internal error on unique casez with --assert, bug1117. [Enzo Chi] + * Verilator 3.890 2016-11-25 diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 273570031..b92a4540f 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -245,9 +245,26 @@ private: AstNode* propp = NULL; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) { - AstNode* onep = new AstEq(icondp->fileline(), - nodep->exprp()->cloneTree(false), - icondp->cloneTree(false)); + AstNode* onep; + AstConst* iconstp = icondp->castConst(); + if (iconstp && iconstp->num().isFourState() + && (nodep->casex() || nodep->casez() || nodep->caseInside())) { + V3Number nummask (itemp->fileline(), iconstp->width()); + nummask.opBitsNonX(iconstp->num()); + V3Number numval (itemp->fileline(), iconstp->width()); + numval.opBitsOne(iconstp->num()); + AstNode* and1p = new AstAnd(itemp->fileline(), nodep->exprp()->cloneTree(false), + new AstConst(itemp->fileline(), nummask)); + AstNode* and2p = new AstAnd(itemp->fileline(), + new AstConst(itemp->fileline(), numval), + new AstConst(itemp->fileline(), nummask)); + onep = AstEq::newTyped(itemp->fileline(), and1p, and2p); + + } else { + onep = AstEq::newTyped(icondp->fileline(), + nodep->exprp()->cloneTree(false), + icondp->cloneTree(false)); + } if (propp) propp = new AstConcat(icondp->fileline(), onep, propp); else propp = onep; } diff --git a/test_regress/t/t_assert_casez.pl b/test_regress/t/t_assert_casez.pl new file mode 100755 index 000000000..b57b2dea8 --- /dev/null +++ b/test_regress/t/t_assert_casez.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 by Wilson Snyder. 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. + +compile ( + verilator_flags2 => ['--assert'], + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_assert_casez.v b/test_regress/t/t_assert_casez.v new file mode 100644 index 000000000..106a8ebd8 --- /dev/null +++ b/test_regress/t/t_assert_casez.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2016 by Wilson Snyder + +module t; + + reg [1:0] value; + + initial begin + value = 2'b00; + unique casez (value) + 2'b00 : ; + 2'b01 : ; + 2'b1? : ; + endcase + value = 2'b11; + unique casez (value) + 2'b00 : ; + 2'b01 : ; + 2'b1? : ; + endcase + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule