forked from github/verilator
Fix pattern assignment width propagation, bug1037.
This commit is contained in:
parent
4945282369
commit
90ecf14a0a
2
Changes
2
Changes
@ -23,6 +23,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
**** Fix slicing mix of big and little-endian, bug1033. [Geoff Barrett]
|
||||
|
||||
**** Fix pattern assignment width propagation, bug1037. [Johan Bjork]
|
||||
|
||||
|
||||
* Verilator 3.880 2015-12-19
|
||||
|
||||
|
@ -1600,7 +1600,8 @@ private:
|
||||
// Determine initial values
|
||||
vdtypep = memp;
|
||||
patp->dtypep(memp);
|
||||
patp->accept(*this,WidthVP(memp,BOTH).p());
|
||||
patp->accept(*this,WidthVP(memp,BOTH).p()); // See visit(AstPatMember*
|
||||
|
||||
// Convert to concat for now
|
||||
AstNode* valuep = patp->lhssp()->unlinkFrBack();
|
||||
if (valuep->castConst()) {
|
||||
@ -1653,8 +1654,8 @@ private:
|
||||
vdtypep = arrayp->subDTypep();
|
||||
// Don't want the RHS an array
|
||||
patp->dtypep(vdtypep);
|
||||
// Determine values - might be another InitArray
|
||||
patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p());
|
||||
// Determine values - might be another InitArray
|
||||
patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p()); // See visit(AstPatMember*
|
||||
// Convert to InitArray or constify immediately
|
||||
AstNode* valuep = patp->lhssp()->unlinkFrBack();
|
||||
if (valuep->castConst()) {
|
||||
@ -1760,8 +1761,8 @@ private:
|
||||
UINFO(9," PATMEMBER "<<nodep<<endl);
|
||||
if (nodep->lhssp()->nextp()) nodep->v3fatalSrc("PatMember value should be singular w/replicates removed");
|
||||
// Need to propagate assignment type downwards, even on prelim
|
||||
nodep->iterateChildren(*this,WidthVP(nodep->dtypep(),BOTH).p());
|
||||
iterateCheck(nodep,"Pattern value",nodep->lhssp(),CONTEXT,FINAL,vdtypep,EXTEND_LHS);
|
||||
nodep->iterateChildren(*this,WidthVP(nodep->dtypep(),PRELIM).p());
|
||||
iterateCheck(nodep,"Pattern value",nodep->lhssp(),ASSIGN,FINAL,vdtypep,EXTEND_LHS);
|
||||
}
|
||||
int visitPatMemberRep(AstPatMember* nodep) {
|
||||
uint32_t times = 1;
|
||||
|
19
test_regress/t/t_struct_pat_width.pl
Executable file
19
test_regress/t/t_struct_pat_width.pl
Executable 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 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;
|
||||
|
38
test_regress/t/t_struct_pat_width.v
Normal file
38
test_regress/t/t_struct_pat_width.v
Normal file
@ -0,0 +1,38 @@
|
||||
// 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 (clk);
|
||||
input clk;
|
||||
typedef struct packed {
|
||||
logic [2:0] _foo;
|
||||
logic [2:0] _bar;
|
||||
} struct_t;
|
||||
|
||||
logic [2:0] meh;
|
||||
struct_t param;
|
||||
localparam integer twentyone = 21;
|
||||
|
||||
// verilator lint_off WIDTH
|
||||
assign param = '{
|
||||
_foo: twentyone % 8 + 1,
|
||||
_bar: (twentyone / 8) + 1
|
||||
};
|
||||
assign meh = twentyone % 8 + 1;
|
||||
// verilator lint_on WIDTH
|
||||
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$display("param: %d, %d, %b, %d", param._foo, param._bar, param, meh);
|
||||
`endif
|
||||
if (param._foo != 6) $stop;
|
||||
if (param._bar != 3) $stop;
|
||||
if (param != 6'b110011) $stop;
|
||||
if (meh != 6) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user