# ABC scripts
# Adapted from:
# https://github.com/The-OpenROAD-Project/OpenLane/blob/23b9177502c19ef749836aef8f4ee06416961a18/scripts/synth.tcl

# OpenLANE defaults
# TODO: we can introduce a flag to allow the user to choose between these "fine
# tuning" variations
set buffering 1
set sizing 0

set abc_rs_K    "resub,-K,"
set abc_rs      "resub"
set abc_rsz     "resub,-z"
set abc_rw_K    "rewrite,-K,"
set abc_rw      "rewrite"
set abc_rwz     "rewrite,-z"
set abc_rf      "refactor"
set abc_rfz     "refactor,-z"
set abc_b       "balance"

set abc_resyn2        "${abc_b}; ${abc_rw}; ${abc_rf}; ${abc_b}; ${abc_rw}; ${abc_rwz}; ${abc_b}; ${abc_rfz}; ${abc_rwz}; ${abc_b}"
set abc_share         "strash; multi,-m; ${abc_resyn2}"
set abc_resyn2a       "${abc_b};${abc_rw};${abc_b};${abc_rw};${abc_rwz};${abc_b};${abc_rwz};${abc_b}"
set abc_resyn3        "balance;resub;resub,-K,6;balance;resub,-z;resub,-z,-K,6;balance;resub,-z,-K,5;balance"
set abc_resyn2rs      "${abc_b};${abc_rs_K},6;${abc_rw};${abc_rs_K},6,-N,2;${abc_rf};${abc_rs_K},8;${abc_rw};${abc_rs_K},10;${abc_rwz};${abc_rs_K},10,-N,2;${abc_b},${abc_rs_K},12;${abc_rfz};${abc_rs_K},12,-N,2;${abc_rwz};${abc_b}"

set abc_choice        "fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
set abc_choice2      "fraig_store; balance; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"

set abc_map_old_cnt			"map,-p,-a,-B,0.2,-A,0.9,-M,0"
set abc_map_old_dly         "map,-p,-B,0.2,-A,0.9,-M,0"
set abc_retime_area         "retime,-D,{D},-M,5"
set abc_retime_dly          "retime,-D,{D},-M,6"
set abc_map_new_area        "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"

set abc_area_recovery_1       "${abc_choice}; map;"
set abc_area_recovery_2       "${abc_choice2}; map;"

set map_old_cnt			    "map,-p,-a,-B,0.2,-A,0.9,-M,0"
set map_old_dly			    "map,-p,-B,0.2,-A,0.9,-M,0"
set abc_retime_area   	"retime,-D,{D},-M,5"
set abc_retime_dly    	"retime,-D,{D},-M,6"
set abc_map_new_area  	"amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"

if {$buffering==1} {
	# TODO: reintroduce the arguments to buffer: max_FO is a
	# synthesis-specific max fanout argument, while max_Tran defaults to
	# 0.1x the clock period. However, since the Yosys default script uses the default
	# arguments to buffer, this should be safe to skip for now.

	# set abc_fine_tune		"buffer,-N,${max_FO},-S,${max_Tran};upsize,{D};dnsize,{D}"
	set abc_fine_tune		"buffer;upsize,{D};dnsize,{D}"
} elseif {$sizing} {
	set abc_fine_tune       "upsize,{D};dnsize,{D}"
} else {
	set abc_fine_tune       ""
}

# TODO: all of these scripts used to begin with a call to `read_constr` which
# took in a pass to an SDC file. In OpenLANE, this file was autogenerated and
# only includes a set_driving_cell and set_load call that are set up based on
# user-provided params (i.e. not a user-provided SDC file). We can consider
# adding something like this back if we want.

# Also had to adjust each script to rewrite 'retime,-D,{D}' as 'retime,{D}' to
# avoid errors when a -D flag isn't passed in. I think this should be equivalent
# -- the default Yosys scripts use a similar syntax.

dict set syn_strategies "DELAY0" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_map_old_dly};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
dict set syn_strategies "DELAY1" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice2};${abc_map_old_dly};${abc_area_recovery_2}; retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
dict set syn_strategies "DELAY2" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice};${abc_map_old_dly};${abc_area_recovery_1}; retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
dict set syn_strategies "DELAY3" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_old_dly};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
dict set syn_strategies "AREA0" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
dict set syn_strategies "AREA1" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
dict set syn_strategies "AREA2" "+fx;mfs;strash;refactor;${abc_choice2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"

# Adopted from: https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/3c605819af855200bf567bfd04b7309218cc8013/flow/scripts/abc_area.script
dict set syn_strategies "AREA3" "+strash;dch;map,-B,0.9;topo;stime,-c;buffer,-c;upsize,-c;dnsize,-c;stime,-p;print_stats,-m"
# Adopted from: https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/3c605819af855200bf567bfd04b7309218cc8013/flow/scripts/abc_speed.script
set or_abc_loop "&get,-n;&st;&syn2;&if,-g,-K,6;&synch2;&nf;&put"
dict set syn_strategies "DELAY4" "+&get,-n;&st;&dch;&nf;&put;${or_abc_loop};${or_abc_loop};${or_abc_loop};${or_abc_loop};${or_abc_loop};buffer,-c;topo;stime,-c;upsize,-c;dnsize,-c;stime,-p;print_stats,-m"
