Решение найдено при более пристальном изучении исходников опорного проекта,
а именно файла es_pc_host.tcl
Функция es_host_gen_csv_viv как раз занимается пост-обработкой данных и расчетом матрицы BER для диаграммы
Там при использовании DFE эквалайзера (lpm_mode = 0) рассчитывают BER для двух случаев UT_SIGN + и - , после чего поэлементно суммируют для всей матрицы
Код
# ################################################################################
#####################
# Function: es_host_gen_csv_viv
# Description: Given arrays containing eye scan data, generates csv file that can be opened in Vivado
#
# Parameters:
# csv_file: name of output csv file
# lpm_mode: equalizer mode
# vert_step: vertical scan step size
# horz_arr_a: reference to array populated with horizontal offset values
# vert_arr_a: reference to array populated with vertical offset values
# utsign_arr_a: reference to array populated with ut-sign values
# sample_count_arr_a: reference to array populated with sample count values
# error_count_arr_a: reference to array populated with error count values
# prescale_arr_a: reference to array populated with prescale values
# data width: parallel data width
# rate: rate mode (e.g. full-rate, half-rate, etc)
#
# Returns: none
# ################################################################################
#####################
proc es_host_gen_csv_viv {csv_file lpm_mode vert_step horz_step horz_arr_a vert_arr_a utsign_arr_a sample_count_arr_a error_count_arr_a prescale_arr_a data_width rate start_time} {
upvar $horz_arr_a horz_arr
upvar $prescale_arr_a prescale_arr
upvar $vert_arr_a vert_arr
upvar $utsign_arr_a utsign_arr
upvar $sample_count_arr_a sample_count_arr
upvar $error_count_arr_a error_count_arr
set f_csv [open $csv_file w]
# Generate CSV Header iBERTplotter
puts $f_csv "SW Version,2013.2.0"
puts $f_csv "GT Type,7 Series GTX"
puts $f_csv "Date and Time Started, $start_time"
puts $f_csv "Date and Time Ended, [clock format [clock seconds] -format {%b. %d %Y %I:%M:%S %p}]"
puts $f_csv "Scan Name,$csv_file"
puts $f_csv "Settings,"
#puts $f_csv "Open Area,3072"
puts $f_csv "Open Area,N/A"
puts $f_csv "Dwell,BER"
puts $f_csv "Dwell BER,1e-$prescale_arr(0,0,0)"
puts $f_csv "Dwell Time,0"
puts $f_csv "Horizontal Increment,$vert_step"
puts $f_csv "Horizontal Range,-0.500 UI to 0.500 UI"
puts $f_csv "Vertical Increment,$vert_step"
puts $f_csv "Vertical Range,100%"
puts $f_csv "Scan Start"
set first_line [lsort -integer [array names horz_arr]]
#puts $first_line
puts -nonewline $f_csv "2d statistical,"
puts $f_csv [join $first_line ","]
set ber 0
set iter 0
foreach curr_vert [lsort -decreasing -integer [array names vert_arr]] {
set ber_list $curr_vert
foreach curr_horz [lsort -integer [array names horz_arr]] {
if {$lpm_mode == 1} {
# In LPM mode, only process data with ut-sign of 0
if {[info exists error_count_arr($curr_horz,$curr_vert,0)] == 1} {
set curr_err0 $error_count_arr($curr_horz,$curr_vert,0)
set curr_samp0 $sample_count_arr($curr_horz,$curr_vert,0)
set curr_prescale0 $prescale_arr($curr_horz,$curr_vert,0)
# Get total samples by multiplying sample count with data width and 2^(prescale + 1)
set curr_tot_samp0 [expr wide($curr_samp0) * ($data_width << (1+$curr_prescale0) )]
set ber [format "%.2E" [expr double($curr_err0)/double($curr_tot_samp0)]]
# To limit BER floor, assume 1 as minimum number of errors.
if {$ber == 0} {
set ber [format "%.2E" [expr 1/double($curr_tot_samp0)]]
}
lappend ber_list $ber
} else {
puts $f_csv "Error: X:$curr_horz, Y:$curr_vert, UT:0 data point does not exist!"
}
} else {
#
# In DFE mode, average BER for ut-sign 0 and 1
if {[info exists error_count_arr($curr_horz,$curr_vert,0)] == 1 && [info exists error_count_arr($curr_horz,$curr_vert,1)] == 1} {
#puts "horz = $curr_horz vert = $curr_vert"
set curr_err0 $error_count_arr($curr_horz,$curr_vert,0)
set curr_samp0 $sample_count_arr($curr_horz,$curr_vert,0)
set curr_prescale0 $prescale_arr($curr_horz,$curr_vert,0)
# Get total samples by multiplying sample count with data width and 2^(prescale + 1)
set curr_tot_samp0 [expr wide($curr_samp0) * ($data_width << (1+$curr_prescale0)) ]
# Calculate BER for ut-sign of 0
set ber0 [expr double($curr_err0)/double($curr_tot_samp0) ]
set curr_err1 $error_count_arr($curr_horz,$curr_vert,1)
set curr_samp1 $sample_count_arr($curr_horz,$curr_vert,1)
set curr_prescale1 $prescale_arr($curr_horz,$curr_vert,1)
# Get total samples by multiplying sample count with data width and 2^(prescale + 1)
set curr_tot_samp1 [expr wide($curr_samp1) * ($data_width << (1+$curr_prescale1)) ]
# Calculate BER for ut-sign of 1
set ber1 [expr double($curr_err1)/double($curr_tot_samp1) ]
#puts "$curr_err0,$curr_samp0,$curr_prescale0,$curr_tot_samp0"
# Calculate final BER
set ber [format "%.2E" [expr ($ber0 + $ber1)/2]]
if {$ber == 0} {
set ber [format "%.2E" [expr 1/(double($curr_tot_samp0) + double($curr_tot_samp1))]]
}
lappend ber_list $ber
} else {
puts $f_csv "Error: X:$curr_horz, Y:$curr_vert data points do not exist or incomplete (not both UT signs present)!"
}
}
#puts $f_csv "$iter,NA,NA,NA,NA,$curr_vert,$curr_horz,NA,NA,NA,$ber"
set iter [expr $iter + 1]
}
puts $f_csv [join $ber_list ","]
#puts $ber_list
}
puts $f_csv "Scan End"
close $f_csv
}
Вот так вот поговорил с собой