Skip to content

Commit 0d137f4

Browse files
committed
Verilog: set defines on command line
This allows setting SystemVerilog preprocessor defines on the command line with -D.
1 parent b7a55de commit 0d137f4

10 files changed

+76
-8
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
cmdline_define1.v
3+
--preprocess -D SOMETHING -D ELSE=foo
4+
^A$
5+
^foo$
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
^B$
10+
^PREPROCESSING FAILED$
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
`ifdef SOMETHING
2+
A
3+
`endif
4+
`ifdef OTHER
5+
B
6+
`endif
7+
`ELSE

src/ebmc/ebmc_parse_options.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class ebmc_parse_optionst:public parse_options_baset
4747
"(random-traces)(trace-steps):(random-seed):(traces):"
4848
"(random-trace)(random-waveform)"
4949
"(liveness-to-safety)"
50-
"I:(preprocess)(systemverilog)(vl2smv-extensions)",
50+
"I:D:(preprocess)(systemverilog)(vl2smv-extensions)",
5151
argc,
5252
argv,
5353
std::string("EBMC ") + EBMC_VERSION),

src/ebmc/transition_system.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ int preprocess(const cmdlinet &cmdline, message_handlert &message_handler)
113113
options.set_option("force-systemverilog", cmdline.isset("systemverilog"));
114114
options.set_option("vl2smv-extensions", cmdline.isset("vl2smv-extensions"));
115115

116+
// do -D
117+
if(cmdline.isset('D'))
118+
options.set_option("defines", cmdline.get_values('D'));
119+
116120
language->set_language_options(options, message_handler);
117121

118122
if(language->preprocess(infile, filename, std::cout, message_handler))
@@ -160,6 +164,10 @@ static bool parse(
160164
options.set_option("force-systemverilog", cmdline.isset("systemverilog"));
161165
options.set_option("vl2smv-extensions", cmdline.isset("vl2smv-extensions"));
162166

167+
// do -D
168+
if(cmdline.isset('D'))
169+
options.set_option("defines", cmdline.get_values('D'));
170+
163171
language.set_language_options(options, message_handler);
164172

165173
message.status() << "Parsing " << filename << messaget::eom;

src/verilog/verilog_language.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ void verilog_languaget::set_language_options(
3636
{
3737
force_systemverilog = options.get_bool_option("force-systemverilog");
3838
vl2smv_extensions = options.get_bool_option("vl2smv-extensions");
39+
initial_defines = options.get_list_option("defines");
3940
}
4041

4142
/*******************************************************************\
@@ -103,7 +104,7 @@ bool verilog_languaget::preprocess(
103104
message_handlert &message_handler)
104105
{
105106
verilog_preprocessort preprocessor(
106-
instream, outstream, message_handler, path);
107+
instream, outstream, message_handler, path, initial_defines);
107108

108109
try { preprocessor.preprocessor(); }
109110
catch(int e) { return true; }
@@ -186,7 +187,7 @@ bool verilog_languaget::typecheck(
186187
message.debug() << "Synthesis " << module << messaget::eom;
187188

188189
if(verilog_synthesis(
189-
symbol_table, module, parse_tree.standard, message_handler, options))
190+
symbol_table, module, parse_tree.standard, message_handler, optionst{}))
190191
return true;
191192

192193
return false;

src/verilog/verilog_language.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,15 @@ class verilog_languaget:public languaget
8585
{
8686
return parse_tree;
8787
}
88-
89-
optionst options;
9088

9189
verilog_languaget() : parse_tree(verilog_standardt::NOT_SET)
9290
{
93-
options.set_option("flatten_hierarchy", true);
9491
}
9592

9693
protected:
9794
bool force_systemverilog = false;
9895
bool vl2smv_extensions = false;
96+
std::list<std::string> initial_defines;
9997
verilog_parse_treet parse_tree;
10098
};
10199

src/verilog/verilog_preprocessor.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,24 @@ void verilog_preprocessort::preprocessor()
184184
{
185185
try
186186
{
187+
// set up the initial defines
188+
for(auto &define : initial_defines)
189+
{
190+
std::size_t equal_pos = define.find('=');
191+
if(equal_pos == std::string::npos)
192+
{
193+
defines.insert(std::pair<std::string, definet>(define, definet{}));
194+
}
195+
else
196+
{
197+
std::string key = define.substr(0, equal_pos);
198+
std::string value = define.substr(equal_pos + 1, std::string::npos);
199+
auto tokens = verilog_preprocessor_tokenize(value);
200+
defines.insert(
201+
std::pair<std::string, definet>(key, definet{std::move(tokens)}));
202+
}
203+
}
204+
187205
// the first context is the input file
188206
context_stack.emplace_back(false, &in, widen_if_needed(filename));
189207

src/verilog/verilog_preprocessor.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,31 @@ class verilog_preprocessort:public preprocessort
2121
std::istream &_in,
2222
std::ostream &_out,
2323
message_handlert &_message_handler,
24-
const std::string &_filename):
25-
preprocessort(_in, _out, _message_handler, _filename)
24+
const std::string &_filename,
25+
const std::list<std::string> &_initial_defines)
26+
: preprocessort(_in, _out, _message_handler, _filename),
27+
initial_defines(_initial_defines)
2628
{
2729
condition=true;
2830
}
2931

3032
virtual ~verilog_preprocessort() { }
3133

3234
protected:
35+
// from the command line
36+
const std::list<std::string> &initial_defines;
37+
3338
using tokent = verilog_preprocessor_token_sourcet::tokent;
3439

3540
struct definet
3641
{
3742
using parameterst = std::vector<std::string>;
3843
parameterst parameters;
3944
std::vector<tokent> tokens;
45+
definet() = default;
46+
explicit definet(std::vector<tokent> _tokens) : tokens(std::move(_tokens))
47+
{
48+
}
4049
};
4150

4251
static std::string as_string(const std::vector<tokent> &);

src/verilog/verilog_preprocessor_tokenizer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,14 @@ void verilog_preprocessor_tokenizert::get_token_from_stream()
114114
token.kind = static_cast<verilog_preprocessor_tokenizert::tokent::kindt>(
115115
yyverilog_preprocessorlex());
116116
}
117+
118+
std::vector<verilog_preprocessor_token_sourcet::tokent>
119+
verilog_preprocessor_tokenize(const std::string &text)
120+
{
121+
std::istringstream instream(text);
122+
verilog_preprocessor_tokenizert tokenizer(instream);
123+
std::vector<verilog_preprocessor_token_sourcet::tokent> result;
124+
while(!tokenizer.eof())
125+
result.push_back(tokenizer.next_token());
126+
return result;
127+
}

src/verilog/verilog_preprocessor_tokenizer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include "verilog_preprocessor_error.h"
1313

14+
#include <vector>
15+
1416
/// Note that the set of tokens recognised by the Verilog preprocessor
1517
/// differs from the set of tokens used by the main parser.
1618

@@ -105,4 +107,8 @@ class verilog_preprocessor_tokenizert
105107
void get_token_from_stream() override;
106108
};
107109

110+
// tokenize a given string
111+
std::vector<verilog_preprocessor_token_sourcet::tokent>
112+
verilog_preprocessor_tokenize(const std::string &);
113+
108114
#endif // VERILOG_PREPROCESSOR_TOKENIZER_H

0 commit comments

Comments
 (0)