@@ -180,7 +180,7 @@ void verilog_ebmc_languaget::typecheck_module(
180180
181181transition_systemt verilog_ebmc_languaget::typecheck (
182182 const parse_treest &parse_trees,
183- irep_idt top_level_module ,
183+ const std::vector< irep_idt> top_level_modules ,
184184 symbol_tablet &&symbol_table)
185185{
186186 std::map<irep_idt, modulet> module_map;
@@ -198,13 +198,17 @@ transition_systemt verilog_ebmc_languaget::typecheck(
198198 }
199199 }
200200
201- // now type check the top-level module
202- auto m_it = module_map.find (verilog_module_symbol (top_level_module));
203- CHECK_RETURN (m_it != module_map.end ());
204-
201+ // now type check the given top-level modules
205202 transition_systemt transition_system;
206203 transition_system.symbol_table = std::move (symbol_table);
207- typecheck_module (m_it->second , transition_system.symbol_table );
204+
205+ for (auto top_level_module : top_level_modules)
206+ {
207+ auto m_it = module_map.find (verilog_module_symbol (top_level_module));
208+ CHECK_RETURN (m_it != module_map.end ());
209+
210+ typecheck_module (m_it->second , transition_system.symbol_table );
211+ }
208212
209213 return transition_system;
210214}
@@ -244,8 +248,10 @@ static void module_dependencies(
244248 module_dependencies_rec (item, action);
245249}
246250
247- irep_idt
248- verilog_ebmc_languaget::top_level_module (const parse_treest &parse_trees) const
251+ // / Determine the set of top-level modules following 1800 2017 23.3.1,
252+ // / given via their base names. Sorted alphabetically.
253+ std::vector<irep_idt>
254+ verilog_ebmc_languaget::top_level_modules (const parse_treest &parse_trees) const
249255{
250256 // start with a set of all modules, from all the files
251257 std::set<irep_idt> all_modules;
@@ -260,29 +266,47 @@ verilog_ebmc_languaget::top_level_module(const parse_treest &parse_trees) const
260266 }
261267 }
262268
263- // Did the user specify one ?
264- irep_idt given_module ;
269+ // Did the user specify a set of top level modules ?
270+ std::vector< irep_idt> given_modules ;
265271
266272 if (cmdline.isset (" module" ))
267- given_module = cmdline.get_value (" module" );
273+ {
274+ for (auto &value : cmdline.get_values (" module" ))
275+ given_modules.push_back (value);
276+ }
268277 else if (cmdline.isset (" top" ))
269- given_module = cmdline.get_value (" top" );
278+ {
279+ for (auto &value : cmdline.get_values (" top" ))
280+ given_modules.push_back (value);
281+ }
270282
271- if (given_module != irep_idt{} )
283+ if (!given_modules. empty () )
272284 {
273- if (all_modules.find (given_module) == all_modules.end ())
285+ // first check that all the given modules exist
286+ for (const auto &given_module : given_modules)
274287 {
275- messaget log{message_handler};
276- log.error () << " module '" << given_module << " ' not found"
277- << messaget::eom;
278- throw ebmc_errort{}.with_exit_code (2 );
288+ if (all_modules.find (given_module) == all_modules.end ())
289+ {
290+ messaget log{message_handler};
291+ log.error () << " module '" << given_module << " ' not found"
292+ << messaget::eom;
293+ throw ebmc_errort{}.with_exit_code (2 );
294+ }
279295 }
280- else
281- return given_module; // done
296+
297+ // now sort alphabetically
298+ std::sort (
299+ given_modules.begin (),
300+ given_modules.end (),
301+ [](const irep_idt &a, const irep_idt &b)
302+ { return id2string (a) < id2string (b); });
303+
304+ return given_modules; // done
282305 }
283306
284- // start with all modules, and then erase the ones that are
285- // used as a dependency
307+ // No modules given. Find all modules that are not used
308+ // as a submodule. Start with all modules, and then erase
309+ // the ones that are used as a submodule.
286310 std::set<irep_idt> top_level_modules = all_modules;
287311
288312 for (auto &parse_tree : parse_trees)
@@ -304,33 +328,41 @@ verilog_ebmc_languaget::top_level_module(const parse_treest &parse_trees) const
304328 log.error () << " no module found" << messaget::eom;
305329 throw ebmc_errort{}.with_exit_code (1 );
306330 }
307- else if (top_level_modules.size () >= 2 )
308- {
309- // sorted alphabetically
310- std::set<std::string> modules;
311331
312- for ( const auto &base_name : top_level_modules)
313- modules. insert ( id2string (base_name)) ;
332+ // sort alphabetically into a vector
333+ std::vector<irep_idt> result ;
314334
335+ for (auto &module : top_level_modules)
336+ result.push_back (module );
337+
338+ std::sort (
339+ result.begin (),
340+ result.end (),
341+ [](const irep_idt &a, const irep_idt &b)
342+ { return id2string (a) < id2string (b); });
343+
344+ return result; // done
345+ }
346+
347+ static bool get_main (
348+ const std::vector<irep_idt> top_level_modules,
349+ message_handlert &message_handler,
350+ transition_systemt &transition_system)
351+ {
352+ if (top_level_modules.size () >= 2 )
353+ {
315354 messaget log{message_handler};
316355 log.error () << " multiple modules found, please select one:\n " ;
317356
318- for (const auto &module : modules )
357+ for (const auto &module : top_level_modules )
319358 log.error () << " " << module << ' \n ' ;
320359
321360 log.error () << messaget::eom;
322361 throw ebmc_errort{}.with_exit_code (1 );
323362 }
324363
325- // we have exactly one top-level module
326- return *top_level_modules.begin ();
327- }
364+ auto top_level_module = top_level_modules.front ();
328365
329- static bool get_main (
330- irep_idt top_level_module,
331- message_handlert &message_handler,
332- transition_systemt &transition_system)
333- {
334366 try
335367 {
336368 auto identifier = verilog_module_symbol (top_level_module);
@@ -448,9 +480,9 @@ std::optional<transition_systemt> verilog_ebmc_languaget::transition_system()
448480 symbol_tablet symbol_table = elaborate_compilation_units (parse_trees);
449481
450482 //
451- // determine the top-level module
483+ // determine the top-level modules
452484 //
453- auto top_level_module = this ->top_level_module (parse_trees);
485+ auto top_level_modules = this ->top_level_modules (parse_trees);
454486
455487 //
456488 // type checking
@@ -459,15 +491,15 @@ std::optional<transition_systemt> verilog_ebmc_languaget::transition_system()
459491 message.status () << " Converting" << messaget::eom;
460492
461493 auto transition_system =
462- typecheck (parse_trees, top_level_module , std::move (symbol_table));
494+ typecheck (parse_trees, top_level_modules , std::move (symbol_table));
463495
464496 if (cmdline.isset (" show-symbol-table" ))
465497 {
466498 std::cout << transition_system.symbol_table ;
467499 return {};
468500 }
469501
470- if (get_main (top_level_module , message_handler, transition_system))
502+ if (get_main (top_level_modules , message_handler, transition_system))
471503 throw ebmc_errort{}.with_exit_code (1 );
472504
473505 if (cmdline.isset (" show-module-hierarchy" ))
0 commit comments