Skip to content

Commit

Permalink
Merge branch 'feature/netlist_traversal_decorator' into feature/hawkeye
Browse files Browse the repository at this point in the history
  • Loading branch information
SJulianS committed May 13, 2024
2 parents 535c20a + 32a395f commit 9da53e7
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,42 +51,49 @@ namespace hal
* Traverse over gates that do not meet the `target_gate_filter` condition.
* Stop traversal if (1) `continue_on_match` is `false` the `target_gate_filter` evaluates to `true`, (2) the `exit_endpoint_filter` evaluates to `false` on a fan-in/out endpoint (i.e., when exiting the current gate during traversal), or (3) the `entry_endpoint_filter` evaluates to `false` on a successor/predecessor endpoint (i.e., when entering the next gate during traversal).
* Both the `entry_endpoint_filter` and the `exit_endpoint_filter` may be omitted.
* Provide a cache to speed up traversal when calling this function multiple times on the same netlist using the same forbidden pins.
* Do not use a cache if the filter functions operate on the `current_depth`.
*
* @param[in] net - Start net.
* @param[in] successors - Set `true` to get successors, set `false` to get predecessors.
* @param[in] target_gate_filter - Filter condition that must be met for the target gates.
* @param[in] continue_on_match - Set `true` to continue even if `target_gate_filter` evaluated to `true`, `false` otherwise. Defaults to `false`.
* @param[in] exit_endpoint_filter - Filter condition that determines whether to stop traversal on a fan-in/out endpoint.
* @param[in] entry_endpoint_filter - Filter condition that determines whether to stop traversal on a successor/predecessor endpoint.
* @param[inout] cache - An optional cache that can be used for better performance on repeated calls. Defaults to a `nullptr`.
* @returns The next gates fulfilling the target gate filter condition on success, an error otherwise.
*/
Result<std::set<Gate*>> get_next_matching_gates(const Net* net,
bool successors,
const std::function<bool(const Gate*)>& target_gate_filter,
bool continue_on_match = false,
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;
const std::function<bool(const Endpoint*, const u32 current_depth)>& entry_endpoint_filter = nullptr,
std::unordered_map<const Net*, std::set<Gate*>>* cache = nullptr) const;

/**
* Starting from the given gate, traverse the netlist and return only 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` the `target_gate_filter` evaluates to `true`, (2) the `exit_endpoint_filter` evaluates to `false` on a fan-in/out endpoint (i.e., when exiting the current gate during traversal), or (3) the `entry_endpoint_filter` evaluates to `false` on a successor/predecessor endpoint (i.e., when entering the next gate during traversal).
* Both the `entry_endpoint_filter` and the `exit_endpoint_filter` may be omitted.
* Do not use a cache if the filter functions operate on the `current_depth`.
*
* @param[in] gate - Start gate.
* @param[in] successors - Set `true` to get successors, set `false` to get predecessors.
* @param[in] target_gate_filter - Filter condition that must be met for the target gates.
* @param[in] continue_on_match - Set `true` to continue even if `target_gate_filter` evaluated to `true`, `false` otherwise. Defaults to `false`.
* @param[in] exit_endpoint_filter - Filter condition that determines whether to stop traversal on a fan-in/out endpoint.
* @param[in] entry_endpoint_filter - Filter condition that determines whether to stop traversal on a successor/predecessor endpoint.
* @param[inout] cache - An optional cache that can be used for better performance on repeated calls. Defaults to a `nullptr`.
* @returns The next gates fulfilling the target gate filter condition on success, an error otherwise.
*/
Result<std::set<Gate*>> get_next_matching_gates(const Gate* gate,
bool successors,
const std::function<bool(const Gate*)>& target_gate_filter,
bool continue_on_match = false,
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;
const std::function<bool(const Endpoint*, const u32 current_depth)>& entry_endpoint_filter = nullptr,
std::unordered_map<const Net*, std::set<Gate*>>* cache = nullptr) const;

/**
* Starting from the given net, traverse the netlist and return only the successor/predecessor gates for which the `target_gate_filter` evaluates to `true`.
Expand Down
66 changes: 56 additions & 10 deletions src/netlist/decorators/netlist_traversal_decorator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ namespace hal
const std::function<bool(const Gate*)>& target_gate_filter,
bool continue_on_match,
const std::function<bool(const Endpoint*, u32 current_depth)>& exit_endpoint_filter,
const std::function<bool(const Endpoint*, u32 current_depth)>& entry_endpoint_filter) const
const std::function<bool(const Endpoint*, u32 current_depth)>& entry_endpoint_filter,
std::unordered_map<const Net*, std::set<Gate*>>* cache) const
{
if (net == nullptr)
{
Expand Down Expand Up @@ -56,29 +57,59 @@ namespace hal
continue;
}

auto* g = entry_ep->get_gate();
auto* gate = entry_ep->get_gate();

if (target_gate_filter(g))
if (target_gate_filter(gate))
{
res.insert(g);
res.insert(gate);

// update cache
if (cache)
{
(*cache)[current].insert(gate);
for (const auto* n : previous)
{
(*cache)[n].insert(gate);
}
}

if (!continue_on_match)
{
continue;
}
}

for (const auto* exit_ep : successors ? g->get_fan_out_endpoints() : g->get_fan_in_endpoints())
for (const auto* exit_ep : successors ? gate->get_fan_out_endpoints() : gate->get_fan_in_endpoints())
{
if (exit_endpoint_filter != nullptr && !exit_endpoint_filter(exit_ep, previous.size() + 1))
{
continue;
}

const Net* n = exit_ep->get_net();
if (visited.find(n) == visited.end())
const Net* exit_net = exit_ep->get_net();
if (cache)
{
stack.push_back(n);
if (const auto it = cache->find(exit_net); it != cache->end())
{
const auto& cached_gates = std::get<1>(*it);

// append cached gates to result
res.insert(cached_gates.begin(), cached_gates.end());

// update cache
(*cache)[current].insert(cached_gates.begin(), cached_gates.end());
for (const auto* n : previous)
{
(*cache)[n].insert(cached_gates.begin(), cached_gates.end());
}

continue;
}
}

if (visited.find(exit_net) == visited.end())
{
stack.push_back(exit_net);
added = true;
}
}
Expand All @@ -102,7 +133,8 @@ namespace hal
const std::function<bool(const Gate*)>& target_gate_filter,
bool continue_on_match,
const std::function<bool(const Endpoint*, u32 current_depth)>& exit_endpoint_filter,
const std::function<bool(const Endpoint*, u32 current_depth)>& entry_endpoint_filter) const
const std::function<bool(const Endpoint*, u32 current_depth)>& entry_endpoint_filter,
std::unordered_map<const Net*, std::set<Gate*>>* cache) const
{
if (gate == nullptr)
{
Expand All @@ -122,7 +154,21 @@ namespace hal
continue;
}

const auto next_res = this->get_next_matching_gates(exit_ep->get_net(), successors, target_gate_filter, continue_on_match, exit_endpoint_filter, entry_endpoint_filter);
const auto* exit_net = exit_ep->get_net();
if (cache)
{
if (const auto it = cache->find(exit_net); it != cache->end())
{
const auto& cached_gates = std::get<1>(*it);

// append cached gates to result
res.insert(cached_gates.begin(), cached_gates.end());

continue;
}
}

const auto next_res = this->get_next_matching_gates(exit_net, successors, target_gate_filter, continue_on_match, exit_endpoint_filter, entry_endpoint_filter, cache);
if (next_res.is_error())
{
return ERR(next_res.get_error());
Expand Down

0 comments on commit 9da53e7

Please sign in to comment.