From 6d66fcaa5731a9585a4ef8448afe149f82e275fb Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 13 Nov 2014 19:05:07 -0500 Subject: [PATCH] Fix +define+A+B to define A and B to match other simulators, bug847. --- Changes | 2 ++ bin/verilator | 16 +++++---- src/V3Options.cpp | 32 +++++++++++------ src/V3Options.h | 2 +- test_regress/t/t_flag_define.pl | 19 ++++++++++ test_regress/t/t_flag_define.v | 61 +++++++++++++++++++++++++++++++++ test_regress/t/t_flag_define.vc | 7 ++++ 7 files changed, 121 insertions(+), 18 deletions(-) create mode 100755 test_regress/t/t_flag_define.pl create mode 100644 test_regress/t/t_flag_define.v create mode 100644 test_regress/t/t_flag_define.vc diff --git a/Changes b/Changes index 2c30c431c..2252d8b31 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.865 devel +*** Fix +define+A+B to define A and B to match other simulators, bug847. [Adam Krolnik] + *** Add optimization of wires from arrayed cells, msg1447. [Jie Xu] *** Add optimization of operators between concats, msg1447. [Jie Xu] diff --git a/bin/verilator b/bin/verilator index 33f431270..59f2e1c71 100755 --- a/bin/verilator +++ b/bin/verilator @@ -267,7 +267,7 @@ descriptions in the next sections for more information. --debugi Enable debugging at a specified level --debugi- Enable debugging a source file at a level --default-language Default language to parse - +define++ Set preprocessor define + +define+= Set preprocessor define --dump-tree Enable dumping .tree files --dump-treei Enable dumping .tree files at a level -E Preprocess, but do not compile @@ -572,8 +572,9 @@ the comment "DefaultClock": =item -DI=I -Defines the given preprocessor symbol. Same as +define; +define is fairly -standard across Verilog tools while -D is an alias for GCC compatibility. +Defines the given preprocessor symbol, without allowing. Similar to ++define; +define is fairly standard across Verilog tools while -D is an +alias for GCC compatibility. =item --debug @@ -615,10 +616,13 @@ used. If no language is specified, either by this flag or +Iext+ options, then the latest SystemVerilog language (IEEE 1800-2012) is used. -=item +define+I+I +=item +define+I=I -Defines the given preprocessor symbol. Same as -D; +define is fairly -standard across Verilog tools while -D is an alias for GCC compatibility. +=item +define+I=I+I=I... + +Defines the given preprocessor symbol, or multiple symbols if separated by +plusses. Similar to -D; +define is fairly standard across Verilog tools +while -D is an alias for GCC compatibility. =item --dump-tree diff --git a/src/V3Options.cpp b/src/V3Options.cpp index a958782e8..a5b582d69 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -107,17 +107,27 @@ void V3Options::addLangExt(const string& langext, const V3LangCode& lc) { void V3Options::addLibExtV(const string& libext) { m_impp->addLibExtV(libext); } -void V3Options::addDefine(const string& defline) { +void V3Options::addDefine(const string& defline, bool allowPlus) { // Split +define+foo=value into the appropriate parts and parse - string def = defline; - string value; - string::size_type pos; - if ( ((pos=defline.find("+")) != string::npos) - || ((pos=defline.find("=")) != string::npos)) { - value = def.substr(pos+1); - def.erase(pos); + // Optional + says to allow multiple defines on the line + // + is not quotable, as other simulators do not allow that + string left = defline; + while (left != "") { + string def = left; + string::size_type pos; + if (allowPlus && ((pos=left.find("+")) != string::npos)) { + left = left.substr(pos+1); + def.erase(pos); + } else { + left = ""; + } + string value; + if ((pos=def.find("=")) != string::npos) { + value = def.substr(pos+1); + def.erase(pos); + } + V3PreShell::defineCmdLine(def,value); } - V3PreShell::defineCmdLine(def,value); } void V3Options::addCppFile(const string& filename) { @@ -668,7 +678,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char if (argv[i][0]=='+') { char *sw = argv[i]; if ( !strncmp (sw, "+define+", 8)) { - addDefine (string (sw+strlen("+define+"))); + addDefine (string (sw+strlen("+define+")), true); } else if ( !strncmp (sw, "+incdir+", 8)) { addIncDirUser (parseFileArg(optdir, string (sw+strlen("+incdir+")))); @@ -803,7 +813,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char m_convergeLimit = atoi(argv[i]); } else if ( !strncmp (sw, "-D", 2)) { - addDefine (string (sw+strlen("-D"))); + addDefine (string (sw+strlen("-D")), false); } else if ( !strcmp (sw, "-debug") ) { setDebugMode(3); diff --git a/src/V3Options.h b/src/V3Options.h index 266fe7f04..4e1c936ee 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -156,7 +156,7 @@ class V3Options { private: // METHODS void addArg(const string& flag); - void addDefine(const string& defline); + void addDefine(const string& defline, bool allowPlus); void addFuture(const string& flag); void addIncDirUser(const string& incdir); // User requested void addIncDirFallback(const string& incdir); // Low priority if not found otherwise diff --git a/test_regress/t/t_flag_define.pl b/test_regress/t/t_flag_define.pl new file mode 100755 index 000000000..0ecc0c0ba --- /dev/null +++ b/test_regress/t/t_flag_define.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. + +compile ( + v_flags2 => ["-f t/t_flag_define.vc"], + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_define.v b/test_regress/t/t_flag_define.v new file mode 100644 index 000000000..d26cc1854 --- /dev/null +++ b/test_regress/t/t_flag_define.v @@ -0,0 +1,61 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2014 by Wilson Snyder + +`define STRINGIFY(x) `"x`" + +module t; + initial begin +`ifdef D1A + if (`STRINGIFY(`D4B) !== "") $stop; +`else + $write("%%Error: Missing define\n"); $stop; +`endif + +`ifdef D2A + if (`STRINGIFY(`D2A) !== "VALA") $stop; +`else + $write("%%Error: Missing define\n"); $stop; +`endif + +`ifdef D3A + if (`STRINGIFY(`D4B) !== "") $stop; +`else + $write("%%Error: Missing define\n"); $stop; +`endif + +`ifdef D3B + if (`STRINGIFY(`D4B) !== "") $stop; +`else + $write("%%Error: Missing define\n"); $stop; +`endif + +`ifdef D4A + if (`STRINGIFY(`D4A) !== "VALA") $stop; +`else + $write("%%Error: Missing define\n"); $stop; +`endif + +`ifdef D4B + if (`STRINGIFY(`D4B) !== "") $stop; +`else + $write("%%Error: Missing define\n"); $stop; +`endif + +`ifdef D5A + if (`STRINGIFY(`D5A) !== "VALA") $stop; +`else + $write("%%Error: Missing define\n"); $stop; +`endif + +`ifdef D5A + if (`STRINGIFY(`D5B) !== "VALB") $stop; +`else + $write("%%Error: Missing define\n"); $stop; +`endif + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_flag_define.vc b/test_regress/t/t_flag_define.vc new file mode 100644 index 000000000..f0b52c58f --- /dev/null +++ b/test_regress/t/t_flag_define.vc @@ -0,0 +1,7 @@ ++define+D1A ++define+D2A=VALA ++define+D3A+D3B ++define+D4A=VALA+D4B ++define+D5A=VALA+D5B=VALB +// Quotes do NOT escape the plus +//+define+D5A="VALA+D5B"+D5C