mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 12:17:35 +00:00
Fix dead modules under generate cells not getting removed
git-svn-id: file://localhost/svn/verilator/trunk/verilator@773 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
fe99abeccc
commit
7f1b16837e
11
Changes
11
Changes
@ -5,21 +5,24 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.60**
|
||||
|
||||
*** Changed how internal functions are invoked to avoid aliasing in GCC 3.3+.
|
||||
|
||||
*** Added --inhibit-sim flag for environments using old __Vm_inhibitSim.
|
||||
|
||||
*** Added `systemc_dtor for destructor extentions. [Allan Cochrane]
|
||||
|
||||
*** Added -MP to make phony dependencies, ala GCC's.
|
||||
|
||||
**** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate.
|
||||
*** Changed how internal functions are invoked to reduce aliasing.
|
||||
Useful when using GCC's -O2 or -fstrict-aliasing, to gain another ~4%.
|
||||
|
||||
**** Fix coredump when unused modules have unused cells. [David Hewson]
|
||||
|
||||
**** Fix memory leak when destroying modules. [John Stroebel]
|
||||
|
||||
**** Fix $display %m name not matching Verilog name inside SystemC modules.
|
||||
|
||||
* Verilator 3.600 08/28/2006
|
||||
**** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate.
|
||||
|
||||
* Verilator 3.600 08/28/2006 Beta
|
||||
|
||||
** Support dotted cross-hierarchy variable and task references.
|
||||
|
||||
|
@ -88,7 +88,7 @@ private:
|
||||
bodysp = newFireAssert(nodep,message);
|
||||
// We assert the property is always true... so report when it fails
|
||||
// (Note this is opposite the behavior of coverage statements.)
|
||||
//FIX 'never' operator: not hold in current or any future cycle
|
||||
// Need: 'never' operator: not hold in current or any future cycle
|
||||
propp = new AstLogNot (nodep->fileline(), propp);
|
||||
} else {
|
||||
nodep->v3fatalSrc("Unknown node type");
|
||||
|
@ -34,6 +34,31 @@
|
||||
#include "V3Dead.h"
|
||||
#include "V3Ast.h"
|
||||
|
||||
//######################################################################
|
||||
|
||||
class DeadModVisitor : public AstNVisitor {
|
||||
// In a module that is dead, cleanup the in-use counts of the modules
|
||||
private:
|
||||
// NODE STATE
|
||||
// ** Shared with DeadVisitor **
|
||||
// VISITORS
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->modp()->user(nodep->modp()->user() - 1);
|
||||
}
|
||||
//-----
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
DeadModVisitor(AstModule* nodep) {
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~DeadModVisitor() {}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Dead state, as a visitor of each AstNode
|
||||
|
||||
@ -46,8 +71,8 @@ private:
|
||||
// AstVarScope::user() -> int. Count of number of references
|
||||
|
||||
// STATE
|
||||
vector<AstVar*> m_varsp; // List of all encountered to avoid another loop through three
|
||||
vector<AstVarScope*> m_vscsp; // List of all encountered to avoid another loop through three
|
||||
vector<AstVar*> m_varsp; // List of all encountered to avoid another loop through tree
|
||||
vector<AstVarScope*> m_vscsp; // List of all encountered to avoid another loop through tree
|
||||
bool m_elimUserVars; // Allow removal of user's vars
|
||||
//int debug() { return 9; }
|
||||
|
||||
@ -85,6 +110,8 @@ private:
|
||||
// METHODS
|
||||
void deadCheckMod() {
|
||||
// Kill any unused modules
|
||||
// V3LinkCells has a graph that is capable of this too, but we need to do it
|
||||
// after we've done all the generate blocks
|
||||
for (bool retry=true; retry; ) {
|
||||
retry=false;
|
||||
AstModule* nextmodp;
|
||||
@ -93,14 +120,11 @@ private:
|
||||
if (modp->level()>2 && modp->user()==0) {
|
||||
// > 2 because L1 is the wrapper, L2 is the top user module
|
||||
UINFO(4," Dead module "<<modp<<endl);
|
||||
// And its children may now be killable too....
|
||||
for (AstNode* nodep = modp->stmtsp(); nodep; nodep=nodep->nextp()) {
|
||||
if (AstCell* cellp=nodep->castCell()) {
|
||||
cellp->modp()->user( cellp->modp()->user() - 1);
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
// And its children may now be killable too; correct counts
|
||||
// Recurse, as cells may not be directly under the module but in a generate
|
||||
DeadModVisitor visitor(modp);
|
||||
modp->unlinkFrBack()->deleteTree(); modp=NULL;
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -286,8 +286,14 @@ void process () {
|
||||
if (v3Global.opt.oGate()) {
|
||||
V3Gate::gateAll(v3Global.rootp());
|
||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("gate.tree"));
|
||||
// V3Gate calls constant propagation itself.
|
||||
}
|
||||
|
||||
// Remove unused vars
|
||||
V3Const::constifyAll(v3Global.rootp());
|
||||
V3Dead::deadifyAll(v3Global.rootp(), true);
|
||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("const.tree"));
|
||||
|
||||
// Reorder assignments in pipelined blocks
|
||||
if (v3Global.opt.oReorder()) {
|
||||
V3Split::splitReorderAll(v3Global.rootp());
|
||||
@ -333,7 +339,7 @@ void process () {
|
||||
|
||||
// Remove unused vars
|
||||
V3Const::constifyAll(v3Global.rootp());
|
||||
V3Dead::deadifyAll(v3Global.rootp(), false);
|
||||
V3Dead::deadifyAll(v3Global.rootp(), true);
|
||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("const.tree"));
|
||||
|
||||
#ifndef NEW_ORDERING
|
||||
|
19
test_regress/t/t_func_lib.pl
Executable file
19
test_regress/t/t_func_lib.pl
Executable file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# 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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ['-v', 't/t_func_lib_sub.v'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
13
test_regress/t/t_func_lib.v
Normal file
13
test_regress/t/t_func_lib.v
Normal file
@ -0,0 +1,13 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003-2006 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
101
test_regress/t/t_func_lib_sub.v
Normal file
101
test_regress/t/t_func_lib_sub.v
Normal file
@ -0,0 +1,101 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003-2006 by Wilson Snyder.
|
||||
|
||||
`define zednkw 200
|
||||
|
||||
module BreadAddrDP (zfghtn, cjtmau, knquim, kqxkkr);
|
||||
input zfghtn;
|
||||
input [4:0] cjtmau;
|
||||
input vipmpg;
|
||||
input [7:0] knquim;
|
||||
input [7:0] kqxkkr;
|
||||
|
||||
reg covfok;
|
||||
|
||||
reg [15:0] xwieqw;
|
||||
reg [2:0] ofnjjt;
|
||||
|
||||
reg [37:0] hdsejo[0:1];
|
||||
|
||||
reg wxxzgd, tceppr, ratebp, fjizkr, iwwrnq;
|
||||
reg vrqrih, ryyjxy;
|
||||
reg fgzsox;
|
||||
|
||||
wire xdjikl = ~wxxzgd & ~tceppr & ~ratebp & fjizkr;
|
||||
wire iytyol = ~wxxzgd & ~tceppr & ratebp & ~fjizkr & ~xwieqw[10];
|
||||
wire dywooz = ~wxxzgd & ~tceppr & ratebp & ~fjizkr & xwieqw[10];
|
||||
wire qnpfus = ~wxxzgd & ~tceppr & ratebp & fjizkr;
|
||||
wire fqlkrg = ~wxxzgd & tceppr & ~ratebp & ~fjizkr;
|
||||
|
||||
wire ktsveg = hdsejo[0][6] | (hdsejo[0][37:34] == 4'h1);
|
||||
wire smxixw = vrqrih | (ryyjxy & ktsveg);
|
||||
|
||||
wire [7:0] grvsrs, kyxrft, uxhkka;
|
||||
|
||||
wire [7:0] eianuv = 8'h01 << ofnjjt;
|
||||
wire [7:0] jvpnxn = {8{qnpfus}} & eianuv;
|
||||
wire [7:0] zlnzlj = {8{fqlkrg}} & eianuv;
|
||||
wire [7:0] nahzat = {8{iytyol}} & eianuv;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0;i<8;i=i+1)
|
||||
begin : dnlpyw
|
||||
DecCountReg4 bzpytc (zfghtn, fgzsox, zlnzlj[i],
|
||||
knquim[3:0], covfok, grvsrs[i]);
|
||||
DecCountReg4 oghukp (zfghtn, fgzsox, zlnzlj[i],
|
||||
knquim[7:4], covfok, kyxrft[i]);
|
||||
DecCountReg4 ttvjoo (zfghtn, fgzsox, nahzat[i],
|
||||
kqxkkr[3:0], covfok, uxhkka[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
module DecCountReg4 (clk, fgzsox, fckiyr, uezcjy, covfok, juvlsh);
|
||||
input clk, fgzsox, fckiyr, covfok;
|
||||
input [3:0] uezcjy;
|
||||
output juvlsh;
|
||||
|
||||
task Xinit;
|
||||
begin
|
||||
`ifdef TEST_HARNESS
|
||||
khgawe = 1'b0;
|
||||
`endif
|
||||
end
|
||||
endtask
|
||||
function X;
|
||||
input vrdejo;
|
||||
begin
|
||||
`ifdef TEST_HARNESS
|
||||
if ((vrdejo & ~vrdejo) !== 1'h0) khgawe = 1'b1;
|
||||
`endif
|
||||
X = vrdejo;
|
||||
end
|
||||
endfunction
|
||||
task Xcheck;
|
||||
input vzpwwy;
|
||||
begin
|
||||
end
|
||||
endtask
|
||||
|
||||
reg [3:0] udbvtl;
|
||||
|
||||
assign juvlsh = |udbvtl;
|
||||
wire [3:0] mppedc = {4{fgzsox}} & (fckiyr ? uezcjy : (udbvtl - 4'h1));
|
||||
|
||||
wire qqibou = ((juvlsh | fckiyr) & covfok) | ~fgzsox;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
Xinit;
|
||||
if (X(qqibou))
|
||||
udbvtl <= #`zednkw mppedc;
|
||||
|
||||
Xcheck(fgzsox);
|
||||
end
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user