PAT_B_结构-02. 有理数加法(15)

本文详细介绍了如何通过输入两个有理数的格式,并使用结构体来存储这些数值,进而实现计算它们的和并进行简化输出的过程。通过求分母的最大公约数,最终得到最简分数形式的和。此方法不仅适用于数学运算,也体现了结构体在编程中的实用性和效率。

输入格式:

 

 输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整形范围内的正整数。

 

 输出格式:

 

 在一行中按照“a/b”的格式输出两个有理数的和。注意必须是该有理数的最简分数形式,若分母为1,则只输出分子。

 

 输入样例1

 1/3 1/6

 输出样例1

 1/2

 输入样例2

 4/3 2/3

 输出样例2

 2

主要考量了结构体的基本使用,主要编程思想先输入,然后求分母公约数,最后化简输出。除此之外,还可以直接相乘,然后化简输出。提供一种AC的Sources Codes


#include <iostream>

using namespace std;

struct Data
{
    int fengzi;
    int fengmu;
};

int gongyueshu(int a,int b)
{
    int i;
    int result=1;
    
    for (i=1; i<=a&&i<=b; i++) {
        
        if (a%i==0&&b%i==0) {
            
            result*=i;
            a/=i;
            b/=i;
            i=1;
            
        }
    }
    
    result=result*a*b;
    
    return result;
}

int main(int argc, const char * argv[])
{

    Data a,b;
    int m,n;
    
    scanf("%d/%d %d/%d",&a.fengzi,&a.fengmu,&b.fengzi,&b.fengmu);
    
    m=gongyueshu(a.fengmu,b.fengmu);
    
    n=a.fengzi*m/a.fengmu+b.fengzi*m/b.fengmu;
    
    for (int i=1; i<=m&&i<=n; i++) {
        
        if (m%i==0&&n%i==0) {
            m/=i;
            n/=i;
            i=1;
        }
        
    }
    
    if (m==1) {
        printf("%d\n",n);
    }
    else
    {
        printf("%d/%d\n",n,m);
    }
    return 0;
}


请为我详细分析下述两个脚本: fate_mapping=report/fate_port_mapping.CHX005.ddr5.list pat_type=CPU_uncore_PAT scan_cell_rpt=report/scan_cell/202310191513/core.CPU_SPATPG.INT.INTEST.LPWR_OFF.A0_CPU_CORE_TO_0530.VERIFY.202310191513.tessent_scan_cell.all.rpt scan_chain_rpt=report/scan_cell/202310191513/core.CPU_SPATPG.INT.INTEST.LPWR_OFF.A0_CPU_CORE_TO_0530.VERIFY.202310191513.tessent_scan_chain.all.cp.rpt # int_log_maping_tool=./tools/int_fail_log_2_scan_cell.pipe.fate.pl int_log_maping_tool=./tools/int_fail_log_2_scan_cell.pipe.fate.20231213.pl # shift_cyc=181479 # load_unload_cyc=25 # capture_cyc=32 # shift_dummy_cyc=4 # input pipe 5 # output pipe 5 # # # load 25(17 edtupdate=1 + 8 edt_update=0 ) # shift 238753 :tpf record shift cycles is 5 less than the actually shift cycles, sell below # unload 4 # capture 32 # # pattern cycle: # 0~24: load # 25~238782: shift cycle 238758 # 238783~238786: unload # 238787~238811: load # 238812~477569: shift cycle 238758 # 477570~477573: unload # 477574~477605: capture # 477606~477630: load # 477631~716388: shift cycle 238758 # 716389~716392: unload end shift_cyc=238758 load_unload_cyc=25 capture_cyc=32 shift_dummy_cyc=4 #fail_log=./tmp/all.#131.#A0_SP5.25C.v900.v900.f2000.f2000.cpu_core_sp_int_163_com2int_2600M.ddr5.2023-10-23_14-09-41.log log_array=( \ ./all#107.#A0_TT336.25C.v850.v850.f2000.f2000.cpu_uncore_sp_int_org_tie_4_2000.ddr5.2024-03-20_10-57-27.log ) for fail_log in ${log_array[@]}; do perl $int_log_maping_tool \ -pat_type $pat_type \ -scan_cell $scan_cell_rpt \ -scan_chain $scan_chain_rpt \ -pad_map $fate_mapping \ -shift_cyc $shift_cyc \ -shift_dummy_cyc $shift_dummy_cyc \ -load_unload_cyc $load_unload_cyc \ -capture_cyc $capture_cyc \ -pipe_stage 5 \ -pat0_shift yes \ -fail_log $fail_log \ -out_log $fail_log.fail \ -excel_log $fail_log.excel done #! /usr/bin/perl -w use warnings; use strict; #============================================================================= # FileName: int_fail_log_2_scan_cell.pl # Desc: use to locate the error scan cell ========= my $argv; my $pat_type; my $scan_cell; my $scan_chain; my $pad_map; my $fail_log; my $shift_cyc; my $shift_dummy_cyc; my $load_unload_cyc; my $capture_cyc; my $pat0_shift; my $out_log; my $pipe_stage; my $excel_log; my $excel_wafer; my $excel_corner; my $excel_die_id; my $excel_pattern; my $excel_freq; my $excel_volt; my $excel_temp; my $excel_fail_reg; my $excel_fail_pat_num; my $excel_fail_scanout; my $excel_fail_chain_offset; my $excel_fail_pat_exp; my $excel_fail_pat_got; my $excel_fail_pat_body; our %padmap; while ($argv = shift @ARGV) { if($argv eq '-pat_type') { $pat_type = shift @ARGV; }elsif($argv eq '-scan_cell') { $scan_cell = shift @ARGV; }elsif($argv eq '-scan_chain') { $scan_chain = shift @ARGV; }elsif($argv eq '-pad_map') { $pad_map = shift @ARGV; }elsif($argv eq '-fail_log') { $fail_log = shift @ARGV; }elsif($argv eq '-shift_cyc') { $shift_cyc = shift @ARGV; }elsif($argv eq '-load_unload_cyc') { $load_unload_cyc = shift @ARGV; }elsif($argv eq '-capture_cyc') { $capture_cyc = shift @ARGV; }elsif($argv eq '-pipe_stage') { $pipe_stage = shift @ARGV; }elsif($argv eq '-shift_dummy_cyc') { $shift_dummy_cyc = shift @ARGV; }elsif($argv eq '-pat0_shift') { $pat0_shift = shift @ARGV; }elsif($argv eq '-out_log') { $out_log = shift @ARGV; }elsif($argv eq '-excel_log') { $excel_log = shift @ARGV; }elsif($argv eq '-excel_wafer') { $excel_wafer = shift @ARGV; }elsif($argv eq '-excel_corner') { $excel_corner = shift @ARGV; }elsif($argv eq '-excel_die_id') { $excel_die_id = shift @ARGV; }elsif($argv eq '-excel_pattern') { $excel_pattern = shift @ARGV; }elsif($argv eq '-excel_freq') { $excel_freq = shift @ARGV; }elsif($argv eq '-excel_volt') { $excel_volt = shift @ARGV; }elsif($argv eq '-excel_temp') { $excel_temp = shift @ARGV; }else{ print "ERROR: parameter error !!!\n"; } } my $line; my $idx; my $fmc; my $fpga; my $fpc_dm4; my $fpc_dm5; my $fpc_ddr5; my $hdr; my $zdi_pad; my $ccd_pad; my $pad; my $atpg_pad; my %PAD_IDX; my %FT2CP_PAD; my %FT2ATPG_PAD; open(MAPPING, "$pad_map")||die "open mapping file failed!($pad_map)\n"; while($line = <MAPPING>){ #1_idx #2_FMC #3_FPGA #4_FPC(DM3/4) #5_FPC(DM5) #6_FPC(DDR5) #7_HDR #8_ZDI_PAD #9_CCD_PAD #10_CPU_uncore_PAT #11_CPU_uncore_ATPG #12_CPU_core_PAT #13_CPU_core_ATPG #14_CPS_PAT #15_CPS_PAT_ATPG #16_GFX_PAT #17_GFX_PAT_ATPG #18_JTAG_PAT #19_CCD_JTAG if($line =~ /^(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/) { $idx = $1; $fmc = $2; $fpga = $3; $fpc_dm4 = $4; $fpc_dm5 = $5; $fpc_ddr5 = $6; $hdr = $7; $zdi_pad = $8; $ccd_pad = $9; $pad = "NA"; $atpg_pad = "NA"; if ($pat_type eq "CPU_uncore_PAT") { $pad = $10; $atpg_pad = $11; } if ($pat_type eq "CPU_core_PAT") { $pad = $12; $atpg_pad = $13; } if ($pat_type eq "CPS_PAT") { $pad = $14; $atpg_pad = $15; $ccd_pad = "NA"; } if ($pat_type eq "GFX_PAT") { $pad = $16; $atpg_pad = $17; $ccd_pad = "NA"; } if ($pat_type eq "JTAG_PAT") { $pad = $18; $atpg_pad = $19; $ccd_pad = "NA"; } if(exists $PAD_IDX{$idx}) { print STDOUT "Error, $idx is exists in $pat_type\n"; } else { $PAD_IDX{$idx} = $pad; } $pad =~ s/^I_//g; $pad =~ s/^O_//g; $FT2CP_PAD{$pad} = $ccd_pad; $FT2ATPG_PAD{$pad} = $atpg_pad; } } close (MAPPING); my $chain_name; my $chain_output_pad; my %CHAIN_PAD; open(CHAIN,"$scan_chain") || die "Can't open the file: $scan_chain"; while($line = <CHAIN>) { chomp($line); if($line=~/chain = (\S+).*output = '\/(\S+)'/) { $chain_name=$1; $chain_output_pad=$2; $CHAIN_PAD{$chain_output_pad}=$chain_name; } } close (CHAIN); #open($input,"gzip -dc $scan_cell | ") || die("Could not open $scan_cell"); open(SCANCELL,"$scan_cell") || die("Could not open $scan_cell"); my %file_handles; my $chain_cell_rpt; while ($line = <SCANCELL>) { chomp($line); if($line=~/(\d+)\s+(\S+)\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(\S+)/) { $chain_name=$2; if (exists $file_handles{$chain_name}) { print {$file_handles{$chain_name}} "$line\n"; } else{ open($chain_cell_rpt,">$scan_cell.$chain_name.txt") || die("Could not write $!"); print {$chain_cell_rpt} "$line\n"; $file_handles{$chain_name} = $chain_cell_rpt; } } } close (SCANCELL); foreach my $chain_cell_rpt (values %file_handles) { close $chain_cell_rpt; } my @PAT_NAME; my @PAT_CYCLE; my $pat_name; my $pat_cycle; open(FAIL_LOG, "$fail_log")||die "open fail log file failed!($fail_log)\n"; $idx=0; $PAT_CYCLE[$idx]=0; while($line = <FAIL_LOG>){ if ($line =~ /^(\S+) has (\d+) cycle/) { $pat_name = $1; $pat_cycle = $2; push @PAT_NAME, $pat_name; $pat_cycle = $pat_cycle + $PAT_CYCLE[$idx]; push @PAT_CYCLE, $pat_cycle; $idx++; } } close (FAIL_LOG); my $fail_cycle; my $fail_pad; my $fail_chain; my $exp; my $got; my $org_exp; my $org_got; my $fail_pattern_num; my $fail_scan_cell_num; my $append_cycle=0; my $fail_cycle_file; my $cell_inv_flag; my $cell_qpin_flag; my $cell_name; my $cell_full_name; my $tmp_line; my $match_flag; my $gen_fail_log=0; my $fail_num=0; open(FAIL_LOG, "$fail_log")||die "open fail log file failed!($fail_log)\n"; open(OUT_LOG, ">$out_log")||die "open fail log file failed!($fail_log)\n"; open(EXCEL_LOG, ">>$excel_log")||die "open fail log file failed!($fail_log)\n"; while($line = <FAIL_LOG>){ if ($line =~ /^\s+(\d+)\s+(\S+)\s+exp=(\S)\s+got=(\S)/) { chomp($line); $fail_cycle = $1; $fail_pad = $2; $exp=$3; $got=$4; $org_exp=$3; $org_got=$4; $idx = 0; $append_cycle=0; $fail_cycle_file=0; $fail_num++; if ($fail_num > 500) { print OUT_LOG "$line\n"; next; } while ($fail_cycle > $PAT_CYCLE[$idx]) { $idx++; } $pat_name=$PAT_NAME[$idx-1]; $fail_cycle_file = $fail_cycle - $PAT_CYCLE[$idx-1]; if ($pat0_shift eq "yes") { $fail_pattern_num = int (($fail_cycle_file + 1) / ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc)) - 1 - 1; $fail_scan_cell_num = ($fail_cycle_file + 1) % ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc) - 1 - $load_unload_cyc - $pipe_stage + $capture_cyc; } else { $fail_pattern_num = int (($fail_cycle_file + 1) / ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc)) - 1; $fail_scan_cell_num = ($fail_cycle_file + 1) % ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc) - 1 - $load_unload_cyc - $pipe_stage; } $atpg_pad=$FT2ATPG_PAD{$fail_pad}; if (exists $FT2CP_PAD{$fail_pad}) { if ($FT2CP_PAD{$fail_pad} eq "NA") { $chain_output_pad = $fail_pad; } else { $chain_output_pad = $FT2CP_PAD{$fail_pad}; } } else { print STDOUT "Error, can not mapping FT pad $fail_pad to CP pad, please check!\n"; } $chain_name=$CHAIN_PAD{$chain_output_pad}; open(CELL,"< $scan_cell.$chain_name.txt") || die "Can't open the file: $scan_cell.$chain_name.txt"; $match_flag=0; $cell_full_name="NA"; while($tmp_line = <CELL>){ # 29636 zdi_1 MASTER (FF-LE) TFFF 42097406 /CCD_CPTEST29 F HDN6BULT08_FSDPQ_DY2_1 /zdi_ccd/zdil_x32/zdi_dll_zdi/r_inst_scan_obs_rxreq24/\sq_reg[4] U1 (SI,Q) if ($tmp_line =~ /^\s*$fail_scan_cell_num\s+$chain_name\s+MASTER\s+\S+\s+(\S)(\S)(\S)(\S)\s+\d+\s+\S+\s+\S\s+\S+\s+(.*)\s+\S+\s+\(\S+,\S+\)/) { $cell_inv_flag=$2; $cell_qpin_flag=$4; $cell_name = $5; $cell_name =~ s/\s+$//g; if ($cell_qpin_flag eq "T") { $cell_full_name = $cell_name . "/QN"; } else { $cell_full_name = $cell_name . "/Q"; } if ($cell_inv_flag eq "T") { my $tmp = $exp; $exp = $got; $got = $exp; } if ($got eq "H") { $got="1'b1"; } else { $got="1'b0"; } $match_flag=1; $gen_fail_log=1; last; } } close (CELL); if ($match_flag == 0) { print STDOUT "Error, can not find $chain_name $fail_scan_cell_num fail cell name, please check!\n"; } my $tmp_str="$cell_full_name"." = "."$got"; printf OUT_LOG "%-30s\t; # %-150s\t # %-5s\t%-12s\t%-8s\t%s\t%s\t; #atpg_pad=%-12s\tchain=%-25s\tpat_name=%s\n", "$line", "$tmp_str", "$fail_pattern_num", "$chain_output_pad", "$fail_scan_cell_num", "$org_exp", "$org_got", "$atpg_pad", "$chain_name", "$pat_name"; printf STDOUT "%-30s\t; # %-150s\t # %-5s\t%-12s\t%-8s\t%s\t%s\t; #atpg_pad=%-12s\tchain=%-25s\tpat_name=%s\n", "$line", "$tmp_str", "$fail_pattern_num", "$chain_output_pad", "$fail_scan_cell_num", "$org_exp", "$org_got", "$atpg_pad", "$chain_name", "$pat_name"; $excel_fail_reg=$cell_name; $excel_fail_pat_num=$fail_pattern_num; $excel_fail_scanout=$chain_output_pad; $excel_fail_chain_offset=$fail_scan_cell_num; $excel_fail_pat_exp=$org_exp; $excel_fail_pat_got=$org_got; $excel_fail_pat_body=$pat_name; printf EXCEL_LOG "$excel_wafer\t$excel_corner\t$excel_die_id\t$excel_pattern\t$excel_volt\t$excel_freq\t$excel_temp\t$excel_fail_reg\t$excel_fail_pat_num\t$excel_fail_scanout\t$excel_fail_chain_offset\t$excel_fail_pat_exp\t$excel_fail_pat_got\t$excel_fail_pat_body\n"; } else { print OUT_LOG "$line"; } } close (FAIL_LOG); close (OUT_LOG); if ($gen_fail_log == 0) { unlink "$out_log"; printf EXCEL_LOG "$excel_wafer\t$excel_corner\t$excel_die_id\t$excel_pattern\t$excel_volt\t$excel_freq\t$excel_temp\tall_pattern_pass\n"; } #mv cps_only_sp_com_sync_production_202309201538_p1.all.#131.#A1_TT_276.25C.v900.v900.f2000.f2000.cps_only_sp_com_sync_production_202309201538_p1.ddr5.2023-09-26_17-40-17.log cps_only_sp_com_sync_production_202309201538_p1.202309201538_p1.ddr5.2023-09-26_17-40-17.log #mv cps_only_sp_com_sync_production_202309201538_p2.all.#131.#A1_TT_276.25C.v900.v900.f2000.f2000.cps_only_sp_com_sync_production_202309201538_p2.ddr5.2023-09-26_17-43-21.log cps_only_sp_com_sync_production_202309201538_p2.202309201538_p2.ddr5.2023-09-26_17-43-21.log #mv cps_only_sp_com_sync_production_202309201538_p3.all.#131.#A1_TT_276.25C.v900.v900.f2000.f2000.cps_only_sp_com_sync_production_202309201538_p3.ddr5.2023-09-26_17-46-26.log cps_only_sp_com_sync_production_202309201538_p3.202309201538_p3.ddr5.2023-09-26_17-46-26.log #mv cps_only_sp_com_sync_production_202309201538_p4.all.#131.#A1_TT_276.25C.v900.v900.f2000.f2000.cps_only_sp_com_sync_production_202309201538_p4.ddr5.2023-09-26_17-48-32.log cps_only_sp_com_sync_production_202309201538_p4.202309201538_p4.ddr5.2023-09-26_17-48-32.log #mv cps_only_sp_com_sync_production_202309201538_p5.all.#131.#A1_TT_276.25C.v900.v900.f2000.f2000.cps_only_sp_com_sync_production_202309201538_p5.ddr5.2023-09-26_17-51-36.log cps_only_sp_com_sync_production_202309201538_p5.202309201538_p5.ddr5.2023-09-26_17-51-36.log #mv cps_only_sp_com_sync_production_202309201538_p6.all.#131.#A1_TT_276.25C.v900.v900.f2000.f2000.cps_only_sp_com_sync_production_202309201538_p6.ddr5.2023-09-26_17-54-42.log cps_only_sp_com_sync_production_202309201538_p6.202309201538_p6.ddr5.2023-09-26_17-54-42.log #mv cps_only_sp_com_sync_production_202309201538_p7.all.#131.#A1_TT_276.25C.v900.v900.f2000.f2000.cps_only_sp_com_sync_production_202309201538_p7.ddr5.2023-09-26_17-57-48.log cps_only_sp_com_sync_production_202309201538_p7.202309201538_p7.ddr5.2023-09-26_17-57-48.log #mv cps_only_sp_com_sync_production_202309201538_p8.all.#131.#A1_TT_276.25C.v900.v900.f2000.f2000.cps_only_sp_com_sync_production_202309201538_p8.ddr5.2023-09-26_18-00-54.log cps_only_sp_com_sync_production_202309201538_p8.202309201538_p8.ddr5.2023-09-26_18-00-54.log #log_array=( #cps_only_sp_com_sync_production_202309201538_p1.202309201538_p1.ddr5.2023-09-26_17-40-17.log #cps_only_sp_com_sync_production_202309201538_p2.202309201538_p2.ddr5.2023-09-26_17-43-21.log #cps_only_sp_com_sync_production_202309201538_p3.202309201538_p3.ddr5.2023-09-26_17-46-26.log #cps_only_sp_com_sync_production_202309201538_p4.202309201538_p4.ddr5.2023-09-26_17-48-32.log #cps_only_sp_com_sync_production_202309201538_p5.202309201538_p5.ddr5.2023-09-26_17-51-36.log #cps_only_sp_com_sync_production_202309201538_p6.202309201538_p6.ddr5.2023-09-26_17-54-42.log #cps_only_sp_com_sync_production_202309201538_p7.202309201538_p7.ddr5.2023-09-26_17-57-48.log #cps_only_sp_com_sync_production_202309201538_p8.202309201538_p8.ddr5.2023-09-26_18-00-54.log #) # #for log in ${log_array[@]}; do # echo $log # perl int_fail_log_2_scan_cell.fate.pl \ # -pat_type CPS_PAT \ # -scan_cell /d/chx005/chx005_fate_2.5_20230807.git/report/scan_cell/202309191707/CNE001.CPS_SPATPG.INT.INTEST.LPWR_OFF.A0_CPS_only_TO_0420.COVERAGE_NOR.202309191707.tessent_scan_cell.rpt \ # -scan_chain /d/chx005/chx005_fate_2.5_20230807.git/report/scan_cell/202309191707/CNE001.CPS_SPATPG.INT.INTEST.LPWR_OFF.A0_CPS_only_TO_0420.COVERAGE_NOR.202309191707.tessent_scan_chain.rpt \ # -pad_map /d/chx005/chx005_fate_2.5_20230807.git/report/fate_port_mapping.CHX005.ddr5.list \ # -shift_cyc 180443 \ # -shift_dummy_cyc 4 \ # -load_unload_cyc 25 \ # -capture_cyc 32 \ # -fail_log $log \ # -out_log $log.fail #done
最新发布
09-23
<think> Hmm, the user has shared two complex scripts related to semiconductor testing - one appears to be a shell script for test automation, and the other is a Perl script for scan cell failure analysis. First, I notice both scripts are highly specialized for ATPG (Automatic Test Pattern Generation) and scan chain debugging in VLSI testing. The shell script sets up environment variables and loops through failure logs, while the Perl script does the heavy lifting of mapping test failures to specific flip-flops in the design. The user seems to be a DFT (Design-for-Test) engineer working on CPU/uncore testing, given the "CPU_uncore_PAT" references. They probably need help understanding how these diagnostic tools work together. The detailed timing annotations in the shell script suggest they're debugging shift/capture timing issues. Key technical points I should explain: - The shell script's shift_cyc=238758 indicates massive scan chains common in modern CPUs - The Perl script's pad mapping logic shows sophisticated test-to-design pin correlation - The scan cell number calculation accounts for pipeline stages (pipe_stage=5) which is crucial for cycle-accurate fault isolation - The "pat0_shift" handling suggests special treatment for initialization patterns The commented-out sections reveal this is likely an evolving debug workflow. The user might be troubleshooting false positives given the inversion flag handling ($cell_inv_flag) in the Perl code. For the questions section, I should focus on: 1. Critical parameters that affect failure mapping accuracy 2. Methodology for handling different pattern types (core/uncore) 3. Error scenarios the script doesn't handle well 4. Performance considerations with large scan chains 5. Integration with other DFT tools The depth of the scripts suggests the user is highly technical, so my explanation should maintain precision while making the control flow clear. The multiple file interactions (pad mapping, chain reports, cell databases) warrant special attention in the analysis. </think> 以下是对两个脚本的详细技术分析: ### **Shell 脚本分析(测试自动化脚本)** ```bash # 关键变量定义 fate_mapping=... # 引脚映射表文件 pat_type=CPU_uncore_PAT # 测试模式类型 scan_cell_rpt=... # 扫描单元报告 scan_chain_rpt=... # 扫描链报告 int_log_maping_tool=... # 核心Perl解析工具 # 时序参数配置(经调整后) shift_cyc=238758 # 有效位移周期数 shift_dummy_cyc=4 # 虚拟位移周期 load_unload_cyc=25 # 加载/卸载周期 capture_cyc=32 # 捕获周期 pipe_stage=5 # 流水线级数 # 日志处理循环 log_array=(...) # 定义故障日志数组 for fail_log in ${log_array[@]}; do # 调用Perl工具进行故障映射 perl $int_log_maping_tool \ -pat_type $pat_type \ ... # 传递所有参数 -out_log $fail_log.fail \ # 输出详细故障报告 -excel_log $fail_log.excel # 输出Excel格式报告 done ``` **核心功能**: 批量处理测试故障日志,通过Perl工具将ATE测试失败数据映射到具体扫描单元(Scan Cell),生成两个报告: 1. 带详细定位信息的文本报告(`*.fail`) 2. 结构化Excel报告(`*.excel`) --- ### **Perl 脚本分析(`int_fail_log_2_scan_cell.pl`)** ```perl # 核心处理流程 1. 解析命令行参数(-pat_type, -scan_cell等) 2. 加载引脚映射表(%FT2CP_PAD, %FT2ATPG_PAD) - 根据pat_type选择对应列(CPU_uncore_PAT等) 3. 扫描链报告解析(%CHAIN_PAD) - 建立输出引脚(Pad)与链名(Chain)的映射 4. 预处理扫描单元报告 - 按扫描链分割文件(生成$scan_cell.$chain_name.txt) 5. 解析故障日志: - 提取测试模式(PAT_NAME)及累积周期(PAT_CYCLE) 6. 故障定位算法: if ($line =~ /(\d+)\s+(\S+)\s+exp=(\S)\s+got=(\S)/) { # 计算失效扫描单元位置: $fail_scan_cell_num = ($fail_cycle_file + 1) % (...) - $load_unload_cyc - $pipe_stage; # 映射物理位置: $atpg_pad = $FT2ATPG_PAD{$fail_pad}; $chain_name = $CHAIN_PAD{$chain_output_pad}; # 查找扫描单元文件: open(CELL, "$scan_cell.$chain_name.txt"); while(<CELL>){...} # 匹配$fail_scan_cell_num行 } 7. 输出结果: - 文本报告:包含原始数据+定位信息 - Excel报告:结构化数据(晶圆/温度/失效寄存器等) ``` **关键技术点**: - **时序计算**:根据位移/捕获周期参数,将ATE失效周期反向推算至扫描链位置 - **层级映射**:ATE引脚(Pad)→ 扫描链(Chain)→ 扫描单元(Cell) - **极性处理**:根据单元属性($cell_inv_flag)反转期望值 - **错误处理**:超过500条故障跳过(避免过大日志) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值