AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

这篇具有很好参考价值的文章主要介绍了AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本章节主要使用ddr3做为缓存,串口接收的数据通过ddr缓存后通过发送模块发送出去。整体的功能框图所下图所示

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

写通道

串口接收到8位数据后,将4个8位数据合并为一个32位数据写入到写fifo,当写入8个32位数据后,也就是一共256位宽数据,这时会发出一个突发写使能信号wr_len_en,将256位数据写入到ddr3中存储(rd_data_count = 9'd1表示写fifo已经写入一个256位宽数据

    //突发写使能
    always@(posedge ui_clk or negedge i_rst_n)begin
            if(!i_rst_n)
                wr_len_en    <=  1'd0;    
            else if(ddr_wr_end)
                wr_len_en    <=  1'd0;    
            else if(rd_len_en)
                wr_len_en    <=  1'd0;    
            else if(wr_len_done)
                wr_len_en    <=  1'd0;                             
            else if(rd_data_count >= 9'd1)
                wr_len_en    <=  1'd1;                        
    end
AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

读通道

当写fifo写入256数据后,并且突发写完成(wr_len_done为突发写完成信号),这时会产生一个突发读使能信号rd_len_en,将ddr3中的256位宽数据读出写入到读fifo中

    always@(posedge ui_clk or negedge i_rst_n)begin
            if(!i_rst_n)
                wr_len_done_r   <=  1'b0;
            else 
                wr_len_done_r   <=  wr_len_done;
    end                    
    
    //突发读使能
    always@(posedge ui_clk or negedge i_rst_n)begin
            if(!i_rst_n)
                rd_len_en    <=  1'd0;
            else if(ddr_rd_end)
                rd_len_en    <=  1'd0;            
            else if(wr_len_en)
                rd_len_en    <=  1'd0;     
            else if(rd_len_done)
                rd_len_en    <=  1'd0;                 
            else if(wr_len_done_r)
                rd_len_en    <=  1'd1;                     
    end 

当tx_data_convert模块检测读fifo的read_fifo_empty为0时,也就是读fifo有数据时,会产生一个read_en读使能信号,读出读fifo的数据,每次都是读一个32位数据read_dout

always@(posedge i_clk or negedge i_rst_n)begin
        if(!i_rst_n)
            read_data   <=  32'd0;
        else if(count == 4 )
            read_data   <=  32'd0;    
        else if(read_en)
            read_data   <=  read_dout;
        else
            read_data   <=  read_data;    
end
always@(posedge i_clk or negedge i_rst_n)begin
        if(!i_rst_n)begin
            read_en  <=  1'd0;
            read_en_flag  <=  1'd0;
            end
        else if(count == 4 )begin
            read_en  <=  1'd0;
            read_en_flag  <=  1'd0;
            end    
        else if(read_en_flag)
            read_en  <=  1'd0;    
        else if(!read_fifo_empty)begin 
            read_en  <=  1'd1;
            read_en_flag  <=  1'd1;
            end
        else
            read_en  <=  1'd0;        
end

最后tx_data_conver模块会将读出32位数据转换为4个8位数据,并且通过uart_tx发送出去

always@(posedge i_clk or negedge i_rst_n)begin
        if(!i_rst_n)
            tx_data  <=  8'd0;
        else case(count)
            0: tx_data  <=  read_data[31:24];
            1: tx_data  <=  read_data[23:16];
            2: tx_data  <=  read_data[15:8];
            3: tx_data  <=  read_data[7:0];
            default:tx_data <= tx_data;
            endcase
end
uart_tx uart_tx_inst(
    . sclk      (clk_50M),
    . s_rst_n   (rst_n),
    // UART Interface
    . rs232_tx  (rs232_tx),
    . tx_flag   (tx_flag),
    . tx_done   (tx_done),
    // others
    . tx_trig   (tx_trig),//tx_trig
    . tx_data   (tx_data)//tx_data
    
    )
AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

将开发板上电,连接串口

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

因ddr3突发一次是256位宽,也就是32个8位数据,所以一次发32个8位数据开发板接收后才会将接收到的数据发送出来。

串口未发送任何数据

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

串口发送32个8位数据,可以看到发送的和接收的数据是一致的

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

点重复发送,看下效果,发送和接收的数据一致并且数量一样

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

重复发送后,可以看到,当数据接收到2048就停止了

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

为什么接收到2048就停止了,打开程序发现我们设置ddr最大的读写地址为512,每次都是突发8个32位256位宽数据,设置为512表示一共计数512个32位宽的数据,换算一下就是2048个8位数据刚好和接收停止的一致

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

所以我们这里需要对ddr的读写地址进行清零,才能再次接收,这里使用ddr读写完成信号ddr_wr_end和ddr_rd_end产生vin_vs和vout_vs信号,发出wr_reset和rd_reset对地址进行清零

always@(posedge ui_clk or negedge rst_n)begin
        if(!rst_n)
            wr_load_r   <=  1'd0;
        else 
            wr_load_r   <=  {wr_load_r[14:0],vin_vs};
end 

always @(posedge ui_clk or negedge rst_n) begin
         if(!rst_n)
             wr_page    <=  3'd0;
         //else if(wr_load_r[0] && !wr_load_r[14])
             //wr_page    <=  wr_page + 1'b1;
end
      
always@(posedge ui_clk or negedge rst_n)begin
        if(!rst_n)
            wr_reset   <=  1'd0;
        else if(wr_load_r[0] && !wr_load_r[14])
            wr_reset   <=  1'd1;
        else if(app_addr_wr == 0 && !(wr_load_r[0] && !wr_load_r[14]))    
            wr_reset   <=  1'd0;
end
always@(posedge ui_clk or negedge rst_n)begin
        if(!rst_n)
            rd_load_r   <=  1'd0;
        else 
            rd_load_r   <=  {rd_load_r[14:0],vout_vs};
end

always @(posedge ui_clk or negedge rst_n) begin
         if(!rst_n)
             rd_page    <=  3'd0;
         //else if(rd_load_r[0] && !rd_load_r[14])
             //rd_page    <=  wr_page - 1'b1;
end 
       
always@(posedge ui_clk or negedge rst_n)begin
        if(!rst_n)
            rd_reset   <=  1'd0;
        else if(rd_load_r[0] && !rd_load_r[14])
            rd_reset   <=  1'd1;
        else if(app_addr_rd == 0 && !(rd_load_r[0] && !rd_load_r[14]))    
            rd_reset   <=  1'd0;
end 
AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)
AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

重新编译工程,将程序下载开发板,重复发送,可以看到发送和接收都是一致的

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

整个工程文件较多,所以不贴代码了

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

ddr3的简单用法就写到这里,如果有不懂的可以直接下载工程进行仿真测试

链接:https://pan.baidu.com/s/1TOrTU7i1RpgEXw-igxiL1A

提取码:2x12

ddr读写需要大家理解读写突发的基本概念,如果基本的读写突发能够理解,基本这个工程也能完全的看懂,这个uart工程每次只进行一次突发传输,所以还是比较好理解的

从评论可以看到64个32位宽数据和128个32位宽数据出现问题,通过仿真发现如果设置为64个32位数据也就是两个突发长度确实会出现问题

2次突发更改的地方

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)
AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

仿真到1个突发长度

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

rd_data_count计数器确实是1

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

第二个突发长度

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

rd_data_count计数器还是1,并不是我们期望的2,所以无法产生突发写命令

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

从官方的fifo仿真波形来,前面三次写的数据都会出现rd_data_count计数器保持为1的情况

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

直到第四fifo读写数据才开始是正常的计数相加

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

将上面总结一下,按照两次突发,可以看出fifo计数rd_data_count前三次都是值为1保持不变,只在第四次开始正常的相加,也就是第四次才能产生一个rd_data_count等于2,并且产生一次写突发,既然四次才能产生一次写突发并且同时产生读突发,那么我们直接一次写入四个突发长度,也就是4个256位数据,一共128个8位数据,因四个突发长度只能产生一次写突发,所以只能打印出前面2个突发长度的数据

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

从上图可以看出发送了4个突发长度数据,按照程序来看确实打印了64个8位数据,也就是一次2个突发长度的数据,还有第二次的2个突发长度数据没有出来,也就是41~80这部分数据没有出来,因fifo后面的数据突发都是正常的,所以我们再发送一次2个突发长度数据,将41~80这部分数据给挤出来,为了区别,这次发送的2个突发长度都是设置为一样的数据

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

按照程序成功的将第二次的fifo里面的数据挤出来了,正常打印了41~80的数据,我们再次发送2个突发长度的数据将将这次发送相同的01数据都给打印出来

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

从上面可以看出来数据是连续的并且是完整的,对于ddr这个fifo虽然前面几次突发有这样的问题,但整体的数据完整性是没有问题,再发送依然是将上次的挤出来了

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

那有没有办法可以解决这样的两次突发都正常,可以使用写fifo中的wr_data_count做为计数

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

下面的截图执行了两次突发,可以看到每次突发都是wr_data_count都是0~8,可以每次等于8就计数器加一,执行两次突发会出现两个8也就相当于计数为2,可以直接触发突发写,这样可以避免出现rd_data_count前面三次突发出现一直保持为1的情况,当然如果是摄像头类的大量数据还是建议使用rd_data_count这种方式,这种方法大家可以尝试一下

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

因2次突发读写和4次突发读写是一样的,所以这里不再继续测试4次突发读写,大家有兴趣可以尝试一下

因有人在下面评论串口接收后,发送会不会速度跟不上,所以将工程又改了一下

突发长度不变

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

突发写使能不变

    //突发写使能
    always@(posedge ui_clk or negedge i_rst_n)begin
            if(!i_rst_n)
                wr_len_en    <=  1'd0;    
            else if(ddr_wr_end)
                wr_len_en    <=  1'd0;    
            else if(rd_len_en)
                wr_len_en    <=  1'd0;    
            else if(wr_len_done)
                wr_len_en    <=  1'd0;                             
            else if(rd_data_count >= 9'd1)
                wr_len_en    <=  1'd1;                        
    end  

突发读变为突发写结束后,才开始进行突发读并且通过串口打印输出,也就是接收完成所有数据后,再通过串口打印输出。其中ddr_wr_end为ddr写完成信号,ddr的最大地址设置为256,说明一共传输256个32位数据,也就是1024个8位就会拉高ddr_wr_end信号,并且会触发ddr读突发,将写入到ddr里面的数据通过串口都打印出来

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)
    //突发读使能
    always@(posedge ui_clk or negedge i_rst_n)begin
            if(!i_rst_n)
                rd_len_en    <=  1'd0;
            else if(ddr_rd_end)
                rd_len_en    <=  1'd0;            
            else if(wr_len_en)
                rd_len_en    <=  1'd0;     
            else if(rd_len_done)
                rd_len_en    <=  1'd0;                 
            else if(ddr_wr_end && wr_data_count <= 9'd1)
                rd_len_en    <=  1'd1;                     
    end   

串口准备1024个8位数据

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

发送数据,发送和接收都是正常的,并且数据量是一样的

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

从ila可以看到,wr_len_en为写突发最后一次突发传输,传输完成后立马产生ddr_wr_en写完成信号,并且产生了突发读使能rd_len_en一共进行了8次突发读

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

同样再次测试也可以抓到最后一次突发读rd_len_en,并且产生ddr_rd_end结束信号

AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)

工程链接:https://pan.baidu.com/s/1PWE1cw9OlI9Zgvz-kj6MDw

提取码:czez文章来源地址https://www.toymoban.com/news/detail-437590.html

到了这里,关于AX7A200教程(5): 基于DDR3的串口发送和接收(一次突发)(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 基于紫光同创 FPGA 的 DDR3 读写实验

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

    2024年01月20日
    浏览(41)
  • 基于DDR3的串口传图帧缓存系统设计实现

    整体设计框图如图所示 模块名称 模块功能 uart_byte_rx模块 负责串口图像数据的接收 bit8_trans_bit16模块 将串口接收的每两个 8bit 数据转换成一个 16bit 数据(图像 数据是 16bit 的 RGB565 的数据,电脑是通过串口将一个像素点数据分两次发送到 FPGA, FPGA 需将串口接收数据重组成

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

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

    2024年04月15日
    浏览(42)
  • 超详细的FPGA使用MIG调用SODIMM DDR3内存条接口教程

    SODIMM 接口DDR3适配额外的内存条才能满足数据缓存的需求,这种需求一般用于高端项目,DDR3 SDRAM 常简称 DDR3, 是当今较为常见的一种储存器, 在计算机及嵌入式产品中得到广泛应用,特别是应用在涉及到大量数据交互的场合。 本文以XC7K325T-FFG900-2L为例,记录MIG的配置过程,

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

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

    2024年02月04日
    浏览(25)
  • 基于 DDR3 的native接口串口传图帧缓存系统设计实现(整体设计)

    DDR系列文章分类地址: (1)DDR3 基础知识分享 (2)DDR3 控制器 MIG IP 详解完整版 (AXI4VivadoVerilog) (3)DDR3 控制器 MIG IP 详解完整版 (nativeVivadoVerilog) (4)基于 DDR3 的串口传图帧缓存系统设计实现 (5)基于 DDR3 的native接口串口局部传图缓存系统设计实现 (6)基于 DDR3 的

    2024年02月13日
    浏览(39)
  • 基于fpga的ddr3读写控制,纯verilog实现,能实现多通道图像数据读写控制

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

    2024年04月12日
    浏览(48)
  • DDR3和DDR4内存有什么区别?DDR3和DDR4的区别

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

    2024年02月11日
    浏览(35)
  • Xilinx FPGA DDR3设计(三)DDR3 IP核详解及读写测试

    引言 :本文我们介绍下Xilinx DDR3 IP核的重要架构、IP核信号管脚定义、读写操作时序、IP核详细配置以及简单的读写测试。 7系列FPGA DDR接口解决方案如图1所示。 图1、7系列FPGA DDR3解决方案 1.1 用户FPGA逻辑(User FPGA Logic) 如图1中①所示,用户FPGA逻辑块是任何需要连接到外部

    2024年02月06日
    浏览(41)
  • DDR3读写模块

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

    2024年02月03日
    浏览(41)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包