Friday 6 December 2019

atpg api

Display API     17:22     No comments
package require Vector
package require dict

### trial test API
namespace eval ::ATE::atpg_init {
variable version 3.0
#namespace export atpg_init_ip
}

proc ::ATE::atpg_init::split_to_hiers {signal} {
set hier_list [list]
while {$signal ne ""} {
if {[regexp {^(\\[\w\/]+ )(.*)} $signal match hier remainder]} {
lappend hier_list $hier
} elseif {[regexp {^(\w+)(.*)} $signal match hier remainder]} {
lappend hier_list $hier
}
set signal [regsub {^[\.\/]} $remainder {}]
}
return $hier_list
}

proc ::ATE::atpg_init::get_signal_view {type signal} {
switch $type {
"verilog" {return [join [split_to_hiers $signal] "/"]}
"hier_ref" {return [join [split_to_hiers $signal] "."]}
default {error "ERROR: use either 'verilog' or 'hier_ref' for 1st argument"}
}
}

proc ::ATE::atpg_init::Stuckat { args } {
global unified_scan_spec
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
{listArgs.arg "" "-option helper; please add -sub_mode tn arg to define SCAN_TEST sub mode defined in the file $::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml, e.g. XTR_STUCKAT_SERDES etc."}
{ftm_cap_win_us.arg "5" "<specify the ftm capture window in the unit of tck period>"}
{legacy_serdes_preshift_count.arg "0" "<specify the number of legacy_serdes_preshift_count values>"}
        {xtr_ip_controller_skip_list.arg "" "list of IP which is required to skip IP controller progm during IST"}
        {enable_all_atpg_ovr_mode  "enable all atpg override mode from atpg_clock_verif_config.yml"}
        {atpg_ovr_mode_list.arg "" "set atpg override mode for clock verification,this could cover specical requirement like onehot and edge control"}
    }

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

array set mainParams [::cmdline::getKnownOptions args $mainOptions]
 
    set tmp_args $::argv
    array set cmdline_tmp [::cmdline::getKnownOptions tmp_args {{tam_forceflow "" ""}}]

    puts "INFO: tam_forceflow cmdline: $cmdline_tmp(tam_forceflow)"
if {![regexp "^\s*$" $mainParams(ListArgs)]} {
upvar $mainParams(ListArgs) subtest_option
set subtest_option [concat $subtest_option $listArgsOptions]

        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_type" -value "SCAN_TEST"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_features" -value "secSHA2"
        puts "INFO: tam_forceflow cmdline: $cmdline_tmp(tam_forceflow)"
        if { $cmdline_tmp(tam_forceflow) == "1" } {
        puts "INFO: tam forceflow is 1"
    ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "global_init_behavior" -value "skip_init"
    ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_init_behavior" -value "skip_init"
        } else {
            puts "INFO: tam forceflow is 0"
        }

::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "chiplet_flow_certified" -value 1
#::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "XTR_STUCKAT_SERDES"
set temp_bak_args $::argv
array set temp_param_array [::cmdline::getKnownOptions temp_bak_args {{sub_mode.arg "" ""}}]
set sub_mode_in $temp_param_array(sub_mode)

## put STUCKAT_CBBGROUP to XTR_STUCKAT_SERDES
if {$sub_mode_in eq "XTR_STUCKAT_CBBGROUP"} {
set sub_mode_in XTR_STUCKAT_SERDES
}
puts "INFO: sub_mode=$sub_mode_in"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "$sub_mode_in"
return 1
}

foreach temp_var_name "prgmConfig testConfig ftm_cap_win_us legacy_serdes_preshift_count xtr_ip_controller_skip_list  " {
set $temp_var_name $listargsParams($temp_var_name)
}

    ## Johnson add an if condition wrapper here for MATHS ATE.
    set test_name [config_map_value [config_find $testConfig CURRENT_TEST] name]
    if {[regexp maths_ate $test_name]} {
    #    when test name is maths_ate, bypass all clusters through JET, so that no programming will happen since now
        puts "MATHS ATE INFO: the test is $test_name, bypass all programming!"
        $prgmConfig set_controller_property {.*} mode bypass
    }

    puts "INFO: wait [expr [$prgmConfig get_tap_frequency]*${ftm_cap_win_us}/1000] cycles for $ftm_cap_win_us us ftm_cap_win"
    set ftm_cap_win [expr [$prgmConfig get_tap_frequency]*${ftm_cap_win_us}/1000]

    set sub_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST] "sub_modes"]]
puts "INFO: sub_modes: $sub_modes"
if {[llength $sub_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -sub_mode to set proper scan sub_mode."
exit 1
}
    if {[config_map_value [config_find $testConfig USER_CUSTOM_ARGS] tam_forceflow]} {
       set tam_forceflow_flag 1
    } else {
       set tam_forceflow_flag 0
    }

    if { $tam_forceflow_flag == 1} {
    ::ATE::atpg_init::tam_forceflow -prgmConfig $prgmConfig -testConfig $testConfig
    }

    ##### begin: clear sdp x for atpg/ate sim #####
    if { $tam_forceflow_flag == 0 } {
    $prgmConfig set_program_value {.*XTR_TAM_CTL} {.*Select_SDPBypassCtrl.*} -value  1
    $prgmConfig set_program_value {.*XTR_TAM_CTL} {.*SDPBypass.*} -value  1
    $prgmConfig set_program_value {.*XTR_TAM_CTL} {.*XTRControl_ShiftStagger.*} -value  1

    set tmax_init [config_find $testConfig "USER_CUSTOM_ARGS/tmax_init"]
    if { $tmax_init == 1} {
        $prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 1
    } else {
        $prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 0
    }
   
    $prgmConfig program
    }
    set design_type [config_map_value [config_find $testConfig CURRENT_TEST] design_type]
    foreach sub_mode $sub_modes {
        if {$design_type == "flat" && [regexp "XTR" $sub_modes]} {
            #2. toggle serdes_4f, wait few cycles, stop serdes4f
            if {[$prgmConfig is_vec_mode]} {
                puts "for atpg vec sim,toggle serdes_4f to clear pipeline X "
                set current_cycle [ $prgmConfig get_current_cycle ]
                puts "Toggle serdes4f before dft mode programming at $current_cycle"
                set die_obj [config_find $testConfig CURRENT_TEST/die_obj]
                set serdes4f_clk_pin [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=serdes4f_clk)}]
                foreach pin $serdes4f_clk_pin {
                    $prgmConfig set_enable_value $pin 1
                    $prgmConfig set_pin_value    $pin 1
                }
                set serdes_div_ratio     [config_find $testConfig USER_CUSTOM_ARGS/serdes_div_ratio]
                set serdes4fToggleCycle [expr $serdes_div_ratio * 20]
                $prgmConfig wait_cycles $serdes4fToggleCycle
                set curr_cyc [$prgmConfig get_current_cycle]
                set tck_mult [$prgmConfig get_tck_multiple]
                puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
                if {[ expr $curr_cyc % $tck_mult ] != 0} {
                    set wait_cyc [ expr $tck_mult - [ expr $curr_cyc % $tck_mult ]]
                    $prgmConfig wait_cycles $wait_cyc
                    set curr_cyc [$prgmConfig get_current_cycle]
                    puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
                }
                set current_cycle [ $prgmConfig get_current_cycle ]
                puts "Stop serdes4f before dft mode programming at $current_cycle"
                foreach pin $serdes4f_clk_pin {
                    $prgmConfig set_enable_value $pin 1
                    $prgmConfig set_pin_value    $pin 0
                }
            }
            if {[$prgmConfig is_sim_mode]} {
                puts "for atpg ate sim, toggle serdes_4f to clear pipeline X"
                $prgmConfig jtag_force "TB_clk_freerunning" 1
                $prgmConfig waitRti [expr int(63 * 500 / ([$prgmConfig get_tap_frequency]/1000))] ;# we need 63/8 = 8 pulses to flush X inside 8 sdps, we have serdes divider, div is 8
                $prgmConfig jtag_force "TB_clk_freerunning" 0
            }
        }
        $prgmConfig program
    }
    ##### end: clear sdp x #####

set dft_modes_config_file "$::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml"
if { [file exists $dft_modes_config_file]} {
puts "INFO: standard dft mode programming yml file found. Reading..."
set dft_modeConfig [config_read_yaml $dft_modes_config_file]
} else {
puts stderr "ERROR: $dft_modes_config_file file is missing. Please fix it first."
exit 1
}

    # inject x on wbr
    if { [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] wbr_injectX] } {
        $prgmConfig jtag_force "tb.enable_force_for_wbr" 1
$prgmConfig wait_cycles 1
    }
set clock_mode [config_map_value [config_find $testConfig CURRENT_TEST] clock_mode]
set sub_clock_mode [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CLOCK_CONFIG] $clock_mode]];

    set rsync [config_find $testConfig USER_CUSTOM_ARGS/resync_serdes]
    set rst_from_sf [config_find $testConfig USER_CUSTOM_ARGS/reset_from_sf]
    set fs_top_up [config_find $testConfig USER_CUSTOM_ARGS/fs_top_up_init]
    if { $rst_from_sf eq "" } { set rst_from_sf 0 }
    if {$rsync eq ""} {set rsync 0}
    if {$fs_top_up eq ""} {set fs_top_up 0}

# DFT mode programming
if {[info procs ::ATE::AteFlowUtils::getTestApiProperty] == "::ATE::AteFlowUtils::getTestApiProperty"} {
set testapi_test_type [::ATE::AteFlowUtils::getTestApiProperty -testConfig $testConfig -categoryName execution_ctrl -propName test_type]
set testapi_dft_mode [::ATE::AteFlowUtils::getTestApiProperty -testConfig $testConfig -categoryName execution_ctrl -propName dft_mode]
} else {
set testapi_test_type ""
set testapi_dft_mode ""
}
if { $testapi_dft_mode ne "" } {
        if { ($rsync || $rst_from_sf || $fs_top_up) != 1 } {
    puts "INFO: set dft program mode to \"$testapi_test_type/$testapi_dft_mode\""
    #commenting $prgmConfig set_program_mode "$testapi_test_type/$testapi_dft_mode"
            if { $tam_forceflow_flag == 0 } {
            ::ATE::AteFlowUtils::set_default_dft_mode -testConfig $testConfig -prgmConfig $prgmConfig
            }
        }
} else {
puts "WARNING: testapi_dft_mode is required for scan test"
}

## fs_validation
    set fs_validation     [config_find $testConfig USER_CUSTOM_ARGS/fs_validation]
    if {$fs_validation ne ""} {
        puts "INFO: fs_validation is being set on FS region $fs_validation"
        ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*DFT_FS_CTRL} {.*DFT_FS_CTRL} 0
        #Below force programming added by subbu after referring to tu102 to see the tags in INIT for the register
        $prgmConfig program -force
    }

    ## check if rsync needs to be called ##
set rsync [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] resync_serdes]
set fstate [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] resync_fstate]
if { $rsync == 1 } {
puts "Calling resync serdes"
if { ! [file exists $fstate] } { puts "ERR: provide fstate yml file: $fstate" }
::ATE::atpg_init::resync_serdes -prgmConfig $prgmConfig -testConfig $testConfig -fstate $fstate
return 1
}

    ## check if reset_from_sf needs to be called ##
    set rst_from_sf [config_find $testConfig USER_CUSTOM_ARGS/reset_from_sf]
    set fstate [config_find $testConfig USER_CUSTOM_ARGS/rsf_fstate]
    if { $rst_from_sf == 1 } {
       puts "Calling reset_from_sf"
        if { ! [file exists $fstate] } {
            puts "ERR: provide fstate yml file: $fstate"
        }

       ::ATE::atpg_init::reset_from_sf -prgmConfig $prgmConfig -testConfig $testConfig -fstate $fstate
       puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============LEAVE procedure: [lindex [info level 0] 0]=============="

       return 1

    }

    ## check if fs_top_up needs to be called ##
    set fs_top_up [config_find $testConfig USER_CUSTOM_ARGS/fs_top_up_init]
    if { $fs_top_up == 1 } {
       puts "Calling fs_top_up"
       ::ATE::atpg_init::fs_top_up -prgmConfig $prgmConfig -testConfig $testConfig
       puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============LEAVE procedure: [lindex [info level 0] 0]=============="

       return 1
    }

foreach sub_mode $sub_modes {
if {[regexp "STUCKAT_CBBGROUP" $sub_mode]} {
set sub_mode XTR_STUCKAT_SERDES
} elseif {[regexp "FTM_CBBGROUP" $sub_mode]} {
set sub_mode XTR_FTM_SERDES
        }
if {[regexp "STUCKAT" $sub_mode]} {
puts "INFO: Validating sub mode $sub_mode..."
if { [config_find $dft_modeConfig "SCAN_TEST/${sub_mode}"] != ""} {
puts "INFO: $sub_mode is valid sub_mode"
} else {
puts stderr "ERROR: sub_mode $sub_mode is invalid. Please follow $dft_modes_config_file for the list of sub_mode's allowed"
exit 1
}
} elseif {[regexp "FTM" $sub_mode]} {
puts stderr "ERROR: STUCKAT subtest is run with FTM sub_mode. Please rerun the test with FTM subtest."
exit 1
} else {
puts stderr "WARNING: sub mode $sub_mode is not SCAN_TEST sub mode"
}
}
# Please specify the test API specific programming here
set tmax_init [config_find $testConfig "USER_CUSTOM_ARGS/tmax_init"]
if { $tmax_init == 1} {
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 1
} else {
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 0
}

    if {[regexp "XTR" $sub_mode]} {
        if {[file exists $unified_scan_spec]} {
            set accessConfig [config_read_yaml $unified_scan_spec]
            set pipe_ports [ config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/INPUTS]]
            set pipe_port_0 [ lindex $pipe_ports 0]
            set input_pipe_count [ config_find $accessConfig SCAN_IOS/XTREME_X4/IO_PIPELINES/$pipe_port_0/INPUT_PIPE_CNT]
            set output_pipe_count [ config_find $accessConfig SCAN_IOS/XTREME_X4/IO_PIPELINES/$pipe_port_0/OUTPUT_PIPE_CNT]
            set xtr_link_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_link_fast_scanin_pipes"]
            set xtr_link_fast_scanout_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_link_fast_scanout_pipes"]
            if {$xtr_link_fast_scanin_pipes ne "" } {
                if {$xtr_link_fast_scanin_pipes != $input_pipe_count} {
                    tn_msg_issue_ATE_102 "xtr_link_fast_scanin_pipes argument $xtr_link_fast_scanin_pipes is not equal to INPUT_PIPE_CNT from scanIo.yml $input_pipe_count"
                    #exit;
                }
            }
            if {$xtr_link_fast_scanout_pipes ne "" } {
                if {$xtr_link_fast_scanout_pipes != $output_pipe_count} {
                    tn_msg_issue_ATE_102 "xtr_link_fast_scanout_pipes argument $xtr_link_fast_scanout_pipes is not equal to OUTPUT_PIPE_CNT from scanIo.yml $output_pipe_count"
                    #exit;
                }
            }
        }
::ATE::atpg_init::serdes_div_reset -prgmConfig $prgmConfig -testConfig $testConfig
} else {
set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set scan_en_ext_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCTL0 ] 0 ]

if { [file exists $unified_scan_spec]} {
set accessConfig [config_read_yaml $unified_scan_spec]
set ufi_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
puts "ufi list is $ufi_list"
set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
puts "INFO: serdes4f pin list is $serdes4f_list"
} else {
set ufi_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj UFI ] 0 ]
            if {$ufi_pin ne ""} {
    set ufi_list [ list $ufi_pin ]
            }
set serdes_4f_clk_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCLK=serdes4f_clk ] 0]
set serdes4f_list [ list $serdes_4f_clk_pin]

}

set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
puts "INFO: common modes: $common_modes"
if {[llength $common_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
exit 1
}
foreach common_mode $common_modes {
if {[regexp "SERDES_RATIO" $common_mode]} {
switch $common_mode {
SERDES_RATIO_S4 { set SerdesRatio 4 }
SERDES_RATIO_S6 { set SerdesRatio 6 }
SERDES_RATIO_S8 { set SerdesRatio 8 }
SERDES_RATIO_S12 { set SerdesRatio 12 }
SERDES_RATIO_S24 { set SerdesRatio 24 }
}
}
}

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Make UFI 0 and serdes fast clock 0 scan_en_ext 0 at cycle $current_cycle"
        if { [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] test_trigger] } {
            puts "blueg, can't find ufi pin for now, comment out for clock sims for now"
        } else {
            if {[info exists ufi_list]} {
                foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
            }
        }
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
        if {[$prgmConfig is_sim_mode]} {
            # ATE simulation: turn off serdes_4f_clk
            $prgmConfig jtag_force "TB_clk_freerunning" 0
        }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 20

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Asserting scan enable at cycle $current_cycle"
$prgmConfig set_pin_value $scan_en_ext_pin 1
$prgmConfig program

set current_cycle [ $prgmConfig get_current_cycle ]
set wait_cyc [ expr 120 * $SerdesRatio ]
puts "INFO: Wait for 120 * serdes ratio cycles at cycle $current_cycle"
$prgmConfig wait_cycles $wait_cyc

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: De-asserting scan enable at cycle $current_cycle"
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 20

::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
}

if {[regexp "XTR" $sub_mode]} {
# bug 1634381.
# irrespective of ECK or ICK mode, this bit should be 1 for XTR
# for ECK should be 0 and ICK should be 1 in TAM Serdes
# Because of this conflict cannot be done in standard programing yml
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*TamControl_SerdesClockMode" -value 1
$prgmConfig program

        # Set DFT_FS_CTRL bits to 1 (the reset value) and add a JRD shift. This is needed to do FSCheck by flipping tags on tester
        if {$design_type eq "flat"} {
            ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*DFT_FS_CTRL} {.*DFT_FS_CTRL} 1
            $prgmConfig program -force
        }

        #set test_trigger [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] test_trigger]
set xtr_ufi_selftest [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ufi_selftest"]
if { $xtr_ufi_selftest } {
::ATE::atpg_init::ufi_selftest -prgmConfig $prgmConfig -testConfig $testConfig
}
::ATE::atpg_init::ufi_reset_sequence -prgmConfig $prgmConfig -testConfig $testConfig -xtr_ip_controller_skip_list $xtr_ip_controller_skip_list
# ::ATE::atpg_init::ufi_reset_sequence  $prgmConfig  $testConfig  $xtr_ip_controller_skip_list  $chiplet_id_bit  $chiplet_string  $xtr_scan_in  $status_link_width  $ist_lbist_6chain
#::ATE::atpg_init::serdes_div_reset -prgmConfig $prgmConfig -testConfig $testConfig
} else {
::ATE::atpg_init::tam_init_seq -prgmConfig $prgmConfig -testConfig $testConfig
}

    if { $tam_forceflow_flag == 0 } {
$prgmConfig set_program_value ".*/CLK_CTL" ".*tmc2clk_block_x_on_clockchain_in_setup.*" -value 0
$prgmConfig program
    if {[$prgmConfig list_registers .*TEST_MASTER_CTRL] != ""} {
        $prgmConfig set_program_value {.*CHIPLET_LOGIC} {.*} -value 1'b0 -replicate
        $prgmConfig program -force
    }
    }

set num_1500_pipelines [$prgmConfig get_total_num_ieee1500_pipelines]
puts "INFO: Waiting for twice 1500 pipelines $num_1500_pipelines"

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Before wait cycle $current_cycle"

$prgmConfig waitRti $num_1500_pipelines
$prgmConfig waitRti $num_1500_pipelines
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After wait cycle $current_cycle"

    # make scan enable as Z to avoid contention on scan enable & scan enable observe port
    if {[regexp "XTR" $sub_mode]} {
        if { [file exists $unified_scan_spec]} {
            set accessConfig [config_read_yaml $unified_scan_spec]
            set scan_en_pin [lindex [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SCAN_EN_PORTS]] 0]
            puts "INFO: scan_en pin is $scan_en_pin"
        } else {
   set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
           set scan_en_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCTL0 ] 0 ]
            puts "INFO: scan_en pin is $scan_en_pin"
        }
        #regsub -all {[\{\}]} $scan_en_pin {} scan_en_pin
        $prgmConfig set_pin_value $scan_en_pin Z
    }
   
# additional 100 waitRti as the above only applies tck for 5 + 5 = 10 waitRti
for {set i 0} {$i < 20} {incr i} {
$prgmConfig waitRti 5
}

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After additional 100 waitRti $current_cycle"

puts "INFO: End of atpg_init of Stuckat"

    puts "Garyk, start dump"
    $prgmConfig jtag_force "TB_enable_fsdb_dump" 1

if {[$prgmConfig is_sim_mode]} {
puts "sim mode for ATE test"
        puts "INFO: SLCG/BLCG is controlled by scan flops, but our monitor are after them, need below prgm to force them open, this is simulation only"
        ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*CLK_PCCM_CTL} {.*tmc2clk_disable_clock_gating.*} 1
        ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*CLK_PCCM_CTL} {.*tmc2clk_ctsroot_disable_clk_gating.*} 1
        ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*CLK_CTL} {.*tmc2clk_ctsroot_disable_clk_gating.*} 1
        $prgmConfig set_program_value {.*/ATPG_CTL} {.*tmc2slcg_disable_clock_gating.*} -value 1'b1
        $prgmConfig program
       
        ::ATE::atpg_init::clock_stuckat $prgmConfig $testConfig $ftm_cap_win $legacy_serdes_preshift_count
}
}

proc ::ATE::atpg_init::over_mode_extra_control {prgmConfig testConfig atpg_clock_verif_config atpg_ovr_mode} {
    if {$atpg_ovr_mode == "DEFAULT"} {
        set atpg_ovr_val [config_new_map]
    } else {
        set atpg_ovr_val [config_find $atpg_clock_verif_config Override_mode/$atpg_ovr_mode]
    }
    #Force
    if {[config_find $atpg_ovr_val Force] != ""} {
        foreach force_point [config_map_keys [config_find $atpg_ovr_val Force]] {
            set width [config_find $atpg_ovr_val Force/${force_point}/width]
            set value [config_find $atpg_ovr_val Force/${force_point}/value]
            puts "INFO: Now force $width wide chain $force_point to $value"
            ::ATE::atpg_init::FORCE_CLOCK_CHAIN $prgmConfig $testConfig $force_point $width $value
        }
        $prgmConfig waitRti 1
    }
   #Program
    if {[config_find $atpg_ovr_val Program] != ""} {
        foreach jtagreg [config_map_keys [config_find $atpg_ovr_val Program]] {
            foreach filed [config_map_keys [config_find $atpg_ovr_val Program/${jtagreg}]] {
                set value [config_find $atpg_ovr_val Program/${jtagreg}/${filed}]
                puts "INFO: Now program $jtagreg $filed to $value"
                $prgmConfig set_program_value ".*${jtagreg}" ".*${filed}.*" -value ${value}
            }
        }
    }
    $prgmConfig program
}

proc ::ATE::atpg_init::clock_monitor_setting {prgmConfig testConfig ftmorsaClockConfig atpg_clock_verif_config atpg_ovr_mode {IsFirstRun 1}} {
    set design_type [config_map_value [config_find $testConfig CURRENT_TEST] design_type]
    set clockProgrammingConfig [::ATE::clock_init_tasks::get_clock_programming_config $testConfig]
    set sub_clock_mode [config_find $atpg_clock_verif_config TMP/sub_clock_mode]
    set sub_mode [config_find $atpg_clock_verif_config TMP/sub_mode]
    set clock_atpg_mode [config_find $atpg_clock_verif_config TMP/clock_atpg_mode]
    set num_core_shift_pulses [config_find $atpg_clock_verif_config TMP/num_core_shift_pulses]
    set serdes_slow_clk_freq_mhz [config_find $atpg_clock_verif_config TMP/serdes_slow_clk_freq_mhz]
    set test_clk_freq_mhz [config_find $atpg_clock_verif_config TMP/test_clk_freq_mhz]
    set serdes_div_ratio [config_find $atpg_clock_verif_config TMP/serdes_div_ratio]


    if {$atpg_ovr_mode == "DEFAULT"} {
        set atpg_ovr_val [config_new_map]
    } else {
        set atpg_ovr_val [config_find $atpg_clock_verif_config Override_mode/$atpg_ovr_mode]
    }

    puts "INFO: Under override mode $atpg_ovr_mode, monitor override config is:"
    puts " [config_write_yaml $atpg_ovr_val]"

    set monitor_ovr [config_find $atpg_ovr_val Monitor]
    if {$monitor_ovr != ""} {
        set monitor_ovr_keyword_config_list [config_list $monitor_ovr]
    } else {
        set monitor_ovr_keyword_config_list ""
    }

    set Associated_cap_stagger_mode [config_find $atpg_ovr_val Associated_cap_stagger_mode]
    
    #Get from ftm/s@ yml
    set portListConfig [config_find $ftmorsaClockConfig PortList]
    set staggerConfig [config_find $ftmorsaClockConfig StaggerConfig]
    foreach tmp [config_list $portListConfig] {
        if [regexp $sub_clock_mode [config_map_keys $tmp]] {
            set portConfig $tmp
        }
    }

# Define "clock_atpg_mode" nickname that describes clock behavior for given ATPG $sub_mode
set modeConfig [config_find $portConfig $sub_clock_mode/mode_${sub_mode}]
set fieldsConfig [config_find $modeConfig FIELDS]
set entries [config_list [config_find $modeConfig ENTRIES]]
# Decode field indices
set fieldsList [split $fieldsConfig "\t"]
for {set i 0} {$i < [llength $fieldsList]} {incr i} {
set FieldIndex([lindex $fieldsList $i]) $i
}
    
    foreach entry $entries {
        puts "INFO: Under $sub_clock_mode/mode_${sub_mode} ,override mode $atpg_ovr_mode ,start config of entry $entry"

#Get default info
        set elementList [split $entry "\t"]
set name [lindex $elementList $FieldIndex(NAME)]
        set outputFreq [lindex $elementList $FieldIndex(OUTPUT_FREQ)]
        set shift_outputFreq ""
set sh_staggerGroup [lindex $elementList $FieldIndex(SH_STAGGER_GROUP)]
set cap_staggerGroup [lindex $elementList $FieldIndex(CAP_STAGGER_GROUP)]
set sh_staggerMode [lindex $elementList $FieldIndex(STAGGER_MODE)]
set cap_staggerMode [lindex $elementList $FieldIndex(CAP_STAGGER_MODE)]
        set sh_staggerEdges [config_find $staggerConfig StaggerModes/$sub_mode/$sh_staggerMode/shift_mode_relation]
        set cap_staggerEdges [config_find $staggerConfig StaggerModes/$sub_mode/$cap_staggerMode/capture_mode_relation]
set num_core_shift_pulses [config_find $atpg_clock_verif_config TMP/num_core_shift_pulses]
        set pulseNum [lindex $elementList $FieldIndex(PULSE_NUM)]
        unset -nocomplain Capture_duty
        puts "INFO:         From Monitor yml, outputFreq is $outputFreq , sh_staggerGroup is $sh_staggerGroup , sh_staggerMode is $sh_staggerMode ,\
               cap_staggerGroup is $cap_staggerGroup , cap_staggerMode is $cap_staggerMode , pulseNum is $pulseNum"
        
        #Shift stagger relation
        switch -regexp "$sub_clock_mode.$clock_atpg_mode" {
            BYPASS_MODE_ISTCLOCK.XTR|STA_BYPASS_MODE_SERDESCLOCK.XTR {
                puts "INFO:         Enable shift stagger check under $sub_clock_mode.$sub_mode by default"
                set staggerRelation 0
            }
            nafll_Ftm.XTR|FTM_BYPASS_MODE_SERDESCLOCK.XTR {
                puts "INFO:         Enable shift stagger check under $sub_clock_mode.$sub_mode by default"
                set staggerRelation 0
            }
            BYPASS_MODE_TESTCLOCK.TAM {
                puts "INFO:         Disable shift stagger check under $sub_clock_mode.$sub_mode by default"
                set staggerRelation 3
            }
            nafll_Ftm.TAM|FTM_BYPASS_MODE_TESTCLOCK.TAM {
                puts "INFO:         Disable shift stagger check under $sub_clock_mode.$sub_mode by default"
                set staggerRelation 3
            }
        }
        
        #Capture stagger relation
        set cap_staggerMode [lindex $elementList $FieldIndex(CAP_STAGGER_MODE)]
        if {[config_find $staggerConfig StaggerModes/${Associated_cap_stagger_mode}/${cap_staggerMode}/capture_mode_relation] != ""} {
            puts "INFO:         Enable capture stagger check for all monitors when Associated_cap_stagger_mode is set"
            set cap_staggerEdges [config_find $staggerConfig StaggerModes/${Associated_cap_stagger_mode}/${cap_staggerMode}/capture_mode_relation]
            set cap_staggerRelation 0
        } else {
            puts "INFO:         Disable capture stagger check by default"
            set cap_staggerRelation 3
            set cap_staggerEdges 0
        }
        set sh_staggerRefClk [config_find $staggerConfig StaggerGroups/ShStaggerGroups/[lindex $elementList $FieldIndex(SH_STAGGER_GROUP)]/sh_ref_clock]
set cap_staggerRefClk [config_find $staggerConfig StaggerGroups/CapStaggerGroups/[lindex $elementList $FieldIndex(CAP_STAGGER_GROUP)]/cap_ref_clock]
        
        regsub -all {[^a-zA-Z0-9_]+} $name {_} monitorName
regsub -all {[^a-zA-Z0-9_]+} $sh_staggerRefClk {_} sh_staggerRefClkName
regsub -all {[^a-zA-Z0-9_]+} $cap_staggerRefClk {_} cap_staggerRefClkName
        #Override by monitor_ovr
        puts "INFO: Current entry is \"$entry\""
        set matched_keyword ""
        foreach monitor_ovr_keyword_config $monitor_ovr_keyword_config_list {
            set monitor_ovr_keyword [config_map_keys $monitor_ovr_keyword_config]
            puts "INFO:   Current monitor override keyword is $monitor_ovr_keyword"
            if {[regexp $monitor_ovr_keyword $entry]} {
                puts "INFO:      Entry is matching keyword: $monitor_ovr_keyword"
                set matched_keyword "$matched_keyword $monitor_ovr_keyword"
                if {[config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Pulse_number] != ""} {
                    set pulseNum [config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Pulse_number]
                    puts "INFO:         Pulse number is overriden to $pulseNum"
                }
                if {[config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Frequency] != ""} {
                    set outputFreq [config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Frequency]
                    puts "INFO:         outputFreq is overriden to $outputFreq"
                }
                if {[config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Shift_Frequency] != ""} {
                    set shift_outputFreq [config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Shift_Frequency]
                    puts "INFO:         shift_outputFreq is overriden to $shift_outputFreq"
                }
                if {[config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Capture_stagger_edge] != ""} {
                    set cap_staggerEdges [config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Capture_stagger_edge]
                    puts "INFO:         cap_staggerEdges is overriden to  $cap_staggerEdges, capture edge check is forced to be enabled"
                    set cap_staggerRelation 0
                }
                if {[config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Shift_stagger_edge] != ""} {
                    set sh_staggerEdges [config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Shift_stagger_edge]
                    puts "INFO:         sh_staggerEdges is overriden to  $sh_staggerEdges, shift edge check is forced to be enabled"
                    set staggerRelation 0
                }
                if {[config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Shift_Pulse_number] != ""} {
                    set num_core_shift_pulses [config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Shift_Pulse_number]
                    puts "INFO:         Shift pulse number is overriden to $num_core_shift_pulses"
                }
                if {[config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Capture_duty] != ""} {
                    set Capture_duty [config_find $monitor_ovr_keyword_config ${monitor_ovr_keyword}/Capture_duty]
                    puts "INFO:         Capture duty is overriden to $Capture_duty"
                }
            }
        }
        if {[llength $matched_keyword] > "1"} {
            #tn_msg_issue_ATE_102 "Under override mode $atpg_ovr_mode ,entry $entry is matched by more than 1 keyword: $matched_keyword"
            puts "ERROR:        Under override mode $atpg_ovr_mode ,entry $entry is matched by more than 1 keyword: $matched_keyword"
        }
        
        #1: configure shift/capture pulse number (per monitor inst)
        puts "INFO:         Capture pulse Number is $pulseNum"
        if {$IsFirstRun == 1 | $clock_atpg_mode eq "TAM"} {
           puts "INFO:         Shift pulse Number is $num_core_shift_pulses"
        } else {
           puts "INFO:         Shift pulse Number is [expr $num_core_shift_pulses + 1]"
        }

        binary scan [binary format I1 $pulseNum] B* binaryPulseNum
        $prgmConfig jtag_force "TB_ftm_${monitorName}_pulse_num\[9:0\]" $binaryPulseNum
        #increase the expected shift number by 1 when we loop test
        if {$IsFirstRun == 1 | $clock_atpg_mode eq "TAM"} {
           binary scan [binary format I1 $num_core_shift_pulses] B* binary_num_core_shift_pulses
        } else {
           binary scan [binary format I1 [expr $num_core_shift_pulses + 1]] B* binary_num_core_shift_pulses
        }
        $prgmConfig jtag_force "TB_ftm_shift_cnt_overwrite_${monitorName}\[9:0\]" $binary_num_core_shift_pulses
        #2: configure ftm target shift and capture frequency period (per monitor inst)
        set outputFreq_d $outputFreq
        switch -regexp "$sub_clock_mode.$clock_atpg_mode" {
            nafll_Ftm.XTR|FTM_BYPASS_MODE_SERDESCLOCK.XTR {
                if {$shift_outputFreq == ""} {set shift_outputFreq $serdes_slow_clk_freq_mhz}
                if {$shift_outputFreq == "0"} {
                    set targetShiftPeriod_ps 0
                } else {
                    set targetShiftPeriod_ps [expr int(1000000.0 / $shift_outputFreq * 256)]; # There is "div 256" applied by the monitor module
                }
                if {![regexp {^\d+(\.\d+)?} $outputFreq]} {
                    if {[catch {::ATE::clock_init_tasks::get_frequency $clockProgrammingConfig $outputFreq_d} errMsg]} {
                        error "ERROR: Your ACV program config file '$::env(ATE_TOT)/jtag/clock_programming_config_${design_type}.yml' did not result in a valid output frequency for '$outputFreq'. Please assign fixed frequency value in your clock monitor config file if you want to skip ACV. Error message: $errMsg"
                    } else {
                        set outputFreq [::ATE::clock_init_tasks::get_frequency $clockProgrammingConfig $outputFreq_d]
                    }
                    set targetCapturePeriod_ps [expr int(1000000.0 / $outputFreq * 256)]
                    set iMaxFreqTolerance 20
                    set iTolerancePercentage 0.01
                    if {[expr $outputFreq*$iTolerancePercentage] > $iMaxFreqTolerance} {
                        set iFreqTolerance $iMaxFreqTolerance
                    } else {
                        set iFreqTolerance [expr $outputFreq*$iTolerancePercentage]
                    }
                    set targetCLKTolerance [expr int(1000000/($outputFreq - $iFreqTolerance)-1000000/$outputFreq)]
                } else {
                    set targetCapturePeriod_ps [expr int(1000000.0 / $outputFreq * 256)]
                    set targetCLKTolerance 0
                }
            }
            BYPASS_MODE_ISTCLOCK.XTR|STA_BYPASS_MODE_SERDESCLOCK.XTR {
                if {$shift_outputFreq == ""} {set shift_outputFreq $serdes_slow_clk_freq_mhz}
                if {$shift_outputFreq == "0"} {
                    set targetShiftPeriod_ps 0
                } else {
                    set targetShiftPeriod_ps [expr int(1000000.0 / $shift_outputFreq * 256)]; # There is "div 256" applied by the monitor module
                }
                set targetCapturePeriod_ps [expr int(1000000.0 / $serdes_slow_clk_freq_mhz * 256)]; # There is "div 256" applied by the monitor module
                set targetCLKTolerance 0
            }
            nafll_Ftm.TAM|FTM_BYPASS_MODE_TESTCLOCK.TAM {
                if {$shift_outputFreq == ""} {set shift_outputFreq $test_clk_freq_mhz}
                if {$shift_outputFreq == "0"} {
                    set targetShiftPeriod_ps 0
                } else {
                    set targetShiftPeriod_ps [expr int(1000000.0 / $shift_outputFreq * 256)]; # There is "div 256" applied by the monitor module
                }
                if {![regexp {^\d+(\.\d+)?} $outputFreq]} {
                    if {[catch {::ATE::clock_init_tasks::get_frequency $clockProgrammingConfig $outputFreq_d} errMsg]} {
                        error "ERROR: Your ACV program config file '$::env(ATE_TOT)/jtag/clock_programming_config_${design_type}.yml' did not result in a valid output frequency for '$outputFreq'. Please assign fixed frequency value in your clock monitor config file if you want to skip ACV. Error message: $errMsg"
                    } else {
                        set outputFreq [::ATE::clock_init_tasks::get_frequency $clockProgrammingConfig $outputFreq_d]
                    }
                    set targetCapturePeriod_ps [expr int(1000000.0 / $outputFreq * 256)]
                    set iMaxFreqTolerance 20
                    set iTolerancePercentage 0.01
                    if {[expr $outputFreq*$iTolerancePercentage] > $iMaxFreqTolerance} {
                        set iFreqTolerance $iMaxFreqTolerance
                    } else {
                        set iFreqTolerance [expr $outputFreq*$iTolerancePercentage]
                    }
                    set targetCLKTolerance [expr int(1000000/($outputFreq - $iFreqTolerance)-1000000/$outputFreq)]
                } else {
                    set targetCapturePeriod_ps [expr int(1000000.0 / $outputFreq * 256)]
                    set targetCLKTolerance 0
                }
            }
            BYPASS_MODE_TESTCLOCK.TAM {
                if {$shift_outputFreq == ""} {set shift_outputFreq $test_clk_freq_mhz}
                if {$shift_outputFreq == "0"} {
                    set targetShiftPeriod_ps 0
                } else {
                    set targetShiftPeriod_ps [expr int(1000000.0 / $shift_outputFreq * 256)]; # There is "div 256" applied by the monitor module
                }
                set targetCapturePeriod_ps [expr int(1000000.0 / $test_clk_freq_mhz * 256)]; # There is "div 256" applied by the monitor module
                set targetCLKTolerance 0
            }
        }
        
        puts "INFO:         Capture output Freq is $outputFreq  (outputFreq_d is $outputFreq_d)"
        puts "INFO:         Capture target period is $targetCapturePeriod_ps"
        puts "INFO:         Capture target period tolerance is $targetCLKTolerance"
        puts "INFO:         Shift target Freq is $shift_outputFreq"
        puts "INFO:         Shift target period is $targetShiftPeriod_ps"

        binary scan [binary format I1 $targetCapturePeriod_ps] B* binary_targetCapturePeriod_ps
        $prgmConfig jtag_force "TB_dynamic_CM_target_period_${monitorName}\[37:0\]" $binary_targetCapturePeriod_ps
        binary scan [binary format I1 $targetShiftPeriod_ps] B* binary_targetShiftPeriod_ps
        $prgmConfig jtag_force "TB_ftm_shift_period_overwrite_${monitorName}\[37:0\]" $binary_targetShiftPeriod_ps
        binary scan [binary format I1 $targetCLKTolerance] B* binary_targetCLKTolerance
        $prgmConfig jtag_force "TB_dynamic_CM_period_tolerance_${monitorName}\[37:0\]" $binary_targetCLKTolerance 
        #3: configure capture stagger relation
# 00: ftmclk lag behind stagger_ref_clk
# 01: ftmclk lead stagger_ref_clk
#    11: no check
# 11: reserved
        puts "INFO:         Capture stagger relation is $cap_staggerRelation"
        for {set i 0} {$i < 2} {incr i} { $prgmConfig jtag_force "TB_CAP_STAGGER_RELATION_${cap_staggerRefClkName}_$i" [expr ($cap_staggerRelation >> $i) & 1]}
        
        #4: configure capture stagger value
        puts "INFO:         Capture stagger edges is $cap_staggerEdges"
        binary scan [binary format I1 $cap_staggerEdges] B* binary_cap_staggerEdges
        $prgmConfig jtag_force "TB_CAP_STAGGER_VAL_${monitorName}\[16:0\]" $binary_cap_staggerEdges

        #5: configure shift stagger relation
#  ultra -> 00: ftmclk lags behind stagger_ref_clk
# 01: ftmclk leads stagger_ref_clk
# legacy -> 11: no check
# 11: reserved
        puts "INFO:         Shift stagger relation is $staggerRelation"
        for {set i 0} {$i < 2} {incr i} { $prgmConfig jtag_force "TB_SH_STAGGER_RELATION_${sh_staggerRefClkName}_$i" [expr ($staggerRelation >> $i) & 1]}
        
        #6: configure shift stagger value
        puts "INFO:         Shift stagger edges is $sh_staggerEdges"
        binary scan [binary format I1 $sh_staggerEdges] B* binary_sh_staggerEdges
        $prgmConfig jtag_force "TB_SH_STAGGER_VAL_${monitorName}\[16:0\]" $binary_sh_staggerEdges

        #6: configure capture duty value
        if {[info exists Capture_duty]} {
           puts "INFO:         Capture duty is ${Capture_duty}%"
           binary scan [binary format I1 $Capture_duty] B* binary_capture_duty
           $prgmConfig jtag_force "TB_ftm_duty_capture_${monitorName}\[9:0\]" $binary_capture_duty
        } else {
           puts "INFO:         Capture duty is 50% (default)"
        }
}
}

proc ::ATE::atpg_init::clock_stuckat_test_sequence {prgmConfig testConfig ftmorsaClockConfig atpg_clock_verif_config atpg_ovr_mode} {
    set sub_clock_mode [config_find $atpg_clock_verif_config TMP/sub_clock_mode]
    set sub_mode [config_find $atpg_clock_verif_config TMP/sub_mode]
    set clock_atpg_mode [config_find $atpg_clock_verif_config TMP/clock_atpg_mode]
    set num_core_shift_pulses [config_find $atpg_clock_verif_config TMP/num_core_shift_pulses]
    set serdes_slow_clk_freq_mhz [config_find $atpg_clock_verif_config TMP/serdes_slow_clk_freq_mhz]
    set test_clk_freq_mhz [config_find $atpg_clock_verif_config TMP/test_clk_freq_mhz]
    set scan_en_pin [config_find $atpg_clock_verif_config TMP/scan_en_pin]
    set SerdesClkList [config_list [config_find $atpg_clock_verif_config TMP/SerdesClkList]]
    set TestClkList [config_list [config_find $atpg_clock_verif_config TMP/TestClkList]]
    set tap_freq_mhz [config_find $atpg_clock_verif_config TMP/tap_freq_mhz]
    set enable_ip_list [config_list [config_find $atpg_clock_verif_config TMP/enable_ip_list]]
    set ftm_cap_win [config_find $atpg_clock_verif_config TMP/ftm_cap_win]

    set jtagConfig [$prgmConfig get_jtag_config]

    #Get from ftm/s@ yml
    set portListConfig [config_find $ftmorsaClockConfig PortList]
    set staggerConfig [config_find $ftmorsaClockConfig StaggerConfig]
    foreach tmp [config_list $portListConfig] {
        if [regexp $sub_clock_mode [config_map_keys $tmp]] {
            set portConfig $tmp
        }
    }

# Define "clock_atpg_mode" nickname that describes clock behavior for given ATPG $sub_mode
set modeConfig [config_find $portConfig $sub_clock_mode/mode_${sub_mode}]
set fieldsConfig [config_find $modeConfig FIELDS]
set entries [config_list [config_find $modeConfig ENTRIES]]
# Decode field indices
set fieldsList [split $fieldsConfig "\t"]
for {set i 0} {$i < [llength $fieldsList]} {incr i} {
set FieldIndex([lindex $fieldsList $i]) $i
}


    if {$clock_atpg_mode eq "TAM"} {
        #Force onebit occ at first, because the pulse_gen would not wait for this
        set name [config_find $atpg_clock_verif_config Default/One_bit_OCC/name]
        set width [config_find $atpg_clock_verif_config Default/One_bit_OCC/width]
        set value 1
        puts "INFO: Now force $width wide chain $name to $value"
        ::ATE::atpg_init::FORCE_CLOCK_CHAIN $prgmConfig $testConfig $name $width $value

    #Step a, assert scan_en & de-assert cap_en
    $prgmConfig set_pin_value $scan_en_pin 1
    foreach TestClk $TestClkList {
    if {[regexp {\[} $TestClk]} {
    $prgmConfig jtag_force "\\${TestClk}_cap_en " 0
    } else {
    $prgmConfig jtag_force "${TestClk}_cap_en" 0
    }
    }
    $prgmConfig waitRti 1
    $prgmConfig jtag_force seq_scan_en 1
    $prgmConfig waitRti 1
    # 4.2: wait until core shift done
    # Total wait time = (15 cycles @ serdes_fast_clk for FSM transition) + (core shift cycles)
    set waitCycles(fsm_transition) [expr int(ceil(15.0 * $tap_freq_mhz / $test_clk_freq_mhz))]
    set waitCycles(scan_en_delay) [expr int(ceil(3.0 * $tap_freq_mhz / 5))]
    set waitCycles(core_shift) [expr int(ceil($num_core_shift_pulses * $tap_freq_mhz / $test_clk_freq_mhz))]
    set totalWaitCycles [expr $waitCycles(fsm_transition) + $waitCycles(scan_en_delay) + $waitCycles(core_shift)]
    puts "Waiting for total of \n\
    \ \ $waitCycles(fsm_transition) tck cycles (fsm_transition)\n\
        + $waitCycles(scan_en_delay) tck cycles (scan en delay)\n\
    + $waitCycles(core_shift) tck cycles (core_shift)\n\
    -------------------------------------------- \n\
    $totalWaitCycles tck cycles (TOTAL) . override to be 100"
    $prgmConfig waitRti $totalWaitCycles
    
    # 4.3: de-assert scan_en, assert cap_en
    $prgmConfig set_pin_value $scan_en_pin 0
    $prgmConfig jtag_force seq_scan_en 0
    foreach TestClk $TestClkList {
    if {[regexp {\[} $TestClk]} {
    $prgmConfig jtag_force "\\${TestClk}_cap_en " 1
    } else {
    $prgmConfig jtag_force "${TestClk}_cap_en" 1
    }
    }
    # 4.4: wait until capture phase done
    set waitCycles(capture) [expr int(ceil($ftm_cap_win))]
    puts "Waiting for $waitCycles(capture) for capture"
    $prgmConfig waitRti $waitCycles(capture)
    # 4.5: Need an extra scan_en posedge to check final results. Just need a posedge, no need to wait for complete shift+capture
    $prgmConfig set_pin_value $scan_en_pin 1
    $prgmConfig jtag_force seq_scan_en 1
    $prgmConfig waitRti [expr 10 + $waitCycles(fsm_transition)]
    foreach TestClk $TestClkList {
    if {[regexp {\[} $TestClk]} {
    $prgmConfig jtag_force "\\${TestClk}_cap_en " 0
    } else {
    $prgmConfig jtag_force "${TestClk}_cap_en" 0
    }
    }
    }
    if {$clock_atpg_mode eq "XTR"  && [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] concurrent] } {
        puts "enable concurrent run for xtr"
        set loop_cnt 0
        #1. initialize scan_en
        $prgmConfig set_enable_value $scan_en_pin 1
        $prgmConfig set_pin_value $scan_en_pin 0
    $prgmConfig waitRti 1
    
        foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            puts "the test order is $chiplet ->"
        }
        foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            
            #2. force/release monitors
            foreach entry $entries {
                set elementList [split $entry "\t"]
                set name            [lindex $elementList $FieldIndex(NAME)]
                regsub -all {[^a-zA-Z0-9_]+} $name {_} monitorName
                regexp .*_(.*) $chiplet match includeName
                set includeNameSuffix "tb_chip_${includeName}_"
                if {[regexp $includeNameSuffix $monitorName]} {
                    puts "enable monitor checker $monitorName in chiplet $chiplet"
                    $prgmConfig jtag_release "tb.FTM_${monitorName}_XTR_STUCKAT_SERDES_CHECKER.scan_en"
                } else {
                    puts "Disable monitor checker $monitorName"
                    $prgmConfig jtag_force "tb.FTM_${monitorName}_XTR_STUCKAT_SERDES_CHECKER.scan_en" 0
                }
            }
            $prgmConfig waitRti 1
    
            set exclude_ip_list [lreplace $enable_ip_list [lsearch $enable_ip_list $chiplet] [lsearch $enable_ip_list $chiplet]]
    
            # update expected capture pulses cnt
            #3. shift phase, set target chiplet scan_en=1; set X for non-target chiplet 
            puts "set idu scan_en input to 1 to start shift"
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 1
            $prgmConfig jtag_force "tb.xtr_concurrent_inst.concurrent_se_${chiplet}" 0
            $prgmConfig set_pin_value $scan_en_pin 1
            foreach exclude_chiplet $exclude_ip_list {
                if {[regexp {_t0} $exclude_chiplet]} { continue }
                puts "force $exclude_chiplet scan_en to an slow clock"
                $prgmConfig jtag_force "tb.xtr_concurrent_inst.concurrent_se_${exclude_chiplet}" 1
            }
    
            $prgmConfig waitRti 1
    
            #4. occ load
            puts "program occ after scan_en 1 , need wait 10 serdes1f cycle for pipeline"
            puts "wait [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)] cycle"
            $prgmConfig waitRti [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
            set value 1;    # occ_clkchain==1 for occ_num_of_testclks=1
            set width [config_find $atpg_clock_verif_config Default/Local_OCC/width]
            set name [config_find $atpg_clock_verif_config Default/Local_OCC/name]

            lappend OccNameList ${name}_${chiplet}
    
            foreach OccName $OccNameList {
                puts "INFO: Now force $width wide chain $OccName to $value"
                ::ATE::atpg_init::FORCE_CLOCK_CHAIN $prgmConfig $testConfig $OccName $width $value
            } 
    
            $prgmConfig waitRti 10
            #5. wait until core shift done
            # Total wait time = (15 cycles @ serdes_fast_clk for FSM transition) + (core shift cycles)
            set waitCycles(fsm_transition) [expr int(ceil(15.0 * $tap_freq_mhz / $serdes_slow_clk_freq_mhz))]
            set waitCycles(core_shift)     [expr int(ceil($num_core_shift_pulses * $tap_freq_mhz / $serdes_slow_clk_freq_mhz))]
            set totalWaitCycles [expr $waitCycles(fsm_transition) + $waitCycles(core_shift)]
            puts "Waiting for total of \n\
            \ \ $waitCycles(fsm_transition) tck cycles (fsm_transition)\n\
            + $waitCycles(core_shift) tck cycles (core_shift)\n\
            -------------------------------------------- \n\
            $totalWaitCycles tck cycles (TOTAL) . override to be 100"
        $prgmConfig waitRti $totalWaitCycles
            $prgmConfig waitRti [expr int(20 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
    
            #6. set scan_en=0, initiate capture state transition in IDU
            puts "set idu scan_en input to 0 to start capture"
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 0
            $prgmConfig set_pin_value $scan_en_pin 0
            $prgmConfig waitRti 1
            
            #7. wait until capture phase done
            set waitCycles(capture)        [expr int(ceil($ftm_cap_win))]
            puts "Waiting for $waitCycles(capture) for capture"
            $prgmConfig waitRti $waitCycles(capture)
    
            $prgmConfig waitRti [expr 10 + $waitCycles(fsm_transition)]
    
            #8. update expected capture pulses cnt(10 puslese for first loop, 11 for other loops)
            foreach entry $entries {
                set elementList [split $entry "\t"]
                set name            [lindex $elementList $FieldIndex(NAME)]
                regsub -all {[^a-zA-Z0-9_]+} $name {_} monitorName
                binary scan [binary format I1 [expr $num_core_shift_pulses + 1]] B* binary_num_core_shift_pulses
                $prgmConfig jtag_force "TB_ftm_shift_cnt_overwrite_${monitorName}\[9:0\]" $binary_num_core_shift_pulses
            }
    
            ##9. toggle exclude ip scan_en once at the end to clear X 
            foreach exclude_chiplet $exclude_ip_list {
                if {[regexp {_t0} $exclude_chiplet]} { continue }
                $prgmConfig jtag_force "tb.tb_idu_se_input_${exclude_chiplet}" 0
                $prgmConfig waitRti [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
                $prgmConfig jtag_force "tb.tb_idu_se_input_${exclude_chiplet}" 1
                $prgmConfig waitRti [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
                puts "release $exclude_chiplet scan_en"
                #$prgmConfig jtag_release "tb.tb_idu_se_input_${exclude_chiplet}"
                $prgmConfig jtag_force "tb.xtr_concurrent_inst.concurrent_se_${exclude_chiplet}" 0
            }
            puts "need wait 10 serdes1f cycle for pipeline"
            puts "wait [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)] cycle"
            $prgmConfig waitRti [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
            
            #10. Need an extra scan_en posedge to check final results. Just need a posedge, no need to wait for complete shift+capture
            puts "set idu scan_en input to 1 to start monitor check"
            #$prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 1
            $prgmConfig set_pin_value $scan_en_pin 1
            $prgmConfig waitRti [expr 10 + $waitCycles(fsm_transition)]
            puts "need wait 10 serdes1f cycle for pipeline"
            puts "wait [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)] cycle"
            $prgmConfig waitRti [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
            incr loop_cnt
        }
    
    } elseif {$clock_atpg_mode eq "XTR" } {
    #for IP run, always use -enable_ip arg to specify the IP under-test
    # 4.1 de-assert scan_en at the beginning
    puts "set all ip IDU scan_en to 0"
    foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 0
    }
    $prgmConfig set_enable_value $scan_en_pin 1
    $prgmConfig set_pin_value $scan_en_pin 0
    $prgmConfig waitRti 1
   
        # 4.2: set scan_en=1, initiate core shift state transition in IDU
    puts "set idu scan_en input to 1 to start shift"
    foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 1
    }
    $prgmConfig set_pin_value $scan_en_pin 1
    $prgmConfig waitRti 1
   
        # 4.3 occ load
    puts "program occ after scan_en 1 , need wait 10 serdes1f cycle for pipeline"
    puts "wait [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)] cycle"
    $prgmConfig waitRti [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
   
        set value 1; # occ_clkchain==1 for occ_num_of_testclks=1
    set width [config_find $atpg_clock_verif_config Default/Local_OCC/width]
        set name [config_find $atpg_clock_verif_config Default/Local_OCC/name]
    foreach chiplet $enable_ip_list {
            lappend OccNameList ${name}_${chiplet}
        }
    foreach OccName $OccNameList {
            puts "INFO: Now force $width wide chain $OccName to $value"
    ::ATE::atpg_init::FORCE_CLOCK_CHAIN $prgmConfig $testConfig $OccName $width $value
    }
    
    $prgmConfig waitRti 10
    # 4.4: wait until core shift done
    # Total wait time = (15 cycles @ serdes_fast_clk for FSM transition) + (core shift cycles)
    set waitCycles(fsm_transition) [expr int(ceil(15.0 * $tap_freq_mhz / $serdes_slow_clk_freq_mhz))]
    set waitCycles(core_shift) [expr int(ceil($num_core_shift_pulses * $tap_freq_mhz / $serdes_slow_clk_freq_mhz))]
    set totalWaitCycles [expr $waitCycles(fsm_transition) + $waitCycles(core_shift)]
    puts "Waiting for total of \n\
    \ \ $waitCycles(fsm_transition) tck cycles (fsm_transition)\n\
    + $waitCycles(core_shift) tck cycles (core_shift)\n\
    -------------------------------------------- \n\
    $totalWaitCycles tck cycles (TOTAL) . override to be 100"
    $prgmConfig waitRti $totalWaitCycles
    $prgmConfig waitRti [expr int(20 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
    
    # 4.5: set scan_en=0, initiate capture state transition in IDU
    puts "set idu scan_en input to 0 to start capture"
    foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 0
    }
    $prgmConfig set_pin_value $scan_en_pin 0
    $prgmConfig waitRti 1
    
    # 4.6: wait until capture phase done
    set waitCycles(capture) [expr int(ceil($ftm_cap_win))]
    puts "Waiting for $waitCycles(capture) for capture"
    $prgmConfig waitRti $waitCycles(capture)
   
        # 4.7: Need an extra scan_en posedge to check final results. Just need a posedge, no need to wait for complete shift+capture
    puts "set idu scan_en input to 1 to start monitor check"
    foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 1
    }
    $prgmConfig set_pin_value $scan_en_pin 1
    
    $prgmConfig waitRti [expr 10 + $waitCycles(fsm_transition)]
    }

    #Check result
    set jtagConfig [$prgmConfig get_jtag_config]
    if {[jtag_output_type $jtagConfig] == "VerilogXface"} {
        set clock_mon_active TB_clock_mon_active
        set_pin_value $jtagConfig $clock_mon_active 0
        waitRti $jtagConfig 1
        puts "Checking clock monitors for any errors..."
        set_pin_value $jtagConfig TB_clock_mon_error 0
        waitRti $jtagConfig 1
        $prgmConfig set_pin_value TB_clock_mon_error X
        $prgmConfig waitRti 5
    }

}

proc ::ATE::atpg_init::clock_stuckat { prgmConfig testConfig ftm_cap_win legacy_serdes_preshift_count} {
puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]============== @cycle [$prgmConfig get_current_cycle] ENTER procedure: [lindex [info level 0] 0]=============="
set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set chip_name [$prgmConfig name]
set design_type [config_map_value [config_find $testConfig CURRENT_TEST] design_type]
set design_scope [config_map_value [config_find $testConfig CURRENT_TEST] design_scope]
set clock_mode [config_map_value [config_find $testConfig CURRENT_TEST] clock_mode]
set sub_clock_mode [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CLOCK_CONFIG] $clock_mode]]; # this is a list,but we only allow one element
set sub_mode [config_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]]; # this is a list, but we only allow one element
set relative_path_local2jtag [config_find $testConfig CURRENT_TEST/relative_path/test2jtag]
set scan_en_pin [::pkgtool::get_vlog_pins_with_test_function $die_obj {TESTCTL0}]
regsub -all {[\{\}]} $scan_en_pin {} scan_en_pin
set SerdesClkList [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=serdes4f_clk)}]
set TestClkList [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=.*)}]
    set clockProgrammingConfig [::ATE::clock_init_tasks::get_clock_programming_config $testConfig]
    set onehot_mode [config_find $testConfig USER_CUSTOM_ARGS/onehot_mode]
    set edge_mode [config_find $testConfig USER_CUSTOM_ARGS/edge_mode]
    set enable_all_atpg_ovr_mode [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/API_ARGUMENTS/enable_all_atpg_ovr_mode] 
    set atpg_ovr_mode_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/API_ARGUMENTS/atpg_ovr_mode_list]

puts "INFO: chip_name  is $chip_name "
puts "INFO: design_type  is $design_type "
puts "INFO: design_scope  is $design_scope "
puts "INFO: clock_mode  is $clock_mode "
puts "INFO: sub_clock_mode  is $sub_clock_mode "
puts "INFO: sub_mode  is $sub_mode "
puts "INFO: relative_path_local2jtag  is $relative_path_local2jtag "
puts "INFO: scan_en_pin  is $scan_en_pin "
puts "INFO: SerdesClkList  is $SerdesClkList "
puts "INFO: TestClkList  is $TestClkList "
    puts "INFO: onehot_mode  is $onehot_mode"
    puts "INFO: edge_mode  is $edge_mode"
    puts "INFO: enable_all_atpg_ovr_mode is $enable_all_atpg_ovr_mode"
    puts "INFO: atpg_ovr_mode_list is $atpg_ovr_mode_list"

# dealing with test specific argument
set listargsParams(debug_mode) -1
if {[catch {config_isa [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]}]} {
set listargsParams(mode) [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]
} else {
if {[config_isa [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]] == "VECTOR"} {
set listargsParams(mode) [config_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]]
} else {
puts "ERROR:exception of getting 'CURRENT_TEST/CURRENT_SUBTEST/sub_modes' from the test configure object"
exit 1;
}
}
if { $listargsParams(mode) != "" } {
set listargsParams(debug_mode) $listargsParams(mode)
} else {
set listargsParams(debug_mode) -1
}
if { $listargsParams(debug_mode) == -1 } {
puts "ERROR: Please specify sub_mode for clock_ftm test by '-sub_mode x'"
exit 1;
} elseif { [llength $listargsParams(debug_mode)] > 1 } {
puts "ERROR: '-sub_mode' only support one entry now"
exit 1;
} else {
puts "Running single sub_mode: $listargsParams(debug_mode)"
}
    #Get clock_atpg_mode
    switch -regexp $sub_mode {
TAM|UPHY|PEX|FABRIC { set clock_atpg_mode "TAM" }
XTR|shift_only { set clock_atpg_mode "XTR" }
default { puts "ERROR: only XTR_STUCKAT_SERDES, LEGACY_INTEST_STUCKAT_SERDES, and LEGACY_EXTEST_STUCKAT_SERDES supported!"; exit 1; }
}
puts "INFO: sub_clock_mode.clock_atpg_mode $sub_clock_mode.$clock_atpg_mode"
    
    #Get serdes div ratio from common_mode
    set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top]]
    puts "INFO: common modes: $common_modes"
    if {[llength $common_modes] eq "0"} {
        puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
        exit 1    
    }
    foreach common_mode $common_modes {
        if {[regexp "SERDES_RATIO" $common_mode]} {
            switch $common_mode {
                SERDES_RATIO_S4 { set serdes_div_ratio 4 }
                SERDES_RATIO_S6 { set serdes_div_ratio 6 }
                SERDES_RATIO_S8 { set serdes_div_ratio 8 }
                SERDES_RATIO_S12 { set serdes_div_ratio 12 }
                SERDES_RATIO_S24 { set serdes_div_ratio 24 }
            }
        }
    }
    #Get JTAG_TCK test_clock serdes_fast_clk serdes_slow_clk frequency
set tap_freq_khz [$prgmConfig get_tap_frequency]
set tap_freq_mhz [expr $tap_freq_khz * 0.001]
# set test_clk_freq_mhz 90.009
set test_clk_freq_mhz 62.5
    switch -regexp "$sub_clock_mode.$clock_atpg_mode" {
BYPASS_MODE_ISTCLOCK.XTR {
set serdes_fast_clk_freq_mhz 203.998
set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
}
default {
set serdes_fast_clk_freq_mhz 500.0
set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
}
}

#Get default ip instances when fullchip simulation 
    set IpList [string tolower [::ATE::AteFlowUtils::get_ip_type -prgmConfig $prgmConfig -all]]
    foreach IpType $IpList {
        set IpType NV_${IpType}
        puts "INFO: IpType = $IpType"
        if {[regexp {dram|hbm|other2} $IpType]} {
            puts "INFO:  Skip $IpType"
            continue
        }
        lappend default_ip_list $IpType
    }
if {[config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip] ne ""} {
set enable_ip_list [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip]
} else {
set enable_ip_list $default_ip_list
}
puts "INFO: enable_ip_list is $enable_ip_list"
    #Set shift pulses number
    set num_core_shift_pulses 10

    
    ######1. BEGIN test-bench setting #####
    #Get serdes/test clock pad prefix for force
    foreach SerdesClk $SerdesClkList {
puts "INFO: cell=$SerdesClk"
regsub -all {(\w+)\[(\d+)\]} $SerdesClk {\1__\2__} SerdesClk
puts "INFO: cell=$SerdesClk"
lappend NewSerdesClkList $SerdesClk
}
foreach TestClk $TestClkList {
puts "INFO: cell=$TestClk"
regsub -all {(\w+)\[(\d+)\]} $TestClk {\1__\2__} TestClk
puts "INFO: cell=$TestClk"
    lappend NewTestClkList $TestClk
}
    switch -regexp "$sub_clock_mode.$clock_atpg_mode" {
STA_BYPASS_MODE_SERDESCLOCK.XTR|FTM_BYPASS_MODE_SERDESCLOCK.XTR {
$prgmConfig jtag_force "ftm_mode" 0; # Set ftm_mode=0 so that SCAN_EN pin will be driven as simple ext pin, not by wide_scan_en
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 1 ;# choose serdesclk as source shift clock for tb ftm monitor
$prgmConfig jtag_force "tb.TB_serdesclk_trigger" 1 ;
$prgmConfig jtag_force "tb.TB_clk_freerunning" 1
}
BYPASS_MODE_ISTCLOCK.XTR {
$prgmConfig jtag_force "ftm_mode" 0; # Set ftm_mode=0 so that SCAN_EN pin will be driven as simple ext pin, not by wide_scan_en
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 1 ;# choose serdesclk as source shift clock for tb ftm monitor
$prgmConfig jtag_force "TB_serdesclk_trigger" 1 ;
}
BYPASS_MODE_TESTCLOCK.TAM {
            $prgmConfig jtag_force seq_scan_en 0
$prgmConfig jtag_force "TB_ftm_debug_port_test_sequence_on" 1
$prgmConfig jtag_force "testen_dummy" 1 ;# testen_dummy=1 to unblock wide/fake_scan_en, which will be used in new_FTM_pulse_gen_rz module.
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 0 ;# choose testclk as source shift clock for tb ftm monitor 
$prgmConfig jtag_force "tb.TB_testclk_ctrl_running_62p5" 1 ;# choose 62.5 free run testclk
### BEGIN create shift/capture clock from tb new_FTM_pulse_gen_rz module ###
set shift_pulse_num $num_core_shift_pulses
set capture_pulse_num 1
# foreach TestClk $TestClkList {
# $prgmConfig set_pin_value $TestClk 1
# }
foreach TestClk $NewTestClkList {
if {[lsearch $NewSerdesClkList $TestClk] != -1} { ;# set test-bench serdes clock shift/capture to 0 in testclk based mode
binary scan [binary format I1 $shift_pulse_num] B* binary_shift_pulse_num
                    $prgmConfig jtag_force "TB_shift_${TestClk}_pulse_num\[9:0\]" $binary_shift_pulse_num
                    binary scan [binary format I1 $capture_pulse_num] B* binary_capture_pulse_num
                    $prgmConfig jtag_force "TB_ftm_${TestClk}_pulse_num\[9:0\]" $binary_capture_pulse_num
} else {
                    binary scan [binary format I1 $shift_pulse_num] B* binary_shift_pulse_num
                    $prgmConfig jtag_force "TB_shift_${TestClk}_pulse_num\[9:0\]" $binary_shift_pulse_num
                    binary scan [binary format I1 $capture_pulse_num] B* binary_capture_pulse_num
                    $prgmConfig jtag_force "TB_ftm_${TestClk}_pulse_num\[9:0\]" $binary_capture_pulse_num
}
}
### END create shift/capture clock from tb new_FTM_pulse_gen_rz module ###
}
}
##### END test-bench setting #####
    
    ##### 3.BEGIN configure IDU transactor #####
    puts "serdes_div_ratio = $serdes_div_ratio"
    puts "num_core_shift_pulses = $num_core_shift_pulses"
    puts "legacy_serdes_preshift_count = $legacy_serdes_preshift_count"
    for {set i 0} {$i <= 15} {incr i} {
    # 3.0: configure number of core shift length, in terms of serdes_fast_clk cycles
    $prgmConfig jtag_force "tb_xtr_num_core_shift_pulses_$i" [expr ([expr $num_core_shift_pulses + 1] >> $i) & 1] ;# add 1 pulse due to idu design: the output pulse from idu is shift_pulse - 1
    # 3.1: configure the number of ftm_cap_win
    $prgmConfig jtag_force "tb_ftm_cap_win_$i" [expr ($ftm_cap_win >> $i) & 1]
    }
    $prgmConfig waitRti 200
    ##### END configure IDU transactor #####
    
    
    #Load atpg_clock_verif_config
    if {[file exist $::env(ATE_TOT)/atpg_init/atpg_clock_verif_config.yml]} {
        puts "INFO: Load atpg_clock_verif_config from $::env(ATE_TOT)/atpg_init/atpg_clock_verif_config.yml"
        set atpg_clock_verif_config [config_read_yaml $::env(ATE_TOT)/atpg_init/atpg_clock_verif_config.yml]
    } else {
        puts "INFO: Could not find $::env(ATE_TOT)/atpg_init/atpg_clock_verif_config.yml"
        set atpg_clock_verif_config [config_new_map]
        config_set $atpg_clock_verif_config Default/Local_OCC/name FTM_occ_control_chain_local
        config_set $atpg_clock_verif_config Default/Local_OCC/width 8
        config_set $atpg_clock_verif_config Default/NO_local_OCC/name FTM_occ_control_chain_non_local
        config_set $atpg_clock_verif_config Default/NO_local_OCC/width 8
        config_set $atpg_clock_verif_config Default/One_bit_OCC/name enable_legacy_serdes_en
        config_set $atpg_clock_verif_config Default/One_bit_OCC/width 1
    }
    
    config_set $atpg_clock_verif_config TMP/sub_clock_mode [lindex $sub_clock_mode 0]
    config_set $atpg_clock_verif_config TMP/sub_mode $sub_mode
    config_set $atpg_clock_verif_config TMP/clock_atpg_mode $clock_atpg_mode
    config_set $atpg_clock_verif_config TMP/num_core_shift_pulses $num_core_shift_pulses
    config_set $atpg_clock_verif_config TMP/serdes_slow_clk_freq_mhz $serdes_slow_clk_freq_mhz
    config_set $atpg_clock_verif_config TMP/test_clk_freq_mhz $test_clk_freq_mhz
    config_set $atpg_clock_verif_config TMP/scan_en_pin $scan_en_pin
    config_set $atpg_clock_verif_config TMP/SerdesClkList $SerdesClkList
    config_set $atpg_clock_verif_config TMP/TestClkList $TestClkList
    config_set $atpg_clock_verif_config TMP/tap_freq_mhz $tap_freq_mhz
    config_set $atpg_clock_verif_config TMP/enable_ip_list $enable_ip_list
    config_set $atpg_clock_verif_config TMP/ftm_cap_win $ftm_cap_win
    config_set $atpg_clock_verif_config TMP/serdes_div_ratio $serdes_div_ratio

    #Get atpg override mode
    if {$enable_all_atpg_ovr_mode == "1"} {
        if {[config_find $atpg_clock_verif_config Override_mode] == ""} {
            puts "WARNING: With -enable_all_atpg_ovr_mode, but as atpg_clock_verif_config does not have Override_mode, atpg_ovr_mode_list is only DEFAULT"
            set atpg_ovr_mode_list [list DEFAULT]
        } else {
            set atpg_ovr_mode_list [config_map_keys [config_find $atpg_clock_verif_config Override_mode]]
            puts "INFO: With -enable_all_atpg_ovr_mode, atpg_ovr_mode_list is $atpg_ovr_mode_list"
        }
    } elseif {$atpg_ovr_mode_list != ""} {
        set atpg_ovr_mode_list_tmp ""
        foreach tmp $atpg_ovr_mode_list {
            if {[lsearch [config_map_keys [config_find $atpg_clock_verif_config Override_mode]] $tmp] == "-1"} {
                tn_msg_issue_ATE_102 "ERROR: $tmp that set by -atpg_ovr_mode_list does not exist in atpg_clock_verif_config.yml, Skipping"
            } else {
                set atpg_ovr_mode_list_tmp [concat $atpg_ovr_mode_list_tmp $tmp]
            }
        }
        set atpg_ovr_mode_list $atpg_ovr_mode_list_tmp
        puts "INFO: With -atpg_ovr_mode_list , atpg_ovr_mode_list is $atpg_ovr_mode_list"

    } else {
        puts "INFO: Without -enable_all_atpg_ovr_mode and -atpg_ovr_mode_list, atpg_ovr_mode_list is only DEFAULT"
        set atpg_ovr_mode_list [list DEFAULT]
    }
    
    
    #Get from ftm/s@ yml
    puts "INFO: relative_path_local2jtag ${relative_path_local2jtag}sa_clock_config_${design_type}.yml"
    set ftmorsaClockConfig [config_read_yaml "${relative_path_local2jtag}sa_clock_config_${design_type}.yml"]

    #Start the test
    foreach atpg_ovr_mode $atpg_ovr_mode_list {
        puts "INFO: \$sub_clock_mode/mode_\${sub_mode} = $sub_clock_mode/mode_${sub_mode}"
        puts "INFO: Now is verifying $atpg_ovr_mode"
        puts "INFO: Start the override config"
        ::ATE::atpg_init::over_mode_extra_control $prgmConfig $testConfig $atpg_clock_verif_config $atpg_ovr_mode
        $prgmConfig waitRti 1
        
        puts "INFO: Start the monitor config"
        ::ATE::atpg_init::clock_monitor_setting $prgmConfig $testConfig $ftmorsaClockConfig $atpg_clock_verif_config $atpg_ovr_mode
        $prgmConfig waitRti 1
    
        puts "INFO: Start the test sequence"
        ::ATE::atpg_init::clock_stuckat_test_sequence $prgmConfig $testConfig $ftmorsaClockConfig $atpg_clock_verif_config $atpg_ovr_mode
        $prgmConfig waitRti 1
    }
    if {[regexp "BYPASS_MODE_ISTCLOCK" $sub_clock_mode]} {
::ATE::AteFlowUtils::strobe_frequency_stop -prgmConfig $prgmConfig -testConfig $testConfig
}
set jtagConfig [$prgmConfig get_jtag_config]
if {[jtag_output_type $jtagConfig] == "VerilogXface"} {
set clock_mon_active TB_clock_mon_active
set_pin_value $jtagConfig $clock_mon_active 0
waitRti $jtagConfig 1
puts "Checking clock monitors for any errors..."
set_pin_value $jtagConfig TB_clock_mon_error 0
waitRti $jtagConfig 1
$prgmConfig set_pin_value TB_clock_mon_error X
$prgmConfig waitRti 5
}
    # add for tam, avoid shift_ir mismatch for tam with related to EOT
    if {$clock_atpg_mode eq "TAM"} {
        $prgmConfig jtag_force seq_scan_en 0
$prgmConfig waitRti 20
    }
}

proc ::ATE::atpg_init::Ftm { args } {
puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============  ENTER procedure: [lindex [info level 0] 0]=============="
global unified_scan_spec

# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
{listArgs.arg "" "-option helper; please add -sub_mode tn arg to define SCAN_TEST sub mode defined in the file $::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml, e.g. XTR_STUCKAT_SERDES etc."}
{ftm_cap_win_us.arg "5" "<specify the ftm capture window in the unit of tck period>"}
{legacy_serdes_preshift_count.arg "0" "<specify the number of legacy_serdes_preshift_count values>"}
{debug_occ_index.arg "" "<specify the OCC group index to activate (debug mode)>"}
        {enable_nmeas_lite 0 "<1 enable enable nmeas_lite, 0 disable nmeas_lite>"}
        {enable_nmeas_lite_readout 0 "<1 enable enable nmeas_lite readout, 0 disable nmeas_lite readout>"}
        {enable_all_atpg_ovr_mode  "enable all atpg override mode from atpg_clock_verif_config.yml"}
        {atpg_ovr_mode_list.arg "" "set atpg override mode for clock verification,this could cover specical requirement like onehot and edge control"}
    }

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

array set mainParams [::cmdline::getKnownOptions args $mainOptions]
if {![regexp "^\s*$" $mainParams(ListArgs)]} {
upvar $mainParams(ListArgs) subtest_option
set subtest_option [concat $subtest_option $listArgsOptions]

        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_features" -value "secSHA2"
::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_type" -value "SCAN_TEST"
#::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "global_init_behavior" -value "skip_init"
#::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_init_behavior" -value "skip_init"
::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "chiplet_flow_certified" -value 1

set temp_bak_args $::argv
array set temp_param_array [::cmdline::getKnownOptions temp_bak_args {{sub_mode.arg "" ""}}]
set sub_mode_in $temp_param_array(sub_mode)

# Replace XTR_FTM_SERDES_SERIAL with XTR_FTM_SERDES: it's only a test body indicator, and should not be carried into atpg_init
set i [lsearch $sub_mode_in XTR_FTM_SERDES_SERIAL]
if {$i != -1} {
set sub_mode_in [lreplace $sub_mode_in $i $i XTR_FTM_SERDES]
}

puts "INFO: sub_mode=$sub_mode_in"
if { [regexp "shift_only" $sub_mode_in] } {
::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "XTR_FTM_SERDES"
} else {
::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "$sub_mode_in"
}
return 1
}
    #puts "blueg, dbg here 1"
foreach temp_var_name "prgmConfig testConfig ftm_cap_win_us legacy_serdes_preshift_count debug_occ_index" {
set $temp_var_name $listargsParams($temp_var_name)
}

    ## Johnson add an if condition wrapper here for MATHS ATE.
    set test_name [config_map_value [config_find $testConfig CURRENT_TEST] name]
    if {[regexp maths_ate $test_name]} {
    #    when test name is maths_ate, bypass all clusters through JET, so that no programming will happen since now
        puts "MATHS ATE INFO: the test is $test_name, bypass all programming!"
        $prgmConfig set_controller_property {.*} mode bypass
    }

    puts "INFO: wait [expr [$prgmConfig get_tap_frequency]*${ftm_cap_win_us}/1000] cycles for $ftm_cap_win_us us ftm_cap_win"
    set ftm_cap_win [expr [$prgmConfig get_tap_frequency]*${ftm_cap_win_us}/1000]

set sub_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST] "sub_modes"]]

# Replace XTR_FTM_SERDES_SERIAL with XTR_FTM_SERDES: it's only a test body indicator, and should not be carried into atpg_init
set i [lsearch $sub_modes XTR_FTM_SERDES_SERIAL]
if {$i != -1} {
set sub_modes [lreplace $sub_modes $i $i XTR_FTM_SERDES]
config_set $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes $sub_modes
set serial 1
} else {
set serial 0
}

puts "INFO: sub modes: $sub_modes"
if {[llength $sub_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -sub_mode to set proper scan sub_mode."
exit 1
}

    set uphy_pd_short_init [config_find $testConfig USER_CUSTOM_ARGS/enable_atpg_EOT]
    if {$uphy_pd_short_init eq ""} {set uphy_pd_short_init 0}
    if {$uphy_pd_short_init} {
        puts "INFO: uphy power down sequence called, skipping ATPG API, for XTR programming serdes stagger"
        if {[regexp "XTR" $sub_modes]} {
    set current_cycle [ $prgmConfig get_current_cycle ]
    puts "INFO: program serdes stagger at cycle $current_cycle"
    ::ATE::atpg_init::serdes_stagger -prgmConfig $prgmConfig -testConfig $testConfig
        }
        return 1
    }


    ##### begin: clear sdp x for atpg/ate sim #####
    $prgmConfig set_program_value {.*XTR_TAM_CTL} {.*Select_SDPBypassCtrl.*} -value  1
    $prgmConfig set_program_value {.*XTR_TAM_CTL} {.*SDPBypass.*} -value  1
    $prgmConfig set_program_value {.*XTR_TAM_CTL} {.*XTRControl_ShiftStagger.*} -value  1
    set tmax_init [config_find $testConfig "USER_CUSTOM_ARGS/tmax_init"]
    if { $tmax_init == 1} {
        $prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 1
    } else {
        $prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 0
    }

    
    $prgmConfig program

    set design_type [config_map_value [config_find $testConfig CURRENT_TEST] design_type]
    foreach sub_mode $sub_modes {
        if {$design_type == "flat" && [regexp "XTR" $sub_modes]} {
            #2. toggle serdes_4f, wait few cycles, stop serdes4f
            if {[$prgmConfig is_vec_mode]} {
                puts "for atpg vec sim,toggle serdes_4f to clear pipeline X "
                set current_cycle [ $prgmConfig get_current_cycle ]
                puts "Toggle serdes4f before dft mode programming at $current_cycle"
                set die_obj [config_find $testConfig CURRENT_TEST/die_obj]
                set serdes4f_clk_pin [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=serdes4f_clk)}]
                foreach pin $serdes4f_clk_pin {
                    $prgmConfig set_enable_value $pin 1
                    $prgmConfig set_pin_value    $pin 1
                }
                set serdes_div_ratio     [config_find $testConfig USER_CUSTOM_ARGS/serdes_div_ratio]
                set serdes4fToggleCycle [expr $serdes_div_ratio * 20]
                $prgmConfig wait_cycles $serdes4fToggleCycle
                set curr_cyc [$prgmConfig get_current_cycle]
                set tck_mult [$prgmConfig get_tck_multiple]
                puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
                if {[ expr $curr_cyc % $tck_mult ] != 0} {
                    set wait_cyc [ expr $tck_mult - [ expr $curr_cyc % $tck_mult ]]
                    $prgmConfig wait_cycles $wait_cyc
                    set curr_cyc [$prgmConfig get_current_cycle]
                    puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
                }
                set current_cycle [ $prgmConfig get_current_cycle ]
                puts "Stop serdes4f before dft mode programming at $current_cycle"
                foreach pin $serdes4f_clk_pin {
                    $prgmConfig set_enable_value $pin 1
                    $prgmConfig set_pin_value    $pin 0
                }
            } 
            if {[$prgmConfig is_sim_mode]} {
                puts "for atpg ate sim, toggle serdes_4f to clear pipeline X" 
                $prgmConfig jtag_force "TB_clk_freerunning" 1
                $prgmConfig waitRti [expr int(63 * 500 / ([$prgmConfig get_tap_frequency]/1000))] ;# we need 63/8 = 8 pulses to flush X inside 8 sdps, we have serdes divider, div is 8
                $prgmConfig jtag_force "TB_clk_freerunning" 0
            }
        }
        $prgmConfig program
    }
    ##### end: clear sdp x #####
set dft_modes_config_file "$::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml"
if { [file exists $dft_modes_config_file]} {
puts "INFO: standard dft mode programming yml file found. Reading..."
set dft_modeConfig [config_read_yaml $dft_modes_config_file]
} else {
puts stderr "ERROR: $dft_modes_config_file file is missing. Please fix it first."
exit 1
}

    # inject x on wbr
    if { [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] wbr_injectX] } {
        $prgmConfig jtag_force "tb.enable_force_for_wbr" 1
$prgmConfig wait_cycles 1
    }
# DFT mode programming
set clock_mode [config_map_value [config_find $testConfig CURRENT_TEST] clock_mode]
set sub_clock_mode [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CLOCK_CONFIG] $clock_mode]];

    set rsync [config_find $testConfig USER_CUSTOM_ARGS/resync_serdes]
    set fs_top_up [config_find $testConfig USER_CUSTOM_ARGS/fs_top_up_init]
    if {$rsync eq ""} {set rsync 0}
    if {$fs_top_up eq ""} {set fs_top_up 0}

if {[info procs ::ATE::AteFlowUtils::getTestApiProperty] == "::ATE::AteFlowUtils::getTestApiProperty"} {
set testapi_test_type [::ATE::AteFlowUtils::getTestApiProperty -testConfig $testConfig -categoryName execution_ctrl -propName test_type]
set testapi_dft_mode [::ATE::AteFlowUtils::getTestApiProperty -testConfig $testConfig -categoryName execution_ctrl -propName dft_mode]
} else {
set testapi_test_type ""
set testapi_dft_mode ""
}
if { $testapi_dft_mode ne "" } {
        if { ($rsync || $fs_top_up ) != 1 } {
    puts "INFO: set dft program mode to \"$testapi_test_type/$testapi_dft_mode\""
    #commenting $prgmConfig set_program_mode "$testapi_test_type/$testapi_dft_mode"
    ::ATE::AteFlowUtils::set_default_dft_mode -testConfig $testConfig -prgmConfig $prgmConfig
        }
} else {
puts "WARNING: testapi_dft_mode is required for scan test"
}
    ## fs_validation
    set fs_validation     [config_find $testConfig USER_CUSTOM_ARGS/fs_validation]
    if {$fs_validation ne ""} {
        puts "INFO: fs_validation is being set on FS region $fs_validation"
        ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*DFT_FS_CTRL} {.*DFT_FS_CTRL} 0
        #Below force programming added by subbu after referring to tu102 to see the tags in INIT for the register
        $prgmConfig program -force
    }

    ## check if rsync needs to be called ##
set rsync [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] resync_serdes]
set fstate [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] resync_fstate]
if { $rsync == 1 } { 
puts "Calling resync serdes"
if { ! [file exists $fstate] } { puts "ERR: provide fstate yml file: $fstate" }
::ATE::atpg_init::resync_serdes -prgmConfig $prgmConfig -testConfig $testConfig -fstate $fstate
return 1
}

    ## check if fs_top_up needs to be called ##
    set fs_top_up [config_find $testConfig USER_CUSTOM_ARGS/fs_top_up_init]
    if { $fs_top_up == 1 } {
       puts "Calling fs_top_up"
       ::ATE::atpg_init::fs_top_up -prgmConfig $prgmConfig -testConfig $testConfig
       puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============LEAVE procedure: [lindex [info level 0] 0]=============="
       return 1
    }

foreach sub_mode $sub_modes {
if {[regexp "FTM" $sub_mode] || [regexp "STUCKAT" $sub_mode]} {
puts "INFO: Validating sub mode $sub_mode..."
            if { [config_find $dft_modeConfig "SCAN_TEST/${sub_mode}"] != ""} {
puts "INFO: $sub_mode is valid sub_mode"
} else {
puts stderr "ERROR: sub_mode $sub_mode is invalid. Please follow $dft_modes_config_file for the list of sub_mode's allowed"
exit 1
}
} else {
puts stderr "WARNING: sub mode $sub_mode is not SCAN_TEST sub mode"
}
}
# Please specify the test API specific programming here
set tmax_init [config_find $testConfig "USER_CUSTOM_ARGS/tmax_init"]
    if {[config_map_value [config_find $testConfig USER_CUSTOM_ARGS] tam_forceflow]} {
       set tam_forceflow_flag 1
    } else {
       set tam_forceflow_flag 0
    }
    if { $tam_forceflow_flag == 0 } {
if { $tmax_init == 1} {
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 1
} else { 
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 0
}
    }

switch -regexp $sub_mode {
TAM|UPHY|PEX|FABRIC { set clock_atpg_mode "TAM" }
XTR|shift_only { set clock_atpg_mode "XTR" }
default { puts "ERROR: only XTR_STUCKAT_SERDES, LEGACY_INTEST_STUCKAT_SERDES, and LEGACY_EXTEST_STUCKAT_SERDES supported!"; exit 1; }
}
    puts "dbg, blueg, sub_modes = $sub_modes; clock_atpg_mode = $clock_atpg_mode"
    puts "unified_scan_spec is $unified_scan_spec"
    if {[regexp "XTR" $sub_modes] || [regexp "XTR" $clock_atpg_mode]} {
        if {[file exists $unified_scan_spec]} {
            set accessConfig [config_read_yaml $unified_scan_spec]
            set pipe_ports [ config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/INPUTS]]
            set pipe_port_0 [ lindex $pipe_ports 0]
            set input_pipe_count [ config_find $accessConfig SCAN_IOS/XTREME_X4/IO_PIPELINES/$pipe_port_0/INPUT_PIPE_CNT]
            set output_pipe_count [ config_find $accessConfig SCAN_IOS/XTREME_X4/IO_PIPELINES/$pipe_port_0/OUTPUT_PIPE_CNT]
            set xtr_link_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_link_fast_scanin_pipes"]
            set xtr_link_fast_scanout_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_link_fast_scanout_pipes"]
            if {$xtr_link_fast_scanin_pipes ne "" } {
                if {$xtr_link_fast_scanin_pipes != $input_pipe_count} {
                    tn_msg_issue_ATE_102 "xtr_link_fast_scanin_pipes argument $xtr_link_fast_scanin_pipes is not equal to INPUT_PIPE_CNT from scanIo.yml $input_pipe_count"
                    #exit;
                }
            }
            if {$xtr_link_fast_scanout_pipes ne "" } {
                if {$xtr_link_fast_scanout_pipes != $output_pipe_count} {
                    tn_msg_issue_ATE_102 "xtr_link_fast_scanout_pipes argument $xtr_link_fast_scanout_pipes is not equal to OUTPUT_PIPE_CNT from scanIo.yml $output_pipe_count"
                    #exit;
                }
            }
        }
        ::ATE::atpg_init::serdes_div_reset -prgmConfig $prgmConfig -testConfig $testConfig
} else {
set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set scan_en_ext_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCTL0 ] 0 ]
puts "INFO: scan_en_ext_pin $scan_en_ext_pin"
if { $scan_en_ext_pin eq "" } { 
puts stderr "ERROR: scan_en_ext pin is not defined" 
exit 1 
}

if { [file exists $unified_scan_spec]} {
set accessConfig [config_read_yaml $unified_scan_spec]
set ufi_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
puts "INFO: UFI pin list is $ufi_list"
set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
puts "INFO: serdes4f pin list is $serdes4f_list"
} else { 
set ufi_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj UFI ] 0 ]
set serdes_4f_clk_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCLK=serdes4f_clk ] 0]
            if {$ufi_pin ne ""} {
    set ufi_list [ list $ufi_pin]
                puts "INFO: UFI pin list is $ufi_list"
            }
set serdes4f_list [ list $serdes_4f_clk_pin]
puts "INFO: serdes4f pin list is $serdes4f_list"
if {!([$prgmConfig is_sim_mode] || [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] ist_mode])} {
if { $ufi_pin eq "" } { 
puts stderr "ERROR: ufi_pin is not defined" 
exit 1 
}
if { $serdes_4f_clk_pin eq "" } { 
puts stderr "ERROR: serdes_4f_clk pin is not defined" 
exit 1 
}
}
}

set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
puts "INFO: common modes: $common_modes"
if {[llength $common_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
exit 1
}
foreach common_mode $common_modes {
if {[regexp "SERDES_RATIO" $common_mode]} {
switch $common_mode {
SERDES_RATIO_S4 { set SerdesRatio 4 }
SERDES_RATIO_S6 { set SerdesRatio 6 }
SERDES_RATIO_S8 { set SerdesRatio 8 }
SERDES_RATIO_S12 { set SerdesRatio 12 }
SERDES_RATIO_S24 { set SerdesRatio 24 }
}
}
}

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Make UFI 0 and serdes fast clock 0 at cycle $current_cycle"
        if { [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] test_trigger] } {
            puts "blueg, can't find ufi pin for now, comment out for clock sims for now"
        } else {
            if {[info exists ufi_list]} {
                foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
            }
        }
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
        if {[$prgmConfig is_sim_mode]} {
            # ATE simulation: turn off serdes_4f_clk
            $prgmConfig jtag_force "TB_clk_freerunning" 0
        }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 20

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Asserting scan enable at cycle $current_cycle"
$prgmConfig set_pin_value $scan_en_ext_pin 1
$prgmConfig program

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Wait for 120 * serdes ratio cycles at cycle $current_cycle"
set wait_cyc [ expr 120 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: De-asserting scan enable at cycle $current_cycle"
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 20

::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After wait cycle $current_cycle"
}

if {[regexp "XTR" $sub_mode]||[regexp "shift_only" $sub_mode]} {
# bug 1634381.
# irrespective of ECK or ICK mode, this bit should be 1 for XTR 
# for ECK should be 0 and ICK should be 1 in TAM Serdes 
# Because of this conflict cannot be done in standard programing yml 
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*TamControl_SerdesClockMode" -value 1
$prgmConfig program

        # Set DFT_FS_CTRL bits to 1 (the reset value) and add a JRD shift. This is needed to do FSCheck by flipping tags on tester
        if {$design_type eq "flat"} {
            ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*DFT_FS_CTRL} {.*DFT_FS_CTRL} 1
            $prgmConfig program -force
        }

set xtr_ufi_selftest [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ufi_selftest"]
if { $xtr_ufi_selftest } {
::ATE::atpg_init::ufi_selftest -prgmConfig $prgmConfig -testConfig $testConfig
}
::ATE::atpg_init::ufi_reset_sequence -prgmConfig $prgmConfig -testConfig $testConfig
#::ATE::atpg_init::serdes_div_reset -prgmConfig $prgmConfig -testConfig $testConfig
} else {
::ATE::atpg_init::tam_init_seq -prgmConfig $prgmConfig -testConfig $testConfig
}

    if { $tam_forceflow_flag == 0} {
$prgmConfig set_program_value ".*/CLK_CTL" ".*tmc2clk_block_x_on_clockchain_in_setup.*" -value 0
    $prgmConfig program
    if {[$prgmConfig list_registers .*TEST_MASTER_CTRL] != ""} {
        $prgmConfig set_program_value {.*CHIPLET_LOGIC} {.*} -value 1'b0 -replicate
        $prgmConfig program -force
    }
    }

set num_1500_pipelines [$prgmConfig get_total_num_ieee1500_pipelines]
puts "INFO: Waiting for twice 1500 pipelines $num_1500_pipelines"
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Before wait cycle $current_cycle"

$prgmConfig waitRti $num_1500_pipelines
$prgmConfig waitRti $num_1500_pipelines

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After wait cycle $current_cycle"

    # make scan enable as Z to avoid contention on scan enable & scan enable observe port
    if {[regexp "XTR" $sub_mode]} {
        if { [file exists $unified_scan_spec]} {
            set accessConfig [config_read_yaml $unified_scan_spec]
            set scan_en_pin [lindex [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SCAN_EN_PORTS]] 0]
            puts "INFO: scan_en pin is $scan_en_pin"
        } else { 
   set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
           set scan_en_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCTL0 ] 0 ]
            puts "INFO: scan_en pin is $scan_en_pin"
        }
        #regsub -all {[\{\}]} $scan_en_pin {} scan_en_pin
        $prgmConfig set_pin_value $scan_en_pin Z
    }
    
# additional 100 waitRti as the above only applies tck for 5 + 5 = 10 waitRti
for {set i 0} {$i < 20} {incr i} {
$prgmConfig waitRti 5
}

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After additional 100 waitRti $current_cycle"

    puts "INFO: Enter Proc ism__ism_noise__ISM_NMEAS_LITE"
    if { $listargsParams(enable_nmeas_lite) } {
        package require atpg_init_tasks_ism
        ::ATE::atpg_init_ism::ism__ism_noise__ISM_NMEAS_LITE $prgmConfig $testConfig
    } else {
    puts "Don't run ism__ism_noise__ISM_NMEAS_LITE proc"
    }


    puts "Garyk, start dump"
    $prgmConfig jtag_force "TB_enable_fsdb_dump" 1


puts "INFO: End of atpg_init of Ftm"
if {[$prgmConfig is_sim_mode]} {
puts "sim mode for ATE test"
if {$serial} {
::ATE::atpg_init::atpg_cutpoint $prgmConfig $testConfig $ftm_cap_win $legacy_serdes_preshift_count $debug_occ_index
} else {
            puts "INFO: SLCG/BLCG is controlled by scan flops, but our monitor are after them, need below prgm to force them open, this is simulation only"
            ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*CLK_PCCM_CTL} {.*tmc2clk_disable_clock_gating.*} 1
            ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*CLK_PCCM_CTL} {.*tmc2clk_ctsroot_disable_clk_gating.*} 1
            ::ATE::AteCustomUtils::prgm_if_exist $prgmConfig {.*CLK_CTL} {.*tmc2clk_ctsroot_disable_clk_gating.*} 1
            $prgmConfig set_program_value {.*/ATPG_CTL} {.*tmc2slcg_disable_clock_gating.*} -value 1'b1
            $prgmConfig program

::ATE::atpg_init::clock_ftm $prgmConfig $testConfig $ftm_cap_win $legacy_serdes_preshift_count
}
}

    puts "INFO: Enter Proc ism__ism_noise__ISM_NMEAS_LITE__readout"
    if { $listargsParams(enable_nmeas_lite_readout) } {
        ::ATE::atpg_init_ism::ism__ism_noise__ISM_NMEAS_LITE__readout $prgmConfig $testConfig
    } else {
    puts "Don't run ism__ism_noise__ISM_NMEAS_LITE__readout proc"
    }
}

proc ::ATE::atpg_init::clock_ftm_test_sequence {prgmConfig testConfig ftmorsaClockConfig atpg_clock_verif_config atpg_ovr_mode {IsFirstRun 1}} {
    set sub_clock_mode [config_find $atpg_clock_verif_config TMP/sub_clock_mode]
    set sub_mode [config_find $atpg_clock_verif_config TMP/sub_mode]
    set clock_atpg_mode [config_find $atpg_clock_verif_config TMP/clock_atpg_mode]
    set num_core_shift_pulses [config_find $atpg_clock_verif_config TMP/num_core_shift_pulses]
    set serdes_slow_clk_freq_mhz [config_find $atpg_clock_verif_config TMP/serdes_slow_clk_freq_mhz]
    set test_clk_freq_mhz [config_find $atpg_clock_verif_config TMP/test_clk_freq_mhz]
    set scan_en_pin [config_find $atpg_clock_verif_config TMP/scan_en_pin]
    set SerdesClkList [config_list [config_find $atpg_clock_verif_config TMP/SerdesClkList]]
    set TestClkList [config_list [config_find $atpg_clock_verif_config TMP/TestClkList]]
    set tap_freq_mhz [config_find $atpg_clock_verif_config TMP/tap_freq_mhz]
    set enable_ip_list [config_list [config_find $atpg_clock_verif_config TMP/enable_ip_list]]
    set ftm_cap_win [config_find $atpg_clock_verif_config TMP/ftm_cap_win]

    set jtagConfig [$prgmConfig get_jtag_config]

    #Get from ftm/s@ yml
    set portListConfig [config_find $ftmorsaClockConfig PortList]
    set staggerConfig [config_find $ftmorsaClockConfig StaggerConfig]
    foreach tmp [config_list $portListConfig] {
        if [regexp $sub_clock_mode [config_map_keys $tmp]] {
            set portConfig $tmp
        }
    }
    # Define "clock_atpg_mode" nickname that describes clock behavior for given ATPG $sub_mode
    set modeConfig [config_find $portConfig $sub_clock_mode/mode_${sub_mode}]
    set fieldsConfig [config_find $modeConfig FIELDS]
    set entries [config_list [config_find $modeConfig ENTRIES]]
    set fieldsList [split $fieldsConfig "\t"]
    for {set i 0} {$i < [llength $fieldsList]} {incr i} {
        set FieldIndex([lindex $fieldsList $i]) $i
    }
    
    if {$clock_atpg_mode eq "TAM"} {
    #4.1 assert scan_en & de-assert cap_en
    $prgmConfig waitRti 5
    $prgmConfig set_pin_value $scan_en_pin 1
    foreach TestClk $TestClkList {
    if {[regexp {\[} $TestClk]} {
    $prgmConfig jtag_force "\\${TestClk}_cap_en " 0
    } else {
    $prgmConfig jtag_force "${TestClk}_cap_en" 0
    }
    }
    $prgmConfig waitRti 1
    $prgmConfig jtag_force seq_scan_en 1
    $prgmConfig waitRti 1
   
    #4.2 occ force
        set value 3
        set width [config_find $atpg_clock_verif_config Default/NO_local_OCC/width]
        set name [config_find $atpg_clock_verif_config Default/NO_local_OCC/name]
        foreach chiplet $enable_ip_list {
            lappend OccNameList ${name}_${chiplet} 
    }
    foreach OccName $OccNameList {
            puts "INFO: Now force $width wide chain $OccName to $value"
    ::ATE::atpg_init::FORCE_CLOCK_CHAIN $prgmConfig $testConfig $OccName $width $value
    }
    
    # 4.3: wait until core shift done
    # Total wait time = (15 cycles @ serdes_fast_clk for FSM transition) + (core shift cycles)
    set waitCycles(fsm_transition) [expr int(ceil(15.0 * $tap_freq_mhz / $test_clk_freq_mhz))]
    set waitCycles(scan_en_delay) [expr int(ceil(3.0 * $tap_freq_mhz / 5))]
    set waitCycles(core_shift) [expr int(ceil($num_core_shift_pulses * $tap_freq_mhz / $test_clk_freq_mhz))]
    set totalWaitCycles [expr $waitCycles(fsm_transition) + $waitCycles(scan_en_delay) + $waitCycles(core_shift)]
    puts "Waiting for total of \n\
    \ \ $waitCycles(fsm_transition) tck cycles (fsm_transition)\n\
    + $waitCycles(scan_en_delay) tck cycles (scan en delay)\n\
    + $waitCycles(core_shift) tck cycles (core_shift)\n\
    -------------------------------------------- \n\
    $totalWaitCycles tck cycles (TOTAL) . override to be 100"
    
        $prgmConfig waitRti $totalWaitCycles
    
    # 4.4: de-assert scan_en, assert cap_en
    $prgmConfig set_pin_value $scan_en_pin 0
    $prgmConfig jtag_force seq_scan_en 0
    foreach TestClk $TestClkList {
    if {[regexp {\[} $TestClk]} {
    $prgmConfig jtag_force "\\${TestClk}_cap_en " 1
    } else {
    $prgmConfig jtag_force "${TestClk}_cap_en" 1
    }
    }
    # 4.5: wait until capture phase done
    set waitCycles(capture) [expr int(ceil($ftm_cap_win))]
    puts "Waiting for $waitCycles(capture) for capture"
    $prgmConfig waitRti $waitCycles(capture)
    # 4.6: Need an extra scan_en posedge to check final results. Just need a posedge, no need to wait for complete shift+capture
    $prgmConfig set_pin_value $scan_en_pin 1
    $prgmConfig jtag_force seq_scan_en 1
    $prgmConfig waitRti [expr 10 + $waitCycles(fsm_transition)]
    foreach TestClk $TestClkList {
    if {[regexp {\[} $TestClk]} {
    $prgmConfig jtag_force "\\${TestClk}_cap_en " 0
    } else {
    $prgmConfig jtag_force "${TestClk}_cap_en" 0
    }
   
    }
   
    if {$clock_atpg_mode eq "XTR" } {
    #for IP run, always use -enable_ip arg to specify the IP under-test
    #skip forcing scan_en to 1 when we loop test
    if {$IsFirstRun == 1} {
       # 4.1 de-assert scan_en at the beginning
       puts "set all ip IDU scan_en to 0"
       foreach chiplet $enable_ip_list {
               if {[regexp {_t0} $chiplet]} { continue }
        $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 0
       }
       $prgmConfig set_enable_value $scan_en_pin 1
       $prgmConfig set_pin_value $scan_en_pin 0
       $prgmConfig waitRti 1
        }
    # 4.2: set scan_en=1, initiate core shift state transition in IDU
    puts "set idu scan_en input to 1 to start shift"
    foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 1
    }
    $prgmConfig set_pin_value $scan_en_pin 1
    $prgmConfig waitRti 1
   
        # 4.3 occ load
    puts "program occ after scan_en 1 , need wait 10 serdes1f cycle for pipeline"
    puts "wait [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)] cycle"
    $prgmConfig waitRti [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
   
        if {[regexp $sub_mode "shift_only"]} { 
            set value 0 
        } elseif {$sub_clock_mode == "BYPASS_MODE_ISTCLOCK"} {
            set value 1
        } elseif {$sub_clock_mode == "FTM_BYPASS_MODE_ISTCLOCK"} {
            set value 3
        } else {
            set value 3
        }
        set width [config_find $atpg_clock_verif_config Default/Local_OCC/width]
        set name [config_find $atpg_clock_verif_config Default/Local_OCC/name]
        foreach chiplet $enable_ip_list {
            lappend OccNameList ${name}_${chiplet}
        }
        foreach OccName $OccNameList {
            puts "INFO: Now force $width wide chain $OccName to $value"
    ::ATE::atpg_init::FORCE_CLOCK_CHAIN $prgmConfig $testConfig $OccName $width $value
    }
    $prgmConfig waitRti 10
    
    # 4.4: wait until core shift done
    # Total wait time = (15 cycles @ serdes_fast_clk for FSM transition) + (core shift cycles)
    set waitCycles(fsm_transition) [expr int(ceil(15.0 * $tap_freq_mhz / $serdes_slow_clk_freq_mhz))]
    set waitCycles(core_shift) [expr int(ceil($num_core_shift_pulses * $tap_freq_mhz / $serdes_slow_clk_freq_mhz))]
    set totalWaitCycles [expr $waitCycles(fsm_transition) + $waitCycles(core_shift)]
    puts "Waiting for total of \n\
    \ \ $waitCycles(fsm_transition) tck cycles (fsm_transition)\n\
    + $waitCycles(core_shift) tck cycles (core_shift)\n\
    -------------------------------------------- \n\
    $totalWaitCycles tck cycles (TOTAL) . override to be 100"
    $prgmConfig waitRti $totalWaitCycles
    $prgmConfig waitRti [expr int(20 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
    
    # 4.5: set scan_en=0, initiate capture state transition in IDU
    puts "set idu scan_en input to 0 to start capture"
    foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 0
    }
    $prgmConfig set_pin_value $scan_en_pin 0
    $prgmConfig waitRti 1
        puts "if we loop shift/capture for xtr, we expect $num_core_shift_pulses shift pulses"
        foreach entry $entries {
            set elementList [split $entry "\t"]
        set name [lindex $elementList $FieldIndex(NAME)]
        regsub -all {[^a-zA-Z0-9_]+} $name {_} monitorName
            binary scan [binary format I1 [expr $num_core_shift_pulses + 1]] B* binary_num_core_shift_pulses
            $prgmConfig jtag_force "TB_ftm_shift_cnt_overwrite_${monitorName}\[9:0\]" $binary_num_core_shift_pulses
        }
    
    # 4.6: wait until capture phase done
    set waitCycles(capture) [expr int(ceil($ftm_cap_win))]
    puts "Waiting for $waitCycles(capture) for capture"
    $prgmConfig waitRti $waitCycles(capture)
   
        puts "set idu scan_en input to 1 to start monitor check"
    foreach chiplet $enable_ip_list {
            if {[regexp {_t0} $chiplet]} { continue }
            $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 1
    }
    $prgmConfig set_pin_value $scan_en_pin 1
   
        $prgmConfig waitRti [expr 10 + $waitCycles(fsm_transition)]
    }

    #Check result
    set jtagConfig [$prgmConfig get_jtag_config]
    if {[jtag_output_type $jtagConfig] == "VerilogXface"} {
        set clock_mon_active TB_clock_mon_active
        set_pin_value $jtagConfig $clock_mon_active 0
        waitRti $jtagConfig 1
        puts "Checking clock monitors for any errors..."
        set_pin_value $jtagConfig TB_clock_mon_error 0
        waitRti $jtagConfig 1
        $prgmConfig set_pin_value TB_clock_mon_error X
        $prgmConfig waitRti 5
    }
}

proc ::ATE::atpg_init::clock_ftm { prgmConfig testConfig ftm_cap_win legacy_serdes_preshift_count} {
puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============@cycle [$prgmConfig get_current_cycle] ENTER gprocedure: [lindex [info level 0] 0]=============="
    set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
    set chip_name [$prgmConfig name]
    set design_type [config_map_value [config_find $testConfig CURRENT_TEST] design_type]
    set design_scope [config_map_value [config_find $testConfig CURRENT_TEST] design_scope]
    set clock_mode [config_map_value [config_find $testConfig CURRENT_TEST] clock_mode]
    set sub_clock_mode [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CLOCK_CONFIG] $clock_mode]]; # this is a list,but we only allow one element
    set sub_mode [config_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]]; # this is a list, but we only allow one element
    set relative_path_local2jtag [config_find $testConfig CURRENT_TEST/relative_path/test2jtag]
    set scan_en_pin [::pkgtool::get_vlog_pins_with_test_function $die_obj {TESTCTL0}]
    regsub -all {[\{\}]} $scan_en_pin {} scan_en_pin
    set SerdesClkList [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=serdes4f_clk)}]
    set TestClkList [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=.*)}]
    set clockProgrammingConfig [::ATE::clock_init_tasks::get_clock_programming_config $testConfig]
    set onehot_mode [config_find $testConfig USER_CUSTOM_ARGS/onehot_mode]
    set edge_mode [config_find $testConfig USER_CUSTOM_ARGS/edge_mode]
    set enable_all_atpg_ovr_mode [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/API_ARGUMENTS/enable_all_atpg_ovr_mode]
    set atpg_ovr_mode_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/API_ARGUMENTS/atpg_ovr_mode_list]

    puts "INFO: chip_name  is $chip_name "
    puts "INFO: design_type  is $design_type "
    puts "INFO: design_scope  is $design_scope "
    puts "INFO: clock_mode  is $clock_mode "
    puts "INFO: sub_clock_mode  is $sub_clock_mode "
    puts "INFO: sub_mode  is $sub_mode "
    puts "INFO: relative_path_local2jtag  is $relative_path_local2jtag "
    puts "INFO: scan_en_pin  is $scan_en_pin "
    puts "INFO: SerdesClkList  is $SerdesClkList "
    puts "INFO: TestClkList  is $TestClkList "
    puts "INFO: onehot_mode  is $onehot_mode"
    puts "INFO: edge_mode  is $edge_mode"
    puts "INFO: enable_all_atpg_ovr_mode is $enable_all_atpg_ovr_mode"
    puts "INFO: atpg_ovr_mode_list is $atpg_ovr_mode_list"

    
# dealing with test specific argument
set listargsParams(debug_mode) -1
if {[catch {config_isa [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]}]} {
set listargsParams(mode) [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]
} else {
if {[config_isa [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]] == "VECTOR"} {
set listargsParams(mode) [config_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]]
} else {
puts "ERROR:exception of getting 'CURRENT_TEST/CURRENT_SUBTEST/sub_modes' from the test configure object"
exit 1;
}
}
if { $listargsParams(mode) != "" } {
set listargsParams(debug_mode) $listargsParams(mode)
} else {
set listargsParams(debug_mode) -1
}
if { $listargsParams(debug_mode) == -1 } {
puts "ERROR: Please specify sub_mode for clock_ftm test by '-sub_mode x'"
exit 1;
} elseif { [llength $listargsParams(debug_mode)] > 1 } {
puts "ERROR: '-sub_mode' only support one entry now"
exit 1;
} else {
puts "Running single sub_mode: $listargsParams(debug_mode)"
}
    #Sub clock mode
    if {$sub_clock_mode == "FTM_BYPASS_MODE_TESTCLOCK_1X"} {
        set sub_clock_mode FTM_BYPASS_MODE_TESTCLOCK
    } elseif {$sub_clock_mode == "FTM_BYPASS_MODE_TESTCLOCK_2X"} {
        set sub_clock_mode FTM_BYPASS_MODE_TESTCLOCK
    }
    
    #Get clock_atpg_mode
    switch -regexp $sub_mode {
TAM|UPHY|PEX|FABRIC { set clock_atpg_mode "TAM" }
XTR|shift_only { set clock_atpg_mode "XTR" }
default { puts "ERROR: only XTR_STUCKAT_SERDES, LEGACY_INTEST_STUCKAT_SERDES, and LEGACY_EXTEST_STUCKAT_SERDES supported!"; exit 1; }
}
puts "INFO: sub_clock_mode.clock_atpg_mode $sub_clock_mode.$clock_atpg_mode"
    
    #Get serdes div ratio from common_mode
    set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
    puts "INFO: common modes: $common_modes"
    if {[llength $common_modes] eq "0"} {
        puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
        exit 1    
    }
    foreach common_mode $common_modes {
        if {[regexp "SERDES_RATIO" $common_mode]} {
            switch $common_mode {
                SERDES_RATIO_S4 { set serdes_div_ratio 4 }
                SERDES_RATIO_S6 { set serdes_div_ratio 6 }
                SERDES_RATIO_S8 { set serdes_div_ratio 8 }
                SERDES_RATIO_S12 { set serdes_div_ratio 12 }
                SERDES_RATIO_S24 { set serdes_div_ratio 24 }
            }
        }
    }
    #Get JTAG_TCK test_clock serdes_fast_clk serdes_slow_clk frequency
    set tap_freq_khz [$prgmConfig get_tap_frequency]
    set tap_freq_mhz [expr $tap_freq_khz * 0.001]
#    set test_clk_freq_mhz 90.009
set test_clk_freq_mhz 62.5
    switch -regexp "$sub_clock_mode.$clock_atpg_mode" {
FTM_BYPASS_MODE_ISTCLOCK.XTR {
set serdes_fast_clk_freq_mhz 203.998
set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
}
BYPASS_MODE_ISTCLOCK.XTR {
set serdes_fast_clk_freq_mhz 203.998
set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
}
default {
set serdes_fast_clk_freq_mhz 500.0
set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
}
}
    
    
    #Get default ip instances when fullchip simulation 
    set IpList [string tolower [::ATE::AteFlowUtils::get_ip_type -prgmConfig $prgmConfig -all]]
    foreach IpType $IpList {
        set IpType NV_${IpType}
        puts "INFO: IpType = $IpType"
        if {[regexp {dram|hbm|other2} $IpType]} {
            puts "INFO:  Skip $IpType"
            continue
        }
        lappend default_ip_list $IpType
    }
if {[config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip] ne ""} {
set enable_ip_list [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip]
} else {
set enable_ip_list $default_ip_list
}
    puts "INFO: enable_ip_list is $enable_ip_list"

    #Set shift pulses number
    set num_core_shift_pulses 10
    
    ######1. BEGIN test-bench setting #####
    #Get serdes/test clock pad prefix for force
    foreach SerdesClk $SerdesClkList {
puts "cell=$SerdesClk"
regsub -all {(\w+)\[(\d+)\]} $SerdesClk {\1__\2__} SerdesClk
puts "cell=$SerdesClk"
lappend NewSerdesClkList $SerdesClk
}

foreach TestClk $TestClkList {
puts "cell=$TestClk"
regsub -all {(\w+)\[(\d+)\]} $TestClk {\1__\2__} TestClk
puts "cell=$TestClk"
lappend NewTestClkList $TestClk
}
    switch -regexp "$sub_clock_mode.$clock_atpg_mode" {
STA_BYPASS_MODE_SERDESCLOCK.XTR|FTM_BYPASS_MODE_SERDESCLOCK.XTR|nafll_Ftm.XTR {
$prgmConfig jtag_force "ftm_mode" 0; # Set ftm_mode=0 so that SCAN_EN pin will be driven as simple ext pin, not by wide_scan_en
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 1 ;# choose serdesclk as source shift clock for tb ftm monitor
$prgmConfig jtag_force "tb.TB_serdesclk_trigger" 1
$prgmConfig jtag_force "tb.TB_clk_freerunning" 1
}
FTM_BYPASS_MODE_ISTCLOCK.XTR|BYPASS_MODE_ISTCLOCK.XTR {
$prgmConfig jtag_force "ftm_mode" 0; # Set ftm_mode=0 so that SCAN_EN pin will be driven as simple ext pin, not by wide_scan_en
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 1 ;# choose serdesclk as source shift clock for tb ftm monitor
$prgmConfig jtag_force "TB_serdesclk_trigger" 1
}
nafll_Ftm.TAM|BYPASS_MODE_TESTCLOCK.TAM {
$prgmConfig jtag_force seq_scan_en 0
$prgmConfig jtag_force "TB_ftm_debug_port_test_sequence_on" 1
$prgmConfig jtag_force "testen_dummy" 1 ;# testen_dummy=1 to unblock wide/fake_scan_en, which will be used in new_FTM_pulse_gen_rz module.
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 0 ;# choose testclk as source shift clock for tb ftm monitor 
$prgmConfig jtag_force "tb.TB_testclk_ctrl_running_62p5" 1 ;# choose 62.5 free run testclk
### BEGIN create shift/capture clock from tb new_FTM_pulse_gen_rz module ###
set shift_pulse_num $num_core_shift_pulses
set capture_pulse_num 1
foreach TestClk $TestClkList {
$prgmConfig set_pin_value $TestClk 1
}
foreach TestClk $NewTestClkList {
if {[lsearch $NewSerdesClkList $TestClk] != -1} { ;# set test-bench serdes clock shift/capture to 0 in testclk based mode
for {set i 0} {$i < 10} {incr i} {
                        binary scan [binary format I1 $shift_pulse_num] B* binary_shift_pulse_num
                        $prgmConfig jtag_force "TB_shift_${TestClk}_pulse_num\[9:0\]" $binary_shift_pulse_num
                        binary scan [binary format I1 $capture_pulse_num] B* binary_capture_pulse_num
                        $prgmConfig jtag_force "TB_ftm_${TestClk}_pulse_num\[9:0\]" $binary_capture_pulse_num
}
} else {
for {set i 0} {$i < 10} {incr i} {
                        binary scan [binary format I1 $shift_pulse_num] B* binary_shift_pulse_num
                        $prgmConfig jtag_force "TB_shift_${TestClk}_pulse_num\[9:0\]" $binary_shift_pulse_num
                        binary scan [binary format I1 $capture_pulse_num] B* binary_capture_pulse_num
                        $prgmConfig jtag_force "TB_ftm_${TestClk}_pulse_num\[9:0\]" $binary_capture_pulse_num
}
}
}
### END create shift/capture clock from tb new_FTM_pulse_gen_rz module ###
}
}
##### END test-bench setting #####
    
    ##### 3.BEGIN configure IDU transactor #####
    $prgmConfig jtag_force "tb.count_capture" 0
    puts "serdes_div_ratio = $serdes_div_ratio"
    puts "num_core_shift_pulses = $num_core_shift_pulses"
    puts "legacy_serdes_preshift_count = $legacy_serdes_preshift_count"
    for {set i 0} {$i <= 15} {incr i} {
    # 3.0: configure number of core shift length, in terms of serdes_fast_clk cycles
    $prgmConfig jtag_force "tb_xtr_num_core_shift_pulses_$i" [expr ([expr $num_core_shift_pulses + 1] >> $i) & 1];# add 1 pulse due to idu design: the output pulse from idu is shift_pulse - 1
    # 3.1: configure the number of ftm_cap_win
    $prgmConfig jtag_force "tb.tb_ftm_cap_win_$i" [expr ($ftm_cap_win >> $i) & 1]
    }
    $prgmConfig waitRti 10
    ##### END configure IDU transactor ##### 

    #Load atpg_clock_verif_config
    if {[file exist $::env(ATE_TOT)/atpg_init/atpg_clock_verif_config.yml]} {
        puts "INFO: Load atpg_clock_verif_config from $::env(ATE_TOT)/atpg_init/atpg_clock_verif_config.yml"
        set atpg_clock_verif_config [config_read_yaml $::env(ATE_TOT)/atpg_init/atpg_clock_verif_config.yml]
    } else {
        puts "INFO: Could not find $::env(ATE_TOT)/atpg_init/atpg_clock_verif_config.yml"
        set atpg_clock_verif_config [config_new_map]
        config_set $atpg_clock_verif_config Default/Local_OCC/name FTM_occ_control_chain_local
        config_set $atpg_clock_verif_config Default/Local_OCC/width 8
        config_set $atpg_clock_verif_config Default/NO_local_OCC/name FTM_occ_control_chain_non_local
        config_set $atpg_clock_verif_config Default/NO_local_OCC/width 8
        config_set $atpg_clock_verif_config Default/One_bit_OCC/name enable_legacy_serdes_en
        config_set $atpg_clock_verif_config Default/One_bit_OCC/width 1
    }
    
    config_set $atpg_clock_verif_config TMP/sub_clock_mode [lindex $sub_clock_mode 0]
    config_set $atpg_clock_verif_config TMP/sub_mode $sub_mode
    config_set $atpg_clock_verif_config TMP/clock_atpg_mode $clock_atpg_mode
    config_set $atpg_clock_verif_config TMP/num_core_shift_pulses $num_core_shift_pulses
    config_set $atpg_clock_verif_config TMP/serdes_slow_clk_freq_mhz $serdes_slow_clk_freq_mhz
    config_set $atpg_clock_verif_config TMP/test_clk_freq_mhz $test_clk_freq_mhz
    config_set $atpg_clock_verif_config TMP/scan_en_pin $scan_en_pin
    config_set $atpg_clock_verif_config TMP/SerdesClkList $SerdesClkList
    config_set $atpg_clock_verif_config TMP/TestClkList $TestClkList
    config_set $atpg_clock_verif_config TMP/tap_freq_mhz $tap_freq_mhz
    config_set $atpg_clock_verif_config TMP/enable_ip_list $enable_ip_list
    config_set $atpg_clock_verif_config TMP/ftm_cap_win $ftm_cap_win
    config_set $atpg_clock_verif_config TMP/serdes_div_ratio $serdes_div_ratio

    #Get atpg override mode
    if {$enable_all_atpg_ovr_mode == "1"} {
        if {[config_find $atpg_clock_verif_config Override_mode] == ""} {
            puts "WARNING: With -enable_all_atpg_ovr_mode, but as atpg_clock_verif_config does not have Override_mode, atpg_ovr_mode_list is only DEFAULT"
            set atpg_ovr_mode_list [list DEFAULT]
        } else {
            set atpg_ovr_mode_list [config_map_keys [config_find $atpg_clock_verif_config Override_mode]]
            puts "INFO: With -enable_all_atpg_ovr_mode, atpg_ovr_mode_list is $atpg_ovr_mode_list"
        }
    } elseif {$atpg_ovr_mode_list != ""} {
        set atpg_ovr_mode_list_tmp ""
        foreach tmp $atpg_ovr_mode_list {
            if {[lsearch [config_map_keys [config_find $atpg_clock_verif_config Override_mode]] $tmp] == "-1"} {
                tn_msg_issue_ATE_102 "ERROR: $tmp that set by -atpg_ovr_mode_list does not exist in atpg_clock_verif_config.yml, Skipping"
            } else {
                set atpg_ovr_mode_list_tmp [concat $atpg_ovr_mode_list_tmp $tmp]
            }
        }
        set atpg_ovr_mode_list $atpg_ovr_mode_list_tmp
        puts "INFO: With -atpg_ovr_mode_list , atpg_ovr_mode_list is $atpg_ovr_mode_list"

    } else {
        puts "INFO: Without -enable_all_atpg_ovr_mode and -atpg_ovr_mode_list, atpg_ovr_mode_list is only DEFAULT"
        set atpg_ovr_mode_list [list DEFAULT]
    }

    #Get from ftm/s@ yml
    puts "INFO: relative_path_local2jtag ${relative_path_local2jtag}ftm_clock_config_${design_type}.yml"
    set ftmorsaClockConfig [config_read_yaml "${relative_path_local2jtag}ftm_clock_config_${design_type}.yml"]

    #Start the test
    set IsFirstRun 1
    foreach atpg_ovr_mode $atpg_ovr_mode_list {
        puts "INFO: \$sub_clock_mode/mode_\${sub_mode} = $sub_clock_mode/mode_${sub_mode}"
        
        puts "INFO: Now is verifying $atpg_ovr_mode"
        puts "INFO: Start the override config"
        ::ATE::atpg_init::over_mode_extra_control $prgmConfig $testConfig $atpg_clock_verif_config $atpg_ovr_mode
        $prgmConfig waitRti 1

        puts "INFO: Start the monitor config"
        ::ATE::atpg_init::clock_monitor_setting $prgmConfig $testConfig $ftmorsaClockConfig $atpg_clock_verif_config $atpg_ovr_mode $IsFirstRun
        $prgmConfig waitRti 1

        puts "INFO: Start the test sequence"
        ::ATE::atpg_init::clock_ftm_test_sequence $prgmConfig $testConfig $ftmorsaClockConfig $atpg_clock_verif_config $atpg_ovr_mode $IsFirstRun
        $prgmConfig waitRti 1
        set IsFirstRun 0
    }

if {[regexp "BYPASS_MODE_ISTCLOCK" $sub_clock_mode]} {
::ATE::AteFlowUtils::strobe_frequency_stop -prgmConfig $prgmConfig -testConfig $testConfig
}
if {[config_find $testConfig CURRENT_TEST/purpose] eq "verilog"} {
$prgmConfig set_enable_value TB_clock_mon_error 0
$prgmConfig set_pin_value TB_clock_mon_error 0
$prgmConfig waitRti 1
$prgmConfig set_pin_value TB_clock_mon_error X
$prgmConfig waitRti 5
}
    # add for tam, avoid shift_ir mismatch for tam with related to EOT
    if {$clock_atpg_mode eq "TAM"} {
        $prgmConfig jtag_force seq_scan_en 0
$prgmConfig waitRti 20
    }
}

proc ::ATE::atpg_init::atpg_cutpoint { prgmConfig testConfig ftm_cap_win legacy_serdes_preshift_count {debug_occ_index ""}} {
puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============@cycle [$prgmConfig get_current_cycle] ENTER gprocedure: [lindex [info level 0] 0]=============="
set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set chip_name [$prgmConfig name]
set design_type [config_map_value [config_find $testConfig CURRENT_TEST] design_type]
set clock_mode [config_map_value [config_find $testConfig CURRENT_TEST] clock_mode]
set sub_clock_mode [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CLOCK_CONFIG] $clock_mode]]; # this is a list,but we only allow one element
set sub_mode [config_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]]; # this is a list, but we only allow one element
puts "DBG_API: sub_mode = $sub_mode"
set relative_path_local2jtag [config_find $testConfig CURRENT_TEST/relative_path/test2jtag]
set scan_en_pin [::pkgtool::get_vlog_pins_with_test_function $die_obj {TESTCTL0}]
regsub -all {[\{\}]} $scan_en_pin {} scan_en_pin
set SerdesClkList [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=serdes4f_clk)}]
set TestClkList [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=.*)}]
set UPhyTestClkList [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=uphy.*)}] 
foreach SerdesClk $SerdesClkList {
puts "cell=$SerdesClk"
regsub -all {(\w+)\[(\d+)\]} $SerdesClk {\1__\2__} SerdesClk
puts "cell=$SerdesClk"
lappend NewSerdesClkList $SerdesClk
}

foreach TestClk $TestClkList {
puts "cell=$TestClk"
regsub -all {(\w+)\[(\d+)\]} $TestClk {\1__\2__} TestClk
puts "cell=$TestClk"
lappend NewTestClkList $TestClk
}
set uphy_testclk_pin_List [::pkgtool::get_vlog_pins_with_test_function $die_obj {(TESTCLK=uphy.*)}]
foreach UPhyTestClk $UPhyTestClkList {
puts "uphy testclk is =$UPhyTestClk"
regsub -all {(\w+)\[(\d+)\]} $TestClk {\1__\2__} UPhyTestClk
lappend NewUPhyTestClkList $UPhyTestClk
}

#serdes div ratio
if {[config_find $testConfig USER_CUSTOM_ARGS/serdes_div_ratio] != ""} {
set serdes_div_ratio [config_find $testConfig USER_CUSTOM_ARGS/serdes_div_ratio] 
} else {
set serdes_div_ratio 8
}
# JTAG tap frequency and expected serdes_fast_clk frequency
set tap_freq_khz [$prgmConfig get_tap_frequency]
set tap_freq_mhz [expr $tap_freq_khz * 0.001]
# TODO (kihara): I don't care about core shift in this test
set num_core_shift_pulses 2;
#set serdes_fast_clk_freq_mhz 500.0
#set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
# set test_clk_freq_mhz 90.009
set test_clk_freq_mhz 62.5

# Get default ip instances when fullchip simulation
if { [$prgmConfig get_design_top] eq "" } {
set default_ip_list [list ]  
} else {
source [ls ../jtag/tu1*_pkginfo_rtl.tn]
set default_ip_list [list ]
foreach index [lsort -integer [array names chiplet_array]] {
set ChipletInst [lindex $chiplet_array($index) 1]
lappend default_ip_list $ChipletInst
}
}
if {[config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip] ne ""} {
set enable_ip_list [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip]
} else {
set enable_ip_list $default_ip_list
}

##### Write your code here #####
######1. BEGIN test-bench setting #####
switch -regexp $sub_mode {
TAM|UPHY|PEX|FABRIC { set clock_atpg_mode "TAM" }
XTR|shift_only { set clock_atpg_mode "XTR" }
default { puts "ERROR: only XTR_FTM_SERDES, TAM_EXTEST_FTM_SERDES supported!"; exit 1; }
}
puts "sub_clock_mode.clock_atpg_mode.ftm_or_sa $sub_clock_mode.$clock_atpg_mode"
switch -regexp "$sub_clock_mode.$clock_atpg_mode" {
FTM_BYPASS_MODE_ISTCLOCK.XTR {
set serdes_fast_clk_freq_mhz 203.998
set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
}
BYPASS_MODE_ISTCLOCK.XTR {
set serdes_fast_clk_freq_mhz 203.998
set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
}
default {
set serdes_fast_clk_freq_mhz 500.0
set serdes_slow_clk_freq_mhz [expr $serdes_fast_clk_freq_mhz / $serdes_div_ratio]
}
switch -regexp "$sub_clock_mode.$clock_atpg_mode" {
STA_BYPASS_MODE_SERDESCLOCK.XTR|FTM_BYPASS_MODE_SERDESCLOCK.XTR|FTM_BYPASS_MODE_ISTCLOCK.XTR {
$prgmConfig jtag_force "ftm_mode" 0; # Set ftm_mode=0 so that SCAN_EN pin will be driven as simple ext pin, not by wide_scan_en
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 1 ;# choose serdesclk as source shift clock for tb ftm monitor
$prgmConfig jtag_force "tb.TB_serdesclk_trigger" 1
$prgmConfig jtag_force "tb.TB_clk_freerunning" 1
set targetShiftPeriod_ps [expr int(1000000.0 / $serdes_slow_clk_freq_mhz * 256)]; # There is "div 256" applied by the monitor module
#set targetCapturePeriod_ps [expr int(1000000.0 / $serdes_slow_clk_freq_mhz * 256)]; # There is "div 256" applied by the monitor module
}
BYPASS_MODE_ISTCLOCK.XTR|nafll_Ftm.XTR {
$prgmConfig jtag_force "ftm_mode" 0; # Set ftm_mode=0 so that SCAN_EN pin will be driven as simple ext pin, not by wide_scan_en
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 1 ;# choose serdesclk as source shift clock for tb ftm monitor
$prgmConfig jtag_force "TB_serdesclk_trigger" 1 ;
set targetShiftPeriod_ps [expr int(1000000.0 / $serdes_slow_clk_freq_mhz * 256)]; # There is "div 256" applied by the monitor module
#set targetCapturePeriod_ps [expr int(1000000.0 / $serdes_slow_clk_freq_mhz * 256)]; # There is "div 256" applied by the monitor module
}
BYPASS_MODE_TESTCLOCK.TAM {
$prgmConfig jtag_force seq_scan_en 0
$prgmConfig jtag_force "TB_ftm_debug_port_test_sequence_on" 1
$prgmConfig jtag_force "testen_dummy" 1 ;# testen_dummy=1 to unblock wide/fake_scan_en, which will be used in new_FTM_pulse_gen_rz module.
$prgmConfig jtag_force "tb.TB_serdesclk_ctrl_mode" 0 ;# choose testclk as source shift clock for tb ftm monitor 
$prgmConfig jtag_force "tb.TB_testclk_ctrl_running_62p5" 1 ;# choose 62.5 free run testclk
set targetShiftPeriod_ps [expr int(1000000.0 / $test_clk_freq_mhz * 256)]; # There is "div 256" applied by the monitor module
#set targetCapturePeriod_ps [expr int(1000000.0 / $test_clk_freq_mhz * 256)]; # There is "div 256" applied by the monitor module 
### BEGIN create shift/capture clock from tb new_FTM_pulse_gen_rz module ###
set shift_pulse_num $num_core_shift_pulses
set capture_pulse_num 1
foreach TestClk $TestClkList {
$prgmConfig set_pin_value $TestClk 1
}
foreach TestClk $NewTestClkList {
if {[lsearch $NewSerdesClkList $TestClk] != -1} { ;# set test-bench serdes clock shift/capture to 0 in testclk based mode
for {set i 0} {$i < 10} {incr i} {
                        binary scan [binary format I1 $shift_pulse_num] B* binary_shift_pulse_num
                        $prgmConfig jtag_force "TB_shift_${TestClk}_pulse_num\[9:0\]" $binary_shift_pulse_num
                        binary scan [binary format I1 $capture_pulse_num] B* binary_capture_pulse_num
                        $prgmConfig jtag_force "TB_ftm_${TestClk}_pulse_num\[9:0\]" $binary_capture_pulse_num
}
} else {
for {set i 0} {$i < 10} {incr i} {
binary scan [binary format I1 $shift_pulse_num] B* binary_shift_pulse_num
                        $prgmConfig jtag_force "TB_shift_${TestClk}_pulse_num\[9:0\]" $binary_shift_pulse_num
                        binary scan [binary format I1 $capture_pulse_num] B* binary_capture_pulse_num
                        $prgmConfig jtag_force "TB_ftm_${TestClk}_pulse_num\[9:0\]" $binary_capture_pulse_num
}
}
}
### END create shift/capture clock from tb new_FTM_pulse_gen_rz module ###
}
}
##### END test-bench setting #####
#####2. BEGIN clock monitor setting:read config from yml #####
# Get the top DUT module name
set f "${relative_path_local2jtag}atpg_cutpoint_config_${design_type}.yml"
if {![file exists $f]} {
error "ATPG cutpoint config file $f does not exist"
}
set cutpointConfig [config_read_yaml $f]
if {[llength $enable_ip_list] == 1} {
set target_top [lindex $enable_ip_list 0]
} else {
set target_top "nv_top"
}
    
    # Currently, only XTR FTM mode is supported
    #wkao, change config_map_value to config_find since the key of config_map_value can't use a hierachical format
    #set design_cfg [config_map_value $cutpointConfig "XTR_FTM_SERDES/$target_top"]
    set design_cfg [co set design_cfg [config_find $cutpointConfig "XTR_FTM_SERDES/$target_top"]
    if {[config_has_key $design_cfg "cutpoints"]} {
        set cutpoint_entries [config_list [config_map_value $design_cfg "cutpoints"]]
    } else {
    set cutpoint_entries [config_list $design_cfg]
    }
# Number of tests = 2 + log-base-2(num_entries)
set num_entries [llength $cutpoint_entries]

# Print debug information on each OCC register group
for {set i 0} {$i < $num_entries} {incr i} {
set cutpoint [lindex $cutpoint_entries $i]
puts "InfoFTM: OCC group index \[$i\] OCC registers:"
foreach occ [config_list [config_find $cutpoint occ]] {
puts "InfoFTM:     $occ"
}
puts "InfoFTM: OCC group index \[$i\] internal cutpoints:"
foreach internal [config_list [config_find $cutpoint internal]] {
puts "InfoFTM:     $internal"
}
}

if {$debug_occ_index eq ""} {
# Default mode: test loop compaction through binary-search style optimization
set num_tests [expr {int(2 + ceil(log($num_entries)/log(2)))}]
} else {
# Debug mode: activate only 1 OCC group index
set num_tests 1
}

################################################################################
# Turn on ATPG cutpoint monitors
################################################################################
$prgmConfig jtag_force "tb.atpg_cutpoint_monitor_en" 1

for {set i 0} {$i < $num_tests} {incr i} {
##### 3.BEGIN configure IDU transactor #####
#$prgmConfig jtag_force "tb.tb_tam_testclk_mode" 0; 
$prgmConfig waitRti 10
$prgmConfig jtag_force "tb.count_capture" 0
puts "serdes_div_ratio = $serdes_div_ratio"
puts "num_core_shift_pulses = $num_core_shift_pulses"
puts "legacy_serdes_preshift_count = $legacy_serdes_preshift_count"
for {set j 0} {$j <= 15} {incr j} {
# 3.0: configure number of core shift length, in terms of serdes_fast_clk cycles
$prgmConfig jtag_force "tb_xtr_num_core_shift_pulses_$j" [expr ([expr $num_core_shift_pulses + 1] >> $j) & 1];# add 1 pulse due to idu design: the output pulse from idu is shift_pulse - 1
# 3.1: configure the number of ftm_cap_win
$prgmConfig jtag_force "tb.tb_ftm_cap_win_$j" [expr ($ftm_cap_win >> $j) & 1]
}
$prgmConfig waitRti 10
##### END configure IDU transactor ##### 

###### 4.BEGIN test sequence #####
#############################################################################
# Force OCC registers
#############################################################################
# Get default ip instances when fullchip simulation
if { [$prgmConfig get_design_top] eq "" } {
set default_ip_list [list ]  
} else {
source [ls ../jtag/tu1*_pkginfo_rtl.tn]
set default_ip_list [list ]
foreach index [lsort -integer [array names chiplet_array]] {
set ChipletInst [lindex $chiplet_array($index) 1]
lappend default_ip_list $ChipletInst
}
}
if {[config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip] ne ""} {
set enable_ip_list [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip]
} else {
set enable_ip_list $default_ip_list
}

if {$clock_atpg_mode eq "TAM"} {
#4.1 assert scan_en & de-assert cap_en
$prgmConfig set_pin_value $scan_en_pin 1
foreach TestClk $TestClkList {
if {[regexp {\[} $TestClk]} {
$prgmConfig jtag_force "\\${TestClk}_cap_en " 0
} else {
$prgmConfig jtag_force "${TestClk}_cap_en" 0
}
}
### below waitRti will remove after ###
$prgmConfig waitRti 1
$prgmConfig jtag_force seq_scan_en 1
$prgmConfig waitRti 1
# 4.2 occ force
::ATE::atpg_init::force_atpg_cutpoint_occ $prgmConfig $i $num_entries $debug_occ_index

# 4.3: wait until core shift done
# Total wait time = (15 cycles @ serdes_fast_clk for FSM transition) + (core shift cycles)
set waitCycles(fsm_transition) [expr int(ceil(15.0 * $tap_freq_mhz / $test_clk_freq_mhz))]
        set waitCycles(scan_en_delay) [expr int(ceil(3.0 * $tap_freq_mhz / 5))]
set waitCycles(core_shift) [expr int(ceil($num_core_shift_pulses * $tap_freq_mhz / $test_clk_freq_mhz))]
set totalWaitCycles [expr $waitCycles(fsm_transition) + $waitCycles(scan_en_delay) + $waitCycles(core_shift)]
puts "Waiting for total of \n\
\ \ $waitCycles(fsm_transition) tck cycles (fsm_transition)\n\
            + $waitCycles(scan_en_delay) tck cycles (scan en delay)\n\
+ $waitCycles(core_shift) tck cycles (core_shift)\n\
-------------------------------------------- \n\
$totalWaitCycles tck cycles (TOTAL) . override to be 100"
$prgmConfig waitRti $totalWaitCycles

# 4.4: de-assert scan_en, assert cap_en
$prgmConfig set_pin_value $scan_en_pin 0
$prgmConfig jtag_force seq_scan_en 0
foreach TestClk $TestClkList {
if {[regexp {\[} $TestClk]} {
$prgmConfig jtag_force "\\${TestClk}_cap_en " 1
} else {
$prgmConfig jtag_force "${TestClk}_cap_en" 1
}
}

# 4.5: wait until capture phase done
set waitCycles(capture) [expr int(ceil($ftm_cap_win))]
puts "Waiting for $waitCycles(capture) for capture"
$prgmConfig waitRti $waitCycles(capture)
# 4.6: Need an extra scan_en posedge to check final results.
# Just need a posedge, no need to wait for complete shift+capture
$prgmConfig set_pin_value $scan_en_pin 1
$prgmConfig jtag_force seq_scan_en 1
$prgmConfig waitRti [expr 10 + $waitCycles(fsm_transition)]
foreach TestClk $TestClkList {
if {[regexp {\[} $TestClk]} {
$prgmConfig jtag_force "\\${TestClk}_cap_en " 0
} else {
$prgmConfig jtag_force "${TestClk}_cap_en" 0
}
}
if {$clock_atpg_mode eq "XTR" } {
#for IP run, always use -enable_ip arg to specify the IP under-test
# 4.1 de-assert scan_en at the beginning
puts "set all ip IDU scan_en to 0"
foreach chiplet $enable_ip_list {
                if {[regexp {_t0} $chiplet]} { continue }
                $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 0
}
$prgmConfig set_enable_value $scan_en_pin 1
#$prgmConfig set_pin_value $scan_en_pin 0
$prgmConfig waitRti 1

# 4.2: set scan_en=1, initiate core shift state transition in IDU
puts "set idu scan_en input to 1 to start shift"
foreach chiplet $enable_ip_list {
                if {[regexp {_t0} $chiplet]} { continue }
$prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 1
}
$prgmConfig set_pin_value $scan_en_pin 1
$prgmConfig waitRti 1

# 4.3 occ load
puts "program occ after scan_en 1 , need wait 10 serdes1f cycle for pipeline"
puts "wait [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)] cycle"
$prgmConfig waitRti [expr int(10 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]
switch $sub_clock_mode {
"FTM_BYPASS_MODE_ISTCLOCK" { set value 3 }
"BYPASS_MODE_ISTCLOCK" { set value 1 }
default { set value 3 }
}
set width 8
# Force values to OCC registers individually
::ATE::atpg_init::force_atpg_cutpoint_occ $prgmConfig $i $num_entries $debug_occ_index
$prgmConfig waitRti 10
# 4.4: wait until core shift done
# Total wait time = (15 cycles @ serdes_fast_clk for FSM transition) + (core shift cycles)
set waitCycles(fsm_transition) [expr int(ceil(15.0 * $tap_freq_mhz / $serdes_slow_clk_freq_mhz))]
set waitCycles(core_shift) [expr int(ceil($num_core_shift_pulses * $tap_freq_mhz / $serdes_slow_clk_freq_mhz))]
set totalWaitCycles [expr $waitCycles(fsm_transition) + $waitCycles(core_shift)]
puts "Waiting for total of \n\
\ \ $waitCycles(fsm_transition) tck cycles (fsm_transition)\n\
+ $waitCycles(core_shift) tck cycles (core_shift)\n\
-------------------------------------------- \n\
$totalWaitCycles tck cycles (TOTAL) . override to be 100"
$prgmConfig waitRti $totalWaitCycles
$prgmConfig waitRti [expr int(20 * ([$prgmConfig get_tap_frequency]/1000) / $serdes_slow_clk_freq_mhz)]

# 4.5: set scan_en=0, initiate capture state transition in IDU
puts "set idu scan_en input to 0 to start capture"
foreach chiplet $enable_ip_list {
                if {[regexp {_t0} $chiplet]} { continue }
                $prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 0
}
$prgmConfig set_pin_value $scan_en_pin 0
$prgmConfig waitRti 1

# 4.6: wait until capture phase done
set waitCycles(capture) [expr int(ceil($ftm_cap_win))]
puts "Waiting for $waitCycles(capture) for capture"
$prgmConfig waitRti $waitCycles(capture)
# 4.7: Need an extra scan_en posedge to check final results. Just need a posedge, no need to wait for complete shift+capture
puts "set idu scan_en input to 1 to start monitor check"
foreach chiplet $enable_ip_list {
                if {[regexp {_t0} $chiplet]} { continue }
$prgmConfig jtag_force "tb.tb_idu_se_input_${chiplet}" 1
}
$prgmConfig set_pin_value $scan_en_pin 1
$prgmConfig waitRti [expr 10 + $waitCycles(fsm_transition)]
}
}; # foreach portConfig
## stop signal monitor check
if {[regexp "BYPASS_MODE_ISTCLOCK" $sub_clock_mode]} {
::ATE::AteFlowUtils::strobe_frequency_stop -prgmConfig $prgmConfig -testConfig $testConfig
}

################################################################################
# Turn off ATPG cutpoint monitors, and invoke automated diagnosis
################################################################################
$prgmConfig jtag_force "tb.atpg_cutpoint_monitor_en" 0

if {[config_find $testConfig CURRENT_TEST/purpose] eq "verilog"} {
$prgmConfig set_enable_value TB_clock_mon_error 0
$prgmConfig set_pin_value TB_clock_mon_error 0
$prgmConfig waitRti 1
$prgmConfig set_pin_value TB_clock_mon_error X
$prgmConfig waitRti 5
}
}

proc ::ATE::atpg_init::force_atpg_cutpoint_occ { prgmConfig test_index num_occ {debug_occ_index ""}} {
for {set j 0} {$j < $num_occ} {incr j} {
        if {$debug_occ_index != ""} {
            # This is a debug mode
            set enable [expr ($j == $debug_occ_index) ? 1 : 0]
        } else {
    # For test index 0, enable none of OCC groups.
            # For test index 1, enable all OCC groups.
            # For all others, use "test_index - 2" to construct enable/disable profile, binary-search style.
            #  ("-2" is to account for the first 2 hardcoded tests)
            switch $test_index {
    0 { set enable 0 }
    1 { set enable 1 }
    default { set enable [expr {($j >> ($test_index - 2)) & 1}] }
    }
        }

        if ($enable) {
            puts "InfoFTM: test loop $test_index, activate OCC register index $j."
} else {
            puts "InfoFTM: test loop $test_index, deactivate OCC register index $j."
        }

        for {set k 0} {$k < 5} {incr k} {
set dst "tb.OCC_FORCE_d${j}_${k}"
set v [expr {($k < 2) ? $enable : 0}]
$prgmConfig jtag_force $dst $v
puts "OCC (test loop $test_index): $dst (entry $j) = $v"
}
$prgmConfig jtag_force "tb.OCC_FORCE_e${j}" 1
}
}

proc ::ATE::atpg_init::tam_init_seq { args } {
global unified_scan_spec
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
}

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
}

set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set scan_en_ext_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCTL0 ] 0 ]
puts "INFO: scan_en_ext_pin $scan_en_ext_pin"
if { $scan_en_ext_pin eq "" } { 
puts stderr "ERROR: scan_en_ext pin is not defined" 
exit 1 
}

if { [file exists $unified_scan_spec]} {
set accessConfig [config_read_yaml $unified_scan_spec]
set ufi_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
puts "INFO: UFI pin list is $ufi_list"
set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
puts "INFO: serdes4f pin list is $serdes4f_list"
} else {
set serdes_4f_clk_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCLK=serdes4f_clk ] 0]
puts "INFO: serdes_4f_clk_pin $serdes_4f_clk_pin"
set serdes4f_list [ list $serdes_4f_clk_pin]
if { $serdes_4f_clk_pin eq "" } { 
puts stderr "ERROR: serdes_4f_clk pin is not defined" 
exit 1 
}
}

        # TOP_FS program with force to all 0. This is required to have TOP_FS values set to 0 on fused parts
        $prgmConfig set_program_value {.*TOP_FS} {.*} -value 0 -replicate
        $prgmConfig program -force
        set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
puts "INFO: common modes: $common_modes"
if {[llength $common_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
exit 1
}
foreach common_mode $common_modes {
if {[regexp "SERDES_RATIO" $common_mode]} {
switch $common_mode {
SERDES_RATIO_S4 { set SerdesRatio 4 }
SERDES_RATIO_S6 { set SerdesRatio 6 }
SERDES_RATIO_S8 { set SerdesRatio 8 }
SERDES_RATIO_S12 { set SerdesRatio 12 }
SERDES_RATIO_S24 { set SerdesRatio 24 }
}
}
}

foreach common_mode $common_modes {
# any of the ICK modes BYPASS_MODE_SERDESCLOCK STA_BYPASS_MODE_SERDESCLOCK FTM_BYPASS_MODE_SERDESCLOCK
if {[regexp "BYPASS_MODE_SERDESCLOCK" $common_mode]} { 
# SDP related calculations
set tam_link_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/tam_link_fast_scanin_pipes"]
set tam_ip_to_tam_top_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/tam_ip_to_tam_top_fast_scanin_pipes"]
set tam_ip_broadcast_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/tam_ip_broadcast_fast_scanin_pipes"]
set tam_ip_broadcast_fast_scanin_default_pipes [config_find $testConfig "USER_CUSTOM_ARGS/tam_ip_broadcast_fast_scanin_default_pipes"]
set tam_ip_tam_top_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/tam_ip_tam_top_fast_scanin_pipes"]
if {$tam_link_fast_scanin_pipes eq ""} { set tam_link_fast_scanin_pipes 0 } 
if {$tam_ip_to_tam_top_fast_scanin_pipes eq ""} { set tam_ip_to_tam_top_fast_scanin_pipes 0 } 
if {$tam_ip_broadcast_fast_scanin_pipes eq ""} { set tam_ip_broadcast_fast_scanin_pipes 0 } 
if {$tam_ip_broadcast_fast_scanin_default_pipes eq ""} { set tam_ip_broadcast_fast_scanin_default_pipes 0 } 
if {$tam_ip_tam_top_fast_scanin_pipes eq ""} { set tam_ip_tam_top_fast_scanin_pipes 0 } 
set total_fast_scanin_pipes [expr $tam_link_fast_scanin_pipes + $tam_ip_to_tam_top_fast_scanin_pipes + $tam_ip_tam_top_fast_scanin_pipes + $tam_ip_broadcast_fast_scanin_default_pipes + $tam_ip_broadcast_fast_scanin_pipes ]
set load_serializer_pipeline_stages $total_fast_scanin_pipes

if {[expr $load_serializer_pipeline_stages % $SerdesRatio] == 0} {
set serializer_override_depth $load_serializer_pipeline_stages
} else {
set serializer_override_depth [expr [expr [expr $load_serializer_pipeline_stages / $SerdesRatio] * $SerdesRatio] + $SerdesRatio]
}

set leg_serdes_preshift_count [expr [expr $serializer_override_depth / $SerdesRatio] + 2]
puts "INFO: legacy serdes preshift count = $leg_serdes_preshift_count"
set bit0 [expr $leg_serdes_preshift_count % 2]
set bit1 [expr [expr $leg_serdes_preshift_count/2] % 2]
set bit2 [expr [expr $leg_serdes_preshift_count/4] % 2]
set bit3 [expr [expr $leg_serdes_preshift_count/8] % 2]
set bit4 [expr [expr $leg_serdes_preshift_count/16] % 2]
set bit5 [expr [expr $leg_serdes_preshift_count/32] % 2]
set bit6 [expr [expr $leg_serdes_preshift_count/64] % 2]
set bit7 [expr [expr $leg_serdes_preshift_count/128] % 2]

$prgmConfig set_program_value ".*/LEG_SERDES_CTL" ".*TamControl_LegacySerdesPreshiftCount0" -value $bit0
$prgmConfig set_program_value ".*/LEG_SERDES_CTL" ".*TamControl_LegacySerdesPreshiftCount1" -value $bit1
$prgmConfig set_program_value ".*/LEG_SERDES_CTL" ".*TamControl_LegacySerdesPreshiftCount2" -value $bit2
$prgmConfig set_program_value ".*/LEG_SERDES_CTL" ".*TamControl_LegacySerdesPreshiftCount3" -value $bit3
$prgmConfig set_program_value ".*/LEG_SERDES_CTL" ".*TamControl_LegacySerdesPreshiftCount4" -value $bit4
$prgmConfig set_program_value ".*/LEG_SERDES_CTL" ".*TamControl_LegacySerdesPreshiftCount5" -value $bit5
$prgmConfig set_program_value ".*/LEG_SERDES_CTL" ".*TamControl_LegacySerdesPreshiftCount6" -value $bit6
$prgmConfig set_program_value ".*/LEG_SERDES_CTL" ".*TamControl_LegacySerdesPreshiftCount7" -value $bit7
$prgmConfig program

}
}

$prgmConfig wait_cycles 1
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1

::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
}

proc ::ATE::atpg_init::resync_serdes { args } {
global unified_scan_spec
# get user option
puts "INFO: calling resync_serdes" 
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
{fstate.arg "" "<fstate obje>" "NO_CUSTOMIZE"}
{SerdesRatio.arg "" "<serdes ratio>" "NO_CUSTOMIZE"}
{listArgs.arg "" "-option helper; resync_serdes proc"}
}

#set fstate "../atpg_init/sa_fstate.yml"
array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig fstate SerdesRatio" {
set $temp_var_name $listargsParams($temp_var_name)
}
if {![regexp "^\s*$" $mainParams(ListArgs)]} {
upvar $mainParams(ListArgs) subtest_option
set subtest_option $listArgsOptions

::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_type" -value "SCAN_TEST"
#::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "global_init_behavior" -value "skip_init"
#::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_init_behavior" -value "skip_init"
::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "chiplet_flow_certified" -value 1
## jeryang
#::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "XTR_STUCKAT_SERDES"
# jeryang
set temp_bak_args $::argv
array set temp_param_array [::cmdline::getKnownOptions temp_bak_args {{sub_mode.arg "" ""}}]
set sub_mode_in $temp_param_array(sub_mode)

puts "INFO: sub_mode=$sub_mode_in"
::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "$sub_mode_in"

return 1
}
foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
}

set sub_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST] "sub_modes"]]
puts "INFO: sub_modes: $sub_modes"
if {[llength $sub_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -sub_mode to set proper scan sub_mode."
exit 1
}
set dft_modes_config_file "$::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml"
if { [file exists $dft_modes_config_file]} {
puts "INFO: standard dft mode programming yml file found. Reading..."
set dft_modeConfig [config_read_yaml $dft_modes_config_file]
} else {
puts stderr "ERROR: $dft_modes_config_file file is missing. Please fix it first."
exit 1
}

puts "Running resync_serdes" 
$prgmConfig set_tag_template ".*CLK_CTL" {.*} tag_<REGPATH>_I_<INSTR>_<FIELD>_<BITID> -regsub {tag_(\w+)\/.*[\.\/]([A-Za-z0-9\_]+)_cli_inst_(I_[A-Za-z0-9]+)_.*[\/\.](.*_cli_inst_[A-Za-z0-9]+_)?(.*)} {tag_$1_$2_$3_$5}
puts "taking the scanio yml"

set access_config $unified_scan_spec
if { [file exists $access_config]} {
set accessConfig [config_read_yaml $access_config]
} else {
puts "ERR: need provide access config list $access_config"
}
set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
puts "INFO: serdes4f pin list is $serdes4f_list"
set ufi_pins [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
    # We do not need this after FTC
# puts " Make ufi pins 0"
# foreach ufi_pin $ufi_pins {
    #     if {[info exists ufi_list]} {
    # $prgmConfig set_pin_value $ufi_pin 0
    #     }
# }

# puts "make pex_rst_n as 1"
# $prgmConfig set_pin_value pex_rst_n 1
# puts "make nvjtag_sel as 1"
# $prgmConfig set_pin_value nvjtag_sel 1
    puts "INFO: program test_mode to 1 again, just to change the preivous register programmed from CLK_CTL to something else this should not get actually programmed."
    $prgmConfig set_program_value {.*DFT_AO_REGS} {.*test_mode} -value 1

puts " Now, make serdes4f clk as 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig waitRti 1

# set the reset state of 0 for all bits
#$prgmConfig set_program_value {.*CLK_CTL} {.*} -value 0
# bits with reset state of 1
$prgmConfig set_program_value {.*CLK_CTL} {.*tmc2clk_stop_on_event_.*} -value 1
    $prgmConfig program

puts "get the previous register state"
#set fstate_file "../atpg_init/fstate.yml"
set fstate_file $fstate
set fstateConfig [config_read_yaml $fstate_file]
set fstate_list [config_list [config_find $fstateConfig fstate]]

foreach state $fstate_list {
# puts "fstate is $state"
set field [split $state "#"]
puts " REG: [lindex $field 0] field: [lindex $field 1] value [lindex $field 2] "
set REG [lindex $field 0]
set REG_FIELD [lindex $field 1] 
set VALUE [lindex $field 2] 
$prgmConfig set_program_value $REG $REG_FIELD -value $VALUE
}

$prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*serdes_reset_select.*} -value 1
$prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*serdes_divider_reset_.*} -value 0
$prgmConfig program

puts "Add 100 waitRti cycles after reset"
for {set i 0} {$i < 20} {incr i} {
$prgmConfig waitRti 5
}
puts "Done adding cycles" 

set serdes_div_ratio [config_find $testConfig USER_CUSTOM_ARGS/serdes_div_ratio]

# Begin 4/17 sandbox area: T186 occ_mode test API draft
if {$serdes_div_ratio eq ""} {
# Elastic serdes divider disabled
puts "INFO: serdes_div_ratio is $serdes_div_ratio ..."
puts "INFO: serdes4f_bypass is 1 ..."
$prgmConfig set_program_value {.*CLK_CTL} {.*serdes4f_bypass.*} -value 1
} else {
# sel_div_programming, only when specified
puts "INFO: serdes_div_ratio is $serdes_div_ratio ..."
puts "INFO: serdes4f_bypass is 0 ..."
$prgmConfig set_program_value {.*CLK_CTL} {.*serdes4f_bypass.*} -value 0
switch $serdes_div_ratio {
1 { $prgmConfig set_program_value {.*CLK_CTL} {.*serdes4f_sel_div.*} -value 0 }
4 { $prgmConfig set_program_value {.*CLK_CTL} {.*serdes4f_sel_div.*} -value 1 }
6 { $prgmConfig set_program_value {.*CLK_CTL} {.*serdes4f_sel_div.*} -value 2 }
8 { $prgmConfig set_program_value {.*CLK_CTL} {.*serdes4f_sel_div.*} -value 3 }
12 { $prgmConfig set_program_value {.*CLK_CTL} {.*serdes4f_sel_div.*} -value 4 }
24 { $prgmConfig set_program_value {.*CLK_CTL} {.*serdes4f_sel_div.*} -value 5 }
default {
puts stderr "ERROR: \"-serdes_div_ratio $serdes_div_ratio\" is illegal, only selectable from 1, 4, 6, 12, 24"
exit 1
}
};#switch
} ;#divider ne ""

$prgmConfig waitRti 5 ;# Extra wait time required to allow reset signal to propagate
$prgmConfig waitRti 5 ;# Extra wait time required to allow reset signal to propagate
# Bring serdes divider out of reset
$prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*serdes_divider_reset_.*} -value 1
$prgmConfig program 

puts "INFO: Add few cycles until serdes starts pulsing"
for {set i 0} {$i < 20} {incr i} {
$prgmConfig waitRti 5
}
puts "INFO: Done adding cycles" 
set curr_cyc [$prgmConfig get_current_cycle]
set tck_mult [$prgmConfig get_tck_multiple]
set serdes_ratio $serdes_div_ratio
set mult_required [expr $tck_mult * $serdes_ratio]
puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
if {[ expr $curr_cyc % $mult_required ] != 0} {
set wait_cyc [ expr $mult_required - [ expr $curr_cyc % $mult_required ]]
$prgmConfig wait_cycles $wait_cyc
set curr_cyc [$prgmConfig get_current_cycle]
puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
}

puts " Now, start serdes4f clk "
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program
$prgmConfig waitRti 5 ;# Extra wait time required to allow reset signal to propagate
$prgmConfig waitRti 5 ;# Extra wait time required to allow reset signal to propagate

set curr_cyc [$prgmConfig get_current_cycle]
set tck_mult [$prgmConfig get_tck_multiple]
set serdes_ratio $serdes_div_ratio
set mult_required [expr $tck_mult * $serdes_ratio]
puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
if {[ expr $curr_cyc % $mult_required ] != 0} {
set wait_cyc [ expr $mult_required - [ expr $curr_cyc % $mult_required ]]
$prgmConfig wait_cycles $wait_cyc
set curr_cyc [$prgmConfig get_current_cycle]
puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
}

puts "done programming resync_serdes"
}

proc ::ATE::atpg_init::serdes_div_reset { args } {
global unified_scan_spec
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
}

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
}

puts "INFO: In the proc serdes_div_reset"

if { [file exists $unified_scan_spec]} {
set accessConfig [config_read_yaml $unified_scan_spec]
set ufi_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
puts "INFO: UFI pin list is $ufi_list"
set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
puts "INFO: serdes4f pin list is $serdes4f_list"
} else {
set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set ufi_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj UFI ] 0 ]
set serdes_4f_clk_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCLK=serdes4f_clk ] 0]
puts "INFO: serdes_4f_clk_pin $serdes_4f_clk_pin"
puts "INFO: ufi_pin $ufi_pin"
        if {$ufi_pin ne ""} {
    set ufi_list [ list $ufi_pin ]
        }
set serdes4f_list [ list $serdes_4f_clk_pin ]
if {!([$prgmConfig is_sim_mode] || [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] ist_mode])} {
if { $ufi_pin eq "" } { 
puts stderr "ERROR: ufi_pin is not defined" 
exit 1 
}
if { $serdes_4f_clk_pin eq "" } { 
puts stderr "ERROR: serdes_4f_clk pin is not defined" 
exit 1 
}
}
}

set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
puts "INFO: common modes: $common_modes"
if {[llength $common_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
exit 1
}
foreach common_mode $common_modes {
if {[regexp "SERDES_RATIO" $common_mode]} {
switch $common_mode {
SERDES_RATIO_S4 { set SerdesRatio 4 }
SERDES_RATIO_S6 { set SerdesRatio 6 }
SERDES_RATIO_S8 { set SerdesRatio 8 }
SERDES_RATIO_S12 { set SerdesRatio 12 }
SERDES_RATIO_S24 { set SerdesRatio 24 }
}
}
}

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Make UFI 0 and serdes fast clock 0 at cycle $current_cycle"
        if { [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] test_trigger] } {
            puts "blueg, can't find ufi pin for now, comment out for clock sims for now"
        } else {
            if {[info exists ufi_list]} {
                foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
            }
        }
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
    if {[$prgmConfig is_sim_mode]} {
        # ATE simulation: turn off serdes_4f_clk
        $prgmConfig jtag_force "TB_clk_freerunning" 0
    }
$prgmConfig program
$prgmConfig wait_cycles 20

::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Asserting serdes reset and serdes load at cycle $current_cycle"
    #set serdes_stagger [config_find $testConfig "USER_CUSTOM_ARGS/serdes_stagger"]
    #set test_trigger [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] test_trigger]
    if {[config_isa [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]] == "VECTOR"} {
        set sub_modes [config_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]]
} else {
        set sub_modes [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]
}
switch -regexp $sub_modes {
TAM|UPHY|PEX|FABRIC { set clock_atpg_mode "TAM" }
XTR|shift_only { set clock_atpg_mode "XTR" }
default { puts "ERROR: only XTR_STUCKAT_SERDES, LEGACY_INTEST_STUCKAT_SERDES, and LEGACY_EXTEST_STUCKAT_SERDES supported!"; exit 1; }
}
    puts "dbg, blueg, sub_modes = $sub_modes; clock_atpg_mode = $clock_atpg_mode"
    if {[regexp "XTR" $sub_modes] || [regexp "XTR" $clock_atpg_mode]} {
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: program serdes stagger at cycle $current_cycle"
::ATE::atpg_init::serdes_stagger -prgmConfig $prgmConfig -testConfig $testConfig
    }
$prgmConfig set_program_value ".*/CLK_PCCM_CTL" ".*serdes_reset_select" -value 1
$prgmConfig set_program_value ".*/CLK_PCCM_CTL" ".*serdes_divider_reset_" -value 0
$prgmConfig program
    if { [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] serdes_stagger] } {
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*XTRControl_ShiftStaggerTmax" -value 0
}
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*Select_SerdesLoadSel" -value 1
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*Select_SerdesLoad" -value 0
$prgmConfig program

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: De-asserting serdes reset and serdes load at cycle $current_cycle"
$prgmConfig set_program_value ".*/CLK_PCCM_CTL" ".*serdes_divider_reset_" -value 1
$prgmConfig program
$prgmConfig set_program_value ".*/XTR_TAM_CTL" ".*Select_SerdesLoad" -value 1
$prgmConfig program

set wait_cyc [ expr 16 * $SerdesRatio ]
puts "INFO: Wait for 16 * serdes ratio cycles"
$prgmConfig wait_cycles $wait_cyc

::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: cycle after wait $current_cycle"
}

proc ::ATE::atpg_init::serdes_stagger { args } {
    # get user option
    set mainOptions {
        {ListArgs.arg "" "-ListArgs <required argument for the API>"}
    }
    set listArgsOptions {
        {prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
        {testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
    }

    array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

    array set mainParams [::cmdline::getKnownOptions args $mainOptions]
    foreach temp_var_name "prgmConfig testConfig" {
        set $temp_var_name $listargsParams($temp_var_name)
    }

    puts "INFO: In the proc serdes_stagger"
    set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
    set sub_mode  [config_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]]
    set enable_ip_list [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] enable_ip]
    set subtest_name [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/name]
    set clock_mode [config_map_value [config_find $testConfig CURRENT_TEST] "clock_mode"]
    set sub_clock_mode [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CLOCK_CONFIG] $clock_mode]]

    puts "INFO: common modes: $common_modes"
    
    if {[llength $common_modes] eq "0"} {
        puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
        exit 1    
    }
    foreach common_mode $common_modes {
        if {[regexp "SERDES_RATIO" $common_mode]} {
            switch $common_mode {
                SERDES_RATIO_S4 { set SerdesRatio 4 }
                SERDES_RATIO_S6 { set SerdesRatio 6 }
                SERDES_RATIO_S8 { set SerdesRatio 8 }
                SERDES_RATIO_S12 { set SerdesRatio 12 }
                SERDES_RATIO_S24 { set SerdesRatio 24 }
            }
        }
    }

    set relative_path_local2jtag [config_find $testConfig CURRENT_TEST/relative_path/test2jtag]
    #set test_trigger [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] test_trigger]
    set serdes_stagger [config_find $testConfig "USER_CUSTOM_ARGS/serdes_stagger"]
    if { [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] test_trigger] } {
        # XTR serdesclock mode
        # selStagger programming
        set design_type [config_map_value [config_find $testConfig CURRENT_TEST] design_type]
        $prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*(serdes_bypass_divider|tmc2clk_serdes4f_bypass).*} -value 0
        switch $SerdesRatio {
            4  { $prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*(serdes_sel_div|tmc2clk_serdes4f_sel_div).*} -value 1 }
            6  { $prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*(serdes_sel_div|tmc2clk_serdes4f_sel_div).*} -value 2 }
            8  { $prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*(serdes_sel_div|tmc2clk_serdes4f_sel_div).*} -value 3 }
            12 { $prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*(serdes_sel_div|tmc2clk_serdes4f_sel_div).*} -value 4 }
            24 { $prgmConfig set_program_value {.*CLK_PCCM_CTL} {.*(serdes_sel_div|tmc2clk_serdes4f_sel_div).*} -value 5 }
            default {
                puts stderr "ERROR: \"serdes_div_ratio $SerdesRatio\" is illegal, only selectable from  4, 6, 8, 12, 24"
                exit 1
            }
        }
        set valid_stagger_edges(4)  [list 0 1 2 3 4 5 6 7]
        set valid_stagger_edges(6)  [list 0 1 2 3 4 5 6 7 8 9 10 11]
        set valid_stagger_edges(8)  [list 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
        set valid_stagger_edges(12) [list 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
        set valid_stagger_edges(24) [list 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]

        if {[regexp "FTM" $sub_mode] || [regexp "shift_only" $sub_mode]} {
            set ftmorsaClockConfig [config_read_yaml "${relative_path_local2jtag}ftm_clock_config_${design_type}.yml"]
        } elseif {[regexp "STUCKAT" $sub_mode]} {
            if {[regexp "BYPASS_MODE_ISTCLOCK" $sub_clock_mode] && [regexp "Ftm" $subtest_name]} {
                puts "npan DBG, special handle for IST_Ftm2/PG_SKU_IST_Ftm2, read ftm_clock_config_rtl/flat.yml"
                set ftmorsaClockConfig [config_read_yaml "${relative_path_local2jtag}ftm_clock_config_${design_type}.yml"]
            } else {
                set ftmorsaClockConfig [config_read_yaml "${relative_path_local2jtag}sa_clock_config_${design_type}.yml"]
            }
        }
        set staggerConfig  [config_find $ftmorsaClockConfig StaggerConfig]
        set staggerModesConfig [config_find $staggerConfig StaggerModes/${sub_mode}]
        foreach staggerKey [config_map_keys $staggerModesConfig] {
            if {[regexp {non_stagger|NonShiftStagger|CbbGroup|PAM|edge_control} $staggerKey]} {
                continue
            }
            set shift_mode_relation [config_find $staggerModesConfig $staggerKey/shift_mode_relation]
            if {[lsearch $valid_stagger_edges($SerdesRatio) $shift_mode_relation] == -1} {
                error "ERROR: cannot program stagger mode \"$staggerKey\" to stagger $shift_mode_relation edges.\n\
                    valid_stagger_edges($SerdesRatio) = $valid_stagger_edges($SerdesRatio)"
            } else {
                puts "Programming stagger mode \"$staggerKey\" to stagger $shift_mode_relation edges"
            }
            regsub -all {_} $staggerKey {.*} staggerKey
            if {$shift_mode_relation == 0} {
                $prgmConfig set_program_value ".*\[\\.\\/\]${staggerKey}_cli_inst/CLK_PCCM_CTL" {.*serdes_enable_stagger} -value 0
                $prgmConfig set_program_value ".*\[\\.\\/\]${staggerKey}_cli_inst/CLK_PCCM_CTL" {.*serdes_selStagger} -value 0
            } else {
                $prgmConfig set_program_value ".*\[\\.\\/\]${staggerKey}_cli_inst/CLK_PCCM_CTL" {.*serdes_enable_stagger} -value 1
                $prgmConfig set_program_value ".*\[\\.\\/\]${staggerKey}_cli_inst/CLK_PCCM_CTL" {.*serdes_selStagger} -value [expr $shift_mode_relation-1]
            }
        }
    } elseif { $serdes_stagger eq "1" } {
        set SerdesStaggerConfig [config_read_yaml "${relative_path_local2jtag}Stagger_Assign_opt2.yaml"]
        set StaggerAssignConfig [config_find $SerdesStaggerConfig CLOCK_STAGGER_ASSIGNMENT]
        foreach staggerKey [config_map_keys $StaggerAssignConfig] {
            #set staggerValue [config_find $StaggerAssignConfig $staggerKey]
            set staggerValue [config_map_value $StaggerAssignConfig $staggerKey]
            puts "Key: is $staggerKey and value is $staggerValue"
            regsub -all {[\%]} $staggerKey {.*} staggerKey
            regsub -all {[\/]} $staggerKey {.*} staggerKey
            regsub -all {nv_top} $staggerKey {} staggerKey
            puts "Key: is $staggerKey and value is $staggerValue"
            if {$staggerValue ne "1"} {
                $prgmConfig set_program_value "$staggerKey.*CLK_PCCM_CTL" ".*serdes_enable_stagger.*" -value 1
                $prgmConfig set_program_value "$staggerKey.*CLK_PCCM_CTL" ".*serdes_selStagger.*" -value [expr $staggerValue-2]
            }
        }
    } else {
        puts "if no test_trigger no serdes_stagger, will not program shift stagger anyway"
    } 
    $prgmConfig program
}

proc ::ATE::atpg_init::ufi_selftest { args } {
global unified_scan_spec
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
}

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]
array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
}

puts "INFO: in the proc ufi_selftest"

set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set scan_en_ext_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCTL0 ] 0 ]
puts "INFO: scan_en_ext_pin $scan_en_ext_pin"
if { $scan_en_ext_pin eq "" } { 
puts stderr "ERROR: scan_en_ext pin is not defined" 
exit 1 
}

if { [file exists $unified_scan_spec]} {
set accessConfig [config_read_yaml $unified_scan_spec]
set ufi_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
puts "INFO: UFI pin list is $ufi_list"
set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
puts "INFO: serdes4f pin list is $serdes4f_list"
} else {
set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set ufi_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj UFI ] 0 ]
        if {$ufi_pin ne ""} {
    set ufi_list [list $ufi_pin]
        }
set serdes_4f_clk_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCLK=serdes4f_clk ] 0]
set serdes4f_list [list $serdes_4f_clk_pin]
}

set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
puts "INFO: common modes: $common_modes"
if {[llength $common_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
exit 1
}
foreach common_mode $common_modes {
if {[regexp "SERDES_RATIO" $common_mode]} {
switch $common_mode {
SERDES_RATIO_S4 { set SerdesRatio 4 }
SERDES_RATIO_S6 { set SerdesRatio 6 }
SERDES_RATIO_S8 { set SerdesRatio 8 }
SERDES_RATIO_S12 { set SerdesRatio 12 }
SERDES_RATIO_S24 { set SerdesRatio 24 }
}
}
}

set padding_list [::ATE::atpg_init::get_padding_cycles -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio]
set PreamblePaddingHeadCycles [ lindex $padding_list 0 ]
set PreamblePaddingTailCycles [ lindex $padding_list 1 ]
set PreamblePaddingTailCyclesForUfiSelfTest [ lindex $padding_list 2 ]

puts "INFO: Setting UFI 0"
puts "INFO: Setting scan enable to 1"
puts "INFO: Setting 4f clock to 0"
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 1
$prgmConfig program

puts "INFO: wait for 5* SerdesRatio"
set wait_cyc [expr 5 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
puts "INFO: De-assert ufi_reset"
$prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_reset_" -value 1
$prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_mode" -value 1
$prgmConfig program
$prgmConfig waitRti 20

# num_1500_pipelines wait
set num_1500_pipelines [$prgmConfig get_total_num_ieee1500_pipelines]
puts "INFO: Waiting for 1500 pipelines $num_1500_pipelines before ufi sequence"
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Before wait cycle $current_cycle"
$prgmConfig waitRti $num_1500_pipelines
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After wait cycle $current_cycle"

# additional 100 waitRti as the above only applies tck for 5 + 5 = 10 waitRti
for {set i 0} {$i < 20} {incr i} { $prgmConfig waitRti 5 }
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After additional 100 waitRti wait cycle $current_cycle"

## ------------------------------------------------------------
## Verify UFI is in RESET Mode and TLR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_tlr -ufi_mode xtr_ufi_mode_reset

## ------------------------------------------------------------
## Sequence UFI to move in IDLE Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1001
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_tlr -ufi_mode xtr_ufi_mode_reset

## ------------------------------------------------------------
## Sequence UFI to move in IDLE Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1001
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_idle

## ------------------------------------------------------------
## Sequence UFI to stay in IDLE Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_idle
## ------------------------------------------------------------
## Sequence UFI to Move in CODEC_DRC Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0010
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_codec_drc

## ------------------------------------------------------------
## Sequence UFI to stay in CODEC_DRC Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_codec_drc

## ------------------------------------------------------------
## Sequence UFI to stay in CODEC_DRC Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_codec_drc

## ------------------------------------------------------------
## Sequence UFI to stay in CODEC_DRC Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_codec_drc

## ------------------------------------------------------------
## Sequence UFI to stay in CODEC_DRC Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_codec_drc

## ------------------------------------------------------------
## Sequence UFI to stay in CODEC_DRC Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_codec_drc

## ------------------------------------------------------------
## Sequence UFI to stay in CODEC_DRC Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_codec_drc

## ------------------------------------------------------------
## Sequence UFI to Move in OCC_LOAD Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0011
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_occ_load

## ------------------------------------------------------------
## Sequence UFI to stay in OCC_LOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_occ_load

## ------------------------------------------------------------
## Sequence UFI to stay in OCC_LOAD Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_occ_load

## ------------------------------------------------------------
## Sequence UFI to stay in OCC_LOAD Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_occ_load

## ------------------------------------------------------------
## Sequence UFI to stay in OCC_LOAD Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_occ_load

## ------------------------------------------------------------
## Sequence UFI to stay in OCC_LOAD Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_occ_load

## ------------------------------------------------------------
## Sequence UFI to stay in OCC_LOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_occ_load

## ------------------------------------------------------------
## Sequence UFI to Move in MISR_UNLOAD Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0100
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_misr_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_UNLOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_misr_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_UNLOAD Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_misr_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_UNLOAD Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_misr_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_UNLOAD Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_misr_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_UNLOAD Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_misr_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_UNLOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_misr_unload

## ------------------------------------------------------------
## Sequence UFI to Move in RESEED_LOAD Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0101
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_reseed_load

## ------------------------------------------------------------
## Sequence UFI to stay in RESEED_LOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_reseed_load

## ------------------------------------------------------------
## Sequence UFI to stay in RESEED_LOAD Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_reseed_load

## ------------------------------------------------------------
## Sequence UFI to stay in RESEED_LOAD Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_reseed_load

## ------------------------------------------------------------
## Sequence UFI to stay in RESEED_LOAD Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_reseed_load

## ------------------------------------------------------------
## Sequence UFI to stay in RESEED_LOAD Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_reseed_load

## ------------------------------------------------------------
## Sequence UFI to stay in RESEED_LOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_reseed_load

## ------------------------------------------------------------
## Sequence UFI to Move in PATTERN_COUNTER_LOAD Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0110
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_pattern_counter_load

## ------------------------------------------------------------
## Sequence UFI to stay in PATTERN_COUNTER_LOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_pattern_counter_load

## ------------------------------------------------------------
## Sequence UFI to stay in PATTERN_COUNTER_LOAD Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_pattern_counter_load

## ------------------------------------------------------------
## Sequence UFI to stay in PATTERN_COUNTER_LOAD Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_pattern_counter_load

## ------------------------------------------------------------
## Sequence UFI to stay in PATTERN_COUNTER_LOAD Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_pattern_counter_load

## ------------------------------------------------------------
## Sequence UFI to stay in PATTERN_COUNTER_LOAD Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_pattern_counter_load

## ------------------------------------------------------------
## Sequence UFI to stay in PATTERN_COUNTER_LOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_pattern_counter_load

## ------------------------------------------------------------
## Sequence UFI to Move in CAPTURE Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0111
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_capture

## ------------------------------------------------------------
## Sequence UFI to stay in CAPTURE Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_capture

## ------------------------------------------------------------
## Sequence UFI to stay in CAPTURE Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_capture

## ------------------------------------------------------------
## Sequence UFI to stay in CAPTURE Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_capture

## ------------------------------------------------------------
## Sequence UFI to stay in CAPTURE Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_capture

## ------------------------------------------------------------
## Sequence UFI to stay in CAPTURE Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_capture

## ------------------------------------------------------------
## Sequence UFI to stay in CAPTURE Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_capture

## ------------------------------------------------------------
## Sequence UFI to Move in MISR_SHADOW_STATUS_UPDATE Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0100
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0111
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_misr_shadow_status_update

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UPDATE Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_misr_shadow_status_update

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UPDATE Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_misr_shadow_status_update

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UPDATE Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_misr_shadow_status_update

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UPDATE Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_misr_shadow_status_update

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UPDATE Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_misr_shadow_status_update

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UPDATE Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_misr_shadow_status_update

## ------------------------------------------------------------
## Sequence UFI to Move in MISR_SHADOW_STATUS_UNLOAD Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0010
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0111
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_misr_shadow_status_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UNLOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_misr_shadow_status_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UNLOAD Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_misr_shadow_status_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UNLOAD Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_misr_shadow_status_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UNLOAD Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_misr_shadow_status_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UNLOAD Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_misr_shadow_status_unload

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_STATUS_UNLOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_misr_shadow_status_unload

## ------------------------------------------------------------
## Sequence UFI to Move in MISR_SHADOW_LOAD Mode and RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0011
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0111
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state mask -ufi_mode xtr_ufi_mode_misr_shadow_load

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_LOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_misr_shadow_load

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_LOAD Mode and move to CDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_captureDR -ufi_mode xtr_ufi_mode_misr_shadow_load

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_LOAD Mode and move to SDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_shiftDR -ufi_mode xtr_ufi_mode_misr_shadow_load

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_LOAD Mode and mode to EDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_exit1DR -ufi_mode xtr_ufi_mode_misr_shadow_load

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_LOAD Mode and move to UDR State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_updateDR -ufi_mode xtr_ufi_mode_misr_shadow_load

## ------------------------------------------------------------
## Sequence UFI to stay in MISR_SHADOW_LOAD Mode and move to RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_misr_shadow_load

## ------------------------------------------------------------
## Sequence UFI to Move in CODEC_DRC Mode and RTI-->CDR-->EDR-->UDR-->RTI State
## ------------------------------------------------------------
set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } { $prgmConfig wait_cycles $PreamblePaddingHeadCycles }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0010
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1010
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1010
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1010
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0010
    if {[info exists ufi_list]} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCyclesForUfiSelfTest ne "0" } { $prgmConfig wait_cycles $PreamblePaddingTailCyclesForUfiSelfTest }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCyclesForUfiSelfTest $cycle_post_wait"
set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"
set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"
if { $wait_cnt ne "0" } { $prgmConfig wait_cycles $wait_cnt }
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1
::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle count after tck_multiple fix $cycle_post_wait"

::ATE::atpg_init::ufi_expect -prgmConfig $prgmConfig -testConfig $testConfig -ufi_state xtr_ufi_state_rti -ufi_mode xtr_ufi_mode_codec_drc
}

proc ::ATE::atpg_init::ufi_reset_sequence { args } {
global unified_scan_spec
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
        {xtr_ip_controller_skip_list.arg "" "list of IP which is required to skip IP controller progm during IST"}
}

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig xtr_ip_controller_skip_list " {
set $temp_var_name $listargsParams($temp_var_name)
}

puts "INFO: In the proc ufi_reset_sequence"

set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set scan_en_ext_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCTL0 ] 0 ]
puts "INFO: scan_en_ext_pin $scan_en_ext_pin"
if { $scan_en_ext_pin eq "" } { 
puts stderr "ERROR: scan_en_ext pin is not defined" 
exit 1 
}

if { [file exists $unified_scan_spec]} {
set accessConfig [config_read_yaml $unified_scan_spec]
set ufi_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
puts "INFO: UFI pin list is $ufi_list"
set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
puts "INFO: serdes4f pin list is $serdes4f_list"
} else {
set ufi_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj UFI ] 0 ]
set serdes_4f_clk_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj TESTCLK=serdes4f_clk ] 0]
puts "INFO: serdes_4f_clk_pin $serdes_4f_clk_pin"
puts "INFO: ufi_pin $ufi_pin"
        if {$ufi_pin ne ""} {
    set ufi_list [ list $ufi_pin]
        }
set serdes4f_list [ list $serdes_4f_clk_pin]
if {!([$prgmConfig is_sim_mode] || [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] ist_mode])} { 
if { $ufi_pin eq "" } { 
puts stderr "ERROR: ufi_pin is not defined" 
exit 1 
}
if { $serdes_4f_clk_pin eq "" } { 
puts stderr "ERROR: serdes_4f_clk pin is not defined" 
exit 1 
}
}
}

set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
puts "INFO: common modes: $common_modes"
if {[llength $common_modes] eq "0"} {
puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
exit 1
}
foreach common_mode $common_modes {
if {[regexp "SERDES_RATIO" $common_mode]} {
switch $common_mode {
SERDES_RATIO_S4 { set SerdesRatio 4 }
SERDES_RATIO_S6 { set SerdesRatio 6 }
SERDES_RATIO_S8 { set SerdesRatio 8 }
SERDES_RATIO_S12 { set SerdesRatio 12 }
SERDES_RATIO_S24 { set SerdesRatio 24 }
}
}
}

set padding_list [::ATE::atpg_init::get_padding_cycles -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio]
set PreamblePaddingHeadCycles [ lindex $padding_list 0 ]
set PreamblePaddingTailCycles [ lindex $padding_list 1 ]
set PreamblePaddingTailCyclesForUfiSelfTest [ lindex $padding_list 2 ]
#puts "PreamblePaddingHeadCycles $PreamblePaddingHeadCycles"
#puts "PreamblePaddingTailCycles $PreamblePaddingTailCycles"
#puts "PreamblePaddingTailCyclesForUfiSelfTest $PreamblePaddingTailCyclesForUfiSelfTest"

puts "INFO: Setting UFI 0"
puts "INFO: Setting scan enable to 1"
puts "INFO: Setting 4f clock to 0"
    if {[info exists ufi_list]} {
        puts "vxiao ufi_list=$ufi_list"
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 1
$prgmConfig program

puts "INFO: wait for 5* SerdesRatio"
set wait_cyc [expr 5 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig
set se_deassert [config_find $testConfig "USER_CUSTOM_ARGS/se_deassert"]
set se_assert [config_find $testConfig "USER_CUSTOM_ARGS/se_assert"]
set capture_count [config_find $testConfig "USER_CUSTOM_ARGS/capture_count"]

if { $se_deassert ne "" } {
puts "INFO: set xtr_ufi_se_deassert_ctrl to $se_deassert"
$prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_se_deassert_ctrl" -value $se_deassert
}
if { $se_assert ne "" } {
puts "INFO: set xtr_ufi_se_assert_ctrl to $se_assert"
$prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_se_assert_ctrl" -value $se_assert
}
if { $capture_count ne "" } {
puts "INFO: set xtr_ufi_capture_count to $capture_count"
$prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_capture_count" -value $capture_count
#} else {
# # set a default value of 8 if it is not defined
# set capture_count 8
# puts "INFO: set xtr_ufi_capture_count to $capture_count"
# $prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_capture_count" -value $capture_count
}

puts "INFO: Assert ufi_reset"
$prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_reset_" -value 0
$prgmConfig program
$prgmConfig waitRti 20


set num_1500_pipelines [$prgmConfig get_total_num_ieee1500_pipelines]
puts "INFO: Waiting for 1500 pipelines $num_1500_pipelines before ufi sequence"
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Before wait cycle $current_cycle"
$prgmConfig waitRti $num_1500_pipelines

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After wait cycle $current_cycle"

# additional 100 waitRti as the above only applies tck for 5 + 5 = 10 waitRti
for {set i 0} {$i < 20} {incr i} {
$prgmConfig waitRti 5
}

set xtr_target_ip_list [config_find $testConfig USER_CUSTOM_ARGS/xtr_target_ip_list]
#    set xtr_ip_controller_skip_list      $params(xtr_ip_controller_skip_list)
#    set xtr_ip_controller_skip_list [config_find $testConfig USER_CUSTOM_ARGS/xtr_ip_controller_skip_list]

# NEW ARG require:
#full chip: 
#  xtr_ip_controller_skip_list.arg
#  capture_count.arg
#  chiplet_string.arg
#  chiplet_id_bit.arg
#  xtr_scan_in.arg
#  status_link_width.arg
#IP level:
#  chiplet_id_bit.arg
#  xtr_scan_in.arg
#  status_link_width.arg

set IST_MODE 0
    set full_test_name [config_map_value [config_find $testConfig CURRENT_TEST] name]
  set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]


foreach common_mode $common_modes {
if {[regexp "IST_LBIST_" $common_mode]} {
                set IST_MODE 1;
}
}

     set xtr_link_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_link_fast_scanin_pipes"]
         set xtr_link_fast_scanout_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_link_fast_scanout_pipes"]
         set xtr_ip_to_tam_top_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_to_tam_top_fast_scanin_pipes"]
         set xtr_ip_from_tam_top_fast_scanout_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_from_tam_top_fast_scanout_pipes"]
         set xtr_ip_broadcast_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_broadcast_fast_scanin_pipes"]
         set xtr_ip_broadcast_fast_scanin_default_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_broadcast_fast_scanin_default_pipes"]
         set xtr_ip_tam_top_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_tam_top_fast_scanin_pipes"]
         set xtr_ip_tam_top_fast_scanout_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_tam_top_fast_scanout_pipes"]
         set xtr_ip_control_slow_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_control_slow_pipes"]
         set xtr_ip_control_slow_default_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_control_slow_default_pipes"]
         set xtr_ip_control_slow_compensatory_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_control_slow_compensatory_pipes"]
         set xtr_ip_misr_slow_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_misr_slow_pipes"]

#         set chiplet_name [config_find $testConfig "USER_CUSTOM_ARGS/chiplet_string"]
#         set chiplet_id_offset [config_find $testConfig "USER_CUSTOM_ARGS/chiplet_id_bit"]
#         set xtr_scan_in_int [config_find $testConfig "USER_CUSTOM_ARGS/xtr_scan_in"]
#         set status_link_wd [config_find $testConfig "USER_CUSTOM_ARGS/status_link_width"]
         set capture_count [config_find $testConfig "USER_CUSTOM_ARGS/capture_count"]

    $prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_reset_" -value 1
$prgmConfig set_program_value ".*/XTR_UFI_FSM" ".*xtr_ufi_mode" -value 1
$prgmConfig program
$prgmConfig waitRti 20


set num_1500_pipelines [$prgmConfig get_total_num_ieee1500_pipelines]
puts "INFO: Waiting for 1500 pipelines $num_1500_pipelines before ufi sequence"
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Before wait cycle $current_cycle"
$prgmConfig waitRti $num_1500_pipelines

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After wait cycle $current_cycle"

# additional 100 waitRti as the above only applies tck for 5 + 5 = 10 waitRti
for {set i 0} {$i < 20} {incr i} {
$prgmConfig waitRti 5
}

set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After additional 100 waitRti wait cycle $current_cycle"

set cycle_ufi_start [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi reset deassert $cycle_ufi_start"

set cycle_4f_start [ $prgmConfig get_current_cycle ]
puts "INFO: Setting serdes fast clock to 1 at cycle $cycle_4f_start"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
$prgmConfig program

puts "INFO: wait for 16* SerdesRatio"
set wait_cyc [expr 16 * $SerdesRatio ]
$prgmConfig wait_cycles $wait_cyc

set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_start - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"

if { $wait_cnt ne "0" } {
$prgmConfig wait_cycles $wait_cnt
}
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

if { $PreamblePaddingHeadCycles ne "0" } {
$prgmConfig wait_cycles $PreamblePaddingHeadCycles
}
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingHeadCycles $cycle_post_wait"

::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1001
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0010
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 1000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0000
::ATE::atpg_init::ufi_program -prgmConfig $prgmConfig -testConfig $testConfig -SerdesRatio $SerdesRatio -ufi_val 0001

set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after UFI programming $cycle_post_wait"

if { $PreamblePaddingTailCycles ne "0" } {
$prgmConfig wait_cycles $PreamblePaddingTailCycles
}

set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number after PreamblePaddingTailCycles $cycle_post_wait"

set cycle_ufi_stop [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of ufi program end $cycle_ufi_stop"

set wait_cnt [expr $SerdesRatio - [expr [expr $cycle_ufi_stop - $cycle_4f_start] % $SerdesRatio]]
puts "INFO: Wait count for 4f 1f sync $wait_cnt"

if { $wait_cnt ne "0" } {
$prgmConfig wait_cycles $wait_cnt
}
set cycle_post_wait [ $prgmConfig get_current_cycle ]
puts "INFO: Cycle number at the time of 4f 1f sync $cycle_post_wait"

puts "INFO: Make 4f clock and scan en 0"
foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
$prgmConfig set_pin_value $scan_en_ext_pin 0
$prgmConfig program
$prgmConfig wait_cycles 1

::ATE::atpg_init::fix_wait_cycles -prgmConfig $prgmConfig -testConfig $testConfig

set cycle_post_wait [ $prgmConfig get_current_cycle ]
#puts "cycle number $cycle_post_wait"
}

proc ::ATE::atpg_init::ufi_program { args } {
global unified_scan_spec
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
{SerdesRatio.arg "" "<serdes ratio>" "NO_CUSTOMIZE"}
{ufi_val.arg "" "<ufi_val>" "NO_CUSTOMIZE"}
}

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig SerdesRatio ufi_val" {
set $temp_var_name $listargsParams($temp_var_name)
}
#puts "In the proc ufi_program SerdesRatio $SerdesRatio"

puts "INFO: programming UFI to $ufi_val"
set ufi_arr [split $ufi_val {} ]
set UMS_0 [lindex $ufi_arr 3]
set UMS_1 [lindex $ufi_arr 2]
set UMS_2 [lindex $ufi_arr 1]
set UFS [lindex $ufi_arr 0]
#puts "UFS $UFS UMS_2 $UMS_2 UMS_1 $UMS_1 UMS_0 $UMS_0 "
if { [file exists $unified_scan_spec]} {
set accessConfig [config_read_yaml $unified_scan_spec]
set ufi_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
} else {
set die_obj [config_find $testConfig "CURRENT_TEST/die_obj"]
set ufi_pin [lindex [::pkgtool::get_vlog_pins_with_test_function $die_obj UFI ] 0 ]
if {!([$prgmConfig is_sim_mode] || [config_map_value [config_find $testConfig USER_CUSTOM_ARGS] ist_mode])} {
if { $ufi_pin eq "" } { 
puts stderr "ERROR: ufi_pin is not defined" 
exit 1 
}
}
        if {$ufi_pin ne ""} {
    set ufi_list [list $ufi_pin]
        }
}

set loop_cnt [expr $SerdesRatio - 4]
#puts "loop_cnt $loop_cnt"
    if {[info exists ufi_list]} {
   for {set i 0} {$i < $loop_cnt} {incr i} {
    foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    $prgmConfig program
    $prgmConfig wait_cycles 1
   }
    }
    if {[info exists ufi_list]} {

foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin $UMS_0 }
$prgmConfig program
$prgmConfig wait_cycles 1
foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin $UMS_1 }
$prgmConfig program
$prgmConfig wait_cycles 1
foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin $UMS_2 }
$prgmConfig program
$prgmConfig wait_cycles 1
foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin $UFS }
$prgmConfig program
$prgmConfig wait_cycles 1
foreach ufi_pin $ufi_list { $prgmConfig set_pin_value $ufi_pin 0 }
    }
}

proc ::ATE::atpg_init::ufi_expect { args } {
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
{ufi_state.arg "" "<ufi_state>" "NO_CUSTOMIZE"}
{ufi_mode.arg "" "<ufi_state>" "NO_CUSTOMIZE"}
}

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]
array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig ufi_state ufi_mode" {
set $temp_var_name $listargsParams($temp_var_name)
}

set curr_cyc [$prgmConfig get_current_cycle ]
puts "INFO: expecting UFI to be in $ufi_state $ufi_mode at $curr_cyc"
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_reset -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_idle -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_codec_drc -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_occ_load -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_misr_unload -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_misr_shadow_status_unload -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_misr_shadow_load -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_misr_shadow_status_update -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_reseed_load -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_pattern_counter_load -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_capture -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_tlr -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_rti -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_captureDR -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_shiftDR -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_exit1DR -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_updateDR -expected 1'b0
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_updateIR -expected 1'b0

if { $ufi_state eq "mask" } { 
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_tlr -expected X
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_rti -expected X
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_captureDR -expected X
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_shiftDR -expected X
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_exit1DR -expected X
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_updateDR -expected X
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_state_updateIR -expected X
} else {
$prgmConfig set_program_value ".*/XTR_UFI_FSM" $ufi_state -expected 1'b1
}
if { $ufi_mode eq "xtr_ufi_mode_capture" } { 
$prgmConfig set_program_value ".*/XTR_UFI_FSM" xtr_ufi_mode_reseed_load -expected 1'b1
$prgmConfig set_program_value ".*/XTR_UFI_FSM" $ufi_mode -expected 1'b1
} else {
$prgmConfig set_program_value ".*/XTR_UFI_FSM" $ufi_mode -expected 1'b1
}

$prgmConfig program

set num_1500_pipelines [$prgmConfig get_total_num_ieee1500_pipelines]
puts "INFO: Waiting for 1500 pipelines $num_1500_pipelines "
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: Before wait cycle $current_cycle"
$prgmConfig waitRti $num_1500_pipelines
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After wait cycle $current_cycle"

# additional 100 waitRti as the above only applies tck for 5 + 5 = 10 waitRti
for {set i 0} {$i < 20} {incr i} { $prgmConfig waitRti 5 }
set current_cycle [ $prgmConfig get_current_cycle ]
puts "INFO: After additional 100 waitRti wait cycle $current_cycle"

}

proc ::ATE::atpg_init::FORCE_CLOCK_CHAIN { prgmConfig testConfig name width value} {
puts "WARN: Forceing clock chain"
set temp [new_binary_vector $width]
set msb [expr $width - 1]
set lsb 0
set chip_name [$prgmConfig name]
set_range $temp $msb $lsb "$width'h$value"

$prgmConfig jtag_force "tb.clock_chain_force.enable_${name}_force" 1
if { $width eq "1"} {
$prgmConfig jtag_force "tb.clock_chain_force.${name}_data" $value
} else {
for {set i 0} {$i < $width} {incr i} {
            if {[regexp "GAA" $chip_name]} {
                # npan, don't force tb.clock_chain_force.enable_edge_control_chain_data_ as we don't have edgecontrol in ga100.
                if {$name ne "enable_edge_control_chain"} {
        $prgmConfig jtag_force "tb.clock_chain_force.${name}_data_$i" [get_range $temp $i $i]
                }
            } else {
    $prgmConfig jtag_force "tb.clock_chain_force.${name}_data_$i" [get_range $temp $i $i]
            }
}
}
}

proc ::ATE::atpg_init::get_padding_cycles { args } {
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
{SerdesRatio.arg "" "<serdes ratio>" "NO_CUSTOMIZE"}
}

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]
array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig SerdesRatio" {
set $temp_var_name $listargsParams($temp_var_name)
}

# SDP related calculations
set xtr_link_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_link_fast_scanin_pipes"]
set xtr_link_fast_scanout_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_link_fast_scanout_pipes"]
set xtr_ip_to_tam_top_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_to_tam_top_fast_scanin_pipes"]
set xtr_ip_from_tam_top_fast_scanout_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_from_tam_top_fast_scanout_pipes"]
set xtr_ip_broadcast_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_broadcast_fast_scanin_pipes"]
set xtr_ip_broadcast_fast_scanin_default_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_broadcast_fast_scanin_default_pipes"]
set xtr_ip_tam_top_fast_scanin_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_tam_top_fast_scanin_pipes"]
set xtr_ip_tam_top_fast_scanout_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_tam_top_fast_scanout_pipes"]
set xtr_ip_control_slow_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_control_slow_pipes"]
set xtr_ip_control_slow_default_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_control_slow_default_pipes"]
set xtr_ip_control_slow_compensatory_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_control_slow_compensatory_pipes"]
set xtr_ip_misr_slow_pipes [config_find $testConfig "USER_CUSTOM_ARGS/xtr_ip_misr_slow_pipes"]
if {$xtr_link_fast_scanin_pipes eq ""} { set xtr_link_fast_scanin_pipes 0 } 
if {$xtr_link_fast_scanout_pipes eq ""} { set xtr_link_fast_scanout_pipes 0 } 
if {$xtr_ip_to_tam_top_fast_scanin_pipes eq ""} { set xtr_ip_to_tam_top_fast_scanin_pipes 0 } 
if {$xtr_ip_from_tam_top_fast_scanout_pipes eq ""} { set xtr_ip_from_tam_top_fast_scanout_pipes 0 } 
if {$xtr_ip_broadcast_fast_scanin_pipes eq ""} { set xtr_ip_broadcast_fast_scanin_pipes 0 } 
if {$xtr_ip_broadcast_fast_scanin_default_pipes eq ""} { set xtr_ip_broadcast_fast_scanin_default_pipes 0 } 
if {$xtr_ip_tam_top_fast_scanin_pipes eq ""} { set xtr_ip_tam_top_fast_scanin_pipes 0 } 
if {$xtr_ip_tam_top_fast_scanout_pipes eq ""} { set xtr_ip_tam_top_fast_scanout_pipes 0 } 
if {$xtr_ip_control_slow_pipes eq ""} { set xtr_ip_control_slow_pipes 0 } 
if {$xtr_ip_control_slow_default_pipes eq ""} { set xtr_ip_control_slow_default_pipes 0 } 
if {$xtr_ip_control_slow_compensatory_pipes eq ""} { set xtr_ip_control_slow_compensatory_pipes 0 } 
if {$xtr_ip_misr_slow_pipes eq ""} { set xtr_ip_misr_slow_pipes 0 } 

set ExternalCyclesPerShift $SerdesRatio
set total_fast_scanin_pipes [expr $xtr_link_fast_scanin_pipes + $xtr_ip_to_tam_top_fast_scanin_pipes + $xtr_ip_tam_top_fast_scanin_pipes + $xtr_ip_broadcast_fast_scanin_default_pipes + $xtr_ip_broadcast_fast_scanin_pipes ]
set total_full_fast_scanin_pipe_fast_cycles [expr [expr [expr $total_fast_scanin_pipes + [expr $SerdesRatio * 2] ] / $SerdesRatio ] * $SerdesRatio ]
set total_slow_scanin_pipes [expr $xtr_ip_control_slow_default_pipes + $xtr_ip_control_slow_pipes]
set total_full_slow_scanin_pipe_fast_cycles [expr $total_slow_scanin_pipes * $SerdesRatio]
set total_fast_scanout_pipe_fast_cycles [expr $xtr_link_fast_scanout_pipes + $xtr_ip_from_tam_top_fast_scanout_pipes + $xtr_ip_tam_top_fast_scanout_pipes + $SerdesRatio + 1 ] 

set InternalLoadDelay [expr $total_full_fast_scanin_pipe_fast_cycles + $total_full_slow_scanin_pipe_fast_cycles ]
set InternalIDUDelay $total_full_fast_scanin_pipe_fast_cycles
set InternalUnloadDelay $total_fast_scanout_pipe_fast_cycles
set AdditionalLoadDelay [expr $total_fast_scanin_pipes % $SerdesRatio] 
set NumCodecDrcChainFastInputCells [expr $xtr_link_fast_scanin_pipes + $xtr_ip_to_tam_top_fast_scanin_pipes + $xtr_ip_tam_top_fast_scanin_pipes ]
set NumCodecDrcChainFastOutputCells [expr $xtr_link_fast_scanout_pipes + $xtr_ip_from_tam_top_fast_scanout_pipes + $xtr_ip_tam_top_fast_scanout_pipes]

#set PreamblePaddingTailCycles $total_fast_scanin_pipes
set PreamblePaddingTailCycles $InternalLoadDelay
set PreamblePaddingTailCyclesForUfiSelfTest $InternalIDUDelay
if {$AdditionalLoadDelay == 0} {
set PreamblePaddingHeadCycles 0
} else {
set PreamblePaddingHeadCycles [expr $SerdesRatio - $AdditionalLoadDelay]
}
puts "INFO: PreamblePaddingHeadCycles $PreamblePaddingHeadCycles"
puts "INFO: PreamblePaddingTailCycles $PreamblePaddingTailCycles"
puts "INFO: PreamblePaddingTailCyclesForUfiSelfTest $PreamblePaddingTailCyclesForUfiSelfTest"
return [list $PreamblePaddingHeadCycles $PreamblePaddingTailCycles $PreamblePaddingTailCyclesForUfiSelfTest]
}

proc ::ATE::atpg_init::fix_wait_cycles { args } {
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
}
array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]
array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
}
set curr_cyc [$prgmConfig get_current_cycle]
set tck_mult [$prgmConfig get_tck_multiple]
puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
if {[ expr $curr_cyc % $tck_mult ] != 0} {
set wait_cyc [ expr $tck_mult - [ expr $curr_cyc % $tck_mult ]]
$prgmConfig wait_cycles $wait_cyc
set curr_cyc [$prgmConfig get_current_cycle]
puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
}
}

proc ::ATE::atpg_init::reset_from_sf { args } {
        global unified_scan_spec
    puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============ENTER procedure: [lindex [info level 0] 0]=============="
        # get user option
puts  "INFO: calling reset_from_sf" 
    set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
        {fstate.arg "" "<fstate obje>" "NO_CUSTOMIZE"}
{SerdesRatio.arg "" "<serdes ratio>" "NO_CUSTOMIZE"}
        {listArgs.arg "" "-option helper; resync_serdes proc"}
}


array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

    array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig fstate SerdesRatio" {
set $temp_var_name $listargsParams($temp_var_name)
    }
    if {![regexp "^\s*$" $mainParams(ListArgs)]} {
upvar $mainParams(ListArgs) subtest_option
set subtest_option $listArgsOptions

        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_type" -value "SCAN_TEST"
        #::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "global_init_behavior" -value "skip_init"
        #::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_init_behavior" -value "skip_init"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "chiplet_flow_certified" -value 1
## jeryang
        #::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "XTR_STUCKAT_SERDES"
# jeryang
set temp_bak_args $::argv
array set temp_param_array [::cmdline::getKnownOptions temp_bak_args {{sub_mode.arg "" ""}}]
set sub_mode_in $temp_param_array(sub_mode)

puts "INFO: sub_mode=$sub_mode_in"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "$sub_mode_in"
        puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============LEAVE procedure: [lindex [info level 0] 0]=============="
return 1
    }
    
    foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
    }

    set sub_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST] "sub_modes"]]
    puts "INFO: sub_modes: $sub_modes"
if {[llength $sub_modes] eq "0"} {
        puts stderr "ERROR: Please add tn arg -sub_mode to set proper scan sub_mode."
        exit 1    
    }
    
    set dft_modes_config_file "$::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml"
    if { [file exists $dft_modes_config_file]} {
        puts "INFO: standard dft mode programming yml file found. Reading..."
        set dft_modeConfig [config_read_yaml $dft_modes_config_file]
    } else {
        puts stderr "ERROR: $dft_modes_config_file file is missing. Please fix it first."
        exit 1
    }

    puts "Running reset_from_sf" 

    set access_config $unified_scan_spec
    if { [file exists $access_config]} {
        set accessConfig [config_read_yaml $access_config]
    } else {
       puts "ERR: need provide access config list $access_config"
    }

    set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
    puts "INFO: serdes4f pin list is $serdes4f_list"
    set ufi_pins [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
    # We do not need this after FTC
    # puts " Make ufi pins 0"
    # foreach ufi_pin $ufi_pins {
    #     $prgmConfig set_pin_value $ufi_pin         0
    # }

    # ##need to review this pex_rst_n
    # puts "make pex_rst_n as 1"
    # #$prgmConfig set_pin_value pex_rst_n 1
    # puts "make nvjtag_sel as 1"
    # $prgmConfig set_pin_value nvjtag_sel 1


    puts " Now, make serdes4f clk as 0"
     foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
    $prgmConfig waitRti 1

    ## set all the bits to reset value of 0.
    $prgmConfig set_program_value {.*ATPG_CTL} {.*} -value 0 -replicate

    # set FSvalidation bits to 1, as that is the reset value
#    $prgmConfig set_program_value {.*ATPG_CTL} {.*FSvalidation.*} -value 1
#    $prgmConfig set_program_value {.*DFT_FS_CTRL} {.*DFT_FS_CTRL} -value 1
    puts "get the previous register state"
    
    #set fstate_file "../atpg_init/fstate.yml"
    set fstate_file $fstate
    set fstateConfig [config_read_yaml $fstate_file]
    set fstate_list [config_list [config_find $fstateConfig fstate]]

    foreach state $fstate_list {
        # puts "fstate is $state"
        set field [split $state "#"]
        puts " REG:  [lindex $field 0] field: [lindex $field 1] value [lindex $field 2] "
        set REG [lindex $field 0]
        set REG_FIELD [lindex $field 1] 
        set VALUE [lindex $field 2] 
        $prgmConfig set_program_value $REG $REG_FIELD -value $VALUE
    }

    # Set reset from scan flop to 1
    $prgmConfig set_program_value {.*ATPG_CTL} {.*RESET_1500_OVERRIDE_RESET_1500_OVERRIDE_select_atpg_ctl.*} -value 1
    $prgmConfig program

    #serdes div ratio
    set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
    puts "INFO: common modes: $common_modes"
        if {[llength $common_modes] eq "0"} {
        puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
        exit 1    
    }
    foreach common_mode $common_modes {
        if {[regexp "SERDES_RATIO" $common_mode]} {
            switch $common_mode {
                SERDES_RATIO_S4 { set serdes_div_ratio 4 }
                SERDES_RATIO_S6 { set serdes_div_ratio 6 }
                SERDES_RATIO_S8 { set serdes_div_ratio 8 }
                SERDES_RATIO_S12 { set serdes_div_ratio 12 }
                SERDES_RATIO_S24 { set serdes_div_ratio 24 }
            }
        }
    }

    puts "INFO: Add few cycles until serdes starts pulsing"
    for {set i 0} {$i < 20} {incr i} {
        $prgmConfig waitRti 5
    }
    puts "INFO: Done adding cycles" 
    set curr_cyc [$prgmConfig get_current_cycle]
    set tck_mult [$prgmConfig get_tck_multiple]
    set serdes_ratio $serdes_div_ratio
    set mult_required [expr $tck_mult * $serdes_ratio]
    puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
    if {[ expr $curr_cyc % $mult_required ] != 0} {
        set wait_cyc [ expr $mult_required - [ expr $curr_cyc % $mult_required ]]
        $prgmConfig wait_cycles $wait_cyc
        set curr_cyc [$prgmConfig get_current_cycle]
        puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
    }

    puts " Now, start serdes4f clk "
    foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
    $prgmConfig program
    $prgmConfig waitRti 5  ;# Extra wait time required to allow reset signal to propagate
    $prgmConfig waitRti 5  ;# Extra wait time required to allow reset signal to propagate

    set curr_cyc [$prgmConfig get_current_cycle]
    set tck_mult [$prgmConfig get_tck_multiple]
    set serdes_ratio $serdes_div_ratio
    set mult_required [expr $tck_mult * $serdes_ratio]
    puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
    if {[ expr $curr_cyc % $mult_required ] != 0} {
        set wait_cyc [ expr $mult_required - [ expr $curr_cyc % $mult_required ]]
        $prgmConfig wait_cycles $wait_cyc
        set curr_cyc [$prgmConfig get_current_cycle]
        puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
    }

    puts "done programming reset_from_sf"
    puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============LEAVE procedure: [lindex [info level 0] 0]=============="
}

proc ::ATE::atpg_init::fs_top_up { args } {
        global unified_scan_spec
    puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============ENTER procedure: [lindex [info level 0] 0]=============="
# get user option
puts  "INFO: calling fs_top_up" 
    set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
{SerdesRatio.arg "" "<serdes ratio>" "NO_CUSTOMIZE"}
        {listArgs.arg "" "-option helper; resync_serdes proc"}
}


array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

    array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig SerdesRatio" {
set $temp_var_name $listargsParams($temp_var_name)
    }
    if {![regexp "^\s*$" $mainParams(ListArgs)]} {
upvar $mainParams(ListArgs) subtest_option
set subtest_option $listArgsOptions

        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_type" -value "SCAN_TEST"
        #::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "global_init_behavior" -value "skip_init"
        #::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_init_behavior" -value "skip_init"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "chiplet_flow_certified" -value 1
## jeryang
        #::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "XTR_STUCKAT_SERDES"
# jeryang
set temp_bak_args $::argv
array set temp_param_array [::cmdline::getKnownOptions temp_bak_args {{sub_mode.arg "" ""}}]
set sub_mode_in $temp_param_array(sub_mode)

puts "INFO: sub_mode=$sub_mode_in"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "$sub_mode_in"
        puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============LEAVE procedure: [lindex [info level 0] 0]=============="
return 1
    }
    
    foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
    }

    set sub_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST] "sub_modes"]]
    puts "INFO: sub_modes: $sub_modes"
if {[llength $sub_modes] eq "0"} {
        puts stderr "ERROR: Please add tn arg -sub_mode to set proper scan sub_mode."
        exit 1    
    }
    
    set dft_modes_config_file "$::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml"
    if { [file exists $dft_modes_config_file]} {
        puts "INFO: standard dft mode programming yml file found. Reading..."
        set dft_modeConfig [config_read_yaml $dft_modes_config_file]
    } else {
        puts stderr "ERROR: $dft_modes_config_file file is missing. Please fix it first."
        exit 1
    }

    puts "Running fs_top_up" 

    set access_config $unified_scan_spec
    if { [file exists $access_config]} {
        set accessConfig [config_read_yaml $access_config]
    } else {
        puts "ERR: need provide access config list $access_config"
    }

    set serdes4f_list [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/SERDES_CLK_PORTS]]
    puts "INFO: serdes4f pin list is $serdes4f_list"
    set ufi_pins [config_list [config_find $accessConfig SCAN_IOS/XTREME_X4/STYLE_SPECIFIC_CONFIG/XTREME_UFI_PORTS]]
    # We do not need this after FTC
    # puts " Make ufi pins 0"
    # foreach ufi_pin $ufi_pins {
    #     $prgmConfig set_pin_value $ufi_pin         0
    # }

# set const_ports_list [config_find $accessConfig SCAN_IOS/XTREME_X4/PIN_CONSTRAINTS]
    # #puts "INFO: Constant ports list is $const_ports_list"
    # puts "INFO: Setting Constant ports to their values, except tck"
    # foreach const_port [config_map_keys $const_ports_list] {
    #     set const_port_value [config_map_value $const_ports_list $const_port]
    #     if { $const_port ne "jtag_tck" } {
    #         puts "INFO: $const_port as $const_port_value"
    #         $prgmConfig set_pin_value $const_port $const_port_value
    #     }
    # }

    # #puts "make pex_rst_n as 1"
    # #$prgmConfig set_pin_value pex_rst_n 1
    # #puts "make nvjtag_sel as 1"
    # #$prgmConfig set_pin_value nvjtag_sel 1

    puts "INFO: Make serdes4f clk as 0"
     foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 0 }
    $prgmConfig waitRti 1

    puts "INFO: start programming TOP_FS register"
    $prgmConfig set_program_value {.*TOP_FS} {.*} -value 0 -replicate
    $prgmConfig program -force


    ##  puts "start programming POWER_CTL_VAL register "
##Confirmed with Nithin, for GA100, POWER_CTL_VAL does not have any loadining any more
    #  $prgmConfig set_program_value {.*g0_.*/POWER_CTL_VAL} {.*jtag_val_pgclamp} -value 1'h0
    #  $prgmConfig program -force


#   <field name="SYS/sys_logic/fuse/opt_hdmi_disable" range="159" reset_value="b0">
#   <field name="SYS/sys_logic/fuse/opt_nvlink_disable" range="153:146" reset_value="b00000000">
#   <field name="SYS/sys_logic/fuse/opt_rop_l2_disable" range="139:128" reset_value="b000000000000">
#   <field name="SYS/sys_logic/fuse/opt_fbp_disable" range="127:122" reset_value="b000000">
#   <field name="SYS/sys_logic/fuse/opt_zcull_disable" range="121:98" reset_value="b000000000000000000000000">
#   <field name="SYS/sys_logic/fuse/opt_pes_disable" range="97:80" reset_value="b000000000000000000">
#   <field name="SYS/sys_logic/fuse/opt_tpc_disable" range="79:50" reset_value="b000000000000000000000000000000">
#   <field name="SYS/sys_logic/fuse/opt_gc6_island_disable" range="37" reset_value="b0">
#   <field name="SYS/sys_logic/fuse/opt_pcie_lane_disable" range="36:35" reset_value="b00">
#   <field name="SYS/sys_logic/fuse/opt_sec_disable" range="34" reset_value="b0">
#   <field name="SYS/sys_logic/fuse/opt_nvenc_disable" range="33:32" reset_value="b00">
#   <field name="SYS/sys_logic/fuse/opt_nvdec_disable" range="31" reset_value="b0">
#   <field name="SYS/sys_logic/fuse/opt_gpc_disable" range="30:25" reset_value="b000000">
#   <field name="SYS/sys_logic/fuse/opt_fbpa_disable" range="24:19" reset_value="b000000">
#   <field name="SYS/sys_logic/fuse/opt_fbio_disable" range="18:13" reset_value="b000000">
#   <field name="SYS/sys_logic/fuse/opt_disp_head_disable" range="6:3" reset_value="b0000">
#   <field name="SYS/sys_logic/fuse/opt_display_disable" range="2" reset_value="b0">


    #serdes div ratio
    set common_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/dft_prgm_common_mode] top ]]
    puts "INFO: common modes: $common_modes"
        if {[llength $common_modes] eq "0"} {
        puts stderr "ERROR: Please add tn arg -common_mode to set proper scan common_mode."
        exit 1    
    }
    foreach common_mode $common_modes {
        if {[regexp "SERDES_RATIO" $common_mode]} {
            switch $common_mode {
                SERDES_RATIO_S4 { set serdes_div_ratio 4 }
                SERDES_RATIO_S6 { set serdes_div_ratio 6 }
                SERDES_RATIO_S8 { set serdes_div_ratio 8 }
                SERDES_RATIO_S12 { set serdes_div_ratio 12 }
                SERDES_RATIO_S24 { set serdes_div_ratio 24 }
            }
        }
    }

    puts "INFO: Add few cycles until serdes starts pulsing"
    for {set i 0} {$i < 20} {incr i} {
        $prgmConfig waitRti 5
    }
    puts "INFO: Done adding cycles" 
    set curr_cyc [$prgmConfig get_current_cycle]
    set tck_mult [$prgmConfig get_tck_multiple]
    set serdes_ratio $serdes_div_ratio
    set mult_required [expr $tck_mult * $serdes_ratio]
    puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
    if {[ expr $curr_cyc % $mult_required ] != 0} {
        set wait_cyc [ expr $mult_required - [ expr $curr_cyc % $mult_required ]]
        $prgmConfig wait_cycles $wait_cyc
        set curr_cyc [$prgmConfig get_current_cycle]
        puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
    }

    puts " Now, start serdes4f clk "
    foreach serdes_4f_clk_pin $serdes4f_list { $prgmConfig set_pin_value $serdes_4f_clk_pin 1 }
    $prgmConfig program
    $prgmConfig waitRti 5  ;# Extra wait time required to allow reset signal to propagate
    $prgmConfig waitRti 5  ;# Extra wait time required to allow reset signal to propagate

    set curr_cyc [$prgmConfig get_current_cycle]
    set tck_mult [$prgmConfig get_tck_multiple]
    set serdes_ratio $serdes_div_ratio
    set mult_required [expr $tck_mult * $serdes_ratio]
    puts "INFO: current_cycle $curr_cyc tck_multiple $tck_mult"
    if {[ expr $curr_cyc % $mult_required ] != 0} {
        set wait_cyc [ expr $mult_required - [ expr $curr_cyc % $mult_required ]]
        $prgmConfig wait_cycles $wait_cyc
        set curr_cyc [$prgmConfig get_current_cycle]
        puts "INFO: After wait_cycle fix - current_cycle $curr_cyc tck_multiple $tck_mult"
    }

    puts "done programming fs_top_up"
    puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============LEAVE procedure: [lindex [info level 0] 0]=============="
}
proc ::ATE::atpg_init::tam_forceflow { args } {
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
}
array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]
array set mainParams [::cmdline::getKnownOptions args $mainOptions]
foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
}
    if {[config_isa [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]] == "VECTOR"} {
        set sub_modes [config_list [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]]
    } else {
        set sub_modes [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST/sub_modes]
    }

    puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============ENTER procedure: [lindex [info level 0] 0]=============="
    if {[regexp {TAM} $sub_modes] || [regexp {PEX} $sub_modes]} {
    puts "Kannan : Info : sub_modes is $sub_modes"
    set mode TAMSERDES_MODE
    }
#    if {[regexp {PEX} $sub_modes]} {
#    puts "Kannan : Info : sub_modes is $sub_modes"
#    set mode PEX_MODE
#    }
    set scaninpin_list [bc_scan_init_analyse $prgmConfig $testConfig $mode scaninpin_list]
    set ufi_list [bc_scan_init_analyse $prgmConfig $testConfig $mode ufi_list]
    set scanoutpin_list [bc_scan_init_analyse $prgmConfig $testConfig $mode scanoutpin_list]
    set scanbidirpin_list  [bc_scan_init_analyse $prgmConfig $testConfig $mode scanbidirpin_list]
    puts "init all pads to be input mode"
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*ten_pindot_over -value 1'b0
#     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*disable_functional_override -value 1'b1
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*prog_bscan_mode -value 1'b1
#     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*pad_tm -value 1'b1
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*pad_tasel -value 1'b0
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*pad_tasel_diff -value 1'b1
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*jtag_mode_1_mask -value 1'b1
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*jtag_mode_1_val -value 1'b0
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*jtag_mode_3_mask -value 1'b1
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*jtag_mode_3_val -value 1'b1
#### this is different between bcsan init and std programming
#     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*en_in_bidir.* -value 1'b1
#     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*en_in_output.* -value 1'b1
#     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*en_in_input.* -value 1'b1
     $prgmConfig set_program_value ".*/GENPADS_CTRLS" .*pad_control_disab.* -value 1'b1
     $prgmConfig set_program_value {.*t0_0.*GENPADS_CTRLS} {.*ist_clamp_ctl} -value 1'b1
     $prgmConfig program
    $prgmConfig set_program_value ".*/EXTEST" {.*} -value 0 -replicate
    $prgmConfig set_program_value ".*/EXTEST" .*_tm.* -value 1'b1
    $prgmConfig set_program_value ".*/EXTEST" .*_ten.* -value 1'b1
    puts " disable ten_inv feature by default"
    $prgmConfig set_program_value ".*/EXTEST"  .*_ten_inv.* -value 1'b0
    array set pin2field {}
    foreach tmppin [concat $scaninpin_list $ufi_list $scanoutpin_list $scanbidirpin_list] {
        #puts "tmppin = $tmppin"
        regsub {\[} $tmppin {\\[} tmppin_1st
        regsub {\]} $tmppin_1st {\\]} tmppin_2nd
        set pin2field($tmppin) ${tmppin_2nd}
        puts "pin2field = $pin2field($tmppin)"
    }
    foreach tmppin $scaninpin_list {
        puts "INFO:Kannan : put $tmppin into input"
        $prgmConfig set_program_value {.*/EXTEST} ".*$pin2field($tmppin)_ten.*" -value 1'b1
        $prgmConfig set_program_value {.*/EXTEST} ".*$pin2field($tmppin)_ten_inv.*" -value 1'b0
    }

    foreach tmppin $ufi_list {
        puts "INFO: Kannan : put ufi $tmppin into input"
        $prgmConfig set_program_value {.*/EXTEST} ".*$pin2field($tmppin)_ten.*" -value 1'b1
        $prgmConfig set_program_value {.*/EXTEST} ".*$pin2field($tmppin)_ten_inv.*" -value 1'b0
    }

    foreach tmppin $scanoutpin_list {
        puts "INFO: Kannan : put $tmppin into output"
        $prgmConfig set_program_value {.*/EXTEST} ".*$pin2field($tmppin)_ten.*" -value 1'b0
        $prgmConfig set_program_value {.*/EXTEST} ".*$pin2field($tmppin)_ten_inv.*" -value 1'b0
    }

    foreach tmppin $scanbidirpin_list {
        puts "enable ten_inv feature"
        $prgmConfig set_program_value {.*/EXTEST} ".*$pin2field($tmppin)_ten_inv.*" -value 1'b1
    }
     $prgmConfig set_program_value ".*/EXTEST" .*tm.*TESTCTL0.* -value 1
     $prgmConfig set_program_value ".*/EXTEST" .*ten.*TESTCTL0.* -value 1
     $prgmConfig set_program_value ".*/EXTEST" .*ten_inv.*TESTCTL0.* -value 0
     $prgmConfig set_program_value ".*/EXTEST" .*tm.*TESTCLK.* -value 1
     $prgmConfig set_program_value ".*/EXTEST" .*ten_TESTCLK.* -value 1
     $prgmConfig set_program_value ".*/EXTEST" .*ten_inv_TESTCLK.* -value 0
     $prgmConfig program
##### this is not needed for EXTEST.. might be for pex.. also.. parallel load is available..dont know if serdesload/ratio0 is a sequence
#     $prgmConfig set_program_value ".*/SERDES_SCAN_TAM" .*pex_pll_bypass -value 1'b1
#     $prgmConfig set_program_value ".*/SERDES_SCAN_TAM" .*Select_SerdesLoad -value 1'b1
#     $prgmConfig set_program_value ".*/SERDES_SCAN_TAM" .*Select_SerdesRatio0 -value 1'b1
#     $prgmConfig set_program_value ".*/SERDES_SCAN_TAM" .*ModeSelect -value 1'b1
#     $prgmConfig program
     puts "Kannan : Info : toggle reset"
     variable die_obj
     set die_obj [config_map_value [config_find $testConfig "CURRENT_TEST"] "die_obj"]
     set resetList [::pkgtool::get_vlog_pins_with_test_function $die_obj "RESET#"]
     set resetList [lreplace $resetList [lsearch $resetList "jtag_trst_"] [lsearch $resetList "jtag_trst_"]]
     foreach reset_signal $resetList {
        puts "INFO: Assert chip reset pin: $reset_signal..."
        $prgmConfig set_enable_value  $reset_signal 1
        $prgmConfig set_pin_value  $reset_signal 1
     }
     $prgmConfig waitRti 100

    puts "[clock format [clock seconds] -format "%m/%d/%Y %H:%M:%S"]==============LEAVE procedure: [lindex [info level 0] 0]=============="

}

proc ::ATE::atpg_init::Template { args } {
# get user option
set mainOptions {
{ListArgs.arg "" "-ListArgs <required argument for the API>"}
}
set listArgsOptions {
{prgmConfig.arg "" "<program config object>" "NO_CUSTOMIZE"}
{testConfig.arg "" "<test config object>" "NO_CUSTOMIZE"}
        {listArgs.arg "" "-option helper; please add -sub_mode tn arg to define SCAN_TEST sub mode defined in the file $::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml, e.g. XTR_STUCKAT_SERDES etc."}
}

array set listargsParams [::cmdline::getKnownOptions args $listArgsOptions]

    array set mainParams [::cmdline::getKnownOptions args $mainOptions]
    if {![regexp "^\s*$" $mainParams(ListArgs)]} {
upvar $mainParams(ListArgs) subtest_option
set subtest_option $listArgsOptions

        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_type" -value "SCAN_TEST"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "global_init_behavior" -value "skip_init"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "test_init_behavior" -value "skip_init"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "chiplet_flow_certified" -value 1
# jeryang
set temp_bak_args $::argv
array set temp_param_array [::cmdline::getKnownOptions temp_bak_args {{sub_mode.arg "" ""}}]
set sub_mode_in $temp_param_array(sub_mode)

puts "INFO: sub_mode=$sub_mode_in"
        ::ATE::AteFlowUtils::setTestApiProperty -name_of_list subtest_option -categoryName execution_ctrl -propName "dft_mode" -value "$sub_mode_in"
#
return 1
}
    
foreach temp_var_name "prgmConfig testConfig" {
set $temp_var_name $listargsParams($temp_var_name)
}

    set sub_modes [config_list [config_map_value [config_find $testConfig CURRENT_TEST/CURRENT_SUBTEST] "sub_modes"]]
    puts "INFO: sub_modes: $sub_modes"
if {[llength $sub_modes] eq "0"} {
        puts stderr "ERROR: Please add tn arg -sub_mode to set proper scan sub_mode."
        exit 1    
    }
    
    set dft_modes_config_file "$::env(NVDEV)/nvtools/dft/data/standard_dft_modes_programming.yml"
    if { [file exists $dft_modes_config_file]} {
        puts "INFO: standard dft mode programming yml file found. Reading..."
        set dft_modeConfig [config_read_yaml $dft_modes_config_file]
    } else {
        puts stderr "ERROR: $dft_modes_config_file file is missing. Please fix it first."
        exit 1
    }
    foreach sub_mode $sub_modes {
        if {[regexp "Stuckat" $sub_mode] || [regexp "Ftm" $sub_mode]} {
            puts "INFO: Validating sub mode $sub_mode..."
            if { [config_find $dft_modeConfig "SCAN_TEST/${sub_mode}"] != ""} {
                puts "$sub_mode is valid sub_mode"
            } else {
                puts stderr "ERROR: sub_mode $sub_mode is invalid. Please follow $dft_modes_config_file for the list of sub_mode's allowed"
                exit 1
            }
        } else {
            puts stderr "WARNING: sub mode $sub_mode is not SCAN_TEST sub mode"
        }
    }
    # Please specify the test API specific programming here
}

package provide atpg_init_tasks $::ATE::atpg_init::version

# Local Variables:
# mode: Tcl
# tab-width: 4
# expand-tab
# c-basic-offset: 4
# tcl-indent-level: 4
# indent-tabs-mode: nil
# End:
# ex: shiftwidth=4 tabstop=4 expandta

0 comments :

Lyte Byte Tech News

Recommended

Company

Legal Stuff

FAQ's

Blogroll

Subscribe to Newsletter

We'll never share your Email address.
© 2015 Lyte Byte Tech News | Distributed By My Blogger Themes | Designed By Bloggertheme9