zynq pl读写ddr 实现vga高清显示
来源:互联网 发布:三网合一网站源码 编辑:程序博客网 时间:2024/05/02 07:47
其实通过vga显示官方有一个ip核可以用,但是我不是主要为了实现vga显示,而是为了实现如何从ps端向pl端进行大量的数据传送,经过了间断性的不断代码测试,编写,我最终实现了。下面简单说下我是怎样实现的。
目的:
1.实现pl读取ddr内的数据将数据转换成vga的数据流显示到屏幕上,显示大小640*480
2.ps端向ddr内写入像素值,pl端能够同步转换并显示出来。
3.利用axi总线实现。
本次是使用的板子,zybo,板子上的芯片是zynq7010,pl端通信通过axi总线与ps端进行数据的交互,如果要进行简单的交互,可以通过利用axi从模式来进行交互,但是从模式有一个缺点,就是只能等待主端来读这个数据,没有办法来实现pl端主动去写。所以在这里我们就要用要axi的Master模式,从下面这个图片可以看到有7个axi总线可以去读写ddr,2个低速,和4个高速总线,我们这次使用高速总线。
1.配置zynq的外设:这个就不用讲了,网上一搜索一堆。
2.生成一个带axi master的例程ip核。
3. 对于生成的实例代码,其实是向0x xxxx_xxxx地址连续写入4KB的数据,然后在读出来,当然这个实例不满足我们的要求,我们显示的大小是640*480,60Hz,而且在编写代码时我偷了懒,每32bit才传一个像素值(颜色是16bit的),那么我一秒钟要写入的数据量就是 640*480*4*60KB=70.3125兆字节的数据,其实我可以优化到只占一半的带宽,但是我有点懒。
下面对实例进行改造,首先看如下几点:
一次事务传输的大小和长度,这些参数都可以在gui界面中配置,暂时不用管,要知道一次传输的长度最大只有256个字节。
// Base address of targeted slaveparameter C_M_TARGET_SLAVE_BASE_ADDR= 32'h40000000,// Burst Length. Supports 1, 2, 4, 8, 16, 32, 64, 128, 256 burst lengthsparameter integer C_M_AXI_BURST_LEN= 16,
要传输的事务次数,第二个参数被我们改过,原来是
C_MASTER_LENGTH-clogb2((C_M_AXI_BURST_LEN*C_M_AXI_DATA_WIDTH/8)-1);传输的次数就是 [2-1:0] 所占的大小的2次方,也就是4次。从clogb2这个函数就是取以2为底的对数。
// C_TRANSACTIONS_NUM is the width of the index counter for // number of write or read transaction. localparam integer C_TRANSACTIONS_NUM = clogb2(C_M_AXI_BURST_LEN-1);// Burst length for transactions, in C_M_AXI_DATA_WIDTHs.// Non-2^n lengths will eventually cause bursts across 4K address boundaries.// localparam integer C_MASTER_LENGTH= 12;// total number of burst transfers is master length divided by burst length and burst size localparam integer C_NO_BURSTS_REQ = 2;//C_MASTER_LENGTH-clogb2((C_M_AXI_BURST_LEN*C_M_AXI_DATA_WIDTH/8)-1);
这个例子的读写其实是一个3态的状态机实现的,从下面两个地方可以看出来,后面我把写的部分给干掉了,因为我只需要读数据:
代码有点长,粘过来了:
always @ ( posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 1'b0 ) begin // reset condition // All the signals are assigned default values under reset condition mst_exec_state <= IDLE; start_single_burst_write <= 1'b0; start_single_burst_read <= 1'b0; compare_done <= 1'b0; ERROR <= 1'b0; end else begin // state transition case (mst_exec_state) IDLE: // This state is responsible to wait for user defined C_M_START_COUNT // number of clock cycles. if ( init_txn_pulse == 1'b1) begin mst_exec_state <= INIT_READ; ERROR <= 1'b0; compare_done <= 1'b0; end else begin mst_exec_state <= IDLE; end // INIT_WRITE: // // This state is responsible to issue start_single_write pulse to // // initiate a write transaction. Write transactions will be // // issued until burst_write_active signal is asserted. // // write controller // if (writes_done) // begin // mst_exec_state <= INIT_READ;// // end // else // begin // mst_exec_state <= INIT_WRITE; // if (~axi_awvalid && ~start_single_burst_write && ~burst_write_active) // begin // start_single_burst_write <= 1'b1; // end // else // begin // start_single_burst_write <= 1'b0; //Negate to generate a pulse // end // end INIT_READ: // This state is responsible to issue start_single_read pulse to // initiate a read transaction. Read transactions will be // issued until burst_read_active signal is asserted. // read controller if (reads_done) begin mst_exec_state <= IDLE; end else begin mst_exec_state <= INIT_READ; if (~axi_arvalid && ~burst_read_active && ~start_single_burst_read) begin start_single_burst_read <= 1'b1; end else begin start_single_burst_read <= 1'b0; //Negate to generate a pulse end end INIT_COMPARE: // This state is responsible to issue the state of comparison // of written data with the read data. If no error flags are set, // compare_done signal will be asseted to indicate success. //if (~error_reg) begin ERROR <= error_reg; mst_exec_state <= IDLE; compare_done <= 1'b1; end default : begin mst_exec_state <= IDLE; end endcase end end //MASTER_EXECUTION_PROC
读地址的地方我也进行了修改,实例中的地址是读到4096个字节就自动复位了,而我们需要读到0x12C000才能复位,这里的复位信号用的是vga显示的场同步来复位的,刚我满足要求。
// Next address after ARREADY indicates previous address acceptance //指向要读的地址,可以通过改变这里来改变要读的地址 always @(posedge M_AXI_ACLK) begin // if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) if (M_AXI_ARESETN == 0 || vga_vs==1'b0) begin axi_araddr <= 'b0; end else if (M_AXI_ARREADY && axi_arvalid) begin axi_araddr <= axi_araddr + burst_size_bytes; end else axi_araddr <= axi_araddr; end
vga实例化的代码如下,增加了许多的数据传输的信号。
vga utt1_vga( clk_25,//25Mhz时钟 M_AXI_ARESETN,//复位 out_color,//输出的颜色 vga_hs,//行同步 vga_vs,//场同步 M_AXI_RDATA,//读的数据 M_AXI_ACLK,//读数据的时钟 rnext,//读取下一个数据init_txn_pulse,//读取脉冲repeat_one//重复或开始读取 );
vga的代码就不粘了,给大家个思路就好。
仿真得到如下波形,不要问我读缓存中的数据为啥是红色,因为我没有去写过数据,所以是全是X,这不重要,我开的缓存有点大,其实用不了这个大,懒的优化了:
可以看到,地址读取是连续的,取数据也没有冲突,仿真已经满足要求了。
在xilinx sdk中进行图片显示测试,代码如下:
/******************************************************************************** Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.** Use of the Software is limited solely to applications:* (a) running on a Xilinx device, or* (b) that interact with a Xilinx device through a bus or interconnect.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE* SOFTWARE.** Except as contained in this notice, the name of the Xilinx shall not be used* in advertising or otherwise to promote the sale, use or other dealings in* this Software without prior written authorization from Xilinx.*******************************************************************************//* * helloworld.c: simple test application * * This application configures UART 16550 to baud rate 9600. * PS7 UART (Zynq) is not initialized by this application, since * bootrom/bsp configures it to baud rate 115200 * * ------------------------------------------------ * | UART TYPE BAUD RATE | * ------------------------------------------------ * uartns550 9600 * uartlite Configurable only in HW design * ps7_uart 115200 (configured by bootrom/bsp) */#include <stdio.h>#include "platform.h"#include "xil_printf.h"#include "xparameters.h"#include "xgpio.h"#include "img.h"int *axi_addr=(int*)0x10000000;void set_point(int x,int y,long color){if((x>=640||x<0)||(y>=480||y<0)){return;}axi_addr[x+y*(640)]=color;}XGpio Gpio; /* The Instance of the GPIO Driver */void delay(int n){int i,j;for(i=0;i<n;i++){for(j=0;j<2048;j++){}}}int main(){int Status; init_platform(); cleanup_platform();/* Initialize the GPIO driver */Status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);if (Status != XST_SUCCESS) {return XST_FAILURE;}/* Set the direction for all signals as inputs except the LED output */XGpio_SetDataDirection(&Gpio, 1, 0);XGpio_DiscreteWrite(&Gpio,1,0x1);//开始传送数据delay(10);XGpio_DiscreteWrite(&Gpio,1,0x0); int i,j;for(i=0;i<640*480;i++)axi_addr[i]=0xffff;int x_y=0;//while(1){for(i=0;i<480;i++){for(j=0;j<640;j++){unsigned short temp=((unsigned short*)gImage_img)[j+i*640];temp=(temp>>11)|((temp&0x1f)<<11)|(temp&0x7e0);set_point((x_y%640)+j,i,temp);}}//x_y++;//} return 0;}点亮屏幕得到显示完美(其实我已经失败了很多次才完美的):
本来是张美女照片的,我们寝室的拿刀逼我让我换成风景照,没办法他们人多。
有问题,联系小号:549654313,大号:不告诉你
- zynq pl读写ddr 实现vga高清显示
- 【ZYNQ-7000开发之一】PL部分驱动VGA显示静态彩色图像
- 高清 / HDMI / VGA 常见误区
- VGA显示原理与VGA时序实现
- Verilog实现VGA显示控制器
- 高清:2口VGA分配器的使用与原理
- Zedboard & Zynq 图像采集 视频开发 (三) AXI4总线读写DDR
- Zedboard & Zynq 图像采集 视频开发 (三) AXI4总线读写DDR .
- 无线高清显示技术
- 在Nexys4 DDR上实现的DDR2读写例程
- ZYNQ PL中断PS
- HDMI、DVI、VGA、RGB、分量、S端子)高清接口图片说明
- 转接IC GM7123:RGB转VGA 3通道高清视频编码电路
- 3通道高清视频编码电路 转接IC GM7123:TTL转VGA芯片
- asp.net显示高清缩略图
- s5pv210 HDMI 1080P 高清显示
- asp.net显示高清缩略图
- ultraedit 中 高亮显示 PL/SQL
- 完全掌握Android Data Binding
- Linux内核升级
- 3-2 构造函数的调用
- phpcms v9 会员投稿后,限制一定时间内可刷新一次,类似58的刷新置顶功能
- 如何让机器人自主行动?伯克利利用神经网络动力学实现基于模型的强化学习
- zynq pl读写ddr 实现vga高清显示
- 3-6 静态数据成员与静态成员函数
- C++:链表
- HTML 特殊字符编码对照表
- mysql 不等于号写法
- 什么是架构师和如何成为一个架构师
- Essential Qt 第十五章 绘图事件
- Cookie&Session会话技术&Servlet三个作用域总结
- redis的配置