DDR系列文章分类地址:
(1)DDR3 基础知识分享
(2)DDR3 控制器 MIG IP 详解完整版 (AXI4&Vivado&Verilog)
(3)DDR3 控制器 MIG IP 详解完整版 (native&Vivado&Verilog)
(4)基于 DDR3 的串口传图帧缓存系统设计实现
(5)基于 DDR3 的native接口串口局部传图缓存系统设计实现
(6)基于 DDR3 的串口传图缓存系统设计实现
(7)基于 FPGA 的彩色图像灰度化的设计实现
前言
结合串口接收模块和 tft 显示屏控制模块,设计一个基于 DDR3 的AXI接口串口传图帧缓存系统。
提示:以下是本篇文章正文内容,下面案例可供参考
一、串口传图顶层系统设计框图
二、各模块说明
(1)uart_byte_rx 模块:负责串口图像数据的接收,该模块的设计前面章节已经有讲(可参考 串口接收)。
(2)bit8_trans_bit16 模块:将串口接收的每两个 8bit 数据转换成一个 16bit 数据(图像数据是 16bit 的 RGB565 的数据,电脑是通过串口将一个像素点数据分两次发送到 FPGA,FPGA 需将串口接收数据重组成 16bit 的图像数据),实现过程相对比较简单(可参考bit8_trans_bit16 模块)。
(3)disp_driver 模块:tft 屏显示驱动控制,对缓存在 DDR3 中的图像数据进行显示(可参考VGA成像原理)。
(6)fifo_mig_axi_fifo 模块:主要是用于接口的转换,将 MIG IP 的 AXI 接口换成与 FIFO对接的接口,里面例化了wr_ddr3_fifo 模块和rd_ddr3_fifo 模块(可参考fifo_mig_axi_fifo 模块)。
(7)mig_7series_0 模块: DDR3 控制器,使用的 Memory Interface Generator(MIG 7
Series)IP(DDR3 控制器 MIG IP 详解完整版)。
(8)pll 模块:上述各个模块所需时钟的产生,使用 PLL IP。除去使用 IP 和前面章节讲过的模块外,还需要设计的模块包括 bit8_trans_bit16 模块和fifo_mig_axi_fifo 模块(IP生成在下方有介绍)。
(9)顶层模块uart_fifo_ddr3_fifo_tft,用于实现上述模块的转换与连接。
三、系统工程及 IP 创建
新建一个以名为uart_ddr3_tft的工程,工程创建好之后,根据系统整体结构图将所需的 IP 的进行一一创建,DDR 控制器 IP就不多说,按照前面 MIG IP 创建流程,创建一个mig_7series_0 的 DDR 控制器。接下来对两个 FIFO IP 进行创建。首先对 wr_ddr3_fifo 模块进行分析,这个 FIFO 处于串口接收模块与 fifo2mig_axi 模块之间,主要是由于两个模块之间时钟和数据传输速率不一致导致需要进行数据缓存。端口数据是 16bit 图像数据,写入时钟采用与串口接收模块相同的工作时钟 50MHz。读端口数据是用于写入到 DDR 存储器,与 DDR 控制器保持一致,数据位宽使用 128bit,读时钟使用 200MHz 的 ui_clk 时钟。根据分析,需创建一个独立时钟的
读写数据位宽不一样的 FIFO,具体 FIFO 的相关配置如下图。注意,这里 FIFO 的 Read Mode需要设置成 First Word Fall Through,写入数据深度暂时设置为 512,根据后面设计情况可进行修改。
rd_ddr3_fifo 模块与 wr_ddr3_fifo 模块类似,同样处于串口接收模块与 fifo2mig_axi 模块
之间。不同的是,这个 FIFO 的写入数据是来自从 DDR 存储器读出的数据,而读出的数据
是用于图像显示。所以写端口数据位宽为 128bit,写入时钟使用 MIG IP 输出的 200MHz 的
ui_clk 时钟。读端口数据位宽为 16bit,读时钟使用与 TFT 驱动时钟一致的时钟。根据分析,
需创建一个独立时钟的读写数据位宽不一样的 FIFO,具体 FIFO 的相关配置如下图。注意,
这里 FIFO 的 Read Mode 需要设置成 First Word Fall Through,写入数据深度暂时设置为 64,根据后面设计情况可进行修改。
pll 模块是用于产生整个系统中所需各种时钟,整个系统中主要使用到 3 个时钟,分别为 DDR 控制器所需 200MHz 时钟、串口模块工作的 50MHz 时钟、5 寸 TFT 屏驱动模块的33MHz。ACX720 板卡 FPGA 的输入时钟是 50MHz 的输入时钟。根据分析可知,PLL 模块的输入时钟是来自外部的 50MHz 晶振时钟,输出时钟为 200MHz、50MHz、33MHz。具体IP 配置界面如下图,其余界面保持默认即可。
整个系统所需的 IP 已经创建完成,创建的 IP 可以通过在 Source 窗口的 IP Source 中看
到。可鼠标双击进行修改配置等操作。
四、uart_fifo_ddr3_fifo_tft模块
该模块主要作用是串联其他模块,完成传图过程。其中各模块对应的介绍均在第二节后附有连接,以供参考。
`timescale 1ns / 1ps
//
// Module Name : uart_fifo_ddr3_fifo_tft
// Description : 串口传图DDR3缓存TFT屏显示
// Version : Vivado2018.3
// Name : 小王在努力...
//
module uart_fifo_ddr3_fifo_tft(
//System clock reset
input clk50m , //系统时钟输入,50MHz
input reset_n , //复位信号输入
//LED
output [3:0] led ,
//Uart interface
input uart_rx , //串口输入信号
//TFT Interface
output [15:0] TFT_rgb , //TFT数据输出
output TFT_hs , //TFT行同步信号
output TFT_vs , //TFT场同步信号
output TFT_clk , //TFT像素时钟
output TFT_de , //TFT数据使能
output TFT_PWM , //TFT背光控制
//DDR3 Interface
// Inouts
inout [15:0] ddr3_dq ,
inout [1:0] ddr3_dqs_n ,
inout [1:0] ddr3_dqs_p ,
// Outputs
output [13:0] ddr3_addr ,
output [2:0] ddr3_ba ,
output ddr3_ras_n ,
output ddr3_cas_n ,
output ddr3_we_n ,
output ddr3_reset_n ,
output [0:0] ddr3_ck_p ,
output [0:0] ddr3_ck_n ,
output [0:0] ddr3_cke ,
output [0:0] ddr3_cs_n ,
output [1:0] ddr3_dm ,
output [0:0] ddr3_odt
);
//pll interface
wire loc_clk200M;
wire loc_clk33M ;
wire loc_clk50M ;
wire loc_clk165M;
wire pll_locked ;
//uart Interface
wire [7:0]uart_byte ;
wire uart_byte_vaild;
//bit8_trans_bit16 interface
wire [15:0]image_data;
wire image_data_valid;
// frame_rx_done_flip interface
reg [15:0] image_data_hcnt ;
reg [15:0] image_data_vcnt ;
reg image_data_hs ;
reg image_data_vs ;
reg frame_rx_done_flip;
// fifo_mig_axi_fifo Interface
wire [15:0]rdfifo_dout ;
wire ui_clk ;
wire ui_clk_sync_rst ;
wire mmcm_locked ;
wire init_calib_complete;
wire rdfifo_rden ;
//disp_driver interface
wire frame_begin;
wire [4:0]disp_blue;
wire [5:0]disp_green;
wire [4:0]disp_red;
parameter DISP_WIDTH = 16'd800;
parameter DISP_HEIGHT= 16'd480;
assign led = {init_calib_complete,mmcm_locked,pll_locked};
pll pll
(
// Clock out ports
.clk_out1 (loc_clk50M ), // output clk_out1
.clk_out2 (loc_clk200M ), // output clk_out2
.clk_out3 (loc_clk33M ), // output clk_out3
.clk_out4 (loc_clk165M ), // output clk_out4
// Status and control signals
.resetn (reset_n ), // input reset
.locked (pll_locked ), // output locked
// Clock in ports
.clk_in1 (clk50m ) // input clk_in1
);
uart_byte_rx#(
.CLK_FRQ(1000000000)
)
uart_byte_rx(
.clk (loc_clk50M ),
.reset_p (ui_clk_sync_rst ),
.baud_set (3'd5 ), //1562500bps
.uart_rx (uart_rx ),
.data_byte(uart_byte ),
.rx_done (uart_byte_vaild ) //一个字节数据有效的标志
);
bit8_trans_bit16 bit8_trans_bit16
(
.clk (loc_clk50M ),
.reset_p (ui_clk_sync_rst ),
.bit8_in (uart_byte ),
.bit8_in_valid (uart_byte_vaild ),
.bit16_out (image_data ),
.bit16_out_valid (image_data_valid)
);
fifo_mig_axi_fifo
#(
. WR_DDR_ADDR_BEGIN ( 0 ) ,
. WR_DDR_ADDR_END ( DISP_WIDTH*DISP_HEIGHT*2 ) ,
. RD_DDR_ADDR_BEGIN ( 0 ) ,
. RD_DDR_ADDR_END ( DISP_WIDTH*DISP_HEIGHT*2 ) ,
. AXI_ID ( 4'b0000 )
)fifo_mig_axi_fifo
(
//wr_ddr3_fifo ports
. wrfifo_rst (ui_clk_sync_rst ) ,
. loc_clk50M (loc_clk50M ) ,
. wrfifo_din (image_data ) ,
. wrfifo_wren (image_data_valid ) ,
//rd_ddr3_fifo ports
. rdfifo_rst (ui_clk_sync_rst || frame_begin) ,
. loc_clk33M (loc_clk33M ) ,
. rdfifo_rden (rdfifo_rden ) ,
. rdfifo_dout (rdfifo_dout ) ,
//DDR3 Interface
//input
. loc_clk200M (loc_clk200M ) ,
. xx_sys_rst (pll_locked ) , //用于连接 pll_locked
. xx_aresetn (pll_locked ) , //用于连接 pll_locked
//output
. ui_clk (ui_clk ) ,
. ui_clk_sync_rst (ui_clk_sync_rst ) ,
. mmcm_locked (mmcm_locked ) ,
. init_calib_complete(init_calib_complete) ,
//DDR3 Interface
// Inouts
. ddr3_dq (ddr3_dq ) ,
. ddr3_dqs_n (ddr3_dqs_n ) ,
. ddr3_dqs_p (ddr3_dqs_p ) ,
// Outputs
. ddr3_addr (ddr3_addr ) ,
. ddr3_ba (ddr3_ba ) ,
. ddr3_ras_n (ddr3_ras_n ) ,
. ddr3_cas_n (ddr3_cas_n ) ,
. ddr3_we_n (ddr3_we_n ) ,
. ddr3_reset_n (ddr3_reset_n) ,
. ddr3_ck_p (ddr3_ck_p ) ,
. ddr3_ck_n (ddr3_ck_n ) ,
. ddr3_cke (ddr3_cke ) ,
. ddr3_cs_n (ddr3_cs_n ) ,
. ddr3_dm (ddr3_dm ) ,
. ddr3_odt (ddr3_odt )
);
disp_driver disp_driver
(
.ClkDisp (loc_clk33M ),
.Rst_p (ui_clk_sync_rst),
.Data (rdfifo_dout ),
.DataReq (rdfifo_rden ),
.Disp_HS (disp_hs ),
.Disp_VS (disp_vs ),
.Disp_Red (disp_red ),
.Disp_Green (disp_green ),
.Disp_Blue (disp_blue ),
.Frame_Begin (frame_begin ),
.Disp_DE (disp_de ),
.Disp_PCLK (TFT_clk ),
.TFT_PWM (TFT_PWM )
);
assign TFT_hs = disp_hs;
assign TFT_vs = disp_vs;
assign TFT_de = disp_de;
assign TFT_rgb = {disp_red,disp_green,disp_blue};
endmodule
五、uart_ddr3_tft波形分析
通过ILA抓取观察数据:
可看到当TFT_de由0-1是TFT_RGB第一个数据为CF9B跟发送的图片数据一致;按同样方式,抓取最后一个数据,也是一致。
六、传图展示
传图过程中,可以看到 TFT 屏上开始显示发送的图片。图片传送完成后,TFT 屏显示效果如下。