23
23
* OTHER DEALINGS IN THE SOFTWARE.
24
24
*/
25
25
#include " experiments.hpp"
26
- #include < lorina/aiger.hpp>
27
26
#include < lorina/diagnostics.hpp>
28
27
#include < lorina/verilog.hpp>
29
28
#include < mockturtle/algorithms/aqfp/buffer_insertion.hpp>
30
29
#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>
35
30
#include < mockturtle/io/verilog_reader.hpp>
36
31
#include < mockturtle/io/write_verilog.hpp>
37
- #include < mockturtle/networks/aig .hpp>
32
+ #include < mockturtle/io/write_dot .hpp>
38
33
#include < mockturtle/networks/buffered.hpp>
39
34
#include < mockturtle/networks/mig.hpp>
40
35
#include < mockturtle/utils/name_utils.hpp>
44
39
45
40
#include < iostream>
46
41
42
+ using namespace mockturtle ;
43
+
47
44
int main ( int argc, char * argv[] )
48
45
{
49
46
std::string run_only_one = " " ;
@@ -59,9 +56,9 @@ int main( int argc, char* argv[] )
59
56
/* NOTE 2: Please clone this repository: https://github.com/lsils/SCE-benchmarks
60
57
* And put in the following string the relative path from your build path to SCE-benchmarks/ISCAS/strashed/
61
58
*/
62
- std::string benchmark_path = " ../../SCE-benchmarks/ISCAS/strashed/" ;
59
+ // std::string benchmark_path = "../../SCE-benchmarks/ISCAS/strashed/";
63
60
// 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/" ;
65
62
static const std::string benchmarks_iscas[] = {
66
63
" adder1" , " adder8" , " mult8" , " counter16" , " counter32" , " counter64" , " counter128" ,
67
64
" c17" , " c432" , " c499" , " c880" , " c1355" , " c1908" , " c2670" , " c3540" , " c5315" , " c6288" , " c7552" ,
@@ -71,33 +68,30 @@ int main( int argc, char* argv[] )
71
68
" m3" , " max512" , " misex3" , " mlp4" , " prom2" , " sqr6" , " x1dn" };
72
69
const auto benchmarks_epfl = experiments::epfl_benchmarks ();
73
70
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" );
76
73
77
74
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 };
93
89
94
90
uint32_t total_buffers{ 0 }, total_depth{ 0 };
95
- for ( auto benchmark : benchmarks_iscas )
91
+ for ( auto benchmark : benchmarks_epfl )
96
92
{
97
93
if ( run_only_one != " " && benchmark != run_only_one )
98
94
continue ;
99
- if ( benchmark == " hyp" && run_only_one != " hyp" )
100
- continue ;
101
95
std::cout << " \n [i] processing " << benchmark << " \n " ;
102
96
103
97
names_view<mig_network> ntk;
@@ -114,29 +108,58 @@ int main( int argc, char* argv[] )
114
108
stopwatch<>::duration t{ 0 };
115
109
buffer_insertion aqfp ( ntk, ps );
116
110
buffered_mig_network bufntk;
111
+ std::vector<uint32_t > pi_levels ( ntk.num_pis () );
117
112
uint32_t num_buffers = call_with_stopwatch ( t, [&]() {
118
- return aqfp.dry_run ( );
113
+ return aqfp.run ( bufntk, pi_levels );
119
114
} );
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 );
122
119
123
120
// names_view named_bufntk{bufntk};
124
121
// restore_pio_names_by_order( ntk, named_bufntk );
125
122
// write_verilog( named_bufntk, benchmark_path + "../best_insertion/" + benchmark + "_buffered.v" );
126
123
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
129
130
130
131
total_buffers += num_buffers;
131
- total_depth += d_buf .depth ();
132
+ total_depth += aqfp .depth ();
132
133
133
134
uint32_t max_fanout{ 0 };
134
135
ntk.foreach_node ( [&]( auto const & n ) {
135
136
if ( !ntk.is_constant ( n ) )
136
137
max_fanout = std::max ( max_fanout, ntk.fanout_size ( n ) );
137
138
} );
138
139
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 );
140
163
}
141
164
142
165
exp.save ();
0 commit comments