Fix --assert with complex case statements, bug1164.

This commit is contained in:
Wilson Snyder 2017-05-17 20:15:40 -04:00
parent 2fa16708b7
commit ce879122bb
8 changed files with 156 additions and 14 deletions

View File

@ -19,6 +19,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
**** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson]
**** Fix --assert with complex case statements, bug1164. [Enzo Chi]
* Verilator 3.902 2017-04-02

View File

@ -246,20 +246,10 @@ private:
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
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);
if (nodep->casex() || nodep->casez() || nodep->caseInside()) {
onep = AstEqWild::newTyped(itemp->fileline(),
nodep->exprp()->cloneTree(false),
icondp->cloneTree(false));
} else {
onep = AstEq::newTyped(icondp->fileline(),
nodep->exprp()->cloneTree(false),

View File

@ -140,6 +140,13 @@ AstNodeBiop* AstLte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
}
}
AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
if (lhsp->isDouble() && rhsp->isDouble()) {
return new AstEqD(fl, lhsp, rhsp);
} else {
return new AstEqWild(fl, lhsp, rhsp);
}
}
bool AstVar::isSigPublic() const {
return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));

View File

@ -4673,6 +4673,7 @@ public:
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(EqWild)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqWild(this->fileline(), lhsp, rhsp); }
static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstEqWild/AstEqD
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f==? %r)"; }
virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }

View File

@ -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;

View File

@ -0,0 +1,33 @@
// 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 (/*AUTOARG*/
// Outputs
dout,
// Inputs
clk, sel, a, c
);
input clk;
input bit [3:0] sel;
input bit [3:0] a;
input bit c;
output bit dout;
localparam logic DC = 1'b?;
always_ff @(posedge clk) begin
unique casez(sel)
4'b0000: dout <= a[0];
4'b001?: dout <= a[1];
{1'b0, 1'b1, 1'b?, 1'b?}: dout <= a[2];
{1'b1, 1'b?, 1'b?, DC}: dout <= a[3];
default: dout <= '0;
endcase
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

18
test_regress/t/t_mem_banks.pl Executable file
View File

@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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 (
);
execute (
check_finished=>1,
);
ok(1);
1;

View File

@ -0,0 +1,72 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
module t (/*AUTOARG*/);
reg [5:0] addr;
parameter BANKS = 6;
parameter ROWS = 8;
wire [2:0] bank;
wire [2:0] row;
integer a;
integer used[BANKS][ROWS];
// Test loop
initial begin
for (a = 0; a < BANKS*ROWS; ++a) begin
addr[5:0] = a[5:0];
hash (addr, bank, row);
used [bank][row] ++;
if (used [bank][row] > 1) begin
$write ("Error: Hash failed addr=%x bank=%x row=%x\n", addr, bank, row);
end
end
$write("*-* All Finished *-*\n");
$finish;
end
task hash (input [5:0] addr,
output [2:0] bank,
output [2:0] row);
reg [1:0] third;
reg [1:0] fourth;
third = {addr[5], addr[4]};
fourth = {addr[3] ^ addr[1],
addr[2] ^ addr[0]};
case (third)
2'h0:
case (fourth)
2'h0: begin bank = 3'h0; row = {1'h0, addr[1:0]}; end
2'h1: begin bank = 3'h1; row = {1'h0, addr[1:0]}; end
2'h2: begin bank = 3'h2; row = {1'h0, addr[1:0]}; end
2'h3: begin bank = 3'h3; row = {1'h0, addr[1:0]}; end
endcase
2'h1:
case (fourth)
2'h0: begin bank = 3'h0; row = {1'h1, addr[1:0]}; end
2'h1: begin bank = 3'h1; row = {1'h1, addr[1:0]}; end
2'h2: begin bank = 3'h4; row = {1'h0, addr[1:0]}; end
2'h3: begin bank = 3'h5; row = {1'h0, addr[1:0]}; end
endcase
2'h2:
case (fourth)
2'h0: begin bank = 3'h2; row = {1'h1, addr[1:0]}; end
2'h1: begin bank = 3'h3; row = {1'h1, addr[1:0]}; end
2'h2: begin bank = 3'h4; row = {1'h1, addr[1:0]}; end
2'h3: begin bank = 3'h5; row = {1'h1, addr[1:0]}; end
endcase
2'h3: $stop;
endcase
endtask
endmodule