Fix escaped identifiers with '.' causing conflicts, bug83.
This commit is contained in:
parent
4569278c53
commit
a3e463030d
5
Changes
5
Changes
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"; }
|
||||
|
|
|
|||
|
|
@ -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=',';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(",");
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue