Skip to content

Commit 747ed9a

Browse files
committed
ebmc language interface implementation for Verilog
This adds an implementation of the ebmc_languaget interface for Verilog.
1 parent 26372be commit 747ed9a

File tree

4 files changed

+329
-358
lines changed

4 files changed

+329
-358
lines changed

src/ebmc/build_transition_system.cpp

Lines changed: 7 additions & 358 deletions
Original file line numberDiff line numberDiff line change
@@ -9,339 +9,16 @@ Author: Daniel Kroening, [email protected]
99
#include "build_transition_system.h"
1010

1111
#include <util/cmdline.h>
12-
#include <util/get_module.h>
1312
#include <util/message.h>
14-
#include <util/namespace.h>
15-
#include <util/options.h>
16-
#include <util/unicode.h>
1713

18-
#include <langapi/language.h>
19-
#include <langapi/language_util.h>
20-
#include <langapi/mode.h>
2114
#include <smvlang/smv_ebmc_language.h>
22-
#include <trans-word-level/show_module_hierarchy.h>
15+
#include <verilog/verilog_ebmc_language.h>
2316

2417
#include "ebmc_error.h"
25-
#include "ebmc_language_file.h"
26-
#include "ebmc_version.h"
27-
#include "output_file.h"
28-
#include "show_modules.h"
2918
#include "transition_system.h"
3019

3120
#include <fstream>
32-
#include <iostream>
33-
34-
void preprocess(const cmdlinet &cmdline, message_handlert &message_handler)
35-
{
36-
messaget message(message_handler);
37-
38-
if(cmdline.args.size() != 1)
39-
throw ebmc_errort{}.with_exit_code(1)
40-
<< "please give exactly one file to preprocess";
41-
42-
const auto &filename = cmdline.args.front();
43-
std::ifstream infile(widen_if_needed(filename));
44-
45-
if(!infile)
46-
throw ebmc_errort{}.with_exit_code(1)
47-
<< "failed to open input file `" << filename << "'";
48-
49-
auto language = get_language_from_filename(filename);
50-
51-
if(language == nullptr)
52-
{
53-
source_locationt location;
54-
location.set_file(filename);
55-
throw ebmc_errort{}.with_location(location).with_exit_code(1)
56-
<< "failed to figure out type of file";
57-
}
58-
59-
optionst options;
60-
61-
// do -I
62-
if(cmdline.isset('I'))
63-
options.set_option("I", cmdline.get_values('I'));
64-
65-
options.set_option("force-systemverilog", cmdline.isset("systemverilog"));
66-
67-
// do -D
68-
if(cmdline.isset('D'))
69-
options.set_option("defines", cmdline.get_values('D'));
70-
71-
language->set_language_options(options, message_handler);
72-
73-
if(language->preprocess(infile, filename, std::cout, message_handler))
74-
throw ebmc_errort{}.with_exit_code(1);
75-
}
76-
77-
static bool parse(
78-
const cmdlinet &cmdline,
79-
const std::string &filename,
80-
ebmc_language_filest &language_files,
81-
message_handlert &message_handler)
82-
{
83-
messaget message(message_handler);
84-
85-
std::ifstream infile(widen_if_needed(filename));
86-
87-
if(!infile)
88-
{
89-
message.error() << "failed to open input file `" << filename << "'"
90-
<< messaget::eom;
91-
return true;
92-
}
93-
94-
auto &lf = language_files.add_file(filename);
95-
lf.filename = filename;
96-
lf.language = get_language_from_filename(filename);
97-
98-
if(lf.language == nullptr)
99-
{
100-
source_locationt location;
101-
location.set_file(filename);
102-
message.error().source_location = location;
103-
message.error() << "failed to figure out type of file" << messaget::eom;
104-
return true;
105-
}
106-
107-
languaget &language = *lf.language;
108-
109-
optionst options;
110-
111-
// do -I
112-
if(cmdline.isset('I'))
113-
options.set_option("I", cmdline.get_values('I'));
114-
115-
options.set_option("force-systemverilog", cmdline.isset("systemverilog"));
116-
options.set_option("vl2smv-extensions", cmdline.isset("vl2smv-extensions"));
117-
options.set_option("warn-implicit-nets", cmdline.isset("warn-implicit-nets"));
118-
119-
// do -D
120-
if(cmdline.isset('D'))
121-
options.set_option("defines", cmdline.get_values('D'));
122-
123-
// do --ignore-initial
124-
if(cmdline.isset("ignore-initial"))
125-
options.set_option("ignore-initial", true);
126-
127-
// do --initial-zero
128-
if(cmdline.isset("initial-zero"))
129-
options.set_option("initial-zero", true);
130-
131-
language.set_language_options(options, message_handler);
132-
133-
message.status() << "Parsing " << filename << messaget::eom;
134-
135-
if(language.parse(infile, filename, message_handler))
136-
{
137-
message.error() << "PARSING ERROR\n";
138-
return true;
139-
}
140-
141-
lf.get_modules();
142-
143-
return false;
144-
}
145-
146-
bool parse(
147-
const cmdlinet &cmdline,
148-
ebmc_language_filest &language_files,
149-
message_handlert &message_handler)
150-
{
151-
for(unsigned i = 0; i < cmdline.args.size(); i++)
152-
{
153-
if(parse(cmdline, cmdline.args[i], language_files, message_handler))
154-
return true;
155-
}
156-
return false;
157-
}
158-
159-
bool get_main(
160-
const cmdlinet &cmdline,
161-
message_handlert &message_handler,
162-
transition_systemt &transition_system)
163-
{
164-
std::string top_module;
165-
166-
if(cmdline.isset("module"))
167-
top_module = cmdline.get_value("module");
168-
else if(cmdline.isset("top"))
169-
top_module = cmdline.get_value("top");
170-
171-
try
172-
{
173-
transition_system.main_symbol =
174-
&get_module(transition_system.symbol_table, top_module, message_handler);
175-
transition_system.trans_expr =
176-
to_trans_expr(transition_system.main_symbol->value);
177-
}
178-
179-
catch(int e)
180-
{
181-
return true;
182-
}
183-
184-
return false;
185-
}
186-
187-
void make_next_state(exprt &expr)
188-
{
189-
for(auto &sub_expression : expr.operands())
190-
make_next_state(sub_expression);
191-
192-
if(expr.id() == ID_symbol)
193-
expr.id(ID_next_symbol);
194-
}
195-
196-
int get_transition_system(
197-
const cmdlinet &cmdline,
198-
message_handlert &message_handler,
199-
transition_systemt &transition_system)
200-
{
201-
messaget message(message_handler);
202-
203-
//
204-
// parsing
205-
//
206-
ebmc_language_filest language_files;
207-
208-
if(parse(cmdline, language_files, message_handler))
209-
return 1;
210-
211-
if(cmdline.isset("show-parse"))
212-
{
213-
language_files.show_parse(std::cout, message_handler);
214-
return 0;
215-
}
216-
217-
//
218-
// type checking
219-
//
220-
221-
message.status() << "Converting" << messaget::eom;
222-
223-
if(language_files.typecheck(transition_system.symbol_table, message_handler))
224-
{
225-
message.error() << "CONVERSION ERROR" << messaget::eom;
226-
return 2;
227-
}
228-
229-
if(cmdline.isset("show-modules"))
230-
{
231-
show_modulest::from_symbol_table(transition_system.symbol_table)
232-
.plain_text(std::cout);
233-
return 0;
234-
}
235-
236-
if(cmdline.isset("modules-xml"))
237-
{
238-
auto filename = cmdline.get_value("modules-xml");
239-
auto out_file = output_filet{filename};
240-
show_modulest::from_symbol_table(transition_system.symbol_table)
241-
.xml(out_file.stream());
242-
return 0;
243-
}
244-
245-
if(cmdline.isset("json-modules"))
246-
{
247-
auto out_file = output_filet{cmdline.get_value("json-modules")};
248-
show_modulest::from_symbol_table(transition_system.symbol_table)
249-
.json(out_file.stream());
250-
return 0;
251-
}
252-
253-
if(cmdline.isset("show-symbol-table"))
254-
{
255-
std::cout << transition_system.symbol_table;
256-
return 0;
257-
}
258-
259-
// get module name
260-
261-
if(get_main(cmdline, message_handler, transition_system))
262-
return 1;
263-
264-
if(cmdline.isset("show-module-hierarchy"))
265-
{
266-
DATA_INVARIANT(
267-
transition_system.main_symbol != nullptr, "must have main_symbol");
268-
show_module_hierarchy(
269-
transition_system.symbol_table,
270-
*transition_system.main_symbol,
271-
std::cout);
272-
return 0;
273-
}
274-
275-
// --reset given?
276-
if(cmdline.isset("reset"))
277-
{
278-
namespacet ns(transition_system.symbol_table);
279-
exprt reset_constraint = to_expr(
280-
ns, transition_system.main_symbol->name, cmdline.get_value("reset"));
281-
282-
// we want the constraint to be boolean
283-
reset_constraint =
284-
typecast_exprt::conditional_cast(reset_constraint, bool_typet{});
285-
286-
// true in initial state
287-
transt new_trans_expr = transition_system.trans_expr;
288-
new_trans_expr.init() = and_exprt(new_trans_expr.init(), reset_constraint);
289-
290-
// and not anymore afterwards
291-
exprt reset_next_state = reset_constraint;
292-
make_next_state(reset_next_state);
293-
294-
new_trans_expr.trans() =
295-
and_exprt(new_trans_expr.trans(), not_exprt(reset_next_state));
296-
transition_system.trans_expr = new_trans_expr;
297-
}
298-
299-
return -1; // done with the transition system
300-
}
301-
302-
transition_systemt get_transition_system(
303-
const cmdlinet &cmdline,
304-
message_handlert &message_handler)
305-
{
306-
transition_systemt transition_system;
307-
auto exit_code =
308-
get_transition_system(cmdline, message_handler, transition_system);
309-
if(exit_code != -1)
310-
throw ebmc_errort().with_exit_code(exit_code);
311-
return transition_system;
312-
}
313-
314-
int show_parse(const cmdlinet &cmdline, message_handlert &message_handler)
315-
{
316-
transition_systemt dummy_transition_system;
317-
return get_transition_system(
318-
cmdline, message_handler, dummy_transition_system);
319-
}
320-
321-
int show_modules(const cmdlinet &cmdline, message_handlert &message_handler)
322-
{
323-
transition_systemt dummy_transition_system;
324-
return get_transition_system(
325-
cmdline, message_handler, dummy_transition_system);
326-
}
327-
328-
int show_module_hierarchy(
329-
const cmdlinet &cmdline,
330-
message_handlert &message_handler)
331-
{
332-
transition_systemt dummy_transition_system;
333-
return get_transition_system(
334-
cmdline, message_handler, dummy_transition_system);
335-
}
336-
337-
int show_symbol_table(
338-
const cmdlinet &cmdline,
339-
message_handlert &message_handler)
340-
{
341-
transition_systemt dummy_transition_system;
342-
return get_transition_system(
343-
cmdline, message_handler, dummy_transition_system);
344-
}
21+
#include <set>
34522

34623
static std::set<std::string> file_extensions(const cmdlinet::argst &args)
34724
{
@@ -379,40 +56,12 @@ std::optional<transition_systemt> ebmc_languagest::transition_system()
37956
{
38057
return smv_ebmc_languaget{cmdline, message_handler}.transition_system();
38158
}
59+
else if(have_verilog)
60+
{
61+
return verilog_ebmc_languaget{cmdline, message_handler}.transition_system();
62+
}
38263
else
38364
{
384-
if(cmdline.isset("preprocess"))
385-
{
386-
preprocess(cmdline, message_handler);
387-
return {};
388-
}
389-
390-
if(cmdline.isset("show-parse"))
391-
{
392-
show_parse(cmdline, message_handler);
393-
return {};
394-
}
395-
396-
if(
397-
cmdline.isset("show-modules") || cmdline.isset("modules-xml") ||
398-
cmdline.isset("json-modules"))
399-
{
400-
show_modules(cmdline, message_handler);
401-
return {};
402-
}
403-
404-
if(cmdline.isset("show-module-hierarchy"))
405-
{
406-
show_module_hierarchy(cmdline, message_handler);
407-
return {};
408-
}
409-
410-
if(cmdline.isset("show-symbol-table"))
411-
{
412-
show_symbol_table(cmdline, message_handler);
413-
return {};
414-
}
415-
416-
return get_transition_system(cmdline, message_handler);
65+
throw ebmc_errort{} << "no support for given input file extensions";
41766
}
41867
}

src/verilog/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ SRC = aval_bval_encoding.cpp \
44
sva_expr.cpp \
55
typename.cpp \
66
verilog_bits.cpp \
7+
verilog_ebmc_language.cpp \
78
verilog_elaborate.cpp \
89
verilog_elaborate_type.cpp \
910
verilog_expr.cpp \

0 commit comments

Comments
 (0)