10 namespace module_identification
14 #ifdef HAL_CANDIDATE_CONTEXT
20 for (
const auto& n : nets)
22 auto bf_res = subgraph_dec.get_subgraph_function(
m_gates, n, gate_cache);
23 if (bf_res.is_error())
26 "cannot populate context with Boolean functions: failed to generate subgraph function for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()));
28 auto bf = bf_res.get();
31 if (sub_res.is_error())
34 "cannot populate context with Boolean functions: failed to substitute power and ground nets for net " + n->get_name() +
" with ID "
35 + std::to_string(n->get_id()));
38 m_boolean_function_cache.insert({{n, {}}, sub_res.get().
simplify_local()});
46 if (
const auto it = m_boolean_function_cache.find({n, ctrl_mapping}); it != m_boolean_function_cache.end())
48 return OK(it->second);
51 return ERR(
"Failed to get boolean function from chache");
56 std::vector<BooleanFunction> functions;
57 for (
const auto&
net : nets)
60 if (bf_res.is_error())
62 return ERR(bf_res.get_error().get());
64 functions.push_back(bf_res.get().clone());
72 if (
const auto it = m_boolean_function_cache.find({n, ctrl_mapping}); it != m_boolean_function_cache.end())
74 return OK(it->second);
77 if (ctrl_mapping.empty())
79 auto func_res = SubgraphNetlistDecorator(*m_netlist).get_subgraph_function(
m_gates, n);
80 if (func_res.is_error())
83 "cannot get Boolean function from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
": failed subgraph function generation");
85 auto bf = func_res.get();
87 auto sub_res = BooleanFunctionDecorator(bf).substitute_power_ground_nets(
m_netlist);
88 if (sub_res.is_error())
91 "cannot get Boolean function from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
": failed to substitute power/ground nets");
93 auto sub_bf = sub_res.get().simplify_local();
95 const auto [it, _] = m_boolean_function_cache.insert({{n, ctrl_mapping}, sub_bf});
96 return OK(it->second);
100 if (bf_res.is_error())
104 const auto& bf = bf_res.get();
106 std::map<std::string, BooleanFunction> substitution_map;
107 for (
const auto& [n_ctrl, val] : ctrl_mapping)
109 substitution_map.insert({BooleanFunctionNetDecorator(*n_ctrl).get_boolean_variable_name(),
BooleanFunction::Const(val)});
111 auto sub_res = bf.substitute(substitution_map);
112 if (sub_res.is_error())
115 "cannot get Boolean function from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
": failed to substitute with input mapping");
117 const auto sub_bf = sub_res.get().simplify_local();
119 const auto [it, _] = m_boolean_function_cache.insert({{n, ctrl_mapping}, sub_bf});
120 return OK(it->second);
125 std::vector<BooleanFunction> functions;
126 for (
const auto&
net : nets)
129 if (bf_res.is_error())
131 return ERR(bf_res.get_error().get());
133 functions.push_back(bf_res.get().clone());
136 return OK(functions);
141 if (
const auto it = m_boolean_vars_cache.find({n, ctrl_mapping}); it != m_boolean_vars_cache.end())
143 return OK(it->second);
147 if (bf_res.is_error())
150 "cannot get variable names from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
": failed to retrieve Boolean function from context");
152 const auto& bf = bf_res.get();
154 const auto [it, _] = m_boolean_vars_cache.insert({{n, ctrl_mapping}, bf.get_variable_names()});
155 return OK(it->second);
161 if (var_names_res.is_error())
164 "cannot get variable nets from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
": failed to retrieve variable names from context");
166 const auto& var_names = var_names_res.get();
168 std::set<Net*> result;
169 for (
const auto& var : var_names)
179 if (
const auto it = m_boolean_influence_cache.find({n, ctrl_mapping}); it != m_boolean_influence_cache.end())
181 return OK(it->second);
185 if (bf_res.is_error())
188 "cannot get Boolean influence from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id())
189 +
": failed to retrieve Boolean function from context");
191 const auto& bf = bf_res.get();
198 "cannot get Boolean influence from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
": failed to calculate Boolean influence");
201 const auto [it, _] = m_boolean_influence_cache.insert({{n, ctrl_mapping}, res.get()});
202 return OK(it->second);
205 Result<std::vector<BooleanFunction::Value>>
206 CandidateContext::evaluate(
const Net* n,
const std::map<Net*, BooleanFunction::Value>& ctrl_mapping,
const std::map<std::string, BooleanFunction::Value>& eval_mapping)
209 std::unordered_map<std::string, BooleanFunction::Value> unordered_eval_mapping = {eval_mapping.begin(), eval_mapping.end()};
210 return OK({bf.evaluate(unordered_eval_mapping).get()});
214 #ifdef Z3_CANDIDATE_CONTEXT
218 if (func_res.is_error())
221 log_error(
"module_identification",
"Error on boolean sugraph function creation, for nets: {}", func_res.get_error().get());
223 auto functions = func_res.get();
225 for (
u32 idx = 0; idx < nets.size(); idx++)
227 auto bf = functions.at(idx);
231 z3::expr_vector from(m_ctx);
232 z3::expr_vector
to(m_ctx);
234 for (
const std::string& var_name : vars)
237 if (net_res.is_error())
239 log_error(
"module_identification",
"Error when trying to replace gnd and vcc nets in boolean function for variable '{}': {}", var_name, net_res.get_error().get());
241 const Net*
net = net_res.get();
243 if (
const auto sources =
net->get_sources(); sources.size() == 1)
247 from.push_back(m_ctx.bv_const(var_name.c_str(), 1));
248 to.push_back(m_ctx.bv_val(1, 1));
252 from.push_back(m_ctx.bv_const(var_name.c_str(), 1));
253 to.push_back(m_ctx.bv_val(0, 1));
258 bf = bf.substitute(from,
to).simplify();
261 if (s_res.is_error())
263 std::cout <<
"ERROR: " << s_res.get_error().get() << std::endl;
267 m_boolean_function_cache.insert({{nets.at(idx), {}}, bf});
275 if (
const auto it = m_boolean_function_cache.find({n, ctrl_mapping}); it != m_boolean_function_cache.end())
277 return OK(it->second);
280 if (ctrl_mapping.empty())
283 if (func_res.is_error())
286 log_error(
"module_identification",
"Error on boolean sugraph function creation, for nets: {}", func_res.get_error().get());
288 auto bf = func_res.get();
293 z3::expr_vector from_power_gnd(m_ctx);
294 z3::expr_vector to_power_gnd(m_ctx);
296 for (
const std::string& var_name : vars)
299 if (net_res.is_error())
301 log_error(
"module_identification",
"Error when trying to replace gnd and vcc nets in boolean function for variable '{}': {}", var_name, net_res.get_error().get());
303 const Net*
net = net_res.get();
305 if (
const auto sources =
net->get_sources(); sources.size() == 1)
309 from_power_gnd.push_back(m_ctx.bv_const(var_name.c_str(), 1));
310 to_power_gnd.push_back(m_ctx.bv_val(1, 1));
314 from_power_gnd.push_back(m_ctx.bv_const(var_name.c_str(), 1));
315 to_power_gnd.push_back(m_ctx.bv_val(0, 1));
320 bf = bf.substitute(from_power_gnd, to_power_gnd).simplify();
323 if (s_res.is_error())
325 std::cout <<
"ERROR: " << s_res.get_error().get() << std::endl;
329 m_boolean_function_cache.insert({{n, {}}, bf});
334 z3::expr_vector from(m_ctx);
335 z3::expr_vector
to(m_ctx);
336 for (
const auto& [cn, val] : ctrl_mapping)
338 from.push_back(m_ctx.bv_const(BooleanFunctionNetDecorator(*cn).get_boolean_variable_name().c_str(), 1));
339 to.push_back(m_ctx.bv_val(val == BooleanFunction::Value::ZERO ? 0 : 1, 1));
341 bf = bf.substitute(from,
to).simplify();
344 if (s_res.is_error())
346 std::cout <<
"ERROR: " << s_res.get_error().get() << std::endl;
350 const auto it = m_boolean_function_cache.insert({{n, ctrl_mapping}, bf});
351 return OK(it.first->second);
356 if (
const auto it = m_boolean_function_cache.find({n, ctrl_mapping}); it != m_boolean_function_cache.end())
358 return OK(it->second);
361 std::cout <<
"Control Mapping: " << std::endl;
362 for (
const auto& [cn, v] : ctrl_mapping)
364 std::cout <<
"\t" << cn->get_id() <<
": " << v << std::endl;
367 std::cout <<
"Candidate Gates: " << std::endl;
368 for (
const auto& g : this->
m_gates)
370 std::cout <<
"\t" << g->get_id() <<
": " << g->get_name() << std::endl;
373 return ERR(
"Failed to get boolean function for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
" from boolean function cache");
376 Result<BooleanFunction> CandidateContext::get_hal_boolean_function(
const Net* n,
const std::map<Net*, BooleanFunction::Value>& ctrl_mapping)
378 if (
const auto it = m_boolean_function_hal_cache.find({n, ctrl_mapping}); it != m_boolean_function_hal_cache.end())
380 return OK(it->second);
384 if (bf_res.is_error())
386 return ERR(bf_res.get_error().get());
390 if (bf_hal_res.is_error())
392 return ERR(bf_hal_res.get_error().get());
395 const auto [it, _] = m_boolean_function_hal_cache.insert({{n, ctrl_mapping}, bf_hal_res.get()});
396 return OK(it->second);
399 Result<BooleanFunction> CandidateContext::get_hal_boolean_function_const(
const Net* n,
const std::map<Net*, BooleanFunction::Value>& ctrl_mapping)
401 if (
const auto it = m_boolean_function_hal_cache.find({n, ctrl_mapping}); it != m_boolean_function_hal_cache.end())
403 return OK(it->second);
406 std::cout <<
"Control Mapping: " << std::endl;
407 for (
const auto& [cn, v] : ctrl_mapping)
409 std::cout <<
"\t" << cn->get_id() <<
": " << v << std::endl;
412 std::cout <<
"Candidate Gates: " << std::endl;
413 for (
const auto& g : this->m_gates)
415 std::cout <<
"\t" << g->get_id() <<
": " << g->get_name() << std::endl;
418 return ERR(
"Failed to get boolean function for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
" from boolean function cache");
423 std::vector<BooleanFunction> functions;
424 for (
const auto&
net : nets)
426 const auto bf_hal_res = get_hal_boolean_function(
net, ctrl_mapping);
427 if (bf_hal_res.is_error())
429 return ERR(bf_hal_res.get_error().get());
432 functions.push_back(bf_hal_res.get());
435 return OK(functions);
440 std::vector<BooleanFunction> functions;
441 for (
const auto&
net : nets)
443 const auto bf_hal_res = get_hal_boolean_function_const(
net, ctrl_mapping);
444 if (bf_hal_res.is_error())
446 return ERR(bf_hal_res.get_error().get());
449 functions.push_back(bf_hal_res.get());
452 return OK(functions);
457 if (
const auto it = m_boolean_vars_cache.find({n, ctrl_mapping}); it != m_boolean_vars_cache.end())
459 return OK(it->second);
463 if (bf_res.is_error())
466 "cannot get variable names from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
": failed to retrieve Boolean function from context");
468 const auto& bf = bf_res.get();
471 return OK(it->second);
477 if (var_names_res.is_error())
480 "cannot get variable nets from context for net " + n->get_name() +
" with ID " + std::to_string(n->get_id()) +
": failed to retrieve variable names from context");
482 const auto& var_names = var_names_res.get();
484 std::set<Net*> result;
485 for (
const auto& var : var_names)
495 if (
const auto it = m_boolean_influence_cache.find({n, ctrl_mapping}); it != m_boolean_influence_cache.end())
497 return OK(it->second);
504 return ERR_APPEND(res.get_error(),
"failed to create boolean influence");
506 m_boolean_influence_cache.insert({{n, ctrl_mapping}, res.get()});
508 return OK(m_boolean_influence_cache.at({n, ctrl_mapping}));
511 Result<std::vector<BooleanFunction::Value>>
512 CandidateContext::evaluate(
const Net* n,
const std::map<Net*, BooleanFunction::Value>& ctrl_mapping,
const std::map<std::string, BooleanFunction::Value>& eval_mapping)
516 z3::expr_vector from(m_ctx);
517 z3::expr_vector
to(m_ctx);
520 for (
const auto& [var_name, val] : eval_mapping)
522 z3::expr var = m_ctx.bv_const(var_name.c_str(), 1);
523 z3::expr val_expr = m_ctx.bv_val(val, 1);
525 to.push_back(val_expr);
529 z3::expr result = bf_z3.substitute(from,
to).simplify();
531 if (!result.is_numeral())
533 return ERR(
"eval result is non numeral");
536 const u64 res_int = result.get_numeral_uint64();
540 return OK({BooleanFunction::Value::ONE});
545 return OK({BooleanFunction::Value::ZERO});
548 return ERR(
"invalid value " + std::to_string(res_int) +
" as result of eval");
This file contains the CandidateContext struct and that is used for optimization purposes during the ...
Result< BooleanFunction > substitute_power_ground_nets(const Netlist *nl) const
static BooleanFunction Const(const BooleanFunction::Value &value)
static Result< Net * > get_net_from(const Netlist *netlist, const BooleanFunction &var)
std::map< std::pair< u32, const GatePin * >, BooleanFunction > SubgraphFunctionCache
#define log_error(channel,...)
#define ERR_APPEND(prev_error, message)
Result< std::unordered_map< std::string, double > > get_boolean_influence(const BooleanFunction &bf, const u32 num_evaluations=32000)
std::set< std::string > get_variable_names(const z3::expr &e)
Extracts all variable names from a z3 expression.
Result< z3::expr > simplify_local(const z3::expr &e, std::unordered_map< u32, z3::expr > &cache, const bool check_correctness=false)
Applies hand-crafted simplification rules iteratively until no further simplifications can be made.
Result< z3::expr > get_subgraph_z3_function(const std::vector< Gate * > &subgraph_gates, const Net *subgraph_output, z3::context &ctx)
Get the z3 expression representation of a combined Boolean function of a subgraph of combinational ga...
Result< std::vector< z3::expr > > get_subgraph_z3_functions(const std::vector< Gate * > &subgraph_gates, const std::vector< Net * > &subgraph_outputs, z3::context &ctx)
Get the z3 expression representations of combined Boolean functions of a subgraph of combinational ga...
Result< BooleanFunction > to_bf(const z3::expr &e)
hal::Result< const std::set< Net * > > get_variable_nets(const Net *n, const std::map< Net *, BooleanFunction::Value > &ctrl_mapping)
Retrieves the variable nets for a given net and control mapping.
hal::Result< std::unordered_map< std::string, double > > get_boolean_influence(const Net *n, const std::map< Net *, BooleanFunction::Value > &ctrl_mapping)
Retrieves the boolean influence for a given net and control mapping.
std::vector< Gate * > m_gates
The gates of the corresponding structural candidate.
CandidateContext(const Netlist *nl, const std::vector< Gate * > &gates)
Constructs a new CandidateContext object saving results for one structural candidate.
hal::Result< std::vector< BooleanFunction > > get_boolean_functions_const(const std::vector< Net * > nets, const std::map< Net *, BooleanFunction::Value > &ctrl_mapping) const
Retrieves a set of constant boolean functions for a given set of nets and control mapping.
hal::Result< const BooleanFunction > get_boolean_function_const(const Net *n, const std::map< Net *, BooleanFunction::Value > &ctrl_mapping) const
Retrieves a constant boolean function for a given net and control mapping.
hal::Result< std::monostate > populate_boolean_function_cache(const std::vector< Net * > nets)
Populates the boolean function cache for a set of nets.
const Netlist * m_netlist
The netlist associated with the candidate context.
hal::Result< const BooleanFunction > get_boolean_function(const Net *n, const std::map< Net *, BooleanFunction::Value > &ctrl_mapping)
Retrieves a boolean function for a given net and control mapping.
hal::Result< std::vector< BooleanFunction::Value > > evaluate(const Net *n, const std::map< Net *, BooleanFunction::Value > &ctrl_mapping, const std::map< std::string, BooleanFunction::Value > &eval_mapping)
Evaluates the boolean function for a given net, control mapping, and evaluation mapping.
hal::Result< const std::set< std::string > > get_variable_names(const Net *n, const std::map< Net *, BooleanFunction::Value > &ctrl_mapping)
Retrieves the variable names for a given net and control mapping.
hal::Result< std::vector< BooleanFunction > > get_boolean_functions(const std::vector< Net * > nets, const std::map< Net *, BooleanFunction::Value > &ctrl_mapping)
Retrieves a set of boolean functions for a given set of nets and control mapping.
The result of a module identification run containing the candidates.