Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/mockturtle/mockturtle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
#include "mockturtle/networks/mig.hpp"
#include "mockturtle/properties/migcost.hpp"
#include "mockturtle/properties/mccost.hpp"
#include "mockturtle/properties/xmgcost.hpp"
#include "mockturtle/mockturtle.hpp"
#include "mockturtle/generators/sorting.hpp"
#include "mockturtle/generators/arithmetic.hpp"
Expand All @@ -132,4 +133,4 @@
#include "mockturtle/views/fanout_view.hpp"
#include "mockturtle/views/cut_view.hpp"
#include "mockturtle/views/depth_view.hpp"
#include "mockturtle/views/aqfp_view.hpp"
#include "mockturtle/views/aqfp_view.hpp"
2 changes: 1 addition & 1 deletion include/mockturtle/properties/migcost.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,4 @@ uint32_t num_dangling_inputs( Ntk const& ntk )
return costs;
}

} // namespace mockturtle
} // namespace mockturtle
151 changes: 46 additions & 105 deletions include/mockturtle/properties/xmgcost.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,156 +33,97 @@

#pragma once

#include <cstdint>
#include <unordered_set>

#include "../traits.hpp"

#include <fmt/format.h>

namespace mockturtle
{

/*! \brief Counts number of inverters.
*
* This number counts all nodes that need to be inverted. Multiple signals
* with complements to the same node are counted once.
*
* \param ntk Network
*/

struct xmg_cost_params
struct xmg_gate_stats
{
/*! \brief Total number of XOR3 . */
/*! \brief Total number of XOR3 gates (structurally). */
uint32_t total_xor3{0};

/*! \brief Actual number of XOR3 with three number of inputs. */
uint32_t actual_xor3{0};
/*! \brief Number of XOR3 (functionally). */
uint32_t xor3{0};

/*! \brief Actual number of XOR2. */
uint32_t actual_xor2{0};
/*! \brief Number of XOR2 (functionally). */
uint32_t xor2{0};

/*! \brief Total number of Majority. */
/*! \brief Total number of MAJ gates (structurally). */
uint32_t total_maj{0};

/*! \brief Actual number of Majority with three inputs. */
uint32_t actual_maj{0};
/*! \brief Number of MAJ gates. */
uint32_t maj{0};

/*! \brief Remaining number of Maj where one of the inputs is a constant. */
uint32_t remaining_maj{0};
/*! \brief Number of AND/OR gates. */
uint32_t and_or{0};

void report() const
{
fmt::print( "#total_xor3 = {} / #total_maj = {} / #xor2 = {} / #xor3 = {} / #actual_maj = {} / #remaining_maj = {} \n", total_xor3, total_maj, actual_xor2, actual_xor3, actual_maj, remaining_maj );
fmt::print( "XOR3: {} = {} XOR3 + {} XOR2 / MAJ: {} = {} MAJ3 + {} AND/OR\n",
total_xor3, xor2, xor3, total_maj, maj, and_or );
}
};

template<class Ntk>
uint32_t num_inverters( Ntk const& ntk )
{
static_assert( is_network_type_v<Ntk>, "Ntk is not a network type" );
static_assert( has_foreach_gate_v<Ntk>, "Ntk does not implement the foreach_gate method" );
static_assert( has_foreach_fanin_v<Ntk>, "Ntk does not implement the foreach_fanin method" );
static_assert( has_foreach_po_v<Ntk>, "Ntk does not implement the foreach_po method" );
static_assert( has_is_complemented_v<Ntk>, "Ntk does not implement the is_complemented method" );
static_assert( has_get_node_v<Ntk>, "Ntk does not implement the get_node method" );

std::unordered_set<node<Ntk>> inverted_nodes;

ntk.foreach_gate( [&]( auto const& n ) {
ntk.foreach_fanin( n, [&]( auto const& f ) {
if ( ntk.is_complemented( f ) )
{
inverted_nodes.insert( ntk.get_node( f ) );
}
} );
} );

ntk.foreach_po( [&]( auto const& f ) {
if ( ntk.is_complemented( f ) )
{
inverted_nodes.insert( ntk.get_node( f ) );
}
} );

return inverted_nodes.size();
}

/*! \brief Counts fanins which are primary inputs.
/*! \brief Profile gates
*
* Counts the numbers of MAJ and XOR nodes in an XMG.
*
* \param ntk Network
* \param stats Statistics
*/

template<class Ntk>
uint32_t num_dangling_inputs( Ntk const& ntk )
{
static_assert( is_network_type_v<Ntk>, "Ntk is not a network type" );
static_assert( has_foreach_gate_v<Ntk>, "Ntk does not implement the foreach_gate method" );
static_assert( has_foreach_fanin_v<Ntk>, "Ntk does not implement the foreach_fanin method" );
static_assert( has_foreach_po_v<Ntk>, "Ntk does not implement the foreach_po method" );
static_assert( has_is_pi_v<Ntk>, "Ntk does not implement the is_pi method" );
static_assert( has_get_node_v<Ntk>, "Ntk does not implement the get_node method" );

uint32_t costs{0u};

ntk.foreach_gate( [&]( auto const& n ) {
ntk.foreach_fanin( n, [&]( auto const& f ) {
if ( ntk.is_pi( ntk.get_node( f ) ) )
{
costs++;
}
} );
} );

ntk.foreach_po( [&]( auto const& f ) {
if ( ntk.is_pi( ntk.get_node( f ) ) )
{
costs++;
}
} );

return costs;
}

template<class Ntk>
void num_gate_profile( Ntk const& ntk, xmg_cost_params& xmg_ps )
void xmg_profile_gates( Ntk const& ntk, xmg_gate_stats& stats )
{
static_assert( is_network_type_v<Ntk>, "Ntk is not a network type" );
static_assert( has_foreach_gate_v<Ntk>, "Ntk does not implement the foreach_gate method" );
static_assert( has_foreach_fanin_v<Ntk>, "Ntk does not implement the foreach_fanin method" );
static_assert( has_foreach_po_v<Ntk>, "Ntk does not implement the foreach_po method" );
static_assert( has_is_pi_v<Ntk>, "Ntk does not implement the is_pi method" );
static_assert( has_get_node_v<Ntk>, "Ntk does not implement the get_node method" );
static_assert( has_is_constant_v<Ntk>, "Ntk does not implement the is_constant method" );
static_assert( has_is_maj_v<Ntk>, "Ntk does not implement the is_maj method" );
static_assert( has_is_xor3_v<Ntk>, "Ntk does not implement the is_xor3 method" );

ntk.foreach_gate( [&]( auto const& node ) {
bool has_const = false;
bool has_const_fanin = false;

/* Check if all of the fanin nodes are not constant */
ntk.foreach_fanin( node, [&]( auto const& f ) {
// Check whether all of the fanin node are not constant
if ( ntk.is_constant( ntk.get_node( f ) ) )
{
has_const = true;
has_const_fanin = true;
return false;
}
else
return true;
} ); // Foreach_fanin
return true;
} );

if ( ntk.is_maj( node ) )
{
if ( has_const )
++xmg_ps.remaining_maj;
if ( has_const_fanin )
{
++stats.and_or;
}
else
++xmg_ps.actual_maj;
{
++stats.maj;
}
}
else if ( ntk.is_xor3( node ) )
{
if ( has_const )
++xmg_ps.actual_xor2;
if ( has_const_fanin )
{
++stats.xor2;
}
else
++xmg_ps.actual_xor3;
{
++stats.xor3;
}
}
} );

xmg_ps.total_xor3 = xmg_ps.actual_xor2 + xmg_ps.actual_xor3;
xmg_ps.total_maj = xmg_ps.remaining_maj + xmg_ps.actual_maj;
stats.total_xor3 = stats.xor2 + stats.xor3;
stats.total_maj = stats.and_or + stats.maj;
}

} // namespace mockturtle
} // namespace mockturtle
30 changes: 30 additions & 0 deletions test/properties/xmgcost.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <catch.hpp>

#include <mockturtle/networks/xmg.hpp>
#include <mockturtle/properties/xmgcost.hpp>

using namespace mockturtle;

TEST_CASE( "profile gates in XMG", "[xmgcost]" )
{
xmg_network xmg;
const auto a = xmg.create_pi();
const auto b = xmg.create_pi();
const auto c = xmg.create_pi();
const auto f1 = xmg.create_xor3( a, b, c );
const auto f2 = xmg.create_xor3( a, b, xmg.get_constant( 0 ) );
const auto f3 = xmg.create_and( a, b );
const auto f4 = xmg.create_maj( f1, f2, f3 );
xmg.create_po( f4 );

xmg_gate_stats stats;
xmg_profile_gates( xmg, stats );
CHECK( stats.total_xor3 == 2u );
CHECK( stats.xor3 == 1u );
CHECK( stats.xor2 == 1u );

CHECK( stats.total_maj == 2u );
CHECK( stats.maj == 1u );
CHECK( stats.and_or == 1u );
}