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**
|
* 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 --inhibit-sim flag for environments using old __Vm_inhibitSim.
|
||||||
|
|
||||||
*** Added `systemc_dtor for destructor extentions. [Allan Cochrane]
|
*** Added `systemc_dtor for destructor extentions. [Allan Cochrane]
|
||||||
|
|
||||||
*** Added -MP to make phony dependencies, ala GCC's.
|
*** 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 memory leak when destroying modules. [John Stroebel]
|
||||||
|
|
||||||
**** Fix $display %m name not matching Verilog name inside SystemC modules.
|
**** 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.
|
** Support dotted cross-hierarchy variable and task references.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ private:
|
||||||
bodysp = newFireAssert(nodep,message);
|
bodysp = newFireAssert(nodep,message);
|
||||||
// We assert the property is always true... so report when it fails
|
// We assert the property is always true... so report when it fails
|
||||||
// (Note this is opposite the behavior of coverage statements.)
|
// (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);
|
propp = new AstLogNot (nodep->fileline(), propp);
|
||||||
} else {
|
} else {
|
||||||
nodep->v3fatalSrc("Unknown node type");
|
nodep->v3fatalSrc("Unknown node type");
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,31 @@
|
||||||
#include "V3Dead.h"
|
#include "V3Dead.h"
|
||||||
#include "V3Ast.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
|
// Dead state, as a visitor of each AstNode
|
||||||
|
|
||||||
|
|
@ -46,8 +71,8 @@ private:
|
||||||
// AstVarScope::user() -> int. Count of number of references
|
// AstVarScope::user() -> int. Count of number of references
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
vector<AstVar*> m_varsp; // 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 three
|
vector<AstVarScope*> m_vscsp; // List of all encountered to avoid another loop through tree
|
||||||
bool m_elimUserVars; // Allow removal of user's vars
|
bool m_elimUserVars; // Allow removal of user's vars
|
||||||
//int debug() { return 9; }
|
//int debug() { return 9; }
|
||||||
|
|
||||||
|
|
@ -85,6 +110,8 @@ private:
|
||||||
// METHODS
|
// METHODS
|
||||||
void deadCheckMod() {
|
void deadCheckMod() {
|
||||||
// Kill any unused modules
|
// 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; ) {
|
for (bool retry=true; retry; ) {
|
||||||
retry=false;
|
retry=false;
|
||||||
AstModule* nextmodp;
|
AstModule* nextmodp;
|
||||||
|
|
@ -93,14 +120,11 @@ private:
|
||||||
if (modp->level()>2 && modp->user()==0) {
|
if (modp->level()>2 && modp->user()==0) {
|
||||||
// > 2 because L1 is the wrapper, L2 is the top user module
|
// > 2 because L1 is the wrapper, L2 is the top user module
|
||||||
UINFO(4," Dead module "<<modp<<endl);
|
UINFO(4," Dead module "<<modp<<endl);
|
||||||
// And its children may now be killable too....
|
// And its children may now be killable too; correct counts
|
||||||
for (AstNode* nodep = modp->stmtsp(); nodep; nodep=nodep->nextp()) {
|
// Recurse, as cells may not be directly under the module but in a generate
|
||||||
if (AstCell* cellp=nodep->castCell()) {
|
DeadModVisitor visitor(modp);
|
||||||
cellp->modp()->user( cellp->modp()->user() - 1);
|
|
||||||
retry = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
modp->unlinkFrBack()->deleteTree(); modp=NULL;
|
modp->unlinkFrBack()->deleteTree(); modp=NULL;
|
||||||
|
retry = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,8 +286,14 @@ void process () {
|
||||||
if (v3Global.opt.oGate()) {
|
if (v3Global.opt.oGate()) {
|
||||||
V3Gate::gateAll(v3Global.rootp());
|
V3Gate::gateAll(v3Global.rootp());
|
||||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("gate.tree"));
|
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
|
// Reorder assignments in pipelined blocks
|
||||||
if (v3Global.opt.oReorder()) {
|
if (v3Global.opt.oReorder()) {
|
||||||
V3Split::splitReorderAll(v3Global.rootp());
|
V3Split::splitReorderAll(v3Global.rootp());
|
||||||
|
|
@ -333,7 +339,7 @@ void process () {
|
||||||
|
|
||||||
// Remove unused vars
|
// Remove unused vars
|
||||||
V3Const::constifyAll(v3Global.rootp());
|
V3Const::constifyAll(v3Global.rootp());
|
||||||
V3Dead::deadifyAll(v3Global.rootp(), false);
|
V3Dead::deadifyAll(v3Global.rootp(), true);
|
||||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("const.tree"));
|
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("const.tree"));
|
||||||
|
|
||||||
#ifndef NEW_ORDERING
|
#ifndef NEW_ORDERING
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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