xapp1052之dma_test.v

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

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

 

[plain]  view plain  copy
 
  1. else if (testname == "dma_mwr_test")  
    在写测试中,仿真文件模仿了操作系统对pcie设备操作的整个流程:

 

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

[html]  view plain  copy
 
  1. TSK_BAT_INIT; // pci_exp_usrapp_tx.v 2281  
[html]  view plain  copy
 
  1. board.RP.cfg_usrapp.TSK_WRITE_CFG_DW(32'h00000004,32'h00000007,4'b1110); // pci_exp_usrapp_cfg.v 226  
[html]  view plain  copy
 
  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的标志位;

[plain]  view plain  copy
 
  1. // Write DMA configuration   
  2.     //--------------------------------------------------------------------------      
  3.       
  4.     $display("[%t] : Writing DCR1 With 0x01", $realtime);  
  5.     fork  
  6.     data=32'h01;  // address 0 {fpga_family, {4'b0},interface_type, version_number, {7'b0}, init_rst_o}  
  7.     DATA_STORE[0] = data[7:0];  
  8.     DATA_STORE[1] = data[15:8];  
  9.     DATA_STORE[2] = data[23:16];  
  10.     DATA_STORE[3] = data[31:24];  
  11.   
  12.     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  
  13.     DEFAULT_TAG = DEFAULT_TAG + 1;  
  14.     TSK_TX_CLK_EAT(100);  
  15.     join  
  16.       
  17.     $display("[%t] : Writing DCR1 With 0x00", $realtime);  
  18.     fork  
  19.     data=32'h0; // diable init operation in last step  
  20.     DATA_STORE[0] = data[7:0];  
  21.     DATA_STORE[1] = data[15:8];  
  22.     DATA_STORE[2] = data[23:16];  
  23.     DATA_STORE[3] = data[31:24];  
  24.   
  25.     TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h0,4'b0,4'hF,1'b0);  
  26.     DEFAULT_TAG = DEFAULT_TAG + 1;  
  27.     TSK_TX_CLK_EAT(100);  
  28.     join  
  29.   
  30.     $display("[%t] : Writing WDMATLPA", $realtime);  
  31.     fork  
  32.     data=32'hffff0000; // memory write DMA address  
  33.     DATA_STORE[0] = data[7:0];  
  34.     DATA_STORE[1] = data[15:8];  
  35.     DATA_STORE[2] = data[23:16];  
  36.     DATA_STORE[3] = data[31:24];  
  37.   
  38.     TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h08,4'b0,4'hF,1'b0);  
  39.     DEFAULT_TAG = DEFAULT_TAG + 1;  
  40.     TSK_TX_CLK_EAT(100);  
  41.     join  
  42.   
  43.     $display("[%t] : Writing WDMATLPS", $realtime);  
  44.     fork  
  45.     data=tlps; // memory write length in DWORD  
  46.     DATA_STORE[0] = data[7:0];  
  47.     DATA_STORE[1] = data[15:8];  
  48.     DATA_STORE[2] = data[23:16];  
  49.     DATA_STORE[3] = data[31:24];  
  50.   
  51.     TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h0c,4'b0,4'hF,1'b0);  
  52.     DEFAULT_TAG = DEFAULT_TAG + 1;  
  53.     TSK_TX_CLK_EAT(100);  
  54.     join  
  55.   
  56.     $display("[%t] : Writing WDMATLPC", $realtime);  
  57.     fork  
  58.     data=tlpc; // memory write package count  
  59.     DATA_STORE[0] = data[7:0];  
  60.     DATA_STORE[1] = data[15:8];  
  61.     DATA_STORE[2] = data[23:16];  
  62.     DATA_STORE[3] = data[31:24];  
  63.   
  64.     TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h10,4'b0,4'hF,1'b0);  
  65.     DEFAULT_TAG = DEFAULT_TAG + 1;  
  66.     TSK_TX_CLK_EAT(100);  
  67.     join  
  68.   
  69.     $display("[%t] : Writing DCR2 With 0x01", $realtime);  
  70.     fork  
  71.     data=32'h00000001; // write DMA start from device to pc  
  72.     DATA_STORE[0] = data[7:0];  
  73.     DATA_STORE[1] = data[15:8];  
  74.     DATA_STORE[2] = data[23:16];  
  75.     DATA_STORE[3] = data[31:24];  
  76.   
  77.     TSK_TX_MEMORY_WRITE_32(DEFAULT_TAG, DEFAULT_TC,10'd1,BAR_INIT_P_BAR[0]+8'h04,4'b0,4'hF,1'b0);  
  78.     DEFAULT_TAG = DEFAULT_TAG + 1;  
  79.     TSK_TX_CLK_EAT(100);  
  80.     join  
    在开启DMA以后,仿真程序的接收端会不断接收到fpga传输过来的数据(pci_exp_usrapp_rx.v),在本测试文件中,会始终检测传回的数据,以及传输的TLP个数,然后做记录。
[plain]  view plain  copy
 
  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.   
  9.     @ board.RP.com_usrapp.rcvd_memwr; //wait for a rcvd_memwr event  
  10.     fork  
  11.     traffic_class_ = board.RP.com_usrapp.frame_store_rx[1] >> 4;  
  12.     td_ = board.RP.com_usrapp.frame_store_rx[2] >> 7;  
  13.     ep_ = board.RP.com_usrapp.frame_store_rx[2] >> 6;  
  14.      attr_ = board.RP.com_usrapp.frame_store_rx[2] >> 4;  
  15.     length_ =board.RP.com_usrapp. frame_store_rx[2];  
  16.      length_ = (length_ << 8) | (board.RP.com_usrapp.frame_store_rx[3]);  
  17.      requester_id_= {board.RP.com_usrapp.frame_store_rx[4], board.RP.com_usrapp.frame_store_rx[5]};  
  18.      tag_= board.RP.com_usrapp.frame_store_rx[6];  
  19.      last_dw_be_= board.RP.com_usrapp.frame_store_rx[7] >> 4;  
  20.      first_dw_be_= board.RP.com_usrapp.frame_store_rx[7];  
  21.      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]};  
  22.      address_[5:0] = board.RP.com_usrapp.frame_store_rx[11] >> 2;  
  23.        
  24.      length_ = (length_ << 2);  
  25.     if (length_==0) length_ = 4096;  
  26.   
  27.   
  28.     $display("[%t] : Received MEMWR --- Tag 0x%h", $realtime, tag_);  
  29.       
  30.     join  
  31.   end  
  32. end  
    最后就是检测中断,在fpga写DMA操作完成之后,会产生一个中断信号,本测试文件会检测从fpga输出的终端信号,然后停止操作
[plain]  view plain  copy
 
  1. wait (board.xilinx_pci_exp_ep.app.cfg_interrupt_n == 1'b0)  
  2. $display("[%t] : Received INT --- ", $realtime);  
  3.   
  4. #100;  
  5.   
  6. $finish;  
    我们可以看出,这个测试文件只是简单地检测fpga模块的输出终端信号,但是我们知道,实际上的操作并不是这样,实际上,fpga的中断信号会被打包成一个TLP的包(信号类型),然后中断信号会被当做TLP包进行发送,当PC端接收到这种包时,会解析出这事一个中断信号,然后进入对应的终端服务程序进行操作。

 

版权声明:本文为博主原创文章,未经博主允许不得转载。
 
 
qqcom_1228010378
  • qqcom_1228010378
    2017-02-14 17:184楼
  • 你好,我现在也在看XAPP1052,但是源代码(没有修改的情况下)仿真果有错,存储器写入的数据不等于存储器读出的数据,是什么原因呢?能否指导一下?谢谢
 
smallfish_love
  • smallfish_love
    2016-10-26 15:263楼
  • 你这个// pci_exp_usrapp_tx 796 指的是// pci_exp_usrapp_tx文件的行号吗?但是看了 好像有不对,感觉应该在2'b10:这个状态这里。最后的三段代码都添加在这里,并把原来的代码都覆盖吗?
 
smallfish_love
  • smallfish_love
    2016-10-26 15:122楼
  • 你好,这个// Write DMA configuration 这两段程序是连在一起的吗,这两个程序是写在什么文件里面的,什么位置的呢?谢谢
 
gxy670166755
  • 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
  • smallfish_love
    2016-12-25 11:57
  • 回复gxy670166755:你好,请问一下你的 DMA PCIE做完了吗 我现在也在修改XAPP1052,基本上修改完了,但是还存在一点小问题,能否加Q交流一下?QQ:1751174079
 
Buyi_Shizi
  • Buyi_Shizi
    2016-09-22 10:52
  • 回复gxy670166755:在仿真源文件下有个sample_test.vh这个就是对应上面的dma_tests.v.
    xapp1052实现了DMA外围的数据接收和发送,如果实现pcie+dma和pc通讯,只需要自己添加RAM模块就可以
smallfish_love
  • smallfish_love
    2016-12-25 11:58
  • 回复Buyi_Shizi:博主你好,我现在基本上修改完了XAPP1052,但是还存在一点小问题,能否加我Q指点一下,谢谢。QQ:1751174079
qqcom_1228010378
  • qqcom_1228010378
    2017-02-14 17:20
  • 回复smallfish_love:你好,我现在也在看XAPP1052,但是源代码(没有修改的情况下)仿真果有错,存储器写入的数据不等于存储器读出的数据,是什么原因呢?能否指导一下?谢谢
 
qqcom_1228010378
  • qqcom_1228010378
    2017-02-14 17:19
  • 回复smallfish_love:你好,我现在也在看XAPP1052,但是源代码(没有修改的情况下)仿真果有错,存储器写入的数据不等于存储器读出的数据,是什么原因呢?能否指导一下?谢谢
转载:http://blog.csdn.net/buyi_shizi/article/details/51251404

转载于:https://www.cnblogs.com/chengqi521/p/8242603.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值