zoukankan      html  css  js  c++  java
  • 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的基础上修改 

      会更快些、更实际些呢?

      期望您的答复,谢谢!
    • 回复 
    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
  • 相关阅读:
    windowssdk编程从简单的对话框开始
    面向扣扣编程知识一
    循序渐进DLL编程(二)
    西方经济学导论
    循序渐进DLL编程(五)
    HLSL Effect的vertex shader和pixel shader的参数传递
    Directx11 HelloWorld之与Directx9的比较
    Directx11 HelloWorld之简单三角形绘制
    正式开始记录自己学习历程
    坐标系的转换
  • 原文地址:https://www.cnblogs.com/chengqi521/p/8242603.html
Copyright © 2011-2022 走看看