Add `systemc_dtor option

git-svn-id: file://localhost/svn/verilator/trunk/verilator@767 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
Wilson Snyder 2006-08-30 17:27:53 +00:00
parent 6358b7f1a3
commit c82235a2de
12 changed files with 128 additions and 67 deletions

View File

@ -7,6 +7,8 @@ indicates the contributor was also the author of the fix; Thanks!
*** Added --inhibit-sim flag for environments using old __Vm_inhibitSim.
*** Added `systemc_dtor for destructor extentions. [Allan Cochrane]
**** Declare tables static, to reduce D-Cache miss rate.
**** Fix $display %m name not matching Verilog name inside SystemC modules.

4
TODO
View File

@ -22,7 +22,9 @@ Features:
Selectable SystemC types based on widths (see notes below)
Compile time
Inline first level trace routines
Expression coverage (see notes)
Coverage
Points should be per-scope like everything else rather then per-module
Expression coverage (see notes)
More Verilog 2001 Support
C-style function and task arguments. [Wim Michiels]
(* *) Attributes (just ignore -- preprocessor?)

View File

@ -357,8 +357,8 @@ C++ file exceeds the specified number of operations, a new file will be
created. In addition, any slow routines will be placed into __Slow files.
This accelerates compilation by as optimization can be disabled on the slow
routines, and the remaining files can be compiled on parallel machines.
With GCC 3.3 on Opteron, --output-split 20000 will result in splitting into
approximately one-minute-compile chunks.
With GCC 3.3 on a 2GHz Opteron, --output-split 20000 will result in
splitting into approximately one-minute-compile chunks.
=item --pins64
@ -963,6 +963,12 @@ Take remaining text up to the next `verilog or `systemc_... mode switch and
place it verbatim into the C++ class constructor. Despite the name of this
macro, this also works in pure C++ code.
=item `systemc_dtor
Take remaining text up to the next `verilog or `systemc_... mode switch and
place it verbatim into the C++ class destructor. Despite the name of this
macro, this also works in pure C++ code.
=item `systemc_interface
Take remaining text up to the next `verilog or `systemc_... mode switch and

View File

@ -2647,6 +2647,17 @@ struct AstScCtor : public AstNodeText {
virtual bool isOutputter() const { return true; }
};
struct AstScDtor : public AstNodeText {
AstScDtor(FileLine* fl, const string& textp)
: AstNodeText(fl, textp) {}
virtual ~AstScDtor() {}
virtual AstType type() const { return AstType::SCDTOR;}
virtual AstNode* clone() { return new AstScDtor(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual bool isSplittable() const { return false; } // SPECIAL: User may order w/other sigs
virtual bool isOutputter() const { return true; }
};
struct AstScHdr : public AstNodeText {
AstScHdr(FileLine* fl, const string& textp)
: AstNodeText(fl, textp) {}

View File

@ -660,9 +660,11 @@ class EmitCImp : EmitCStmts {
void emitCellCtors(AstModule* modp);
void emitSensitives();
// Medium level
void emitCoverageCtor(AstModule* modp);
void emitCtorImp(AstModule* modp);
void emitConfigureImp(AstModule* modp);
void emitCoverageDecl(AstModule* modp);
void emitCoverageImp(AstModule* modp);
void emitDestructorImp(AstModule* modp);
void emitTextSection(AstType type);
void emitIntFuncDecls(AstModule* modp);
// High level
@ -1087,19 +1089,6 @@ void EmitCImp::emitVarResets(AstModule* modp) {
}
}
void EmitCImp::emitCoverageCtor(AstModule* modp) {
bool first=true;
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (nodep->castCoverDecl()) {
if (first) {
first = false;
puts("// Coverage Declarations\n");
}
nodep->accept(*this);
}
}
}
void EmitCImp::emitCoverageDecl(AstModule* modp) {
m_coverIds.clear();
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
@ -1117,6 +1106,42 @@ void EmitCImp::emitCoverageDecl(AstModule* modp) {
}
}
void EmitCImp::emitCtorImp(AstModule* modp) {
puts("\n");
if (optSystemPerl() && modp->isTop()) {
puts("SP_CTOR_IMP("+modClassName(modp)+")");
} else if (optSystemC() && modp->isTop()) {
puts("VL_SC_CTOR_IMP("+modClassName(modp)+")");
} else {
puts("VL_CTOR_IMP("+modClassName(modp)+")");
}
emitVarCtors();
puts(" {\n");
emitCellCtors(modp);
emitSensitives();
emitVarResets(modp);
emitTextSection(AstType::SCCTOR);
if (optSystemPerl()) puts("SP_AUTO_CTOR;\n");
puts("}\n");
}
void EmitCImp::emitConfigureImp(AstModule* modp) {
puts("\nvoid "+modClassName(modp)+"::__Vconfigure("+symClassName()+"* symsp) {\n");
puts( "__VlSymsp = symsp;\n"); // First, as later stuff needs it.
bool first=true;
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (nodep->castCoverDecl()) {
if (first) {
first = false;
puts("// Coverage Declarations\n");
}
nodep->accept(*this);
}
}
puts("}\n");
}
void EmitCImp::emitCoverageImp(AstModule* modp) {
if (m_coverIds.size()) {
puts("\n// Coverage\n");
@ -1136,6 +1161,14 @@ void EmitCImp::emitCoverageImp(AstModule* modp) {
}
}
void EmitCImp::emitDestructorImp(AstModule* modp) {
puts("\n");
puts(modClassName(modp)+"::~"+modClassName(modp)+"() {\n");
emitTextSection(AstType::SCDTOR);
if (modp->isTop()) puts("delete __VlSymsp; __VlSymsp=NULL;\n");
puts("}\n");
}
void EmitCImp::emitStaticDecl(AstModule* modp) {
// Need implementation here. Be careful of alignment code; needs to be uniquified
// with module name to avoid multiple symbols.
@ -1419,10 +1452,13 @@ void EmitCImp::emitInt(AstModule* modp) {
ofp()->putsPrivate(false); // public:
if (optSystemC() && modp->isTop()) {
puts("SC_CTOR("+modClassName(modp)+");\n");
puts("virtual ~"+modClassName(modp)+"();\n");
} else if (optSystemC()) {
puts("VL_CTOR("+modClassName(modp)+");\n");
puts("~"+modClassName(modp)+"();\n");
} else {
puts(modClassName(modp)+"(const char* name=\"TOP\");\n");
puts("~"+modClassName(modp)+"();\n");
if (v3Global.opt.trace()) {
puts("void\ttrace (SpTraceVcdCFile* tfp, int levels, int options=0);\n");
}
@ -1511,34 +1547,14 @@ void EmitCImp::emitImp(AstModule* modp) {
emitStaticDecl(modp);
}
// Constructor
if (m_slow && m_splitFilenum==0) {
puts("\n//--------------------\n");
puts("\n");
if (optSystemPerl() && modp->isTop()) {
puts("SP_CTOR_IMP("+modClassName(modp)+")");
} else if (optSystemC() && modp->isTop()) {
puts("VL_SC_CTOR_IMP("+modClassName(modp)+")");
} else {
puts("VL_CTOR_IMP("+modClassName(modp)+")");
}
emitVarCtors();
puts(" {\n");
emitCellCtors(modp);
emitSensitives();
emitVarResets(modp);
emitTextSection(AstType::SCCTOR);
if (optSystemPerl()) puts("SP_AUTO_CTOR;\n");
puts("}\n");
puts("\nvoid "+modClassName(m_modp)+"::__Vconfigure("+symClassName()+"* symsp) {\n");
puts( "__VlSymsp = symsp;\n"); // First, as later stuff needs it.
emitCoverageCtor(modp);
puts("}\n");
emitCtorImp(modp);
emitConfigureImp(modp);
emitDestructorImp(modp);
emitCoverageImp(modp);
}
if (m_fast && m_splitFilenum==0) {
if (modp->isTop()) {
emitStaticDecl(modp);

View File

@ -366,6 +366,11 @@ private:
m_modp->modPublic(true);
nodep->iterateChildren(*this);
}
virtual void visit(AstScDtor* nodep, AstNUser*) {
// Destructor info means the module must remain public
m_modp->modPublic(true);
nodep->iterateChildren(*this);
}
virtual void visit(AstScInt* nodep, AstNUser*) {
// Special class info means the module must remain public
m_modp->modPublic(true);

View File

@ -88,7 +88,7 @@ void yyerrorf(const char* format, ...) {
%a 15000
%o 25000
%s VLG PSL STRING SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR IGNORE
%s VLG PSL STRING SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR IGNORE
ws [ \t\f\r]+
/* identifier */
@ -537,24 +537,28 @@ escid \\[^ \t\f\r\n]+
/************************************************************************/
/* Common for all SYSC header states */
/* OPTIMIZE: we return one per line, make it one for the entire block */
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>[ \t]*"`verilog" { BEGIN VLG; }
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>[ \t]*"`psl" { if (V3Read::optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } }
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>[ \t]*"`systemc_header" { BEGIN SYSCHDR; }
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>[ \t]*"`systemc_ctor" { BEGIN SYSCCTOR; }
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>[ \t]*"`systemc_interface" { BEGIN SYSCINT; }
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>[ \t]*"`systemc_implementation" { BEGIN SYSCIMP; }
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>[ \t]*"`systemc_imp_header" { BEGIN SYSCIMPH; }
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>"`line"[ \t][^\n]*\n {V3Read::ppline(yytext);}
<VLG,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
[ \t]*"`verilog" { BEGIN VLG; }
[ \t]*"`psl" { if (V3Read::optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } }
[ \t]*"`systemc_header" { BEGIN SYSCHDR; }
[ \t]*"`systemc_ctor" { BEGIN SYSCCTOR; }
[ \t]*"`systemc_dtor" { BEGIN SYSCDTOR; }
[ \t]*"`systemc_interface" { BEGIN SYSCINT; }
[ \t]*"`systemc_implementation" { BEGIN SYSCIMP; }
[ \t]*"`systemc_imp_header" { BEGIN SYSCIMPH; }
"`line"[ \t][^\n]*\n {V3Read::ppline(yytext);}
}
<SYSCHDR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCHDR;}
<SYSCINT>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCINT;}
<SYSCIMP>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCIMP;}
<SYSCIMPH>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCIMPH;}
<SYSCCTOR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCCTOR;}
<SYSCDTOR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCDTOR;}
<IGNORE>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); }
<SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>[ \t]*\n { NEXTLINE(); yymore();}
<SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,IGNORE>\r ;
<SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>[ \t]*\n { NEXTLINE(); yymore();}
<SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>\r ;
/************************************************************************/
/* Default rules - leave last */

View File

@ -125,7 +125,7 @@ class AstSenTree;
%token<nump> yINTNUM
%token<cdouble> yFLOATNUM
%token<strp> yID ySTRING
%token<strp> ySCHDR ySCINT ySCIMP ySCIMPH ySCCTOR
%token<strp> ySCHDR ySCINT ySCIMP ySCIMPH ySCCTOR ySCDTOR
%token<fileline> yMODULE yENDMODULE yALWAYS yINITIAL yPOSEDGE yNEGEDGE yBBEGIN yBEND yOR
%token<fileline> yINPUT yOUTPUT yINOUT yWIRE yTRI yREG yPARAM yLOCALPARAM yDEFPARAM
%token<fileline> yFUNCTION yENDFUNCTION yTASK yENDTASK
@ -405,6 +405,7 @@ modItem: modOrGenItem { $$ = $1; }
| ySCIMP { $$ = new AstScImp(CRELINE(),*$1); }
| ySCIMPH { $$ = new AstScImpHdr(CRELINE(),*$1); }
| ySCCTOR { $$ = new AstScCtor(CRELINE(),*$1); }
| ySCDTOR { $$ = new AstScDtor(CRELINE(),*$1); }
| yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); }
| yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); }
| yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); }

View File

@ -572,6 +572,7 @@ sub _make_main {
print $fh " }\n";
print $fh " top->final();\n";
print $fh " SpCoverage::write(\"",$self->{coverage_filename},"\");\n" if $self->{coverage};
print $fh " delete top;\n";
print $fh " exit(0L);\n";
print $fh "}\n";
$fh->close();

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

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

View File

@ -2,11 +2,9 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
// without warranty, 2003-2006 by Wilson Snyder.
module t_extend (/*AUTOARG*/
// Outputs
passed,
module t (/*AUTOARG*/
// Inputs
clk
);
@ -14,7 +12,6 @@ module t_extend (/*AUTOARG*/
/*verilator public_module*/
input clk;
output passed; reg passed; initial passed = 0;
// No verilator_public needed, because it's outside the "" in the $c statement
reg [7:0] cyc; initial cyc=0;
reg c_worked;
@ -47,8 +44,7 @@ module t_extend (/*AUTOARG*/
if (cyc == 8'd3) begin
if (c_worked !== 1'b1) $stop;
if (c_wider !== 9'h10) $stop;
$write("[%0t] t_extend: Passed\n",$time);
passed <= 1'b1;
$finish;
end
end
@ -72,6 +68,9 @@ module t_extend (/*AUTOARG*/
#endif
`systemc_ctor
m_did_ctor = 1;
`systemc_dtor
printf("In systemc_dtor\n");
printf("*-* All Finished *-*\n");
`verilog
`endif

View File

@ -1,4 +1,4 @@
// $Id:$
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
@ -90,16 +90,12 @@ module t (/*AUTOARG*/
// Inputs
.clk (clk),
.fastclk (fastclk));
t_extend textend
t_loop tloop
(.passed (passedv[15]),
/*AUTOINST*/
// Inputs
.clk (clk));
t_loop tloop
(.passed (passedv[16]),
/*AUTOINST*/
// Inputs
.clk (clk));
assign passedv[16] = 1'b1;
assign passedv[17] = 1'b1;
assign passedv[18] = 1'b1;
t_task ttask