Support arbitrary characters in identifiers and tracing.
This commit is contained in:
parent
6aaef67e73
commit
22543f3e19
2
Changes
2
Changes
|
|
@ -20,6 +20,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
**** Fix stack overflow on large ? : trees. [John Sanguinetti]
|
**** Fix stack overflow on large ? : trees. [John Sanguinetti]
|
||||||
|
|
||||||
|
**** Support arbitrary characters in identifiers. [Stephane Laurent]
|
||||||
|
|
||||||
* Verilator 3.670 2008/07/23
|
* Verilator 3.670 2008/07/23
|
||||||
|
|
||||||
** Add --x-assign=fast option, and make it the default.
|
** Add --x-assign=fast option, and make it the default.
|
||||||
|
|
|
||||||
|
|
@ -85,12 +85,27 @@ void AstNode::init() {
|
||||||
string AstNode::encodeName(const string& namein) {
|
string AstNode::encodeName(const string& namein) {
|
||||||
string name2 = namein;
|
string name2 = namein;
|
||||||
string out;
|
string out;
|
||||||
for (string::iterator pos = name2.begin(); pos != name2.end(); pos++) {
|
const char* start = name2.c_str();
|
||||||
if (pos[0]=='_' && pos[1]=='_') {
|
for (const char* pos = start; *pos; pos++) {
|
||||||
out += "__ULUL_";
|
if ((pos==start) ? isalpha(pos[0]) // digits can't lead identifiers
|
||||||
pos++;
|
: isalnum(pos[0])) {
|
||||||
} else {
|
|
||||||
out += 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;
|
return out;
|
||||||
|
|
@ -116,19 +131,37 @@ string AstNode::dedotName(const string& namein) {
|
||||||
}
|
}
|
||||||
|
|
||||||
string AstNode::prettyName(const string& namein) {
|
string AstNode::prettyName(const string& namein) {
|
||||||
string pretty = namein;
|
string pretty;
|
||||||
string::size_type pos;
|
string name2 = namein;
|
||||||
while ((pos=pretty.find("__BRA__")) != string::npos) {
|
pretty = "";
|
||||||
pretty.replace(pos, 7, "[");
|
for (const char* pos = name2.c_str(); *pos; ) {
|
||||||
}
|
if (0==strncmp(pos,"__BRA__",7)) {
|
||||||
while ((pos=pretty.find("__KET__")) != string::npos) {
|
pretty += "[";
|
||||||
pretty.replace(pos, 7, "]");
|
pos += 7;
|
||||||
}
|
}
|
||||||
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
else if (0==strncmp(pos,"__KET__",7)) {
|
||||||
pretty.replace(pos, 7, "");
|
pretty += "]";
|
||||||
}
|
pos += 7;
|
||||||
while ((pos=pretty.find("__ULUL_")) != 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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return AstNode::dedotName(pretty);
|
return AstNode::dedotName(pretty);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -654,19 +654,8 @@ escid \\[^ \t\f\r\n]+
|
||||||
|
|
||||||
/* Identifiers and numbers */
|
/* Identifiers and numbers */
|
||||||
<V95,V01,V05,S05,PSL>{
|
<V95,V01,V05,S05,PSL>{
|
||||||
{escid} { int i;
|
{escid} { yylval.strp = V3Read::newString
|
||||||
for (i=0; yytext[i] != 0; i++)
|
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
|
||||||
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
|
|
||||||
}
|
|
||||||
return yaID;
|
return yaID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue