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

这篇具有很好参考价值的文章主要介绍了基于DDR3的串口传图帧缓存系统设计实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

整体设计框图如图所示
ddr3 fifo,FPGA,缓存,fpga开发

模块名称 模块功能
uart_byte_rx模块 负责串口图像数据的接收
bit8_trans_bit16模块 将串口接收的每两个 8bit 数据转换成一个 16bit 数据(图像 数据是 16bit 的 RGB565 的数据,电脑是通过串口将一个像素点数据分两次发送到 FPGA, FPGA 需将串口接收数据重组成 16bit 的图像数据),实现过程相对比较简单。
disp_driver模块 tft 屏显示驱动控制,对缓存在 DDR3 中的图像数据进行显示。
wr_ddr3_fifo 模块 使用的 FIFO IP ,主要用于写入 DDR3 数据的缓存、解决数 据跨时钟域以及数据位宽的转换。
rd_ddr3_fifo 模块 使用的 FIFO IP ,主要用于读出 DDR3 数据的缓存、解决数据 跨时钟域以及数据位宽的转换。
fifo2mig_axi 模块 主要是用于接口的转换,将 MIG IP 的 AXI 接口换成与 FIFO对接的接口
mig_7series_0 模块 主要是用于接口的转换,将 MIG IP 的 AXI 接口换成与 FIFO
pll 模块 上述各个模块所需时钟的产生,使用 PLL IP。

1、wr_ddr3_fifo:这个FIFO处于串口接收模块与fifo2mig_axi模块之间,主要是由于两个模块之间时钟和数据传输速率不一致导致需要进行数据缓存。端口数据是 16bit 图像数据,写入时钟采用与串口接收模块相同的工作时钟 50MHz。读端口数据是用于写入到 DDR 存储器,与 DDR 控制器保持一致,数 据位宽使用 128bit,读时钟使用 200MHz 的 ui_clk 时钟。

根据分析,需创建一个独立时钟的 读写数据位宽不一样的 FIFO,具体 FIFO 的相关配置如下图。注意,这里 FIFO 的 Read Mode 需要设置成 First Word Fall Through,写入数据深度暂时设置为 512,根据后面设计情况可进行修改。
ddr3 fifo,FPGA,缓存,fpga开发

ddr3 fifo,FPGA,缓存,fpga开发

2、rd_ddr3_fifo

这个 FIFO 的写入数据是来自从 DDR 存储器读出的数据,而读出的数据 是用于图像显示。所以写端口数据位宽为 128bit,写入时钟使用 MIG IP 输出的 200MHz 的 ui_clk 时钟。读端口数据位宽为 16bit,读时钟使用与 TFT 驱动时钟一致的时钟

3、PLL模块

  1. pll 模块是用于产生整个系统中所需各种时钟,整个系统中主要使用到 3 个时钟,分别 为 DDR 控制器所需 200MHz 时钟串口模块工作的 50MHz 时钟5 寸 TFT 屏驱动模块的 33MHz。ACX720 板卡 FPGA 的输入时钟是 50MHz 的输入时钟。根据分析可知,PLL 模块 的输入时钟是来自外部的 50MHz 晶振时钟,输出时钟为 200MHz、50MHz、33MHz。具体 IP 配置界面如下图,其余界面保持默认即可。

4、fifo2mig_axi模块

fifo2mig_axi 模块是系统中相对比较重要的模块,涉及到与 DDR 控制器接口对接。该模块的主要是实现接口的转换,将普通的 FIFO 接口转换成 AXI 接口,用于将 FIFO 里的数据读出然后存储在 DDR 存储器以及将 DDR 存储器读出的数据存放到 FIFO 缓存。

AXI 接口包括 5 个通道,分为写事务和读事务。考虑模块设计实现的简单性(AXI 协议 支持复杂的乱序读写操作等,这里就不做考虑),

将一次完整的写事务流程规定为

  1. 主机向写地址通道写入地址和控制信息。
  2. 写数据通道突发写入数据。
  3. 收到设备的写数据响应。

一次完整的读事务流程规定为

  1. 主机向读地址通道写入地址和控制信息。
  2. 收到设备的读数据响应和读的数据。

写事务的结构图:
ddr3 fifo,FPGA,缓存,fpga开发

读事务的结构图:

ddr3 fifo,FPGA,缓存,fpga开发

  • 这 5 条独立的通道都包含一个双路的 VALID、READY 握手机制。信息源通过 VALID 信号来指示通道中的数据和控制信息什么时候有效目地源用 READY 信号来表示何时准备好接收数据。传输地址信息和数据都是在 VALID 和 READY 同时为高时有效。
  • 读数据和写数据通道都包括一个 LAST 信号,用来指明一个事物传输的最后一个数据
  • 读/写事务都有自己的地址通道,地址通道携带着传输事务所必须的地址和信息。
  • 读数据通道传送着从设备到主机的读数据和读响应信息。读响应信息指明读事务的完成状态。
  • 写数据通路传送着主机向设备的写数据和写控制信息。写响应通道提供了设备响应写事务的一种方式。在每一次突发式写会产生一个完成信号。

突发读时序图:

ddr3 fifo,FPGA,缓存,fpga开发

主机发送地址和控制信息到写地址通道中

  1. 当地址通道上 ARVALID 和 ARREADY 同时为高时,地址 A 被有效的传给设备,之后设备输出的数据将出现在读数据通道上。

  2. 当 RREADY 和 RVALID 同时为高的时候表明有效的数据传输,从图中可以看到传输了 4 个数 据。

  3. 为了表明一次突发式读写的完成,设备用 RLAST 信号变高电平来表示最后一个被传输 的数据,D(A3)是本次读突发的最后一个读数据。
    ddr3 fifo,FPGA,缓存,fpga开发
    写操作的开始时,主机发送地址和控制信息到写地址通道中:

  4. 当地址通道上 AWVALID 和 AWREADY 同时为高时,地址 A 被有效的传给设备。然后主机发送每一个写数据到写数 据通道中,

  5. 当 WREADY 和 WVALID 同时为高的时候表明一个有效的写数据,

  6. 当主机发送 最后一个数据时,WLAST 信号就变为高。

  7. 当设备接收完所有数据之后,设备将一个写响应 发送回主机来表明写事务完成,当 BVALID 和 BREADY 同时为高的时候表明有效的响应。

对于 DDR 控制器 mig_7series_0 模块,需要初始化结束后即 init_calib_complete为高后,才能进行读/写操作。读/写操作不可同时进行,对读/写操作就需要有一个判断仲裁的过程 fifo2mig_axi 模块状态机设计如下图所示。

ddr3 fifo,FPGA,缓存,fpga开发

上电初始状态为 IDLE 状态,当 DDR 完成初始化和校准(即 init_calib_complete 变为高 电平)后进入读/写仲裁状态 ARB;在该状态根据是否有读/写操作请求跳转到读/写流程的各个状态;完成一次读/写流程后,状态回到 ARB 状态进行下一次的操作。状态机采用三段式,第一二段的代码如下。

always@(posedge ui_clk or posedge ui_clk_sync_rst)begin
	if(ui_clk_sync_rst)
    	curr_state <= S_IDLE;
    else
 		curr_state <= next_state;
end
always@(*)begin
	case(curr_state)
 //具体状态转移见下
    	S_IDLE:begin
            	if(init_calib_complete)
 					next_state = S_ARB;
				else
 					next_state = S_IDLE;
		 end

 	endcase
end
always@(posedge ui_clk or posedge ui_clk_sync_rst)begin
	if(ui_clk_sync_rst)
    	curr_state <= S_IDLE;
    else
 		curr_state <= next_state;
end
always@(*)begin
	case(curr_state)
 //具体状态转移见下
    	S_IDLE:begin
            	if(init_calib_complete)
 					next_state = S_ARB;
				else
 					next_state = S_IDLE;
		 end

 	endcase
end

第三段为

always@(posedge ui_clk or posedge ui_clk_sync_rst)
 begin
 if(ui_clk_sync_rst)
 m_axi_awaddr <= WR_DDR_ADDR_BEGIN;
 else if(wr_addr_clr)
 m_axi_awaddr <= WR_DDR_ADDR_BEGIN;
 else if(m_axi_awaddr >= WR_DDR_ADDR_END)
 m_axi_awaddr <= WR_DDR_ADDR_BEGIN;
 else if((curr_state == S_WR_RESP) && m_axi_bready && m_axi_bvalid && (m_axi_bresp == 2'b00)
&& (m_axi_bid == AXI_ID))
 m_axi_awaddr <= m_axi_awaddr + ((m_axi_awlen + 1'b1)<<4);
 else
 m_axi_awaddr <= m_axi_awaddr;
 end

整体的代码

module fifo2mig_axi
#(
  parameter WR_DDR_ADDR_BEGIN = 0      ,
  parameter WR_DDR_ADDR_END   = 200    ,
  parameter RD_DDR_ADDR_BEGIN = 0      ,
  parameter RD_DDR_ADDR_END   = 200    ,
  
  parameter AXI_ID            = 4'b0000,
  parameter AXI_LEN           = 8'd31    //burst length = 32
)
(
  //FIFO Interface ports
  input               wr_addr_clr         ,//sync ui_clk
  output              wr_fifo_rdreq       ,
  input     [127:0]   wr_fifo_rddata      ,
  input               wr_fifo_empty       ,
  input     [8:0]     wr_fifo_rd_cnt      ,
  input               wr_fifo_rst_busy    ,

  input               rd_addr_clr         ,
  output              rd_fifo_wrreq       ,
  output    [127:0]   rd_fifo_wrdata      ,
  input               rd_fifo_alfull      ,
  input     [8:0]     rd_fifo_wr_cnt      ,
  input               rd_fifo_rst_busy    ,
  // Application interface ports
  input               ui_clk              ,
  input               ui_clk_sync_rst     ,
  input               mmcm_locked         ,
  input               init_calib_complete ,
  // Slave Interface Write Address Ports
  output    [3:0]     m_axi_awid          ,
  output reg[27:0]    m_axi_awaddr        ,
  output    [7:0]     m_axi_awlen         ,
  output    [2:0]     m_axi_awsize        ,
  output    [1:0]     m_axi_awburst       ,
  output    [0:0]     m_axi_awlock        ,
  output    [3:0]     m_axi_awcache       ,
  output    [2:0]     m_axi_awprot        ,
  output    [3:0]     m_axi_awqos         ,
  output reg          m_axi_awvalid       ,
  input               m_axi_awready       ,
  // Slave Interface Write Data Ports
  output    [127:0]   m_axi_wdata         ,
  output    [15:0]    m_axi_wstrb         ,
  output reg          m_axi_wlast         ,
  output reg          m_axi_wvalid        ,
  input               m_axi_wready        ,
  // Slave Interface Write Response Ports
  input     [3:0]     m_axi_bid           ,
  input     [1:0]     m_axi_bresp         ,
  input               m_axi_bvalid        ,
  output              m_axi_bready        ,
  // Slave Interface Read Address Ports
  output    [3:0]     m_axi_arid          ,
  output reg[27:0]    m_axi_araddr        ,
  output    [7:0]     m_axi_arlen         ,
  output    [2:0]     m_axi_arsize        ,
  output    [1:0]     m_axi_arburst       ,
  output    [0:0]     m_axi_arlock        ,
  output    [3:0]     m_axi_arcache       ,
  output    [2:0]     m_axi_arprot        ,
  output    [3:0]     m_axi_arqos         ,
  output reg          m_axi_arvalid       ,
  input               m_axi_arready       ,
  // Slave Interface Read Data Ports
  input     [3:0]     m_axi_rid           ,
  input     [127:0]   m_axi_rdata         ,
  input     [1:0]     m_axi_rresp         ,
  input               m_axi_rlast         ,
  input               m_axi_rvalid        ,
  output              m_axi_rready        
);

  localparam S_IDLE    = 7'b0000001,
             S_ARB     = 7'b0000010,
             S_WR_ADDR = 7'b0000100,
             S_WR_DATA = 7'b0001000,
             S_WR_RESP = 7'b0010000,
             S_RD_ADDR = 7'b0100000,
             S_RD_RESP = 7'b1000000;

  wire[7:0]wr_req_cnt_thresh;
  wire[7:0]rd_req_cnt_thresh;
  wire     wr_ddr3_req ;
  wire     rd_ddr3_req ;
  reg [6:0]curr_state  ;
  reg [6:0]next_state  ;
  reg      wr_rd_poll  ;  //0:allow wr  1:allow rd
  reg [7:0]wr_data_cnt ;

  assign m_axi_awid    = AXI_ID   ; //output [3:0]      m_axi_awid   
  assign m_axi_awsize  = 3'b100   ; //output [2:0]      m_axi_awsize 
  assign m_axi_awburst = 2'b01    ; //output [1:0]      m_axi_awburst
  assign m_axi_awlock  = 1'b0     ; //output [0:0]      m_axi_awlock 
  assign m_axi_awcache = 4'b0000  ; //output [3:0]      m_axi_awcache
  assign m_axi_awprot  = 3'b000   ; //output [2:0]      m_axi_awprot 
  assign m_axi_awqos   = 4'b0000  ; //output [3:0]      m_axi_awqos    
  assign m_axi_awlen   = AXI_LEN  ;
  
  assign m_axi_wstrb   = 16'hffff ; //output [15:0]     m_axi_wstrb 
  assign m_axi_wdata   = wr_fifo_rddata;

  assign m_axi_bready  = 1'b1     ; //output            m_axi_bready

  assign m_axi_arid    = AXI_ID   ; //output [3:0]      m_axi_arid   
  assign m_axi_arsize  = 3'b100   ; //output [2:0]      m_axi_arsize 
  assign m_axi_arburst = 2'b01    ; //output [1:0]      m_axi_arburst
  assign m_axi_arlock  = 1'b0     ; //output [0:0]      m_axi_arlock 
  assign m_axi_arcache = 4'b0000  ; //output [3:0]      m_axi_arcache
  assign m_axi_arprot  = 3'b000   ; //output [2:0]      m_axi_arprot 
  assign m_axi_arqos   = 4'b0000  ; //output [3:0]      m_axi_arqos
  assign m_axi_arlen   = AXI_LEN  ;

  assign m_axi_rready  = ~rd_fifo_alfull; //output            m_axi_rready

  assign wr_fifo_rdreq  = m_axi_wvalid && m_axi_wready;
  assign rd_fifo_wrreq  = m_axi_rvalid && m_axi_rready;
  assign rd_fifo_wrdata = m_axi_rdata;  

  assign wr_req_cnt_thresh = (m_axi_awlen == 1'b0)? 1'b0 : AXI_LEN-1'b1;
  assign rd_req_cnt_thresh = AXI_LEN;
  assign wr_ddr3_req = (wr_fifo_rst_busy == 1'b0) && (wr_fifo_rd_cnt >= wr_req_cnt_thresh) ? 1'b1:1'b0;
  assign rd_ddr3_req = (rd_fifo_rst_busy == 1'b0) && (rd_fifo_wr_cnt <= rd_req_cnt_thresh) ? 1'b1:1'b0;
  
//**********************************
//三段式状态机
//**********************************

//第一段状态机**同步电路 描述状态转移
always@(posedge ui_clk or posedge ui_clk_sync_rst)begin
    if(ui_clk_sync_rst)
        curr_state <= S_IDLE;
    else
        curr_state <= next_state;
end
//第二段状态机**组合逻辑电路 判断状态转移
always@(*)begin
    case(curr_state)
    
        // 状态机在上电复位处于初始状态 IDLE,当 DDR 完成初始化和校准后进入读/写仲裁状态 ARB
        S_IDLE:begin
            if(mmcm_locked && init_calib_complete)
                next_state = S_ARB;
            else
                next_state = S_IDLE;
        end
        
        // 在读/写仲裁状态 ARB,根据当前的读/写请求跳转到读/写操作流程中的地址通道的操作。
        S_ARB:begin
            if((wr_ddr3_req == 1'b1) && (wr_rd_poll == 1'b0))
                next_state = S_WR_ADDR;
            else if((rd_ddr3_req == 1'b1) && (wr_rd_poll == 1'b1))
                next_state = S_RD_ADDR;
            else
                next_state = S_ARB;
        end
        
        //当在 ARB 状态出现写操作请求后,进入到 AXI 写地址通道的操作状态 S_WR_ADDR,
        //在该状态,传输写操作的地址和控制信息,当 awready 和 awvalid 同时为高时表明地址已经
        //传输完成,进入到写操作的写数据通道的操作。
        S_WR_ADDR:begin
            if(m_axi_awready && m_axi_awvalid)
                next_state = S_WR_DATA;
            else
                next_state = S_WR_ADDR;
        end

        //当主机写完最后一个数据后 m_axi_wlast 置高,进入等待写相应的状态。
        S_WR_DATA:begin
            if(m_axi_wready && m_axi_wvalid && m_axi_wlast)
                next_state = S_WR_RESP;
            else
                next_state = S_WR_DATA;
        end

        //在等待写响应状态,当主机接收到设备的写响应后,一次完整的写操作流程完成,状态
        //回到仲裁状态进行下一次的操作,bresp 不同值表示不同的响应结果,bresp 为 2’b00 表示写
        //数据成功,bid 需要与写地址通道传输的 awbid 一致。
        S_WR_RESP:begin
            if(m_axi_bready && m_axi_bvalid && (m_axi_bresp == 2'b00) && (m_axi_bid == AXI_ID))
                next_state = S_ARB;
            else if(m_axi_bready && m_axi_bvalid)
                next_state = S_IDLE;
            else
                next_state = S_WR_RESP;
        end

        S_RD_ADDR:begin
            if(m_axi_arready && m_axi_arvalid)
                next_state = S_RD_RESP;
            else
                next_state = S_RD_ADDR;
        end

        S_RD_RESP:begin
            if(m_axi_rready && m_axi_rvalid && m_axi_rlast && (m_axi_rresp == 2'b00) && (m_axi_rid == AXI_ID))
                next_state = S_ARB;
            else if(m_axi_rready && m_axi_rvalid && m_axi_rlast)
                next_state = S_IDLE;
            else
                next_state = S_RD_RESP;
        end

        default: next_state = S_IDLE;
    endcase
  end

状态机设计完成后,剩下的就是在各个状态中产生各种信号。

写操作的写地址通道比较关键的是产生 awaddrawvalid。其中,awaddr 除了在复位和清除时变为起始地址外,在完成一次写操作流程后,地址就需要增加一次突发写入的数据 量,需要注意的是这里的地址是以字节为单位的,则每次地址增加量应该是突发写数据个数 ×每个数据的字节数。这里每次突发长读为 AWLEN 加 1,每个数据是 16 字节(数据位宽是 128bit),所以每完成一次写操作,地址增加(m_axi_awlen + 1’b1)*16。

这里 AXI 地址对应的数据是以 1 字节进行计算的,不要与 DDR3 的地址和存储数据混淆。板载 DDR3 存储器存储空间 2Gbit(2Gbit = 256MByte = 2^28 Byte,所以 AXI 的地址位宽为 28)。

  always@(posedge ui_clk or posedge ui_clk_sync_rst)
  begin
    if(ui_clk_sync_rst)
      m_axi_araddr <= RD_DDR_ADDR_BEGIN;
    else if(rd_addr_clr)
      m_axi_araddr <= RD_DDR_ADDR_BEGIN;
    else if(m_axi_araddr >= RD_DDR_ADDR_END)
      m_axi_araddr <= RD_DDR_ADDR_BEGIN;
    else if((curr_state == S_RD_RESP) && m_axi_rready && m_axi_rvalid && m_axi_rlast && (m_axi_rresp == 2'b00) && (m_axi_rid == AXI_ID))
      m_axi_araddr <= m_axi_araddr + ((m_axi_awlen + 1'b1)<<4);
    else
      m_axi_araddr <= m_axi_araddr;
  end

对于 awvalid ,在进入 WR_ADDR 状态到就将其输出为高等到 awready 和 awvalid 同时高的时候,就将 awvalid 输出为低,保证 awready 和 awvalid 信号只 有一个时钟周期的同时高。

  always@(posedge ui_clk or posedge ui_clk_sync_rst)
  begin
    if(ui_clk_sync_rst)
      m_axi_arvalid <= 1'b0;
    else if((curr_state == S_RD_ADDR) && m_axi_arready && m_axi_arvalid)
      m_axi_arvalid <= 1'b0;
    else if(curr_state == S_RD_ADDR)
      m_axi_arvalid <= 1'b1;
    else
      m_axi_arvalid <= m_axi_arvalid;
  end

在写操作的写数据通道比较关键的是产生 wvalid 和 wlast 信号。wvalid 在进入到 WR_DATA 状态就变为高电平,在发送完最后一个数据后变为低电平。(期间,在主机给出 的 wvalid 与设备给出的 wready 信号同时为高的情况下,数据写入到设备)

  always@(posedge ui_clk or posedge ui_clk_sync_rst)
  begin
    if(ui_clk_sync_rst)
      m_axi_wvalid <= 1'b0;
    else if((curr_state == S_WR_DATA) && m_axi_wready && m_axi_wvalid && m_axi_wlast)
      m_axi_wvalid <= 1'b0;
    else if(curr_state == S_WR_DATA)
      m_axi_wvalid <= 1'b1;
    else
      m_axi_wvalid <= m_axi_wvalid;
  end

对于wlast信号是主机向设备传输最后一个数据的标识信号,这个信号的产生依赖于一次突发写入数据个数和当前已经传输了几个数据,主机在传输最后一个数据同时将其输出为高,在发送完最后一个数据后立马将其输出为低。

这个过程首先需要对传输数据个数进行计数, 当 wready 和 m_axi_wvalid 同时为高时代表传输一个数据,传输数据个数计数器代码如下。

在产生 wlast 时,分两种情况:
一、是当突发写数据个数为 1,也就是 wlen 等于 0 时,那 么传输的第一个数就是传输的最后一个数据,这种情况下,一进入到 WR_DATA 状态就将 wlast 变为高电平;
二、当突发写数据个数大于 1,也就是 wlen 等于等于 1 时,就在传输完 倒数第二个数(即 wr_data_cnt 为 m_axi_awlen -1’b1)后将 wlast 变为高电平。当最后一个 数据传输完成(m_axi_wready、m_axi_wvalid 和 m_axi_wlast 同时为高电平)后将 wlast 变 为低,(比如突发长度为4,那么判断为3-1=2)具体代码如下。

  //wr_data_cnt
  always@(posedge ui_clk or posedge ui_clk_sync_rst)
  begin
    if(ui_clk_sync_rst)
      wr_data_cnt <= 1'b0;
    else if(curr_state == S_ARB)
      wr_data_cnt <= 1'b0;
    else if(curr_state == S_WR_DATA && m_axi_wready && m_axi_wvalid)
      wr_data_cnt <= wr_data_cnt + 1'b1;
    else
      wr_data_cnt <= wr_data_cnt;
  end

  //m_axi_wlast
  always@(posedge ui_clk or posedge ui_clk_sync_rst)
  begin
    if(ui_clk_sync_rst)
      m_axi_wlast <= 1'b0;
    else if(curr_state == S_WR_DATA && m_axi_wready && m_axi_wvalid && m_axi_wlast)
      m_axi_wlast <= 1'b0;
    else if(curr_state == S_WR_DATA && m_axi_awlen == 8'd0)
      m_axi_wlast <= 1'b1;
    else if(curr_state == S_WR_DATA && m_axi_wready && m_axi_wvalid && (wr_data_cnt == m_axi_awlen -1'b1))
      m_axi_wlast <= 1'b1;
    else
      m_axi_wlast <= m_axi_wlast;
  end

控制状态机条状的读写 DDR 请求信号是根据当前 FIFO 中数据量进行判断产生,当写 FIFO 中的数据量超过一个阈值(这里阈值使用 WLEN,)就产生写 DDR 请求;当读 FIFO 中的数据量低于一个阈值(这里阈值使用 RLEN,也可以设置为其他值)就产生读 DDR 请 求,信号产生需要满足在 DDR 初始化完成之后并且当前 FIFO 不处于复位。

fifo2mip_axi模块仿真

仿真1如下图所示
可以看到当初始化校准完成后(init_calib_complete变高)DDR3向rdfifo写入了一些数据(错误的),读数据之前先对 rd_ddr3_fifo 进行一次复位清空缓存的操作(rd_clr),同时对把 DDR 的地址也复位到起始地址。
ddr3 fifo,FPGA,缓存,fpga开发
仿真2是DDR3的AXI突发写事务:
往wrfifo里写1024个数据(16bit),AXI总线上发生了4次突发写事务,每次突发写是32个数据(位宽128bit,32位是设置的)。
可以看到一次AXI突发写的流程为:

  1. 在地址通道写入接下来要写入数据的起始地址和写突发长度等信息,在 awready和 awvalid 同时为高时,这些信息被传输给 DDR 控制器;
  2. 在写数据通道写入指定突发长度的数据,当 wready 和 wvalid 同时为高时表示写入数据被传输给 DDR 控制器,在写最后一个数据时,wlast 变为高,写完最后一个 wlast 变为低;
  3. 在写响应通道等待设备的写响应,当 bready 和 bvalid 同时为高时表示响应的到来。

ddr3 fifo,FPGA,缓存,fpga开发
仿真3:AXI突发读事务的时序文章来源地址https://www.toymoban.com/news/detail-656017.html

到了这里,关于基于DDR3的串口传图帧缓存系统设计实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA实战开发-基于的ddr图像缓存设计(上)

    目录 概要 整体架构流程 技术名词解释 技术细节 ​编辑 小结 提示:这里可以添加技术概要 本文主要基于DDR的图像缓存设计。 提示:这里可以添加技术整体架构 先用图像产生模块产生一个1080P60Hz的测试图像,然后经过FDMA进入ddr3,缓存3帧后在读出来。然后在经过HDMI显示。

    2024年02月08日
    浏览(60)
  • 基于紫光同创 FPGA 的 DDR3 读写实验

    此篇为专栏 《紫光同创FPGA开发笔记》 的第二篇,记录我的学习FPGA的一些开发过程和心得感悟,刚接触FPGA的朋友们可以先去此专栏置顶 《FPGA零基础入门学习路线》来做最基础的扫盲。 本篇内容基于笔者实际开发过程和正点原子资料撰写,将会详细讲解此 FPGA 实验的全流程

    2024年01月20日
    浏览(48)
  • Linux系统中DDR3硬件初始化实验

           大家好,我是ST。        今天的话,主要和大家聊一聊,如何使用Cortex-A芯片自带的RAM,很多时候要运行Linux的话是完全不够用的,必须要外接一片RAM芯片,驱动开发板上的DDR3。 目录 第一:何为RAM和ROM 第二:DDR初始化与测试 第三:DDR框架图基本分析            

    2024年02月12日
    浏览(41)
  • FPGA-基于AXI4接口的DDR3读写顶层模块

    AXI4(Advancede Xtensible Interface 4)是一种高性能、高带宽的总线接口协议,用于在系统级芯片设计中连接不同的IP核(Intellectual Property)或模块。它是由ARM公司开发的,被广泛应用于各种SoC(System-on-Chip)设计中。 AXI4接口协议定义了一组规范,用于描述数据传输、地址传输、控

    2024年04月15日
    浏览(54)
  • 基于 A7 的 DDR3 SDRAM IP 核使用(二)初始化篇

    前言 :在前文简单介绍了MIG ip核的调用(包括某些参数的设置)以及该ip核的架构。那么接下来可以开始使用ip核了吗?NO!!! 注意 :在调完ip之后,并不可以立即使用该 IP 核完成 DDR3 SDRAM 的读和写的,而是要在该 IP核初始化成功之后 ,才可以进行读和写的。 可以通过 Models

    2024年02月04日
    浏览(31)
  • AX7A200教程(5): 基于DDR3的串口发送和接收

    本章节主要使用ddr3做为缓存,串口接收的数据通过ddr缓存后通过发送模块发送出去。整体的功能框图所下图所示 串口接收到8位数据后,将4个8位数据合并为一个32位数据写入到写fifo,当写入8个32位数据后,也就是一共256位宽数据,这时会发出一个突发写使能信号 wr_len_en ,将

    2023年04月16日
    浏览(33)
  • 基于fpga的ddr3读写控制,纯verilog实现,能实现多通道图像数据读写控制

    基于fpga的ddr3读写控制,纯verilog实现,能实现多通道图像数据读写控制,模块接口清晰,可移植性高. 基于FPGA的DDR3读写控制是一项重要的技术,它为多通道图像数据的读写提供了高效的解决方案。本文将介绍一种纯Verilog实现的DDR3读写控制模块,旨在实现模块接口清晰、可移

    2024年04月12日
    浏览(55)
  • AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

    本章节主要使用ddr3做为缓存,串口接收的数据通过ddr缓存后通过发送模块发送出去。整体的功能框图所下图所示 串口接收到8位数据后,将4个8位数据合并为一个32位数据写入到写fifo,当写入8个32位数据后,也就是一共256位宽数据,这时会发出一个突发写使能信号 wr_len_en ,将

    2024年02月03日
    浏览(61)
  • DDR3和DDR4内存有什么区别?DDR3和DDR4的区别

    开机之后,系统会存入内存,打开软件,也会在内存存储,可以说内存就是临时数据仓库,内存的性能对计算机的影响非常大。而内存的发展比较缓慢,现如今用的还是DDR3和DDR4居多。 DDR3内存诞生于2007年 ,DDR4在2014年底纷纷上架,当前,DDR4是主流。有何区别?   一、在外形

    2024年02月11日
    浏览(45)
  • DDR3读写模块

    使用xilinx官方提供的MIG IP核进行设计,接口协议为AXI,关于AXI协议的内容此处不做过多介绍。 关于IP核个参数的介绍可以参考野火教程,以下为目前使用的通用配置。 DDR物理接口的位宽为32bit DDR用户接口的位宽为64bit MIG核的XADC是关闭的,需要外部模块例化XADC模块读取FPGA的内

    2024年02月03日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包