vivado的vio怎么使用_使用VIVADO中VIO模拟CPU接口进行在线寄存器读写调试(附源代码)...
发布日期:2021-06-24 01:28:22 浏览次数:3 分类:技术文章

本文共 7344 字,大约阅读时间需要 24 分钟。

debug,尤其是通信芯片的debug,可以有很多的方法。一个数据帧从进入到输出,可以在通路上的关键节点处设置监测如各种计数器等,可通过VIO(xilinx)定时上报实时状态。可以把VIO的各个信号线设置成类似于CPU总线的结构,监测计数器或者状态寄存器编成相应的地址,轮询读取回PC,在PC上通过TCL或者其它语言捕获数据。甚至可以将多个FPGA芯片都通过VIO进行调试,远程操作,效率也可以大大提升。另外,也可以设置专门的测试帧,在里面打各种不同大小的闭环,层层检测,发现问题。

这个VIO比chipscope有多大优势?

原理是一样的,不同的就是可以方便操控,可以写脚本抓取数据,还可以远程操控。VIO有输入也有输出,可以实时的配置寄存器。http://xilinx.eetrend.com/blog/11987,VivadoVIO (virtual input output)虚拟IO使用;

一、使用方法概述

一般情况下VIO用在设计中,可以提供模拟IO(我们主要用到模拟输出接口的功能)。如图1所示,红框内vio_0模块的两个输出probe_out[0:0]和probe_out[7:0]都可以接到其他模块直接使用,但是我们不需要用到板子上的实际接口(比如按键)。那么为什么我们在电脑上点一点鼠标,就可以将数据传递到FPGA内部呢?数据是通过什么传输到FPGA内部?答案是JTAG,电脑上的VIVADO软件可以通过JTAG软件与FPGA实现通信,这就是VIO模块在FPGA内部模拟IO引脚的原理。

图1 VIO IP核

1、VIO IP核的配置

下面用实际例子说明VIO IP核的配置过程:

在某设计中,需要使用按键出发,但是板子上没有设计按键,所以需要使用VIO模拟按键输入还有其他信号的输出。具体过程如下:

(1)例化VIO IP核 ;

(2)参数配置,配置输入探针数量和输出探针数量,如图2所示。分别可以设置0-256个。(一般输入探针用不到,最常用的是输出探针,在这里这两种探针都在图里体现了)。

图2 探针数量设置

(3)配置输出探针数据位宽及初始值

输出探针的数据位宽,及初始化数据(in hex)配置如图3所示

图3配置输出探针数据位宽及初始值

3、 VIO IP核的例化

VIO IP核代码实例化如下图所示。

ILA_wrapper ILA(

.clk    ( ),

.probe0 (),

.probe1 (),

.probe_out0 (),

.probe_out1 (),

.probe_in0 ()

);

4、 VIO IP核的使用

在hw_vio界面加入输出探针,并且配置对应的参数,此时FPGA内部的输出探针就会相应地发出信号,如图4所示。

图4 VIO IP核的使用

二、使用VIO实现大量寄存器读写

1、背景

在FPGA调试中,如果没有CPU接口及操作系统,但同时希望能够有一种类似于有CPU且可以实时在线读写FPGA内部状态寄存器或者配置FPGA内部寄存器的功能,就可以采用VIO来实现一个模拟的CPU接口,以下进行详细的介绍。

2、 原理框图及VIO字段定义

在Vivado 2016.2 软件环境,Zedboard硬件平台下,实现了一个示例工程,该工程的功能是,电脑运行Vivado软件,并通过Jtag与zedboard相连,利用VIO模拟CPU接口,实现寄存器读写功能(寄存器数量为32个,位数为32位),如图5所示。

图5原理框图

其参数配置说明如下:

如图6所示,vio_out_1的前32位是写地址,后32位是写数据;

图6 VIO写地址与写数据

如图7所示,vio_rd_addr代表读地址;

图7 VIO读地址

如图8所示,vio_rd_data代表读数据

图8 VIO读数据

3、操作示例

这里给出一个寄存器读写的例子,在这里不用tcl脚本,直接用图形界面,使用更加方便。

(1)给地址为1的寄存器写入数据32'hffff_ffff,即配置vio_out_1[63:0]为64'h0000_0001_FFFF_FFFF,如图9所示。

图9 VIO写入数据

(2) 将读地址设置为1,观察读数据变化,如图10所示。

图10 VIO读数据

观察图10可以发现,配置读地址vio_rd_addr为32'h0000_0001后,读数据vio_rd_data[31:0]由图9中的32'h0000_0000变为图10中的32'hffff_ffff,与写入的数据相同,寄存器读写操作成功。

三、源代码

1、VIO源码

// **************************************************************

// COPYRIGHT(c)2018, Xidian University

// All rights reserved.

//

// IP LIB INDEX :  VIO

// IP Name      :      VIO

// File name    :

// Module name  :

// Full name    :

//

// Author       : Liu-Huan

// Email        : assasin9997@163.com

// Data         :

// Version      : V 1.0

//

// Abstract     :

// Called by    :

//

// Modification history

// -----------------------------------------------------------------

// *****************************************************************

// *******************

// TIMESCALE

// *******************

`timescale 1ns/1ps

//*******************

//DEFINE MODULE PORT

//*******************

module  VIO_CPU_PORT   (

input   clk

) ;

//*********************

//INNER SIGNAL DECLARATION

//*********************

//REGS

reg [31:0]   mod_reg_0  = 32'b0 ;

reg [31:0]   mod_reg_1  = 32'b0 ;

reg [31:0]   mod_reg_2  = 32'b0 ;

reg [31:0]   mod_reg_3  = 32'b0 ;

reg [31:0]   mod_reg_4  = 32'b0 ;

reg [31:0]   mod_reg_5  = 32'b0 ;

reg [31:0]   mod_reg_6  = 32'b0 ;

reg [31:0]   mod_reg_7  = 32'b0 ;

reg [31:0]   mod_reg_8  = 32'b0 ;

reg [31:0]   mod_reg_9  = 32'b0 ;

reg [31:0]   mod_reg_10 = 32'b0 ;

reg [31:0]   mod_reg_11 = 32'b0 ;

reg [31:0]   mod_reg_12 = 32'b0 ;

reg [31:0]   mod_reg_13 = 32'b0 ;

reg [31:0]   mod_reg_14 = 32'b0 ;

reg [31:0]   mod_reg_15 = 32'b0 ;

reg [31:0]   mod_reg_16 = 32'b0 ;

reg [31:0]   mod_reg_17 = 32'b0 ;

reg [31:0]   mod_reg_18 = 32'b0 ;

reg [31:0]   mod_reg_19 = 32'b0 ;

reg [31:0]   mod_reg_20 = 32'b0 ;

reg [31:0]   mod_reg_21 = 32'b0 ;

reg [31:0]   mod_reg_22 = 32'b0 ;

reg [31:0]   mod_reg_23 = 32'b0 ;

reg [31:0]   mod_reg_24 = 32'b0 ;

reg [31:0]   mod_reg_25 = 32'b0 ;

reg [31:0]   mod_reg_26 = 32'b0 ;

reg [31:0]   mod_reg_27 = 32'b0 ;

reg [31:0]   mod_reg_28 = 32'b0 ;

reg [31:0]   mod_reg_29 = 32'b0 ;

reg [31:0]   mod_reg_30 = 32'b0 ;

reg [31:0]   mod_reg_31 = 32'b0 ;

reg  [63:0] vio_out_1_ff = 63'b0 ;

reg  [31:0] vio_rd_data  = 32'b0 ;

//WIRES

wire [63:0] vio_out_1 ;

wire [31:0] vio_out_2 ;

wire [31:0] vio_rd_addr ;

wire [31:0] vio_wr_addr ;

wire [31:0] vio_wr_data ;

reg wr_en ;

//*********************

//MAIN CORE

//*********************

vio_0 your_instance_name (

.clk(clk),                // input wire clk

.probe_in0(vio_rd_data),    // input wire [31 : 0] probe_in0

.probe_out0(vio_out_1),  // output wire [63 : 0] probe_out0

.probe_out1(vio_out_2)  // output wire [31 : 0] probe_out1

);

assign vio_rd_addr = vio_out_2;

assign vio_wr_addr = vio_out_1[63:32];

assign vio_wr_data = vio_out_1[31:0] ;

always @(posedge clk  )

begin

vio_out_1_ff <= vio_out_1 ;

end

always @(posedge clk  )

begin

if ( vio_out_1_ff != vio_out_1 )

wr_en <= 1'b1 ;

else

wr_en <= 1'b0 ;

end

always @(posedge clk )

begin

if ( wr_en == 1'b1 ) begin

case ( vio_wr_addr )

32'd0  : mod_reg_0  <= vio_wr_data ;

32'd1  : mod_reg_1  <= vio_wr_data ;

32'd2  : mod_reg_2  <= vio_wr_data ;

32'd3  : mod_reg_3  <= vio_wr_data ;

32'd4  : mod_reg_4  <= vio_wr_data ;

32'd5  : mod_reg_5  <= vio_wr_data ;

32'd6  : mod_reg_6  <= vio_wr_data ;

32'd7  : mod_reg_7  <= vio_wr_data ;

32'd8  : mod_reg_8  <= vio_wr_data ;

32'd9  : mod_reg_9  <= vio_wr_data ;

32'd10 : mod_reg_10 <= vio_wr_data ;

32'd11 : mod_reg_11 <= vio_wr_data ;

32'd12 : mod_reg_12 <= vio_wr_data ;

32'd13 : mod_reg_13 <= vio_wr_data ;

32'd14 : mod_reg_14 <= vio_wr_data ;

32'd15 : mod_reg_15 <= vio_wr_data ;

32'd16 : mod_reg_16 <= vio_wr_data ;

32'd17 : mod_reg_17 <= vio_wr_data ;

32'd18 : mod_reg_18 <= vio_wr_data ;

32'd19 : mod_reg_19 <= vio_wr_data ;

32'd20 : mod_reg_20 <= vio_wr_data ;

32'd21 : mod_reg_21 <= vio_wr_data ;

32'd22 : mod_reg_22 <= vio_wr_data ;

32'd23 : mod_reg_23 <= vio_wr_data ;

32'd24 : mod_reg_24 <= vio_wr_data ;

32'd25 : mod_reg_25 <= vio_wr_data ;

32'd26 : mod_reg_26 <= vio_wr_data ;

32'd27 : mod_reg_27 <= vio_wr_data ;

32'd28 : mod_reg_28 <= vio_wr_data ;

32'd29 : mod_reg_29 <= vio_wr_data ;

32'd30 : mod_reg_30 <= vio_wr_data ;

32'd31 : mod_reg_31 <= vio_wr_data ;

default :

begin

end

endcase

end

else

begin

end

end

always @(posedge clk)

begin

case ( vio_rd_addr )

32'd0  : vio_rd_data <= mod_reg_0  ;

32'd1  : vio_rd_data <= mod_reg_1  ;

32'd2  : vio_rd_data <= mod_reg_2  ;

32'd3  : vio_rd_data <= mod_reg_3  ;

32'd4  : vio_rd_data <= mod_reg_4  ;

32'd5  : vio_rd_data <= mod_reg_5  ;

32'd6  : vio_rd_data <= mod_reg_6  ;

32'd7  : vio_rd_data <= mod_reg_7  ;

32'd8  : vio_rd_data <= mod_reg_8  ;

32'd9  : vio_rd_data <= mod_reg_9  ;

32'd10 : vio_rd_data <= mod_reg_10 ;

32'd11 : vio_rd_data <= mod_reg_11 ;

32'd12 : vio_rd_data <= mod_reg_12 ;

32'd13 : vio_rd_data <= mod_reg_13 ;

32'd14 : vio_rd_data <= mod_reg_14 ;

32'd15 : vio_rd_data <= mod_reg_15 ;

32'd16 : vio_rd_data <= mod_reg_16 ;

32'd17 : vio_rd_data <= mod_reg_17 ;

32'd18 : vio_rd_data <= mod_reg_18 ;

32'd19 : vio_rd_data <= mod_reg_19 ;

32'd20 : vio_rd_data <= mod_reg_20 ;

32'd21 : vio_rd_data <= mod_reg_21 ;

32'd22 : vio_rd_data <= mod_reg_22 ;

32'd23 : vio_rd_data <= mod_reg_23 ;

32'd24 : vio_rd_data <= mod_reg_24 ;

32'd25 : vio_rd_data <= mod_reg_25 ;

32'd26 : vio_rd_data <= mod_reg_26 ;

32'd27 : vio_rd_data <= mod_reg_27 ;

32'd28 : vio_rd_data <= mod_reg_28 ;

32'd29 : vio_rd_data <= mod_reg_29 ;

32'd30 : vio_rd_data <= mod_reg_30 ;

32'd31 : vio_rd_data <= mod_reg_31 ;

default :

begin

vio_rd_data <= vio_rd_data ;

end

endcase

end

endmodule

2、约束文件源码

set_property PACKAGE_PIN Y9 [get_ports clk]

set_property IOSTANDARD LVCMOS33 [get_ports clk]

上述源码及约束文件适用于Xilinx的Zedboard开发板,已上板验证。另外,上面仅是原理性的简单演示,可以把寄存器应用于自己设计中的各个内部关键模块中,调试的过程中,实时的从VIO接口获取数据,或者动态的配置FPGA内部的寄存器,使其按照寄存器约定的功能运行。虽没有CPU,却等效有了CPU,可大大提高FPGA调试的效率。VIO占用资源情况与chipscope类似。

在PC上通过TCL或者其它语言捕获数据的功能在后续的文章中会陆续的公布,欢迎留言讨论。

转载地址:https://blog.csdn.net/weixin_29240711/article/details/112819156 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:idea shell 使用linux_Shell编程-编辑器选择
下一篇:智能手机芯片天梯图片_关于图像处理芯片(DSP)

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月14日 20时29分01秒