本文算作Quartus II工程设计“自动化”开发的继续,最近在Altera的英文论坛看到有人提出一个问题,即如何自动抽取编译后的警告信息,由于他可能使用的是嵌入式操作系统,所以有人回复说如果使用Linux操作系统可以使用grep命令直接打印。具体命令格式是:
“quartus_sh -t build.tcl | grep Warning”
只是该指令在MS-DOS下的批处理下不能执行的,因为grep不是DOS命令也不是quartus_sh下的任何命令。
但是经过研究TCL关于字符串的操作命令,我们可以在自动化设计Quartus II的tcl脚本里添加一些字符串操作的代码,就可以从相关的编译报告里抽取出我们需要的信息。具体的代码,如下所示:
以下是代码片段: puts stdout "\nCompile End!!\n" set a "*Warning (*" set f [open "sfifo_test.map.rpt" r] while { [gets $f line ] >=0} { if {[string match $a $line]} { puts stdout $line ###puts stdout " Warnings!!!" } else { ##puts stdout "NO Warnings!!!" } } close $f |
上述代码添加到以前介绍的QII自动开发脚本里即可,这里贴出之前的脚本:
以下是代码片段:
load_package project
project_new sfifo_test -overwrite
set_global_assignment -name FAMILY "Cyclone II"
set_global_assignment -name DEVICE EP2C5Q208C8
set_global_assignment -name VHDL_FILE src/sfifo.vhd
set_global_assignment -name VHDL_FILE src/sfifo_test.vhd
set_location_assignment PIN_23 -to clk
load_package flow
execute_flow -compile
|
上述抽取警告的代码只是抽取了Map后的警告信息,如果还需要抽取Fit后的警告信息,那么依照上述代码添加即可,因为Map和Fit的编译信息分部存储在不同的文件里,所以需要你打开不同的文件,然后进行信息抽取。
下图是实际执行的效果,我们看到所有警告都打印到MS-DOS窗口了
附注:
Tcl脚本语言对于字符串匹配检查一共有三种常见的指令,这里我们使用了指令string match,请注意我贴出来的抽取警告信息代码,使用了C语言里常见的通配符“*”,似乎在TCL脚本里也能使用,如果在Warning前不使用该通配符,是无法打印警告信息的,说明脚本打开的文件在每一行应该还有一个我们平时看不到行起始符,就类似行尾的结束或者回车符一样。
下面给出各种不同字符匹配的指令详细说明。
通配符样式的模式匹配: string match
string match ?-nocase? pattern string
返回 1 —匹配, 0 —不匹配
eg:
string match a* “alpha”
=>1
string match a* “bat”
=>0
string match a* “Amazing”
=>0
string match –nocase a* “Amazing”
=>1
其实有两种正则表达式指令分别是:
使用正则表达式进行模式匹配:regexp 命令
regexp 命令,返回 0 或者 1 ,表示能否匹配。用法:
regexp pattern string ?var1 var2 var3…?
eg:
regexp {^[0-9]+$} 510
=>1
regexp {^[0-9]+$} -510
=>0
如果给出 ?var1 var2 var3…? 选项,则 var1 存入与整个正则表达式匹配的子字符串, var2 存入与捕获到的第一个子表达式相匹配的子字符串,一次类推。 eg:
regexp {([0-9]+)*([a-z]+)} “Walk 10 km” a b c
结果 a 的值为 ”10km” , b 的值为 10 , c 的值为 km
可以指定 -start 选项指定开始匹配的位置; -all 选项指定查找尽量多次的匹配; -nocase 选项指定不区分大小写。
-indices 选项指明额外的变量不应该用于存放匹配的子字符串的值,而是存放给出子字符串范围的起始索引。 eg :
regexp –indices {([0-9]+)*([a-z]+)} “Walk 10 km” a b c
结果 a 的值为 5 9 , b 的值为 5 6 , c 的值为 8 9.
-inline 选项让 regexp 把匹配变量返回为一个数据列表。
regexp –inline {([0-9]+)*([a-z]+)} “Walk 10 km”
=>{10 km} 10 km
使用正则表达式进行替换: regsub
regsub pattern string replace var
regsub there “ they live there lives ” their x
=>1
返回 1 —表示匹配, 0 —表示不匹配。
替换后的结果赋给参数 x ,因此 x 的值为 ”they live their lives ”
通常, regsub 只进行简单的替换,只替换最先出现的匹配项。然而,如果制定了 -all 选项,则替换所有:
regsub –all a “ababa” zz x
=>1
x 的值为 ”zzbzzbzz”
还可以指定 -start 、 -nocase 等选项。
coyoo 2013-10-11 12:37