VIO即虚拟输入输出单元,可以实时地监控和驱动FPGA内部的逻辑信号,本文将演示具体的调试过程。
很多时候我们需要在调程序的时候输入具体的数值,以找到最佳的参数,以往我们只能通过串口或者按键的方式将数据传输给系统,但是这就对硬件有一定的要求(必须有对应的硬件接口),而且用这种方式我们就需要额外编写对应串口的FPGA代码。 这里xilinx给了我们另一种思路,即VIO虚拟输入输出核,通过VIO,我们只需要在VIVADO 上通过JTAG数据线就可以完成上述的要求。
与ILA有不同,VIO的数据是实时的(可以显示当前的数值)而ILA只能抓取一个时间段的波形,并且VIO可以支持参数的输入,
本文在 vivado2018.3版本上 演示, 其他版本请自行研究
(备注 此章节内容适用于 Smart ZYNQ SP和SL 版的板子,如果是Smart ZYNQ 标准版请看对应板子目录)
以下是具体的实现过程
VIO模块的添加
本文用一个计数器的简单工程来演示下 VIO功能模块的使用。
创建工程:(本文仅对VIO的部分进行介绍,对工程创建过程不熟悉的可以看工程一)
Smart ZYNQ(SP&SL 版) 工程一 用ZYNQ的PL资源点亮一个LED(完整图文)
这里用一个很简单的程序进行演示
`timescale 1ns / 1ps module VIO_TEST( input CLK, output LED0, output LED1 ); wire [1:0]LED_STATE;//时钟计数器 assign LED0=LED_STATE[0]; assign LED1=LED_STATE[1]; endmodule
非常简单,LED0,LED1的状态分别对应LED_STATE[0],LED_STATE[1]
我们接下来用VIO来输入LED_STATE的值。相当于用VIO来控制LED灯的亮与灭
调用VIO模块
在vivado软件中,打开IP核目录(IP Catalog),搜索VIO,如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-30.png)
这里 input选择2个探针,来显示2个LED的状态
output选择1个探针,来给系统输入LED_STATE的值
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-31.png)
2个输入都设置成1位
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-32.png)
输出的数据选择2位位宽,默认值设置成0
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-33.png)
之后选择ok生成VIO资源
在我们之前写的代码里加入VIO模块的例化代码(例化就是生成一个实体)
vio_0 u_vio ( .clk(CLK), // input wire clk .probe_in0(LED0), // input wire [0 : 0] probe_in0 .probe_in1(LED1), // input wire [0 : 0] probe_in1 .probe_out0(LED_STATE) // output wire [2 : 0] probe_out0 );
完整代码如下:
`timescale 1ns / 1ps module VIO_TEST( input CLK, output LED0, output LED1 ); wire [1:0]LED_STATE;//时钟计数器 assign LED0=LED_STATE[0]; assign LED1=LED_STATE[1]; vio_0 u_vio ( .clk(CLK), // input wire clk .probe_in0(LED0), // input wire [0 : 0] probe_in0 .probe_in1(LED1), // input wire [0 : 0] probe_in1 .probe_out0(LED_STATE) // output wire [2 : 0] probe_out0 ); endmodule
增加约束文件
set_property IOSTANDARD LVCMOS33 [get_ports LED0] set_property IOSTANDARD LVCMOS33 [get_ports LED1] set_property IOSTANDARD LVCMOS33 [get_ports CLK] set_property PACKAGE_PIN P20 [get_ports LED0] set_property PACKAGE_PIN P21 [get_ports LED1] set_property PACKAGE_PIN M19 [get_ports CLK]
之后点选run 和 generate bitstream进行综合 布线,和生成二进制文件
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-81.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-80.png)
2. 下载代码
2.1 接通好JTAG 和主板,并且将主板供上电源, 点选 open target 来连接目标板子
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-82.png)
2.2接通成功后会出现下面这个图
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-83.png)
2.3 右键选择芯片型号,并点program device进行FPGA的代码下载(这些操作都和正常FPGA工程一致)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-84.png)
点选Program 下载
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-34.png)
VIO调试
执行完之前的下载操作后,系统如果运行没问题会自动弹出一个VIO调试窗口, 如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-35.png)
默认调试窗口是空的没有任何参数可以调,这里点选加号,然后选中出现的所有信号,点选OK
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-36.png)
这时候我们就得到了我们所要信号的调试窗口了
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-37.png)
因为LED_STATE我们需要按位去调整,所以我们这里将LED_STATE的十六进制调整成二进制
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-38.png)
准备工作做好了接下来我们来实际调试,首先没有任何动作情况下两个LED灯应该默认是熄灭的,之后我们点选LED_STATE信号的 VALUE,将信号改成10
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-39.png)
修改之后 点选OK后,我们会发现其中一个LED(LED2)灯被点亮
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-99.png)
此时观察我们的VIO窗口可以看到 下面两个input窗口其中一个变成1了,并且右边有个向上箭头(代表这个信号有变化,并且是由低变高)
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-40.png)
同样我们把LED_STATE由10改成01(可以看到下面input窗口中也同样读到信号变成1和0了,并且一个带向上箭头,一个带向下箭头)
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-42.png)
同样的LED灯和之前反向了(LED1被点亮)
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-100.png)
VIO还有其他玩法,我们还可以将我们之前观察的信号换算成LED指示灯
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-44.png)
将低电平设置成灰色,高电平设置成红色
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-45.png)
同样另一个输入信号也作相同处理,得到以下的调试结果(红色和灰色,跟板子上的LED灯的亮灭对应了,让调试更为直观)
![](http://www.hellofpga.com/wp-content/uploads/2022/11/image-46.png)
当然还有很多玩法(包括输出可以设置成按键形式的)这边只作简单演示,大家自行尝试
通过以上试验,我们可以知道VIO可以对实际运行的程序中的指定的信号进行实时的写入和读出,这大大缩短了我们在做工程时的调试时间。
以下是完整工程(仅供学习参考):