Skip to content

Commit fac58aa

Browse files
authored
Realistic AQFP technology constraints (#614)
* missing includes * realistic assumptions & updated verification * modifications from unmerged PR #594 * update basic ASAP ALAP scheduling * update counting & dump * update chunk movement * compile & debug * debug chunk movement * clean up depth-optimal scheduling * visualization * move PIs and POs, debug * remove buffer chains; clean up * cleanup * fix merging mistakes * fix retiming * fix tests * delete deprecated verification method * fix experiments
1 parent 975cd50 commit fac58aa

16 files changed

+1326
-1448
lines changed

experiments/aqfp_flow_aspdac.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,18 @@ int main()
9191
/* convert MIG network to AQFP */
9292
aqfp_network aqfp = cleanup_dangling<mig_network, aqfp_network>( mig_opt );
9393

94+
aqfp_assumptions_legacy aqfp_ps;
95+
aqfp_ps.splitter_capacity = 4;
96+
aqfp_ps.branch_pis = true;
97+
aqfp_ps.balance_pis = true;
98+
aqfp_ps.balance_pos = true;
99+
94100
/* Buffer insertion params */
95101
buffer_insertion_params buf_ps;
96102
buf_ps.scheduling = buffer_insertion_params::better_depth;
97103
buf_ps.optimization_effort = buffer_insertion_params::none;
98104
buf_ps.max_chunk_size = 100;
99-
buf_ps.assume.splitter_capacity = 4u;
100-
buf_ps.assume.branch_pis = true;
101-
buf_ps.assume.balance_pis = true;
102-
buf_ps.assume.balance_pos = true;
105+
buf_ps.assume = legacy_to_realistic( aqfp_ps );
103106

104107
/* buffer insertion */
105108
stopwatch<>::duration time_insertion{ 0 };
@@ -110,12 +113,6 @@ int main()
110113
uint32_t jj_depth = buf_inst.depth();
111114
total_runtime += to_seconds( time_insertion );
112115

113-
aqfp_assumptions aqfp_ps;
114-
aqfp_ps.splitter_capacity = buf_ps.assume.splitter_capacity;
115-
aqfp_ps.branch_pis = buf_ps.assume.branch_pis;
116-
aqfp_ps.balance_pis = buf_ps.assume.balance_pis;
117-
aqfp_ps.balance_pos = buf_ps.assume.balance_pos;
118-
119116
/* retiming params */
120117
aqfp_retiming_params aps;
121118
aps.aqfp_assumptions_ps = aqfp_ps;
@@ -169,7 +166,10 @@ int main()
169166

170167
/* cec */
171168
auto cec = abc_cec( buffered_aqfp, benchmark );
172-
cec &= verify_aqfp_buffer( buffered_aqfp, aqfp_ps );
169+
std::vector<uint32_t> pi_levels;
170+
for ( auto i = 0u; i < buffered_aqfp.num_pis(); ++i )
171+
pi_levels.emplace_back( 0 );
172+
cec &= verify_aqfp_buffer( buffered_aqfp, aqfp_ps, pi_levels );
173173

174174
/* compute final JJ cost */
175175
uint32_t num_jjs_ret = 0;

experiments/aqfp_flow_date.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,8 @@ int main( int argc, char** argv )
401401
buf_ps.optimization_effort = buffer_insertion_params::until_sat;
402402
buf_ps.max_chunk_size = std::numeric_limits<uint32_t>::max();
403403
buf_ps.assume.splitter_capacity = 4u;
404-
buf_ps.assume.branch_pis = false;
405-
buf_ps.assume.balance_pis = false;
406-
buf_ps.assume.balance_pos = true;
404+
buf_ps.assume.ci_capacity = std::numeric_limits<uint32_t>::max();
405+
buf_ps.assume.balance_cios = true;
407406
buffer_insertion buf_inst( aqfp, buf_ps );
408407
uint32_t num_bufs = buf_inst.dry_run();
409408
uint32_t num_jjs = opt_stats.maj3_after_exact * 6 + opt_stats.maj5_after_exact * 10 + num_bufs * 2;

experiments/buffer_insertion.cpp

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,13 @@
2323
* OTHER DEALINGS IN THE SOFTWARE.
2424
*/
2525
#include "experiments.hpp"
26-
#include <lorina/aiger.hpp>
2726
#include <lorina/diagnostics.hpp>
2827
#include <lorina/verilog.hpp>
2928
#include <mockturtle/algorithms/aqfp/buffer_insertion.hpp>
3029
#include <mockturtle/algorithms/aqfp/buffer_verification.hpp>
31-
#include <mockturtle/algorithms/cleanup.hpp>
32-
#include <mockturtle/algorithms/mapper.hpp>
33-
#include <mockturtle/algorithms/node_resynthesis/mig_npn.hpp>
34-
#include <mockturtle/io/aiger_reader.hpp>
3530
#include <mockturtle/io/verilog_reader.hpp>
3631
#include <mockturtle/io/write_verilog.hpp>
37-
#include <mockturtle/networks/aig.hpp>
32+
#include <mockturtle/io/write_dot.hpp>
3833
#include <mockturtle/networks/buffered.hpp>
3934
#include <mockturtle/networks/mig.hpp>
4035
#include <mockturtle/utils/name_utils.hpp>
@@ -44,6 +39,8 @@
4439

4540
#include <iostream>
4641

42+
using namespace mockturtle;
43+
4744
int main( int argc, char* argv[] )
4845
{
4946
std::string run_only_one = "";
@@ -59,9 +56,9 @@ int main( int argc, char* argv[] )
5956
/* NOTE 2: Please clone this repository: https://github.com/lsils/SCE-benchmarks
6057
* And put in the following string the relative path from your build path to SCE-benchmarks/ISCAS/strashed/
6158
*/
62-
std::string benchmark_path = "../../SCE-benchmarks/ISCAS/strashed/";
59+
// std::string benchmark_path = "../../SCE-benchmarks/ISCAS/strashed/";
6360
// std::string benchmark_path = "../../SCE-benchmarks/MCNC/original/";
64-
// std::string benchmark_path = "../../SCE-benchmarks/EPFL/MIGs/";
61+
std::string benchmark_path = "../../SCE-benchmarks/EPFL/MIGs/";
6562
static const std::string benchmarks_iscas[] = {
6663
"adder1", "adder8", "mult8", "counter16", "counter32", "counter64", "counter128",
6764
"c17", "c432", "c499", "c880", "c1355", "c1908", "c2670", "c3540", "c5315", "c6288", "c7552",
@@ -71,33 +68,30 @@ int main( int argc, char* argv[] )
7168
"m3", "max512", "misex3", "mlp4", "prom2", "sqr6", "x1dn" };
7269
const auto benchmarks_epfl = experiments::epfl_benchmarks();
7370

74-
experiment<std::string, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, float, bool>
75-
exp( "buffer_insertion", "benchmark", "#gates", "depth", "max FO", "#buffers", "opt. #JJs", "depth_JJ", "runtime", "verified" );
71+
experiment<std::string, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, float, bool>
72+
exp( "buffer_insertion", "benchmark", "#gates", "#buffers", "#buff real", "max phase skip", "depth_JJ", "runtime", "verified" );
7673

7774
buffer_insertion_params ps;
78-
ps.scheduling = buffer_insertion_params::better;
79-
ps.optimization_effort = buffer_insertion_params::until_sat;
80-
ps.assume.splitter_capacity = 4u;
81-
ps.assume.branch_pis = true;
82-
ps.assume.balance_pis = true;
83-
ps.assume.balance_pos = true;
84-
85-
if ( argc == 3 ) // example syntax: ./buffer_insertion 4 111
86-
{
87-
ps.assume.splitter_capacity = std::stoi( argv[1] );
88-
uint32_t arg = std::stoi( argv[2] );
89-
ps.assume.branch_pis = arg >= 100;
90-
ps.assume.balance_pis = ( arg % 100 ) >= 10;
91-
ps.assume.balance_pos = arg % 10;
92-
}
75+
ps.scheduling = buffer_insertion_params::better_depth;
76+
ps.optimization_effort = buffer_insertion_params::none;
77+
ps.max_chunk_size = 10000;
78+
79+
// ASP-DAC etc. SoTA works
80+
//ps.assume.num_phases = 1;
81+
//ps.assume.ci_phases = {0u};
82+
//ps.assume.ci_capacity = 1;
83+
//ps.assume.splitter_capacity = 4;
84+
//ps.assume.balance_cios = true;
85+
86+
// best possible relaxation
87+
ps.assume.ci_capacity = 2;
88+
ps.assume.ci_phases = { 3u, 4u, 5u };
9389

9490
uint32_t total_buffers{ 0 }, total_depth{ 0 };
95-
for ( auto benchmark : benchmarks_iscas )
91+
for ( auto benchmark : benchmarks_epfl )
9692
{
9793
if ( run_only_one != "" && benchmark != run_only_one )
9894
continue;
99-
if ( benchmark == "hyp" && run_only_one != "hyp" )
100-
continue;
10195
std::cout << "\n[i] processing " << benchmark << "\n";
10296

10397
names_view<mig_network> ntk;
@@ -114,29 +108,58 @@ int main( int argc, char* argv[] )
114108
stopwatch<>::duration t{ 0 };
115109
buffer_insertion aqfp( ntk, ps );
116110
buffered_mig_network bufntk;
111+
std::vector<uint32_t> pi_levels( ntk.num_pis() );
117112
uint32_t num_buffers = call_with_stopwatch( t, [&]() {
118-
return aqfp.dry_run();
113+
return aqfp.run( bufntk, pi_levels );
119114
} );
120-
aqfp.dump_buffered_network( bufntk );
121-
bool verified = verify_aqfp_buffer( bufntk, ps.assume );
115+
bool verified = verify_aqfp_buffer( bufntk, ps.assume, pi_levels );
116+
auto const levels = schedule_buffered_network_with_PI_levels( bufntk, pi_levels );
117+
118+
uint32_t max_chain = aqfp.remove_buffer_chains( bufntk );
122119

123120
// names_view named_bufntk{bufntk};
124121
// restore_pio_names_by_order( ntk, named_bufntk );
125122
// write_verilog( named_bufntk, benchmark_path + "../best_insertion/" + benchmark + "_buffered.v" );
126123

127-
depth_view d{ ntk };
128-
depth_view d_buf{ bufntk };
124+
#if 0
125+
depth_view<buffered_mig_network> depth_buffered( bufntk );
126+
depth_buffered.foreach_node( [&]( auto n ){ depth_buffered.set_level( n, levels[n] ); } );
127+
write_dot( depth_buffered, benchmark + ".dot" );
128+
std::system( fmt::format( "dot -Tpng -o {0}.png {0}.dot; rm {0}.dot; open {0}.png", benchmark ).c_str() );
129+
#endif
129130

130131
total_buffers += num_buffers;
131-
total_depth += d_buf.depth();
132+
total_depth += aqfp.depth();
132133

133134
uint32_t max_fanout{ 0 };
134135
ntk.foreach_node( [&]( auto const& n ) {
135136
if ( !ntk.is_constant( n ) )
136137
max_fanout = std::max( max_fanout, ntk.fanout_size( n ) );
137138
} );
138139

139-
exp( benchmark, ntk.num_gates(), d.depth(), max_fanout, num_buffers, ntk.num_gates() * 6 + num_buffers * 2, d_buf.depth(), to_seconds( t ), verified );
140+
uint32_t num_buffers_real{0}, max_phase_skip{0};
141+
142+
bufntk.foreach_node( [&]( auto n ){
143+
if ( bufntk.is_buf( n ) && !bufntk.is_dead( n ) )
144+
num_buffers_real++;
145+
});
146+
max_phase_skip = max_chain;
147+
for ( auto pil : pi_levels )
148+
{
149+
if ( pil % 4 == 1 )
150+
max_phase_skip = std::max( max_phase_skip, pil - 5 );
151+
else if ( pil % 4 == 0 )
152+
max_phase_skip = std::max( max_phase_skip, pil - 4 );
153+
else if ( pil % 4 == 3 )
154+
max_phase_skip = std::max( max_phase_skip, pil - 3 );
155+
else
156+
fmt::print( "strange pi level {}\n", pil );
157+
}
158+
bufntk.foreach_po( [&]( auto f ){
159+
max_phase_skip = std::max( max_phase_skip, aqfp.depth() - levels[f] );
160+
});
161+
162+
exp( benchmark, ntk.num_gates(), num_buffers, num_buffers_real, max_phase_skip, aqfp.depth(), to_seconds( t ), verified );
140163
}
141164

142165
exp.save();

experiments/buffer_insertion_iwls.cpp

Lines changed: 0 additions & 101 deletions
This file was deleted.

0 commit comments

Comments
 (0)