Xilinx TCL shell 在哪里发出结果?
Where does the Xilinx TCL shell emit the results?
我正在尝试围绕 Xilinx ISE TCL shell xtclsh.exe
开发一个基于 Python 的包装器。如果可行,我将添加对其他 shell 的支持,例如 PlanAhead 或 Vivado ...
那么大局是什么?我有一个 VHDL 源文件列表,它们构成了一个 IP 核。我想打开一个现有的 ISE 项目,搜索丢失的 VHDL 文件并在必要时添加它们。由于 IP 核具有重叠的文件依赖性,因此一个项目可能已经包含一些文件,所以我只查找丢失的文件。
使用管道的示例用户 Python 3.x 和 subprocess
。 xtclsh.exe
启动,命令逐行发送到 shell。监控输出的结果。为了简化示例,我将 STDERR 重定向到 STDOUT。将虚拟输出 POC_BOUNDARY 插入到命令流中,以指示已完成的命令。
可以通过设置示例 ISE 项目来测试附加的示例代码,其中包含一些 VHDL 源文件。
我的问题是显示了 INFO、WARNING 和 ERROR 消息,但脚本无法读取 TCL 命令的结果。
在 xtclsh.exe 中手动执行 search *.vhdl -type file
结果:
% search *.vhdl -type file
D:/git/PoC/src/common/config.vhdl
D:/git/PoC/src/common/utils.vhdl
D:/git/PoC/src/common/vectors.vhdl
执行脚本结果:
....
press ENTER for the next step
sending 'search *.vhdl -type file'
stdoutLine='POC_BOUNDARY
'
output consumed until boundary string
....
问题:
- xtclsh 写入哪里?
- 如何读取 TCL 命令的结果?
顺便说一句:提示符号 %
对我的脚本也不可见。
Python 重现该行为的代码:
import subprocess
class XilinxTCLShellProcess(object):
# executable = "sortnet_BitonicSort_tb.exe"
executable = r"C:\Xilinx.7\ISE_DS\ISE\bin\nt64\xtclsh.exe"
boundarString = "POC_BOUNDARY"
boundarCommand = bytearray("puts {0}\n".format(boundarString), "ascii")
def create(self, arguments):
sysargs = []
sysargs.append(self.executable)
self.proc = subprocess.Popen(sysargs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
self.sendBoundardCommand()
while(True):
stdoutLine = self.proc.stdout.readline().decode()
if (self.boundarString in stdoutLine):
break
print("found boundary string")
def terminate(self):
self.proc.terminate()
def sendBoundardCommand(self):
self.proc.stdin.write(self.boundarCommand)
self.proc.stdin.flush()
def sendCommand(self, line):
command = bytearray("{0}\n".format(line), "ascii")
self.proc.stdin.write(command)
self.sendBoundardCommand()
def sendLine(self, line):
self.sendCommand(line)
while(True):
stdoutLine = self.proc.stdout.readline().decode()
print("stdoutLine='{0}'".format(stdoutLine))
if (stdoutLine == ""):
print("reached EOF in stdout")
break
elif ("vhdl" in stdoutLine):
print("found a file name")
elif (self.boundarString in stdoutLine):
print("output consumed until boundary string")
break
def main():
print("creating 'XilinxTCLShellProcess' instance")
xtcl = XilinxTCLShellProcess()
print("launching process")
arguments = []
xtcl.create(arguments)
i = 1
while True:
print("press ENTER for the next step")
from msvcrt import getch
from time import sleep
sleep(0.1) # 0.1 seconds
key = ord(getch())
if key == 27: # ESC
print("aborting")
print("sending 'exit'")
xtcl.sendLine("exit")
break
elif key == 13: # ENTER
if (i == 1):
#print("sending 'project new test.xise'")
#xtcl.sendLine("project new test.xise")
print("sending 'project open PoCTest.xise'")
xtcl.sendLine("project open PoCTest.xise")
i += 1
elif (i == 2):
print("sending 'lib_vhdl get PoC files'")
xtcl.sendLine("lib_vhdl get PoC files")
i += 1
elif (i == 3):
print("sending 'search *.vhdl -type file'")
xtcl.sendLine("search *.vhdl -type file")
i += 1
elif (i == 4):
print("sending 'xfile add ../../src/common/strings.vhdl -lib_vhdl PoC -view ALL'")
xtcl.sendLine("xfile add ../../src/common/strings.vhdl -lib_vhdl PoC -view ALL")
i += 16
elif (i == 20):
print("sending 'project close'")
xtcl.sendLine("project close")
i += 1
elif (i == 21):
print("sending 'exit'")
xtcl.sendCommand("exit")
break
print("exit main()")
xtcl.terminate()
print("the end!")
# entry point
if __name__ == "__main__":
main()
我在 Linux 上尝试了几种方法,但 xtclsh 似乎检测标准输入是连接到管道还是(伪)终端。如果它连接到管道,xtclsh 会抑制通常写入标准输出(提示输出、命令结果)的任何输出。我认为,这同样适用于 Windows.
即使输入连接到管道,在标准错误上打印的消息(无论是信息性的、警告的还是错误的)仍然存在。
要在标准输出上打印消息,您可以使用 puts
tcl 命令,该命令始终在标准输出上打印。也就是说,puts [command]
获取 command
的标准输出并始终将其打印到标准输出。
示例:假设我们有一个包含两个文件的 test.xise
项目:test.vhd
中的顶级实体和 [=18] 中的测试平台=].而且,我们要使用此 tcl 脚本 (commands.tcl
) 列出项目中的所有文件:
puts [project open test]
puts "-----------------------------------------------------------------------"
puts [search *.vhd]
exit
然后调用 xtclsh < commands.tcl 2> error.log
在标准输出上打印:
test
-----------------------------------------------------------------------
/home/zabel/tmp/test/test.vhd
/home/zabel/tmp/test/test_tb.vhd
这是在标准错误上打印的(到文件 error.log
中):
INFO:HDLCompiler:1061 - Parsing VHDL file "/home/zabel/tmp/test/test.vhd" into
library work
INFO:ProjectMgmt - Parsing design hierarchy completed successfully.
我正在尝试围绕 Xilinx ISE TCL shell xtclsh.exe
开发一个基于 Python 的包装器。如果可行,我将添加对其他 shell 的支持,例如 PlanAhead 或 Vivado ...
那么大局是什么?我有一个 VHDL 源文件列表,它们构成了一个 IP 核。我想打开一个现有的 ISE 项目,搜索丢失的 VHDL 文件并在必要时添加它们。由于 IP 核具有重叠的文件依赖性,因此一个项目可能已经包含一些文件,所以我只查找丢失的文件。
使用管道的示例用户 Python 3.x 和 subprocess
。 xtclsh.exe
启动,命令逐行发送到 shell。监控输出的结果。为了简化示例,我将 STDERR 重定向到 STDOUT。将虚拟输出 POC_BOUNDARY 插入到命令流中,以指示已完成的命令。
可以通过设置示例 ISE 项目来测试附加的示例代码,其中包含一些 VHDL 源文件。
我的问题是显示了 INFO、WARNING 和 ERROR 消息,但脚本无法读取 TCL 命令的结果。
在 xtclsh.exe 中手动执行 search *.vhdl -type file
结果:
% search *.vhdl -type file
D:/git/PoC/src/common/config.vhdl
D:/git/PoC/src/common/utils.vhdl
D:/git/PoC/src/common/vectors.vhdl
执行脚本结果:
....
press ENTER for the next step
sending 'search *.vhdl -type file'
stdoutLine='POC_BOUNDARY
'
output consumed until boundary string
....
问题:
- xtclsh 写入哪里?
- 如何读取 TCL 命令的结果?
顺便说一句:提示符号 %
对我的脚本也不可见。
Python 重现该行为的代码:
import subprocess
class XilinxTCLShellProcess(object):
# executable = "sortnet_BitonicSort_tb.exe"
executable = r"C:\Xilinx.7\ISE_DS\ISE\bin\nt64\xtclsh.exe"
boundarString = "POC_BOUNDARY"
boundarCommand = bytearray("puts {0}\n".format(boundarString), "ascii")
def create(self, arguments):
sysargs = []
sysargs.append(self.executable)
self.proc = subprocess.Popen(sysargs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
self.sendBoundardCommand()
while(True):
stdoutLine = self.proc.stdout.readline().decode()
if (self.boundarString in stdoutLine):
break
print("found boundary string")
def terminate(self):
self.proc.terminate()
def sendBoundardCommand(self):
self.proc.stdin.write(self.boundarCommand)
self.proc.stdin.flush()
def sendCommand(self, line):
command = bytearray("{0}\n".format(line), "ascii")
self.proc.stdin.write(command)
self.sendBoundardCommand()
def sendLine(self, line):
self.sendCommand(line)
while(True):
stdoutLine = self.proc.stdout.readline().decode()
print("stdoutLine='{0}'".format(stdoutLine))
if (stdoutLine == ""):
print("reached EOF in stdout")
break
elif ("vhdl" in stdoutLine):
print("found a file name")
elif (self.boundarString in stdoutLine):
print("output consumed until boundary string")
break
def main():
print("creating 'XilinxTCLShellProcess' instance")
xtcl = XilinxTCLShellProcess()
print("launching process")
arguments = []
xtcl.create(arguments)
i = 1
while True:
print("press ENTER for the next step")
from msvcrt import getch
from time import sleep
sleep(0.1) # 0.1 seconds
key = ord(getch())
if key == 27: # ESC
print("aborting")
print("sending 'exit'")
xtcl.sendLine("exit")
break
elif key == 13: # ENTER
if (i == 1):
#print("sending 'project new test.xise'")
#xtcl.sendLine("project new test.xise")
print("sending 'project open PoCTest.xise'")
xtcl.sendLine("project open PoCTest.xise")
i += 1
elif (i == 2):
print("sending 'lib_vhdl get PoC files'")
xtcl.sendLine("lib_vhdl get PoC files")
i += 1
elif (i == 3):
print("sending 'search *.vhdl -type file'")
xtcl.sendLine("search *.vhdl -type file")
i += 1
elif (i == 4):
print("sending 'xfile add ../../src/common/strings.vhdl -lib_vhdl PoC -view ALL'")
xtcl.sendLine("xfile add ../../src/common/strings.vhdl -lib_vhdl PoC -view ALL")
i += 16
elif (i == 20):
print("sending 'project close'")
xtcl.sendLine("project close")
i += 1
elif (i == 21):
print("sending 'exit'")
xtcl.sendCommand("exit")
break
print("exit main()")
xtcl.terminate()
print("the end!")
# entry point
if __name__ == "__main__":
main()
我在 Linux 上尝试了几种方法,但 xtclsh 似乎检测标准输入是连接到管道还是(伪)终端。如果它连接到管道,xtclsh 会抑制通常写入标准输出(提示输出、命令结果)的任何输出。我认为,这同样适用于 Windows.
即使输入连接到管道,在标准错误上打印的消息(无论是信息性的、警告的还是错误的)仍然存在。
要在标准输出上打印消息,您可以使用 puts
tcl 命令,该命令始终在标准输出上打印。也就是说,puts [command]
获取 command
的标准输出并始终将其打印到标准输出。
示例:假设我们有一个包含两个文件的 test.xise
项目:test.vhd
中的顶级实体和 [=18] 中的测试平台=].而且,我们要使用此 tcl 脚本 (commands.tcl
) 列出项目中的所有文件:
puts [project open test]
puts "-----------------------------------------------------------------------"
puts [search *.vhd]
exit
然后调用 xtclsh < commands.tcl 2> error.log
在标准输出上打印:
test
-----------------------------------------------------------------------
/home/zabel/tmp/test/test.vhd
/home/zabel/tmp/test/test_tb.vhd
这是在标准错误上打印的(到文件 error.log
中):
INFO:HDLCompiler:1061 - Parsing VHDL file "/home/zabel/tmp/test/test.vhd" into
library work
INFO:ProjectMgmt - Parsing design hierarchy completed successfully.