mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 12:17:35 +00:00
Make display %m name() calls relative to vlsyms
git-svn-id: file://localhost/svn/verilator/trunk/verilator@766 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
268f0544be
commit
6358b7f1a3
2
Changes
2
Changes
@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
**** Declare tables static, to reduce D-Cache miss rate.
|
||||
|
||||
**** Fix $display %m name not matching Verilog name inside SystemC modules.
|
||||
|
||||
* Verilator 3.600 08/28/2006
|
||||
|
||||
** Support dotted cross-hierarchy variable and task references.
|
||||
|
@ -202,7 +202,7 @@ public:
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
|
||||
puts("_vlCoverInsert("); // As Declared in emitCoverageDecl
|
||||
puts("__vlCoverInsert("); // As Declared in emitCoverageDecl
|
||||
puts("&__Vcoverage[");
|
||||
puts(cvtToStr(m_coverIds.remap(nodep))); puts("]");
|
||||
puts(", \""); puts(nodep->fileline()->filebasename()); puts("\"");
|
||||
@ -593,7 +593,7 @@ class EmitCImp : EmitCStmts {
|
||||
for (int i=0;i<m_modp->level();i++) { puts(" "); }
|
||||
puts(modClassName(m_modp)+"::"+nodep->name()
|
||||
+" \""
|
||||
+(optSystemC()?"<<name()":"")
|
||||
+"<<name()"
|
||||
+"<<endl; );\n");
|
||||
|
||||
if (nodep->initsp()) puts("// Variables\n");
|
||||
@ -662,6 +662,7 @@ class EmitCImp : EmitCStmts {
|
||||
// Medium level
|
||||
void emitCoverageCtor(AstModule* modp);
|
||||
void emitCoverageDecl(AstModule* modp);
|
||||
void emitCoverageImp(AstModule* modp);
|
||||
void emitTextSection(AstType type);
|
||||
void emitIntFuncDecls(AstModule* modp);
|
||||
// High level
|
||||
@ -987,7 +988,7 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
||||
case 't': displayArg(nodep,&elistp,fmt,'u'); break;
|
||||
case 'm': {
|
||||
emitDispState.pushFormat("%s");
|
||||
emitDispState.pushArg(NULL, "name(");
|
||||
emitDispState.pushArg(NULL, "__VlSymsp->name(");
|
||||
for (AstText* textp=nodep->scopeTextp(); textp; textp=textp->nextp()->castText()) {
|
||||
emitDispState.pushFormat(textp->text());
|
||||
}
|
||||
@ -1111,14 +1112,23 @@ void EmitCImp::emitCoverageDecl(AstModule* modp) {
|
||||
puts("// Coverage\n");
|
||||
puts("SpZeroed<uint32_t>\t__Vcoverage["); puts(cvtToStr(m_coverIds.size())); puts("];\n");
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint32_t)*m_coverIds.size());
|
||||
puts("void __vlCoverInsert(SpZeroed<uint32_t>* countp, const char* filename, int lineno, int column,\n");
|
||||
puts( "const char* hier, const char* type, const char* comment);\n");
|
||||
}
|
||||
}
|
||||
|
||||
void EmitCImp::emitCoverageImp(AstModule* modp) {
|
||||
if (m_coverIds.size()) {
|
||||
puts("\n// Coverage\n");
|
||||
// Rather then putting out SP_COVER_INSERT calls directly, we do it via this function
|
||||
// This gets around gcc slowness constructing all of the template arguments
|
||||
puts("void _vlCoverInsert(SpZeroed<uint32_t>* countp, const char* filename, int lineno, int column,\n");
|
||||
puts("void "+modClassName(m_modp)+"::__vlCoverInsert(SpZeroed<uint32_t>* countp, const char* filename, int lineno, int column,\n");
|
||||
puts( "const char* hier, const char* type, const char* comment) {\n");
|
||||
puts( "SP_COVER_INSERT(countp,");
|
||||
puts( " \"filename\",filename,");
|
||||
puts( " \"lineno\",lineno,");
|
||||
puts( " \"column\",column,\n");
|
||||
//puts( "\"hier\",string(__VlSymsp->name())+hier,"); // Need to move hier into scopes and back out if do this
|
||||
puts( "\"hier\",string(name())+hier,");
|
||||
puts( " \"type\",type,");
|
||||
puts( " \"comment\",comment);\n");
|
||||
@ -1157,7 +1167,8 @@ void EmitCImp::emitTextSection(AstType type) {
|
||||
|
||||
void EmitCImp::emitCellCtors(AstModule* modp) {
|
||||
if (modp->isTop()) {
|
||||
puts("__VlSymsp = new "+symClassName()+"(this);\n");
|
||||
// Must be before other constructors, as __vlCoverInsert calls it
|
||||
puts("__VlSymsp = new "+symClassName()+"(this, name());\n");
|
||||
}
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstCell* cellp=nodep->castCell()) {
|
||||
@ -1416,9 +1427,7 @@ void EmitCImp::emitInt(AstModule* modp) {
|
||||
puts("void\ttrace (SpTraceVcdCFile* tfp, int levels, int options=0);\n");
|
||||
}
|
||||
}
|
||||
if (!modp->isTop()) {
|
||||
puts("void\t__Vconfigure("+symClassName()+"*\tsymsp) { __VlSymsp = symsp; } ///< Internal symbol table construction\n");
|
||||
}
|
||||
puts("void\t__Vconfigure("+symClassName()+"* symsp);\n");
|
||||
if (optSystemPerl()) puts("/*AUTOMETHODS*/\n");
|
||||
|
||||
if (modp->isTop()) {
|
||||
@ -1519,10 +1528,16 @@ void EmitCImp::emitImp(AstModule* modp) {
|
||||
emitCellCtors(modp);
|
||||
emitSensitives();
|
||||
emitVarResets(modp);
|
||||
emitCoverageCtor(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");
|
||||
|
||||
emitCoverageImp(modp);
|
||||
}
|
||||
if (m_fast && m_splitFilenum==0) {
|
||||
if (modp->isTop()) {
|
||||
|
@ -123,7 +123,11 @@ void EmitCSyms::emitInt() {
|
||||
|
||||
puts("// STATIC STATE\n");
|
||||
puts("static "+symClassName()+"* s_thisp;\n");
|
||||
puts("\n// STATE\n");
|
||||
|
||||
puts("\n// LOCAL STATE\n");
|
||||
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
|
||||
|
||||
puts("\n// SUBCELL STATE\n");
|
||||
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
|
||||
AstScope* scopep = it->first; AstModule* modp = it->second;
|
||||
if (modp->isTop()) {
|
||||
@ -137,9 +141,9 @@ void EmitCSyms::emitInt() {
|
||||
}
|
||||
|
||||
puts("\n// CREATORS\n");
|
||||
puts(symClassName()+"("+topClassName()+"* topp);\n");
|
||||
puts(symClassName()+"("+topClassName()+"* topp, const char* namep);\n");
|
||||
puts((string)"~"+symClassName()+"() {};\n");
|
||||
puts("// METHODS\n");
|
||||
puts("\n// METHODS\n");
|
||||
puts("/// Called at top of each eval to setup global pointer to top-of-symbol table\n");
|
||||
puts((string)"inline static void init ("+symClassName()+"* symsp) {\n");
|
||||
puts("s_thisp = symsp;\n");
|
||||
@ -147,6 +151,7 @@ void EmitCSyms::emitInt() {
|
||||
puts((string)"inline static void init ("+topClassName()+"* topp) {\n");
|
||||
puts("s_thisp = topp->__VlSymsp;\n");
|
||||
puts("}\n");
|
||||
puts("inline const char* name() { return __Vm_namep; }\n");
|
||||
puts("\n");
|
||||
puts("};\n");
|
||||
puts("#endif /*guard*/\n");
|
||||
@ -171,9 +176,11 @@ void EmitCSyms::emitImp() {
|
||||
puts(symClassName()+"* "+symClassName()+"::s_thisp;\n");
|
||||
|
||||
puts("\n// FUNCTIONS\n");
|
||||
puts(symClassName()+"::"+symClassName()+"("+topClassName()+"* topp)\n");
|
||||
puts(symClassName()+"::"+symClassName()+"("+topClassName()+"* topp, const char* namep)\n");
|
||||
puts("\t// Setup locals\n");
|
||||
puts("\t: __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed
|
||||
puts("\t// Setup submodule names\n");
|
||||
char comma=':';
|
||||
char comma=',';
|
||||
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
|
||||
AstScope* scopep = it->first; AstModule* modp = it->second;
|
||||
if (modp->isTop()) {
|
||||
@ -207,7 +214,7 @@ void EmitCSyms::emitImp() {
|
||||
}
|
||||
}
|
||||
puts("// Setup each module's pointer back to symbol table (for public functions)\n");
|
||||
puts("TOPp->__VlSymsp = this;\n");
|
||||
puts("TOPp->__Vconfigure(this);\n");
|
||||
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
|
||||
AstScope* scopep = it->first; AstModule* modp = it->second;
|
||||
if (!modp->isTop()) {
|
||||
|
@ -197,6 +197,22 @@ private:
|
||||
nodep->taskp(NULL);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
if (nodep->name().find("%m") != string::npos) {
|
||||
string prefix = (string)(".")+m_scopep->prettyName();
|
||||
// TOP and above will be the user's name().
|
||||
// Note 'TOP.'is stripped by prettyName, but not 'TOP'.
|
||||
if (prefix != ".TOP") {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
}
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
// Scope that was made by this module for different cell;
|
||||
// Want to ignore blocks under it, so just do nothing
|
||||
|
@ -12,8 +12,10 @@ compile (
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
expect=>
|
||||
'\[0\] (%m|.*v): Hi'.quotemeta('
|
||||
expect=>quotemeta(
|
||||
'[0] In TOP.v: Hi
|
||||
[0] In TOP.v.sub
|
||||
[0] In TOP.v.sub2
|
||||
[0] %X=0c %D=12 %0X=c %0O=14 %B=001100
|
||||
[0] %x=0c %d=12 %0x=c %0o=14 %b=001100
|
||||
[0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100
|
||||
|
@ -10,9 +10,14 @@ module t;
|
||||
reg [31:0] str; initial str = "\000\277\021\n";
|
||||
reg [47:0] str2; initial str2 = "\000what!";
|
||||
reg [79:0] str3; initial str3 = "\000hmmm!1234";
|
||||
|
||||
sub sub ();
|
||||
sub2 sub2 ();
|
||||
|
||||
initial begin
|
||||
$write("[%0t] ", $time);
|
||||
$write("%m: Hi\n");
|
||||
$write("[%0t] In %m: Hi\n", $time);
|
||||
sub.write_m;
|
||||
sub2.write_m;
|
||||
|
||||
// Display formatting
|
||||
$display("[%0t] %%X=%X %%D=%D %%0X=%0X %%0O=%0O %%B=%B", $time,
|
||||
@ -32,8 +37,20 @@ module t;
|
||||
`ifndef nc // NC-Verilog 5.3 chokes on this test
|
||||
if (str !== 32'h00_bf_11_0a) $stop;
|
||||
`endif
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sub;
|
||||
task write_m;
|
||||
$write("[%0t] In %m\n", $time);
|
||||
endtask
|
||||
endmodule
|
||||
|
||||
module sub2;
|
||||
// verilator no_inline_module
|
||||
task write_m;
|
||||
$write("[%0t] In %m\n", $time);
|
||||
endtask
|
||||
endmodule
|
||||
|
@ -20,9 +20,9 @@ PWD := $(shell pwd)
|
||||
DEBUG_ON = --debug --trace-dups --output-split 100
|
||||
|
||||
######################################################################
|
||||
default: prep preproc compile run coverage
|
||||
debug: prep_dbg preproc compile run coverage
|
||||
nopublic: prep_dbg_np preproc compile run coverage
|
||||
default: prep preproc compile run coverage
|
||||
debug: prep_dbg preproc compile_dbg run coverage
|
||||
nopublic: prep_dbg_np preproc compile_dbg run coverage
|
||||
|
||||
V_FLAGS = -f $(PWD)/../test_v/input.vc
|
||||
VERILATOR_FLAGS = --public --sp --coverage --stats --trace $(V_FLAGS) top.v
|
||||
@ -38,7 +38,10 @@ preproc:
|
||||
cd obj_dir ; $(MAKE) -j 1 -f ../Makefile_obj preproc
|
||||
|
||||
compile:
|
||||
cd obj_dir ; $(MAKE) -j 3 -f ../Makefile_obj
|
||||
cd obj_dir ; $(MAKE) -j 3 -f ../Makefile_obj
|
||||
|
||||
compile_dbg:
|
||||
cd obj_dir ; $(MAKE) OPT=-g -j 3 -f ../Makefile_obj
|
||||
|
||||
run:
|
||||
obj_dir/simx
|
||||
|
@ -20,6 +20,7 @@ include Vtop.mk
|
||||
CPPFLAGS += -DUTIL_PRINTF=sp_log_printf
|
||||
CPPFLAGS += -Wno-deprecated
|
||||
CPPFLAGS += $(SYSTEMC_CXX_FLAGS)
|
||||
CPPFLAGS += $(OPT)
|
||||
|
||||
LDFLAGS += $(SYSTEMC_CXX_FLAGS)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user