dma_test是针对dma硬件设计的仿真测试文件,文件包括DMA写数据测试,DMA读数据测试以及DMA读写数据测试。这个测试文件其实就是模拟pc的应用程序对fpga设备进行DMA读写。

DMA写测试指的是fpga设备往pc端进行DMA方式的写数据,而不是pc端往fpga设备中进行读写,这点要弄清。dma写测试的选择如下所示:

  1. else if (testname == "dma_mwr_test")

在写测试中,仿真文件模仿了操作系统对pcie设备操作的整个流程:

首先:测试文件会对fpga设备中的配置寄存器进行赋值,例如BAR寄存器,command寄存器。在TSK_BAT_INIT任务里面其实是在模拟BIOS和驱动程序的操作,首先会对BAR寄存器进行赋值,然后会对BAR指向的设备内存进行IO或者mem映射,最后就是对设备的配置寄存器的参数写入。

  1. TSK_BAT_INIT; // pci_exp_usrapp_tx.v 2281
  1. board.RP.cfg_usrapp.TSK_WRITE_CFG_DW(32'h00000004,32'h00000007,4'b1110); // pci_exp_usrapp_cfg.v 226
  1. TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG,12'h04,P_READ_DATA[31:0],4'hF); // pci_exp_usrapp_tx.v 522

然后:测试文件会进行写DMA配置操作,在执行DMA操作之前,是需要利用PIO的方式对fpga设备进行初始化的,初始化的数据存放在BAR空间中,即设备的内存中;DMA读和DMA写所进行的配置是不同的,所以不同的DMA配置就需要写入不同的数据。这里需要说明的是,DMA的配置是有先后顺序的,

第一步是配置使能初始化标志位;

第二步是去去使能化标志位;

第三步配置写DMA的起始地址;

第四步配置每个TLP中要写的数据长度;

第五步配置TLP的个数;

最后才是配置开始DMA的标志位;

  1. // Write DMA configuration
  2. //--------------------------------------------------------------------------
  3. $display("[%t] : Writing DCR1 With 0x01", $realtime);
  4. fork
  5. data=32'h01;  // address 0 {fpga_family, {4'b0},interface_type, version_number, {7'b0}, init_rst_o}
  6. DATA_STORE[0] = data[7:0];
  7. DATA_STORE[1] = data[15:8];
  8. DATA_STORE[2] = data[23:16];
  9. DATA_STORE[3] = data[31:24];
  10. TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h0,4'b0,4'hF,1'b0); // pci_exp_usrapp_tx 796
  11. DEFAULT_TAG = DEFAULT_TAG + 1;
  12. TSK_TX_CLK_EAT(100);
  13. join
  14. $display("[%t] : Writing DCR1 With 0x00", $realtime);
  15. fork
  16. data=32'h0; // diable init operation in last step
  17. DATA_STORE[0] = data[7:0];
  18. DATA_STORE[1] = data[15:8];
  19. DATA_STORE[2] = data[23:16];
  20. DATA_STORE[3] = data[31:24];
  21. TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h0,4'b0,4'hF,1'b0);
  22. DEFAULT_TAG = DEFAULT_TAG + 1;
  23. TSK_TX_CLK_EAT(100);
  24. join
  25. $display("[%t] : Writing WDMATLPA", $realtime);
  26. fork
  27. data=32'hffff0000; // memory write DMA address
  28. DATA_STORE[0] = data[7:0];
  29. DATA_STORE[1] = data[15:8];
  30. DATA_STORE[2] = data[23:16];
  31. DATA_STORE[3] = data[31:24];
  32. TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h08,4'b0,4'hF,1'b0);
  33. DEFAULT_TAG = DEFAULT_TAG + 1;
  34. TSK_TX_CLK_EAT(100);
  35. join
  36. $display("[%t] : Writing WDMATLPS", $realtime);
  37. fork
  38. data=tlps; // memory write length in DWORD
  39. DATA_STORE[0] = data[7:0];
  40. DATA_STORE[1] = data[15:8];
  41. DATA_STORE[2] = data[23:16];
  42. DATA_STORE[3] = data[31:24];
  43. TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h0c,4'b0,4'hF,1'b0);
  44. DEFAULT_TAG = DEFAULT_TAG + 1;
  45. TSK_TX_CLK_EAT(100);
  46. join
  47. $display("[%t] : Writing WDMATLPC", $realtime);
  48. fork
  49. data=tlpc; // memory write package count
  50. DATA_STORE[0] = data[7:0];
  51. DATA_STORE[1] = data[15:8];
  52. DATA_STORE[2] = data[23:16];
  53. DATA_STORE[3] = data[31:24];
  54. TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h10,4'b0,4'hF,1'b0);
  55. DEFAULT_TAG = DEFAULT_TAG + 1;
  56. TSK_TX_CLK_EAT(100);
  57. join
  58. $display("[%t] : Writing DCR2 With 0x01", $realtime);
  59. fork
  60. data=32'h00000001; // write DMA start from device to pc
  61. DATA_STORE[0] = data[7:0];
  62. DATA_STORE[1] = data[15:8];
  63. DATA_STORE[2] = data[23:16];
  64. DATA_STORE[3] = data[31:24];
  65. TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h04,4'b0,4'hF,1'b0);
  66. DEFAULT_TAG = DEFAULT_TAG + 1;
  67. TSK_TX_CLK_EAT(100);
  68. join

在开启DMA以后,仿真程序的接收端会不断接收到fpga传输过来的数据(pci_exp_usrapp_rx.v),在本测试文件中,会始终检测传回的数据,以及传输的TLP个数,然后做记录。

  1. begin
  2. wait_for_next = 1'b1; //haven't found any matching tag yet
  3. while(wait_for_next)
  4. begin
  5. tlpc=tlpc-1;
  6. if (tlpc==0)
  7. wait_for_next=1'b0;
  8. @ board.RP.com_usrapp.rcvd_memwr; //wait for a rcvd_memwr event
  9. fork
  10. traffic_class_ = board.RP.com_usrapp.frame_store_rx[1] >> 4;
  11. td_ = board.RP.com_usrapp.frame_store_rx[2] >> 7;
  12. ep_ = board.RP.com_usrapp.frame_store_rx[2] >> 6;
  13. attr_ = board.RP.com_usrapp.frame_store_rx[2] >> 4;
  14. length_ =board.RP.com_usrapp. frame_store_rx[2];
  15. length_ = (length_ << 8) | (board.RP.com_usrapp.frame_store_rx[3]);
  16. requester_id_= {board.RP.com_usrapp.frame_store_rx[4], board.RP.com_usrapp.frame_store_rx[5]};
  17. tag_= board.RP.com_usrapp.frame_store_rx[6];
  18. last_dw_be_= board.RP.com_usrapp.frame_store_rx[7] >> 4;
  19. first_dw_be_= board.RP.com_usrapp.frame_store_rx[7];
  20. address_[29:6] = {board.RP.com_usrapp.frame_store_rx[8], board.RP.com_usrapp.frame_store_rx[9], board.RP.com_usrapp.frame_store_rx[10]};
  21. address_[5:0] = board.RP.com_usrapp.frame_store_rx[11] >> 2;
  22. length_ = (length_ << 2);
  23. if (length_==0) length_ = 4096;
  24. $display("[%t] : Received MEMWR --- Tag 0x%h", $realtime, tag_);
  25. join
  26. end
  27. end

最后就是检测中断,在fpga写DMA操作完成之后,会产生一个中断信号,本测试文件会检测从fpga输出的终端信号,然后停止操作

  1. wait (board.xilinx_pci_exp_ep.app.cfg_interrupt_n == 1'b0)
  2. $display("[%t] : Received INT --- ", $realtime);
  3. #100;
  4. $finish;

我们可以看出,这个测试文件只是简单地检测fpga模块的输出终端信号,但是我们知道,实际上的操作并不是这样,实际上,fpga的中断信号会被打包成一个TLP的包(信号类型),然后中断信号会被当做TLP包进行发送,当PC端接收到这种包时,会解析出这事一个中断信号,然后进入对应的终端服务程序进行操作。

版权声明:本文为博主原创文章,未经博主允许不得转载。
 
  • qqcom_1228010378

    2017-02-14 17:184楼

  • 你好,我现在也在看XAPP1052,但是源代码(没有修改的情况下)仿真果有错,存储器写入的数据不等于存储器读出的数据,是什么原因呢?能否指导一下?谢谢
 
  • smallfish_love

    2016-10-26 15:263楼

  • 你这个// pci_exp_usrapp_tx 796 指的是// pci_exp_usrapp_tx文件的行号吗?但是看了 好像有不对,感觉应该在2'b10:这个状态这里。最后的三段代码都添加在这里,并把原来的代码都覆盖吗?
 
  • smallfish_love

    2016-10-26 15:122楼

  • 你好,这个// Write DMA configuration 这两段程序是连在一起的吗,这两个程序是写在什么文件里面的,什么位置的呢?谢谢
 
  • gxy670166755

    2016-08-11 14:181楼

  • 请问,xapp1052.zip里面 存在dma_test.v 这个文件吗,我怎么找不到?

    我是新手对于pcie和dma来说,PIO参考设计我看完了,也仿真过,基本了解了。

    因为未来用7系列FPGFA,所以xapp859就没考虑。

    xapp1052 也正在看,“Xilinx中的xapp1052理解”这篇文章对我有很大帮助,谢谢。

    第二个问题是,像我这样的新手,实现pcie+dma和PC通信的功能,是不是在xapp1052的基础上修改

    会更快些、更实际些呢?

    期望您的答复,谢谢!

  • 回复 2条回复
  • smallfish_love

    2016-12-25 11:57

  • 回复gxy670166755:你好,请问一下你的 DMA PCIE做完了吗 我现在也在修改XAPP1052,基本上修改完了,但是还存在一点小问题,能否加Q交流一下?QQ:1751174079
 
  • Buyi_Shizi

    2016-09-22 10:52

  • 回复gxy670166755:在仿真源文件下有个sample_test.vh这个就是对应上面的dma_tests.v.
    xapp1052实现了DMA外围的数据接收和发送,如果实现pcie+dma和pc通讯,只需要自己添加RAM模块就可以
  • smallfish_love

    2016-12-25 11:58

  • 回复Buyi_Shizi:博主你好,我现在基本上修改完了XAPP1052,但是还存在一点小问题,能否加我Q指点一下,谢谢。QQ:1751174079
  • qqcom_1228010378

    2017-02-14 17:20

  • 回复smallfish_love:你好,我现在也在看XAPP1052,但是源代码(没有修改的情况下)仿真果有错,存储器写入的数据不等于存储器读出的数据,是什么原因呢?能否指导一下?谢谢
 
  • qqcom_1228010378

    2017-02-14 17:19

  • 回复smallfish_love:你好,我现在也在看XAPP1052,但是源代码(没有修改的情况下)仿真果有错,存储器写入的数据不等于存储器读出的数据,是什么原因呢?能否指导一下?谢谢
转载:http://blog.csdn.net/buyi_shizi/article/details/51251404

xapp1052之dma_test.v的更多相关文章

  1. PCIE_DMA实例二:xapp1052的EDK仿真

    一:前言 这篇博客是我应一位网友之约写的,他想要学习基于FPGA的PCIe DMA控制器设计,但是手上没有合适的Xilinx开发板,而且xapp1052又没有提供仿真代码,让他的学习陷入了困境.所以我 ...

  2. PCIE_DMA实例一:xapp1052详细使用说明

    一:前言 很多和我一样初学pcie的硬件工程师都会遇到这样一个问题,看了不少pcie相关的资料,还是搞不清这玩意儿到底该怎么用.于是我们打开ISE的core_generator工具,生成了一个pcie ...

  3. J a v a 的“多重继承”

    接口只是比抽象类“更纯”的一种形式.它的用途并不止那些.由于接口根本没有具体的实施细节——也就是说,没有与存储空间与“接口”关联在一起——所以没有任何办法可以防止多个接口合并到一起.这一点是至关重要的 ...

  4. Exception in thread "main" java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V

    在学习CGlib动态代理时,遇到如下错误: Exception in thread "main" java.lang.NoSuchMethodError: org.objectwe ...

  5. [Erlang 0118] Erlang 杂记 V

       我在知乎回答问题不多,这个问题: "对你职业生涯帮助最大的习惯是什么?它是如何帮助你的?",我还是主动回答了一下.    做笔记 一开始笔记软件做的不好的时候就发邮件给自己, ...

  6. v$session中server为none与shared值解析

    查询V$SESSION,你会看到SERVER可能会有DEDICATED| SHARED| PSEUDO| NONE 四种值,如果SERVER字段的值除了DEDICATED,还有NONE,则说明当前实例 ...

  7. 引用js或css后加?v= 版本号的用法

    <span style="font-size:14px;">css和js带参数(形如.css?v=与.js?v= 或 .css?version=与.js?version ...

  8. 操作系统中的P,V操作(转)

    无论是计算机考研.计算机软件水平考试.计算机操作系统期末考试还是其他计算机岗位考试,P.V原语操作都是一个常考点.下面笔者总结了关于P.V操作的一些知识. 信号量是最早出现的用来解决进程同步与互斥问题 ...

  9. 关于P,V操作理解的突破,关于并发设计与并行

    今天又找了一篇博客研究P,V操作.. 发现..它有一个变量没有声明.. 我就换了篇博客..http://c.biancheng.net/cpp/html/2600.html 然后就看懂了.. 关键突破 ...

随机推荐

  1. CAD批量合并文件

    要求:将整饰完成504幅单独的宗地图合并成一张总图,合并后,去掉其他要素,只保留毕合的权属线. 解决: 1.合并dwg文件,除了手工粘贴复制外,最先想到的是插入块,即用Insert命令插入,测试结果可 ...

  2. ListView实现数据列表显示

    要将数据库中的数据列表显示在屏幕上,我们要使用ListView这个控件,当用户从数据库中取出数据时,要将数据绑定到显示控件上,如何绑定呢,我们需要创建适配器进行绑定,创建适配器有两种方式: 第一种是用 ...

  3. STL - 容器 - List

    List内部结构完全不同于array, vector, deque. 它提供了两个pointer,指向第一个和最后一个元素. 不支持随机访问元素,因此要访问第n个元素必须爬过n - 1个元素. 在任何 ...

  4. C# 64位系统调用32位DLL异常解决办法(异常来自HRESULT :0x8007007E)

    解决办法如下 1.在IDE中将目标平台设置成x86(VS是在项目的属性->生成->目标平台) 2.如果DLL中调用了其他的DLL,需要将其他的DLL一同编译 3.有时DLL生成时会依赖于I ...

  5. android google map v1 v2 v3 参考

    V1,V2已经不被推荐使用,谷歌强烈推荐使用V3. 本人在选择时着实纠结了良久,现在总结如下: 对于V1,现在已经申请不到API KEY了,所以不要使用这个版本.这个是网址:https://devel ...

  6. UILabel文字竖排

    方法一: UILabel *mindName = [[UILabel alloc]initWithFrame:kCR(, , ,)]; mindName.text = @"苏\n小\n明&q ...

  7. 【CMS】安装CMS

    Apache和MySQL准备好后开始安装CMS 在浏览器输入:http://localhost/install/index.php即可开始安装.

  8. 用javascript的isNan()函数,可以判断是否为数字

    var getstockid = $.trim($("#SearchString").val()); if (!isNaN(getstockid)) alert('是数字!'); ...

  9. 【Oracle】函数

    函数一般用于计算和返回一个值,可以将经常需要使用的计算或功能写成一个函数. 语法 create [or replace] function func_name[(parameter1,[,parame ...

  10. 【微信小程序】详解wx:if elif else的用法(搭配view、block)

    1.搭配view <view wx:if="{{boolean==true}}"> <view class="bg_black">< ...