Bootstrap

基于 FPGA 的彩色图像灰度化的设计实现

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

;