26 m_modules_by_name.clear();
30 ifs.open(file_path.string(), std::ifstream::in);
33 return ERR(
"could not parse Verilog file '" + m_path.string() +
"' : unable to open file");
45 if (
auto res = parse_tokens(); res.is_error())
47 return ERR_APPEND(res.get_error(),
"could not parse Verilog file '" + file_path.string() +
"': unable to parse tokens");
52 if (e.line_number != (
u32)-1)
54 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': " + e.message +
" (line " + std::to_string(e.line_number) +
")");
58 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': " + e.message);
62 if (m_modules.empty())
64 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': does not contain any modules");
68 for (
auto& [module_name, verilog_module] : m_modules_by_name)
71 for (
const auto& port : verilog_module->m_ports)
73 if (port->m_expression == port->m_identifier)
75 if (!port->m_ranges.empty())
77 port->m_expanded_identifiers = expand_ranges(port->m_identifier, port->m_ranges);
81 port->m_expanded_identifiers = {port->m_identifier};
86 if (!port->m_ranges.empty())
88 port->m_expanded_identifiers = expand_ranges(port->m_identifier, port->m_ranges);
89 auto expanded_expression = expand_ranges(port->m_expression, port->m_ranges);
91 std::transform(port->m_expanded_identifiers.begin(),
92 port->m_expanded_identifiers.end(),
93 expanded_expression.begin(),
94 std::inserter(verilog_module->m_expanded_port_identifiers_to_expressions, verilog_module->m_expanded_port_identifiers_to_expressions.end()),
95 std::make_pair<const std::string&, const std::string&>);
99 port->m_expanded_identifiers = {port->m_identifier};
100 verilog_module->m_expanded_port_identifiers_to_expressions[port->m_identifier] = port->m_expression;
106 for (
auto& signal : verilog_module->m_signals)
108 if (!signal->m_ranges.empty())
110 signal->m_expanded_names = expand_ranges(signal->m_name, signal->m_ranges);
114 signal->m_expanded_names = std::vector<std::string>({signal->m_name});
119 for (
auto& assignment : verilog_module->m_assignments)
121 const std::vector<std::string> left_signals = expand_assignment_expression(verilog_module, assignment.m_variable);
122 const std::vector<std::string> right_signals = expand_assignment_expression(verilog_module, assignment.m_assignment);
123 if (left_signals.empty() || right_signals.empty())
125 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': unable to expand assignments within module '" + verilog_module->m_name +
"'");
128 u32 left_size = left_signals.size();
129 u32 right_size = right_signals.size();
130 if (left_size <= right_size)
133 for (
u32 i = 0; i < left_size; i++)
135 verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i), right_signals.at(i)));
140 for (
u32 i = 0; i < right_size; i++)
142 verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i), right_signals.at(i)));
146 for (
u32 i = 0; i < left_size - right_size; i++)
148 verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i + right_size),
"'0'"));
155 for (
auto& [module_name, verilog_module] : m_modules_by_name)
157 for (
auto& instance : verilog_module->m_instances)
159 if (
auto module_it = m_modules_by_name.find(instance->m_type); module_it != m_modules_by_name.end())
161 instance->m_is_module =
true;
162 if (!instance->m_port_assignments.empty())
165 if (instance->m_port_assignments.front().m_port_name.has_value())
167 for (
const auto& port_assignment : instance->m_port_assignments)
169 const std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
170 if (!right_port.empty())
173 if (
const auto port_it = module_it->second->m_ports_by_identifier.find(port_assignment.m_port_name.value());
174 port_it == module_it->second->m_ports_by_identifier.end())
176 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': unable to assign signal to port '" + port_assignment.m_port_name.value()
177 +
"' as it is not a port of module '" + module_it->first +
"'");
181 port = port_it->second;
183 const std::vector<std::string>& left_port = port->m_expanded_identifiers;
184 if (left_port.empty())
186 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': unable to expand port assignment");
189 u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
191 for (
u32 i = 0; i < max_size; i++)
193 instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
201 std::vector<std::string> ports;
202 for (
const auto& port : m_modules_by_name.at(instance->m_type)->m_ports)
204 ports.insert(ports.end(), port->m_expanded_identifiers.begin(), port->m_expanded_identifiers.end());
207 auto port_it = ports.begin();
209 for (
const auto& port_assignment : instance->m_port_assignments)
211 std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
212 if (!right_port.empty())
214 std::vector<std::string> left_port;
216 for (
u32 i = 0; i < right_port.size() && port_it != ports.end(); i++)
218 left_port.push_back(*port_it++);
221 u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
223 for (
u32 i = 0; i < max_size; i++)
225 instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
242 m_netlist = result.get();
243 if (m_netlist ==
nullptr)
245 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': failed to create empty netlist");
248 m_gate_types.clear();
249 m_gnd_gate_types.clear();
250 m_vcc_gate_types.clear();
251 m_module_instantiation_count.clear();
252 m_instance_name_occurences.clear();
253 m_net_name_occurences.clear();
254 m_net_by_name.clear();
255 m_nets_to_merge.clear();
256 m_module_ports.clear();
257 m_module_port_by_net.clear();
258 for (
const auto& verilog_module : m_modules)
260 for (
const auto& instance : verilog_module->m_instances)
262 if (!instance->m_is_module)
264 instance->m_expanded_port_assignments.clear();
276 if (m_zero_net ==
nullptr)
278 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': failed to create zero net");
280 m_net_by_name[m_zero_net->
get_name()] = m_zero_net;
283 if (m_one_net ==
nullptr)
285 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': failed to create one net");
287 m_net_by_name[m_one_net->
get_name()] = m_one_net;
290 std::map<std::string, u32> module_name_to_refereneces;
291 for (
const auto& [_name,
module] : m_modules_by_name)
293 for (
const auto& instance :
module->m_instances)
295 if (
const auto it = m_modules_by_name.find(instance->m_type); it != m_modules_by_name.end())
297 module_name_to_refereneces[it->first]++;
302 std::vector<std::string> top_module_candidates;
303 for (
const auto& [
name,
module] : m_modules_by_name)
305 if (module_name_to_refereneces.find(
name) == module_name_to_refereneces.end())
307 top_module_candidates.push_back(
name);
311 if (top_module_candidates.empty())
313 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': unable to find any top module candidates");
316 if (top_module_candidates.size() > 1)
318 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': found multiple modules as candidates for the top module");
322 VerilogModule* top_module = m_modules_by_name.at(top_module_candidates.front());
324 if (
const auto res = construct_netlist(top_module); res.is_error())
326 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");
330 std::queue<Net*> nets_to_be_deleted;
334 const u32 num_of_sources =
net->get_num_of_sources();
335 const u32 num_of_destinations =
net->get_num_of_destinations();
336 const bool no_source = num_of_sources == 0 && !(
net->is_global_input_net() && num_of_destinations != 0);
337 const bool no_destination = num_of_destinations == 0 && !(
net->is_global_output_net() && num_of_sources != 0);
338 if (no_source && no_destination)
340 nets_to_be_deleted.push(
net);
344 while (!nets_to_be_deleted.empty())
346 Net*
net = nets_to_be_deleted.front();
347 nets_to_be_deleted.pop();
353 return OK(std::move(result));
360 void VerilogParser::tokenize()
362 const std::string delimiters =
"`,()[]{}\\#*: ;=./";
363 std::string current_token;
368 bool in_string =
false;
369 bool escaped =
false;
370 bool in_comment =
false;
372 std::vector<Token<std::string>> parsed_tokens;
373 while (std::getline(m_fs, line))
383 if (c ==
'/' && prev_char ==
'*')
393 if (!in_string && c ==
'\\')
398 else if (escaped && std::isspace(c))
403 else if (!escaped && c ==
'"')
405 in_string = !in_string;
408 if (!in_comment && ((!std::isspace(c) && delimiters.find(c) == std::string::npos) || escaped || in_string))
415 if (!current_token.empty())
417 if (parsed_tokens.size() > 1 &&
utils::is_digits(parsed_tokens.at(parsed_tokens.size() - 2).string) && parsed_tokens.at(parsed_tokens.size() - 1) ==
"."
420 parsed_tokens.pop_back();
421 parsed_tokens.back() +=
"." + current_token;
425 parsed_tokens.emplace_back(line_number, current_token);
427 current_token.clear();
430 if (!parsed_tokens.empty())
433 if (c ==
'(' && parsed_tokens.back() ==
"#")
435 parsed_tokens.back() =
"#(";
438 else if (c ==
'*' && parsed_tokens.back() ==
"(")
440 parsed_tokens.back() =
"(*";
443 else if (c ==
')' && parsed_tokens.back() ==
"*")
445 parsed_tokens.back() =
"*)";
449 else if (c ==
'/' && parsed_tokens.back() ==
"/")
451 parsed_tokens.pop_back();
454 else if (c ==
'*' && parsed_tokens.back() ==
"/")
457 parsed_tokens.pop_back();
462 if (!std::isspace(c))
464 parsed_tokens.emplace_back(line_number, std::string(1, c));
468 if (!current_token.empty())
470 parsed_tokens.emplace_back(line_number, current_token);
471 current_token.clear();
475 m_token_stream = TokenStream(parsed_tokens, {
"(",
"["}, {
")",
"]"});
478 Result<std::monostate> VerilogParser::parse_tokens()
480 std::vector<VerilogDataEntry> attributes;
485 if (m_token_stream.
peek() ==
"(*")
487 parse_attribute(attributes);
489 else if (m_token_stream.
peek() ==
"`")
492 log_warning(
"verilog_parser",
"could not parse compiler directives.");
496 line_number = m_token_stream.
peek().number;
497 if (
auto res = parse_module(attributes); res.is_error())
499 return ERR_APPEND(res.get_error(),
"could not parse tokens: unable to parse module (line " + std::to_string(line_number) +
")");
507 Result<std::monostate> VerilogParser::parse_module(std::vector<VerilogDataEntry>& attributes)
509 std::set<std::string> port_names;
510 std::vector<VerilogDataEntry> internal_attributes;
512 m_token_stream.
consume(
"module",
true);
513 const u32 line_number = m_token_stream.
peek().number;
514 const std::string module_name = m_token_stream.
consume();
517 if (
const auto it = m_modules_by_name.find(module_name); it != m_modules_by_name.end())
519 return ERR(
"could not parse module '" + module_name +
"' (line " + std::to_string(line_number) +
"): a module with the same name already exists (line "
520 + std::to_string(it->second->m_line_number) +
")");
523 auto verilog_module = std::make_unique<VerilogModule>();
524 VerilogModule* verilog_module_raw = verilog_module.get();
525 verilog_module_raw->m_line_number = line_number;
526 verilog_module_raw->m_name = module_name;
529 if (m_token_stream.
consume(
"#("))
533 m_token_stream.
consume(
")",
true);
534 log_warning(
"verilog_parser",
"could not parse parameter list provided for module '{}'.", module_name);
538 m_token_stream.
consume(
"(",
true);
539 Token<std::string> next_token = m_token_stream.
peek();
540 if (next_token ==
"input" || next_token ==
"output" || next_token ==
"inout")
542 if (
auto res = parse_port_declaration_list(verilog_module_raw); res.is_error())
544 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse port declaration list (line " + std::to_string(line_number) +
")");
549 parse_port_list(verilog_module_raw);
552 m_token_stream.
consume(
";",
true);
554 next_token = m_token_stream.
peek();
555 while (next_token !=
"endmodule")
557 if (next_token ==
"input" || next_token ==
"output" || next_token ==
"inout")
559 if (
auto res = parse_port_definition(verilog_module_raw, internal_attributes); res.is_error())
561 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse port definition (line " + std::to_string(line_number) +
")");
564 else if (next_token ==
"wire" || next_token ==
"tri")
566 if (
auto res = parse_signal_definition(verilog_module_raw, internal_attributes); res.is_error())
568 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse signal definition (line " + std::to_string(line_number) +
")");
571 else if (next_token ==
"parameter")
575 m_token_stream.
consume(
";",
true);
576 log_warning(
"verilog_parser",
"could not parse parameter provided for module '{}'.", module_name);
578 else if (next_token ==
"assign")
580 if (
auto res = parse_assignment(verilog_module_raw); res.is_error())
582 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse assignment (line " + std::to_string(line_number) +
")");
585 else if (next_token ==
"defparam")
587 if (
auto res = parse_defparam(verilog_module_raw); res.is_error())
589 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse defparam (line " + std::to_string(line_number) +
")");
592 else if (next_token ==
"(*")
594 parse_attribute(internal_attributes);
598 if (
auto res = parse_instance(verilog_module_raw, internal_attributes); res.is_error())
600 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse instance (line " + std::to_string(line_number) +
")");
604 next_token = m_token_stream.
peek();
607 m_token_stream.
consume(
"endmodule",
true);
610 if (!attributes.empty())
612 verilog_module->m_attributes.insert(verilog_module->m_attributes.end(), attributes.begin(), attributes.end());
617 m_modules.push_back(std::move(verilog_module));
618 m_modules_by_name[module_name] = verilog_module_raw;
619 m_last_module = module_name;
624 void VerilogParser::parse_port_list(VerilogModule* verilog_module)
626 TokenStream<std::string> ports_stream = m_token_stream.
extract_until(
")");
627 m_token_stream.
consume(
")",
true);
629 while (ports_stream.remaining() > 0)
631 Token<std::string> next_token = ports_stream.consume();
632 auto port = std::make_unique<VerilogPort>();
634 if (next_token ==
".")
636 port->m_identifier = ports_stream.consume().string;
637 ports_stream.consume(
"(",
true);
638 port->m_expression = ports_stream.consume().string;
639 ports_stream.consume(
")",
true);
643 port->m_identifier = next_token.string;
644 port->m_expression = next_token.string;
647 verilog_module->m_ports_by_identifier[port->m_identifier] = port.get();
648 verilog_module->m_ports_by_expression[port->m_expression] = port.get();
649 verilog_module->m_ports.push_back(std::move(port));
651 ports_stream.consume(
",", ports_stream.remaining() > 0);
655 Result<std::monostate> VerilogParser::parse_port_declaration_list(VerilogModule* verilog_module)
657 TokenStream<std::string> ports_stream = m_token_stream.
extract_until(
")");
658 m_token_stream.
consume(
")",
true);
660 while (ports_stream.remaining() > 0)
663 const Token<std::string> direction_token = ports_stream.consume();
667 return ERR(
"could not parse port declaration list: invalid direction '" + direction_token.string +
"' (line " + std::to_string(direction_token.number) +
")");
671 std::vector<std::vector<u32>> ranges;
672 while (ports_stream.consume(
"["))
674 const std::vector<u32> range = parse_range(ports_stream);
675 ports_stream.consume(
"]",
true);
677 ranges.emplace_back(range);
683 const Token<std::string> next_token = ports_stream.peek();
684 if (next_token ==
"input" || next_token ==
"output" || next_token ==
"inout")
688 ports_stream.consume();
690 auto port = std::make_unique<VerilogPort>();
691 const std::string& port_expression = next_token.string;
692 port->m_identifier = port_expression;
693 port->m_expression = port_expression;
697 port->m_ranges = ranges;
699 verilog_module->m_ports_by_identifier[port_expression] = port.get();
700 verilog_module->m_ports_by_expression[port_expression] = port.get();
701 verilog_module->m_ports.push_back(std::move(port));
704 if (verilog_module->m_signals_by_name.find(port_expression) == verilog_module->m_signals_by_name.end())
706 auto signal = std::make_unique<VerilogSignal>();
707 signal->m_name = port_expression;
710 signal->m_ranges = ranges;
712 verilog_module->m_signals_by_name[port_expression] = signal.get();
713 verilog_module->m_signals.push_back(std::move(signal));
715 }
while (ports_stream.consume(
",", ports_stream.remaining() > 0));
721 Result<std::monostate> VerilogParser::parse_port_definition(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
724 const Token<std::string> direction_token = m_token_stream.
consume();
728 return ERR(
"could not parse port definition: invalid direction '" + direction_token.string +
"' (line " + std::to_string(direction_token.number) +
")");
732 std::vector<std::vector<u32>> ranges;
733 while (m_token_stream.
consume(
"["))
735 const std::vector<u32> range = parse_range(m_token_stream);
736 m_token_stream.
consume(
"]",
true);
738 ranges.emplace_back(range);
744 Token<std::string> port_expression_token = m_token_stream.
consume();
745 std::string port_expression = port_expression_token.string;
748 if (
const auto it = verilog_module->m_ports_by_expression.find(port_expression); it == verilog_module->m_ports_by_expression.end())
750 return ERR(
"could not parse port definition: a port with name '" + port_expression +
"' does not exist for module '" + verilog_module->m_name +
"' (line "
751 + std::to_string(direction_token.number) +
")");
761 port->m_ranges = ranges;
765 if (
const auto signal_it = verilog_module->m_signals_by_name.find(port_expression); signal_it == verilog_module->m_signals_by_name.end())
767 auto signal = std::make_unique<VerilogSignal>();
768 signal->m_name = port_expression;
771 signal->m_ranges = ranges;
773 signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
774 verilog_module->m_signals_by_name[port_expression] = signal.get();
775 verilog_module->m_signals.push_back(std::move(signal));
779 auto* signal = signal_it->second;
780 signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
782 }
while (m_token_stream.
consume(
",",
false));
784 m_token_stream.
consume(
";",
true);
790 Result<std::monostate> VerilogParser::parse_signal_definition(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
793 u32 line_number = m_token_stream.
consume().number;
795 TokenStream<std::string> signal_stream = m_token_stream.
extract_until(
";");
796 m_token_stream.
consume(
";",
true);
799 std::vector<std::vector<u32>> ranges;
800 while (signal_stream.consume(
"["))
802 const std::vector<u32> range = parse_range(signal_stream);
803 signal_stream.consume(
"]",
true);
805 ranges.emplace_back(range);
811 Token<std::string> signal_name = signal_stream.consume();
812 if (signal_stream.remaining() > 0 && signal_stream.peek() ==
"=")
814 VerilogAssignment assignment;
815 assignment.m_variable.push_back(signal_name);
816 signal_stream.consume(
"=",
true);
817 if (
auto res = parse_assignment_expression(signal_stream.extract_until(
",")); res.is_error())
819 return ERR_APPEND(res.get_error(),
"could not parse signal definition: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
823 assignment.m_assignment = res.get();
825 verilog_module->m_assignments.push_back(std::move(assignment));
829 if (
const auto signal_it = verilog_module->m_signals_by_name.find(signal_name.string); signal_it == verilog_module->m_signals_by_name.end())
831 auto signal = std::make_unique<VerilogSignal>();
832 signal->m_name = signal_name.string;
835 signal->m_ranges = ranges;
837 signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
838 verilog_module->m_signals_by_name[signal_name.string] = signal.get();
839 verilog_module->m_signals.push_back(std::move(signal));
843 auto* signal = signal_it->second;
844 signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
847 }
while (signal_stream.consume(
",",
false));
854 Result<std::monostate> VerilogParser::parse_assignment(VerilogModule* verilog_module)
856 m_token_stream.
consume(
"assign",
true);
857 u32 line_number = m_token_stream.
peek().number;
858 VerilogAssignment assignment;
860 if (
auto res = parse_assignment_expression(m_token_stream.
extract_until(
"=")); res.is_error())
862 return ERR_APPEND(res.get_error(),
"could not parse assignment: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
866 assignment.m_variable = res.get();
868 m_token_stream.
consume(
"=",
true);
870 if (
auto res = parse_assignment_expression(m_token_stream.
extract_until(
";")); res.is_error())
872 return ERR_APPEND(res.get_error(),
"could not parse assignment: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
876 assignment.m_assignment = res.get();
880 for (
const auto& var : assignment.m_variable)
882 if (
const auto* identifier = std::get_if<identifier_t>(&var); identifier !=
nullptr)
884 if (verilog_module->m_signals_by_name.find(*identifier) == verilog_module->m_signals_by_name.end())
886 auto signal = std::make_unique<VerilogSignal>();
887 signal->m_name = *identifier;
888 verilog_module->m_signals_by_name[*identifier] = signal.get();
889 verilog_module->m_signals.push_back(std::move(signal));
892 else if (
const auto* ranged_identifier = std::get_if<ranged_identifier_t>(&var); ranged_identifier !=
nullptr)
894 const auto& signal_name = std::get<0>(*ranged_identifier);
895 if (verilog_module->m_signals_by_name.find(signal_name) == verilog_module->m_signals_by_name.end())
897 auto signal = std::make_unique<VerilogSignal>();
898 signal->m_name = signal_name;
899 signal->m_ranges = std::get<1>(*ranged_identifier);
900 verilog_module->m_signals_by_name[signal_name] = signal.get();
901 verilog_module->m_signals.push_back(std::move(signal));
905 m_token_stream.
consume(
";",
true);
907 verilog_module->m_assignments.push_back(std::move(assignment));
911 Result<std::monostate> VerilogParser::parse_defparam(VerilogModule*
module)
913 m_token_stream.
consume(
"defparam",
true);
914 std::string instance_name = m_token_stream.
consume().string;
915 m_token_stream.
consume(
".",
true);
917 if (
const auto inst_it =
module->m_instances_by_name.find(instance_name); inst_it !=
module->m_instances_by_name.end())
919 VerilogDataEntry param;
920 param.m_name = m_token_stream.
consume().string;
921 m_token_stream.
consume(
"=",
true);
923 if (
const auto res = parse_parameter_value(m_token_stream.
consume()); res.is_ok())
925 const auto value = res.get();
926 param.m_type = value.first;
927 param.m_value = value.second;
928 inst_it->second->m_parameters.push_back(param);
932 log_warning(
"verilog_parser",
"{}", res.get_error().get());
937 m_token_stream.
consume(
";",
true);
938 return ERR(
"could not parse defparam: no instance with name '" + instance_name +
"' exists within module '" +
module->m_name +
"'");
941 m_token_stream.
consume(
";",
true);
945 void VerilogParser::parse_attribute(std::vector<VerilogDataEntry>& attributes)
947 m_token_stream.
consume(
"(*",
true);
952 VerilogDataEntry attribute;
953 attribute.m_name = m_token_stream.
consume().string;
956 if (m_token_stream.
consume(
"="))
958 attribute.m_value = m_token_stream.
consume();
961 if (attribute.m_value[0] ==
'\"' && attribute.m_value.back() ==
'\"')
963 attribute.m_value = attribute.m_value.substr(1, attribute.m_value.size() - 2);
967 attributes.push_back(std::move(attribute));
969 }
while (m_token_stream.
consume(
",",
false));
971 m_token_stream.
consume(
"*)",
true);
974 Result<std::monostate> VerilogParser::parse_instance(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
976 auto instance = std::make_unique<VerilogInstance>();
977 u32 line_number = m_token_stream.
peek().number;
978 instance->m_type = m_token_stream.
consume().string;
981 if (m_token_stream.
consume(
"#("))
983 if (
auto res = parse_parameter_assign(); res.is_error())
985 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) +
")");
989 instance->m_parameters = res.get();
994 instance->m_name = m_token_stream.
consume().string;
997 if (
auto res = parse_port_assign(instance.get()); res.is_error())
1000 "could not parse instance '" + instance->m_name +
"' of type '" + instance->m_type +
"': unable to parse port assignment (line " + std::to_string(line_number) +
")");
1004 instance->m_attributes = attributes;
1007 verilog_module->m_instances_by_name[instance->m_name] = instance.get();
1008 verilog_module->m_instances.push_back(std::move(instance));
1013 Result<std::monostate> VerilogParser::parse_port_assign(VerilogInstance* instance)
1015 u32 line_number = m_token_stream.
peek().number;
1016 m_token_stream.
consume(
"(",
true);
1018 if (m_token_stream.
peek() ==
".")
1023 VerilogPortAssignment port_assignment;
1024 port_assignment.m_port_name = m_token_stream.
consume().string;
1025 m_token_stream.
consume(
"(",
true);
1026 if (
auto res = parse_assignment_expression(m_token_stream.
extract_until(
")")); res.is_error())
1028 return ERR_APPEND(res.get_error(),
"could not parse port assignment: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
1032 port_assignment.m_assignment = res.get();
1034 m_token_stream.
consume(
")",
true);
1035 if (port_assignment.m_assignment.empty())
1039 instance->m_port_assignments.push_back(std::move(port_assignment));
1040 }
while (m_token_stream.
consume(
",",
false));
1046 VerilogPortAssignment port_assignment;
1047 if (
auto res = parse_assignment_expression(m_token_stream.
extract_until(
",", line_end - 1)); res.is_error())
1049 return ERR_APPEND(res.get_error(),
"could not parse port assignment: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
1053 port_assignment.m_assignment = res.get();
1055 if (port_assignment.m_assignment.empty())
1059 instance->m_port_assignments.push_back(std::move(port_assignment));
1060 }
while (m_token_stream.
consume(
",",
false));
1063 m_token_stream.
consume(
")",
true);
1064 m_token_stream.
consume(
";",
true);
1069 Result<std::vector<VerilogParser::VerilogDataEntry>> VerilogParser::parse_parameter_assign()
1071 std::vector<VerilogDataEntry> generics;
1075 if (m_token_stream.
consume(
".",
false))
1077 const Token<std::string> lhs = m_token_stream.
join_until(
"(",
"");
1078 m_token_stream.
consume(
"(",
true);
1079 const Token<std::string> rhs = m_token_stream.
join_until(
")",
"");
1080 m_token_stream.
consume(
")",
true);
1082 if (
const auto res = parse_parameter_value(rhs); res.is_ok())
1084 const auto value = res.get();
1085 generics.push_back(VerilogDataEntry({lhs.string, value.first, value.second}));
1089 log_warning(
"verilog_parser",
"{}", res.get_error().get());
1092 }
while (m_token_stream.
consume(
",",
false));
1094 m_token_stream.
consume(
")",
true);
1096 return OK(generics);
1103 Result<std::monostate> VerilogParser::construct_netlist(VerilogModule* top_module)
1109 std::queue<VerilogModule*> q;
1114 VerilogModule*
module = q.front();
1117 m_module_instantiation_count[
module->m_name]++;
1120 for (
const auto& s :
module->m_signals)
1122 std::vector<std::string> expanded_names;
1123 expand_ranges_recursively(expanded_names, s->m_name, s->m_ranges, 0);
1124 for (
const auto& net_name : expanded_names)
1126 m_net_name_occurences[net_name]++;
1130 for (
const auto& instance :
module->m_instances)
1132 m_instance_name_occurences[instance->m_name]++;
1135 if (
const auto it = m_modules_by_name.find(instance->m_type); it != m_modules_by_name.end())
1142 for (
auto& [module_name, verilog_module] : m_modules_by_name)
1145 if (m_module_instantiation_count[module_name] == 0)
1147 log_warning(
"verilog_parser",
"module '{}' has been defined in the netlist but is not instantiated.", module_name);
1152 for (
const auto& instance : verilog_module->m_instances)
1154 if (
const auto gate_type_it = m_gate_types.find(instance->m_type); gate_type_it != m_gate_types.end())
1156 if (!instance->m_port_assignments.empty())
1159 if (instance->m_port_assignments.front().m_port_name.has_value())
1162 std::unordered_map<std::string, std::vector<std::string>> pin_groups;
1163 for (
const auto pin_group : gate_type_it->second->get_pin_groups())
1165 const auto pins = pin_group->get_pins();
1166 for (
auto it =
pins.rbegin(); it !=
pins.rend(); it++)
1168 const auto* pin = *it;
1169 pin_groups[pin_group->get_name()].push_back(pin->get_name());
1173 for (
const auto& port_assignment : instance->m_port_assignments)
1175 std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
1176 if (!right_port.empty())
1178 std::vector<std::string> left_port;
1180 const auto& port_name = port_assignment.m_port_name.value();
1181 if (
const auto group_it = pin_groups.find(port_name); group_it != pin_groups.end())
1183 left_port = group_it->second;
1187 left_port.push_back(port_name);
1190 u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
1192 for (
u32 i = 0; i < max_size; i++)
1194 instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
1203 std::vector<std::string>
pins = gate_type_it->second->get_pin_names();
1204 auto pin_it =
pins.begin();
1206 for (
const auto& port_assignment : instance->m_port_assignments)
1208 std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
1209 if (!right_port.empty())
1211 std::vector<std::string> left_port;
1213 for (
u32 i = 0; i < right_port.size() && pin_it !=
pins.end(); i++)
1215 left_port.push_back(*pin_it++);
1218 u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
1220 for (
u32 i = 0; i < max_size; i++)
1222 instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
1233 std::unordered_map<std::string, std::string> top_assignments;
1234 for (
const auto& port : top_module->m_ports)
1236 for (
const auto& expanded_port_identifier : port->m_expanded_identifiers)
1238 const auto signal_name = get_unique_alias(
"", expanded_port_identifier +
"__GLOBAL_IO__", m_net_name_occurences);
1239 m_net_name_occurences[signal_name]++;
1242 if (global_port_net ==
nullptr)
1244 return ERR(
"could not construct netlist: failed to create global I/O net '" + signal_name +
"'");
1247 m_net_by_name[signal_name] = global_port_net;
1250 top_assignments[expanded_port_identifier] = signal_name;
1254 if (!global_port_net->mark_global_input_net())
1256 return ERR(
"could not construct netlist: failed to mark global I/O net '" + signal_name +
"' as global input");
1262 if (!global_port_net->mark_global_output_net())
1264 return ERR(
"could not construct netlist: failed to mark global I/O net '" + signal_name +
"' as global output");
1270 if (
auto res = instantiate_module(
"top_module", top_module,
nullptr, top_assignments); res.is_error())
1272 return ERR_APPEND(res.get_error(),
"could not construct netlist: unable to instantiate top module");
1276 std::unordered_map<std::string, std::string> merged_nets;
1277 std::unordered_map<std::string, std::vector<std::string>> master_to_slaves;
1279 for (
auto& [master, slave] : m_nets_to_merge)
1284 if (
const auto master_it = merged_nets.find(master); master_it != merged_nets.end())
1286 master = master_it->second;
1297 if (
const auto slave_it = merged_nets.find(slave); slave_it != merged_nets.end())
1299 slave = slave_it->second;
1307 auto master_net = m_net_by_name.at(master);
1308 auto slave_net = m_net_by_name.at(slave);
1310 if (master_net == slave_net)
1314 else if (slave_net == m_zero_net || slave_net == m_one_net)
1316 auto* tmp_net = master_net;
1317 master_net = slave_net;
1318 slave_net = tmp_net;
1320 auto tmp_name = master;
1326 if (slave_net->is_global_input_net())
1328 master_net->mark_global_input_net();
1331 for (
auto src : slave_net->get_sources())
1333 Gate* src_gate = src->get_gate();
1334 GatePin* src_pin = src->get_pin();
1336 if (!slave_net->remove_source(src))
1338 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()));
1341 if (!master_net->is_a_source(src_gate, src_pin))
1343 if (!master_net->add_source(src_gate, src_pin))
1345 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()));
1351 if (slave_net->is_global_output_net())
1353 master_net->mark_global_output_net();
1356 for (
auto dst : slave_net->get_destinations())
1358 Gate* dst_gate = dst->get_gate();
1359 GatePin* dst_pin = dst->get_pin();
1361 if (!slave_net->remove_destination(dst))
1363 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()));
1366 if (!master_net->is_a_destination(dst_gate, dst_pin))
1368 if (!master_net->add_destination(dst_gate, dst_pin))
1370 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()));
1376 for (
const auto& [identifier, content] : slave_net->get_data_map())
1378 if (!master_net->set_data(std::get<0>(identifier), std::get<1>(identifier), std::get<0>(content), std::get<1>(content)))
1381 "unable to transfer data from slave net '{}' with ID {} to master net '{}' with ID {}.",
1382 slave_net->get_name(),
1383 slave_net->get_id(),
1384 master_net->get_name(),
1385 master_net->get_id());
1390 if (
const auto it = m_module_port_by_net.find(slave_net); it != m_module_port_by_net.end())
1392 for (
auto [
module, index] : it->second)
1394 std::get<1>(m_module_ports.at(
module).at(index)) = master_net;
1396 m_module_port_by_net[master_net].insert(m_module_port_by_net[master_net].end(), it->second.begin(), it->second.end());
1397 m_module_port_by_net.erase(it);
1401 m_net_by_name.erase(slave);
1402 merged_nets[slave] = master;
1403 master_to_slaves[master].push_back(slave);
1407 for (
auto& master_net : m_netlist->
get_nets())
1409 const auto master_name = master_net->get_name();
1411 if (
const auto m2s_it = master_to_slaves.find(master_name); m2s_it != master_to_slaves.end())
1413 std::vector<std::vector<std::string>> merged_slaves;
1414 auto current_slaves = m2s_it->second;
1416 while (!current_slaves.empty())
1418 std::vector<std::string> next_slaves;
1419 for (
const auto& s : current_slaves)
1421 if (
const auto m2s_inner_it = master_to_slaves.find(s); m2s_inner_it != master_to_slaves.end())
1423 next_slaves.insert(next_slaves.end(), m2s_inner_it->second.begin(), m2s_inner_it->second.end());
1427 merged_slaves.push_back(current_slaves);
1428 current_slaves = next_slaves;
1429 next_slaves.clear();
1434 std::string merged_str =
"";
1435 bool has_merged_nets =
false;
1436 for (
const auto& vec : merged_slaves)
1440 has_merged_nets =
true;
1442 const auto s =
utils::join(
", ", vec, [](
const auto e) {
return '"' + e +
'"'; });
1443 merged_str +=
"[" + s +
"], ";
1445 merged_str = merged_str.substr(0, merged_str.size() - 2);
1447 if (has_merged_nets)
1449 master_net->set_data(
"parser_annotation",
"merged_nets",
"string",
"[" + merged_str +
"]");
1459 GateType* gnd_type = m_gnd_gate_types.begin()->second;
1460 GatePin* output_pin = gnd_type->get_output_pins().front();
1465 return ERR(
"failed to mark GND gate");
1468 if (m_zero_net->
add_source(gnd, output_pin) ==
nullptr)
1470 return ERR(
"failed to add source to GND gate");
1476 m_zero_net =
nullptr;
1485 GateType* vcc_type = m_vcc_gate_types.begin()->second;
1486 GatePin* output_pin = vcc_type->get_output_pins().front();
1491 return ERR(
"failed to mark VCC gate");
1494 if (m_one_net->
add_source(vcc, output_pin) ==
nullptr)
1496 return ERR(
"failed to add source to VCC gate");
1502 m_one_net =
nullptr;
1513 for (
const auto& [
module, ports] : m_module_ports)
1518 for (
const auto& [port_name, port_net] : ports)
1528 "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())
1538 Result<Module*> VerilogParser::instantiate_module(
const std::string& instance_identifier,
1539 VerilogModule* verilog_module,
1541 const std::unordered_map<std::string, std::string>& parent_module_assignments)
1543 std::unordered_map<std::string, std::string> signal_alias;
1544 std::unordered_map<std::string, std::string> instance_alias;
1548 const std::string parent_name = (parent ==
nullptr) ?
"" : parent->get_name();
1549 instance_alias[instance_identifier] = get_unique_alias(parent_name, instance_identifier, m_instance_name_occurences);
1553 if (parent ==
nullptr)
1563 std::string instance_type = verilog_module->m_name;
1566 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to create module");
1571 for (
const VerilogDataEntry& attribute : verilog_module->m_attributes)
1573 if (!
module->
set_data(
"attribute", attribute.m_name, attribute.m_type, attribute.m_value))
1576 "could not set attribute '{} = {}' of type '{}' for instance '{}' type '{}'.",
1580 instance_identifier,
1586 for (
const auto& port : verilog_module->m_ports)
1588 for (
const auto& expanded_port_identifier : port->m_expanded_identifiers)
1590 if (
const auto it = parent_module_assignments.find(expanded_port_identifier); it != parent_module_assignments.end())
1592 Net* port_net = m_net_by_name.at(it->second);
1593 m_module_ports[
module].push_back(std::make_tuple(expanded_port_identifier, port_net));
1594 m_module_port_by_net[port_net].push_back(std::make_pair(
module, m_module_ports[
module].size() - 1));
1600 for (
const auto& signal : verilog_module->m_signals)
1602 for (
const auto& expanded_name : signal->m_expanded_names)
1604 std::string unique_net_name = get_unique_alias(
module->
get_name(), expanded_name, m_net_name_occurences);
1605 if (unique_net_name != expanded_name)
1607 m_net_name_occurences[unique_net_name]++;
1609 signal_alias[expanded_name] = unique_net_name;
1612 Net* signal_net = m_netlist->
create_net(signal_alias.at(expanded_name));
1613 if (signal_net ==
nullptr)
1615 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to create net '" + expanded_name +
"'");
1618 m_net_by_name[signal_alias.at(expanded_name)] = signal_net;
1621 for (
const VerilogDataEntry& attribute : signal->m_attributes)
1623 if (!signal_net->set_data(
"attribute", attribute.m_name,
"unknown", attribute.m_value))
1626 "could not set attribute ({} = {}) for net '{}' of instance '{}' of type '{}'.",
1630 instance_identifier,
1638 for (
const auto& [left_expanded_signal, right_expanded_signal] : verilog_module->m_expanded_assignments)
1640 std::string a = left_expanded_signal;
1641 std::string b = right_expanded_signal;
1643 if (
const auto alias_it = signal_alias.find(a); alias_it != signal_alias.end())
1645 a = alias_it->second;
1649 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to find alias for net '" + a +
"'");
1652 if (
const auto alias_it = signal_alias.find(b); alias_it != signal_alias.end())
1654 b = alias_it->second;
1656 else if (b ==
"'Z'" || b ==
"'X'")
1660 else if (b !=
"'0'" && b !=
"'1'")
1662 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to find alias for net '" + b +
"'");
1665 m_nets_to_merge.push_back(std::make_pair(a, b));
1669 for (
const auto& [port_identifier, net_name] : parent_module_assignments)
1671 std::string signal_name;
1672 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())
1674 signal_name = port_identifier;
1678 signal_name = expr_it->second;
1682 if (
const auto alias_it = signal_alias.find(signal_name); alias_it != signal_alias.end())
1684 const bool swap = net_name.find(
"__GLOBAL_IO__") == std::string::npos;
1685 m_nets_to_merge.push_back(swap ? std::make_pair(net_name, alias_it->second) : std::make_pair(alias_it->second, net_name));
1689 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to find alias for net '" + signal_name +
"'");
1694 for (
const auto& instance : verilog_module->m_instances)
1697 DataContainer* container =
nullptr;
1700 std::unordered_map<std::string, std::string> instance_assignments;
1703 if (
auto module_it = m_modules_by_name.find(instance->m_type); module_it != m_modules_by_name.end())
1706 for (
const auto& [port, assignment] : instance->m_expanded_port_assignments)
1708 if (
const auto alias_it = signal_alias.find(assignment); alias_it != signal_alias.end())
1710 instance_assignments[port] = alias_it->second;
1712 else if (assignment ==
"'0'" || assignment ==
"'1'")
1714 instance_assignments[port] = assignment;
1716 else if (assignment ==
"'Z'" || assignment ==
"'X'" || assignment.empty())
1722 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': port assignment '" + port +
" = " + assignment +
"' is invalid");
1726 if (
auto res = instantiate_module(instance->m_name, module_it->second,
module, instance_assignments); res.is_error())
1729 "could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': unable to create instance '" + instance->m_name +
"' of type '"
1730 + module_it->second->m_name +
"'");
1734 container = res.get();
1738 else if (
const auto gate_type_it = m_gate_types.find(instance->m_type); gate_type_it != m_gate_types.end())
1741 instance_alias[instance->m_name] = get_unique_alias(
module->
get_name(), instance->m_name, m_instance_name_occurences);
1742 Gate* new_gate = m_netlist->
create_gate(gate_type_it->second, instance_alias.at(instance->m_name));
1743 if (new_gate ==
nullptr)
1745 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to create gate '" + instance->m_name +
"'");
1753 container = new_gate;
1756 if (m_vcc_gate_types.find(instance->m_type) != m_vcc_gate_types.end() && !new_gate->mark_vcc_gate())
1758 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to mark '" + instance->m_name +
"' of type '" + instance->m_type
1761 if (m_gnd_gate_types.find(instance->m_type) != m_gnd_gate_types.end() && !new_gate->mark_gnd_gate())
1763 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to mark '" + instance->m_name +
"' of type '" + instance->m_type
1768 std::unordered_map<std::string, GatePin*> pin_names_map;
1769 for (
auto* pin : gate_type_it->second->get_pins())
1771 pin_names_map[pin->get_name()] = pin;
1775 for (
const auto& [pin, assignment] : instance->m_expanded_port_assignments)
1779 if (
const auto alias_it = signal_alias.find(assignment); alias_it != signal_alias.end())
1781 signal = alias_it->second;
1783 else if (assignment ==
"'0'" || assignment ==
"'1'")
1785 signal = assignment;
1787 else if (assignment ==
"'Z'" || assignment ==
"'X'")
1793 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to assign '" + assignment +
"' to pin '" + pin +
"' of gate '"
1794 + instance->m_name +
"' of type '" + instance->m_type +
"' as the assignment is invalid");
1798 if (
const auto net_it = m_net_by_name.find(signal); net_it == m_net_by_name.end())
1800 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to assign signal'" + signal +
"' to pin '" + pin
1801 +
"' as the signal has not been declared");
1805 Net* current_net = net_it->second;
1808 bool is_input =
false;
1809 bool is_output =
false;
1811 if (
const auto it = pin_names_map.find(pin); it != pin_names_map.end())
1825 if (!is_input && !is_output)
1827 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to assign net '" + signal +
"' to pin '" + pin
1828 +
"' as it is not a pin of gate '" + new_gate->get_name() +
"' of type '" + new_gate->get_type()->get_name() +
"'");
1831 if (is_output && !current_net->add_source(new_gate, pin))
1833 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to add net '" + signal +
"' as a source to gate '"
1834 + new_gate->get_name() +
"' via pin '" + pin +
"'");
1837 if (is_input && !current_net->add_destination(new_gate, pin))
1839 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to add net '" + signal +
"' as a destination to gate '"
1840 + new_gate->get_name() +
"' via pin '" + pin +
"'");
1847 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to find gate type '" + instance->m_type +
"' in gate library '"
1852 for (
const auto& attribute : instance->m_attributes)
1854 if (!container->set_data(
"attribute", attribute.m_name, attribute.m_type, attribute.m_value))
1857 "could not set attribute '{} = {}' of type '{}' for instance '{}' of type '{}' within instance '{}' of type '{}'.",
1863 instance_identifier,
1869 for (
const auto& parameter : instance->m_parameters)
1871 if (!container->set_data(
"generic", parameter.m_name, parameter.m_type, parameter.m_value))
1874 "could not set generic '{} = {}' of type '{}' for instance '{}' of type '{}' within instance '{}' of type '{}'.",
1880 instance_identifier,
1895 static const std::map<char, BooleanFunction::Value> bin_map = {{
'0', BooleanFunction::Value::ZERO},
1896 {
'1', BooleanFunction::Value::ONE},
1897 {
'X', BooleanFunction::Value::X},
1898 {
'Z', BooleanFunction::Value::Z}};
1900 static const std::map<char, std::vector<BooleanFunction::Value>> oct_map = {{
'0', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1901 {
'1', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1902 {
'2', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1903 {
'3', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1904 {
'4', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1905 {
'5', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1906 {
'6', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1907 {
'7', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1908 {
'X', {BooleanFunction::Value::X, BooleanFunction::Value::X, BooleanFunction::Value::X}},
1909 {
'Z', {BooleanFunction::Value::Z, BooleanFunction::Value::Z, BooleanFunction::Value::Z}}};
1911 static const std::map<char, std::vector<BooleanFunction::Value>> hex_map = {
1912 {
'0', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1913 {
'1', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1914 {
'2', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1915 {
'3', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO}},
1916 {
'4', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1917 {
'5', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1918 {
'6', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1919 {
'7', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO}},
1920 {
'8', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1921 {
'9', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1922 {
'A', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1923 {
'B', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE}},
1924 {
'C', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1925 {
'D', {BooleanFunction::Value::ONE, BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1926 {
'E', {BooleanFunction::Value::ZERO, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1927 {
'F', {BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE, BooleanFunction::Value::ONE}},
1928 {
'X', {BooleanFunction::Value::X, BooleanFunction::Value::X, BooleanFunction::Value::X, BooleanFunction::Value::X}},
1929 {
'Z', {BooleanFunction::Value::Z, BooleanFunction::Value::Z, BooleanFunction::Value::Z, BooleanFunction::Value::Z}}};
1933 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
1935 std::string unique_alias =
name;
1937 if (!parent_name.empty())
1941 auto instance_name_it = name_occurences.find(
name);
1947 while (instance_name_it != name_occurences.end() && (cnt || instance_name_it->second > 1))
1949 std::string extension;
1952 extension =
"_u" + std::to_string(cnt);
1954 unique_alias = parent_name + instance_name_seperator + unique_alias + extension;
1955 instance_name_it = name_occurences.find(unique_alias);
1959 return unique_alias;
1962 std::vector<u32> VerilogParser::parse_range(TokenStream<std::string>& stream)
const
1964 if (stream.remaining() == 1)
1966 return {(
u32)std::stoi(stream.consume().string)};
1970 const int end = std::stoi(stream.consume().string);
1971 stream.consume(
":",
true);
1972 const int start = std::stoi(stream.consume().string);
1974 const int direction = (start <= end) ? 1 : -1;
1976 std::vector<u32> result;
1979 result.push_back((
u32)i);
1984 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
1987 if (ranges.size() > dimension)
1989 for (
const u32 index : ranges[dimension])
1991 expand_ranges_recursively(expanded_names, current_name +
"(" + std::to_string(index) +
")", ranges, dimension + 1);
1997 expanded_names.push_back(current_name);
2001 std::vector<std::string> VerilogParser::expand_ranges(
const std::string&
name,
const std::vector<std::vector<u32>>& ranges)
const
2003 std::vector<std::string> res;
2005 expand_ranges_recursively(res,
name, ranges, 0);
2010 Result<std::vector<BooleanFunction::Value>> VerilogParser::get_binary_vector(std::string value)
const
2017 std::vector<BooleanFunction::Value> result;
2020 if (value.find(
'\'') == std::string::npos)
2027 if (value.at(0) !=
'\'')
2029 len = std::stoi(value.substr(0, value.find(
'\'')));
2031 prefix = value.substr(value.find(
'\'') + 1, 1);
2032 number = value.substr(value.find(
'\'') + 2);
2036 switch (prefix.at(0))
2039 for (
auto it = number.rbegin(); it != number.rend(); it++)
2042 if (c ==
'0' || c ==
'1' || c ==
'Z' || c ==
'X')
2044 result.push_back(bin_map.at(c));
2048 return ERR(
"could not convert string to binary vector: invalid character within binary number literal '" + value +
"'");
2055 for (
auto it = number.rbegin(); it != number.rend(); it++)
2058 if ((c >=
'0' && c <=
'7') || c ==
'X' || c ==
'Z')
2060 const auto& bits = oct_map.at(c);
2061 result.insert(result.end(), bits.begin(), bits.end());
2065 return ERR(
"could not convert string to binary vector: invalid character within octal number literal '" + value +
"'");
2073 for (
const char c : number)
2075 if ((c >=
'0' && c <=
'9'))
2077 tmp_val = (tmp_val * 10) + (c -
'0');
2081 return ERR(
"could not convert string to binary vector: invalid character within decimal number literal '" + value +
"'");
2087 result.push_back(((tmp_val & 1) == 1) ? BooleanFunction::Value::ONE : BooleanFunction::Value::ZERO);
2089 }
while (tmp_val != 0);
2094 for (
auto it = number.rbegin(); it != number.rend(); it++)
2097 if ((c >=
'0' && c <=
'9') || (c >=
'A' && c <=
'F') || c ==
'X' || c ==
'Z')
2099 const auto& bits = hex_map.at(c);
2100 result.insert(result.end(), bits.begin(), bits.end());
2104 return ERR(
"could not convert string to binary vector: invalid character within hexadecimal number literal '" + value +
"'");
2111 return ERR(
"could not convert string to binary vector: invalid base '" + prefix +
"' within number literal '" + value +
"'");
2117 i32 result_size = result.size();
2119 if (len > result_size)
2122 for (
i32 i = 0; i < (len - result_size); i++)
2124 result.push_back(BooleanFunction::Value::ZERO);
2130 for (
i32 i = 0; i < (result_size - len); i++)
2140 Result<std::string> VerilogParser::get_hex_from_literal(
const Token<std::string>& value_token)
const
2142 const u32 line_number = value_token.number;
2151 if (value.find(
'\'') == std::string::npos)
2158 if (value.at(0) !=
'\'')
2160 len = std::stoi(value.substr(0, value.find(
'\'')));
2162 prefix = value.substr(value.find(
'\'') + 1, 1);
2163 number = value.substr(value.find(
'\'') + 2);
2167 switch (prefix.at(0))
2170 if (!std::all_of(number.begin(), number.end(), [](
const char& c) { return (c >=
'0' && c <=
'1'); }))
2172 return ERR(
"could not convert token to hexadecimal string: invalid character within binary number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2180 if (!std::all_of(number.begin(), number.end(), [](
const char& c) { return (c >=
'0' && c <=
'7'); }))
2182 return ERR(
"could not convert token to hexadecimal string: invalid character within ocatl number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2190 if (!std::all_of(number.begin(), number.end(), [](
const char& c) { return (c >=
'0' && c <=
'9'); }))
2192 return ERR(
"could not convert token to hexadecimal string: invalid character within decimal number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2202 for (
const char c : number)
2204 if ((c >=
'0' && c <=
'9') || (c >=
'A' && c <=
'F'))
2210 return ERR(
"could not convert token to hexadecimal string: invalid character within hexadecimal number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2218 return ERR(
"could not convert token to hexadecimal string: invalid base '" + prefix +
"' within number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2222 std::stringstream ss;
2226 ss << std::uppercase << std::setfill(
'0') << std::setw((len + 3) / 4) << std::hex << stoull(number, 0, base);
2230 ss << std::uppercase << std::hex << stoull(number, 0, base);
2232 return OK(ss.str());
2235 Result<std::pair<std::string, std::string>> VerilogParser::parse_parameter_value(
const Token<std::string>& value_token)
const
2237 std::pair<std::string, std::string> value;
2241 value.first =
"integer";
2242 value.second = value_token.string;
2246 value.first =
"floating_point";
2247 value.second = value_token.string;
2249 else if (value_token.string[0] ==
'\"' && value_token.string.back() ==
'\"')
2251 value.first =
"string";
2252 value.second = value_token.string.substr(1, value_token.string.size() - 2);
2254 else if (isdigit(value_token.string[0]) || value_token.string[0] ==
'\'')
2256 if (
const auto res = get_hex_from_literal(value_token); res.is_error())
2259 "could not parse parameter value: failed to convert '" + value_token.string +
"' to hexadecimal value (line " + std::to_string(value_token.number) +
")");
2263 value.second = res.get();
2266 if (value.second ==
"0" || value.second ==
"1")
2268 value.first =
"bit_value";
2272 value.first =
"bit_vector";
2277 return ERR(
"could not parse parameter value: failed to identify data type of parameter '" + value_token.string +
"' (line " + std::to_string(value_token.number) +
")");
2283 Result<std::vector<VerilogParser::assignment_t>> VerilogParser::parse_assignment_expression(TokenStream<std::string>&& stream)
const
2285 std::vector<TokenStream<std::string>> parts;
2287 if (stream.size() == 0)
2292 if (stream.peek() ==
"{")
2294 stream.consume(
"{",
true);
2296 TokenStream<std::string> assignment_list_str = stream.extract_until(
"}");
2297 stream.consume(
"}",
true);
2301 parts.push_back(assignment_list_str.extract_until(
","));
2302 }
while (assignment_list_str.consume(
",",
false));
2306 parts.push_back(stream);
2309 std::vector<assignment_t> result;
2310 result.reserve(parts.size());
2312 for (
auto it = parts.rbegin(); it != parts.rend(); it++)
2314 TokenStream<std::string>& part_stream = *it;
2316 const Token<std::string> signal_name_token = part_stream.consume();
2317 std::string signal_name = signal_name_token.string;
2320 if (isdigit(signal_name[0]) || signal_name[0] ==
'\'')
2322 if (
auto res = get_binary_vector(signal_name_token); res.is_error())
2324 return ERR_APPEND(res.get_error(),
"could not parse assignment expression: unable to convert token to binary vector");
2328 result.push_back(std::move(res.get()));
2334 if (part_stream.consume(
"["))
2339 std::vector<std::vector<u32>> ranges;
2342 TokenStream<std::string> range_str = part_stream.extract_until(
"]");
2343 ranges.emplace_back(parse_range(range_str));
2344 part_stream.consume(
"]",
true);
2345 }
while (part_stream.consume(
"[",
false));
2347 result.push_back(ranged_identifier_t({std::move(signal_name), std::move(ranges)}));
2353 result.push_back(std::move(signal_name));
2361 std::vector<std::string> VerilogParser::expand_assignment_expression(VerilogModule* verilog_module,
const std::vector<assignment_t>& vars)
const
2363 std::vector<std::string> result;
2364 for (
const auto& var : vars)
2366 if (
const identifier_t* identifier = std::get_if<identifier_t>(&var); identifier !=
nullptr)
2368 std::vector<std::vector<u32>> ranges;
2370 if (
const auto signal_it = verilog_module->m_signals_by_name.find(*identifier); signal_it != verilog_module->m_signals_by_name.end())
2372 ranges = signal_it->second->m_ranges;
2374 else if (
const auto port_it = verilog_module->m_ports_by_expression.find(*identifier); port_it != verilog_module->m_ports_by_expression.end())
2376 ranges = port_it->second->m_ranges;
2379 std::vector<std::string> expanded = expand_ranges(*identifier, ranges);
2380 result.insert(result.end(), expanded.begin(), expanded.end());
2382 else if (
const ranged_identifier_t* ranged_identifier = std::get_if<ranged_identifier_t>(&var); ranged_identifier !=
nullptr)
2384 std::vector<std::string> expanded = expand_ranges(ranged_identifier->first, ranged_identifier->second);
2385 result.insert(result.end(), expanded.begin(), expanded.end());
2387 else if (
const numeral_t* numeral = std::get_if<numeral_t>(&var); numeral !=
nullptr)
2389 for (
auto value : *numeral)
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
void set_name(const std::string &name)
bool is_top_module() const
bool assign_gate(Gate *gate)
bool is_output_net(Net *net) const
std::string get_name() const
const std::unordered_set< Net * > & get_input_nets() const
void set_type(const std::string &type)
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)
const std::unordered_set< Net * > & get_output_nets() const
Endpoint * add_source(Gate *gate, const std::string &pin_name)
const std::string & get_name() const
u32 get_num_of_destinations(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Module * get_top_module() const
bool mark_vcc_gate(Gate *gate)
bool mark_gnd_gate(Gate *gate)
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 >())
bool delete_net(Net *net)
Net * create_net(const u32 net_id, const std::string &name)
const std::vector< Gate * > & get_gnd_gates() const
void set_design_name(const std::string &name)
void enable_automatic_net_checks(bool enable_checks=true)
const std::vector< Gate * > & get_vcc_gates() const
const std::vector< Module * > & get_modules() const
Gate * create_gate(const u32 gate_id, GateType *gate_type, const std::string &name="", i32 x=-1, i32 y=-1)
const std::vector< Net * > & get_nets() const
const GateLibrary * get_gate_library() const
Module * create_module(const u32 module_id, const std::string &name, Module *parent, const std::vector< Gate * > &gates={})
Token< T > consume_until(const T &expected, u32 end=END_OF_STREAM, bool level_aware=true, bool throw_on_error=false)
Token< T > consume_current_line()
Token< T > & peek(i32 offset=0)
u32 find_next(const T &match, u32 end=END_OF_STREAM, bool level_aware=true) const
Token< T > join_until(const T &match, const T &joiner, u32 end=END_OF_STREAM, bool level_aware=true, bool throw_on_error=false)
TokenStream< T > extract_until(const T &expected, u32 end=END_OF_STREAM, bool level_aware=true, bool throw_on_error=false)
Token< T > consume(u32 num=1)
Result< std::monostate > parse(const std::filesystem::path &file_path) override
Result< std::unique_ptr< Netlist > > instantiate(const GateLibrary *gate_library) override
#define log_warning(channel,...)
#define ERR_APPEND(prev_error, message)
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.
CORE_API T replace(const T &str, const T &search, const T &replace)
CORE_API bool is_digits(const T &s)
CORE_API std::string join(const std::string &joiner, const Iterator &begin, const Iterator &end, const Transform &transform)
CORE_API bool is_integer(const T &s)
CORE_API bool is_floating_point(const T &s)
CORE_API T to_upper(const T &s)
std::vector< PinInformation > pins
This file contains various functions to create and load netlists.