浙江大学PAT_甲级_1071. Speech Patterns (25)

本文介绍了一种方法,用于从给定的文本中找到最常出现的单词,并提供了一个C++实现示例。

题目链接:点击打开链接

People often have a preference among synonyms of the same word. For example, some may prefer "the police", while others may prefer "the cops". Analyzing such patterns can help to narrow down a speaker's identity, which is useful when validating, for example, whether it's still the same person behind an online avatar.

Now given a paragraph of text sampled from someone's speech, can you find the person's most commonly used word?

Input Specification:

Each input file contains one test case. For each case, there is one line of text no more than 1048576 characters in length, terminated by a carriage return '\n'. The input contains at least one alphanumerical character, i.e., one character from the set [0-9 A-Z a-z].

Output Specification:

For each test case, print in one line the most commonly occurring word in the input text, followed by a space and the number of times it has occurred in the input. If there are more than one such words, print the lexicographically smallest one. The word should be printed in all lower case. Here a "word" is defined as a continuous sequence of alphanumerical characters separated by non-alphanumerical characters or the line beginning/end.

Note that words are case insensitive.

Sample Input:
Can1: "Can a can can a can?  It can!"
Sample Output:
can 5
我的C++代码:

#include<iostream>
#include<map>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
	string sentence;
	getline(cin, sentence);//输入一句话
	map<string, int> word_frequency;//单个单词出现的次数
	string word;//单词
	int i = 0;
	vector<string>vec_word;//存储单词的vector
	int max_frequency = 0;//最大出现次数
	string most_commonly_word;//出现次数最多的单词
	for (i = 0; i <sentence.length(); i++)//把一句话分解成单词组成的vector
	{
		word= "";
		while (isalnum(sentence[i]))//字符是数字或字母
		{
			if (isupper(sentence[i]))//大写转小写
				sentence[i] = tolower(sentence[i]);
			word += sentence[i];//得到单个的单词
			i++;
		}
		if (word!= "")
			vec_word.push_back(word);//把单词放进vector
	}
	for (int i = 0; i<vec_word.size(); i++)//把单词放进map
	{
		word_frequency [ vec_word[i] ]++;//记录每个单词的出现次数
		if (max_frequency <word_frequency [vec_word[i]] )//查找出现次数最多的单词
		{
			max_frequency = word_frequency [vec_word[i]];
			most_commonly_word = vec_word [i];
		}
	}
	cout << most_commonly_word << " " << max_frequency;//输出最常见的单词,和出现次数
	//system("pause");
	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条故障跳过(避免过大日志) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值