[X]关闭

【ZYNQ-7000开发之十一】VGA RLT代码封装成AXI Stream

文档创建者:RZJM
浏览次数:9145
最后更新:2016-06-01
 
本帖最后由 RZJM 于 2016-1-29 23:39 编辑

本编文章将对VGA的RTL代码,封装成AXI Stream,并且在vivado 里用TPG进行测试

本篇文章的VGA RTL代码在【ZYNQ-7000开发之一】基础上修改,封装好的VGA Stream可以方便我们实现视频图像处理

TGP 等的规范说明可以到官网下载最新版本

本文所使用的开发板是Miz702(兼容zedboard)
PC 开发环境版本:Vivado 2015.2 Xilinx SDK 2015.2
其它:VGA显示器

AXI Stream原理

首先这里列出axi stream的信号,红框里的是要用到的

核心的信号是,TVALID,TREADY,TLAST,TUSER

TVALID和TREADY握手信号


在TVALID和TREADY同时有效的时候,数据才有效。对于TPG来说,大部分时间TVALID是有效的,TREADY由我们自己控制。
TUSER(SOF,Start Of Frame),代表每一帧的开始。TLAST(EOL,End Of Line),代表每一行的结束。
这里给出TPG的时序图,比较简洁,要理解之后才好把RTL封装成AXI Stream

封装AXI Stream打开vivado,建立一个工程(选择zed)选择Tools->Create and Package IP

点击NEXT,选择Create AXI4,如图所示

输入好name和路径后,点击NEXT

按照如下配置(Name为S00_AXI_VGA)

点击NEXT,选择Edit IP,然后点击Finish这时会弹出一个新的IP 编辑界面,这个可以看到VIVADO已经自动生成了一些必要的AXI Stream相关的代码,我们在这个基础上修改很方便把VGA_AXI_Stream_v1_0.v文件里的代码,修改如下
  1. `timescale 1 ns / 1 ps
  2.     module myip_v1_0 #
  3.     (
  4.         // Users to add parameters here
  5.         // User parameters ends
  6.         // Do not modify the parameters beyond this line
  7.         // Parameters of Axi Slave Bus Interface S00_AXIS_VGA
  8.         parameter integer C_S00_AXIS_VGA_TDATA_WIDTH    = 32
  9.     )
  10.     (
  11.         // Users to add ports here
  12.         input   wire            clk_25mhz,
  13.         output  wire            hsync,
  14.         output  wire            vsync,
  15.         output  wire   [11:0]   rgb,
  16.         output  reg             led,
  17.         // User ports ends
  18.         // Do not modify the ports beyond this line
  19.         // Ports of Axi Slave Bus Interface S00_AXIS_VGA
  20.         input wire  s00_axis_vga_aclk,
  21.         input wire  s00_axis_vga_aresetn,
  22.         output wire  s00_axis_vga_tready,
  23.         input wire [C_S00_AXIS_VGA_TDATA_WIDTH-1 : 0] s00_axis_vga_tdata,
  24.         input wire [(C_S00_AXIS_VGA_TDATA_WIDTH/8)-1 : 0] s00_axis_vga_tstrb,
  25.         input wire  s00_axis_vga_tlast,
  26.         input wire  s00_axis_vga_tvalid,
  27.         input wire  s00_axis_vga_tuser
  28.     );
  29. // Instantiation of Axi Bus Interface S00_AXIS_VGA
  30.     myip_v1_0_S00_AXIS_VGA # (
  31.         .C_S_AXIS_TDATA_WIDTH(C_S00_AXIS_VGA_TDATA_WIDTH)
  32.     ) myip_v1_0_S00_AXIS_VGA_inst (
  33.         .S_AXIS_ACLK(s00_axis_vga_aclk),
  34.         .S_AXIS_ARESETN(s00_axis_vga_aresetn),
  35.         .S_AXIS_TREADY(s00_axis_vga_tready),
  36.         .S_AXIS_TDATA(s00_axis_vga_tdata),
  37.         .S_AXIS_TSTRB(s00_axis_vga_tstrb),
  38.         .S_AXIS_TLAST(s00_axis_vga_tlast),
  39.         .S_AXIS_TVALID(s00_axis_vga_tvalid),
  40.         .S_AXIS_TUSER(s00_axis_vga_tuser),
  41.         .clk            (clk_25mhz),
  42.         .rst_n          (s00_axis_vga_aresetn),
  43.         .video_en       (video_en),
  44.         .hsync          (hsync),
  45.         .vsync          (vsync),
  46.         .pixel_x        (pixel_x),
  47.         .pixel_y        (pixel_y)
  48.     );
  49.     // Add user logic here
  50.     wire    [9:0]   pixel_x;
  51.     wire    [9:0]   pixel_y;
  52.     wire            clk_25mhz;
  53.     reg     [11:0]  rgb_reg;
  54.     //显示静态图像640*480
  55.     reg        [23:0] cnt;
  56.     always @(posedge clk_25mhz or negedge s00_axis_vga_aresetn)
  57.         if(!s00_axis_vga_aresetn)
  58.             begin
  59.                 cnt <= 0;
  60.                 led <= 0;
  61.             end
  62.         else
  63.             begin
  64.                 cnt <= cnt + 1'b1;
  65.                 if(cnt == 24'd12500000)
  66.                     begin
  67.                         cnt <= 24'b0;
  68.                         led <= ~led;
  69.                     end
  70.             end
  71.     always @ (posedge clk_25mhz or negedge s00_axis_vga_aresetn)
  72.         if(!s00_axis_vga_aresetn)
  73.             begin
  74.                 rgb_reg <= 12'b0;
  75.             end
  76.         else if(s00_axis_vga_tvalid == 1'b1 && s00_axis_vga_tready == 1'b1)
  77.             begin                //显示图像         
  78.                 rgb_reg[3:0] <= s00_axis_vga_tdata[7:4];
  79.                 rgb_reg[7:4] <= s00_axis_vga_tdata[15:12];
  80.                 rgb_reg[11:8] <= s00_axis_vga_tdata[23:20];   
  81.             end        
  82.    /*         
  83.     always @ (posedge clk_25mhz or negedge s00_axis_vga_aresetn)
  84.         if(!s00_axis_vga_aresetn)
  85.             begin
  86.                 address_sig <= 19'b0;
  87.             end
  88.         else
  89.             begin               
  90.                 if(pixel_x>=0 && pixel_x<= 639 && pixel_y>=0 && pixel_y<=479)
  91.                     address_sig = (pixel_x + 640*pixel_y);
  92.             end   
  93. */
  94.     //////////////////////////////////////////////////////////////        
  95.     assign rgb = (video_en == 1'b1) ? rgb_reg:12'b0;         
  96.     // User logic ends
  97.     endmodule
复制代码


把VGA_AXI_Stream_v1_0_S00_AXI_VgA.v文件里的代码,修改如下
保存后,按照如图所示操作



其它的类似,最后在Review and Package,里选择repackage

建立硬件工程首先要把IP的路径添加进来在vivado里新建一个Block Design,按照如图所示建立硬件工程,FCLK_CLK0设置成25MHz

TPG这样配置

约束文件如下
  1. set_property PACKAGE_PIN T22 [get_ports led]
  2. set_property IOSTANDARD LVCMOS33 [get_ports led]
  3. set_property PACKAGE_PIN AA19 [get_ports hsync]
  4. set_property IOSTANDARD LVCMOS33 [get_ports hsync]
  5. set_property PACKAGE_PIN Y19 [get_ports vsync]
  6. set_property IOSTANDARD LVCMOS33 [get_ports vsync]
  7. set_property PACKAGE_PIN Y21 [get_ports {rgb[0]}]
  8. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[0]}]
  9. set_property PACKAGE_PIN Y20 [get_ports {rgb[1]}]
  10. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[1]}]
  11. set_property PACKAGE_PIN AB20 [get_ports {rgb[2]}]
  12. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[2]}]
  13. set_property PACKAGE_PIN AB19 [get_ports {rgb[3]}]
  14. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[3]}]
  15. set_property PACKAGE_PIN AB22 [get_ports {rgb[4]}]
  16. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[4]}]
  17. set_property PACKAGE_PIN AA22 [get_ports {rgb[5]}]
  18. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[5]}]
  19. set_property PACKAGE_PIN AB21 [get_ports {rgb[6]}]
  20. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[6]}]
  21. set_property PACKAGE_PIN AA21 [get_ports {rgb[7]}]
  22. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[7]}]
  23. set_property PACKAGE_PIN V20 [get_ports {rgb[8]}]
  24. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[8]}]
  25. set_property PACKAGE_PIN U20 [get_ports {rgb[9]}]
  26. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[9]}]
  27. set_property PACKAGE_PIN V19 [get_ports {rgb[10]}]
  28. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[10]}]
  29. set_property PACKAGE_PIN V18 [get_ports {rgb[11]}]
  30. set_property IOSTANDARD LVCMOS33 [get_ports {rgb[11]}]
复制代码


编译后,导出硬件,新建一个Hello工程(主要是为PL提供25M时钟)开发板上电测试,效果如下(color bar效果)


发表评论已发布 6

宋桓公

发表于 2016-2-1 10:00:52 | 显示全部楼层


哈哈,棒棒的~~~

zjsxfkf@163.com

发表于 2016-3-7 17:51:20 | 显示全部楼层

请教个问题,我使用的版本是2014.4, 我在生成AXI_Stream总线的时候,没有TUSER(SOF)信号,这个是要自己增加进去的?还有能否提供工程代码,谢谢

RZJM

发表于 2016-3-8 16:18:40 | 显示全部楼层

zjsxfkf@163.com 发表于 2016-3-7 17:51
请教个问题,我使用的版本是2014.4, 我在生成AXI_Stream总线的时候,没有TUSER(SOF)信号,这个是要自己 ...

我是自己添加的

zjsxfkf@163.com

发表于 2016-3-8 20:06:47 | 显示全部楼层

RZJM 发表于 2016-3-8 16:18
我是自己添加的

哦,那你是利用tuser信号来触发同步信号的吗?我在输出VGA的时候,显示屏显示超出范围,我用ila查看了我看了下hsync信号应该是对的,至于vsync有信号跳变,但是ila不能看全信号周期,我像应该是vsync出了问题,要不应该不会出现超出范围这样的情况是吧,明天用示波器或者逻辑分析仪直接测试下vga输出口,这样应该可以看到,我的时序代码是按照你上一个例子里的时序代码,我看了应该没上面问题,而且时序我用ila看的时候也是按照设计的来的,不知道哪里出了问题。

tnavy

发表于 2016-5-24 15:24:32 | 显示全部楼层

VGA_AXI_Stream_v1_0_S00_AXI_VgA.v 里面的代码看不到?我想知道里面是怎样设置的,能贴出来不?谢谢

RZJM

发表于 2016-6-1 22:47:05 | 显示全部楼层

tnavy 发表于 2016-5-24 15:24
VGA_AXI_Stream_v1_0_S00_AXI_VgA.v 里面的代码看不到?我想知道里面是怎样设置的,能贴出来不?谢谢

网站应该是有源码的。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则