Skip to content

Commit

Permalink
Adding test cases, small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
aletempiac committed Feb 15, 2024
1 parent 0ac6ed5 commit 5168ba2
Show file tree
Hide file tree
Showing 9 changed files with 923 additions and 784 deletions.
989 changes: 242 additions & 747 deletions experiments/cell_libraries/asap7.genlib

Large diffs are not rendered by default.

260 changes: 260 additions & 0 deletions experiments/cell_libraries/multioutput.genlib

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions experiments/emap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ int main()

/* library to map to technology */
fmt::print( "[i] processing technology library\n" );
std::string library = "asap7";
std::string library = "multioutput";
std::vector<gate> gates;
std::ifstream in( cell_libraries_path( library ) );

Expand Down Expand Up @@ -82,9 +82,9 @@ int main()
emap_params ps;
ps.matching_mode = emap_params::hybrid;
ps.area_oriented_mapping = false;
ps.map_multioutput = false;
ps.map_multioutput = true;
emap_stats st;
cell_view<block_network> res = emap<6>( aig, tech_lib, ps, &st );
cell_view<block_network> res = emap<9>( aig, tech_lib, ps, &st );

names_view res_names{ res };
restore_network_name( aig, res_names );
Expand Down
94 changes: 80 additions & 14 deletions include/mockturtle/utils/struct_library.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@
namespace mockturtle
{

struct struct_library_params
{
/*! \brief Load gates with minimum size only */
bool load_minimum_size_only{ true };

/*! \brief Reports loaded gates */
bool verbose{ false };
};

/*! \brief Library of gates for structural matching
*
* This class creates a technology library from a set
Expand Down Expand Up @@ -82,7 +91,6 @@ namespace mockturtle
mockturtle::struct_library lib( gates );
\endverbatim
*/

template<unsigned NInputs = 9u>
class struct_library
{
Expand Down Expand Up @@ -172,8 +180,9 @@ class struct_library
using map_label_gate = std::unordered_map<uint32_t, supergates_list_t>;

public:
explicit struct_library( std::vector<gate> const& gates )
explicit struct_library( std::vector<gate> const& gates, struct_library_params const& ps = {} )
: _gates( gates ),
_ps( ps ),
_supergates(),
_dsd_map(),
_and_table(),
Expand All @@ -188,9 +197,9 @@ class struct_library
* gate inputs considered for the library creation.
* 0 < min_vars < UINT32_MAX
*/
void construct( uint32_t min_vars = 2u, bool verbose = false )
void construct( uint32_t min_vars = 2u )
{
generate_library( min_vars, verbose );
generate_library( min_vars );
}

/*! \brief Construct the structural library.
Expand Down Expand Up @@ -244,6 +253,15 @@ class struct_library
return nullptr;
}

/*! \brief Returns the number of large gates.
*
* Number of gates with more than 6 inputs.
*/
const uint32_t get_num_large_gates() const
{
return num_large_gates;
}

/*! \brief Print and table.
*
*/
Expand All @@ -260,15 +278,15 @@ class struct_library
}

private:
void generate_library( uint32_t min_vars, bool verbose )
void generate_library( uint32_t min_vars )
{
/* select and load gates */
_supergates.reserve( _gates.size() );
generate_composed_gates();

/* mark dominate gates */
std::vector<bool> skip_gates( _supergates.size(), false );
select_dominated_gates( skip_gates );
filter_gates( skip_gates );

std::vector<uint32_t> indexes( _supergates.size() );
std::iota( indexes.begin(), indexes.end(), 0 );
Expand Down Expand Up @@ -304,17 +322,22 @@ class struct_library
/* ignore gates with reconvergence */
if ( gate_disjoint )
continue;

if ( gate.num_vars > 6 )
{
++num_large_gates;
}

_dsd_map.insert( { gate.function, rule } );
if ( verbose )
if ( _ps.verbose )
{
std::cout << "Dsd:\n";
print_rule( rule, rule[rule.size() - 1] );
}

/* Aig conversion */
auto aig_rule = map_to_aig( rule );
if ( verbose )
if ( _ps.verbose )
{
std::cout << "\nAig:\n";
print_rule( aig_rule, aig_rule[aig_rule.size() - 1] );
Expand All @@ -325,7 +348,7 @@ class struct_library
der_rules.push_back( aig_rule );
std::vector<std::tuple<uint32_t, uint32_t>> depths = { { get_depth( aig_rule, aig_rule[aig_rule[aig_rule.size() - 1].fanin[0].index] ), get_depth( aig_rule, aig_rule[aig_rule[aig_rule.size() - 1].fanin[1].index] ) } };
create_rules_from_dsd( der_rules, aig_rule, aig_rule[aig_rule.size() - 1], depths, true, true );
if ( verbose )
if ( _ps.verbose )
{
std::cout << "\nDerived:\n";
}
Expand Down Expand Up @@ -364,7 +387,7 @@ class struct_library

v.insert( it, sg );

if ( verbose )
if ( _ps.verbose )
{
print_rule( elem, elem[elem.size() - 1] );
std::cout << "\n";
Expand All @@ -379,15 +402,15 @@ class struct_library
}
}

if ( verbose )
if ( _ps.verbose )
{
std::cout << "\n";
std::cout << "And table:\n";
print_and_table();
std::cout << "\n";
}
}
if ( verbose )
if ( _ps.verbose )
std::cout << "\n";
}

Expand Down Expand Up @@ -440,7 +463,33 @@ class struct_library
}
}

void select_dominated_gates( std::vector<bool>& skip_gates )
bool compare_sizes( composed_gate<NInputs> const& s1, composed_gate<NInputs> const& s2 )
{
if ( s1.area < s2.area )
return true;
else if ( s1.area > s2.area )
return false;

/* compute average pin delay */
float s1_delay = 0, s2_delay = 0;
assert( s1.num_vars == s2.num_vars );
for ( uint32_t i = 0; i < s1.num_vars; ++i )
{
s1_delay += s1.tdelay[i];
s2_delay += s2.tdelay[i];
}

if ( s1_delay < s2_delay )
return true;
else if ( s1_delay > s2_delay )
return false;
else if ( s1.root->name < s2.root->name )
return true;

return false;
}

void filter_gates( std::vector<bool>& skip_gates )
{
for ( uint32_t i = 0; i < skip_gates.size() - 1; ++i )
{
Expand All @@ -456,8 +505,22 @@ class struct_library
auto const& ttj = _supergates[j].function;

/* get the same functionality */
if ( tti != ttj )
if ( skip_gates[j] || tti != ttj )
continue;

if ( _ps.load_minimum_size_only )
{
if ( compare_sizes( _supergates[i], _supergates[j] ) )
{
skip_gates[j] = true;
continue;
}
else
{
skip_gates[i] = true;
break;
}
}

/* is i smaller than j */
bool smaller = _supergates[i].area < _supergates[j].area;
Expand Down Expand Up @@ -1459,8 +1522,11 @@ class struct_library

private:
bool gate_disjoint{ false }; /* flag for gate support*/
uint32_t num_large_gates{ 0 };

std::vector<gate> const& _gates; /* collection of gates */
struct_library_params const _ps;

composed_list_t _supergates; /* list of composed_gates */
lib_rule _dsd_map; /* hash map for DSD decomposition of gates */
lib_table _and_table; /* AND table */
Expand Down
8 changes: 6 additions & 2 deletions include/mockturtle/utils/super_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ class super_utils
/* create composed gates */
uint32_t ignored = 0;
uint32_t ignored_id = 0;
uint32_t large_gates = 0;
for ( const auto& g : _gates )
{
std::array<float, NInputs> pin_to_pin_delays{};
Expand All @@ -165,7 +166,10 @@ class super_utils
continue;
}
if ( g.function.num_vars() > truth_table_size )
{
++large_gates;
continue;
}

auto i = 0u;
for ( auto const& pin : g.pins )
Expand Down Expand Up @@ -208,8 +212,8 @@ class super_utils

if ( _ps.verbose )
{
std::cout << fmt::format( "[i] Loading {} simple gates in the library\n", simple_gates_size );
std::cout << fmt::format( "[i] Loading {} multi-output gates in the library\n", _multioutput_gates.size() );
std::cout << fmt::format( "[i] Loading {} simple cells in the library\n", simple_gates_size + large_gates );
std::cout << fmt::format( "[i] Loading {} multi-output cells in the library\n", _multioutput_gates.size() );
}

if ( ignored > 0 )
Expand Down
21 changes: 14 additions & 7 deletions include/mockturtle/utils/tech_library.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class tech_library
_cells( get_standard_cells( _gates ) ),
_super( _gates, _supergates_spec, super_utils_params{ ps.load_multioutput_gates_single, ps.verbose } ),
_use_supergates( false ),
_struct( _gates ),
_struct( _gates, struct_library_params{ ps.load_minimum_size_only, ps.very_verbose } ),
_super_lib(),
_multi_lib(),
_struct_lib()
Expand All @@ -216,7 +216,7 @@ class tech_library

if ( ps.load_large_gates )
{
_struct.construct( 2, _ps.very_verbose );
_struct.construct( 2 );
}
}

Expand All @@ -227,7 +227,7 @@ class tech_library
_cells( get_standard_cells( _gates ) ),
_super( _gates, _supergates_spec, super_utils_params{ ps.load_multioutput_gates_single, ps.verbose } ),
_use_supergates( true ),
_struct( _gates ),
_struct( _gates, struct_library_params{ ps.load_minimum_size_only, ps.very_verbose } ),
_super_lib(),
_multi_lib(),
_struct_lib()
Expand All @@ -241,7 +241,7 @@ class tech_library

if ( ps.load_large_gates )
{
_struct.construct( 2, _ps.very_verbose );
_struct.construct( 2 );
}
}

Expand Down Expand Up @@ -359,6 +359,12 @@ class tech_library
return _struct.get_struct_library().size();
}

/*! \brief Returns the number of gates for structural matching with more than 6 inputs. */
const uint32_t num_structural_large_gates() const
{
return _struct.get_struct_library().size();
}

private:
void generate_library()
{
Expand Down Expand Up @@ -1086,7 +1092,7 @@ class tech_library
auto const& ttj = supergates[j].function;

/* get the same functionality */
if ( tti != ttj )
if ( skip_gates[j] || tti != ttj )
continue;

if ( _ps.load_minimum_size_only )
Expand All @@ -1104,7 +1110,7 @@ class tech_library
}

/* is i smaller than j */
bool smaller = supergates[i].area < supergates[j].area;
bool smaller = supergates[i].area <= supergates[j].area;

/* is i faster for every pin */
bool faster = true;
Expand All @@ -1121,14 +1127,15 @@ class tech_library
}

/* is j faster for every pin */
smaller = supergates[i].area >= supergates[j].area;
faster = true;
for ( uint32_t k = 0; k < tti.num_vars(); ++k )
{
if ( supergates[j].tdelay[k] > supergates[i].tdelay[k] )
faster = false;
}

if ( !smaller && faster )
if ( smaller && faster )
{
skip_gates[i] = true;
break;
Expand Down
Loading

0 comments on commit 5168ba2

Please sign in to comment.