FPGA自动保存编译版本
1、前言
在FPGA开发过程中,会随着设计的调试与更新,软件版本会不断地迭代,当迭代次数较多时,很容易忘记版本,影响版本记录,手动在程序中添加编译时间版本比较麻烦,也有可能在更改过程中会忘记,如果使用自动的获取当前时间的方式,每次在编译时即将当前时间写入设计中,即方便又不会出现忘记的情况。
这里使用两种方式来实现自动获取编译时间戳的方式,一种是网上所说的通过TCL脚本的方式自动获取时间写入设计的方式,另一种是使用XILINX原语的方式。
2、Tcl脚本方式
作为FPGA设计工具都是支持Tcl脚本的,Tcl脚本方式的原理就是通过Tcl脚本的方式获取当前系统时间,然后建立一个宏定义头文件,再将获取的系统时间写入头文件中然后加入工程中;如下是转载网上的一种方式(在后文测试中会使用比较):
Vivado 自动日期版本号
3、USR_ACCESS原语方式
3.1 USR_ACCESS原理
根据UG470手册描述,7系列USR_ACCESS2为内置原语,是一个配置寄存器,用户可以自定义值,或者在生成bit流时自动加载时间戳,具体的使用方式通过XAPP497手册有详细描述,如下:
![](https://img-blog.csdnimg.cn/6b167723c7b74b43b5413555400b74f8.png)
参数1:-g USR_ACCESS: NONE
![](https://img-blog.csdnimg.cn/34b4be6096b448bbbeef25f63564e423.png)
参数2:-g USR_ACCESS: xxxxxxxx
![](https://img-blog.csdnimg.cn/34b4be6096b448bbbeef25f63564e423.png)
参数3:-g USR_ACCESS: TIMESTAMP
![](https://img-blog.csdnimg.cn/590a00ead5c045ed9598f67796defc41.png)
![](https://img-blog.csdnimg.cn/c40979156e1441b1987f65215488aa3e.png)
ddddd:5bit用来表示日;
MMMM:4bit用来表示月;
yyyyyy:6bit用来表示年,因为只有6bit,最大为63,因此最大到2063;
hhhhh:5bit用来表示小时;
mmmmmm:6bit用来表示分钟;
ssssss:6bit用来表示秒;
3.2 USR_ACCESS使用
在7系列中USR_ACCESS原语为USR_ACCESS2,在不同系列的器件中,原语名称不同,可以通过打开原语查找,选择对应的原语即可,其电路图如下,只有3个端口:
使用方式也很简单,在原语种找到USR_ACCESSE2,直接例化,DATA即为配置的值,另外两个端口均未使用。
![](https://img-blog.csdnimg.cn/13bdd3798a1346519ccfb152be5bd982.png)
根据手册描述,实际上这个原语是读取FPGA内部配置寄存器(如下图)的值来确认当前编译时间。
![](https://img-blog.csdnimg.cn/99ac27da7e784263912a3f6056461abe.png)
4、测试比较
4.1 TCL方式测试
由于需要将TCL获取的时间写入到逻辑中,因此需要在综合前就获取完成,在设置中设置TCL脚本目录,然后开始编译工程,可以看到综合开始后,会生成一个参数文件(测试中为version.vh),其内为综合时通过TCL获取的时间(BCD码),将version.vh文件添加到工程中。
![](https://img-blog.csdnimg.cn/fb5ab739c9bb43a6ad47d6b954d0c880.png)
编译工程后将其值(这里使用宏定义的方式)通过ILA抓取可以看到与生成的参数一致。
![](https://img-blog.csdnimg.cn/2c2aaada64ac41739a3072eee9f72ced.png)
![](https://img-blog.csdnimg.cn/8c45174968b24c24b37e2d34bba86a39.png)
4.2 USR_ACCESS方式测试
将USR_ACCESS2例化,根据XAPP497手册分别设置3种参数,通过ILA观察实际值;
![](https://img-blog.csdnimg.cn/f4c4443ed6484d3bbb21c097850c378d.png)
首先设置第一种,-g USR_ACCESS: NONE,通过ILA观察可以看到其值为0;
![](https://img-blog.csdnimg.cn/dd59125dd9e64bfdabfad283c3bc5acc.png)
![](https://img-blog.csdnimg.cn/d187981c3b4344e4a15773199068434f.png)
设置第二种,-g USR_ACCESS: 0x12345678,设置16进制数,通过ILA观察可以看到其值为12345678;
![](https://img-blog.csdnimg.cn/47d554180b1b4a418cf117026d6563b0.png)
![](https://img-blog.csdnimg.cn/5afe1b3c749a4628bcfe596866004df8.png)
设置第三种,-g USR_ACCESS: TIMESTAMP,通过ILA观察可以看到其值为54AF2725,通过换算表示的为时间2023年9月10日18:28:37;
![](https://img-blog.csdnimg.cn/6b7287a800f74d09ab7c262981ac2bf7.png)
![](https://img-blog.csdnimg.cn/8d0def749db548a7aae0aa2b94e2c3e6.png)
![](https://img-blog.csdnimg.cn/8ddc32801cbb499dbe2b29b09187445a.png)
测试中同时将TCL脚本方式和USR_ACCESS方式使用,通过ILA观察,日期都为20230910,时间有差别,TCL方式时间为18:25:54,USR_ACCESS方式时间为18:28:37,再查看bit文件时间为:18:28:47,可以看到USR_ACCESS更接近文件生成时间,如果设计更复杂,那么差别会更大。
5、总结
TCL方式获取时间戳需要写入逻辑中,因此需要在设计综合前获取时间,与生成bit时间差异随着设计的复杂度增加而增加,USR_ACCESS方式通过配置寄存器的方式写入到bit流中,在bit开始生成时获取时间,同样与生成bit时间差异随着设计的复杂度增加而增加,相对与综合和实现的过程,生成bit的时间相对较短,与生成bit时间相对接近。
两种方式均可作为同一工程的版本变化自动获取,时间的差异不影响版本的记录。
6、扩展
6.1 扩展1
USR_ACCESS方式在设置-g 参数时,需要打开电路图然后在User Access中设置相应参数,然后保存,保存过程其实会将界面通过TCL方式写入到XDC约束文件中,然后工具通过读取XDC约束实现对应的参数设置,因此为了方便可以直接通过更改XDC约束的方式实现。
![](https://img-blog.csdnimg.cn/e1521fba32784c26ae60d71abbe7728a.png)
6.2 扩展2
USR_ACCESS 根据UG470手册描述,USR_ACCESS实际为AXSS配置寄存器,通过JTAG Hardware Device Properties 可以观察对应的值与ILA抓取的值相同。
![](https://img-blog.csdnimg.cn/c636a4e3e66f48588a696838eb00851e.png)
6.3 扩展3
由于手动换算不方便,可以将获取到的时间戳通过AXI_JTAG 方式通过JTAG读取对应的值,再使用TCL脚本封装一个对应的换算函数,直接使用对应的扩展命令一键读取,可以看到读取的时间为2023/9/10 18:28:37,同样TCL脚本获取的时间戳也可以通过同样的方式读取。
![](https://img-blog.csdnimg.cn/2e98f6df5c71497496a73ea6591fb177.png)
![](https://img-blog.csdnimg.cn/dfc540db8e1049cea7747b19fce6e207.png)
参考文档:UG470:7 Series FPGAs Configuration
XAPP497:Bitstream Identification with USR_ACCESS