From 7163c8d04838d32fe3762b683c8511d1f24e13a8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 18 Sep 2015 20:57:27 -0400 Subject: [PATCH] Fix internal error on dotted refs into generates, bug958. --- Changes | 2 ++ src/V3Broken.cpp | 13 +++++++--- src/V3Param.cpp | 3 +++ test_regress/t/t_var_xref_gen.pl | 15 +++++++++++ test_regress/t/t_var_xref_gen.v | 43 ++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_var_xref_gen.pl create mode 100644 test_regress/t/t_var_xref_gen.v diff --git a/Changes b/Changes index 179e4abeb..9cd7d5638 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.877 devel +**** Fix internal error on dotted refs into generates, bug958. [Jie Xu] + **** Fix mis-optimizing public DPI functions, bug963. [Wei Song] diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index 723e840b5..abc7fee87 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -186,11 +186,15 @@ private: // NODE STATE // Nothing! // This may be called deep inside other routines // // so userp and friends may not be used - // VISITORS - virtual void visit(AstNode* nodep, AstNUser*) { + // METHODS + void processAndIterate(AstNode* nodep) { BrokenTable::addInTree(nodep, nodep->maybePointedTo()); nodep->iterateChildrenConst(*this); } + // VISITORS + virtual void visit(AstNode* nodep, AstNUser*) { + processAndIterate(nodep); + } public: // CONSTUCTORS BrokenMarkVisitor(AstNetlist* nodep) { @@ -210,7 +214,7 @@ private: nodep->v3fatalSrc("Width != WidthMin"); } } - virtual void visit(AstNode* nodep, AstNUser*) { + void processAndIterate(AstNode* nodep) { BrokenTable::setUnder(nodep,true); if (const char* whyp=nodep->broken()) { nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<iterateChildrenConst(*this); BrokenTable::setUnder(nodep,false); } + virtual void visit(AstNode* nodep, AstNUser*) { + processAndIterate(nodep); + } public: // CONSTUCTORS BrokenCheckVisitor(AstNetlist* nodep) { diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 5948d3bd4..ee06aea77 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -248,6 +248,9 @@ private: virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varp()) nodep->varp()->iterate(*this); } + virtual void visit(AstVarXRef* nodep, AstNUser*) { + nodep->varp(NULL); // Needs relink, as may remove pointed-to var + } // Generate Statements virtual void visit(AstGenerate* nodep, AstNUser*) { diff --git a/test_regress/t/t_var_xref_gen.pl b/test_regress/t/t_var_xref_gen.pl new file mode 100755 index 000000000..d0b997efb --- /dev/null +++ b/test_regress/t/t_var_xref_gen.pl @@ -0,0 +1,15 @@ +#!/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 ( + verilator_flags2 => ["--debug-check"], + ); + +ok(1); +1; diff --git a/test_regress/t/t_var_xref_gen.v b/test_regress/t/t_var_xref_gen.v new file mode 100644 index 000000000..ac15a246f --- /dev/null +++ b/test_regress/t/t_var_xref_gen.v @@ -0,0 +1,43 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This is to test the handling of VarXRef when the referenced VAR is +// under a generate construction. +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Jie Xu and Roland Kruse. + +module t (/*AUTOARG*/ + // Inputs + clk, addr, res + ); + + input clk; + + input [31:0] addr; + output [15:0] res; + + memory i_mem(.addr(addr),.dout(res)); + + assign i_mem.cxrow_inst[0].cmem_xrow[0] = 16'h0; + +endmodule + + + +module memory(addr, dout); + parameter CM_XROWSIZE = 256; + parameter CM_NUMXROWS = 2; + + input [31:0] addr; + output [15:0] dout; + + generate + genvar g_cx; + for (g_cx = 0; g_cx < CM_NUMXROWS; g_cx++) + begin: cxrow_inst + reg [15:0] cmem_xrow[0:CM_XROWSIZE - 1]; + end + endgenerate + + assign dout = cxrow_inst[0].cmem_xrow[addr]; +endmodule