Support arbitrary characters in identifiers and tracing.

This commit is contained in:
Wilson Snyder 2008-09-17 22:22:46 -04:00
parent 6aaef67e73
commit 22543f3e19
5 changed files with 139 additions and 31 deletions

View File

@ -20,6 +20,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix stack overflow on large ? : trees. [John Sanguinetti]
**** Support arbitrary characters in identifiers. [Stephane Laurent]
* Verilator 3.670 2008/07/23
** Add --x-assign=fast option, and make it the default.

View File

@ -85,13 +85,28 @@ void AstNode::init() {
string AstNode::encodeName(const string& namein) {
string name2 = namein;
string out;
for (string::iterator pos = name2.begin(); pos != name2.end(); pos++) {
if (pos[0]=='_' && pos[1]=='_') {
out += "__ULUL_";
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])) {
out += pos[0];
} else if (pos[0]=='_') {
if (pos[1]=='_') {
out += "_"; out += "__5F"; // hex(_) = 0x5F
pos++;
} else {
out += pos[0];
}
} else if (pos[0]=='.') {
out += "__DOT__";
} else if (pos[0]=='[') {
out += "__BRA__";
} else if (pos[0]==']') {
out += "__KET__";
} else {
char hex[10]; sprintf(hex,"%02X",pos[0]);
out += "__"; out += hex;
}
}
return out;
}
@ -116,19 +131,37 @@ string AstNode::dedotName(const string& namein) {
}
string AstNode::prettyName(const string& namein) {
string pretty = namein;
string::size_type pos;
while ((pos=pretty.find("__BRA__")) != string::npos) {
pretty.replace(pos, 7, "[");
string pretty;
string name2 = namein;
pretty = "";
for (const char* pos = name2.c_str(); *pos; ) {
if (0==strncmp(pos,"__BRA__",7)) {
pretty += "[";
pos += 7;
}
while ((pos=pretty.find("__KET__")) != string::npos) {
pretty.replace(pos, 7, "]");
else if (0==strncmp(pos,"__KET__",7)) {
pretty += "]";
pos += 7;
}
while ((pos=pretty.find("__PVT__")) != string::npos) {
pretty.replace(pos, 7, "");
else if (0==strncmp(pos,"__DOT__",7)) {
pretty += ".";
pos += 7;
}
else if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
}
else if (pos[0]=='_' && pos[1]=='_' && isxdigit(pos[2]) && isxdigit(pos[3])) {
char value = 0;
value += 16*(isdigit(pos[2]) ? (pos[2]-'0') : (tolower(pos[2])-'a'+10));
value += (isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
pretty += value;
pos += 4;
}
else {
pretty += pos[0];
pos++;
}
while ((pos=pretty.find("__ULUL_")) != string::npos) {
pretty.replace(pos, 7, "");
}
return AstNode::dedotName(pretty);
}

View File

@ -654,19 +654,8 @@ escid \\[^ \t\f\r\n]+
/* Identifiers and numbers */
<V95,V01,V05,S05,PSL>{
{escid} { int i;
for (i=0; yytext[i] != 0; i++)
if (!isalnum(yytext[i]))
yytext[i] = '_';
if (isalpha(yytext[1])) {
yylval.strp = V3Read::newString(
AstNode::encodeName(
string(yytext+1))); // +1 to skip the backslash
} else {
yylval.strp = V3Read::newString(
AstNode::encodeName(
yytext)); // Need _ as "6..." isn't legal ID
}
{escid} { yylval.strp = V3Read::newString
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
return yaID;
}

25
test_regress/t/t_var_escape.pl Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2007 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 (
# Access is so we can dump waves
v_flags2 => [$Last_Self->{v3}?'-trace':' +access+rwc'],
);
execute (
check_finished=>1,
);
if ($Last_Self->{v3}) {
file_grep ("obj_dir/$Last_Self->{name}_simx.vcd", qr/\$enddefinitions/x);
my $sig = quotemeta("bra[ket]slash/dash-colon:9");
file_grep ("obj_dir/$Last_Self->{name}_simx.vcd", qr/$sig/);
}
ok(1);
1;

View File

@ -0,0 +1,59 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2005 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
\escaped_normal , double__underscore, \9num , \bra[ket]slash/dash-colon:9 ,
// Inputs
clk
);
input clk;
integer cyc; initial cyc=1;
output \escaped_normal ;
wire \escaped_normal = cyc[0];
output double__underscore ;
wire double__underscore = cyc[0];
// C doesn't allow leading non-alpha, so must escape
output \9num ;
wire \9num = cyc[0];
output \bra[ket]slash/dash-colon:9 ;
wire \bra[ket]slash/dash-colon:9 = 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_dump.vcd");
$dumpvars( 0, t );
$dumpon;
end
`endif
always @ (posedge clk) begin
cyc <= cyc + 1;
if (escaped_normal != cyc[0]) $stop;
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 (\check_alias != cyc[0]) $stop;
if (\check:alias != cyc[0]) $stop;
if (\check;alias != !cyc[0]) $stop;
if (cyc==10) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule