Skip to content

Commit

Permalink
fixed pybinds for get_next_sequential_gates
Browse files Browse the repository at this point in the history
  • Loading branch information
SJulianS committed May 10, 2024
1 parent b826e4e commit e0a5660
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 25 deletions.
33 changes: 28 additions & 5 deletions include/hal_core/netlist/decorators/netlist_traversal_decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace hal

/**
* Starting from the given net, traverse the netlist and return only the successor/predecessor gates for which the `target_gate_filter` evaluates to `true`.
* Continues traversal independent of whatever `target_gate_filter` evaluates to.
* Continue traversal independent of whatever `target_gate_filter` evaluates to.
* Stop traversal if (1) the `exit_endpoint_filter` evaluates to `false` on a fan-in/out endpoint (i.e., when exiting the current gate during traversal) or (2) the `entry_endpoint_filter` evaluates to `false` on a successor/predecessor endpoint (i.e., when entering the next gate during traversal).
* The target_gate_filter may be omitted in which case all traversed gates will be returned.
* Both `entry_endpoint_filter` and the `exit_endpoint_filter` may be omitted as well.
Expand All @@ -106,6 +106,7 @@ namespace hal

/**
* Starting from the given gate, traverse the netlist and return only the successor/predecessor gates for which the `target_gate_filter` evaluates to `true`.
* Continue traversal independent of whatever `target_gate_filter` evaluates to.
* Stop traversal if (1) the `exit_endpoint_filter` evaluates to `false` on a fan-in/out endpoint (i.e., when exiting the current gate during traversal) or (2) the `entry_endpoint_filter` evaluates to `false` on a successor/predecessor endpoint (i.e., when entering the next gate during traversal).
* The target_gate_filter may be omitted in which case all traversed gates will be returned.
* Both `entry_endpoint_filter` and the `exit_endpoint_filter` may be omitted as well.
Expand All @@ -123,13 +124,35 @@ namespace hal
const std::function<bool(const Endpoint*, const u32 current_depth)>& exit_endpoint_filter = nullptr,
const std::function<bool(const Endpoint*, const u32 current_depth)>& entry_endpoint_filter = nullptr) const;

// test & document
/**
* Starting from the given net, traverse the netlist and return only the next layer of sequential successor/predecessor gates.
* Traverse over gates that are not sequential until a sequential gate is found.
* Stops at all sequential gates, but only adds those to the result that have not been reached through a pin of one of the forbidden types.
* Provide a cache to speed up traversal when calling this function multiple times on the same netlist using the same forbidden pins.
*
* @param[in] net - Start net.
* @param[in] successors - Set `true` to get successors, set `false` to get predecessors.
* @param[in] forbidden_pins - Sequential gates reached through these pins will not be part of the result. Defaults to an empty set.
* @param[in] cache - An optional cache that can be used for better performance on repeated calls. Defaults to a `nullptr`.
* @returns The next sequential gates.
*/
Result<std::set<Gate*>>
get_next_sequential_gates(const Net* net, bool successors, const std::set<PinType>& forbidden_input_pins = {}, std::unordered_map<const Net*, std::set<Gate*>>* cache = nullptr) const;
get_next_sequential_gates(const Net* net, bool successors, const std::set<PinType>& forbidden_pins = {}, std::unordered_map<const Net*, std::set<Gate*>>* cache = nullptr) const;

// test & document
/**
* Starting from the given gate, traverse the netlist and return only the next layer of sequential successor/predecessor gates.
* Traverse over gates that are not sequential until a sequential gate is found.
* Stops at all sequential gates, but only adds those to the result that have not been reached through a pin of one of the forbidden types.
* Provide a cache to speed up traversal when calling this function multiple times on the same netlist using the same forbidden pins.
*
* @param[in] gate - Start gate.
* @param[in] successors - Set `true` to get successors, set `false` to get predecessors.
* @param[in] forbidden_pins - Sequential gates reached through these pins will not be part of the result. Defaults to an empty set.
* @param[in] cache - An optional cache that can be used for better performance on repeated calls. Defaults to a `nullptr`.
* @returns The next sequential gates.
*/
Result<std::set<Gate*>>
get_next_sequential_gates(const Gate* gate, bool successors, const std::set<PinType>& forbidden_input_pins = {}, std::unordered_map<const Net*, std::set<Gate*>>* cache = nullptr) const;
get_next_sequential_gates(const Gate* gate, bool successors, const std::set<PinType>& forbidden_pins = {}, std::unordered_map<const Net*, std::set<Gate*>>* cache = nullptr) const;

// TODO implement get_next_combinational_gates (get all combinational successor gates until sequential (non-combinational) gates are hit)

Expand Down
16 changes: 6 additions & 10 deletions src/netlist/decorators/netlist_traversal_decorator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,8 @@ namespace hal
return OK(res);
}

Result<std::set<Gate*>> NetlistTraversalDecorator::get_next_sequential_gates(const Net* net,
bool successors,
const std::set<PinType>& forbidden_input_pins,
std::unordered_map<const Net*, std::set<Gate*>>* cache) const
Result<std::set<Gate*>>
NetlistTraversalDecorator::get_next_sequential_gates(const Net* net, bool successors, const std::set<PinType>& forbidden_pins, std::unordered_map<const Net*, std::set<Gate*>>* cache) const
{
if (net == nullptr)
{
Expand Down Expand Up @@ -289,7 +287,7 @@ namespace hal
if (gate->get_type()->has_property(GateTypeProperty::sequential))
{
// stop traversal if gate is sequential
if (forbidden_input_pins.find(pin->get_type()) == forbidden_input_pins.end())
if (forbidden_pins.find(pin->get_type()) == forbidden_pins.end())
{
// only add gate to result if it has not been reached through a forbidden pin (e.g., control pin)
res.insert(gate);
Expand Down Expand Up @@ -332,10 +330,8 @@ namespace hal
return OK(res);
}

Result<std::set<Gate*>> NetlistTraversalDecorator::get_next_sequential_gates(const Gate* gate,
bool successors,
const std::set<PinType>& forbidden_input_pins,
std::unordered_map<const Net*, std::set<Gate*>>* cache) const
Result<std::set<Gate*>>
NetlistTraversalDecorator::get_next_sequential_gates(const Gate* gate, bool successors, const std::set<PinType>& forbidden_pins, std::unordered_map<const Net*, std::set<Gate*>>* cache) const
{
if (gate == nullptr)
{
Expand All @@ -350,7 +346,7 @@ namespace hal
std::set<Gate*> res;
for (const auto* exit_ep : successors ? gate->get_fan_out_endpoints() : gate->get_fan_in_endpoints())
{
const auto next_res = this->get_next_sequential_gates(exit_ep->get_net(), successors, forbidden_input_pins, cache);
const auto next_res = this->get_next_sequential_gates(exit_ep->get_net(), successors, forbidden_pins, cache);
if (next_res.is_error())
{
return ERR(next_res.get_error());
Expand Down
91 changes: 81 additions & 10 deletions src/python_bindings/bindings/netlist_traversal_decorator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace hal
py::arg("entry_endpoint_filter") = nullptr,
R"(
Starting from the given net, traverse the netlist and return only the successor/predecessor gates for which the ``target_gate_filter`` evaluates to ``True``.
Continues traversal independent of whatever ``target_gate_filter`` evaluates to.
Continue traversal independent of whatever ``target_gate_filter`` evaluates to.
Stop traversal if (1) the ``exit_endpoint_filter`` evaluates to ``False`` on a fan-in/out endpoint (i.e., when exiting the current gate during traversal) or (2) the ``entry_endpoint_filter`` evaluates to ``False`` on a successor/predecessor endpoint (i.e., when entering the next gate during traversal).
The target_gate_filter may be omitted in which case all traversed gates will be returned.
Both ``entry_endpoint_filter`` and the ``exit_endpoint_filter`` may be omitted as well.
Expand Down Expand Up @@ -157,6 +157,7 @@ namespace hal
py::arg("entry_endpoint_filter") = nullptr,
R"(
Starting from the given gate, traverse the netlist and return only the successor/predecessor gates for which the ``target_gate_filter`` evaluates to ``True``.
Continue traversal independent of whatever ``target_gate_filter`` evaluates to.
Stop traversal if (1) the ``exit_endpoint_filter`` evaluates to ``False`` on a fan-in/out endpoint (i.e., when exiting the current gate during traversal) or (2) the ``entry_endpoint_filter`` evaluates to ``False`` on a successor/predecessor endpoint (i.e., when entering the next gate during traversal).
The target_gate_filter may be omitted in which case all traversed gates will be returned.
Both ``entry_endpoint_filter`` and the ``exit_endpoint_filter`` may be omitted as well.
Expand All @@ -172,9 +173,38 @@ namespace hal

py_netlist_traversal_decorator.def(
"get_next_sequential_gates",
[](NetlistTraversalDecorator& self, const Net* net, bool successors, const std::set<PinType>& forbidden_input_pins = {}, std::unordered_map<const Net*, std::set<Gate*>>* cache = nullptr)
[](NetlistTraversalDecorator& self, const Net* net, bool successors, const std::set<PinType>& forbidden_pins = {}) -> std::optional<std::set<Gate*>> {
auto res = self.get_next_sequential_gates(net, successors, forbidden_pins, nullptr);
if (res.is_ok())
{
return res.get();
}
else
{
log_error("python_context", "error encountered while getting next sequential gates:\n{}", res.get_error().get());
return std::nullopt;
}
},
py::arg("net"),
py::arg("successors"),
py::arg("forbidden_pins") = std::set<PinType>(),
R"(
Starting from the given net, traverse the netlist and return only the next layer of sequential successor/predecessor gates.
Traverse over gates that are not sequential until a sequential gate is found.
Stops at all sequential gates, but only adds those to the result that have not been reached through a pin of one of the forbidden types.
:param hal_py.Net net: Start net.
:param bool successors: Set ``True`` to get successors, set ``False`` to get predecessors.
:param set[hal_py.PinType] forbidden_pins: Sequential gates reached through these pins will not be part of the result. Defaults to an empty set.
:returns: The next sequential gates.
:rtype: set[hal_py.Gate] or None
)");

py_netlist_traversal_decorator.def(
"get_next_sequential_gates",
[](NetlistTraversalDecorator& self, const Net* net, bool successors, const std::set<PinType>& forbidden_pins, std::unordered_map<const Net*, std::set<Gate*>>* cache)
-> std::optional<std::set<Gate*>> {
auto res = self.get_next_sequential_gates(net, successors, forbidden_input_pins, cache);
auto res = self.get_next_sequential_gates(net, successors, forbidden_pins, cache);
if (res.is_ok())
{
return res.get();
Expand All @@ -187,21 +217,56 @@ namespace hal
},
py::arg("net"),
py::arg("successors"),
py::arg("forbidden_input_pins") = std::set<PinType>(),
py::arg("cache") = nullptr,
py::arg("forbidden_pins"),
py::arg("cache"),
R"(
Starting from the given net, traverse the netlist and return only the next layer of sequential successor/predecessor gates.
Traverse over gates that are not sequential until a sequential gate is found.
Stops at all sequential gates, but only adds those to the result that have not been reached through a pin of one of the forbidden types.
Provide a cache to speed up traversal when calling this function multiple times on the same netlist using the same forbidden pins.
:param hal_py.Net net: Start net.
:param bool successors: Set ``True`` to get successors, set ``False`` to get predecessors.
:param set[hal_py.PinType] forbidden_pins: Sequential gates reached through these pins will not be part of the result.
:param dict[hal_py.Net, set[hal_py.Gate]] cache: A cache that can be used for better performance on repeated calls.
:returns: The next sequential gates.
:rtype: set[hal_py.Gate] or None
)");

py_netlist_traversal_decorator.def(
"get_next_sequential_gates",
[](NetlistTraversalDecorator& self, const Gate* gate, bool successors, const std::set<PinType>& forbidden_pins = {}) -> std::optional<std::set<Gate*>> {
auto res = self.get_next_sequential_gates(gate, successors, forbidden_pins, nullptr);
if (res.is_ok())
{
return res.get();
}
else
{
log_error("python_context", "error encountered while getting next sequential gates:\n{}", res.get_error().get());
return std::nullopt;
}
},
py::arg("gate"),
py::arg("successors"),
py::arg("forbidden_pins") = std::set<PinType>(),
R"(
Starting from the given gate, traverse the netlist and return only the next layer of sequential successor/predecessor gates.
Traverse over gates that are not sequential until a sequential gate is found.
Stops at all sequential gates, but only adds those to the result that have not been reached through a pin of one of the forbidden types.
:param hal_py.Gate gate: Start gate.
:param bool successors: Set ``True`` to get successors, set ``False`` to get predecessors.
:param set[hal_py.PinType] forbidden_pins: Sequential gates reached through these pins will not be part of the result. Defaults to an empty set.
:returns: The next sequential gates.
:rtype: set[hal_py.Gate] or None
)");

py_netlist_traversal_decorator.def(
"get_next_sequential_gates",
[](NetlistTraversalDecorator& self, const Gate* gate, bool successors, const std::set<PinType>& forbidden_input_pins = {}, std::unordered_map<const Net*, std::set<Gate*>>* cache = nullptr)
[](NetlistTraversalDecorator& self, const Gate* gate, bool successors, const std::set<PinType>& forbidden_pins, std::unordered_map<const Net*, std::set<Gate*>>* cache)
-> std::optional<std::set<Gate*>> {
auto res = self.get_next_sequential_gates(gate, successors, forbidden_input_pins, cache);
auto res = self.get_next_sequential_gates(gate, successors, forbidden_pins, cache);
if (res.is_ok())
{
return res.get();
Expand All @@ -214,13 +279,19 @@ namespace hal
},
py::arg("gate"),
py::arg("successors"),
py::arg("forbidden_input_pins") = std::set<PinType>(),
py::arg("cache") = nullptr,
py::arg("forbidden_pins"),
py::arg("cache"),
R"(
Starting from the given gate, traverse the netlist and return only the next layer of sequential successor/predecessor gates.
Traverse over gates that are not sequential until a sequential gate is found.
Stops at all sequential gates, but only adds those to the result that have not been reached through a pin of one of the forbidden types.
Provide a cache to speed up traversal when calling this function multiple times on the same netlist using the same forbidden pins.
:param hal_py.Gate gate: Start gate.
:param bool successors: Set ``True`` to get successors, set ``False`` to get predecessors.
:param set[hal_py.PinType] forbidden_pins: Sequential gates reached through these pins will not be part of the result.
:param dict[hal_py.Net, set[hal_py.Gate]] cache: A cache that can be used for better performance on repeated calls.
:returns: The next sequential gates.
:rtype: set[hal_py.Gate] or None
)");
}
Expand Down

0 comments on commit e0a5660

Please sign in to comment.