# =============================================================================
# synth_pass2_targeted.tcl — Pass 2: Targeted Timing Recovery
# =============================================================================
# Reads back the Pass 1 gate-level netlist and re-maps combinational logic
# using a timing-aggressive ABC strategy with gate sizing.
#
# This is an incremental approach: flip-flop mappings from Pass 1 are
# preserved; only combinational cells are re-optimized for timing.
#
# The old ABC 'map' command is used instead of '&nf' because it is more
# delay-aware for standard-cell mapping. Gate sizing (upsize/dnsize) is
# enabled via a constraints file.
#
# This is the opencos-adapted version of timing_flow/tcl/synth_pass2_targeted.tcl.
#
# Environment Variables (all required):
#   LIBERTY_FILE    — Path(s) to Liberty timing library, space-delimited
#   LIBERTY_FILE_DFF — Single lib for dfflibmap (flip-flop mapping)
#   LIBERTY_FILE_ABC — Single lib for abc (combinational mapping)
#   PASS1_NETLIST   — Path to Pass 1 synthesized netlist (.syn.v)
#   TOP_MODULE      — Top-level module name
#   OUT_DIR         — Output directory
#   FILE_SUFFIX     — Suffix for output file naming
#   DELAY_TARGET_PS — ABC delay target in picoseconds
#   CONSTR_FILE     — Path to ABC constraints file (for gate sizing)
#
# Output:
#   $OUT_DIR/${TOP_MODULE}_pass2.syn.v   — Re-optimized netlist
# =============================================================================

yosys -import

set liberty_files $::env(LIBERTY_FILE)
set liberty_dff   [expr {[info exists ::env(LIBERTY_FILE_DFF)] ? $::env(LIBERTY_FILE_DFF) : [lindex $liberty_files 0]}]
set liberty_abc   [expr {[info exists ::env(LIBERTY_FILE_ABC)] ? $::env(LIBERTY_FILE_ABC) : [lindex $liberty_files 0]}]
set pass1_netlist $::env(PASS1_NETLIST)
set top_module    $::env(TOP_MODULE)
set out_dir       $::env(OUT_DIR)
set file_suffix   $::env(FILE_SUFFIX)
set delay_ps      $::env(DELAY_TARGET_PS)
set constr_file   $::env(CONSTR_FILE)

puts "========================================================"
puts "PASS 2: TARGETED TIMING RECOVERY"
puts "========================================================"
puts "Top Module:     $top_module"
puts "Pass 1 Netlist: $pass1_netlist"
puts "Delay Target:   $delay_ps ps"
puts "Constraints:    $constr_file"
puts "========================================================"

# --- Read Inputs ---
foreach _lib $liberty_files {
    read_liberty -lib $_lib
}
read_verilog $pass1_netlist
hierarchy -check -top $top_module

puts ""
puts "--- Pass 1 netlist loaded ---"
stat -liberty $liberty_abc

# --- Targeted ABC: Timing-Aggressive on Combinational Logic ---
# The 'map' command (old mapper) is more timing-aware than '&nf'.
# Gate sizing (buffer/upsize/dnsize) requires the -constr file.
puts ""
puts "INFO: Running timing-aggressive ABC on all combinational logic..."
puts "INFO: Strategy: map + buffer + upsize + dnsize (with gate sizing)"
abc -liberty $liberty_abc \
    -constr $constr_file \
    -script "+strash; dc2; scorr; strash; dch -f; map -D $delay_ps; buffer; upsize -D $delay_ps; dnsize -D $delay_ps; stime -p"

opt
opt_clean

# --- Final Cleanup ---
opt_clean -purge
clean
hierarchy -check

# --- Statistics ---
puts ""
puts "========================================================"
puts "PASS 2 (TARGETED) SYNTHESIS STATISTICS"
puts "========================================================"
stat -liberty $liberty_abc

# --- Write Netlist ---
set outfile "$out_dir/${top_module}_pass2.syn.v"
write_verilog -noattr $outfile

puts ""
puts "Pass 2 (targeted) netlist: $outfile"
puts "========================================================"
