Fix escaped identifiers with '.' causing conflicts, bug83.

This commit is contained in:
Wilson Snyder 2009-05-08 13:16:19 -04:00
parent 4569278c53
commit a3e463030d
11 changed files with 91 additions and 47 deletions

View File

@ -7,6 +7,11 @@ indicates the contributor was also the author of the fix; Thanks!
** Verilator is now licensed under LGPL v3 and/or Artistic v2.0.
**** The front end parser has been re-factored to enable more SV parsing.
Code should parse the same, but minor parsing bugs may pop up now.
**** Fix escaped identifiers with '.' causing conflicts, bug83. [J Baxter]
* Verilator 3.703 2009/05/02
*** Fix $clog2 calculation error with powers-of-2, bug81. [Patricio Kaplan]

View File

@ -86,9 +86,9 @@ void AstNode::init() {
}
string AstNode::encodeName(const string& namein) {
string name2 = namein;
// Encode signal name raw from parser, then not called again on same signal
const char* start = namein.c_str();
string out;
const char* start = name2.c_str();
for (const char* pos = start; *pos; pos++) {
if ((pos==start) ? isalpha(pos[0]) // digits can't lead identifiers
: isalnum(pos[0])) {
@ -100,17 +100,13 @@ string AstNode::encodeName(const string& namein) {
} else {
out += pos[0];
}
} else if (pos[0]=='.') {
out += "__DOT__";
} else if (pos[0]=='[') {
out += "__BRA__";
} else if (pos[0]==']') {
out += "__KET__";
} else {
// Need the leading 0 so this will never collide with
// a user identifier nor a temp we create in Verilator.
char hex[10]; sprintf(hex,"%02X",pos[0]);
out += "__0"; out += hex;
// We also do *NOT* use __DOT__ etc, as we search for those
// in some replacements, and don't want to mangle the user's names.
char hex[10]; sprintf(hex,"__0%02X",pos[0]);
out += hex;
}
}
return out;
@ -145,9 +141,8 @@ string AstNode::dedotName(const string& namein) {
string AstNode::prettyName(const string& namein) {
string pretty;
string name2 = namein;
pretty = "";
for (const char* pos = name2.c_str(); *pos; ) {
for (const char* pos = namein.c_str(); *pos; ) {
if (0==strncmp(pos,"__BRA__",7)) {
pretty += "[";
pos += 7;

View File

@ -207,12 +207,12 @@ public:
// hiearchies itself, and if SystemPerl also did it, you'd end up
// with (number-of-instant) times too many counts in this bin.
puts(", first"); // Enable, passed from __Vconfigure parameter
puts(", \""); puts(nodep->fileline()->filename()); puts("\"");
puts(", "); putsQuoted(nodep->fileline()->filename());
puts(", "); puts(cvtToStr(nodep->fileline()->lineno()));
puts(", "); puts(cvtToStr(nodep->column()));
puts(", \""); puts((nodep->hier()!=""?".":"")+nodep->hier()); puts("\"");
puts(", \""); puts(nodep->page()); puts("\"");
puts(", \""); puts(nodep->comment()); puts("\"");
puts(", "); putsQuoted((nodep->hier()!=""?".":"")+nodep->hier());
puts(", "); putsQuoted(nodep->page());
puts(", "); putsQuoted(nodep->comment());
puts(");\n");
}
virtual void visit(AstCoverInc* nodep, AstNUser*) {
@ -339,16 +339,16 @@ public:
puts("}\n");
}
virtual void visit(AstStop* nodep, AstNUser*) {
puts("vl_stop(\"");
puts(nodep->fileline()->filename());
puts("\",");
puts("vl_stop(");
putsQuoted(nodep->fileline()->filename());
puts(",");
puts(cvtToStr(nodep->fileline()->lineno()));
puts(",\"\");\n");
}
virtual void visit(AstFinish* nodep, AstNUser*) {
puts("vl_finish(\"");
puts(nodep->fileline()->filename());
puts("\",");
puts("vl_finish(");
putsQuoted(nodep->fileline()->filename());
puts(",");
puts(cvtToStr(nodep->fileline()->lineno()));
puts(",\"\");\n");
}
@ -830,8 +830,8 @@ void EmitCStmts::emitVarCtors() {
}
else puts(", ");
if (ofp()->exceededWidth()) puts("\n ");
puts((*it)->name()); puts("(\"");
puts((*it)->name()); puts("\")");
puts((*it)->name());
puts("("); putsQuoted((*it)->name()); puts(")");
}
if (!first) puts ("\n#endif\n");
ofp()->indentDec();
@ -995,7 +995,7 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
nodep->v3fatalSrc("Unknown displayEmit node type");
}
puts("\"");
ofp()->putsNoTracking(emitDispState.m_format);
ofp()->putsNoTracking(emitDispState.m_format); // Not putsQuoted - already contains \s
puts("\"");
// Arguments
for (unsigned i=0; i < emitDispState.m_argsp.size(); i++) {
@ -1299,7 +1299,9 @@ void EmitCImp::emitTextSection(AstType type) {
puts("\n//*** Below code from `systemc in Verilog file\n");
}
ofp()->putsNoTracking("//#line "+cvtToStr(nodep->fileline()->lineno())
+" \""+nodep->fileline()->filename()+"\"\n");
+" ");
ofp()->putsQuoted(nodep->fileline()->filename());
ofp()->putsNoTracking("\n");
last_line = nodep->fileline()->lineno();
}
ofp()->putsNoTracking(textp->text());
@ -1838,7 +1840,8 @@ class EmitCTrace : EmitCStmts {
}
puts("(c+"+cvtToStr(nodep->code()));
if (nodep->arrayWidth()) puts("+i*"+cvtToStr(nodep->widthWords()));
puts(",\""+nodep->showname()+"\"");
puts(",");
putsQuoted(nodep->showname());
if (nodep->arrayWidth()) {
puts(",(i+"+cvtToStr(nodep->arrayLsb())+")");
} else {

View File

@ -107,6 +107,7 @@ public:
V3OutCFile* ofp() const { return m_ofp; };
void puts(const string& str) { ofp()->puts(str); }
void putbs(const string& str) { ofp()->putbs(str); }
void putsQuoted(const string& str) { ofp()->putsQuoted(str); }
bool optSystemC() { return v3Global.opt.systemC(); }
bool optSystemPerl() { return v3Global.opt.systemPerl(); }
static string symClassName() { return v3Global.opt.prefix()+"__Syms"; }

View File

@ -209,9 +209,9 @@ void EmitCSyms::emitImp() {
if (modp->isTop()) {
} else {
ofp()->printf("\t%c %-30s ", comma, scopep->nameDotless().c_str());
puts("(Verilated::catName(topp->name(),\"");
puts("."+scopep->prettyName());
puts("\"))\n");
puts("(Verilated::catName(topp->name(),");
putsQuoted("."+scopep->prettyName());
puts("))\n");
comma=',';
}
}

View File

@ -177,7 +177,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
putbs(" (");
if (filep) { filep->iterateAndNext(*this); putbs(","); }
puts("\"");
putsNoTracking(text);
putsNoTracking(text); // Not putsQuoted, as display text contains \ already
puts("\"");
for (AstNode* expp=exprsp; expp; expp = expp->nextp()) {
puts(",");

View File

@ -431,6 +431,23 @@ void V3OutFile::putBreak () {
}
}
void V3OutFile::putsQuoted(const char* strg) {
// Quote \ and " for use inside C programs
// Don't use to quote a filename for #include - #include doesn't \ escape.
putcNoTracking('"');
for (const char* cp=strg; *cp; cp++) {
if (*cp == '\\') {
putcNoTracking('\\');
putcNoTracking('\\');
} else if (*cp == '"') {
putcNoTracking('\\');
putcNoTracking('"');
} else {
putcNoTracking (*cp);
}
}
putcNoTracking('"');
}
void V3OutFile::putsNoTracking (const char *strg) {
// Don't track {}'s, probably because it's a $display format string
for (const char* cp=strg; *cp; cp++) {

View File

@ -113,6 +113,8 @@ public:
void puts(const string& strg) { puts(strg.c_str()); }
void putsNoTracking(const char* strg);
void putsNoTracking(const string& strg) { putsNoTracking(strg.c_str()); }
void putsQuoted(const char* strg);
void putsQuoted(const string& strg) { putsQuoted(strg.c_str()); }
void putBreak(); // Print linebreak if line is too wide
void putBreakExpr(); // Print linebreak in expression if line is too wide
void putAlign(bool isstatic/*AlignClass*/, int align, int size=0/*=align*/, const char* prefix=""); // Declare a variable, with natural alignment

View File

@ -278,7 +278,7 @@ private:
}
// Autoflush
virtual void visit(AstDisplay* nodep, AstNUser* vup) {
virtual void visit(AstDisplay* nodep, AstNUser*) {
startStatement(nodep);
nodep->iterateChildren(*this);
m_stmtp = NULL;

View File

@ -44,6 +44,7 @@ my $opt_vcs;
my $opt_v3;
my $opt_stop;
my $opt_optimize;
my $opt_trace;
my $opt_gdb;
my $opt_jobs = 1;
my $opt_verbose;
@ -63,6 +64,7 @@ if (! GetOptions (
"gdb!" => \$opt_gdb,
"optimize:s" => \$opt_optimize,
"stop!" => \$opt_stop,
"trace!" => \$opt_trace,
"verbose!" => \$opt_verbose,
"<>" => \&parameter,
)) {
@ -122,7 +124,7 @@ sub one_test {
} else {
$test->oprint("FAILED: ","*"x60,"\n");
push @fails, "\t#".$test->soprint("%Error: $test->{errors}\n");
my $j = ($opt_jobs>1?" -j 2":"");
my $j = ($opt_jobs>1?" -j $opt_jobs":"");
push @fails, "\t\tmake$j && test_regress/"
.$test->{pl_filename}." ".join(' ',@Orig_ARGV_Sw)."\n";
$failcnt++;
@ -234,6 +236,7 @@ sub new {
v_flags => [split(/\s+/,(" -f input.vc --debug-check"
.($opt_verbose ? " +define+TEST_VERBOSE=1":"")
.($opt_benchmark ? " +define+TEST_BENCHMARK=$opt_benchmark":"")
.($opt_trace ? " +define+WAVES=1":"")
))],
v_flags2 => [], # Overridden in some sim files
v_other_filenames => [], # After the filename so we can spec multiple files
@ -265,6 +268,7 @@ sub new {
$self->{status_filename} ||= "$self->{obj_dir}/V".$self->{name}.".status";
$self->{run_log_filename} ||= "$self->{obj_dir}/vl_sim.log";
$self->{coverage_filename} ||= "$self->{obj_dir}/vl_coverage.pl";
$self->{vcd_filename} ||= "$self->{obj_dir}/sim.vcd";
($self->{top_filename} = $self->{pl_filename}) =~ s/\.pl$/\.v/;
if (!$self->{make_top_shell}) {
$self->{top_shell_filename} = $self->{top_filename};
@ -349,7 +353,7 @@ sub compile {
@{$param{verilator_flags2}});
$self->{sc} = 1 if ($checkflags =~ /-sc\b/);
$self->{sp} = 1 if ($checkflags =~ /-sp\b/);
$self->{trace} = 1 if ($checkflags =~ /-trace\b/);
$self->{trace} = 1 if ($opt_trace || $checkflags =~ /-trace\b/);
$self->{coverage} = 1 if ($checkflags =~ /-coverage\b/);
if ($param{vcs}) {
@ -386,7 +390,7 @@ sub compile {
unshift @verilator_flags, "--gdb $opt_gdb" if $opt_gdb;
unshift @verilator_flags, @Opt_Driver_Verilator_Flags;
unshift @verilator_flags, "--x-assign unique"; # More likely to be buggy
# unshift @verilator_flags, "--trace";
unshift @verilator_flags, "--trace" if $opt_trace;
if (defined $opt_optimize) {
my $letters = "";
if ($opt_optimize =~ /[a-zA-Z]/) {
@ -786,7 +790,18 @@ sub _make_top {
}
print $fh " );\n";
# Waves
print $fh "\n";
print $fh "`ifdef WAVES\n";
print $fh " initial begin\n";
print $fh " \$display(\"-Tracing Waves to Dumpfile: $self->{vcd_filename}\");\n";
print $fh " \$dumpfile(\"$self->{vcd_filename}\");\n";
print $fh " \$dumpvars(12, t);\n";
print $fh " end\n";
print $fh "`endif\n";
# Test
print $fh "\n";
print $fh " initial begin\n";
print $fh " fastclk=1;\n" if $self->{inputs}{fastclk};
print $fh " clk=1;\n" if $self->{inputs}{clk};

View File

@ -5,7 +5,7 @@
module t (/*AUTOARG*/
// Outputs
\escaped_normal , double__underscore, \9num , \bra[ket]slash/dash-colon:9 ,
\escaped_normal , double__underscore, \9num , \bra[ket]slash/dash-colon:9backslash\done ,
// Inputs
clk
);
@ -24,20 +24,19 @@ module t (/*AUTOARG*/
output \9num ;
wire \9num = cyc[0];
output \bra[ket]slash/dash-colon:9 ;
wire \bra[ket]slash/dash-colon:9 = cyc[0];
output \bra[ket]slash/dash-colon:9backslash\done ;
wire \bra[ket]slash/dash-colon:9backslash\done = cyc[0];
wire \wire = cyc[0];
wire \check_alias = cyc[0];
wire \check:alias = cyc[0];
wire \check;alias = !cyc[0];
`ifndef verilator
initial begin
$dumpfile("obj_dir/t_var_escape/t_var_escape_dump.vcd");
$dumpvars( 0, t );
$dumpon;
end
`endif
// These are *different entities*, bug83
wire [31:0] \a0.cyc = ~a0.cyc;
wire [31:0] \other.cyc = ~a0.cyc;
sub a0 (.cyc(cyc));
always @ (posedge clk) begin
cyc <= cyc + 1;
@ -45,11 +44,13 @@ module t (/*AUTOARG*/
if (\escaped_normal != cyc[0]) $stop;
if (double__underscore != cyc[0]) $stop;
if (\9num != cyc[0]) $stop;
if (\bra[ket]slash/dash-colon:9 != cyc[0]) $stop;
if (\bra[ket]slash/dash-colon:9backslash\done != cyc[0]) $stop;
if (\wire != cyc[0]) $stop;
if (\check_alias != cyc[0]) $stop;
if (\check:alias != cyc[0]) $stop;
if (\check;alias != !cyc[0]) $stop;
if (\a0.cyc != ~cyc) $stop;
if (\other.cyc != ~cyc) $stop;
if (cyc==10) begin
$write("*-* All Finished *-*\n");
$finish;
@ -57,3 +58,8 @@ module t (/*AUTOARG*/
end
endmodule
module sub (
input [31:0] cyc
);
endmodule