我有一个 TCL 脚本。此 tcl 脚本的输入是一个 .txt 文件(基本上是日志文件),输出是配置文件。表示此脚本正在将 .txt 文件转换为 .config 文件。
下面是 tcl 脚本:
set script "[file tail [info script]]"
array set arg $argv;
if { $argc != 4 } {
puts "The $script script requires two switches.";
puts "For example, tclsh $script -i st.log -o st.cfg";
puts "Please try again.";
exit 2;
}
foreach key [array names arg] {
set key [string range $key 1 end];
switch $key {
"i" {
set if $arg(-$key);
set x [catch {set ifid [open $if r]}];
}
"o" {
set of $arg(-$key);
set x [catch {set ofid [open $of w+]}];
}
}
}
while {[gets $ifid line] >= 0} {
#puts $line;
if [regexp {\/\/\s+MT_DEBG:\s+STEP\s+\#\s+:\s+(\d+)$} $line matched mtStep] {
set currentMtStep $mtStep;
puts $currentMtStep;
}
if [regexp {\/\/\s+MT_DEBG:\s+MKS\s+:\s+(\S+)$} $line matched mtMask] {
array set arrMtMask [list $mtStep $mtMask];
puts $mtMask;
puts $arrMtMask($mtStep);
}
if [regexp {\#\#\s+MKS.*MT_DEBG:\s+STEP\s+\#\s+:\s(\S+)$} $line matched mtMaskStep] {
set currentMtMask $arrMtMask($mtMaskStep);
}
if [regexp {\/\/\s+SCK_DEBG:\s+STEP\s+\#\s+:\s+(\d+)$} $line matched sckStep] {
if [info exist currentMtStep] {
set currentMtMask $arrMtMask($currentMtStep);
}
set currentSckStep $sckStep;
#puts $currentSckStep;
}
if [regexp {\/\/\s+SCK_DEBG:\s+LOAD_NOP\s+\(\s+(\d+)\s+\)} $line matched sckNOP] {
set currentSckNOP $sckNOP;
puts $ofid "RUNTEST $currentSckNOP";
}
if [regexp {\/\/\s+SCK_DEBG:\s+TDI\s+:\s+(\d+)'b(\S+)$} $line matched sckTDILength sckTDI] {
set currentSckTDILength $sckTDILength;
set currentSckTDI $sckTDI;
#puts "$currentSckTDILength $currentSckTDI";
}
if [regexp {\/\/\s+SCK_DEBG:\s+TDO\s+:\s+(\d+)'b(\S+)$} $line matched sckTDOLength sckTDO] {
set currentSckTDO $sckTDO;
set currentSckTDOLength $sckTDOLength;
#puts $currentSckTDO;
}
if [regexp {\/\/\s+SCK_DEBG:\s+LOAD_IR\s+\(\s+(\d+)\s+,\s+\S+\s+\)} $line matched sckIR] {
set currentSckIR $sckIR;
switch $currentSckTDI {
"1000" {set op 8; set jtagInstruction "ATPG_CLOCK_CFG";}
"1010" {set op a; set jtagInstruction "SCK_CORESEL";}
"110001" {set op 31; set jtagInstruction "MBIST_CFG";}
"110011" {set op 33; set jtagInstruction "MBIST_SIF_SHIFT";}
"110110" {set op 36; set jtagInstruction "PLL_CFG";}
"111110" {set op 3E; set jtagInstruction "MREPAIR_CMD";}
"1100001" {set op 61; set jtagInstruction "SERDES_CFG";}
"1100010" {set op 62; set jtagInstruction "SERDES_ITCP";}
"1100011" {set op 63; set jtagInstruction "MBIST_STATUS";}
"1100101" {set op 65; set jtagInstruction "TCK_CTRL";}
"1100110" {set op 66; set jtagInstruction "TEST_CFG";}
"1100111" {set op 67; set jtagInstruction "TS0_CFG";}
"1101000" {set op 68; set jtagInstruction "TS0_DATA";}
"1101001" {set op 69; set jtagInstruction "TS1_CFG";}
"1101010" {set op 6A; set jtagInstruction "TS1_DATA";}
"1101011" {set op 6B; set jtagInstruction "USERCODE";}
"1101100" {set op 6C; set jtagInstruction "VS0_CFG";}
"1101101" {set op 6D; set jtagInstruction "VS0_DATA";}
"1101110" {set op 6E; set jtagInstruction "VS1_CFG";}
"1101111" {set op 6F; set jtagInstruction "VS1_DATA";}
default {set jtagInstruction "UNKNOWN_INSTRUCTION"}
}
puts $ofid "INSTR $jtagInstruction $currentSckTDILength'b$currentSckTDI";
}
if [regexp {\/\/\s+SCK_DEBG:\s+LOAD_DR\s+\(\s+(\d+)\s+,\s+\S+\s+\)} $line matched sckDR] {
set currentSckDR $sckDR;
if { $currentSckTDOLength !=$currentSckTDILength } {
puts "Error: TDOLength != TDILength";
exit 2;
}
puts $ofid "SHIFTDR $currentSckTDILength \{"
if ![info exist currentMtMask] {
puts $ofid " SCK_STEP_$currentSckStep $currentSckTDILength $currentSckTDILength'b$currentSckTDI ( $currentSckTDOLength'b$currentSckTDO )";
} else {
################################################
set lengthMtMask [string length $currentMtMask];
if {$currentSckTDOLength != $lengthMtMask} {
puts "Error: MtMask != TDOLength";
exit 2;
}
set lengthTDI [string length $currentSckTDI];
set lengthTDO [string length $currentSckTDO];
if {$lengthTDI != $currentSckTDILength} {
puts "STEP $currentSckStep lengthTDI = $lengthTDI"
}
if {$lengthTDO != $currentSckTDOLength} {
puts "STEP $currentSckStep lengthTDO = $lengthTDO"
}
set patch "";
for {set i $currentSckTDILength} {$i > $lengthTDI} {incr i -1} {
set patch ${patch}0;
}
set currentSckTDI ${patch}${currentSckTDI};
set patch "";
for {set i $currentSckTDOLength} {$i > $lengthTDO} {incr i -1} {
set patch ${patch}x;
}
set currentSckTDO ${patch}${currentSckTDO};
set maskedTDO "";
for {set i [expr $lengthMtMask -1]} {$i >= 0} {incr i -1} {
set index [expr $lengthMtMask -$i -1];
set maskBit [string range $currentMtMask $index $index];
if {$maskBit == 1} {
set oBit [string range $currentSckTDO $index $index];
} else {
set oBit x;
}
set maskedTDO ${maskedTDO}${oBit};
}
puts $ofid " SCK_STEP_$currentSckStep $currentSckTDILength $currentSckTDILength'b$currentSckTDI ( $currentSckTDOLength'b$maskedTDO )";
################################################
}
puts $ofid "\}"
}
}
使用以下命令运行上面的脚本:
tclsh tcl_script -i txt_file -o config_file
输入文件(.txt)的部分内容
tool(64): 10-s01: (c) Copyright 1999-2016
tool> source nls
tool> set gui on
on
// SCK_INFO: READ_OPERATION
// SCK_DEBG: STEP # : 0
// SCK_DEBG: LOAD_NOP ( 4001 ) ;
// SCK_DEBG: STEP # : 2
// SCK_DEBG: TDI : 4'b0000
// SCK_DEBG: TDO : 4'b1110
// SCK_DEBG: LOAD_IR(4 , 4'b1010) ;
// SCK_DEBG: STEP # : 10
// SCK_DEBG: TDI : 4'b0000
// SCK_DEBG: TDO : 4'b1110
// SCK_DEBG: LOAD_DR(16 , 4'b1010000010101111) ;
// SCK_DEBG: MKS : 16'b1111010010110101
// SCK_DEBG: STEP # : 12
// SCK_DEBG: TDI : 4'b0100
// SCK_DEBG: TDO : 4'b1001
// SCK_DEBG: LOAD_DR(4 , 4'b1100) ;
// SCK_DEBG: STEP # : 14
// SCK_DEBG: TDI : 4'b0001
// SCK_DEBG: TDO : 4'b1100
// SCK_DEBG: LOAD_DR(4 , 4'b1011) ;
// SCK_DEBG: MKS : 4'b1110
输出文件(config)的部分内容,由脚本生成:
This is output file..
Run 20
"some text"
SCK_STEP_2 4 4'b1010 ( 4'b1110)
SCK_STEP_10 4 4'b1100 (4'b1001)
SCK_STEP_12 4 4'b1100 (4'b1001)
SCK_STEP_14 4'b1011 (4'b1100)
现在的问题是,如果特定步骤不存在“SCK_DEBG:MKS”,则此 tcl 脚本会将 txt 文件转换为配置文件而不会出现任何错误。
理想情况下,如果存在“SCK_DEBG: MKS”,则脚本应在最后一个括号中使用 MKS 位。例如:SCK_STEP_14 具有 MKS,因此正确的输出应该是:
SCK_STEP_14 4'b1011 (4'b1110)
但不是该脚本在输出文件中给出以下输出。
SCK_STEP_14 4'b1011 (4'b1100)
在这里,如果 MKS 存在于该特定步骤,则在最后一个括号脚本中应使用 MKS 中的位,否则应选择 TDO 位。但在所有情况下,脚本都只选择 TDO 位。
...我尝试了以下方法来使该脚本正常工作,但仍然无法正常工作:在脚本中,MT_DEBG 存在 3 个“if”语句,在我的 txt 文件中不存在 MT_DEBG,而不是存在 SCK_DEBG所以我已经更换了它,但它不起作用。然后像 MKS.*MT_DEBG 或 MKS.*SKC_DEBG 这样的语法在我的 txt 中根本不存在,所以我已经评论了这个“if”语句并重新运行了脚本。但它仍然无法正常工作。
我从我的上级那里得到了这个 txt 到配置文件的转换脚本。但是他现在不在,所以这就是为什么在这里写。
由于我处于TCL的初始阶段,请有人帮助我。