diff --git a/Changes b/Changes index c15dee736..04bbd4f37 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ indicates the contributor was also the author of the fix; Thanks! *** Add --trace-max-width and --trace-max-array, bug 319. [Alex Solomatnikov] +**** Support ${...} and $(...) env vars in .vc files. [by Stefan Wallentowitz] + **** Support $bits(data_type), bug327. [Alex Solomatnikov] **** Support loop unrolling on width mismatches, bug 333. [Joe Eiler] diff --git a/bin/verilator b/bin/verilator index fc265d26c..b8bc4171a 100755 --- a/bin/verilator +++ b/bin/verilator @@ -536,14 +536,18 @@ the command line that implement the main loop for your simulation. Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the directory -containing the specified file. Note -F is fairly standard across Verilog -tools. +containing the specified file. See also -f. Note -F is fairly standard +across Verilog tools. =item -f I Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the current -directory. Note -f is fairly standard across Verilog tools. +directory. See also -F. Note -f is fairly standard across Verilog tools. + +The file may contain // comments which are ignored to the end of the line. +Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment +variable. =item --gdbbt diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 66c304536..4860cffb6 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -194,18 +194,33 @@ string V3Options::filenameNonExt (const string& filename) { string V3Options::filenameSubstitute (const string& filename) { string out; + enum { NONE, PAREN, CURLY } brackets = NONE; for (string::size_type pos = 0; pos < filename.length(); ++pos) { - if (filename[pos] == '$') { + if ((filename[pos] == '$') && (pos+1 < filename.length())) { + switch (filename[pos+1]) { + case '{': brackets = CURLY; break; + case '(': brackets = PAREN; break; + default: brackets = NONE; break; + } + if (brackets != NONE) pos = pos+1; string::size_type endpos = pos+1; - while ((endpos+1) < filename.length() - && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) + while (((endpos+1) < filename.length()) && + (((brackets==NONE) && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) || + ((brackets==CURLY) && (filename[endpos+1]!='}')) || + ((brackets==PAREN) && (filename[endpos+1]!=')')))) ++endpos; + // Catch bracket errors + if (((brackets==CURLY) && (filename[endpos+1]!='}')) || + ((brackets==PAREN) && (filename[endpos+1]!=')'))) { + v3fatal("Unmatched brackets in variable substitution in file: "+filename); + } string envvar = filename.substr(pos+1,endpos-pos); const char* envvalue = NULL; if (envvar != "") envvalue = getenv(envvar.c_str()); if (envvalue) { out += envvalue; - pos = endpos; + if (brackets==NONE) pos = endpos; + else pos = endpos+1; } else { out += filename[pos]; // *pos == '$' } @@ -214,6 +229,7 @@ string V3Options::filenameSubstitute (const string& filename) { } } return out; + } bool V3Options::filenameIsRel(const string& filename) { diff --git a/test_regress/t/t_flag_f.vc b/test_regress/t/t_flag_f.vc index 887dc4587..7356b8b10 100644 --- a/test_regress/t/t_flag_f.vc +++ b/test_regress/t/t_flag_f.vc @@ -1,6 +1,6 @@ // Test that environment substitutions work -f $VERILATOR_ROOT/test_regress/t/t_flag_f__2.vc -// Env var with .v file -$VERILATOR_ROOT/test_regress/t/t_flag_f__3.v +// Env var with .v file, and parens +${VERILATOR_ROOT}/test_regress/t/t_flag_f__3.v // Test -f -F $VERILATOR_ROOT/test_regress/t/tsub/t_flag_f_tsub.vc