Skip to content
Open
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
13 changes: 11 additions & 2 deletions include/mockturtle/algorithms/emap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,7 @@ class emap_impl

node_data.est_refs[0] = node_data.est_refs[1] = static_cast<double>( ntk.fanout_size( n ) );
node_data.map_refs[0] = node_data.map_refs[1] = 0;
node_data.required[0] = node_data.required[1] = std::numeric_limits<float>::max();
node_data.required[0] = node_data.required[1] = std::numeric_limits<double>::max();

if ( ntk.is_constant( n ) )
{
Expand Down Expand Up @@ -1618,6 +1618,8 @@ class emap_impl

/* reset mapping */
node_match[index].map_refs[0] = node_match[index].map_refs[1] = 0u;
node_match[index].arrival[0] = node_match[index].arrival[1] = 0.0;
node_match[index].required[0] = node_match[index].required[1] = std::numeric_limits<double>::max();

if ( ntk.is_constant( n ) )
continue;
Expand Down Expand Up @@ -2343,6 +2345,13 @@ class emap_impl
}
}

// guard against unmapped nodes: if neither phase has a best gate, skip
if ( node_data.best_gate[0] == nullptr && node_data.best_gate[1] == nullptr )
{
// no valid mapping stored for this node (e.g., not in cover); skip arrival/area.
continue;
}

uint8_t use_phase = node_data.best_gate[0] != nullptr ? 0 : 1;

/* compute arrival of use_phase */
Expand Down Expand Up @@ -5969,4 +5978,4 @@ void emap_load_mapping( Ntk& ntk )
} );
}

} /* namespace mockturtle */
} /* namespace mockturtle */
47 changes: 41 additions & 6 deletions test/algorithms/emap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <mockturtle/networks/aig.hpp>
#include <mockturtle/networks/block.hpp>
#include <mockturtle/networks/klut.hpp>
#include <mockturtle/networks/xag.hpp>
#include <mockturtle/utils/tech_library.hpp>
#include <mockturtle/views/binding_view.hpp>
#include <mockturtle/views/cell_view.hpp>
Expand Down Expand Up @@ -273,7 +274,7 @@ TEST_CASE( "Emap on ripple carry adder with multi-output gates", "[emap]" )
tech_library<3, classification_type::p_configurations> lib( gates, tps );

aig_network aig;

std::vector<aig_network::signal> a( 8 ), b( 8 );
std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } );
std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } );
Expand Down Expand Up @@ -316,7 +317,7 @@ TEST_CASE( "Emap on ripple carry adder with multi-output cells", "[emap]" )
tech_library<3, classification_type::p_configurations> lib( gates, tps );

aig_network aig;

std::vector<aig_network::signal> a( 8 ), b( 8 );
std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } );
std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } );
Expand Down Expand Up @@ -721,7 +722,7 @@ TEST_CASE( "Emap with global required times", "[emap]" )
tech_library<6> lib( gates );

aig_network aig;

std::vector<aig_network::signal> a( 8 ), b( 8 );
std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } );
std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } );
Expand Down Expand Up @@ -761,7 +762,7 @@ TEST_CASE( "Emap with required times", "[emap]" )
tech_library<6> lib( gates );

aig_network aig;

std::vector<aig_network::signal> a( 8 ), b( 8 );
std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } );
std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } );
Expand Down Expand Up @@ -802,7 +803,7 @@ TEST_CASE( "Emap with required time relaxation", "[emap]" )
tech_library<6> lib( gates );

aig_network aig;

std::vector<aig_network::signal> a( 8 ), b( 8 );
std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } );
std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } );
Expand Down Expand Up @@ -1011,4 +1012,38 @@ TEST_CASE( "Emap on circuit with don't touch cells", "[emap]" )
CHECK( st.area < 11.0f + eps );
CHECK( st.delay > 5.8f - eps );
CHECK( st.delay < 5.8f + eps );
}
}

TEST_CASE( "Failing test case", "[emap]" )
{
std::string const failing_library = "GATE zero 0 O=CONST0;\n"
"GATE one 0 O=CONST1;\n"
"GATE buf 1 O=a; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"
"GATE inv1 1 O=!a; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"
"GATE and2 1 O=a*b; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"
"GATE or2 1 O=a+b; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"
"GATE maj3 1 O=a*b+a*c+b*c; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n";

std::vector<gate> gates;

std::istringstream in( failing_library );
auto result = lorina::read_genlib( in, genlib_reader( gates ) );
CHECK( result == lorina::return_code::success );

tech_library<3> lib( gates );

xag_network xag;
const auto a = xag.create_pi();
const auto b = xag.create_pi();
const auto c = xag.create_pi();

const auto f = xag.create_maj( a, b, c );
xag.create_po( f );

emap_params ps;
emap_stats st;
cell_view<block_network> ntk = emap( xag, lib, ps, &st );

CHECK( ntk.num_pis() == 3u );
CHECK( ntk.num_pos() == 1u );
}
Loading