mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 12:17:35 +00:00
Add `systemc_dtor option
git-svn-id: file://localhost/svn/verilator/trunk/verilator@767 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
6358b7f1a3
commit
c82235a2de
2
Changes
2
Changes
@ -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
4
TODO
@ -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?)
|
||||
|
@ -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
|
||||
|
@ -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) {}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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); }
|
||||
|
@ -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
18
test_regress/t/t_extend.pl
Executable 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;
|
@ -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
|
||||
|
10
test_v/t.v
10
test_v/t.v
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user