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 的彩色图像灰度化的设计实现
前言
本次实验主要是在上一节的基础上,加入图像处理模块,实现在 PC 端通过上位机下发尺寸为 400*480 大小的彩色图像数据到 FPGA 的串口,FPGA 通过串口接收的彩色图像数据并进行实时彩色图像灰度化处理,然后将原始彩色图像和处理后的图像拼接在一起并缓存在DDR3 中,最终在 TFT 屏上同时显示处理前的彩色图像和处理后的灰度图像。
提示:以下是本篇文章正文内容,下面案例可供参考
一、系统整体设计
系统整体设计框图如下。大体结构与“基于 DDR3 的串口传图帧缓存系统设计实现”基本一致,增加了彩色图像灰度化处理模块 rgb2gray 模块和图像合并模块 image_stitche_x 模块。
二、各模块的功能
(1)uart_byte_rx 模块:负责串口图像数据的接收,该模块的设计前面章节已经有讲。数据(图像数据是 16bit 的 RGB565 的数据,电脑是通过串口将一个像素点数据分两次发送到 FPGA,FPGA 需将串口接收数据重组成 16bit 的图像数据),实现过程相对比较简单(可参考串口接收)。
(2)bit8_trans_bit16 模块:将串口接收的每两个 8bit 数据转换成一个 16bit(可参考8_trans_16)。
(3)rgb2gray 模块:彩色图像灰度化处理,对串口接收的彩色图像数据实时进行灰度化处理(参考基于 FPGA 的彩色图像灰度化的设计实现)。
(4)image_stitche_x 模块:将串口接收的尺寸为 400480 大小的彩色图像与灰度化处理后的 400480 大小的图像数据以左右形式合并成一张 800*480 的图像(基于 FPGA 的彩色图像灰度化的设计实现)。
(5)disp_driver 模块:tft 屏显示驱动控制,对缓存在 DDR3 中的图像数据进行显示(可参考VGA成像原理)。
(6)wr_ddr3_fifo 模块:使用的 FIFO IP ,主要用于写入 DDR3 数据的缓存、解决数据跨时钟域以及数据位宽的转换(参考IP模块)。
(7)rd_ddr3_fifo 模块:使用的 FIFO IP ,主要用于读出 DDR3 数据的缓存、解决数据跨时钟域以及数据位宽的转换(参考IP模块)。
(8)fifo_mig_axi_fifo 模块:主要是用于接口的转换,将 MIG IP 的 AXI 接口换成与 FIFO 对接的接口(可参考添加链接描述)。
(9)mig_7series_0 模块: DDR3 控制器,使用的 Memory Interface Generator(MIG 7 Series)IP(可参考DDR3 控制器 MIG IP 详解完整版)。
(10)pll 模块:上述各个模块所需时钟的产生,使用 PLL IP(参考IP模块)。
本系统就是在上一系统基础上添加图像处理模块搭建系统。除去使用 IP 和前面章节讲过的模块外,还需要设计的模块包括 rgb2gray 模块和 image_stitche_x 模块。
三、uart_ddr3_tft_rgb2gray模块
该模块主要作用是串联其他模块,完成传图过程。其中各模块对应的介绍均在第二节后附有连接,以供参考。
/
// Module Name : uart_ddr3_tft_rgb2gray
// Description : 基于串口传图DDR3缓存TFT屏显示彩色图像灰度化处理
// Name :C.V-Pupil
/
module uart_ddr3_tft_rgb2gray(
//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
);
//*********************************
//Internal connect
//*********************************
//clock
wire pll_locked;
wire loc_clk50m;
wire loc_clk200m;
wire loc_clk33m;
wire loc_clk9m;
//reset
wire g_rst_p;
//uart Interface
wire [7:0] uart_byte;
wire uart_byte_vaild;
//wr_fifo Interface
wire [15:0] wrfifo_din;
wire wrfifo_wren;
wire wrfifo_rden;
wire [127:0] wrfifo_dout;
wire [5 : 0] wrfifo_rd_cnt;
wire wrfifo_empty;
wire wrfifo_wr_rst_busy;
wire wrfifo_rd_rst_busy;
//rd_fifo Interface
wire rdfifo_wren;
wire [127:0] rdfifo_din;
wire rdfifo_rden;
wire [15 :0] rdfifo_dout;
wire [5 : 0] rdfifo_wr_cnt;
wire rdfifo_full;
wire rdfifo_wr_rst_busy;
wire rdfifo_rd_rst_busy;
//mig Interface
wire mig_reset_n;
wire aresetn;
wire mmcm_locked;
wire init_calib_complete;
wire ui_clk;
wire ui_clk_sync_rst;
wire[3:0] s_axi_awid;
wire[27:0] s_axi_awaddr;
wire[7:0] s_axi_awlen;
wire[2:0] s_axi_awsize;
wire[1:0] s_axi_awburst;
wire[0:0] s_axi_awlock;
wire[3:0] s_axi_awcache;
wire[2:0] s_axi_awprot;
wire[3:0] s_axi_awqos;
wire s_axi_awvalid;
wire s_axi_awready;
wire[127:0] s_axi_wdata;
wire[15:0] s_axi_wstrb;
wire s_axi_wlast;
wire s_axi_wvalid;
wire s_axi_wready;
wire [3:0] s_axi_bid;
wire [1:0] s_axi_bresp;
wire s_axi_bvalid;
wire s_axi_bready;
wire[3:0] s_axi_arid;
wire[27:0] s_axi_araddr;
wire[7:0] s_axi_arlen;
wire[2:0] s_axi_arsize;
wire[1:0] s_axi_arburst;
wire[0:0] s_axi_arlock;
wire[3:0] s_axi_arcache;
wire[2:0] s_axi_arprot;
wire[3:0] s_axi_arqos;
wire s_axi_arvalid;
wire s_axi_arready;
wire [3:0] s_axi_rid;
wire [127:0] s_axi_rdata;
wire [1:0] s_axi_rresp;
wire s_axi_rlast;
wire s_axi_rvalid;
wire s_axi_rready;
//tft
wire clk_disp;
wire frame_begin;
wire rdfifo_clr;
reg rdfifo_clr_sync_ui_clk;
reg rd_addr_clr;
wire wrfifo_clr;
reg wrfifo_clr_sync_ui_clk;
reg wr_addr_clr;
reg frame_rx_done_flip;
//兼容小梅哥TFT5.0寸和TFT4.3寸显示屏,可根据实际进行配置选择
/*
parameter DISP_WIDTH = 480;
parameter DISP_HEIGHT = 272;
assign clk_disp = loc_clk9m;
*/
parameter DISP_WIDTH = 800;
parameter DISP_HEIGHT = 480;
assign clk_disp = loc_clk33m;
assign mig_reset_n = pll_locked;
assign aresetn = pll_locked;
assign g_rst_p = ui_clk_sync_rst;
assign led = {frame_rx_done_flip,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_clk9m ), // 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(50000000)
)
uart_byte_rx(
.clk (loc_clk50m ),
.reset_p (g_rst_p ),
.baud_set (3'd5 ), //1562500bps
.uart_rx (uart_rx ),
.data_byte(uart_byte ),
.rx_done (uart_byte_vaild )
);
//---------------------------------------------
//仅仿真用,正常功能时,将197~226行代码屏蔽
//仿真时,取消屏蔽197~226行代码,将179~191代码屏蔽
//---------------------------------------------
// reg [15:0]col_data_cnt;
// reg [15:0]row_data_cnt;
//
// always@(posedge loc_clk50m or posedge g_rst_p)
// begin
// if(g_rst_p)
// col_data_cnt <= 16'd0;
// else if(!init_calib_complete)
// col_data_cnt <= 16'd0;
// else if(col_data_cnt == DISP_WIDTH/2)
// col_data_cnt <= 16'd0;
// else
// col_data_cnt <= col_data_cnt + 1'b1;
// end
//
// always@(posedge loc_clk50m or posedge g_rst_p)
// begin
// if(g_rst_p)
// row_data_cnt <= 16'd0;
// else if(col_data_cnt == DISP_WIDTH/2)
// if(row_data_cnt >= DISP_HEIGHT-1)
// row_data_cnt <= 16'hffff;
// else
// row_data_cnt <= row_data_cnt + 1'b1;
// else
// row_data_cnt <= row_data_cnt;
// end
//
// assign uart_byte = row_data_cnt[7:0];
// assign uart_byte_vaild = (col_data_cnt > 1'b0) && (col_data_cnt <= DISP_WIDTH/2) && (row_data_cnt <= DISP_HEIGHT-1);
//-------------------------------------------
wire [15:0]image_data;
wire image_data_valid;
reg [15:0] image_data_hcnt;
reg [15:0] image_data_vcnt;
reg image_data_hs;
reg image_data_vs;
bit8_trans_bit16 bit8_trans_bit16
(
.clk (loc_clk50m ),
.reset_p (g_rst_p ),
.bit8_in (uart_byte ),
.bit8_in_valid (uart_byte_vaild ),
.bit16_out (image_data ),
.bit16_out_valid (image_data_valid)
);
//generate image data hs or vs
always@(posedge loc_clk50m or posedge g_rst_p)
if(g_rst_p)
image_data_hcnt <= 'd0;
else if(image_data_valid) begin
if(image_data_hcnt == (DISP_WIDTH/2 - 1'b1))
image_data_hcnt <= 'd0;
else
image_data_hcnt <= image_data_hcnt + 1'b1;
end
always@(posedge loc_clk50m or posedge g_rst_p)
if(g_rst_p)
image_data_vcnt <= 'd0;
else if(image_data_valid) begin
if(image_data_hcnt == (DISP_WIDTH/2 - 1'b1)) begin
if(image_data_vcnt == (DISP_HEIGHT - 1'b1))
image_data_vcnt <= 'd0;
else
image_data_vcnt <= image_data_vcnt + 1'b1;
end
end
//hs
always@(posedge loc_clk50m or posedge g_rst_p)
if(g_rst_p)
image_data_hs <= 1'b0;
else if(image_data_valid && image_data_hcnt == (DISP_WIDTH/2 - 1'b1))
image_data_hs <= 1'b0;
else
image_data_hs <= 1'b1;
//vs
always@(posedge loc_clk50m or posedge g_rst_p)
if(g_rst_p)
image_data_vs <= 1'b0;
else if(image_data_valid && image_data_hcnt == (DISP_WIDTH/2 - 1'b1) &&
image_data_vcnt == (DISP_HEIGHT - 1'b1))
image_data_vs <= 1'b0;
else
image_data_vs <= 1'b1;
always@(posedge loc_clk50m or posedge g_rst_p)
if(g_rst_p)
frame_rx_done_flip <= 1'b0;
else if(image_data_valid && image_data_hcnt == (DISP_WIDTH/2 - 1'b1) &&
image_data_vcnt == (DISP_HEIGHT - 1'b1))
frame_rx_done_flip <= ~frame_rx_done_flip;
//---------------------------------------------
//image processing
//---------------------------------------------
wire [7:0] image_gray_data;
wire image_gray_data_valid;
wire [15:0]image_stitche_data;
wire image_stitche_data_valid;
rgb2gray
#(
.PROC_METHOD ( "FORMULA" )//"AVERAGE" :求平均法
//or "FORMULA" :直接公式法
//or "LUT" :查找表法
)rgb2gray
(
.clk (loc_clk50m ),//input
.reset_p (g_rst_p ),//input
.rgb_valid (image_data_valid ),//input
.rgb_hs (image_data_hs ),//input
.rgb_vs (image_data_vs ),//input
.red_8b_i ({image_data[15:11],3'b000}),//input [7:0]
.green_8b_i ({image_data[10:5],2'b00} ),//input [7:0]
.blue_8b_i ({image_data[4:0],3'b000} ),//input [7:0]
.gray_8b_o (image_gray_data ),//output [7:0]
.gray_valid (image_gray_data_valid ),//output reg
.gray_hs ( ),//output reg
.gray_vs ( ) //output reg
);
image_stitche_x
#(
.DATA_WIDTH ( 16 ), //16 or 24
//image1_in: 400*480
.IMAGE1_WIDTH_IN ( DISP_WIDTH/2),
.IMAGE1_HEIGHT_IN ( DISP_HEIGHT ),
//image2_in: 400*480
.IMAGE2_WIDTH_IN ( DISP_WIDTH/2),
.IMAGE2_HEIGHT_IN ( DISP_HEIGHT ),
//image_out: 800*480
.IMAGE_WIDTH_OUT ( DISP_WIDTH ),
.IMAGE_HEIGHT_OUT ( DISP_HEIGHT )
)image_stitche_x(
.clk_image1_in (loc_clk50m ),
.clk_image2_in (loc_clk50m ),
.clk_image_out (loc_clk50m ),
.reset_p (g_rst_p ),
.rst_busy_o ( ),
.image_in_ready_o ( ),
.image1_data_pixel_i(image_data ),
.image1_data_valid_i(image_data_valid ),
.image2_data_pixel_i({image_gray_data[7:3],image_gray_data[7:2],image_gray_data[7:3]}),
.image2_data_valid_i(image_gray_data_valid),
.data_out_ready_i (1'b0 ),
.data_pixel_o (image_stitche_data ),
.data_valid_o (image_stitche_data_valid)
);
//---------------------------------------------
assign wrfifo_din = image_stitche_data;
assign wrfifo_wren = image_stitche_data_valid;
disp_driver disp_driver
(
.ClkDisp (clk_disp ),
.Rst_p (g_rst_p ),
.Data (rdfifo_dout ),
.DataReq (rdfifo_rden ),
.H_Addr ( ),
.V_Addr ( ),
.Disp_HS (TFT_hs ),
.Disp_VS (TFT_vs ),
.Disp_Red (TFT_rgb[15:11] ),
.Disp_Green (TFT_rgb[10:5] ),
.Disp_Blue (TFT_rgb[4:0] ),
.Frame_Begin (frame_begin ),
.Disp_DE (TFT_de ),
.Disp_PCLK (TFT_clk )
);
assign TFT_pwm = 1'b1;
assign wrfifo_clr = ui_clk_sync_rst;
assign rdfifo_clr = frame_begin || ui_clk_sync_rst;
wr_ddr3_fifo wr_ddr3_fifo
(
.rst (wrfifo_clr ), // input wire rst
.wr_clk (loc_clk50m ), // input wire wr_clk
.rd_clk (ui_clk ), // input wire rd_clk
.din (wrfifo_din ), // input wire [15 : 0] din
.wr_en (wrfifo_wren ), // input wire wr_en
.rd_en (wrfifo_rden ), // input wire rd_en
.dout (wrfifo_dout ), // output wire [127 : 0] dout
.full ( ), // output wire full
.empty (wrfifo_empty ), // output wire empty
.rd_data_count (wrfifo_rd_cnt ), // output wire [5 : 0] rd_data_count
.wr_data_count ( ), // output wire [8 : 0] wr_data_count
.wr_rst_busy (wrfifo_wr_rst_busy ), // output wire wr_rst_busy
.rd_rst_busy (wrfifo_rd_rst_busy ) // output wire rd_rst_busy
);
rd_ddr3_fifo rd_ddr3_fifo
(
.rst (rdfifo_clr ), // input wire rst
.wr_clk (ui_clk ), // input wire wr_clk
.rd_clk (clk_disp ), // input wire rd_clk
.din (rdfifo_din ), // input wire [127 : 0] din
.wr_en (rdfifo_wren ), // input wire wr_en
.rd_en (rdfifo_rden ), // input wire rd_en
.dout (rdfifo_dout ), // output wire [15 : 0] dout
.full (rdfifo_full ), // output wire full
.empty ( ), // output wire empty
.rd_data_count ( ), // output wire [8 : 0] rd_data_count
.wr_data_count (rdfifo_wr_cnt ), // output wire [5 : 0] wr_data_count
.wr_rst_busy (rdfifo_wr_rst_busy ), // output wire wr_rst_busy
.rd_rst_busy (rdfifo_rd_rst_busy ) // output wire rd_rst_busy
);
always@(posedge ui_clk)
begin
wrfifo_clr_sync_ui_clk <= wrfifo_clr;
wr_addr_clr <= wrfifo_clr_sync_ui_clk;
end
always@(posedge ui_clk)
begin
rdfifo_clr_sync_ui_clk <= rdfifo_clr;
rd_addr_clr <= rdfifo_clr_sync_ui_clk;
end
fifo2mig_axi
#(
.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 ),
.AXI_LEN (8'd31 ) //axi burst length = 32
)fifo2mig_axi
(
//FIFO Interface ports
.wr_addr_clr (wr_addr_clr ), //1:clear sync ui_clk
.wr_fifo_rdreq (wrfifo_rden ),
.wr_fifo_rddata (wrfifo_dout ),
.wr_fifo_empty (wrfifo_empty ),
.wr_fifo_rd_cnt (wrfifo_rd_cnt ),
.wr_fifo_rst_busy (wrfifo_wr_rst_busy | wrfifo_rd_rst_busy),
.rd_addr_clr (rd_addr_clr ), //1:clear sync ui_clk
.rd_fifo_wrreq (rdfifo_wren ),
.rd_fifo_wrdata (rdfifo_din ),
.rd_fifo_alfull (rdfifo_full ),
.rd_fifo_wr_cnt (rdfifo_wr_cnt ),
.rd_fifo_rst_busy (rdfifo_wr_rst_busy | rdfifo_rd_rst_busy),
// Application interface ports
.ui_clk (ui_clk ),
.ui_clk_sync_rst (ui_clk_sync_rst ),
.mmcm_locked (mmcm_locked ),
.init_calib_complete (init_calib_complete ),
// Slave Interface Write Address Ports
.m_axi_awid (s_axi_awid ),
.m_axi_awaddr (s_axi_awaddr ),
.m_axi_awlen (s_axi_awlen ),
.m_axi_awsize (s_axi_awsize ),
.m_axi_awburst (s_axi_awburst ),
.m_axi_awlock (s_axi_awlock ),
.m_axi_awcache (s_axi_awcache ),
.m_axi_awprot (s_axi_awprot ),
.m_axi_awqos (s_axi_awqos ),
.m_axi_awvalid (s_axi_awvalid ),
.m_axi_awready (s_axi_awready ),
// Slave Interface Write Data Ports
.m_axi_wdata (s_axi_wdata ),
.m_axi_wstrb (s_axi_wstrb ),
.m_axi_wlast (s_axi_wlast ),
.m_axi_wvalid (s_axi_wvalid ),
.m_axi_wready (s_axi_wready ),
// Slave Interface Write Response Ports
.m_axi_bid (s_axi_bid ),
.m_axi_bresp (s_axi_bresp ),
.m_axi_bvalid (s_axi_bvalid ),
.m_axi_bready (s_axi_bready ),
// Slave Interface Read Address Ports
.m_axi_arid (s_axi_arid ),
.m_axi_araddr (s_axi_araddr ),
.m_axi_arlen (s_axi_arlen ),
.m_axi_arsize (s_axi_arsize ),
.m_axi_arburst (s_axi_arburst ),
.m_axi_arlock (s_axi_arlock ),
.m_axi_arcache (s_axi_arcache ),
.m_axi_arprot (s_axi_arprot ),
.m_axi_arqos (s_axi_arqos ),
.m_axi_arvalid (s_axi_arvalid ),
.m_axi_arready (s_axi_arready ),
// Slave Interface Read Data Ports
.m_axi_rid (s_axi_rid ),
.m_axi_rdata (s_axi_rdata ),
.m_axi_rresp (s_axi_rresp ),
.m_axi_rlast (s_axi_rlast ),
.m_axi_rvalid (s_axi_rvalid ),
.m_axi_rready (s_axi_rready )
);
mig_7series_0 u_mig_7series_0 (
// Memory interface ports
.ddr3_addr (ddr3_addr ), // output [13:0] ddr3_addr
.ddr3_ba (ddr3_ba ), // output [2:0] ddr3_ba
.ddr3_cas_n (ddr3_cas_n ), // output ddr3_cas_n
.ddr3_ck_n (ddr3_ck_n ), // output [0:0] ddr3_ck_n
.ddr3_ck_p (ddr3_ck_p ), // output [0:0] ddr3_ck_p
.ddr3_cke (ddr3_cke ), // output [0:0] ddr3_cke
.ddr3_ras_n (ddr3_ras_n ), // output ddr3_ras_n
.ddr3_reset_n (ddr3_reset_n ), // output ddr3_reset_n
.ddr3_we_n (ddr3_we_n ), // output ddr3_we_n
.ddr3_dq (ddr3_dq ), // inout [15:0] ddr3_dq
.ddr3_dqs_n (ddr3_dqs_n ), // inout [1:0] ddr3_dqs_n
.ddr3_dqs_p (ddr3_dqs_p ), // inout [1:0] ddr3_dqs_p
.init_calib_complete (init_calib_complete ), // output init_calib_complete
.ddr3_cs_n (ddr3_cs_n ), // output [0:0] ddr3_cs_n
.ddr3_dm (ddr3_dm ), // output [1:0] ddr3_dm
.ddr3_odt (ddr3_odt ), // output [0:0] ddr3_odt
// Application interface ports
.ui_clk (ui_clk ), // output ui_clk
.ui_clk_sync_rst (ui_clk_sync_rst ), // output ui_clk_sync_rst
.mmcm_locked (mmcm_locked ), // output mmcm_locked
.aresetn (aresetn ), // input aresetn
.app_sr_req (1'b0 ), // input app_sr_req
.app_ref_req (1'b0 ), // input app_ref_req
.app_zq_req (1'b0 ), // input app_zq_req
.app_sr_active ( ), // output app_sr_active
.app_ref_ack ( ), // output app_ref_ack
.app_zq_ack ( ), // output app_zq_ack
// Slave Interface Write Address Ports
.s_axi_awid (s_axi_awid ), // input [3:0] s_axi_awid
.s_axi_awaddr (s_axi_awaddr ), // input [27:0] s_axi_awaddr
.s_axi_awlen (s_axi_awlen ), // input [7:0] s_axi_awlen
.s_axi_awsize (s_axi_awsize ), // input [2:0] s_axi_awsize
.s_axi_awburst (s_axi_awburst ), // input [1:0] s_axi_awburst
.s_axi_awlock (s_axi_awlock ), // input [0:0] s_axi_awlock
.s_axi_awcache (s_axi_awcache ), // input [3:0] s_axi_awcache
.s_axi_awprot (s_axi_awprot ), // input [2:0] s_axi_awprot
.s_axi_awqos (s_axi_awqos ), // input [3:0] s_axi_awqos
.s_axi_awvalid (s_axi_awvalid ), // input s_axi_awvalid
.s_axi_awready (s_axi_awready ), // output s_axi_awready
// Slave Interface Write Data Ports
.s_axi_wdata (s_axi_wdata ), // input [127:0] s_axi_wdata
.s_axi_wstrb (s_axi_wstrb ), // input [15:0] s_axi_wstrb
.s_axi_wlast (s_axi_wlast ), // input s_axi_wlast
.s_axi_wvalid (s_axi_wvalid ), // input s_axi_wvalid
.s_axi_wready (s_axi_wready ), // output s_axi_wready
// Slave Interface Write Response Ports
.s_axi_bid (s_axi_bid ), // output [3:0] s_axi_bid
.s_axi_bresp (s_axi_bresp ), // output [1:0] s_axi_bresp
.s_axi_bvalid (s_axi_bvalid ), // output s_axi_bvalid
.s_axi_bready (s_axi_bready ), // input s_axi_bready
// Slave Interface Read Address Ports
.s_axi_arid (s_axi_arid ), // input [3:0] s_axi_arid
.s_axi_araddr (s_axi_araddr ), // input [27:0] s_axi_araddr
.s_axi_arlen (s_axi_arlen ), // input [7:0] s_axi_arlen
.s_axi_arsize (s_axi_arsize ), // input [2:0] s_axi_arsize
.s_axi_arburst (s_axi_arburst ), // input [1:0] s_axi_arburst
.s_axi_arlock (s_axi_arlock ), // input [0:0] s_axi_arlock
.s_axi_arcache (s_axi_arcache ), // input [3:0] s_axi_arcache
.s_axi_arprot (s_axi_arprot ), // input [2:0] s_axi_arprot
.s_axi_arqos (s_axi_arqos ), // input [3:0] s_axi_arqos
.s_axi_arvalid (s_axi_arvalid ), // input s_axi_arvalid
.s_axi_arready (s_axi_arready ), // output s_axi_arready
// Slave Interface Read Data Ports
.s_axi_rid (s_axi_rid ), // output [3:0] s_axi_rid
.s_axi_rdata (s_axi_rdata ), // output [127:0] s_axi_rdata
.s_axi_rresp (s_axi_rresp ), // output [1:0] s_axi_rresp
.s_axi_rlast (s_axi_rlast ), // output s_axi_rlast
.s_axi_rvalid (s_axi_rvalid ), // output s_axi_rvalid
.s_axi_rready (s_axi_rready ), // input s_axi_rready
// System Clock Ports
.sys_clk_i (loc_clk200m ),
.sys_rst (mig_reset_n ) // input sys_rst
);
endmodule
四、传图显示
顶层的仿真与“基于 DDR3 的串口传图帧缓存系统”类似,这里就不做详细讲解,读者自己建立仿真文件完成顶层的仿真。
在顶层设计分析综合没有错误并且顶层仿真确认设计功能没有问题后,进行上板验证。对工程的管脚和时钟进行约束后,生成 Bit 文件。
传图过程中,可以看到 TFT 屏上开始显示发送的图片。图片传送完成后,TFT 屏显示效果如下。
通过对比可以看出,TFT 屏上左右两边分别显示的是原始的彩色图像和灰度化之后的灰度图像。可通过改变在顶层例化彩色图像灰度化模块使用的方式观察不同的实现方法下的实现效果。
【附件:】链接:https://pan.baidu.com/s/1kk3gUrrznMLlZoH3Tz0GGQ?pwd=r1ds
提取码:r1ds