diff --git a/include/hal_core/netlist/decorators/netlist_abstraction_decorator.h b/include/hal_core/netlist/decorators/netlist_abstraction_decorator.h index 7eed81ea5af..d8c28ccbcf4 100644 --- a/include/hal_core/netlist/decorators/netlist_abstraction_decorator.h +++ b/include/hal_core/netlist/decorators/netlist_abstraction_decorator.h @@ -284,7 +284,7 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed = true, - bool continue_on_match = false, + const bool continue_on_match = false, const std::function& exit_endpoint_filter = nullptr, const std::function& entry_endpoint_filter = nullptr) const; @@ -307,10 +307,56 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed = true, - bool continue_on_match = false, + const bool continue_on_match = false, const std::function& exit_endpoint_filter = nullptr, const std::function& entry_endpoint_filter = nullptr) const; + /** + * @brief Starting from the given endpoint, traverse the netlist abstraction and return the successor/predecessor gates for which the `target_gate_filter` evaluates to `true`. + * Traverse over gates that do not meet the `target_gate_filter` condition. + * Stop traversal if (1) `continue_on_match` is `false` and the `target_gate_filter` evaluates to `true`, (2) the `exit_endpoint_filter` evaluates to `false` on a fan-in/out endpoint, or (3) the `entry_endpoint_filter` evaluates to `false` on a successor/predecessor endpoint. + * Both the `entry_endpoint_filter` and the `exit_endpoint_filter` may be omitted. + * + * @param[in] endpoint - The starting endpoint. + * @param[in] target_gate_filter - Filter condition that must be met for the target gates. + * @param[in] direction - The direction to search in (`PinDirection::input` or `PinDirection::output`). + * @param[in] directed - Defines whether we are searching on a directed or undirected graph represenation of the netlist. + * @param[in] continue_on_match - Set `true` to continue even if `target_gate_filter` evaluates to `true`, `false` otherwise. Defaults to `false`. + * @param[in] exit_endpoint_filter - Filter condition to stop traversal on a fan-in/out endpoint. + * @param[in] entry_endpoint_filter - Filter condition to stop traversal on a successor/predecessor endpoint. + * @returns OK() and a set of gates fulfilling the `target_gate_filter` condition on success, an error otherwise. + */ + Result>> get_next_matching_gates(const std::vector& endpoints, + const std::function& target_gate_filter, + const PinDirection& direction, + const bool directed = true, + const bool continue_on_match = false, + const std::function& exit_endpoint_filter = nullptr, + const std::function& entry_endpoint_filter = nullptr) const; + + /** + * @brief Starting from the given gate, traverse the netlist abstraction and return the successor/predecessor gates for which the `target_gate_filter` evaluates to `true`. + * Traverse over gates that do not meet the `target_gate_filter` condition. + * Stop traversal if (1) `continue_on_match` is `false` and the `target_gate_filter` evaluates to `true`, (2) the `exit_endpoint_filter` evaluates to `false` on a fan-in/out endpoint, or (3) the `entry_endpoint_filter` evaluates to `false` on a successor/predecessor endpoint. + * Both the `entry_endpoint_filter` and the `exit_endpoint_filter` may be omitted. + * + * @param[in] gate - The starting gate. + * @param[in] target_gate_filter - Filter condition that must be met for the target gates. + * @param[in] direction - The direction to search in (`PinDirection::input` or `PinDirection::output`). + * @param[in] directed - Defines whether we are searching on a directed or undirected graph represenation of the netlist. + * @param[in] continue_on_match - Set `true` to continue even if `target_gate_filter` evaluates to `true`, `false` otherwise. Defaults to `false`. + * @param[in] exit_endpoint_filter - Filter condition to stop traversal on a fan-in/out endpoint. + * @param[in] entry_endpoint_filter - Filter condition to stop traversal on a successor/predecessor endpoint. + * @returns OK() and a set of gates fulfilling the `target_gate_filter` condition on success, an error otherwise. + */ + Result>> get_next_matching_gates(const std::vector& gates, + const std::function& target_gate_filter, + const PinDirection& direction, + const bool directed = true, + const bool continue_on_match = false, + const std::function& exit_endpoint_filter = nullptr, + const std::function& entry_endpoint_filter = nullptr) const; + /** * @brief Starting from the given endpoint, traverse the netlist abstraction and return the successor/predecessor gates for which the `target_gate_filter` evaluates to `true`. * Continue traversal regardless of whether `target_gate_filter` evaluates to `true` or `false`. @@ -330,7 +376,7 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed = true, - bool continue_on_mismatch = false, + const bool continue_on_mismatch = false, const std::function& exit_endpoint_filter = nullptr, const std::function& entry_endpoint_filter = nullptr) const; @@ -353,7 +399,7 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed = true, - bool continue_on_mismatch = false, + const bool continue_on_mismatch = false, const std::function& exit_endpoint_filter = nullptr, const std::function& entry_endpoint_filter = nullptr) const; @@ -392,7 +438,28 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed = true, - bool continue_on_match = false, + const bool continue_on_match = false, + const std::function& exit_endpoint_filter = nullptr, + const std::function& entry_endpoint_filter = nullptr) const; + + /** + * @brief Internal method to traverse the netlist abstraction and return matching gates based on the provided filters. + * + * @param[in] start - The starting endpoints. + * @param[in] target_gate_filter - Filter condition that must be met for the target gates. + * @param[in] direction - The direction to search in. + * @param[in] directed - Defines whether we are searching on a directed or undirected graph represenation of the netlist. + * @param[in] continue_on_match - Determines whether to continue traversal after a match. + * @param[in] exit_endpoint_filter - Filter condition to stop traversal on a fan-in/out endpoint. + * @param[in] entry_endpoint_filter - Filter condition to stop traversal on a successor/predecessor endpoint. + * @returns OK() and a set of gates fulfilling the `target_gate_filter` condition on success, an error otherwise. + */ + Result> get_next_matching_gates_internal(const std::vector& start, + const std::function& target_gate_filter, + const PinDirection& direction, + std::map, std::set>& cache, + const bool directed = true, + const bool continue_on_match = false, const std::function& exit_endpoint_filter = nullptr, const std::function& entry_endpoint_filter = nullptr) const; @@ -412,7 +479,7 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed = true, - bool continue_on_mismatch = false, + const bool continue_on_mismatch = false, const std::function& exit_endpoint_filter = nullptr, const std::function& entry_endpoint_filter = nullptr) const; diff --git a/plugins/machine_learning/include/machine_learning/labels/gate_label.h b/plugins/machine_learning/include/machine_learning/labels/gate_label.h index 22763c95e40..1e31e1fd6cb 100644 --- a/plugins/machine_learning/include/machine_learning/labels/gate_label.h +++ b/plugins/machine_learning/include/machine_learning/labels/gate_label.h @@ -17,6 +17,7 @@ namespace hal /* Forward declarations */ class Gate; enum class GateTypeProperty : int; + enum class PinType : int; namespace machine_learning { @@ -82,6 +83,34 @@ namespace hal const std::string m_key_word; const std::vector m_applicable_to; }; + + /** + * @class NetNameKeyWord + * @brief Labels gate based on whether one of the net names at specified pins includes a keyword or not. + */ + class NetNameKeyWord : public GateLabel + { + public: + /** + * @brief Default constructor. + */ + NetNameKeyWord(const std::string& key_word, const std::vector& pin_types, const std::vector& applicable_to = {}) + : m_key_word(key_word), m_pin_types(pin_types), m_applicable_to(applicable_to){}; + + const std::vector MATCH = {1, 0, 0}; + const std::vector MISMATCH = {0, 1, 0}; + const std::vector NA = {0, 0, 1}; + + Result> calculate_label(Context& ctx, const Gate* g) const override; + Result>> calculate_labels(Context& ctx, const std::vector& gates) const override; + Result>> calculate_labels(Context& ctx) const override; + std::string to_string() const override; + + private: + const std::string m_key_word; + const std::vector m_pin_types; + const std::vector m_applicable_to; + }; } // namespace gate_label } // namespace machine_learning } // namespace hal \ No newline at end of file diff --git a/plugins/machine_learning/python/python_bindings.cpp b/plugins/machine_learning/python/python_bindings.cpp index 9910f6bc22d..e482b078788 100644 --- a/plugins/machine_learning/python/python_bindings.cpp +++ b/plugins/machine_learning/python/python_bindings.cpp @@ -139,7 +139,7 @@ Maps a (gate, word) pair to an index. py::class_ py_context(m, "Context", R"()"); - py_context.def(py::init(), + py_context.def(py::init(), py::arg("netlist"), py::arg("_num_threads") = 1, R"( @@ -2246,6 +2246,129 @@ Get the gates of the context. :rtype: str )"); + py::class_> py_net_name_key_word( + py_gate_label, "NetNameKeyWord", R"( +Labels gate based on whether one of the net names at specified pins includes a keyword or not. +)"); + + // Constructor: + // NetNameKeyWord(const std::string& key_word, const std::vector& pin_types, const std::vector& applicable_to = {}) + py_net_name_key_word.def(py::init&, const std::vector&>(), + py::arg("key_word"), + py::arg("pin_types"), + py::arg("applicable_to") = std::vector(), + R"( +Construct a new NetNameKeyWord labeler. + +:param str key_word: The keyword to search in the net names. +:param list[hal_py.PinType] pin_types: The pin types to check for the keyword. +:param list[hal_py.GateTypeProperty] applicable_to: The gate type properties to which this labeling applies. Defaults to an empty list. +)"); + + py_net_name_key_word.def_readonly("MATCH", &machine_learning::gate_label::NetNameKeyWord::MATCH, R"( + A label vector indicating a match. + + :type: list[int] + )"); + + py_net_name_key_word.def_readonly("MISMATCH", &machine_learning::gate_label::NetNameKeyWord::MISMATCH, R"( + A label vector indicating a mismatch. + + :type: list[int] + )"); + + py_net_name_key_word.def_readonly("NA", &machine_learning::gate_label::NetNameKeyWord::NA, R"( + A label vector indicating not applicable. + + :type: list[int] + )"); + + // NetNameKeyWord::calculate_label + py_net_name_key_word.def( + "calculate_label", + [](machine_learning::gate_label::NetNameKeyWord& self, machine_learning::Context& ctx, const Gate* g) -> std::optional> { + auto res = self.calculate_label(ctx, g); + if (res.is_ok()) + { + return res.get(); + } + else + { + log_error("python_context", "error encountered while calculating label:\n{}", res.get_error().get()); + return std::nullopt; + } + }, + py::arg("ctx"), + py::arg("g"), + R"( +Calculate labels for a given gate based on net names at specified pins containing the keyword. + +:param hal_py.Context ctx: The machine learning context. +:param hal_py.Gate g: The gate. +:returns: A list of labels on success, None otherwise. +:rtype: list[int] or None +)"); + + // NetNameKeyWord::calculate_labels(Context&, const std::vector&) + py_net_name_key_word.def( + "calculate_labels", + [](machine_learning::gate_label::NetNameKeyWord& self, machine_learning::Context& ctx, const std::vector& gates) -> std::optional>> { + auto res = self.calculate_labels(ctx, gates); + if (res.is_ok()) + { + return res.get(); + } + else + { + log_error("python_context", "error encountered while calculating labels for gates:\n{}", res.get_error().get()); + return std::nullopt; + } + }, + py::arg("ctx"), + py::arg("gates"), + R"( +Calculate labels for multiple gates based on net names at specified pins containing the keyword. + +:param hal_py.Context ctx: The machine learning context. +:param list[hal_py.Gate] gates: The gates to label. +:returns: A list of label vectors for each gate on success, None otherwise. +:rtype: list[list[int]] or None +)"); + + // NetNameKeyWord::calculate_labels(Context&) + py_net_name_key_word.def( + "calculate_labels", + [](machine_learning::gate_label::NetNameKeyWord& self, machine_learning::Context& ctx) -> std::optional>> { + auto res = self.calculate_labels(ctx); + if (res.is_ok()) + { + return res.get(); + } + else + { + log_error("python_context", "error encountered while calculating labels in context:\n{}", res.get_error().get()); + return std::nullopt; + } + }, + py::arg("ctx"), + R"( +Calculate labels within the labeling context based on net names at specified pins containing the keyword. + +:param hal_py.Context ctx: The machine learning context. +:returns: A list of label vectors on success, None otherwise. +:rtype: list[list[int]] or None +)"); + + // NetNameKeyWord::to_string() + py_net_name_key_word.def("to_string", + &machine_learning::gate_label::NetNameKeyWord::to_string, + R"( +Convert the NetNameKeyWord labeler to a string. + +:returns: The string representation. +:rtype: str +)"); + #ifndef PYBIND11_MODULE return m.ptr(); #endif // PYBIND11_MODULE diff --git a/plugins/machine_learning/src/features/gate_pair_feature.cpp b/plugins/machine_learning/src/features/gate_pair_feature.cpp index 2fa5f497b35..6a62696b93a 100644 --- a/plugins/machine_learning/src/features/gate_pair_feature.cpp +++ b/plugins/machine_learning/src/features/gate_pair_feature.cpp @@ -19,7 +19,14 @@ namespace hal { if (g_a == g_b) { - return OK({FEATURE_TYPE(0), FEATURE_TYPE(0)}); + if (m_direction != PinDirection::inout) + { + return OK({FEATURE_TYPE(0), FEATURE_TYPE(0)}); + } + else + { + return OK({FEATURE_TYPE(0)}); + } } const hal::Result nl_abstr = ctx.get_original_abstraction(); @@ -92,7 +99,14 @@ namespace hal { if (g_a == g_b) { - return OK({FEATURE_TYPE(0), FEATURE_TYPE(0)}); + if (m_direction != PinDirection::inout) + { + return OK({FEATURE_TYPE(0), FEATURE_TYPE(0)}); + } + else + { + return OK({FEATURE_TYPE(0)}); + } } const hal::Result nl_abstr = ctx.get_sequential_abstraction(); diff --git a/plugins/machine_learning/src/labels/gate_label.cpp b/plugins/machine_learning/src/labels/gate_label.cpp index 39183df1dc9..6074e112276 100644 --- a/plugins/machine_learning/src/labels/gate_label.cpp +++ b/plugins/machine_learning/src/labels/gate_label.cpp @@ -1,4 +1,5 @@ #include "hal_core/netlist/gate.h" +#include "hal_core/netlist/net.h" #include "machine_learning/labels/gate_label.h" namespace hal @@ -64,6 +65,72 @@ namespace hal return "GateNameKeyWord_" + m_key_word + "_" + (m_applicable_to.empty() ? "ALL" : applicable_to_str); } + Result> NetNameKeyWord::calculate_label(Context& ctx, const Gate* g) const + { + UNUSED(ctx); + + for (const auto& gtp : m_applicable_to) + { + if (g->get_type()->has_property(gtp)) + { + for (const auto& pt : m_pin_types) + { + const auto& pins = g->get_type()->get_pins([&pt](const auto& gt_p) { return gt_p->get_type() == pt; }); + for (const auto* p : pins) + { + const auto* ep = (p->get_direction() == PinDirection::input) ? g->get_fan_in_endpoint(p) : g->get_fan_out_endpoint(p); + const auto& net_name = ep->get_net()->get_name(); + if (net_name.find(m_key_word) != std::string::npos) + { + return OK(MATCH); + } + } + } + + return OK(MISMATCH); + } + } + + return OK(NA); + } + + Result>> NetNameKeyWord::calculate_labels(Context& ctx, const std::vector& gates) const + { + std::vector> labels; + + for (const auto& g : gates) + { + const auto new_label = calculate_label(ctx, g); + if (new_label.is_error()) + { + return ERR_APPEND(new_label.get_error(), "Cannot caluclate label for gate " + g->get_name() + " with ID " + std::to_string(g->get_id())); + } + + labels.push_back(new_label.get()); + } + + return OK(labels); + } + + Result>> NetNameKeyWord::calculate_labels(Context& ctx) const + { + const auto labels = calculate_labels(ctx, ctx.get_gates()); + if (labels.is_error()) + { + return ERR_APPEND(labels.get_error(), "Failed to calculate labels"); + } + + return OK(labels.get()); + } + + std::string NetNameKeyWord::to_string() const + { + std::string pin_types_str = utils::join("_", m_pin_types.begin(), m_pin_types.end(), [](const PinType& pt) { return enum_to_string(pt); }); + std::string applicable_to_str = utils::join("_", m_applicable_to.begin(), m_applicable_to.end(), [](const GateTypeProperty& gtp) { return enum_to_string(gtp); }); + + return "NetNameKeyWord_" + m_key_word + "_" + pin_types_str + "_" + (m_applicable_to.empty() ? "ALL" : applicable_to_str); + } + } // namespace gate_label } // namespace machine_learning } // namespace hal \ No newline at end of file diff --git a/src/netlist/decorators/netlist_abstraction_decorator.cpp b/src/netlist/decorators/netlist_abstraction_decorator.cpp index 010a60a581d..0b736b2501c 100644 --- a/src/netlist/decorators/netlist_abstraction_decorator.cpp +++ b/src/netlist/decorators/netlist_abstraction_decorator.cpp @@ -582,7 +582,7 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed, - bool continue_on_match, + const bool continue_on_match, const std::function& exit_endpoint_filter, const std::function& entry_endpoint_filter) const { @@ -713,11 +713,153 @@ namespace hal return ERR("cannot get next matching gates until: pin direction " + enum_to_string(direction) + " is not supported"); } + Result> NetlistAbstractionDecorator::get_next_matching_gates_internal(const std::vector& start, + const std::function& target_gate_filter, + const PinDirection& direction, + std::map, std::set>& cache, + const bool directed, + const bool continue_on_match, + const std::function& exit_endpoint_filter, + const std::function& entry_endpoint_filter) const + { + if (direction != PinDirection::output && direction != PinDirection::input) + { + return ERR("cannot get next matching gates until: pin direction " + enum_to_string(direction) + " is not supported"); + } + + std::set res; + u32 distance = 0; + + std::unordered_set visited; + std::set> visited_at; + + std::vector current; + std::vector next; + + // check whether start already fullfills target or exit filter + for (auto* start_ep : start) + { + if (exit_endpoint_filter != nullptr && !exit_endpoint_filter(start_ep, distance)) + { + continue; + } + + visited.insert(start_ep); + visited_at.insert({start_ep, distance}); + + if (const auto it = cache.find({start_ep, distance}); it != cache.end()) + { + for (auto* c_gate : it->second) + { + res.insert(c_gate); + } + continue; + } + + current.push_back(start_ep); + } + + while (true) + { + distance++; + + for (const auto& exit_ep : current) + { + // currently only works for input and output pins + if (exit_ep->get_pin()->get_direction() != PinDirection::output && exit_ep->get_pin()->get_direction() != PinDirection::input) + { + return ERR("failed to get shortest path distance: found endpoint at gate " + exit_ep->get_gate()->get_name() + " with ID " + std::to_string(exit_ep->get_gate()->get_id()) + + " and pin " + exit_ep->get_pin()->get_name() + " with direction " + enum_to_string(exit_ep->get_pin()->get_direction()) + " that is currently unhandled"); + } + + const auto entry_eps = (exit_ep->get_pin()->get_direction() == PinDirection::output) ? m_abstraction.get_successors(exit_ep) : m_abstraction.get_predecessors(exit_ep); + if (entry_eps.is_error()) + { + return ERR_APPEND(entry_eps.get_error(), "cannot get shortest path distance starting from endpoints"); + } + + for (const auto& entry_ep : entry_eps.get()) + { + if (entry_endpoint_filter != nullptr && !entry_endpoint_filter(entry_ep, distance)) + { + continue; + } + + const auto next_g = entry_ep->get_gate(); + + if (target_gate_filter(next_g)) + { + res.insert(next_g); + + if (!continue_on_match) + { + continue; + } + } + + std::vector next_eps; + if (directed) + { + next_eps = (direction == PinDirection::output) ? next_g->get_fan_out_endpoints() : next_g->get_fan_in_endpoints(); + } + else + { + next_eps.insert(next_eps.end(), next_g->get_fan_out_endpoints().begin(), next_g->get_fan_out_endpoints().end()); + next_eps.insert(next_eps.end(), next_g->get_fan_in_endpoints().begin(), next_g->get_fan_in_endpoints().end()); + } + + for (const auto& next_ep : next_eps) + { + if (exit_endpoint_filter != nullptr && !exit_endpoint_filter(next_ep, distance)) + { + continue; + } + + if (const auto it = visited.find(next_ep); it != visited.end()) + { + continue; + } + visited.insert(next_ep); + visited_at.insert({next_ep, distance}); + + // Check if endpoint was cached + if (const auto it = cache.find({next_ep, distance}); it != cache.end()) + { + for (auto* c_gate : it->second) + { + res.insert(c_gate); + } + continue; + } + + next.push_back(next_ep); + } + } + } + + if (next.empty()) + { + break; + } + + current = next; + next.clear(); + } + + // add the result to the cache for all visited + for (const auto& ep_at_distance : visited_at) + { + cache.insert({ep_at_distance, res}); + } + + return OK(res); + } + Result> NetlistAbstractionDecorator::get_next_matching_gates(Endpoint* endpoint, const std::function& target_gate_filter, const PinDirection& direction, const bool directed, - bool continue_on_match, + const bool continue_on_match, const std::function& exit_endpoint_filter, const std::function& entry_endpoint_filter) const { @@ -743,7 +885,7 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed, - bool continue_on_match, + const bool continue_on_match, const std::function& exit_endpoint_filter, const std::function& entry_endpoint_filter) const { @@ -787,11 +929,115 @@ namespace hal return get_next_matching_gates_internal(start, target_gate_filter, direction, directed, continue_on_match, exit_endpoint_filter, entry_endpoint_filter); } + Result>> NetlistAbstractionDecorator::get_next_matching_gates(const std::vector& endpoints, + const std::function& target_gate_filter, + const PinDirection& direction, + const bool directed, + const bool continue_on_match, + const std::function& exit_endpoint_filter, + const std::function& entry_endpoint_filter) const + { + std::map, std::set> cache; + std::vector> results; + + for (auto* ep : endpoints) + { + if (ep == nullptr) + { + return ERR("nullptr given as endpoint"); + } + + if (!target_gate_filter) + { + return ERR("no target gate filter specified"); + } + + if (ep->get_pin()->get_direction() != direction) + { + return ERR("pin does not match direction"); + } + + auto res = get_next_matching_gates_internal({ep}, target_gate_filter, direction, cache, directed, continue_on_match, exit_endpoint_filter, entry_endpoint_filter); + + if (res.is_error()) + { + return ERR_APPEND(res.get_error(), "cannot get next matching gates for all endpoints"); + } + + results.push_back(res.get()); + } + + return OK(results); + } + + Result>> NetlistAbstractionDecorator::get_next_matching_gates(const std::vector& gates, + const std::function& target_gate_filter, + const PinDirection& direction, + const bool directed, + const bool continue_on_match, + const std::function& exit_endpoint_filter, + const std::function& entry_endpoint_filter) const + { + std::map, std::set> cache; + std::vector> results; + + for (auto* g : gates) + { + if (g == nullptr) + { + return ERR("nullptr given as gate"); + } + + if (!target_gate_filter) + { + return ERR("no target gate filter specified"); + } + + std::vector start; + if (direction == PinDirection::output || direction == PinDirection::inout) + { + for (auto* exit_ep : g->get_fan_out_endpoints()) + { + if (exit_endpoint_filter != nullptr && !exit_endpoint_filter(exit_ep, 0)) + { + continue; + } + + start.push_back(exit_ep); + } + } + + if (direction == PinDirection::input || direction == PinDirection::inout) + { + for (auto* exit_ep : g->get_fan_in_endpoints()) + { + if (exit_endpoint_filter != nullptr && !exit_endpoint_filter(exit_ep, 0)) + { + continue; + } + + start.push_back(exit_ep); + } + } + + auto res = get_next_matching_gates_internal(start, target_gate_filter, direction, cache, directed, continue_on_match, exit_endpoint_filter, entry_endpoint_filter); + + if (res.is_error()) + { + return ERR_APPEND(res.get_error(), "cannot get next matching gates for all gates"); + } + + results.push_back(res.get()); + } + + return OK(results); + } + Result> NetlistAbstractionDecorator::get_next_matching_gates_until_internal(const std::vector& start, const std::function& target_gate_filter, const PinDirection& direction, const bool directed, - bool continue_on_mismatch, + const bool continue_on_mismatch, const std::function& exit_endpoint_filter, const std::function& entry_endpoint_filter) const { @@ -928,7 +1174,7 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed, - bool continue_on_mismatch, + const bool continue_on_mismatch, const std::function& exit_endpoint_filter, const std::function& entry_endpoint_filter) const { @@ -954,7 +1200,7 @@ namespace hal const std::function& target_gate_filter, const PinDirection& direction, const bool directed, - bool continue_on_mismatch, + const bool continue_on_mismatch, const std::function& exit_endpoint_filter, const std::function& entry_endpoint_filter) const { diff --git a/src/netlist/gate_library/gate_type.cpp b/src/netlist/gate_library/gate_type.cpp index cd6a5eedefc..dc315036da9 100644 --- a/src/netlist/gate_library/gate_type.cpp +++ b/src/netlist/gate_library/gate_type.cpp @@ -1,5 +1,4 @@ #include "hal_core/netlist/gate_library/gate_type.h" - #include "hal_core/utilities/log.h" namespace hal