ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

转载 PCIe学习(三):PCIe DMA关键模块分析之二

2019-09-02 14:02:07  阅读:628  来源: 互联网

标签:DMA 标头 BMD 之二 发送 PCIe TLP 64


原文链接:https://blog.csdn.net/cllovexyh/article/details/79855813

简介
    这是学习PCIe DMA传输的第二篇博客,在前一篇中叙述了PCIe DMA传输的部分基础知识,并且较为详细的分析了接收引擎的各个状态,这里接着分析第二个关键模块:发送引擎(BMD_64_TX_ENGINE.v)。
    软件:VIVADO2017.4
第一步:模块功能分析
    在分析发送引擎的具体操作之前,需要多这个模块实现的功能进行简单的分析。如下是发送引擎中的标头类型
这里写图片描述
    由图可知,这个模块包含5种类型的标头,这里先简单的说明这几种标头的应用场景,BMD_64_CPLD_FMT_TYPE 标志着发送一个带数据的完成包,这个使用在PC端向FPGA发送一个存储器读请求后,FPGA通过这个报文将存储器信息返回到PC端,这是PIO模式;
    BMD_64_MWR_FMT_TYPEBMD_64_MWR64_FMT_TYPE标志着FPGA发送存储器写请求TLPs,这个使用在启动DMA写时,发送引擎组建存储器写请求包将数据发送到PC上;
    BMD_64_MRD_FMT_TYPEBMD_64_MRD64_FMT_TYPE标志着FPGA发送存储读请求TLPs,这个使用在PC配置启动DMA读时,发送引擎组建存储器读请求包,PC发送带数据的完成包到FPGA上,被接收引擎接收(上一篇博客中分析的带数据的完成包)。
    以上就是几种标头的应用场景,了解清楚这些对分析发送引擎的结构很有帮助。接下来就开始分析发送引擎。
第二步:具体代码分析
    观察状态机跳转
这里写图片描述
    首先进入复位状态BMD_64_TX_RST_STATE,这个状态中有多个判断条件,包含发送完成包、DMA读操作和DMA写操作,接下来就逐个分析。
这里写图片描述
    1、假设首先发送完成包。设置compl_done_o 为0,表示完成包未发送完成,这个信号会进入接收引擎来判断PC发送的存储器读请求是否完成。然后是条件判断,req_compl_q 是从接收引擎引入的信号,其目的是让发送引擎发送完成包;compl_done_o 是上文说的完成包是否发送完成标志信号;trn_tdst_rdy_n 是从机是否准备好接收数据标志信号,此时是FPGA发送数据给PC,所以PC是从机,这个信号表示PC端是否准备好接收数据;trn_tdst_dsc_n 这个信号在FPGA上被置1了。
    设置帧开始信号(trn_tsof_n)有效、帧结束信号(trn_teof_n)无效、主机准备好发送数据(trn_tsrc_rdy_n)之后,就开始组装完成包头;组装的信息来自接收引擎和PCIe IP核,这就完成了发送完成包标头的前2DW。跳转到下一状态。
这里写图片描述
    由于完成包是3DW标头,所以在这个状态中发送1DW标头+1DW数据。
    首先判断从机是否准备好接收数据,准备好后设置帧起始无效,由于这是PIO模式,因此只有两帧,所以这是最后一帧,设置帧结束有效,接着设置主机准备好发送数据,然后发送第二帧(1DW标头+1DW数据),然后设置trn_trem_n 有效,表明这一帧数据都有效,然后compl_done_o 表示完成包发送完成,状态跳转到BMD_64_TX_CPLD_WIT
这里写图片描述
    这个状态中设置关键的4个信号无效,然后跳转到复位状态,准备下一次传输。
    2、假设进入DMA写存储器操作,
这里写图片描述
    首先判断是否启动DMA写操作、DMA写操作完成等信号,其中serv_mwr 信号是用轮询操作控制DMA写操作的进行。接着和上面完成报文传输的格式差不多,trn_trem_n为0表示这一帧的两个DW都有效,cur_mwr_dw_count表示这一个TLP中数据的数量(单位DW),拼接发送第一帧数据,即2DW标头。接着就进入轮询操作。
这里写图片描述
    轮询操作的目的是在发送一段时间的存储器写TLP之后,停止一次,然后判断此时是否有DMA读存储器开始信号,如果有的话就去执行DMA读操作,否则就是停止一次传输,下一个周期开始又继续DMA写操作。其中tmwr_wrr_cnt 信号统计发送TLP的数量,而mwr_wrr_cnt_i 信号则是设定轮询操作的TLP的量,这个值是在寄存器中配置的,当这两个值相等时就发生一次轮询操作。
    通过mwr_64b_en_i 信号判断发送的存储器写请求的标头是3DW还是4DW,这和完成包不一样,因为完成包只有3DW标头,而存储器写或者读的TLP有3DW和4DW两种。
    先分析3DW标头,此时跳转到BMD_64_TX_MWR_QW1状态
这里写图片描述
    这个状态是发送第二帧数据,包含1DW标头(地址)+1DW数据,同样设置主机有效信号,然后通过cur_wr_count判断这是不是第一个TLP,因为第几个TLP决定着需要存入存储器的地址,mwr_addr是PC端申请的连续内存的首个地址,所以cur_wr_count为0,则要存入的地址为连续内存的首地址,之后就按照每个TLP中的数据量改变下一个TLP数据的存储地址。
    cur_mwr_dw_count信号初值是一个TLP中的数据量(DW),如果当前cur_mwr_dw_count为1,则表示这是最后一个数据了,那么这时通过cur_wr_count分析这是否是最后一个包,如果是最后一个包那么说明这个TLP只有两帧(3DW标头+1DW数据),此次DMA传输完全结束,mwr_done_o置1;若不是最后一个数据,说明这个TLP不止两帧数据,则跳转BMD_64_TX_MWR_QWN 状态。
这里写图片描述
    一个TLP传输到最后有可能还剩下1个或者2个DW数据,所以程序中就设计两种情况,如果只有1个DW,那么还需要组装1DW无用数据,同时使用trn_trem_n 信号来表明最后一个DW无效;如果刚好还剩两个DW数据,则刚好一次传输完,此时设置trn_trem_n 为0来表示这一帧中两个DW数据都是有效的。如果还剩的数据大于2DW,则就直接每次传输2DW数据,直到出现只剩下1个或者2个DW数据。
    至此,DMA写操作的流程已经分析完成了,至于DMA读操作,以及3DW或4DW标头的分析都与分析类似,就不再分析了。
    此外,BMD_EP_MEM.v 以及BMD_EP_MEM_ACCESS.v两个模块可以参照PIO中的分析,BMD_EP_MEM.v中的寄存器可以参照官方资料xapp1052,在这里就不过多叙述了。
结束
    以上就是PCIe DMA的全部分析,后期会上传一些参考资料及有详细注释的.v文件,有需要的同学可以下载(https://download.csdn.net/download/cllovexyh/10335472)。

标签:DMA,标头,BMD,之二,发送,PCIe,TLP,64
来源: https://blog.csdn.net/Lynrxl/article/details/100254955

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有