27 m_modules_by_name.clear();
31 ifs.open(file_path.string(), std::ifstream::in);
34 return ERR(
"could not parse Verilog file '" + m_path.string() +
"' : unable to open file");
46 if (
auto res = parse_tokens(); res.is_error())
48 return ERR_APPEND(res.get_error(),
"could not parse Verilog file '" + file_path.string() +
"': unable to parse tokens");
53 if (e.line_number != (
u32)-1)
55 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': " + e.message +
" (line " + std::to_string(e.line_number) +
")");
59 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': " + e.message);
63 if (m_modules.empty())
65 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': does not contain any modules");
69 for (
auto& [module_name, verilog_module] : m_modules_by_name)
72 for (
const auto& port : verilog_module->m_ports)
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)
78 const std::vector<std::string> expanded_expression = expand_assignment_expression(verilog_module, port->m_expression_parts);
79 if (expanded_expression.empty())
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 +
"'");
83 if (expanded_expression.size() == 1)
85 port->m_expanded_identifiers = {port->m_identifier};
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);
94 for (
u32 i = 0; i < expanded_expression.size(); i++)
96 verilog_module->m_expanded_port_identifiers_to_expressions[port->m_expanded_identifiers.at(i)] = expanded_expression.at(i);
99 else if (
const identifier_t& signal = std::get<identifier_t>(port->m_expression_parts.front()); signal != port->m_identifier)
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++)
106 verilog_module->m_expanded_port_identifiers_to_expressions[port->m_expanded_identifiers.at(i)] = expanded_expression.at(i);
111 port->m_expanded_identifiers = port->m_ranges.empty() ? std::vector<std::string>{port->m_identifier} : expand_ranges(port->m_identifier, port->m_ranges);
116 for (
auto& signal : verilog_module->m_signals)
118 if (!signal->m_ranges.empty())
120 signal->m_expanded_names = expand_ranges(signal->m_name, signal->m_ranges);
124 signal->m_expanded_names = std::vector<std::string>({signal->m_name});
129 for (
auto& assignment : verilog_module->m_assignments)
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())
135 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': unable to expand assignments within module '" + verilog_module->m_name +
"'");
138 u32 left_size = left_signals.size();
139 u32 right_size = right_signals.size();
140 if (left_size <= right_size)
143 for (
u32 i = 0; i < left_size; i++)
145 verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i), right_signals.at(i)));
150 for (
u32 i = 0; i < right_size; i++)
152 verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i), right_signals.at(i)));
156 for (
u32 i = 0; i < left_size - right_size; i++)
158 verilog_module->m_expanded_assignments.push_back(std::make_pair(left_signals.at(i + right_size),
"'0'"));
165 for (
auto& [module_name, verilog_module] : m_modules_by_name)
167 for (
auto&
instance : verilog_module->m_instances)
169 if (
auto module_it = m_modules_by_name.find(
instance->m_type); module_it != m_modules_by_name.end())
172 if (!
instance->m_port_assignments.empty())
175 if (
instance->m_port_assignments.front().m_port_name.has_value())
177 for (
const auto& port_assignment :
instance->m_port_assignments)
179 const std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
180 if (!right_port.empty())
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())
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 +
"'");
191 port = port_it->second;
193 const std::vector<std::string>& left_port = port->m_expanded_identifiers;
194 if (left_port.empty())
196 return ERR(
"could not parse Verilog file '" + m_path.string() +
"': unable to expand port assignment");
199 u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
201 for (
u32 i = 0; i < max_size; i++)
203 instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
211 std::vector<std::string> ports;
212 for (
const auto& port : m_modules_by_name.at(
instance->m_type)->m_ports)
214 ports.insert(ports.end(), port->m_expanded_identifiers.begin(), port->m_expanded_identifiers.end());
217 auto port_it = ports.begin();
219 for (
const auto& port_assignment :
instance->m_port_assignments)
221 std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
222 if (!right_port.empty())
224 std::vector<std::string> left_port;
226 for (
u32 i = 0; i < right_port.size() && port_it != ports.end(); i++)
228 left_port.push_back(*port_it++);
231 u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
233 for (
u32 i = 0; i < max_size; i++)
235 instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
252 m_netlist = result.get();
253 if (m_netlist ==
nullptr)
255 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': failed to create empty netlist");
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)
270 for (
const auto&
instance : verilog_module->m_instances)
274 instance->m_expanded_port_assignments.clear();
286 if (m_zero_net ==
nullptr)
288 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': failed to create zero net");
290 m_net_by_name[m_zero_net->
get_name()] = m_zero_net;
293 if (m_one_net ==
nullptr)
295 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': failed to create one net");
297 m_net_by_name[m_one_net->
get_name()] = m_one_net;
300 std::vector<std::string> marked_top_modules;
301 for (
const auto& [
name,
module] : m_modules_by_name)
303 for (
const VerilogDataEntry& attribute :
module->m_attributes)
305 if (attribute.m_name ==
"top" &&
utils::trim(attribute.m_value) ==
"1")
307 marked_top_modules.push_back(
name);
312 if (marked_top_modules.size() > 1)
314 return ERR(
"could not instantiate Verilog netlist '" + m_path.string() +
"' with gate library '" + gate_library->
get_name() +
"': several modules carry the top attribute: "
318 std::map<std::string, u32> module_name_to_refereneces;
319 for (
const auto& [_name,
module] : m_modules_by_name)
323 if (
const auto it = m_modules_by_name.find(
instance->m_type); it != m_modules_by_name.end())
325 module_name_to_refereneces[it->first]++;
330 std::vector<std::string> top_module_candidates = marked_top_modules;
331 if (top_module_candidates.empty())
333 for (
const auto& [
name,
module] : m_modules_by_name)
335 if (module_name_to_refereneces.find(
name) == module_name_to_refereneces.end())
337 top_module_candidates.push_back(
name);
342 if (top_module_candidates.empty())
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");
347 if (top_module_candidates.size() > 1)
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));
354 VerilogModule* top_module = m_modules_by_name.at(top_module_candidates.front());
356 if (
const auto res = construct_netlist(top_module); res.is_error())
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");
362 std::queue<Net*> nets_to_be_deleted;
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)
372 nets_to_be_deleted.push(
net);
376 while (!nets_to_be_deleted.empty())
378 Net*
net = nets_to_be_deleted.front();
379 nets_to_be_deleted.pop();
385 return OK(std::move(result));
392 void VerilogParser::tokenize()
394 const std::string delimiters =
"`,()[]{}\\#*: ;=./";
395 std::string current_token;
400 bool in_string =
false;
401 bool escaped =
false;
402 bool in_comment =
false;
404 std::vector<Token<std::string>> parsed_tokens;
405 while (std::getline(m_fs, line))
415 if (c ==
'/' && prev_char ==
'*')
425 if (!in_string && c ==
'\\')
430 else if (escaped && std::isspace(c))
435 else if (!escaped && c ==
'"')
437 in_string = !in_string;
440 if (!in_comment && ((!std::isspace(c) && delimiters.find(c) == std::string::npos) || escaped || in_string))
447 if (!current_token.empty())
449 if (parsed_tokens.size() > 1 &&
utils::is_digits(parsed_tokens.at(parsed_tokens.size() - 2).string) && parsed_tokens.at(parsed_tokens.size() - 1) ==
"."
452 parsed_tokens.pop_back();
453 parsed_tokens.back() +=
"." + current_token;
457 parsed_tokens.emplace_back(line_number, current_token);
459 current_token.clear();
462 if (!parsed_tokens.empty())
465 if (c ==
'(' && parsed_tokens.back() ==
"#")
467 parsed_tokens.back() =
"#(";
470 else if (c ==
'*' && parsed_tokens.back() ==
"(")
472 parsed_tokens.back() =
"(*";
475 else if (c ==
')' && parsed_tokens.back() ==
"*")
477 parsed_tokens.back() =
"*)";
481 else if (c ==
'/' && parsed_tokens.back() ==
"/")
483 parsed_tokens.pop_back();
486 else if (c ==
'*' && parsed_tokens.back() ==
"/")
489 parsed_tokens.pop_back();
494 if (!std::isspace(c))
496 parsed_tokens.emplace_back(line_number, std::string(1, c));
500 if (!current_token.empty())
502 parsed_tokens.emplace_back(line_number, current_token);
503 current_token.clear();
507 m_token_stream = TokenStream(parsed_tokens, {
"(",
"["}, {
")",
"]"});
510 Result<std::monostate> VerilogParser::parse_tokens()
512 std::vector<VerilogDataEntry> attributes;
517 if (m_token_stream.
peek() ==
"(*")
519 parse_attribute(attributes);
521 else if (m_token_stream.
peek() ==
"`")
524 log_warning(
"verilog_parser",
"could not parse compiler directives.");
528 line_number = m_token_stream.
peek().number;
529 if (
auto res = parse_module(attributes); res.is_error())
531 return ERR_APPEND(res.get_error(),
"could not parse tokens: unable to parse module (line " + std::to_string(line_number) +
")");
539 Result<std::monostate> VerilogParser::parse_module(std::vector<VerilogDataEntry>& attributes)
541 std::set<std::string> port_names;
542 std::vector<VerilogDataEntry> internal_attributes;
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();
549 if (
const auto it = m_modules_by_name.find(module_name); it != m_modules_by_name.end())
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) +
")");
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;
561 if (m_token_stream.
consume(
"#("))
565 m_token_stream.
consume(
")",
true);
566 log_warning(
"verilog_parser",
"could not parse parameter list provided for module '{}'.", module_name);
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")
574 if (
auto res = parse_port_declaration_list(verilog_module_raw); res.is_error())
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) +
")");
581 if (
auto res = parse_port_list(verilog_module_raw); res.is_error())
583 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"' (line " + std::to_string(line_number) +
"): unable to parse port list");
587 m_token_stream.
consume(
";",
true);
589 next_token = m_token_stream.
peek();
590 while (next_token !=
"endmodule")
592 if (next_token ==
"input" || next_token ==
"output" || next_token ==
"inout")
594 if (
auto res = parse_port_definition(verilog_module_raw, internal_attributes); res.is_error())
596 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse port definition (line " + std::to_string(line_number) +
")");
599 else if (next_token ==
"wire" || next_token ==
"tri")
601 if (
auto res = parse_signal_definition(verilog_module_raw, internal_attributes); res.is_error())
603 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse signal definition (line " + std::to_string(line_number) +
")");
606 else if (next_token ==
"parameter")
610 m_token_stream.
consume(
";",
true);
611 log_warning(
"verilog_parser",
"could not parse parameter provided for module '{}'.", module_name);
613 else if (next_token ==
"assign")
615 if (
auto res = parse_assignment(verilog_module_raw); res.is_error())
617 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse assignment (line " + std::to_string(line_number) +
")");
620 else if (next_token ==
"defparam")
622 if (
auto res = parse_defparam(verilog_module_raw); res.is_error())
624 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse defparam (line " + std::to_string(line_number) +
")");
627 else if (next_token ==
"(*")
629 parse_attribute(internal_attributes);
633 if (
auto res = parse_instance(verilog_module_raw, internal_attributes); res.is_error())
635 return ERR_APPEND(res.get_error(),
"could not parse module '" + module_name +
"': unable to parse instance (line " + std::to_string(line_number) +
")");
639 next_token = m_token_stream.
peek();
642 m_token_stream.
consume(
"endmodule",
true);
645 if (!attributes.empty())
647 verilog_module->m_attributes.insert(verilog_module->m_attributes.end(), attributes.begin(), attributes.end());
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;
659 Result<std::monostate> VerilogParser::parse_port_list(VerilogModule* verilog_module)
661 TokenStream<std::string> ports_stream = m_token_stream.
extract_until(
")");
662 m_token_stream.
consume(
")",
true);
664 while (ports_stream.remaining() > 0)
666 Token<std::string> next_token = ports_stream.consume();
667 auto port = std::make_unique<VerilogPort>();
669 if (next_token ==
".")
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);
678 auto parts_res = parse_assignment_expression(std::move(expression_stream));
679 if (parts_res.is_error())
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) +
")");
683 port->m_expression_parts = parts_res.get();
687 port->m_identifier = next_token.string;
688 port->m_expression_parts = {identifier_t(next_token.string)};
692 for (
const auto& part : port->m_expression_parts)
696 verilog_module->m_ports_by_expression[*
identifier] = port.get();
698 else if (
const ranged_identifier_t* ranged = std::get_if<ranged_identifier_t>(&part); ranged !=
nullptr)
700 verilog_module->m_ports_by_expression[ranged->first] = port.get();
704 verilog_module->m_ports_by_identifier[port->m_identifier] = port.get();
705 verilog_module->m_ports.push_back(std::move(port));
707 ports_stream.consume(
",", ports_stream.remaining() > 0);
713 Result<std::monostate> VerilogParser::parse_port_declaration_list(VerilogModule* verilog_module)
715 TokenStream<std::string> ports_stream = m_token_stream.
extract_until(
")");
716 m_token_stream.
consume(
")",
true);
718 while (ports_stream.remaining() > 0)
721 const Token<std::string> direction_token = ports_stream.consume();
725 return ERR(
"could not parse port declaration list: invalid direction '" + direction_token.string +
"' (line " + std::to_string(direction_token.number) +
")");
729 std::vector<std::vector<u32>> ranges;
730 while (ports_stream.consume(
"["))
732 const std::vector<u32> range = parse_range(ports_stream);
733 ports_stream.consume(
"]",
true);
735 ranges.emplace_back(range);
741 const Token<std::string> next_token = ports_stream.peek();
742 if (next_token ==
"input" || next_token ==
"output" || next_token ==
"inout")
746 ports_stream.consume();
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)};
755 port->m_ranges = ranges;
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));
762 if (verilog_module->m_signals_by_name.find(port_expression) == verilog_module->m_signals_by_name.end())
764 auto signal = std::make_unique<VerilogSignal>();
765 signal->m_name = port_expression;
768 signal->m_ranges = ranges;
770 verilog_module->m_signals_by_name[port_expression] = signal.get();
771 verilog_module->m_signals.push_back(std::move(signal));
773 }
while (ports_stream.consume(
",", ports_stream.remaining() > 0));
779 Result<std::monostate> VerilogParser::parse_port_definition(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
782 const Token<std::string> direction_token = m_token_stream.
consume();
786 return ERR(
"could not parse port definition: invalid direction '" + direction_token.string +
"' (line " + std::to_string(direction_token.number) +
")");
790 std::vector<std::vector<u32>> ranges;
791 while (m_token_stream.
consume(
"["))
793 const std::vector<u32> range = parse_range(m_token_stream);
794 m_token_stream.
consume(
"]",
true);
796 ranges.emplace_back(range);
802 Token<std::string> port_expression_token = m_token_stream.
consume();
803 std::string port_expression = port_expression_token.string;
806 if (
const auto it = verilog_module->m_ports_by_expression.find(port_expression); it == verilog_module->m_ports_by_expression.end())
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) +
")");
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)
821 port->m_ranges = ranges;
825 if (
const auto signal_it = verilog_module->m_signals_by_name.find(port_expression); signal_it == verilog_module->m_signals_by_name.end())
827 auto signal = std::make_unique<VerilogSignal>();
828 signal->m_name = port_expression;
831 signal->m_ranges = ranges;
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));
839 auto* signal = signal_it->second;
840 signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
842 }
while (m_token_stream.
consume(
",",
false));
844 m_token_stream.
consume(
";",
true);
850 Result<std::monostate> VerilogParser::parse_signal_definition(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
853 u32 line_number = m_token_stream.
consume().number;
855 TokenStream<std::string> signal_stream = m_token_stream.
extract_until(
";");
856 m_token_stream.
consume(
";",
true);
859 std::vector<std::vector<u32>> ranges;
860 while (signal_stream.consume(
"["))
862 const std::vector<u32> range = parse_range(signal_stream);
863 signal_stream.consume(
"]",
true);
865 ranges.emplace_back(range);
871 Token<std::string> signal_name = signal_stream.consume();
872 if (signal_stream.remaining() > 0 && signal_stream.peek() ==
"=")
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())
879 return ERR_APPEND(res.get_error(),
"could not parse signal definition: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
883 assignment.m_assignment = res.get();
885 verilog_module->m_assignments.push_back(std::move(assignment));
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())
891 auto signal = std::make_unique<VerilogSignal>();
892 signal->m_name = signal_name.string;
895 signal->m_ranges = ranges;
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));
903 auto* signal = signal_it->second;
904 signal->m_attributes.insert(signal->m_attributes.end(), attributes.begin(), attributes.end());
907 }
while (signal_stream.consume(
",",
false));
914 Result<std::monostate> VerilogParser::parse_assignment(VerilogModule* verilog_module)
916 m_token_stream.
consume(
"assign",
true);
917 u32 line_number = m_token_stream.
peek().number;
918 VerilogAssignment assignment;
920 if (
auto res = parse_assignment_expression(m_token_stream.
extract_until(
"=")); res.is_error())
922 return ERR_APPEND(res.get_error(),
"could not parse assignment: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
926 assignment.m_variable = res.get();
928 m_token_stream.
consume(
"=",
true);
930 if (
auto res = parse_assignment_expression(m_token_stream.
extract_until(
";")); res.is_error())
932 return ERR_APPEND(res.get_error(),
"could not parse assignment: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
936 assignment.m_assignment = res.get();
940 for (
const auto& var : assignment.m_variable)
944 if (verilog_module->m_signals_by_name.find(*
identifier) == verilog_module->m_signals_by_name.end())
946 auto signal = std::make_unique<VerilogSignal>();
948 verilog_module->m_signals_by_name[*
identifier] = signal.get();
949 verilog_module->m_signals.push_back(std::move(signal));
952 else if (
const auto* ranged_identifier = std::get_if<ranged_identifier_t>(&var); ranged_identifier !=
nullptr)
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())
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));
965 m_token_stream.
consume(
";",
true);
967 verilog_module->m_assignments.push_back(std::move(assignment));
971 Result<std::monostate> VerilogParser::parse_defparam(VerilogModule*
module)
973 m_token_stream.
consume(
"defparam",
true);
974 std::string instance_name = m_token_stream.
consume().string;
975 m_token_stream.
consume(
".",
true);
977 if (
const auto inst_it =
module->m_instances_by_name.find(instance_name); inst_it !=
module->m_instances_by_name.end())
979 VerilogDataEntry param;
980 param.m_name = m_token_stream.
consume().string;
981 m_token_stream.
consume(
"=",
true);
983 if (
const auto res = parse_parameter_value(m_token_stream.
consume()); res.is_ok())
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);
992 log_warning(
"verilog_parser",
"{}", res.get_error().get());
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 +
"'");
1001 m_token_stream.
consume(
";",
true);
1005 void VerilogParser::parse_attribute(std::vector<VerilogDataEntry>& attributes)
1007 m_token_stream.
consume(
"(*",
true);
1012 VerilogDataEntry attribute;
1013 attribute.m_name = m_token_stream.
consume().string;
1016 if (m_token_stream.
consume(
"="))
1018 attribute.m_value = m_token_stream.
consume();
1021 if (attribute.m_value[0] ==
'\"' && attribute.m_value.back() ==
'\"')
1023 attribute.m_value = attribute.m_value.substr(1, attribute.m_value.size() - 2);
1027 attributes.push_back(std::move(attribute));
1029 }
while (m_token_stream.
consume(
",",
false));
1031 m_token_stream.
consume(
"*)",
true);
1034 Result<std::monostate> VerilogParser::parse_instance(VerilogModule* verilog_module, std::vector<VerilogDataEntry>& attributes)
1036 auto instance = std::make_unique<VerilogInstance>();
1037 u32 line_number = m_token_stream.
peek().number;
1041 if (m_token_stream.
consume(
"#("))
1043 if (
auto res = parse_parameter_assign(); res.is_error())
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) +
")");
1049 instance->m_parameters = res.get();
1057 if (
auto res = parse_port_assign(
instance.get()); res.is_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) +
")");
1064 instance->m_attributes = attributes;
1068 verilog_module->m_instances.push_back(std::move(
instance));
1073 Result<std::monostate> VerilogParser::parse_port_assign(VerilogInstance*
instance)
1075 u32 line_number = m_token_stream.
peek().number;
1076 m_token_stream.
consume(
"(",
true);
1078 if (m_token_stream.
peek() ==
".")
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())
1088 return ERR_APPEND(res.get_error(),
"could not parse port assignment: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
1092 port_assignment.m_assignment = res.get();
1094 m_token_stream.
consume(
")",
true);
1095 if (port_assignment.m_assignment.empty())
1099 instance->m_port_assignments.push_back(std::move(port_assignment));
1100 }
while (m_token_stream.
consume(
",",
false));
1106 VerilogPortAssignment port_assignment;
1107 if (
auto res = parse_assignment_expression(m_token_stream.
extract_until(
",", line_end - 1)); res.is_error())
1109 return ERR_APPEND(res.get_error(),
"could not parse port assignment: unable to parse assignment expression (line " + std::to_string(line_number) +
")");
1113 port_assignment.m_assignment = res.get();
1115 if (port_assignment.m_assignment.empty())
1119 instance->m_port_assignments.push_back(std::move(port_assignment));
1120 }
while (m_token_stream.
consume(
",",
false));
1123 m_token_stream.
consume(
")",
true);
1124 m_token_stream.
consume(
";",
true);
1129 Result<std::vector<VerilogParser::VerilogDataEntry>> VerilogParser::parse_parameter_assign()
1131 std::vector<VerilogDataEntry> generics;
1135 if (m_token_stream.
consume(
".",
false))
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);
1142 if (
const auto res = parse_parameter_value(rhs); res.is_ok())
1144 const auto value = res.get();
1145 generics.push_back(VerilogDataEntry({lhs.string, value.first, value.second}));
1149 log_warning(
"verilog_parser",
"{}", res.get_error().get());
1152 }
while (m_token_stream.
consume(
",",
false));
1154 m_token_stream.
consume(
")",
true);
1156 return OK(generics);
1163 Result<std::monostate> VerilogParser::construct_netlist(VerilogModule* top_module)
1169 std::queue<VerilogModule*> q;
1174 VerilogModule*
module = q.front();
1177 m_module_instantiation_count[
module->m_name]++;
1180 for (
const auto& s :
module->m_signals)
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)
1186 m_net_name_occurences[net_name]++;
1192 m_instance_name_occurences[
instance->m_name]++;
1195 if (
const auto it = m_modules_by_name.find(
instance->m_type); it != m_modules_by_name.end())
1202 for (
auto& [module_name, verilog_module] : m_modules_by_name)
1205 if (m_module_instantiation_count[module_name] == 0)
1207 log_warning(
"verilog_parser",
"module '{}' has been defined in the netlist but is not instantiated.", module_name);
1212 for (
const auto&
instance : verilog_module->m_instances)
1214 if (
const auto gate_type_it = m_gate_types.find(
instance->m_type); gate_type_it != m_gate_types.end())
1216 if (!
instance->m_port_assignments.empty())
1219 if (
instance->m_port_assignments.front().m_port_name.has_value())
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())
1225 const auto pins = pin_group->get_pins();
1226 for (
auto it =
pins.rbegin(); it !=
pins.rend(); it++)
1228 const auto* pin = *it;
1229 pin_groups[pin_group->get_name()].push_back(pin->get_name());
1233 for (
const auto& port_assignment :
instance->m_port_assignments)
1235 std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
1236 if (!right_port.empty())
1238 std::vector<std::string> left_port;
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())
1243 left_port = group_it->second;
1247 left_port.push_back(port_name);
1250 u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
1252 for (
u32 i = 0; i < max_size; i++)
1254 instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
1263 std::vector<std::string>
pins = gate_type_it->second->get_pin_names();
1264 auto pin_it =
pins.begin();
1266 for (
const auto& port_assignment :
instance->m_port_assignments)
1268 std::vector<std::string> right_port = expand_assignment_expression(verilog_module, port_assignment.m_assignment);
1269 if (!right_port.empty())
1271 std::vector<std::string> left_port;
1273 for (
u32 i = 0; i < right_port.size() && pin_it !=
pins.end(); i++)
1275 left_port.push_back(*pin_it++);
1278 u32 max_size = right_port.size() <= left_port.size() ? right_port.size() : left_port.size();
1280 for (
u32 i = 0; i < max_size; i++)
1282 instance->m_expanded_port_assignments.push_back(std::make_pair(left_port.at(i), right_port.at(i)));
1293 std::unordered_map<std::string, std::string> top_assignments;
1294 for (
const auto& port : top_module->m_ports)
1296 for (
const auto& expanded_port_identifier : port->m_expanded_identifiers)
1298 const auto signal_name = get_unique_alias(
"", expanded_port_identifier +
"__GLOBAL_IO__", m_net_name_occurences);
1299 m_net_name_occurences[signal_name]++;
1302 if (global_port_net ==
nullptr)
1304 return ERR(
"could not construct netlist: failed to create global I/O net '" + signal_name +
"'");
1307 m_net_by_name[signal_name] = global_port_net;
1310 top_assignments[expanded_port_identifier] = signal_name;
1314 if (!global_port_net->mark_global_input_net())
1316 return ERR(
"could not construct netlist: failed to mark global I/O net '" + signal_name +
"' as global input");
1322 if (!global_port_net->mark_global_output_net())
1324 return ERR(
"could not construct netlist: failed to mark global I/O net '" + signal_name +
"' as global output");
1330 if (
auto res = instantiate_module(
"top_module", top_module,
nullptr, top_assignments); res.is_error())
1332 return ERR_APPEND(res.get_error(),
"could not construct netlist: unable to instantiate top module");
1336 std::unordered_map<std::string, std::string> merged_nets;
1337 std::unordered_map<std::string, std::vector<std::string>> master_to_slaves;
1339 for (
auto& [master, slave] : m_nets_to_merge)
1344 if (
const auto master_it = merged_nets.find(master); master_it != merged_nets.end())
1346 master = master_it->second;
1357 if (
const auto slave_it = merged_nets.find(slave); slave_it != merged_nets.end())
1359 slave = slave_it->second;
1367 auto master_net = m_net_by_name.at(master);
1368 auto slave_net = m_net_by_name.at(slave);
1370 if (master_net == slave_net)
1374 else if (slave_net == m_zero_net || slave_net == m_one_net)
1376 auto* tmp_net = master_net;
1377 master_net = slave_net;
1378 slave_net = tmp_net;
1380 auto tmp_name = master;
1386 if (slave_net->is_global_input_net())
1388 master_net->mark_global_input_net();
1391 for (
auto src : slave_net->get_sources())
1393 Gate* src_gate = src->get_gate();
1394 GatePin* src_pin = src->get_pin();
1396 if (!slave_net->remove_source(src))
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()));
1401 if (!master_net->is_a_source(src_gate, src_pin))
1403 if (!master_net->add_source(src_gate, src_pin))
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()));
1411 if (slave_net->is_global_output_net())
1413 master_net->mark_global_output_net();
1416 for (
auto dst : slave_net->get_destinations())
1418 Gate* dst_gate = dst->get_gate();
1419 GatePin* dst_pin = dst->get_pin();
1421 if (!slave_net->remove_destination(dst))
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()));
1426 if (!master_net->is_a_destination(dst_gate, dst_pin))
1428 if (!master_net->add_destination(dst_gate, dst_pin))
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()));
1436 for (
const auto& [
identifier, content] : slave_net->get_data_map())
1438 if (!master_net->set_data(std::get<0>(
identifier), std::get<1>(
identifier), std::get<0>(content), std::get<1>(content)))
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());
1450 if (
const auto it = m_module_port_by_net.find(slave_net); it != m_module_port_by_net.end())
1454 std::get<1>(m_module_ports.at(
module).at(
index)) = master_net;
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);
1461 m_net_by_name.erase(slave);
1462 merged_nets[slave] = master;
1463 master_to_slaves[master].push_back(slave);
1467 for (
auto& master_net : m_netlist->
get_nets())
1469 const auto master_name = master_net->get_name();
1471 if (
const auto m2s_it = master_to_slaves.find(master_name); m2s_it != master_to_slaves.end())
1473 std::vector<std::vector<std::string>> merged_slaves;
1474 auto current_slaves = m2s_it->second;
1476 while (!current_slaves.empty())
1478 std::vector<std::string> next_slaves;
1479 for (
const auto& s : current_slaves)
1481 if (
const auto m2s_inner_it = master_to_slaves.find(s); m2s_inner_it != master_to_slaves.end())
1483 next_slaves.insert(next_slaves.end(), m2s_inner_it->second.begin(), m2s_inner_it->second.end());
1487 merged_slaves.push_back(current_slaves);
1488 current_slaves = next_slaves;
1489 next_slaves.clear();
1494 std::string merged_str =
"";
1495 bool has_merged_nets =
false;
1496 for (
const auto& vec : merged_slaves)
1500 has_merged_nets =
true;
1502 const auto s =
utils::join(
", ", vec, [](
const auto e) {
return '"' + e +
'"'; });
1503 merged_str +=
"[" + s +
"], ";
1505 merged_str = merged_str.substr(0, merged_str.size() - 2);
1507 if (has_merged_nets)
1509 master_net->set_data(
"parser_annotation",
"merged_nets",
"string",
"[" + merged_str +
"]");
1519 GateType* gnd_type = m_gnd_gate_types.begin()->second;
1520 GatePin* output_pin = gnd_type->get_output_pins().front();
1525 return ERR(
"failed to mark GND gate");
1528 if (m_zero_net->
add_source(gnd, output_pin) ==
nullptr)
1530 return ERR(
"failed to add source to GND gate");
1536 m_zero_net =
nullptr;
1545 GateType* vcc_type = m_vcc_gate_types.begin()->second;
1546 GatePin* output_pin = vcc_type->get_output_pins().front();
1551 return ERR(
"failed to mark VCC gate");
1554 if (m_one_net->
add_source(vcc, output_pin) ==
nullptr)
1556 return ERR(
"failed to add source to VCC gate");
1562 m_one_net =
nullptr;
1573 for (
const auto& [
module, ports] : m_module_ports)
1578 for (
const auto& [port_name, port_net] : ports)
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())
1598 Result<Module*> VerilogParser::instantiate_module(
const std::string& instance_identifier,
1599 VerilogModule* verilog_module,
1601 const std::unordered_map<std::string, std::string>& parent_module_assignments)
1603 std::unordered_map<std::string, std::string> signal_alias;
1604 std::unordered_map<std::string, std::string> instance_alias;
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);
1613 if (parent ==
nullptr)
1623 std::string instance_type = verilog_module->m_name;
1626 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to create module");
1631 for (
const VerilogDataEntry& attribute : verilog_module->m_attributes)
1633 if (!
module->
set_data(
"attribute", attribute.m_name, attribute.m_type, attribute.m_value))
1636 "could not set attribute '{} = {}' of type '{}' for instance '{}' type '{}'.",
1640 instance_identifier,
1646 for (
const auto& port : verilog_module->m_ports)
1648 for (
const auto& expanded_port_identifier : port->m_expanded_identifiers)
1650 if (
const auto it = parent_module_assignments.find(expanded_port_identifier); it != parent_module_assignments.end())
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));
1660 for (
const auto& signal : verilog_module->m_signals)
1662 for (
const auto& expanded_name : signal->m_expanded_names)
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)
1667 m_net_name_occurences[unique_net_name]++;
1669 signal_alias[expanded_name] = unique_net_name;
1672 Net* signal_net = m_netlist->
create_net(signal_alias.at(expanded_name));
1673 if (signal_net ==
nullptr)
1675 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to create net '" + expanded_name +
"'");
1678 m_net_by_name[signal_alias.at(expanded_name)] = signal_net;
1681 for (
const VerilogDataEntry& attribute : signal->m_attributes)
1683 if (!signal_net->set_data(
"attribute", attribute.m_name,
"unknown", attribute.m_value))
1686 "could not set attribute ({} = {}) for net '{}' of instance '{}' of type '{}'.",
1690 instance_identifier,
1698 for (
const auto& [left_expanded_signal, right_expanded_signal] : verilog_module->m_expanded_assignments)
1700 std::string a = left_expanded_signal;
1701 std::string b = right_expanded_signal;
1703 if (
const auto alias_it = signal_alias.find(a); alias_it != signal_alias.end())
1705 a = alias_it->second;
1709 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to find alias for net '" + a +
"'");
1712 if (
const auto alias_it = signal_alias.find(b); alias_it != signal_alias.end())
1714 b = alias_it->second;
1716 else if (b ==
"'Z'" || b ==
"'X'")
1720 else if (b !=
"'0'" && b !=
"'1'")
1722 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to find alias for net '" + b +
"'");
1725 m_nets_to_merge.push_back(std::make_pair(a, b));
1729 for (
const auto& [port_identifier, net_name] : parent_module_assignments)
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())
1734 signal_name = port_identifier;
1738 signal_name = expr_it->second;
1742 if (
const auto alias_it = signal_alias.find(signal_name); alias_it != signal_alias.end())
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));
1749 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to find alias for net '" + signal_name +
"'");
1754 for (
const auto&
instance : verilog_module->m_instances)
1757 DataContainer* container =
nullptr;
1760 std::unordered_map<std::string, std::string> instance_assignments;
1763 if (
auto module_it = m_modules_by_name.find(
instance->m_type); module_it != m_modules_by_name.end())
1766 for (
const auto& [port, assignment] :
instance->m_expanded_port_assignments)
1768 if (
const auto alias_it = signal_alias.find(assignment); alias_it != signal_alias.end())
1770 instance_assignments[port] = alias_it->second;
1772 else if (assignment ==
"'0'" || assignment ==
"'1'")
1774 instance_assignments[port] = assignment;
1776 else if (assignment ==
"'Z'" || assignment ==
"'X'" || assignment.empty())
1782 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': port assignment '" + port +
" = " + assignment +
"' is invalid");
1786 if (
auto res = instantiate_module(
instance->m_name, module_it->second,
module, instance_assignments); res.is_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 +
"'");
1794 container = res.get();
1798 else if (
const auto gate_type_it = m_gate_types.find(
instance->m_type); gate_type_it != m_gate_types.end())
1803 if (new_gate ==
nullptr)
1805 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to create gate '" +
instance->m_name +
"'");
1813 container = new_gate;
1816 if (m_vcc_gate_types.find(
instance->m_type) != m_vcc_gate_types.end() && !new_gate->mark_vcc_gate())
1818 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to mark '" +
instance->m_name +
"' of type '" +
instance->m_type
1821 if (m_gnd_gate_types.find(
instance->m_type) != m_gnd_gate_types.end() && !new_gate->mark_gnd_gate())
1823 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to mark '" +
instance->m_name +
"' of type '" +
instance->m_type
1828 std::unordered_map<std::string, GatePin*> pin_names_map;
1829 for (
auto* pin : gate_type_it->second->get_pins())
1831 pin_names_map[pin->get_name()] = pin;
1835 for (
const auto& [pin, assignment] :
instance->m_expanded_port_assignments)
1839 if (
const auto alias_it = signal_alias.find(assignment); alias_it != signal_alias.end())
1841 signal = alias_it->second;
1843 else if (assignment ==
"'0'" || assignment ==
"'1'")
1845 signal = assignment;
1847 else if (assignment ==
"'Z'" || assignment ==
"'X'")
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");
1858 if (
const auto net_it = m_net_by_name.find(signal); net_it == m_net_by_name.end())
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");
1865 Net* current_net = net_it->second;
1868 bool is_input =
false;
1869 bool is_output =
false;
1871 if (
const auto it = pin_names_map.find(pin); it != pin_names_map.end())
1885 if (!is_input && !is_output)
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() +
"'");
1891 if (is_output && !current_net->add_source(new_gate, pin))
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 +
"'");
1897 if (is_input && !current_net->add_destination(new_gate, pin))
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 +
"'");
1907 return ERR(
"could not create instance '" + instance_identifier +
"' of type '" + instance_type +
"': failed to find gate type '" +
instance->m_type +
"' in gate library '"
1912 for (
const auto& attribute :
instance->m_attributes)
1914 if (!container->set_data(
"attribute", attribute.m_name, attribute.m_type, attribute.m_value))
1917 "could not set attribute '{} = {}' of type '{}' for instance '{}' of type '{}' within instance '{}' of type '{}'.",
1923 instance_identifier,
1929 for (
const auto& parameter :
instance->m_parameters)
1931 if (!container->set_data(
"generic", parameter.m_name, parameter.m_type, parameter.m_value))
1934 "could not set generic '{} = {}' of type '{}' for instance '{}' of type '{}' within instance '{}' of type '{}'.",
1940 instance_identifier,
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}};
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}}};
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}}};
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
1995 std::string unique_alias =
name;
1997 if (!parent_name.empty())
2001 auto instance_name_it = name_occurences.find(
name);
2007 while (instance_name_it != name_occurences.end() && (cnt || instance_name_it->second > 1))
2009 std::string extension;
2012 extension =
"_u" + std::to_string(cnt);
2014 unique_alias = parent_name + instance_name_seperator + unique_alias + extension;
2015 instance_name_it = name_occurences.find(unique_alias);
2019 return unique_alias;
2022 std::vector<u32> VerilogParser::parse_range(TokenStream<std::string>& stream)
const
2024 if (stream.remaining() == 1)
2026 return {(
u32)std::stoi(stream.consume().string)};
2030 const int end = std::stoi(stream.consume().string);
2031 stream.consume(
":",
true);
2032 const int start = std::stoi(stream.consume().string);
2034 const int direction = (start <= end) ? 1 : -1;
2036 std::vector<u32> result;
2039 result.push_back((
u32)i);
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
2047 if (ranges.size() > dimension)
2049 for (
const u32 index : ranges[dimension])
2051 expand_ranges_recursively(expanded_names, current_name +
"(" + std::to_string(
index) +
")", ranges, dimension + 1);
2057 expanded_names.push_back(current_name);
2061 std::vector<std::string> VerilogParser::expand_ranges(
const std::string&
name,
const std::vector<std::vector<u32>>& ranges)
const
2063 std::vector<std::string> res;
2065 expand_ranges_recursively(res,
name, ranges, 0);
2070 Result<std::vector<BooleanFunction::Value>> VerilogParser::get_binary_vector(std::string value)
const
2077 std::vector<BooleanFunction::Value> result;
2080 if (value.find(
'\'') == std::string::npos)
2087 if (value.at(0) !=
'\'')
2089 len = std::stoi(value.substr(0, value.find(
'\'')));
2091 prefix = value.substr(value.find(
'\'') + 1, 1);
2092 number = value.substr(value.find(
'\'') + 2);
2096 switch (prefix.at(0))
2099 for (
auto it = number.rbegin(); it != number.rend(); it++)
2102 if (c ==
'0' || c ==
'1' || c ==
'Z' || c ==
'X')
2104 result.push_back(bin_map.at(c));
2108 return ERR(
"could not convert string to binary vector: invalid character within binary number literal '" + value +
"'");
2115 for (
auto it = number.rbegin(); it != number.rend(); it++)
2118 if ((c >=
'0' && c <=
'7') || c ==
'X' || c ==
'Z')
2120 const auto& bits = oct_map.at(c);
2121 result.insert(result.end(), bits.begin(), bits.end());
2125 return ERR(
"could not convert string to binary vector: invalid character within octal number literal '" + value +
"'");
2133 for (
const char c : number)
2135 if ((c >=
'0' && c <=
'9'))
2137 tmp_val = (tmp_val * 10) + (c -
'0');
2141 return ERR(
"could not convert string to binary vector: invalid character within decimal number literal '" + value +
"'");
2147 result.push_back(((tmp_val & 1) == 1) ? BooleanFunction::Value::ONE : BooleanFunction::Value::ZERO);
2149 }
while (tmp_val != 0);
2154 for (
auto it = number.rbegin(); it != number.rend(); it++)
2157 if ((c >=
'0' && c <=
'9') || (c >=
'A' && c <=
'F') || c ==
'X' || c ==
'Z')
2159 const auto& bits = hex_map.at(c);
2160 result.insert(result.end(), bits.begin(), bits.end());
2164 return ERR(
"could not convert string to binary vector: invalid character within hexadecimal number literal '" + value +
"'");
2171 return ERR(
"could not convert string to binary vector: invalid base '" + prefix +
"' within number literal '" + value +
"'");
2177 i32 result_size = result.size();
2179 if (len > result_size)
2182 for (
i32 i = 0; i < (len - result_size); i++)
2184 result.push_back(BooleanFunction::Value::ZERO);
2190 for (
i32 i = 0; i < (result_size - len); i++)
2200 Result<std::string> VerilogParser::get_hex_from_literal(
const Token<std::string>& value_token)
const
2202 const u32 line_number = value_token.number;
2211 if (value.find(
'\'') == std::string::npos)
2218 if (value.at(0) !=
'\'')
2220 len = std::stoi(value.substr(0, value.find(
'\'')));
2222 prefix = value.substr(value.find(
'\'') + 1, 1);
2223 number = value.substr(value.find(
'\'') + 2);
2227 switch (prefix.at(0))
2230 if (!std::all_of(number.begin(), number.end(), [](
const char& c) { return (c >=
'0' && c <=
'1'); }))
2232 return ERR(
"could not convert token to hexadecimal string: invalid character within binary number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2240 if (!std::all_of(number.begin(), number.end(), [](
const char& c) { return (c >=
'0' && c <=
'7'); }))
2242 return ERR(
"could not convert token to hexadecimal string: invalid character within ocatl number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2250 if (!std::all_of(number.begin(), number.end(), [](
const char& c) { return (c >=
'0' && c <=
'9'); }))
2252 return ERR(
"could not convert token to hexadecimal string: invalid character within decimal number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2262 for (
const char c : number)
2264 if ((c >=
'0' && c <=
'9') || (c >=
'A' && c <=
'F'))
2270 return ERR(
"could not convert token to hexadecimal string: invalid character within hexadecimal number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2278 return ERR(
"could not convert token to hexadecimal string: invalid base '" + prefix +
"' within number literal '" + value +
"' (line " + std::to_string(line_number) +
")");
2282 std::stringstream ss;
2286 ss << std::uppercase << std::setfill(
'0') << std::setw((len + 3) / 4) << std::hex << stoull(number, 0, base);
2290 ss << std::uppercase << std::hex << stoull(number, 0, base);
2292 return OK(ss.str());
2295 Result<std::pair<std::string, std::string>> VerilogParser::parse_parameter_value(
const Token<std::string>& value_token)
const
2297 std::pair<std::string, std::string> value;
2301 value.first =
"integer";
2302 value.second = value_token.string;
2306 value.first =
"floating_point";
2307 value.second = value_token.string;
2309 else if (value_token.string[0] ==
'\"' && value_token.string.back() ==
'\"')
2311 value.first =
"string";
2312 value.second = value_token.string.substr(1, value_token.string.size() - 2);
2314 else if (isdigit(value_token.string[0]) || value_token.string[0] ==
'\'')
2316 if (
const auto res = get_hex_from_literal(value_token); res.is_error())
2319 "could not parse parameter value: failed to convert '" + value_token.string +
"' to hexadecimal value (line " + std::to_string(value_token.number) +
")");
2323 value.second = res.get();
2326 if (value.second ==
"0" || value.second ==
"1")
2328 value.first =
"bit_value";
2332 value.first =
"bit_vector";
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) +
")");
2343 Result<std::vector<VerilogParser::assignment_t>> VerilogParser::parse_assignment_expression(TokenStream<std::string>&& stream)
const
2345 std::vector<TokenStream<std::string>> parts;
2347 if (stream.size() == 0)
2352 if (stream.peek() ==
"{")
2354 stream.consume(
"{",
true);
2356 TokenStream<std::string> assignment_list_str = stream.extract_until(
"}");
2357 stream.consume(
"}",
true);
2361 parts.push_back(assignment_list_str.extract_until(
","));
2362 }
while (assignment_list_str.consume(
",",
false));
2366 parts.push_back(stream);
2369 std::vector<assignment_t> result;
2370 result.reserve(parts.size());
2372 for (
auto it = parts.rbegin(); it != parts.rend(); it++)
2374 TokenStream<std::string>& part_stream = *it;
2376 const Token<std::string> signal_name_token = part_stream.consume();
2377 std::string signal_name = signal_name_token.string;
2380 if (isdigit(signal_name[0]) || signal_name[0] ==
'\'')
2382 if (
auto res = get_binary_vector(signal_name_token); res.is_error())
2384 return ERR_APPEND(res.get_error(),
"could not parse assignment expression: unable to convert token to binary vector");
2388 result.push_back(std::move(res.get()));
2394 if (part_stream.consume(
"["))
2399 std::vector<std::vector<u32>> ranges;
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));
2407 result.push_back(ranged_identifier_t({std::move(signal_name), std::move(ranges)}));
2413 result.push_back(std::move(signal_name));
2421 std::vector<std::string> VerilogParser::expand_assignment_expression(VerilogModule* verilog_module,
const std::vector<assignment_t>& vars)
const
2423 std::vector<std::string> result;
2424 for (
const auto& var : vars)
2428 std::vector<std::vector<u32>> ranges;
2430 if (
const auto signal_it = verilog_module->m_signals_by_name.find(*
identifier); signal_it != verilog_module->m_signals_by_name.end())
2432 ranges = signal_it->second->m_ranges;
2434 else if (
const auto port_it = verilog_module->m_ports_by_expression.find(*
identifier); port_it != verilog_module->m_ports_by_expression.end())
2436 ranges = port_it->second->m_ranges;
2439 std::vector<std::string> expanded = expand_ranges(*
identifier, ranges);
2440 result.insert(result.end(), expanded.begin(), expanded.end());
2442 else if (
const ranged_identifier_t* ranged_identifier = std::get_if<ranged_identifier_t>(&var); ranged_identifier !=
nullptr)
2444 std::vector<std::string> expanded = expand_ranges(ranged_identifier->first, ranged_identifier->second);
2445 result.insert(result.end(), expanded.begin(), expanded.end());
2447 else if (
const numeral_t* numeral = std::get_if<numeral_t>(&var); numeral !=
nullptr)
2449 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.
T replace(const T &str, const T &search, const T &replace)
bool is_digits(const T &s)
std::string join(const std::string &joiner, const Iterator &begin, const Iterator &end, const Transform &transform)
bool is_floating_point(const T &s)
bool is_integer(const T &s)
T trim(const T &s, const char *to_remove=" \t\r\n")
std::vector< PinInformation > pins
This file contains various functions to create and load netlists.
std::unique_ptr< BasePluginInterface > instance