原创 【博客大赛】TCL脚本完成二进制文件存取

2014-3-24 14:57 5482 19 20 分类: FPGA/CPLD 文集: TCL/TK

TCL脚本完成二进制文件存取

王敏志

概述

 

         项目电路板测试,特别是需要从FPGA收集一些测试数据的时候可以通过Altera提供的virtual JTAG接口来完成。开发调试平台需要使用TCL脚本来设计,收集到的数据可以存储到一个文件里面,对于TCL脚本来说,任何数据都被认为是字符,所以存储成文本格式是很方便的,但是由于项目测试另一个平台是利用LabView或者C++来分析数据,而LabView或者C++程序设计者希望数据存储在二进制文件中。笔者折腾用TCL读二进制文件以及TCL将数据存储成二进制格式文件,好长时间才搞定,特记录于此已备时间一长遗忘,因为不常用,备后续参考。

 

TCL读取二进制文件

 

         一般读取文本文件很简单,代码如下所示:

         set chan [open "file_t" r]

    set myfile1 [open "file_t1" w]

    while {[gets $chan line] >=0} {

         puts $myfile1 $line

    }

 

上述代码第一句是先打开一个文件“file_t”并开始读这个文件,这是一个文本文件。第二句是打开一个文件“file_t1”并开始写,如果这个文件不存在,那么就创建这个文件。最后的while循环是将第一个文件里的内容全部写入到第二个文件中。相当于复制黏贴。

 

文件file_t只是一个文本文件,文件里的内容如图1所示,笔者在使用Virtual JTAG处理数据的时候一般都是按照图1所示的格式存储,也即每一行只存储一个数据,所以在使用上述代码while循环里就可以直接逐一对数据读出并进行相关处理。

 

4628.jpg

1:文本文件中的内容

那么如果存在一个二进制格式的数据文件,应该如何将数据读出来呢?首先我们来看二进制数据文件的存放格式,如图2所示。

 

4628.jpg

2:二进制格式文件内容

1和图2存放的内容都是一样的,注意二进制格式存放的时候需要定义每一个数据位宽,这里给每个数据定义为32-bit,所以我们看图2的第一个数据是0,第二个数据是0x100000,即1048576,后面数据依次类推。所以如果要将图2所示的数据读出来,那么在打开这个文件以后首先要对其进行配置,因为TCL默认认为打开的文件是字符格式,具体代码实现如下所示:

set chan [open "lg5mm.dat" r]

fconfigure $chan -translation binary

while {1} {

       set data_read [read $chan 4]

;##一次读4个字节,即32bit,在循环体中,该命令似乎可以自动连续往后读。

 

       binary scan $data_read "H*" tmp0;##将这4个字节转换成16进制数据

       set m_val [get_m $tmp0]

       set x_val [get_x $tmp0]

       set y_val [get_y $tmp0]

       pain_cross_star $m_val $x_val $y_val

       incr cnt

       if {$cnt > 10000} {

           close $chan

           break

}

 

第一句和上面一样,先是打开一个文件,并开始读。第二句是给刚刚打开的文件配置“二进制”属性。读的时候使用“read”命令,由于我们定义一个数据的位宽是32-bit,所以每次需要读四个字节。Binary scan是将读出来的32-bit数据转换成16进制数据,否则默认读出来的数据认为是字符格式。

 

TCL存储数据成二进制格式

 

         上一节讲述了如何从二进制格式文件中读取数据并进行处理,这一节介绍一下如何将数据存储成类似图2所示的二进制格式文件。

 

         首先我们还是来看看默认TCL脚本是如何存储数据到文件的,由于数据默认认为是字符格式,所以存储后的数据文件就是图1所示的格式。具体代码如第一节所示。即file_t1file_t中的内容都是如图1所示那样。那么如何才能将file_t中的文件存储成图2所示那样呢?具体代码如下所示。

    set chan [open "file_t" r]

set my_binfile [open "bin_file.dat" w]

fconfigure $my_binfile -translation binary

set a 0

    while {[gets $chan line] >=0} {

         set a [binary format "I1" $line]

         puts -nonewline $my_binfile $a

    }

 

         第一句同样是打开一个要读取的文件,即file_t,第二句是打开一个文件,即bin_file.dat,如果文件不存在那么创建这个文件,打开属性是“w”。第三句是配置刚刚创建的文件配置成“二进制”属性。第四句定一个临时变量a,并赋值为0While循环里从file_t逐行读出数据(千万记住每一行只有一个数据),将每行读出的数据首先转换成二进制格式,转换后将二进制格式数据写入二进制文件,注意此时带上写入参数“nonewline”。需要特别注意的是数据格式转换的时候使用了“I1”参数,“I”表示将一个或多个整数转换成32-bit,且字节顺序是Big-endian模式,如果“i”则是Little-endian模式。如果不是32-bit,那么可以查此命令找到相关参数(c/C指定8-bits/S指定16-bit等等)

 

分析及结论

 

二进制文件处理在项目测试阶段非常有用,在分析数据的时候如果数据量庞大,如果按照字符模式,且每一行只存放一个数据那么数据文件的容量将非常之大,如果采用二进制格式,可以大大减少文件存放容量,同时可以统一各个平台之间的数据格式,所谓一举多得啊。

 

 

文章评论1条评论)

登录后参与讨论

用户1651405 2014-3-17 16:39

...

用户91462 2009-12-5 13:45

谢谢,下载看看~~~

用户1364249 2008-5-3 11:52

欢迎来到EDN
相关推荐阅读
coyoo 2024-12-03 12:20
比较器检测模拟脉冲说明(四)
概述 说明(三)探讨的是比较器一般带有滞回(Hysteresis)功能,为了解决输入信号转换速率不够的问题。前文还提到,即便使能滞回(Hysteresis)功能,还是无法解决SiPM读出测试系统需要解...
coyoo 2024-11-16 13:54
不同ADC采样同一前端模拟信号时转换用时差异分析
概述 同一组前端模拟信号接入由不同型号ADC组成的模数转换电路时,采样后在FPGA中发现采样用时差异较大。本文主要分析这个时间差异形成的原因,并记录该差异产生对系统造成的影响。系统数字化简介 项目前端...
coyoo 2024-11-10 13:04
ALTERA Cyclone 10器件的使用-7:FPGA片内RAM资源利用率思考
概述 项目使用的FPGA目标器件为Cyclone 10 GX系列规模最大一颗料,由于功能升级增加了功能模块更多,发现器件片内RAM不够使用了。为了探索片内RAM使用的利用率问题,从代码RTL级与编译软...
coyoo 2024-11-10 12:30
转知乎:幽灵般的人体成像技术-PET
幽灵般的人体成像技术——PET - 知乎...
coyoo 2024-11-09 10:26
AD9633默认情况下调试记录(二)
概述 所谓默认情况,即如器件手册中图2所标示那样。对应AD9633的调试,除了涉及到ADC自身,还需要兼顾前端驱动器,系统中AD9633驱动器使用了差分运算放大器,这里不在赘述,笔者已有相关文章论述。...
coyoo 2024-11-07 10:40
AD9633默认情况下调试记录(一)
AD9633在旁路SPI接口时如何在FPGA逻辑中确认字边界概述 AD9633与FPGA之间的LVDS接口初调试,ADC可以通过SPI接口对其内部寄存器进行各项配置。在SPI接口未调通之前,对LVDS...
我要评论
1
19
关闭 站长推荐上一条 /2 下一条