HAL  v4.5.0-133-g64838ea8d
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
verilog_parser.cpp
Go to the documentation of this file.
2 
10 
11 #include <fstream>
12 #include <iomanip>
13 #include <numeric>
14 #include <queue>
15 
16 namespace hal
17 {
18  namespace
19  {
20 
21  } // namespace
22 
23  Result<std::monostate> VerilogParser::parse(const std::filesystem::path& file_path)
24  {
25  m_path = file_path;
26  m_modules.clear();
27  m_modules_by_name.clear();
28 
29  {
30  std::ifstream ifs;
31  ifs.open(file_path.string(), std::ifstream::in);
32  if (!ifs.is_open())
33  {
34  return ERR("could not parse Verilog file '" + m_path.string() + "' : unable to open file");
35  }
36  m_fs << ifs.rdbuf();
37  ifs.close();
38  }
39 
40  // tokenize file
41  tokenize();
42 
43  // parse tokens into intermediate format
44  try
45  {
46  if (auto res = parse_tokens(); res.is_error())
47  {
48  return ERR_APPEND(res.get_error(), "could not parse Verilog file '" + file_path.string() + "': unable to parse tokens");
49  }
50  }
52  {
53  if (e.line_number != (u32)-1)
54  {
55  return ERR("could not parse Verilog file '" + m_path.string() + "': " + e.message + " (line " + std::to_string(e.line_number) + ")");
56  }
57  else
58  {
59  return ERR("could not parse Verilog file '" + m_path.string() + "': " + e.message);
60  }
61  }
62 
63  if (m_modules.empty())
64  {
65  return ERR("could not parse Verilog file '" + m_path.string() + "': does not contain any modules");
66  }
67 
68  // expand module port identifiers, signals, and assignments
69  for (auto& [module_name, verilog_module] : m_modules_by_name)
70  {
71  // expand port identifiers
72  for (const auto& port : verilog_module->m_ports)
73  {
74  const bool stands_for_one_signal = port->m_expression_parts.size() == 1 && std::holds_alternative<identifier_t>(port->m_expression_parts.front());
75  if (!stands_for_one_signal)
76  {
77  // the width of the port is the width of its expression, whose signals are declared by now
78  const std::vector<std::string> expanded_expression = expand_assignment_expression(verilog_module, port->m_expression_parts);
79  if (expanded_expression.empty())
80  {
81  return ERR("could not parse Verilog file '" + m_path.string() + "': unable to expand the expression of port '" + port->m_identifier + "' of module '" + verilog_module->m_name + "'");
82  }
83  if (expanded_expression.size() == 1)
84  {
85  port->m_expanded_identifiers = {port->m_identifier};
86  }
87  else
88  {
89  std::vector<u32> range(expanded_expression.size());
90  std::iota(range.begin(), range.end(), 0);
91  port->m_ranges = {range};
92  port->m_expanded_identifiers = expand_ranges(port->m_identifier, port->m_ranges);
93  }
94  for (u32 i = 0; i < expanded_expression.size(); i++)
95  {
96  verilog_module->m_expanded_port_identifiers_to_expressions[port->m_expanded_identifiers.at(i)] = expanded_expression.at(i);
97  }
98  }
99  else if (const identifier_t& signal = std::get<identifier_t>(port->m_expression_parts.front()); signal != port->m_identifier)
100  {
101  // the port stands for one whole signal of another name, bit for bit
102  port->m_expanded_identifiers = port->m_ranges.empty() ? std::vector<std::string>{port->m_identifier} : expand_ranges(port->m_identifier, port->m_ranges);
103  const std::vector<std::string> expanded_expression = port->m_ranges.empty() ? std::vector<std::string>{signal} : expand_ranges(signal, port->m_ranges);
104  for (u32 i = 0; i < expanded_expression.size(); i++)
105  {
106  verilog_module->m_expanded_port_identifiers_to_expressions[port->m_expanded_identifiers.at(i)] = expanded_expression.at(i);
107  }
108  }
109  else
110  {
111  port->m_expanded_identifiers = port->m_ranges.empty() ? std::vector<std::string>{port->m_identifier} : expand_ranges(port->m_identifier, port->m_ranges);
112  }
113  }
114 
115  // expand signals
116  for (auto& signal : verilog_module->m_signals)
117  {
118  if (!signal->m_ranges.empty())
119  {
120  signal->m_expanded_names = expand_ranges(signal->m_name, signal->m_ranges);
121  }
122  else
123  {
124  signal->m_expanded_names = std::vector<std::string>({signal->m_name});
125  }
126  }
127 
128  // expand assignments
129  for (auto& assignment : verilog_module->m_assignments)
130  {
131  const std::vector<std::string> left_signals = expand_assignment_expression(verilog_module, assignment.m_variable);
132  const std::vector<std::string> right_signals = expand_assignment_expression(verilog_module, assignment.m_assignment);
133  if (left_signals.empty() || right_signals.empty())
134  {
135  return ERR("could not parse Verilog file '" + m_path.string() + "': unable to expand assignments within module '" + verilog_module->m_name + "'");
136  }
137 
138  u32 left_size = left_signals.size();
139  u32 right_size = right_signals.size();
140  if (left_size <= right_size)
141  {
142  // cut off redundant bits
143  for (u32 i = 0; i < left_size; i++)
144  {
145  verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i), right_signals.at(i)));
146  }
147  }
148  else
149  {
150  for (u32 i = 0; i < right_size; i++)
151  {
152  verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i), right_signals.at(i)));
153  }
154 
155  // implicit "0"
156  for (u32 i = 0; i < left_size - right_size; i++)
157  {
158  verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i + right_size), "'0'"));
159  }
160  }
161  }
162  }
163 
164  // expand module port assignments
165  for (auto& [module_name, verilog_module] : m_modules_by_name)
166  {
167  for (auto& instance : verilog_module->m_instances)
168  {
169  if (auto module_it = m_modules_by_name.find(instance->m_type); module_it != m_modules_by_name.end())
170  {
171  instance->m_is_module = true;
172  if (!instance->m_port_assignments.empty())
173  {
174  // all port assignments by name
175  if (instance->m_port_assignments.front().m_port_name.has_value())
176  {
177  for (const auto& port_assignment : instance->m_port_assignments)
178  {
179  const std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
180  if (!right_port.empty())
181  {
182  VerilogPort* port;
183  if (const auto port_it = module_it->second->m_ports_by_identifier.find(port_assignment.m_port_name.value());
184  port_it == module_it->second->m_ports_by_identifier.end())
185  {
186  return ERR("could not parse Verilog file '" + m_path.string() + "': unable to assign signal to port '" + port_assignment.m_port_name.value()
187  + "' as it is not a port of module '" + module_it->first + "'");
188  }
189  else
190  {
191  port = port_it->second;
192  }
193  const std::vector<std::string>& left_port = port->m_expanded_identifiers;
194  if (left_port.empty())
195  {
196  return ERR("could not parse Verilog file '" + m_path.string() + "': unable to expand port assignment");
197  }
198 
199  u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
200 
201  for (u32 i = 0; i < max_size; i++)
202  {
203  instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
204  }
205  }
206  }
207  }
208  // all port assignments by order
209  else
210  {
211  std::vector<std::string> ports;
212  for (const auto& port : m_modules_by_name.at(instance->m_type)->m_ports)
213  {
214  ports.insert(ports.end(), port->m_expanded_identifiers.begin(), port->m_expanded_identifiers.end());
215  }
216 
217  auto port_it = ports.begin();
218 
219  for (const auto& port_assignment : instance->m_port_assignments)
220  {
221  std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
222  if (!right_port.empty())
223  {
224  std::vector<std::string> left_port;
225 
226  for (u32 i = 0; i < right_port.size() && port_it != ports.end(); i++)
227  {
228  left_port.push_back(*port_it++);
229  }
230 
231  u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
232 
233  for (u32 i = 0; i < max_size; i++)
234  {
235  instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
236  }
237  }
238  }
239  }
240  }
241  }
242  }
243  }
244 
245  return OK({});
246  }
247 
249  {
250  // create empty netlist
251  std::unique_ptr<Netlist> result = netlist_factory::create_netlist(gate_library);
252  m_netlist = result.get();
253  if (m_netlist == nullptr)
254  {
255  return ERR("could not instantiate Verilog netlist '" + m_path.string() + "' with gate library '" + gate_library->get_name() + "': failed to create empty netlist");
256  }
257 
258  m_gate_types.clear();
259  m_gnd_gate_types.clear();
260  m_vcc_gate_types.clear();
261  m_module_instantiation_count.clear();
262  m_instance_name_occurences.clear();
263  m_net_name_occurences.clear();
264  m_net_by_name.clear();
265  m_nets_to_merge.clear();
266  m_module_ports.clear();
267  m_module_port_by_net.clear();
268  for (const auto& verilog_module : m_modules)
269  {
270  for (const auto& instance : verilog_module->m_instances)
271  {
272  if (!instance->m_is_module)
273  {
274  instance->m_expanded_port_assignments.clear();
275  }
276  }
277  }
278 
279  // buffer gate types
280  m_gate_types = gate_library->get_gate_types();
281  m_gnd_gate_types = gate_library->get_gnd_gate_types();
282  m_vcc_gate_types = gate_library->get_vcc_gate_types();
283 
284  // create const 0 and const 1 net, will be removed if unused
285  m_zero_net = m_netlist->create_net("'0'");
286  if (m_zero_net == nullptr)
287  {
288  return ERR("could not instantiate Verilog netlist '" + m_path.string() + "' with gate library '" + gate_library->get_name() + "': failed to create zero net");
289  }
290  m_net_by_name[m_zero_net->get_name()] = m_zero_net;
291 
292  m_one_net = m_netlist->create_net("'1'");
293  if (m_one_net == nullptr)
294  {
295  return ERR("could not instantiate Verilog netlist '" + m_path.string() + "' with gate library '" + gate_library->get_name() + "': failed to create one net");
296  }
297  m_net_by_name[m_one_net->get_name()] = m_one_net;
298 
299  // a module marked (* top = 1 *), as Yosys does, is the top module; otherwise it is the one module nobody instantiates
300  std::vector<std::string> marked_top_modules;
301  for (const auto& [name, module] : m_modules_by_name)
302  {
303  for (const VerilogDataEntry& attribute : module->m_attributes)
304  {
305  if (attribute.m_name == "top" && utils::trim(attribute.m_value) == "1")
306  {
307  marked_top_modules.push_back(name);
308  break;
309  }
310  }
311  }
312  if (marked_top_modules.size() > 1)
313  {
314  return ERR("could not instantiate Verilog netlist '" + m_path.string() + "' with gate library '" + gate_library->get_name() + "': several modules carry the top attribute: "
315  + utils::join(", ", marked_top_modules));
316  }
317 
318  std::map<std::string, u32> module_name_to_refereneces;
319  for (const auto& [_name, module] : m_modules_by_name)
320  {
321  for (const auto& instance : module->m_instances)
322  {
323  if (const auto it = m_modules_by_name.find(instance->m_type); it != m_modules_by_name.end())
324  {
325  module_name_to_refereneces[it->first]++;
326  }
327  }
328  }
329 
330  std::vector<std::string> top_module_candidates = marked_top_modules;
331  if (top_module_candidates.empty())
332  {
333  for (const auto& [name, module] : m_modules_by_name)
334  {
335  if (module_name_to_refereneces.find(name) == module_name_to_refereneces.end())
336  {
337  top_module_candidates.push_back(name);
338  }
339  }
340  }
341 
342  if (top_module_candidates.empty())
343  {
344  return ERR("could not instantiate Verilog netlist '" + m_path.string() + "' with gate library '" + gate_library->get_name() + "': unable to find any top module candidates");
345  }
346 
347  if (top_module_candidates.size() > 1)
348  {
349  return ERR("could not instantiate Verilog netlist '" + m_path.string() + "' with gate library '" + gate_library->get_name()
350  + "': found multiple modules as candidates for the top module, none of them marked (* top = 1 *): " + utils::join(", ", top_module_candidates));
351  }
352 
353  // construct the netlist with the the top module
354  VerilogModule* top_module = m_modules_by_name.at(top_module_candidates.front());
355 
356  if (const auto res = construct_netlist(top_module); res.is_error())
357  {
358  return ERR_APPEND(res.get_error(), "could not instantiate Verilog netlist '" + m_path.string() + "' with gate library '" + gate_library->get_name() + "': unable to construct netlist");
359  }
360 
361  // delete unused nets
362  std::queue<Net*> nets_to_be_deleted;
363 
364  for (auto net : m_netlist->get_nets())
365  {
366  const u32 num_of_sources = net->get_num_of_sources();
367  const u32 num_of_destinations = net->get_num_of_destinations();
368  const bool no_source = num_of_sources == 0 && !(net->is_global_input_net() && num_of_destinations != 0);
369  const bool no_destination = num_of_destinations == 0 && !(net->is_global_output_net() && num_of_sources != 0);
370  if (no_source && no_destination)
371  {
372  nets_to_be_deleted.push(net);
373  }
374  }
375 
376  while (!nets_to_be_deleted.empty())
377  {
378  Net* net = nets_to_be_deleted.front();
379  nets_to_be_deleted.pop();
380  m_netlist->delete_net(net);
381  }
382 
383  m_netlist->load_gate_locations_from_data();
384 
385  return OK(std::move(result));
386  }
387 
388  // ###########################################################################
389  // ########### Parse HDL into Intermediate Format ##########
390  // ###########################################################################
391 
392  void VerilogParser::tokenize()
393  {
394  const std::string delimiters = "`,()[]{}\\#*: ;=./";
395  std::string current_token;
396  u32 line_number = 0;
397 
398  std::string line;
399  char prev_char = 0;
400  bool in_string = false;
401  bool escaped = false;
402  bool in_comment = false;
403 
404  std::vector<Token<std::string>> parsed_tokens;
405  while (std::getline(m_fs, line))
406  {
407  line_number++;
408  // this->remove_comments(line, multi_line_comment);
409 
410  for (char c : line)
411  {
412  // deal with comments
413  if (in_comment)
414  {
415  if (c == '/' && prev_char == '*')
416  {
417  in_comment = false;
418  }
419 
420  prev_char = c;
421  continue;
422  }
423 
424  // deal with escaping and strings
425  if (!in_string && c == '\\')
426  {
427  escaped = true;
428  continue;
429  }
430  else if (escaped && std::isspace(c))
431  {
432  escaped = false;
433  continue;
434  }
435  else if (!escaped && c == '"')
436  {
437  in_string = !in_string;
438  }
439 
440  if (!in_comment && ((!std::isspace(c) && delimiters.find(c) == std::string::npos) || escaped || in_string))
441  {
442  current_token += c;
443  }
444  else
445  {
446  // deal with floats
447  if (!current_token.empty())
448  {
449  if (parsed_tokens.size() > 1 && utils::is_digits(parsed_tokens.at(parsed_tokens.size() - 2).string) && parsed_tokens.at(parsed_tokens.size() - 1) == "."
450  && utils::is_digits(current_token))
451  {
452  parsed_tokens.pop_back();
453  parsed_tokens.back() += "." + current_token;
454  }
455  else
456  {
457  parsed_tokens.emplace_back(line_number, current_token);
458  }
459  current_token.clear();
460  }
461 
462  if (!parsed_tokens.empty())
463  {
464  // deal with multi-character tokens
465  if (c == '(' && parsed_tokens.back() == "#")
466  {
467  parsed_tokens.back() = "#(";
468  continue;
469  }
470  else if (c == '*' && parsed_tokens.back() == "(")
471  {
472  parsed_tokens.back() = "(*";
473  continue;
474  }
475  else if (c == ')' && parsed_tokens.back() == "*")
476  {
477  parsed_tokens.back() = "*)";
478  continue;
479  }
480  // start a comment
481  else if (c == '/' && parsed_tokens.back() == "/")
482  {
483  parsed_tokens.pop_back();
484  break;
485  }
486  else if (c == '*' && parsed_tokens.back() == "/")
487  {
488  in_comment = true;
489  parsed_tokens.pop_back();
490  continue;
491  }
492  }
493 
494  if (!std::isspace(c))
495  {
496  parsed_tokens.emplace_back(line_number, std::string(1, c));
497  }
498  }
499  }
500  if (!current_token.empty())
501  {
502  parsed_tokens.emplace_back(line_number, current_token);
503  current_token.clear();
504  }
505  }
506 
507  m_token_stream = TokenStream(parsed_tokens, {"(", "["}, {")", "]"});
508  }
509 
510  Result<std::monostate> VerilogParser::parse_tokens()
511  {
512  std::vector<VerilogDataEntry> attributes;
513  u32 line_number;
514 
515  while (m_token_stream.remaining() > 0)
516  {
517  if (m_token_stream.peek() == "(*")
518  {
519  parse_attribute(attributes);
520  }
521  else if (m_token_stream.peek() == "`")
522  {
523  m_token_stream.consume_current_line();
524  log_warning("verilog_parser", "could not parse compiler directives.");
525  }
526  else
527  {
528  line_number = m_token_stream.peek().number;
529  if (auto res = parse_module(attributes); res.is_error())
530  {
531  return ERR_APPEND(res.get_error(), "could not parse tokens: unable to parse module (line " + std::to_string(line_number) + ")");
532  }
533  }
534  }
535 
536  return OK({});
537  }
538 
539  Result<std::monostate> VerilogParser::parse_module(std::vector<VerilogDataEntry>& attributes)
540  {
541  std::set<std::string> port_names;
542  std::vector<VerilogDataEntry> internal_attributes;
543 
544  m_token_stream.consume("module", true);
545  const u32 line_number = m_token_stream.peek().number;
546  const std::string module_name = m_token_stream.consume();
547 
548  // verify entity name
549  if (const auto it = m_modules_by_name.find(module_name); it != m_modules_by_name.end())
550  {
551  return ERR("could not parse module '" + module_name + "' (line " + std::to_string(line_number) + "): a module with the same name already exists (line "
552  + std::to_string(it->second->m_line_number) + ")");
553  }
554 
555  auto verilog_module = std::make_unique<VerilogModule>();
556  VerilogModule* verilog_module_raw = verilog_module.get();
557  verilog_module_raw->m_line_number = line_number;
558  verilog_module_raw->m_name = module_name;
559 
560  // parse parameter list
561  if (m_token_stream.consume("#("))
562  {
563  // TODO add support for parameter parsing
564  m_token_stream.consume_until(")");
565  m_token_stream.consume(")", true);
566  log_warning("verilog_parser", "could not parse parameter list provided for module '{}'.", module_name);
567  }
568 
569  // parse port (declaration) list
570  m_token_stream.consume("(", true);
571  Token<std::string> next_token = m_token_stream.peek();
572  if (next_token == "input" || next_token == "output" || next_token == "inout")
573  {
574  if (auto res = parse_port_declaration_list(verilog_module_raw); res.is_error())
575  {
576  return ERR_APPEND(res.get_error(), "could not parse module '" + module_name + "': unable to parse port declaration list (line " + std::to_string(line_number) + ")");
577  }
578  }
579  else
580  {
581  if (auto res = parse_port_list(verilog_module_raw); res.is_error())
582  {
583  return ERR_APPEND(res.get_error(), "could not parse module '" + module_name + "' (line " + std::to_string(line_number) + "): unable to parse port list");
584  }
585  }
586 
587  m_token_stream.consume(";", true);
588 
589  next_token = m_token_stream.peek();
590  while (next_token != "endmodule")
591  {
592  if (next_token == "input" || next_token == "output" || next_token == "inout")
593  {
594  if (auto res = parse_port_definition(verilog_module_raw, internal_attributes); res.is_error())
595  {
596  return ERR_APPEND(res.get_error(), "could not parse module '" + module_name + "': unable to parse port definition (line " + std::to_string(line_number) + ")");
597  }
598  }
599  else if (next_token == "wire" || next_token == "tri")
600  {
601  if (auto res = parse_signal_definition(verilog_module_raw, internal_attributes); res.is_error())
602  {
603  return ERR_APPEND(res.get_error(), "could not parse module '" + module_name + "': unable to parse signal definition (line " + std::to_string(line_number) + ")");
604  }
605  }
606  else if (next_token == "parameter")
607  {
608  // TODO add support for parameter parsing
609  m_token_stream.consume_until(";");
610  m_token_stream.consume(";", true);
611  log_warning("verilog_parser", "could not parse parameter provided for module '{}'.", module_name);
612  }
613  else if (next_token == "assign")
614  {
615  if (auto res = parse_assignment(verilog_module_raw); res.is_error())
616  {
617  return ERR_APPEND(res.get_error(), "could not parse module '" + module_name + "': unable to parse assignment (line " + std::to_string(line_number) + ")");
618  }
619  }
620  else if (next_token == "defparam")
621  {
622  if (auto res = parse_defparam(verilog_module_raw); res.is_error())
623  {
624  return ERR_APPEND(res.get_error(), "could not parse module '" + module_name + "': unable to parse defparam (line " + std::to_string(line_number) + ")");
625  }
626  }
627  else if (next_token == "(*")
628  {
629  parse_attribute(internal_attributes);
630  }
631  else
632  {
633  if (auto res = parse_instance(verilog_module_raw, internal_attributes); res.is_error())
634  {
635  return ERR_APPEND(res.get_error(), "could not parse module '" + module_name + "': unable to parse instance (line " + std::to_string(line_number) + ")");
636  }
637  }
638 
639  next_token = m_token_stream.peek();
640  }
641 
642  m_token_stream.consume("endmodule", true);
643 
644  // assign attributes to entity
645  if (!attributes.empty())
646  {
647  verilog_module->m_attributes.insert(verilog_module->m_attributes.end(), attributes.begin(), attributes.end());
648  attributes.clear();
649  }
650 
651  // add to collection of entities
652  m_modules.push_back(std::move(verilog_module));
653  m_modules_by_name[module_name] = verilog_module_raw;
654  m_last_module = module_name;
655 
656  return OK({});
657  }
658 
659  Result<std::monostate> VerilogParser::parse_port_list(VerilogModule* verilog_module)
660  {
661  TokenStream<std::string> ports_stream = m_token_stream.extract_until(")");
662  m_token_stream.consume(")", true);
663 
664  while (ports_stream.remaining() > 0)
665  {
666  Token<std::string> next_token = ports_stream.consume();
667  auto port = std::make_unique<VerilogPort>();
668 
669  if (next_token == ".")
670  {
671  port->m_identifier = ports_stream.consume().string;
672  ports_stream.consume("(", true);
673  TokenStream<std::string> expression_stream = ports_stream.extract_until(")");
674  ports_stream.consume(")", true);
675 
676  // a port expression is anything a right-hand side may be: a signal, a slice of one, or a concatenation
677  // of those, which Vivado writes for a port that is partly constant, e.g. .sum({<const0> ,\^sum [1:0]})
678  auto parts_res = parse_assignment_expression(std::move(expression_stream));
679  if (parts_res.is_error())
680  {
681  return ERR_APPEND(parts_res.get_error(), "could not parse port list: invalid expression of port '" + port->m_identifier + "' (line " + std::to_string(next_token.number) + ")");
682  }
683  port->m_expression_parts = parts_res.get();
684  }
685  else
686  {
687  port->m_identifier = next_token.string;
688  port->m_expression_parts = {identifier_t(next_token.string)};
689  }
690 
691  // the body declares direction and width on the signals the port stands for, so each of them has to find the port
692  for (const auto& part : port->m_expression_parts)
693  {
694  if (const identifier_t* identifier = std::get_if<identifier_t>(&part); identifier != nullptr)
695  {
696  verilog_module->m_ports_by_expression[*identifier] = port.get();
697  }
698  else if (const ranged_identifier_t* ranged = std::get_if<ranged_identifier_t>(&part); ranged != nullptr)
699  {
700  verilog_module->m_ports_by_expression[ranged->first] = port.get();
701  }
702  }
703 
704  verilog_module->m_ports_by_identifier[port->m_identifier] = port.get();
705  verilog_module->m_ports.push_back(std::move(port));
706 
707  ports_stream.consume(",", ports_stream.remaining() > 0);
708  }
709 
710  return OK({});
711  }
712 
713  Result<std::monostate> VerilogParser::parse_port_declaration_list(VerilogModule* verilog_module)
714  {
715  TokenStream<std::string> ports_stream = m_token_stream.extract_until(")");
716  m_token_stream.consume(")", true);
717 
718  while (ports_stream.remaining() > 0)
719  {
720  // direction
721  const Token<std::string> direction_token = ports_stream.consume();
722  PinDirection direction = enum_from_string<PinDirection>(direction_token.string, PinDirection::none);
724  {
725  return ERR("could not parse port declaration list: invalid direction '" + direction_token.string + "' (line " + std::to_string(direction_token.number) + ")");
726  }
727 
728  // ranges
729  std::vector<std::vector<u32>> ranges;
730  while (ports_stream.consume("["))
731  {
732  const std::vector<u32> range = parse_range(ports_stream);
733  ports_stream.consume("]", true);
734 
735  ranges.emplace_back(range);
736  }
737 
738  // port expressions
739  do
740  {
741  const Token<std::string> next_token = ports_stream.peek();
742  if (next_token == "input" || next_token == "output" || next_token == "inout")
743  {
744  break;
745  }
746  ports_stream.consume();
747 
748  auto port = std::make_unique<VerilogPort>();
749  const std::string& port_expression = next_token.string;
750  port->m_identifier = port_expression;
751  port->m_expression_parts = {identifier_t(port_expression)};
752  port->m_direction = direction;
753  if (!ranges.empty())
754  {
755  port->m_ranges = ranges;
756  }
757  verilog_module->m_ports_by_identifier[port_expression] = port.get();
758  verilog_module->m_ports_by_expression[port_expression] = port.get();
759  verilog_module->m_ports.push_back(std::move(port));
760 
761  // every port implicitly creates a wire, so create signal if not already declared explicitly
762  if (verilog_module->m_signals_by_name.find(port_expression) == verilog_module->m_signals_by_name.end())
763  {
764  auto signal = std::make_unique<VerilogSignal>();
765  signal->m_name = port_expression;
766  if (!ranges.empty())
767  {
768  signal->m_ranges = ranges;
769  }
770  verilog_module->m_signals_by_name[port_expression] = signal.get();
771  verilog_module->m_signals.push_back(std::move(signal));
772  }
773  } while (ports_stream.consume(",", ports_stream.remaining() > 0));
774  }
775 
776  return OK({});
777  }
778 
779  Result<std::monostate> VerilogParser::parse_port_definition(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
780  {
781  // port direction
782  const Token<std::string> direction_token = m_token_stream.consume();
783  PinDirection direction = enum_from_string<PinDirection>(direction_token.string, PinDirection::none);
785  {
786  return ERR("could not parse port definition: invalid direction '" + direction_token.string + "' (line " + std::to_string(direction_token.number) + ")");
787  }
788 
789  // ranges
790  std::vector<std::vector<u32>> ranges;
791  while (m_token_stream.consume("["))
792  {
793  const std::vector<u32> range = parse_range(m_token_stream);
794  m_token_stream.consume("]", true);
795 
796  ranges.emplace_back(range);
797  }
798 
799  // port expressions
800  do
801  {
802  Token<std::string> port_expression_token = m_token_stream.consume();
803  std::string port_expression = port_expression_token.string;
804 
805  VerilogPort* port;
806  if (const auto it = verilog_module->m_ports_by_expression.find(port_expression); it == verilog_module->m_ports_by_expression.end())
807  {
808  return ERR("could not parse port definition: a port with name '" + port_expression + "' does not exist for module '" + verilog_module->m_name + "' (line "
809  + std::to_string(direction_token.number) + ")");
810  }
811  else
812  {
813  port = it->second;
814  }
815 
816  port->m_direction = direction;
817  // the ranges of a concatenation's signals belong to those signals, the port's width follows from the expression
818  const bool stands_for_one_signal = port->m_expression_parts.size() == 1 && std::holds_alternative<identifier_t>(port->m_expression_parts.front());
819  if (!ranges.empty() && stands_for_one_signal)
820  {
821  port->m_ranges = ranges;
822  }
823 
824  // every port implicitly creates a wire, so create signal if not already declared explicitly
825  if (const auto signal_it = verilog_module->m_signals_by_name.find(port_expression); signal_it == verilog_module->m_signals_by_name.end())
826  {
827  auto signal = std::make_unique<VerilogSignal>();
828  signal->m_name = port_expression;
829  if (!ranges.empty())
830  {
831  signal->m_ranges = ranges;
832  }
833  signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
834  verilog_module->m_signals_by_name[port_expression] = signal.get();
835  verilog_module->m_signals.push_back(std::move(signal));
836  }
837  else
838  {
839  auto* signal = signal_it->second;
840  signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
841  }
842  } while (m_token_stream.consume(",", false));
843 
844  m_token_stream.consume(";", true);
845  attributes.clear();
846 
847  return OK({});
848  }
849 
850  Result<std::monostate> VerilogParser::parse_signal_definition(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
851  {
852  // consume "wire" or "tri"
853  u32 line_number = m_token_stream.consume().number;
854 
855  TokenStream<std::string> signal_stream = m_token_stream.extract_until(";");
856  m_token_stream.consume(";", true);
857 
858  // extract bounds
859  std::vector<std::vector<u32>> ranges;
860  while (signal_stream.consume("["))
861  {
862  const std::vector<u32> range = parse_range(signal_stream);
863  signal_stream.consume("]", true);
864 
865  ranges.emplace_back(range);
866  }
867 
868  // extract names
869  do
870  {
871  Token<std::string> signal_name = signal_stream.consume();
872  if (signal_stream.remaining() > 0 && signal_stream.peek() == "=")
873  {
874  VerilogAssignment assignment;
875  assignment.m_variable.push_back(signal_name);
876  signal_stream.consume("=", true);
877  if (auto res = parse_assignment_expression(signal_stream.extract_until(",")); res.is_error())
878  {
879  return ERR_APPEND(res.get_error(), "could not parse signal definition: unable to parse assignment expression (line " + std::to_string(line_number) + ")");
880  }
881  else
882  {
883  assignment.m_assignment = res.get();
884  }
885  verilog_module->m_assignments.push_back(std::move(assignment));
886  }
887 
888  // create signal if not already implicitly declared otherwise
889  if (const auto signal_it = verilog_module->m_signals_by_name.find(signal_name.string); signal_it == verilog_module->m_signals_by_name.end())
890  {
891  auto signal = std::make_unique<VerilogSignal>();
892  signal->m_name = signal_name.string;
893  if (!ranges.empty())
894  {
895  signal->m_ranges = ranges;
896  }
897  signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
898  verilog_module->m_signals_by_name[signal_name.string] = signal.get();
899  verilog_module->m_signals.push_back(std::move(signal));
900  }
901  else
902  {
903  auto* signal = signal_it->second;
904  signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
905  }
906 
907  } while (signal_stream.consume(",", false));
908 
909  attributes.clear();
910 
911  return OK({});
912  }
913 
914  Result<std::monostate> VerilogParser::parse_assignment(VerilogModule* verilog_module)
915  {
916  m_token_stream.consume("assign", true);
917  u32 line_number = m_token_stream.peek().number;
918  VerilogAssignment assignment;
919 
920  if (auto res = parse_assignment_expression(m_token_stream.extract_until("=")); res.is_error())
921  {
922  return ERR_APPEND(res.get_error(), "could not parse assignment: unable to parse assignment expression (line " + std::to_string(line_number) + ")");
923  }
924  else
925  {
926  assignment.m_variable = res.get();
927  }
928  m_token_stream.consume("=", true);
929 
930  if (auto res = parse_assignment_expression(m_token_stream.extract_until(";")); res.is_error())
931  {
932  return ERR_APPEND(res.get_error(), "could not parse assignment: unable to parse assignment expression (line " + std::to_string(line_number) + ")");
933  }
934  else
935  {
936  assignment.m_assignment = res.get();
937  }
938 
939  // every assignment implicitly creates a wire, so create signal if not already declared explicitly
940  for (const auto& var : assignment.m_variable)
941  {
942  if (const auto* identifier = std::get_if<identifier_t>(&var); identifier != nullptr)
943  {
944  if (verilog_module->m_signals_by_name.find(*identifier) == verilog_module->m_signals_by_name.end())
945  {
946  auto signal = std::make_unique<VerilogSignal>();
947  signal->m_name = *identifier;
948  verilog_module->m_signals_by_name[*identifier] = signal.get();
949  verilog_module->m_signals.push_back(std::move(signal));
950  }
951  }
952  else if (const auto* ranged_identifier = std::get_if<ranged_identifier_t>(&var); ranged_identifier != nullptr)
953  {
954  const auto& signal_name = std::get<0>(*ranged_identifier);
955  if (verilog_module->m_signals_by_name.find(signal_name) == verilog_module->m_signals_by_name.end())
956  {
957  auto signal = std::make_unique<VerilogSignal>();
958  signal->m_name = signal_name;
959  signal->m_ranges = std::get<1>(*ranged_identifier);
960  verilog_module->m_signals_by_name[signal_name] = signal.get();
961  verilog_module->m_signals.push_back(std::move(signal));
962  }
963  }
964  }
965  m_token_stream.consume(";", true);
966 
967  verilog_module->m_assignments.push_back(std::move(assignment));
968  return OK({});
969  }
970 
971  Result<std::monostate> VerilogParser::parse_defparam(VerilogModule* module)
972  {
973  m_token_stream.consume("defparam", true);
974  std::string instance_name = m_token_stream.consume().string;
975  m_token_stream.consume(".", true);
976 
977  if (const auto inst_it = module->m_instances_by_name.find(instance_name); inst_it != module->m_instances_by_name.end())
978  {
979  VerilogDataEntry param;
980  param.m_name = m_token_stream.consume().string;
981  m_token_stream.consume("=", true);
982 
983  if (const auto res = parse_parameter_value(m_token_stream.consume()); res.is_ok())
984  {
985  const auto value = res.get();
986  param.m_type = value.first;
987  param.m_value = value.second;
988  inst_it->second->m_parameters.push_back(param);
989  }
990  else
991  {
992  log_warning("verilog_parser", "{}", res.get_error().get());
993  }
994  }
995  else
996  {
997  m_token_stream.consume(";", true);
998  return ERR("could not parse defparam: no instance with name '" + instance_name + "' exists within module '" + module->m_name + "'");
999  }
1000 
1001  m_token_stream.consume(";", true);
1002  return OK({});
1003  }
1004 
1005  void VerilogParser::parse_attribute(std::vector<VerilogDataEntry>& attributes)
1006  {
1007  m_token_stream.consume("(*", true);
1008 
1009  // extract attributes
1010  do
1011  {
1012  VerilogDataEntry attribute;
1013  attribute.m_name = m_token_stream.consume().string;
1014 
1015  // attribute value specified?
1016  if (m_token_stream.consume("="))
1017  {
1018  attribute.m_value = m_token_stream.consume();
1019 
1020  // remove "
1021  if (attribute.m_value[0] == '\"' && attribute.m_value.back() == '\"')
1022  {
1023  attribute.m_value = attribute.m_value.substr(1, attribute.m_value.size() - 2);
1024  }
1025  }
1026 
1027  attributes.push_back(std::move(attribute));
1028 
1029  } while (m_token_stream.consume(",", false));
1030 
1031  m_token_stream.consume("*)", true);
1032  }
1033 
1034  Result<std::monostate> VerilogParser::parse_instance(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
1035  {
1036  auto instance = std::make_unique<VerilogInstance>();
1037  u32 line_number = m_token_stream.peek().number;
1038  instance->m_type = m_token_stream.consume().string;
1039 
1040  // parse generics map
1041  if (m_token_stream.consume("#("))
1042  {
1043  if (auto res = parse_parameter_assign(); res.is_error())
1044  {
1045  return ERR_APPEND(res.get_error(), "could not parse instance of type '" + instance->m_type + "': unable to parse parameter assignment (line " + std::to_string(line_number) + ")");
1046  }
1047  else
1048  {
1049  instance->m_parameters = res.get();
1050  }
1051  }
1052 
1053  // parse instance name
1054  instance->m_name = m_token_stream.consume().string;
1055 
1056  // parse port map
1057  if (auto res = parse_port_assign(instance.get()); res.is_error())
1058  {
1059  return ERR_APPEND(res.get_error(),
1060  "could not parse instance '" + instance->m_name + "' of type '" + instance->m_type + "': unable to parse port assignment (line " + std::to_string(line_number) + ")");
1061  }
1062 
1063  // assign attributes to instance
1064  instance->m_attributes = attributes;
1065  attributes.clear();
1066 
1067  verilog_module->m_instances_by_name[instance->m_name] = instance.get();
1068  verilog_module->m_instances.push_back(std::move(instance));
1069 
1070  return OK({});
1071  }
1072 
1073  Result<std::monostate> VerilogParser::parse_port_assign(VerilogInstance* instance)
1074  {
1075  u32 line_number = m_token_stream.peek().number;
1076  m_token_stream.consume("(", true);
1077  u32 line_end = m_token_stream.find_next(";");
1078  if (m_token_stream.peek() == ".")
1079  {
1080  do
1081  {
1082  m_token_stream.consume(".");
1083  VerilogPortAssignment port_assignment;
1084  port_assignment.m_port_name = m_token_stream.consume().string;
1085  m_token_stream.consume("(", true);
1086  if (auto res = parse_assignment_expression(m_token_stream.extract_until(")")); res.is_error())
1087  {
1088  return ERR_APPEND(res.get_error(), "could not parse port assignment: unable to parse assignment expression (line " + std::to_string(line_number) + ")");
1089  }
1090  else
1091  {
1092  port_assignment.m_assignment = res.get();
1093  }
1094  m_token_stream.consume(")", true);
1095  if (port_assignment.m_assignment.empty())
1096  {
1097  continue;
1098  }
1099  instance->m_port_assignments.push_back(std::move(port_assignment));
1100  } while (m_token_stream.consume(",", false));
1101  }
1102  else
1103  {
1104  do
1105  {
1106  VerilogPortAssignment port_assignment;
1107  if (auto res = parse_assignment_expression(m_token_stream.extract_until(",", line_end - 1)); res.is_error())
1108  {
1109  return ERR_APPEND(res.get_error(), "could not parse port assignment: unable to parse assignment expression (line " + std::to_string(line_number) + ")");
1110  }
1111  else
1112  {
1113  port_assignment.m_assignment = res.get();
1114  }
1115  if (port_assignment.m_assignment.empty())
1116  {
1117  continue;
1118  }
1119  instance->m_port_assignments.push_back(std::move(port_assignment));
1120  } while (m_token_stream.consume(",", false));
1121  }
1122 
1123  m_token_stream.consume(")", true);
1124  m_token_stream.consume(";", true);
1125 
1126  return OK({});
1127  }
1128 
1129  Result<std::vector<VerilogParser::VerilogDataEntry>> VerilogParser::parse_parameter_assign()
1130  {
1131  std::vector<VerilogDataEntry> generics;
1132 
1133  do
1134  {
1135  if (m_token_stream.consume(".", false))
1136  {
1137  const Token<std::string> lhs = m_token_stream.join_until("(", "");
1138  m_token_stream.consume("(", true);
1139  const Token<std::string> rhs = m_token_stream.join_until(")", "");
1140  m_token_stream.consume(")", true);
1141 
1142  if (const auto res = parse_parameter_value(rhs); res.is_ok())
1143  {
1144  const auto value = res.get();
1145  generics.push_back(VerilogDataEntry({lhs.string, value.first, value.second}));
1146  }
1147  else
1148  {
1149  log_warning("verilog_parser", "{}", res.get_error().get());
1150  }
1151  }
1152  } while (m_token_stream.consume(",", false));
1153 
1154  m_token_stream.consume(")", true);
1155 
1156  return OK(generics);
1157  }
1158 
1159  // ###########################################################################
1160  // ########### Assemble Netlist from Intermediate Format ##########
1161  // ###########################################################################
1162 
1163  Result<std::monostate> VerilogParser::construct_netlist(VerilogModule* top_module)
1164  {
1165  m_netlist->set_design_name(top_module->m_name);
1166  m_netlist->enable_automatic_net_checks(false);
1167 
1168  // preparations for alias: count the occurences of all names
1169  std::queue<VerilogModule*> q;
1170  q.push(top_module);
1171 
1172  while (!q.empty())
1173  {
1174  VerilogModule* module = q.front();
1175  q.pop();
1176 
1177  m_module_instantiation_count[module->m_name]++;
1178 
1179  // collect and count all net names in the netlist
1180  for (const auto& s : module->m_signals)
1181  {
1182  std::vector<std::string> expanded_names;
1183  expand_ranges_recursively(expanded_names, s->m_name, s->m_ranges, 0);
1184  for (const auto& net_name : expanded_names)
1185  {
1186  m_net_name_occurences[net_name]++;
1187  }
1188  }
1189 
1190  for (const auto& instance : module->m_instances)
1191  {
1192  m_instance_name_occurences[instance->m_name]++;
1193 
1194  // add type of instance to q if it is a module
1195  if (const auto it = m_modules_by_name.find(instance->m_type); it != m_modules_by_name.end())
1196  {
1197  q.push(it->second);
1198  }
1199  }
1200  }
1201 
1202  for (auto& [module_name, verilog_module] : m_modules_by_name)
1203  {
1204  // detect unused modules
1205  if (m_module_instantiation_count[module_name] == 0)
1206  {
1207  log_warning("verilog_parser", "module '{}' has been defined in the netlist but is not instantiated.", module_name);
1208  continue;
1209  }
1210 
1211  // expand gate pin assignments
1212  for (const auto& instance : verilog_module->m_instances)
1213  {
1214  if (const auto gate_type_it = m_gate_types.find(instance->m_type); gate_type_it != m_gate_types.end())
1215  {
1216  if (!instance->m_port_assignments.empty())
1217  {
1218  // all port assignments by name
1219  if (instance->m_port_assignments.front().m_port_name.has_value())
1220  {
1221  // cache pin groups
1222  std::unordered_map<std::string, std::vector<std::string>> pin_groups;
1223  for (const auto pin_group : gate_type_it->second->get_pin_groups())
1224  {
1225  const auto pins = pin_group->get_pins();
1226  for (auto it = pins.rbegin(); it != pins.rend(); it++)
1227  {
1228  const auto* pin = *it;
1229  pin_groups[pin_group->get_name()].push_back(pin->get_name());
1230  }
1231  }
1232 
1233  for (const auto& port_assignment : instance->m_port_assignments)
1234  {
1235  std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
1236  if (!right_port.empty())
1237  {
1238  std::vector<std::string> left_port;
1239 
1240  const auto& port_name = port_assignment.m_port_name.value();
1241  if (const auto group_it = pin_groups.find(port_name); group_it != pin_groups.end())
1242  {
1243  left_port = group_it->second;
1244  }
1245  else
1246  {
1247  left_port.push_back(port_name);
1248  }
1249 
1250  u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
1251 
1252  for (u32 i = 0; i < max_size; i++)
1253  {
1254  instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
1255  }
1256  }
1257  }
1258  }
1259  // all port assignments by order
1260  else
1261  {
1262  // cache pins
1263  std::vector<std::string> pins = gate_type_it->second->get_pin_names();
1264  auto pin_it = pins.begin();
1265 
1266  for (const auto& port_assignment : instance->m_port_assignments)
1267  {
1268  std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
1269  if (!right_port.empty())
1270  {
1271  std::vector<std::string> left_port;
1272 
1273  for (u32 i = 0; i < right_port.size() && pin_it != pins.end(); i++)
1274  {
1275  left_port.push_back(*pin_it++);
1276  }
1277 
1278  u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
1279 
1280  for (u32 i = 0; i < max_size; i++)
1281  {
1282  instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
1283  }
1284  }
1285  }
1286  }
1287  }
1288  }
1289  }
1290  }
1291 
1292  // for the top module, generate global i/o signals for all ports
1293  std::unordered_map<std::string, std::string> top_assignments;
1294  for (const auto& port : top_module->m_ports)
1295  {
1296  for (const auto& expanded_port_identifier : port->m_expanded_identifiers)
1297  {
1298  const auto signal_name = get_unique_alias("", expanded_port_identifier + "__GLOBAL_IO__", m_net_name_occurences);
1299  m_net_name_occurences[signal_name]++;
1300 
1301  Net* global_port_net = m_netlist->create_net(signal_name);
1302  if (global_port_net == nullptr)
1303  {
1304  return ERR("could not construct netlist: failed to create global I/O net '" + signal_name + "'");
1305  }
1306 
1307  m_net_by_name[signal_name] = global_port_net;
1308 
1309  // assign global port nets to ports of top module
1310  top_assignments[expanded_port_identifier] = signal_name;
1311 
1312  if (port->m_direction == PinDirection::input || port->m_direction == PinDirection::inout)
1313  {
1314  if (!global_port_net->mark_global_input_net())
1315  {
1316  return ERR("could not construct netlist: failed to mark global I/O net '" + signal_name + "' as global input");
1317  }
1318  }
1319 
1320  if (port->m_direction == PinDirection::output || port->m_direction == PinDirection::inout)
1321  {
1322  if (!global_port_net->mark_global_output_net())
1323  {
1324  return ERR("could not construct netlist: failed to mark global I/O net '" + signal_name + "' as global output");
1325  }
1326  }
1327  }
1328  }
1329 
1330  if (auto res = instantiate_module("top_module", top_module, nullptr, top_assignments); res.is_error())
1331  {
1332  return ERR_APPEND(res.get_error(), "could not construct netlist: unable to instantiate top module");
1333  }
1334 
1335  // merge nets without gates in between them
1336  std::unordered_map<std::string, std::string> merged_nets;
1337  std::unordered_map<std::string, std::vector<std::string>> master_to_slaves;
1338 
1339  for (auto& [master, slave] : m_nets_to_merge)
1340  {
1341  // check if master net has already been merged into other net
1342  while (true)
1343  {
1344  if (const auto master_it = merged_nets.find(master); master_it != merged_nets.end())
1345  {
1346  master = master_it->second;
1347  }
1348  else
1349  {
1350  break;
1351  }
1352  }
1353 
1354  // check if slave net has already been merged into other net
1355  while (true)
1356  {
1357  if (const auto slave_it = merged_nets.find(slave); slave_it != merged_nets.end())
1358  {
1359  slave = slave_it->second;
1360  }
1361  else
1362  {
1363  break;
1364  }
1365  }
1366 
1367  auto master_net = m_net_by_name.at(master);
1368  auto slave_net = m_net_by_name.at(slave);
1369 
1370  if (master_net == slave_net)
1371  {
1372  continue;
1373  }
1374  else if (slave_net == m_zero_net || slave_net == m_one_net)
1375  {
1376  auto* tmp_net = master_net;
1377  master_net = slave_net;
1378  slave_net = tmp_net;
1379 
1380  auto tmp_name = master;
1381  master = slave;
1382  slave = tmp_name;
1383  }
1384 
1385  // merge sources
1386  if (slave_net->is_global_input_net())
1387  {
1388  master_net->mark_global_input_net();
1389  }
1390 
1391  for (auto src : slave_net->get_sources())
1392  {
1393  Gate* src_gate = src->get_gate();
1394  GatePin* src_pin = src->get_pin();
1395 
1396  if (!slave_net->remove_source(src))
1397  {
1398  return ERR("could not construct netlist: failed to remove source from net '" + slave_net->get_name() + "' with ID " + std::to_string(slave_net->get_id()));
1399  }
1400 
1401  if (!master_net->is_a_source(src_gate, src_pin))
1402  {
1403  if (!master_net->add_source(src_gate, src_pin))
1404  {
1405  return ERR("could not construct netlist: failed to add source to net '" + master_net->get_name() + "' with ID " + std::to_string(master_net->get_id()));
1406  }
1407  }
1408  }
1409 
1410  // merge destinations
1411  if (slave_net->is_global_output_net())
1412  {
1413  master_net->mark_global_output_net();
1414  }
1415 
1416  for (auto dst : slave_net->get_destinations())
1417  {
1418  Gate* dst_gate = dst->get_gate();
1419  GatePin* dst_pin = dst->get_pin();
1420 
1421  if (!slave_net->remove_destination(dst))
1422  {
1423  return ERR("could not construct netlist: failed to remove destination from net '" + slave_net->get_name() + "' with ID " + std::to_string(slave_net->get_id()));
1424  }
1425 
1426  if (!master_net->is_a_destination(dst_gate, dst_pin))
1427  {
1428  if (!master_net->add_destination(dst_gate, dst_pin))
1429  {
1430  return ERR("could not construct netlist: failed to add destination to net '" + master_net->get_name() + "' with ID " + std::to_string(master_net->get_id()));
1431  }
1432  }
1433  }
1434 
1435  // merge generics and attributes
1436  for (const auto& [identifier, content] : slave_net->get_data_map())
1437  {
1438  if (!master_net->set_data(std::get<0>(identifier), std::get<1>(identifier), std::get<0>(content), std::get<1>(content)))
1439  {
1440  log_warning("verilog_parser",
1441  "unable to transfer data from slave net '{}' with ID {} to master net '{}' with ID {}.",
1442  slave_net->get_name(),
1443  slave_net->get_id(),
1444  master_net->get_name(),
1445  master_net->get_id());
1446  }
1447  }
1448 
1449  // update module ports
1450  if (const auto it = m_module_port_by_net.find(slave_net); it != m_module_port_by_net.end())
1451  {
1452  for (auto [module, index] : it->second)
1453  {
1454  std::get<1>(m_module_ports.at(module).at(index)) = master_net;
1455  }
1456  m_module_port_by_net[master_net].insert(m_module_port_by_net[master_net].end(), it->second.begin(), it->second.end());
1457  m_module_port_by_net.erase(it);
1458  }
1459 
1460  m_netlist->delete_net(slave_net);
1461  m_net_by_name.erase(slave);
1462  merged_nets[slave] = master;
1463  master_to_slaves[master].push_back(slave);
1464  }
1465 
1466  // annotate all surviving master nets with the net names that where merged into them
1467  for (auto& master_net : m_netlist->get_nets())
1468  {
1469  const auto master_name = master_net->get_name();
1470 
1471  if (const auto m2s_it = master_to_slaves.find(master_name); m2s_it != master_to_slaves.end())
1472  {
1473  std::vector<std::vector<std::string>> merged_slaves;
1474  auto current_slaves = m2s_it->second;
1475 
1476  while (!current_slaves.empty())
1477  {
1478  std::vector<std::string> next_slaves;
1479  for (const auto& s : current_slaves)
1480  {
1481  if (const auto m2s_inner_it = master_to_slaves.find(s); m2s_inner_it != master_to_slaves.end())
1482  {
1483  next_slaves.insert(next_slaves.end(), m2s_inner_it->second.begin(), m2s_inner_it->second.end());
1484  }
1485  }
1486 
1487  merged_slaves.push_back(current_slaves);
1488  current_slaves = next_slaves;
1489  next_slaves.clear();
1490  }
1491 
1492  // annotate all merged slave wire names as a JSON formatted list of list of strings
1493  // each net can span a tree of "consumed" slave wire names where the nth list represents all wire names that where merged at depth n
1494  std::string merged_str = "";
1495  bool has_merged_nets = false;
1496  for (const auto& vec : merged_slaves)
1497  {
1498  if (!vec.empty())
1499  {
1500  has_merged_nets = true;
1501  }
1502  const auto s = utils::join(", ", vec, [](const auto e) { return '"' + e + '"'; });
1503  merged_str += "[" + s + "], ";
1504  }
1505  merged_str = merged_str.substr(0, merged_str.size() - 2);
1506 
1507  if (has_merged_nets)
1508  {
1509  master_net->set_data("parser_annotation", "merged_nets", "string", "[" + merged_str + "]");
1510  }
1511  }
1512  }
1513 
1514  // add global GND gate if required by any instance
1515  if (m_netlist->get_gnd_gates().empty())
1516  {
1517  if (m_zero_net->get_num_of_destinations() > 0)
1518  {
1519  GateType* gnd_type = m_gnd_gate_types.begin()->second;
1520  GatePin* output_pin = gnd_type->get_output_pins().front();
1521  Gate* gnd = m_netlist->create_gate(m_netlist->get_unique_gate_id(), gnd_type, "global_gnd");
1522 
1523  if (!m_netlist->mark_gnd_gate(gnd))
1524  {
1525  return ERR("failed to mark GND gate");
1526  }
1527 
1528  if (m_zero_net->add_source(gnd, output_pin) == nullptr)
1529  {
1530  return ERR("failed to add source to GND gate");
1531  }
1532  }
1533  else
1534  {
1535  m_netlist->delete_net(m_zero_net);
1536  m_zero_net = nullptr;
1537  }
1538  }
1539 
1540  // add global VCC gate if required by any instance
1541  if (m_netlist->get_vcc_gates().empty())
1542  {
1543  if (m_one_net->get_num_of_destinations() > 0)
1544  {
1545  GateType* vcc_type = m_vcc_gate_types.begin()->second;
1546  GatePin* output_pin = vcc_type->get_output_pins().front();
1547  Gate* vcc = m_netlist->create_gate(m_netlist->get_unique_gate_id(), vcc_type, "global_vcc");
1548 
1549  if (!m_netlist->mark_vcc_gate(vcc))
1550  {
1551  return ERR("failed to mark VCC gate");
1552  }
1553 
1554  if (m_one_net->add_source(vcc, output_pin) == nullptr)
1555  {
1556  return ERR("failed to add source to VCC gate");
1557  }
1558  }
1559  else
1560  {
1561  m_netlist->delete_net(m_one_net);
1562  m_one_net = nullptr;
1563  }
1564  }
1565 
1566  // update module nets, internal nets, input nets, and output nets
1567  for (Module* module : m_netlist->get_modules())
1568  {
1569  module->update_nets();
1570  }
1571 
1572  // assign module pins
1573  for (const auto& [module, ports] : m_module_ports)
1574  {
1575  std::unordered_set<Net*> input_nets = module->get_input_nets();
1576  std::unordered_set<Net*> output_nets = module->get_output_nets();
1577 
1578  for (const auto& [port_name, port_net] : ports)
1579  {
1580  if (!module->is_input_net(port_net) && !module->is_output_net(port_net))
1581  {
1582  continue;
1583  }
1584 
1585  if (auto res = module->create_pin(port_name, port_net); res.is_error())
1586  {
1587  return ERR_APPEND(res.get_error(),
1588  "could not construct netlist: failed to create pin '" + port_name + "' at net '" + port_net->get_name() + "' with ID " + std::to_string(port_net->get_id())
1589  + " within module '" + module->get_name() + "' with ID " + std::to_string(module->get_id()));
1590  }
1591  }
1592  }
1593 
1594  m_netlist->enable_automatic_net_checks(true);
1595  return OK({});
1596  }
1597 
1598  Result<Module*> VerilogParser::instantiate_module(const std::string& instance_identifier,
1599  VerilogModule* verilog_module,
1600  Module* parent,
1601  const std::unordered_map<std::string, std::string>& parent_module_assignments)
1602  {
1603  std::unordered_map<std::string, std::string> signal_alias;
1604  std::unordered_map<std::string, std::string> instance_alias;
1605 
1606  // TODO check parent module assignments for port aliases
1607 
1608  const std::string parent_name = (parent == nullptr) ? "" : parent->get_name();
1609  instance_alias[instance_identifier] = get_unique_alias(parent_name, instance_identifier, m_instance_name_occurences);
1610 
1611  // create netlist module
1612  Module* module;
1613  if (parent == nullptr)
1614  {
1615  module = m_netlist->get_top_module();
1616  module->set_name(instance_alias.at(instance_identifier));
1617  }
1618  else
1619  {
1620  module = m_netlist->create_module(instance_alias.at(instance_identifier), parent);
1621  }
1622 
1623  std::string instance_type = verilog_module->m_name;
1624  if (module == nullptr)
1625  {
1626  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to create module");
1627  }
1628  module->set_type(instance_type);
1629 
1630  // assign entity-level attributes
1631  for (const VerilogDataEntry& attribute : verilog_module->m_attributes)
1632  {
1633  if (!module->set_data("attribute", attribute.m_name, attribute.m_type, attribute.m_value))
1634  {
1635  log_warning("verilog_parser",
1636  "could not set attribute '{} = {}' of type '{}' for instance '{}' type '{}'.",
1637  attribute.m_name,
1638  attribute.m_value,
1639  attribute.m_type,
1640  instance_identifier,
1641  instance_type);
1642  }
1643  }
1644 
1645  // assign module port names
1646  for (const auto& port : verilog_module->m_ports)
1647  {
1648  for (const auto& expanded_port_identifier : port->m_expanded_identifiers)
1649  {
1650  if (const auto it = parent_module_assignments.find(expanded_port_identifier); it != parent_module_assignments.end())
1651  {
1652  Net* port_net = m_net_by_name.at(it->second);
1653  m_module_ports[module].push_back(std::make_tuple(expanded_port_identifier, port_net));
1654  m_module_port_by_net[port_net].push_back(std::make_pair(module, m_module_ports[module].size() - 1));
1655  }
1656  }
1657  }
1658 
1659  // create internal signals
1660  for (const auto& signal : verilog_module->m_signals)
1661  {
1662  for (const auto& expanded_name : signal->m_expanded_names)
1663  {
1664  std::string unique_net_name = get_unique_alias(module->get_name(), expanded_name, m_net_name_occurences);
1665  if (unique_net_name != expanded_name)
1666  {
1667  m_net_name_occurences[unique_net_name]++;
1668  }
1669  signal_alias[expanded_name] = unique_net_name;
1670 
1671  // create new net for the signal
1672  Net* signal_net = m_netlist->create_net(signal_alias.at(expanded_name));
1673  if (signal_net == nullptr)
1674  {
1675  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to create net '" + expanded_name + "'");
1676  }
1677 
1678  m_net_by_name[signal_alias.at(expanded_name)] = signal_net;
1679 
1680  // assign signal attributes
1681  for (const VerilogDataEntry& attribute : signal->m_attributes)
1682  {
1683  if (!signal_net->set_data("attribute", attribute.m_name, "unknown", attribute.m_value))
1684  {
1685  log_warning("verilog_parser",
1686  "could not set attribute ({} = {}) for net '{}' of instance '{}' of type '{}'.",
1687  attribute.m_name,
1688  attribute.m_value,
1689  expanded_name,
1690  instance_identifier,
1691  instance_type);
1692  }
1693  }
1694  }
1695  }
1696 
1697  // schedule assigned nets for merging
1698  for (const auto& [left_expanded_signal, right_expanded_signal] : verilog_module->m_expanded_assignments)
1699  {
1700  std::string a = left_expanded_signal;
1701  std::string b = right_expanded_signal;
1702 
1703  if (const auto alias_it = signal_alias.find(a); alias_it != signal_alias.end())
1704  {
1705  a = alias_it->second;
1706  }
1707  else
1708  {
1709  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to find alias for net '" + a + "'");
1710  }
1711 
1712  if (const auto alias_it = signal_alias.find(b); alias_it != signal_alias.end())
1713  {
1714  b = alias_it->second;
1715  }
1716  else if (b == "'Z'" || b == "'X'")
1717  {
1718  continue;
1719  }
1720  else if (b != "'0'" && b != "'1'")
1721  {
1722  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to find alias for net '" + b + "'");
1723  }
1724 
1725  m_nets_to_merge.push_back(std::make_pair(a, b));
1726  }
1727 
1728  // schedule assigned port nets for merging
1729  for (const auto& [port_identifier, net_name] : parent_module_assignments)
1730  {
1731  std::string signal_name;
1732  if (const auto expr_it = verilog_module->m_expanded_port_identifiers_to_expressions.find(port_identifier); expr_it == verilog_module->m_expanded_port_identifiers_to_expressions.end())
1733  {
1734  signal_name = port_identifier;
1735  }
1736  else
1737  {
1738  signal_name = expr_it->second;
1739  }
1740 
1741  // TODO handle identifier != expression
1742  if (const auto alias_it = signal_alias.find(signal_name); alias_it != signal_alias.end())
1743  {
1744  const bool swap = net_name.find("__GLOBAL_IO__") == std::string::npos;
1745  m_nets_to_merge.push_back(swap ? std::make_pair(net_name, alias_it->second) : std::make_pair(alias_it->second, net_name));
1746  }
1747  else
1748  {
1749  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to find alias for net '" + signal_name + "'");
1750  }
1751  }
1752 
1753  // process instances i.e. gates or other entities
1754  for (const auto& instance : verilog_module->m_instances)
1755  {
1756  // will later hold either module or gate, so attributes can be assigned properly
1757  DataContainer* container = nullptr;
1758 
1759  // assign actual signal names to ports
1760  std::unordered_map<std::string, std::string> instance_assignments;
1761 
1762  // if the instance is another entity, recursively instantiate it
1763  if (auto module_it = m_modules_by_name.find(instance->m_type); module_it != m_modules_by_name.end())
1764  {
1765  // expand port assignments
1766  for (const auto& [port, assignment] : instance->m_expanded_port_assignments)
1767  {
1768  if (const auto alias_it = signal_alias.find(assignment); alias_it != signal_alias.end())
1769  {
1770  instance_assignments[port] = alias_it->second;
1771  }
1772  else if (assignment == "'0'" || assignment == "'1'")
1773  {
1774  instance_assignments[port] = assignment;
1775  }
1776  else if (assignment == "'Z'" || assignment == "'X'" || assignment.empty())
1777  {
1778  continue;
1779  }
1780  else
1781  {
1782  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': port assignment '" + port + " = " + assignment + "' is invalid");
1783  }
1784  }
1785 
1786  if (auto res = instantiate_module(instance->m_name, module_it->second, module, instance_assignments); res.is_error())
1787  {
1788  return ERR_APPEND(res.get_error(),
1789  "could not create instance '" + instance_identifier + "' of type '" + instance_type + "': unable to create instance '" + instance->m_name + "' of type '"
1790  + module_it->second->m_name + "'");
1791  }
1792  else
1793  {
1794  container = res.get();
1795  }
1796  }
1797  // otherwise it has to be an element from the gate library
1798  else if (const auto gate_type_it = m_gate_types.find(instance->m_type); gate_type_it != m_gate_types.end())
1799  {
1800  // create the new gate
1801  instance_alias[instance->m_name] = get_unique_alias(module->get_name(), instance->m_name, m_instance_name_occurences);
1802  Gate* new_gate = m_netlist->create_gate(gate_type_it->second, instance_alias.at(instance->m_name));
1803  if (new_gate == nullptr)
1804  {
1805  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to create gate '" + instance->m_name + "'");
1806  }
1807 
1808  if (!module->is_top_module())
1809  {
1810  module->assign_gate(new_gate);
1811  }
1812 
1813  container = new_gate;
1814 
1815  // if gate is of a GND or VCC gate type, mark it as such
1816  if (m_vcc_gate_types.find(instance->m_type) != m_vcc_gate_types.end() && !new_gate->mark_vcc_gate())
1817  {
1818  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to mark '" + instance->m_name + "' of type '" + instance->m_type
1819  + "' as GND gate");
1820  }
1821  if (m_gnd_gate_types.find(instance->m_type) != m_gnd_gate_types.end() && !new_gate->mark_gnd_gate())
1822  {
1823  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to mark '" + instance->m_name + "' of type '" + instance->m_type
1824  + "' as VCC gate");
1825  }
1826 
1827  // cache pin names
1828  std::unordered_map<std::string, GatePin*> pin_names_map;
1829  for (auto* pin : gate_type_it->second->get_pins())
1830  {
1831  pin_names_map[pin->get_name()] = pin;
1832  }
1833 
1834  // expand pin assignments
1835  for (const auto& [pin, assignment] : instance->m_expanded_port_assignments)
1836  {
1837  std::string signal;
1838 
1839  if (const auto alias_it = signal_alias.find(assignment); alias_it != signal_alias.end())
1840  {
1841  signal = alias_it->second;
1842  }
1843  else if (assignment == "'0'" || assignment == "'1'")
1844  {
1845  signal = assignment;
1846  }
1847  else if (assignment == "'Z'" || assignment == "'X'")
1848  {
1849  continue;
1850  }
1851  else
1852  {
1853  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to assign '" + assignment + "' to pin '" + pin + "' of gate '"
1854  + instance->m_name + "' of type '" + instance->m_type + "' as the assignment is invalid");
1855  }
1856 
1857  // get the respective net for the assignment
1858  if (const auto net_it = m_net_by_name.find(signal); net_it == m_net_by_name.end())
1859  {
1860  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to assign signal'" + signal + "' to pin '" + pin
1861  + "' as the signal has not been declared");
1862  }
1863  else
1864  {
1865  Net* current_net = net_it->second;
1866 
1867  // add net src/dst by pin types
1868  bool is_input = false;
1869  bool is_output = false;
1870 
1871  if (const auto it = pin_names_map.find(pin); it != pin_names_map.end())
1872  {
1873  PinDirection direction = it->second->get_direction();
1875  {
1876  is_input = true;
1877  }
1878 
1880  {
1881  is_output = true;
1882  }
1883  }
1884 
1885  if (!is_input && !is_output)
1886  {
1887  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to assign net '" + signal + "' to pin '" + pin
1888  + "' as it is not a pin of gate '" + new_gate->get_name() + "' of type '" + new_gate->get_type()->get_name() + "'");
1889  }
1890 
1891  if (is_output && !current_net->add_source(new_gate, pin))
1892  {
1893  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to add net '" + signal + "' as a source to gate '"
1894  + new_gate->get_name() + "' via pin '" + pin + "'");
1895  }
1896 
1897  if (is_input && !current_net->add_destination(new_gate, pin))
1898  {
1899  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to add net '" + signal + "' as a destination to gate '"
1900  + new_gate->get_name() + "' via pin '" + pin + "'");
1901  }
1902  }
1903  }
1904  }
1905  else
1906  {
1907  return ERR("could not create instance '" + instance_identifier + "' of type '" + instance_type + "': failed to find gate type '" + instance->m_type + "' in gate library '"
1908  + m_netlist->get_gate_library()->get_name() + "'");
1909  }
1910 
1911  // assign instance attributes
1912  for (const auto& attribute : instance->m_attributes)
1913  {
1914  if (!container->set_data("attribute", attribute.m_name, attribute.m_type, attribute.m_value))
1915  {
1916  log_warning("verilog_parser",
1917  "could not set attribute '{} = {}' of type '{}' for instance '{}' of type '{}' within instance '{}' of type '{}'.",
1918  attribute.m_name,
1919  attribute.m_value,
1920  attribute.m_type,
1921  instance->m_name,
1922  instance->m_type,
1923  instance_identifier,
1924  instance_type);
1925  }
1926  }
1927 
1928  // process generics
1929  for (const auto& parameter : instance->m_parameters)
1930  {
1931  if (!container->set_data("generic", parameter.m_name, parameter.m_type, parameter.m_value))
1932  {
1933  log_warning("verilog_parser",
1934  "could not set generic '{} = {}' of type '{}' for instance '{}' of type '{}' within instance '{}' of type '{}'.",
1935  parameter.m_name,
1936  parameter.m_value,
1937  parameter.m_type,
1938  instance->m_name,
1939  instance->m_type,
1940  instance_identifier,
1941  instance_type);
1942  }
1943  }
1944  }
1945 
1946  return OK(module);
1947  }
1948 
1949  // ###########################################################################
1950  // ################### Helper Functions ####################
1951  // ###########################################################################
1952 
1953  namespace
1954  {
1955  static const std::map<char, BooleanFunction::Value> bin_map = {{'0', BooleanFunction::Value::ZERO},
1956  {'1', BooleanFunction::Value::ONE},
1957  {'X', BooleanFunction::Value::X},
1958  {'Z', BooleanFunction::Value::Z}};
1959 
1960  static const std::map<char, std::vector<BooleanFunction::Value>> oct_map = {{'0', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1961  {'1', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1962  {'2', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1963  {'3', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1964  {'4', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1965  {'5', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1966  {'6', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1967  {'7', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1968  {'X', {BooleanFunction::Value::X, BooleanFunction::Value::X, BooleanFunction::Value::X}},
1969  {'Z', {BooleanFunction::Value::Z, BooleanFunction::Value::Z, BooleanFunction::Value::Z}}};
1970 
1971  static const std::map<char, std::vector<BooleanFunction::Value>> hex_map = {
1972  {'0', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1973  {'1', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1974  {'2', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1975  {'3', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1976  {'4', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1977  {'5', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1978  {'6', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1979  {'7', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1980  {'8', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1981  {'9', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1982  {'A', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1983  {'B', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1984  {'C', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1985  {'D', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1986  {'E', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1987  {'F', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1988  {'X', {BooleanFunction::Value::X, BooleanFunction::Value::X, BooleanFunction::Value::X, BooleanFunction::Value::X}},
1989  {'Z', {BooleanFunction::Value::Z, BooleanFunction::Value::Z, BooleanFunction::Value::Z, BooleanFunction::Value::Z}}};
1990  } // namespace
1991 
1992  // generate a unique name for a gate/module instance
1993  std::string VerilogParser::get_unique_alias(const std::string& parent_name, const std::string& name, const std::unordered_map<std::string, u32>& name_occurences) const
1994  {
1995  std::string unique_alias = name;
1996 
1997  if (!parent_name.empty())
1998  {
1999  // if there is no other instance with that name, we omit the name prefix
2000 
2001  auto instance_name_it = name_occurences.find(name);
2002 
2003  int cnt = 0;
2004 
2005  // it is OK if base name (first loop cnt=0) is already in name_occurences once
2006  // unique_alias (cnt > 0) must not be in name_occurences
2007  while (instance_name_it != name_occurences.end() && (cnt || instance_name_it->second > 1))
2008  {
2009  std::string extension;
2010  if (cnt++)
2011  {
2012  extension = "_u" + std::to_string(cnt);
2013  }
2014  unique_alias = parent_name + instance_name_seperator + unique_alias + extension;
2015  instance_name_it = name_occurences.find(unique_alias);
2016  }
2017  }
2018 
2019  return unique_alias;
2020  }
2021 
2022  std::vector<u32> VerilogParser::parse_range(TokenStream<std::string>& stream) const
2023  {
2024  if (stream.remaining() == 1)
2025  {
2026  return {(u32)std::stoi(stream.consume().string)};
2027  }
2028 
2029  // MSB to LSB
2030  const int end = std::stoi(stream.consume().string);
2031  stream.consume(":", true);
2032  const int start = std::stoi(stream.consume().string);
2033 
2034  const int direction = (start <= end) ? 1 : -1;
2035 
2036  std::vector<u32> result;
2037  for (int i = start; i != end + direction; i += direction)
2038  {
2039  result.push_back((u32)i);
2040  }
2041  return result;
2042  }
2043 
2044  void VerilogParser::expand_ranges_recursively(std::vector<std::string>& expanded_names, const std::string& current_name, const std::vector<std::vector<u32>>& ranges, u32 dimension) const
2045  {
2046  // expand signal recursively
2047  if (ranges.size() > dimension)
2048  {
2049  for (const u32 index : ranges[dimension])
2050  {
2051  expand_ranges_recursively(expanded_names, current_name + "(" + std::to_string(index) + ")", ranges, dimension + 1);
2052  }
2053  }
2054  else
2055  {
2056  // last dimension
2057  expanded_names.push_back(current_name);
2058  }
2059  }
2060 
2061  std::vector<std::string> VerilogParser::expand_ranges(const std::string& name, const std::vector<std::vector<u32>>& ranges) const
2062  {
2063  std::vector<std::string> res;
2064 
2065  expand_ranges_recursively(res, name, ranges, 0);
2066 
2067  return res;
2068  }
2069 
2070  Result<std::vector<BooleanFunction::Value>> VerilogParser::get_binary_vector(std::string value) const
2071  {
2072  value = utils::to_upper(utils::replace(value, std::string("_"), std::string("")));
2073 
2074  i32 len = -1;
2075  std::string prefix;
2076  std::string number;
2077  std::vector<BooleanFunction::Value> result;
2078 
2079  // base specified?
2080  if (value.find('\'') == std::string::npos)
2081  {
2082  prefix = "D";
2083  number = value;
2084  }
2085  else
2086  {
2087  if (value.at(0) != '\'')
2088  {
2089  len = std::stoi(value.substr(0, value.find('\'')));
2090  }
2091  prefix = value.substr(value.find('\'') + 1, 1);
2092  number = value.substr(value.find('\'') + 2);
2093  }
2094 
2095  // select base
2096  switch (prefix.at(0))
2097  {
2098  case 'B': {
2099  for (auto it = number.rbegin(); it != number.rend(); it++)
2100  {
2101  const char c = *it;
2102  if (c == '0' || c == '1' || c == 'Z' || c == 'X')
2103  {
2104  result.push_back(bin_map.at(c));
2105  }
2106  else
2107  {
2108  return ERR("could not convert string to binary vector: invalid character within binary number literal '" + value + "'");
2109  }
2110  }
2111  break;
2112  }
2113 
2114  case 'O':
2115  for (auto it = number.rbegin(); it != number.rend(); it++)
2116  {
2117  const char c = *it;
2118  if ((c >= '0' && c <= '7') || c == 'X' || c == 'Z')
2119  {
2120  const auto& bits = oct_map.at(c);
2121  result.insert(result.end(), bits.begin(), bits.end());
2122  }
2123  else
2124  {
2125  return ERR("could not convert string to binary vector: invalid character within octal number literal '" + value + "'");
2126  }
2127  }
2128  break;
2129 
2130  case 'D': {
2131  u64 tmp_val = 0;
2132 
2133  for (const char c : number)
2134  {
2135  if ((c >= '0' && c <= '9'))
2136  {
2137  tmp_val = (tmp_val * 10) + (c - '0');
2138  }
2139  else
2140  {
2141  return ERR("could not convert string to binary vector: invalid character within decimal number literal '" + value + "'");
2142  }
2143  }
2144 
2145  do
2146  {
2147  result.push_back(((tmp_val & 1) == 1) ? BooleanFunction::Value::ONE : BooleanFunction::Value::ZERO);
2148  tmp_val >>= 1;
2149  } while (tmp_val != 0);
2150  break;
2151  }
2152 
2153  case 'H': {
2154  for (auto it = number.rbegin(); it != number.rend(); it++)
2155  {
2156  const char c = *it;
2157  if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || c == 'X' || c == 'Z')
2158  {
2159  const auto& bits = hex_map.at(c);
2160  result.insert(result.end(), bits.begin(), bits.end());
2161  }
2162  else
2163  {
2164  return ERR("could not convert string to binary vector: invalid character within hexadecimal number literal '" + value + "'");
2165  }
2166  }
2167  break;
2168  }
2169 
2170  default: {
2171  return ERR("could not convert string to binary vector: invalid base '" + prefix + "' within number literal '" + value + "'");
2172  }
2173  }
2174 
2175  if (len != -1)
2176  {
2177  i32 result_size = result.size();
2178 
2179  if (len > result_size)
2180  {
2181  // fill with '0'
2182  for (i32 i = 0; i < (len - result_size); i++)
2183  {
2184  result.push_back(BooleanFunction::Value::ZERO);
2185  }
2186  }
2187  else
2188  {
2189  // drop trailing bits
2190  for (i32 i = 0; i < (result_size - len); i++)
2191  {
2192  result.pop_back();
2193  }
2194  }
2195  }
2196 
2197  return OK(result);
2198  }
2199 
2200  Result<std::string> VerilogParser::get_hex_from_literal(const Token<std::string>& value_token) const
2201  {
2202  const u32 line_number = value_token.number;
2203  const std::string value = utils::to_upper(utils::replace(value_token.string, std::string("_"), std::string("")));
2204 
2205  i32 len = -1;
2206  std::string prefix;
2207  std::string number;
2208  u32 base;
2209 
2210  // base specified?
2211  if (value.find('\'') == std::string::npos)
2212  {
2213  prefix = "D";
2214  number = value;
2215  }
2216  else
2217  {
2218  if (value.at(0) != '\'')
2219  {
2220  len = std::stoi(value.substr(0, value.find('\'')));
2221  }
2222  prefix = value.substr(value.find('\'') + 1, 1);
2223  number = value.substr(value.find('\'') + 2);
2224  }
2225 
2226  // select base
2227  switch (prefix.at(0))
2228  {
2229  case 'B': {
2230  if (!std::all_of(number.begin(), number.end(), [](const char& c) { return (c >= '0' && c <= '1'); }))
2231  {
2232  return ERR("could not convert token to hexadecimal string: invalid character within binary number literal '" + value + "' (line " + std::to_string(line_number) + ")");
2233  }
2234 
2235  base = 2;
2236  break;
2237  }
2238 
2239  case 'O': {
2240  if (!std::all_of(number.begin(), number.end(), [](const char& c) { return (c >= '0' && c <= '7'); }))
2241  {
2242  return ERR("could not convert token to hexadecimal string: invalid character within ocatl number literal '" + value + "' (line " + std::to_string(line_number) + ")");
2243  }
2244 
2245  base = 8;
2246  break;
2247  }
2248 
2249  case 'D': {
2250  if (!std::all_of(number.begin(), number.end(), [](const char& c) { return (c >= '0' && c <= '9'); }))
2251  {
2252  return ERR("could not convert token to hexadecimal string: invalid character within decimal number literal '" + value + "' (line " + std::to_string(line_number) + ")");
2253  }
2254 
2255  base = 10;
2256  break;
2257  }
2258 
2259  case 'H': {
2260  std::string res;
2261 
2262  for (const char c : number)
2263  {
2264  if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
2265  {
2266  res += c;
2267  }
2268  else
2269  {
2270  return ERR("could not convert token to hexadecimal string: invalid character within hexadecimal number literal '" + value + "' (line " + std::to_string(line_number) + ")");
2271  }
2272  }
2273 
2274  return OK(res);
2275  }
2276 
2277  default: {
2278  return ERR("could not convert token to hexadecimal string: invalid base '" + prefix + "' within number literal '" + value + "' (line " + std::to_string(line_number) + ")");
2279  }
2280  }
2281 
2282  std::stringstream ss;
2283  if (len != -1)
2284  {
2285  // fill with '0'
2286  ss << std::uppercase << std::setfill('0') << std::setw((len + 3) / 4) << std::hex << stoull(number, 0, base);
2287  }
2288  else
2289  {
2290  ss << std::uppercase << std::hex << stoull(number, 0, base);
2291  }
2292  return OK(ss.str());
2293  }
2294 
2295  Result<std::pair<std::string, std::string>> VerilogParser::parse_parameter_value(const Token<std::string>& value_token) const
2296  {
2297  std::pair<std::string, std::string> value;
2298 
2299  if (utils::is_integer(value_token.string))
2300  {
2301  value.first = "integer";
2302  value.second = value_token.string;
2303  }
2304  else if (utils::is_floating_point(value_token.string))
2305  {
2306  value.first = "floating_point";
2307  value.second = value_token.string;
2308  }
2309  else if (value_token.string[0] == '\"' && value_token.string.back() == '\"')
2310  {
2311  value.first = "string";
2312  value.second = value_token.string.substr(1, value_token.string.size() - 2);
2313  }
2314  else if (isdigit(value_token.string[0]) || value_token.string[0] == '\'')
2315  {
2316  if (const auto res = get_hex_from_literal(value_token); res.is_error())
2317  {
2318  return ERR_APPEND(res.get_error(),
2319  "could not parse parameter value: failed to convert '" + value_token.string + "' to hexadecimal value (line " + std::to_string(value_token.number) + ")");
2320  }
2321  else
2322  {
2323  value.second = res.get();
2324  }
2325 
2326  if (value.second == "0" || value.second == "1")
2327  {
2328  value.first = "bit_value";
2329  }
2330  else
2331  {
2332  value.first = "bit_vector";
2333  }
2334  }
2335  else
2336  {
2337  return ERR("could not parse parameter value: failed to identify data type of parameter '" + value_token.string + "' (line " + std::to_string(value_token.number) + ")");
2338  }
2339 
2340  return OK(value);
2341  }
2342 
2343  Result<std::vector<VerilogParser::assignment_t>> VerilogParser::parse_assignment_expression(TokenStream<std::string>&& stream) const
2344  {
2345  std::vector<TokenStream<std::string>> parts;
2346 
2347  if (stream.size() == 0)
2348  {
2349  return OK({});
2350  }
2351 
2352  if (stream.peek() == "{")
2353  {
2354  stream.consume("{", true);
2355 
2356  TokenStream<std::string> assignment_list_str = stream.extract_until("}");
2357  stream.consume("}", true);
2358 
2359  do
2360  {
2361  parts.push_back(assignment_list_str.extract_until(","));
2362  } while (assignment_list_str.consume(",", false));
2363  }
2364  else
2365  {
2366  parts.push_back(stream);
2367  }
2368 
2369  std::vector<assignment_t> result;
2370  result.reserve(parts.size());
2371 
2372  for (auto it = parts.rbegin(); it != parts.rend(); it++)
2373  {
2374  TokenStream<std::string>& part_stream = *it;
2375 
2376  const Token<std::string> signal_name_token = part_stream.consume();
2377  std::string signal_name = signal_name_token.string;
2378 
2379  // (3) NUMBER
2380  if (isdigit(signal_name[0]) || signal_name[0] == '\'')
2381  {
2382  if (auto res = get_binary_vector(signal_name_token); res.is_error())
2383  {
2384  return ERR_APPEND(res.get_error(), "could not parse assignment expression: unable to convert token to binary vector");
2385  }
2386  else
2387  {
2388  result.push_back(std::move(res.get()));
2389  }
2390  }
2391  else
2392  {
2393  // any bounds specified?
2394  if (part_stream.consume("["))
2395  {
2396  // (4) NAME[INDEX1][INDEX2]...
2397  // (5) NAME[BEGIN_INDEX1:END_INDEX1][BEGIN_INDEX2:END_INDEX2]...
2398 
2399  std::vector<std::vector<u32>> ranges;
2400  do
2401  {
2402  TokenStream<std::string> range_str = part_stream.extract_until("]");
2403  ranges.emplace_back(parse_range(range_str));
2404  part_stream.consume("]", true);
2405  } while (part_stream.consume("[", false));
2406 
2407  result.push_back(ranged_identifier_t({std::move(signal_name), std::move(ranges)}));
2408  }
2409  else
2410  {
2411  // (1) NAME *single-dimensional*
2412  // (2) NAME *multi-dimensional*
2413  result.push_back(std::move(signal_name));
2414  }
2415  }
2416  }
2417 
2418  return OK(result);
2419  }
2420 
2421  std::vector<std::string> VerilogParser::expand_assignment_expression(VerilogModule* verilog_module, const std::vector<assignment_t>& vars) const
2422  {
2423  std::vector<std::string> result;
2424  for (const auto& var : vars)
2425  {
2426  if (const identifier_t* identifier = std::get_if<identifier_t>(&var); identifier != nullptr)
2427  {
2428  std::vector<std::vector<u32>> ranges;
2429 
2430  if (const auto signal_it = verilog_module->m_signals_by_name.find(*identifier); signal_it != verilog_module->m_signals_by_name.end())
2431  {
2432  ranges = signal_it->second->m_ranges;
2433  }
2434  else if (const auto port_it = verilog_module->m_ports_by_expression.find(*identifier); port_it != verilog_module->m_ports_by_expression.end())
2435  {
2436  ranges = port_it->second->m_ranges;
2437  }
2438 
2439  std::vector<std::string> expanded = expand_ranges(*identifier, ranges);
2440  result.insert(result.end(), expanded.begin(), expanded.end());
2441  }
2442  else if (const ranged_identifier_t* ranged_identifier = std::get_if<ranged_identifier_t>(&var); ranged_identifier != nullptr)
2443  {
2444  std::vector<std::string> expanded = expand_ranges(ranged_identifier->first, ranged_identifier->second);
2445  result.insert(result.end(), expanded.begin(), expanded.end());
2446  }
2447  else if (const numeral_t* numeral = std::get_if<numeral_t>(&var); numeral != nullptr)
2448  {
2449  for (auto value : *numeral)
2450  {
2451  result.push_back("'" + BooleanFunction::to_string(value) + "'");
2452  }
2453  }
2454  }
2455 
2456  return result;
2457  }
2458 } // namespace hal
u32 size
static std::string to_string(Value value)
bool set_data(const std::string &category, const std::string &key, const std::string &data_type, const std::string &value, const bool log_with_info_level=false)
std::unordered_map< std::string, GateType * > get_gate_types(const std::function< bool(const GateType *)> &filter=nullptr) const
std::unordered_map< std::string, GateType * > get_vcc_gate_types() const
std::unordered_map< std::string, GateType * > get_gnd_gate_types() const
std::string get_name() const
bool is_input_net(Net *net) const
Definition: module.cpp:564
void set_name(const std::string &name)
Definition: module.cpp:93
void update_nets()
Definition: module.cpp:443
bool is_top_module() const
Definition: module.cpp:321
bool assign_gate(Gate *gate)
Definition: module.cpp:331
bool is_output_net(Net *net) const
Definition: module.cpp:574
std::string get_name() const
Definition: module.cpp:88
const std::unordered_set< Net * > & get_input_nets() const
Definition: module.cpp:549
void set_type(const std::string &type)
Definition: module.cpp:112
Result< ModulePin * > create_pin(const u32 id, const std::string &name, Net *net, PinType type=PinType::none, bool create_group=true, bool force_name=false)
Definition: module.cpp:796
const std::unordered_set< Net * > & get_output_nets() const
Definition: module.cpp:554
u32 get_id() const
Definition: module.cpp:83
Definition: net.h:58
Endpoint * add_source(Gate *gate, const std::string &pin_name)
Definition: net.cpp:127
const std::string & get_name() const
Definition: net.cpp:98
u32 get_num_of_destinations(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:432
Module * get_top_module() const
Definition: netlist.cpp:610
u32 get_unique_gate_id()
Definition: netlist.cpp:162
bool mark_vcc_gate(Gate *gate)
Definition: netlist.cpp:230
bool mark_gnd_gate(Gate *gate)
Definition: netlist.cpp:246
bool load_gate_locations_from_data(const std::string &data_category="", const std::pair< std::string, std::string > &data_identifiers=std::pair< std::string, std::string >())
Definition: netlist.cpp:864
bool delete_net(Net *net)
Definition: netlist.cpp:345
Net * create_net(const u32 net_id, const std::string &name)
Definition: netlist.cpp:335
const std::vector< Gate * > & get_gnd_gates() const
Definition: netlist.cpp:311
void set_design_name(const std::string &name)
Definition: netlist.cpp:111
void enable_automatic_net_checks(bool enable_checks=true)
Definition: netlist.cpp:565
const std::vector< Gate * > & get_vcc_gates() const
Definition: netlist.cpp:306
const std::vector< Module * > & get_modules() const
Definition: netlist.cpp:626
Gate * create_gate(const u32 gate_id, GateType *gate_type, const std::string &name="", i32 x=-1, i32 y=-1)
Definition: netlist.cpp:175
const std::vector< Net * > & get_nets() const
Definition: netlist.cpp:366
const GateLibrary * get_gate_library() const
Definition: netlist.cpp:134
Module * create_module(const u32 module_id, const std::string &name, Module *parent, const std::vector< Gate * > &gates={})
Definition: netlist.cpp:589
u32 remaining() const
Definition: token_stream.h:494
Token< T > consume_until(const T &expected, u32 end=END_OF_STREAM, bool level_aware=true, bool throw_on_error=false)
Definition: token_stream.h:266
Token< T > consume_current_line()
Definition: token_stream.h:282
Token< T > & peek(i32 offset=0)
Definition: token_stream.h:392
u32 find_next(const T &match, u32 end=END_OF_STREAM, bool level_aware=true) const
Definition: token_stream.h:446
Token< T > join_until(const T &match, const T &joiner, u32 end=END_OF_STREAM, bool level_aware=true, bool throw_on_error=false)
Definition: token_stream.h:338
TokenStream< T > extract_until(const T &expected, u32 end=END_OF_STREAM, bool level_aware=true, bool throw_on_error=false)
Definition: token_stream.h:308
Token< T > consume(u32 num=1)
Definition: token_stream.h:216
Result< std::monostate > parse(const std::filesystem::path &file_path) override
Result< std::unique_ptr< Netlist > > instantiate(const GateLibrary *gate_library) override
uint64_t u64
Definition: defines.h:42
uint32_t u32
Definition: defines.h:41
int32_t i32
Definition: defines.h:36
#define log_warning(channel,...)
Definition: log.h:76
#define ERR(message)
Definition: result.h:60
#define OK(...)
Definition: result.h:56
#define ERR_APPEND(prev_error, message)
Definition: result.h:64
const Module * module(const Gate *g, const NodeBoxes &boxes)
std::unique_ptr< Netlist > create_netlist(const GateLibrary *gate_library)
Create a new empty netlist using the specified gate library.
T replace(const T &str, const T &search, const T &replace)
Definition: utils.h:428
bool is_digits(const T &s)
Definition: utils.h:232
std::string join(const std::string &joiner, const Iterator &begin, const Iterator &end, const Transform &transform)
Definition: utils.h:458
bool is_floating_point(const T &s)
Definition: utils.h:264
T to_upper(const T &s)
Definition: utils.h:509
bool is_integer(const T &s)
Definition: utils.h:244
T trim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:404
Definition: defines.h:45
PinDirection
Definition: pin_direction.h:36
std::vector< PinInformation > pins
Net * net
PinDirection direction
std::string name
This file contains various functions to create and load netlists.
std::string identifier
std::unique_ptr< BasePluginInterface > instance