Page MenuHomePhorge

cover_to_bbdd.hpp
No OneTemporary

Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None

cover_to_bbdd.hpp

// Copyright 2025 Oliver Theimer
#pragma once
#include <climits>
#include <cstdint>
#include "../bbdd/include/bbdd.hpp"
#include "../bbdd/include/bbdd_node.hpp"
#include "../bbdd/include/unique_table.hpp"
#include "mockturtle/traits.hpp"
#include "util.hpp"
#define LEFT_CHILD(node) node.children[0].index
#define RIGHT_CHILD(node) node.children[1].index
#define CUBE(node) ntk._storage->data.covers[node.data[1].h1]
int nodes_visited;
using namespace mockturtle;
/**
* @brief recursively creates a bbdd based on the given network
*
* @tparam Ntk template for which network type is used
* @param table unique table in which the bbdd should be stored in
* @param ntk input network data structure that should be converted
* @param node_i starting node from which onwards the bbdd should be created,
* will be used for the recursion
* @param output_completed statistics that are used in the recursion to properly
* show the progress bar
* @return root node of the created bbdd
*/
template <typename Ntk>
static bbdd_node_t *create_bbdd(Unique_table *table, Ntk &ntk,
const auto &node_i, int output_completed) {
static_assert(has_is_ci_v<Ntk>, "Ntk does not implement the is_ci method");
const auto &node = ntk._storage->nodes[node_i];
bbdd_node_t *f, *g, *result;
bbdd_op_t op = Util::cube_to_bbdd_op(CUBE(node));
if (ntk.visited(node_i)) {
return table->get_node_p(ntk.visited(node_i));
}
#ifdef DEBUG_COVER
printf("[INFO] CREATE: node %d with op %s\n", node_i, bbdd_op_s[op].c_str());
#endif
if (node.children.size() != 2 && node.children.size() != 1) {
if (node_i == 1 || node_i == 0) {
return table->get_node_p(node_i);
}
#ifdef DEBUG_COVER
std::cout << node_i << ": " << node.children.size() << " with "
<< bbdd_op_s[op].c_str() << "\n";
#endif
assert(ntk.is_ci(node_i));
assert(node_i < pow(2, 31));
assert(node_i - 2 < ntk._storage->inputs.size());
return table->insert_node({{(node_index_t)node_i, INT_MAX}, 0, 1});
}
assert(node.children.size() == 2 || node.children.size() == 1);
// all the logic gates except buf and inv
if (node.children.size() == 2) {
node_index_t f_i = LEFT_CHILD(node), g_i = RIGHT_CHILD(node);
if (ntk.is_ci(LEFT_CHILD(node)) && ntk.is_ci(RIGHT_CHILD(node))) {
result = base_case_two_inputs(table, f_i, g_i, op);
#ifdef DEBUG_COVER
printf("[INFO] CREATE: two input case %d: %d %s %d\n", result->index, f_i,
bbdd_op_s[op].c_str(), g_i);
#endif
return result;
}
f = create_bbdd(table, ntk, LEFT_CHILD(node), output_completed);
g = create_bbdd(table, ntk, RIGHT_CHILD(node), output_completed);
result = merge_bbdds(table, f, g, op);
#ifdef DEBUG_COVER
std::cout << "[INFO] CREATE: merging " << result->index << ": " << f->index
<< " " << bbdd_op_s[op] << " " << g->index << "\n";
dump_node(g);
#endif
ntk.set_visited(node_i, result->index);
Util::show_progress_bar(
{{"Output", {output_completed, ntk._storage->outputs.size()}},
{"Nodes", {++nodes_visited, ntk._storage->nodes.size()}}},
50);
return result;
} else {
// buf and inverter nodes
f = create_bbdd(table, ntk, LEFT_CHILD(node), output_completed);
if (op == bbdd_inv) {
result = negate_recursive(table, f);
ntk.set_visited(node_i, result->index);
Util::show_progress_bar(
{{"Output", {output_completed, ntk._storage->outputs.size()}},
{"Nodes", {++nodes_visited, ntk._storage->nodes.size()}}},
50);
return result;
}
ntk.set_visited(node_i, f->index);
Util::show_progress_bar(
{{"Output", {output_completed, ntk._storage->outputs.size()}},
{"Nodes", {++nodes_visited, ntk._storage->nodes.size()}}},
50);
return f;
}
}
/**
* @brief main conversion function that should be used as an interface, it
* interact with the recursive function, instantiates the progress bar and
* registers output in the unique table
*
* @tparam Ntk template of network type that should be used
* @param table unique table in which the data structure should be stores
* @param ntk data strucutre that stores the input network type which should be
* converted
* @param use_height if true the height of the bbdd is used as the target
* function for the sifting algorithm, otherwise the number of nodes i used
* @param sifting_repetitions indicates how often the sifting algorithm should be repeated at the end of the conversion
*/
template <typename Ntk>
void cover_to_bbdd(Unique_table *table, Ntk &ntk, bool use_height,
int sifting_repetitions) {
static_assert(has_foreach_co_v<Ntk>,
"Ntk does not implement the foreach_pi method");
static_assert(has_get_node_v<Ntk>,
"Ntk does not implement the get_node method");
static_assert(has_set_visited_v<Ntk>,
"Ntk does not implement the set_visited method");
static_assert(has_visited_v<Ntk>,
"Ntk does not implement the set_visited method");
int index = ntk._storage->inputs.size() + 2;
int output_completed = 0;
nodes_visited = 0;
Util::show_progress_bar(
{{"Output", {output_completed, ntk._storage->outputs.size()}},
{"Nodes", {++nodes_visited, ntk._storage->nodes.size()}}},
50);
ntk.foreach_co([ntk, &table, &index, &output_completed,
sifting_repetitions](const auto &node_i) {
const auto &node = ntk.get_node(node_i);
auto &n = ntk._storage->nodes[node_i];
#ifdef DEBUG_COVER
std::cout << "output with node_i: " << node_i << " and n->index: " << " : "
<< n.children.size() << "\n";
#endif
bbdd_node_t *output =
add_ref(create_bbdd(table, ntk, node, output_completed));
Util::show_progress_bar(
{{"Output", {++output_completed, ntk._storage->outputs.size()}},
{"Nodes", {++nodes_visited, ntk._storage->nodes.size()}}},
50);
table->add_output(ntk.get_signal_name(index), output);
index++;
});
for (int i = 0; i < sifting_repetitions; i++) {
if (table->get_total_height() < 30) {
if (use_height) {
sift(table, &Unique_table::get_total_height, table);
} else {
sift(table, &Unique_table::get_total_number_nodes, table);
}
}
}
}

File Metadata

Mime Type
text/x-c++
Expires
Tue, Oct 27, 8:12 PM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
407775
Default Alt Text
cover_to_bbdd.hpp (6 KB)

Event Timeline