基于 DDR3 的串口传图帧缓存系统设计实现(整体设计)

news2024/11/28 22:49:20

文章目录

  • 前言
  • 一、串口传图顶层系统设计框图
  • 二、各模块说明
  • 三、系统工程及 IP 创建
  • 四、uart_ddr3_tft模块
  • 五、uart_ddr3_tft模块仿真文件
  • 六、uart_ddr3_tft模块仿真文件


前言

结合串口接收模块和 tft 显示屏控制模块,设计一个基于 DDR3 的串口传图帧缓存系统。


提示:以下是本篇文章正文内容,下面案例可供参考

一、串口传图顶层系统设计框图

在这里插入图片描述

二、各模块说明

(1)uart_byte_rx 模块:负责串口图像数据的接收,该模块的设计前面章节已经有讲(可参考串口接收)。
(2)bit8_trans_bit16 模块:将串口接收的每两个 8bit 数据转换成一个 16bit 数据(图像数据是 16bit 的 RGB565 的数据,电脑是通过串口将一个像素点数据分两次发送到 FPGA,FPGA 需将串口接收数据重组成 16bit 的图像数据),实现过程相对比较简单(可参考8_trans_16)。
(3)disp_driver 模块:tft 屏显示驱动控制,对缓存在 DDR3 中的图像数据进行显示(可参考VGA成像原理)。
(4)wr_ddr3_fifo 模块:使用的 FIFO IP ,主要用于写入 DDR3 数据的缓存、解决数
据跨时钟域以及数据位宽的转换(IP生成在下方有介绍)。
(5)rd_ddr3_fifo 模块:使用的 FIFO IP ,主要用于读出 DDR3 数据的缓存、解决数据
跨时钟域以及数据位宽的转换(IP生成在下方有介绍)。
(6)fifo2mig_axi 模块:主要是用于接口的转换,将 MIG IP 的 AXI 接口换成与 FIFO
对接的接口(可参考fifo2mig_axi)。
(7)mig_7series_0 模块: DDR3 控制器,使用的 Memory Interface Generator(MIG 7
Series)IP(可参考添加链接描述)。
(8)pll 模块:上述各个模块所需时钟的产生,使用 PLL IP。除去使用 IP 和前面章节讲过的模块外,还需要设计的模块包括 bit8_trans_bit16 模块和fifo2mig_axi 模块(IP生成在下方有介绍)。
(9)顶层模块uart_ddr3_tft,用于实现上述模块的转换与连接(参考第四节uart_ddr3_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,根据后面设计情况可进行修改。
2
3
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,根据后面设计情况可进行修改。
4
5
pll 模块是用于产生整个系统中所需各种时钟,整个系统中主要使用到 3 个时钟,分别为 DDR 控制器所需 200MHz 时钟、串口模块工作的 50MHz 时钟、5 寸 TFT 屏驱动模块的33MHz。ACX720 板卡 FPGA 的输入时钟是 50MHz 的输入时钟。根据分析可知,PLL 模块的输入时钟是来自外部的 50MHz 晶振时钟,输出时钟为 200MHz、50MHz、33MHz。具体IP 配置界面如下图,其余界面保持默认即可。
6
整个系统所需的 IP 已经创建完成,创建的 IP 可以通过在 Source 窗口的 IP Source 中看
到。可鼠标双击进行修改配置等操作。
7

四、uart_ddr3_tft模块

该模块主要作用是串联其他模块,完成传图过程。其中个模块对应的介绍均在第二节后附有连接,以供参考。

/

// Module Name   : uart_ddr3_tft
// Description   : 串口传图DDR3缓存TFT屏显示
// Version       : Vivado2018.3 
// Name          : 小王在努力...
/

module uart_ddr3_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        
);
//*********************************
//Internal connect
//*********************************
  //clock
  wire          pll_locked;
  wire          loc_clk50m;
  wire          loc_clk200m;
  wire          loc_clk33m;
  wire          loc_clk9m;
  
  //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 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(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 )  //一个字节数据有效的标志
  );

//---------------------------------------------
//仅仿真用,正常功能时,将197~226行代码屏蔽
//仿真时,取消屏蔽197~226行代码,将179~191代码屏蔽
//---------------------------------------------
 // reg [15:0]col_data_cnt;
 // reg [15:0]row_data_cnt;

 // always@(posedge loc_clk50m or posedge ui_clk_sync_rst)
 // begin
   // if(ui_clk_sync_rst)
     // 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 ui_clk_sync_rst)
 // begin
   // if(ui_clk_sync_rst)
     // 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 == DISP_WIDTH*2);
//-------------------------------------------

  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         (ui_clk_sync_rst ),

    .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观察数据是否产生了800*480
  always@(posedge loc_clk50m or posedge ui_clk_sync_rst)
    if(ui_clk_sync_rst)
      image_data_hcnt <= 'd0;
    else if(image_data_valid) begin
      if(image_data_hcnt == (DISP_WIDTH - 1'b1))
        image_data_hcnt <= 'd0;
      else
        image_data_hcnt <= image_data_hcnt + 1'b1;
    end

  always@(posedge loc_clk50m or posedge ui_clk_sync_rst)
    if(ui_clk_sync_rst)
      image_data_vcnt <= 'd0;
    else if(image_data_valid) begin
      if(image_data_hcnt == (DISP_WIDTH - 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 ui_clk_sync_rst)
    if(ui_clk_sync_rst)
      image_data_hs <= 1'b0;
    else if(image_data_valid && image_data_hcnt == (DISP_WIDTH - 1'b1))
      image_data_hs <= 1'b0;
    else
      image_data_hs <= 1'b1;
  //vs
  always@(posedge loc_clk50m or posedge ui_clk_sync_rst)
    if(ui_clk_sync_rst)
      image_data_vs <= 1'b0;
    else if(image_data_valid && image_data_hcnt == (DISP_WIDTH - 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 ui_clk_sync_rst)
    if(ui_clk_sync_rst)
      frame_rx_done_flip <= 1'b0;
    else if(image_data_valid && image_data_hcnt == (DISP_WIDTH - 1'b1) &&
            image_data_vcnt == (DISP_HEIGHT - 1'b1))
      frame_rx_done_flip <= ~frame_rx_done_flip;

  //-------------------------------------------------------------------------------------------



  assign wrfifo_din  = image_data;
  assign wrfifo_wren = image_data_valid;

  disp_driver disp_driver
  (
    .ClkDisp     (clk_disp       ),
    .Rst_p       (ui_clk_sync_rst),

    .Data        (rdfifo_dout    ),
    .DataReq     (rdfifo_rden    ),

    .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        (loc_clk33m         ), // 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

五、uart_ddr3_tft模块仿真文件

`timescale 1ns / 1ns
`define CLK_PERIOD 20

module uart_ddr3_tft_tb();
  reg           clk50m;
  reg           reset_n;

  wire [15:0]   TFT_rgb; //TFT数据输出
  wire          TFT_hs;  //TFT行同步信号
  wire          TFT_vs;  //TFT场同步信号
  wire          TFT_clk; //TFT像素时钟
  wire          TFT_de;  //TFT数据使能
  wire          TFT_pwm; //TFT背光控制

  wire [13:0]   ddr3_addr;
  wire [2:0]    ddr3_ba;
  wire          ddr3_cas_n;
  wire [0:0]    ddr3_ck_n;
  wire [0:0]    ddr3_ck_p;
  wire [0:0]    ddr3_cke;
  wire          ddr3_ras_n;
  wire          ddr3_reset_n;
  wire          ddr3_we_n;
  wire [15:0]   ddr3_dq;
  wire [1:0]    ddr3_dqs_n;
  wire [1:0]    ddr3_dqs_p;
  wire [0:0]    ddr3_cs_n;
  wire [1:0]    ddr3_dm;
  wire [0:0]    ddr3_odt;

  initial clk50m = 1;
  always #(`CLK_PERIOD/2) clk50m = ~clk50m;

  initial begin
    reset_n = 1'b0;
    #201;
    reset_n = 1'b1;
    
    @(posedge uart_ddr3_tft.init_calib_complete)
    @(posedge TFT_vs);
    @(posedge TFT_vs);
    @(posedge TFT_vs);
    $stop;
  end

  uart_ddr3_tft
  uart_ddr3_tft
  (
    //System clock reset
    .clk50m         (clk50m         ), //系统时钟输入,50M
    .reset_n        (reset_n        ), //复位信号输入,低有效
    //led
    .led            (               ), //指示灯
    //Uart interface                
    .uart_rx        (               ), //串口输入信号
    //TFT Interface                 
    .TFT_rgb        (TFT_rgb        ), //TFT数据输出
    .TFT_hs         (TFT_hs         ), //TFT行同步信号
    .TFT_vs         (TFT_vs         ), //TFT场同步信号
    .TFT_clk        (TFT_clk        ), //TFT像素时钟
    .TFT_de         (TFT_de         ), //TFT数据使能
    .TFT_pwm        (TFT_pwm        ), //TFT背光控制
    // 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
    .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
  );

  ddr3_model ddr3_model
  (
    .rst_n  (ddr3_reset_n ),
    .ck     (ddr3_ck_p    ),
    .ck_n   (ddr3_ck_n    ),
    .cke    (ddr3_cke     ),
    .cs_n   (ddr3_cs_n    ),
    .ras_n  (ddr3_ras_n   ),
    .cas_n  (ddr3_cas_n   ),
    .we_n   (ddr3_we_n    ),
    .dm_tdqs(ddr3_dm      ),
    .ba     (ddr3_ba      ),
    .addr   (ddr3_addr    ),
    .dq     (ddr3_dq      ),
    .dqs    (ddr3_dqs_p   ),
    .dqs_n  (ddr3_dqs_n   ),
    .tdqs_n (             ),
    .odt    (ddr3_odt     )
  );

endmodule

六、uart_ddr3_tft模块仿真文件

在顶层设计分析综合没有错误并且顶层仿真确认设计功能没有问题后,进行上板验证。对工程的管脚和时钟进行约束后,生成 Bit 文件。下载完成后,开发板上 LED0~LED2 会亮,TFT5.0 寸屏上显示花屏状态。如下图所示。
1
出现这种花屏是因为这个时候,DDR3 中并未写入数据,显示的数据是不可知的一些数据。LED0 和 LED1 分别表示的是 DDR 控制器内时钟锁相环的 locked 信号和 DDR 初始化校准完成信号的状态,亮表示这个两个信号均变为高电平,说明 DDR 已经正常完成初始化和校准操作。接下来通过串口传图工具向 FPGA 传输图片数据。

这里提供的上位机要求图片为位深度为 24 或 16 的 bmp 格式图片,图片的宽度和高度需要为 800480(插 5 寸屏情况下)或 480272(插 4.3 寸屏情况下)。关于图片的信息可通过右键图片查看其属性,在属性的详细信息窗口可以看到图片大小,位深度等信息。

传图过程中,可以看到 TFT 屏上开始显示发送的图片。图片传送完成后,TFT 屏显示效果如下。
在这里插入图片描述

【附件:】链接:https://pan.baidu.com/s/1YPc3aytOKLQmEqpLnjk4rw?pwd=wzxj
提取码:wzxj

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/512667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DES加密算法、RSA加密算法

DES加密算法 DES加密过程 1、将明文和密钥转化为ASCII码&#xff0c;明文64位bit&#xff0c;密钥56位 2、明文进行初始置换 3、明文初始置换后前32位为L0&#xff0c;后32位为R0 4、第一轮算法&#xff0c;L1R0&#xff0c;R0进行F运算后跟L0异或的结果为R1 5、F运算&#x…

jmeter如何测试一个get请求

目录 1.配置测试计划1.1.创建线程组1.2.创建GET的HTTP请求取样器&#xff08;模拟GET请求&#xff09;1.3.添加查看结果树和聚合报告 2.执行压测并查看结果2.1.验证接口2.2.执行压力测试 使用jmeter测试一个http的get请求示例. 1.配置测试计划 1.1.创建线程组 打开jmeter - 测…

C语言实现扫雷(包含递归展开)

目录 一&#xff1a;扫雷游戏的基础逻辑 二&#xff1a;关于扫雷相关的信息存储 三&#xff1a;游戏大体实现逻辑 四&#xff1a;具体实现 (1)初始化 (2)打印 (3)布置雷 (4)查雷 五&#xff1a;全部代码 (1)game.h (2)game.c (3)test.c 六&#xff1a;实际效果演示…

【操作系统复习】第6章 虚拟存储器 2

请求分页中的内存分配 在为进程分配物理块时&#xff0c;要解决下列的三个问题&#xff1a; 1. 保证进程可正常运行所需要的最少物理块数 2. 每个进程的物理块数&#xff0c;是固定值还是可变值&#xff08;分配策略&#xff09; 3. 不同进程所分配的物理块数&#xff…

Python基础入门编程代码练习(三)

一、猜数游戏 有一个数列&#xff1a;8&#xff0c;4&#xff0c;2&#xff0c;1&#xff0c;23&#xff0c;344&#xff0c;12循环输出数列的值求数列中所有数值的和猜数游戏&#xff1a;从键盘中任意输入一个数据&#xff0c;判断数列中是否包含此数 实现代码如下&#xf…

【云原生】Kubrenetes二进制--单节点Master集群

单节点Master集群 一、Kubernetes概述1、Master组件2、Node组件 二、Kubernetes核心概念1、Pod概述2、Pod控制器3、Label标签4、Label选择器5、Service6、Ingress 三、部署kubernetes1、所有节点关闭防火墙 核心防护 Swap交换2、将三台服务器的地址hosts中3、调整内核参数4、时…

十分钟教你搭建ChatGPT 图片生成的安卓应用

十分钟教你搭建ChatGPT 图片生成的安卓应用 大家好&#xff0c;我是易安&#xff01; 今天&#xff0c;我们将集成 OpenAI API (ChatGPT)来构建一个简单的类似 ChatGPT 的 android 应用程序&#xff0c;让它返回我们想要的图片&#xff0c;本文是上一篇的姊妹篇。 详细步骤 第…

防止表单重复提交的几种方式,演示一个自定义注解方式的实现

防止表单重复提交的几种方式&#xff0c;演示一个自定义注解方式的实现 一、防止表单重复提交的几种方式方式一&#xff1a;Token 机制方式二&#xff1a;去重表&#xff08;主要是利用 MySQL 的唯一索引机制来实现的&#xff09;方式三&#xff1a;Redis 的 setnx方式四&#…

数组(C语言版)

&#x1f929;本文作者&#xff1a;大家好&#xff0c;我是paperjie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 &#x1f970;内容专栏&#xff1a;这里是《C知识系统分享》专栏&#xff0c;笔者用重金(时间和精力)打造&#xff0c;基础知识一网打尽&#xff0c;…

3 ES快速入门

3 ES快速入门 ES作为一个索引及搜索服务&#xff0c;对外提供丰富的REST接口&#xff0c;快速入门部分的实例使用head插件来测试&#xff0c;目的是对ES 的使用方法及流程有个初步的认识。 3.1 创建索引库 ES的索引库是一个逻辑概念&#xff0c;它包括了分词列表及文档列表…

电力系统负荷与电价预测优化模型(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【C++】vector的模拟实现及深度剖析

目录 一、模拟实现二、使用memcpy拷贝问题三、动态二维数组理解 一、模拟实现 namespace hxj {template<class T>class vector{public:// Vector的迭代器是一个原生指针typedef T* iterator;typedef const T* const_iterator;//构造和销毁vector():_start(nullptr), _fi…

Spring更简单的存储和读取Bean对象

目录 1.第一个Spring项目 2.存储Bean对象 2.1 准备工作 2.2 五大类注解 2.3 方法注解Bean 2.4 Bean对象的默认命名规则 3. 读取Bean对象 3.1 属性注入 3.2 setter注入 3.3 构造方法注入 3.4 注入异常问题 3.5 注入方式优缺点 3.6 Autowired和Resource的区别 1.第一…

python web开发(二):HTML标签语言

文章目录 简介标签语法标题div和span超链接插入图片列表表格Input系列提交表单 参考 简介 如下展示了一段简单的HTML模板&#xff0c; <head></head>标签中主要包含一些基本配置&#xff0c;如编码方式&#xff0c;标题等&#xff0c;注意标题的作用如下图所示 …

【java BUG收集-持续更~】

JAVA BUG JAVA BUGliquibase.lockservice锁异常1、启动参数增加jvm参数 -Dliquibase.lockservicefalse2、修改或清空 包含有 DATABASECHANGELOGLOCK的表 JAVA BUG 该章收集工作中遇到的java bug,作为工作日志&#xff0c;方便回顾。 liquibase.lockservice锁异常 报错信息&a…

Spring Boot实用技巧之单元测试

文章目录 一、单元测试的概念二、单元测试的优势三、Spring Boot实现单元测试&#xff08;一&#xff09;添加依赖&#xff08;二&#xff09;生成单元测试的类&#xff08;三&#xff09; 添加注解和业务代码1. 添加 SpringBootTest 注解2. 添加单元测试的业务代码3. 执行测试…

MySQL部分常用函数总结

数值计算函数 使用方法&#xff1a; ABS&#xff08;x&#xff09; date函数 获取date中对应部分&#xff1a; YEAR(date) 字符串函数 用法举例&#xff1a; 左侧截取字符 SELECT LEFT(‘MySQL’,2); 按符号拆分字符&#xff0c;返回拆分后的部分 SUBSTRING_INDEX(profile,“…

创新洞察 |与众不同的DTC模式:2023年发展趋势将如何影响零售业增长策略?

DTC零售不再局限于数字原生品牌。传统零售商也在采用相同的策略&#xff0c;特别是在后疫情世界中竞争时。预计DTC销售将继续增长&#xff0c;因为更多品牌转向电子商务领域&#xff0c;而已建立的DTC参与者也在扩大其现有市场。预计仅在美国&#xff0c;数字原生品牌将在2023年…

多分类的ROC曲线绘制思路

目录 一、什么是ROC曲线 二、AUC面积 三、代码示例 1、二分类问题 2、多分类问题 一、什么是ROC曲线 我们通常说的ROC曲线的中文全称叫做接收者操作特征曲线&#xff08;receiver operating characteristic curve&#xff09;&#xff0c;也被称为感受性曲线。 该曲线有两…

第四节 Linux 特殊权限SUID、SGID、SBIT

目录 1.Set UID 简称 SUID 2.Set GID 简称 SGID 3.Sticky Bit 简称 SBIT 1.Set UID 简称 SUID 简称 SUID 限制与功能&#xff1a; SUID权限仅对二进制程序有效&#xff1b; 执行者对于该程序需要具有x的执行权限&#xff1b; 本权限仅在执行该程序的过程中有效&#xff1…