原创 BAR空间扫描子程序学习(TSK_BAR_SCAN)

2019-8-8 12:59 3752 26 26 分类: FPGA/CPLD 文集: Xilinx PCIe仿真模型
前面博文有介绍在仿真测试功能代码里前面几步分别是设置仿真时间(以防止仿真被无休止挂起)、系统初始化(等待复位被释放以及链路链接ok)、BAR空间初始化等等。其中在BAR初始化子函数里调用了本文要介绍的BAR空间扫描子程序,其具体代码是:
/************************************************************
  • Task : TSK_BAR_SCAN
  • Inputs : None
  • Outputs : None
  • Description : Scans PCI core's configuration registers.
  • *************************************************************/
  • task TSK_BAR_SCAN;
  • begin
  • //--------------------------------------------------------------------------
  • // Write PCI_MASK to bar's space via PCIe fabric interface to find range
  • //--------------------------------------------------------------------------
  • P_ADDRESS_MASK = 32'hffff_ffff;
  • DEFAULT_TAG = 0;
  • DEFAULT_TC = 0;
  • $display("[%t] : Inspecting Core Configuration Space...", $realtime);
  • // Determine Range for BAR0
  • TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h10, P_ADDRESS_MASK, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_TX_CLK_EAT(100);
  • // Read BAR0 Range
  • TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h10, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_WAIT_FOR_READ_DATA;
  • BAR_INIT_P_BAR_RANGE[0] = P_READ_DATA;
  • // Determine Range for BAR1
  • TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h14, P_ADDRESS_MASK, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_TX_CLK_EAT(100);
  • // Read BAR1 Range
  • TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h14, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_WAIT_FOR_READ_DATA;
  • BAR_INIT_P_BAR_RANGE[1] = P_READ_DATA;
  • // Determine Range for BAR2
  • TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h18, P_ADDRESS_MASK, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_TX_CLK_EAT(100);
  • // Read BAR2 Range
  • TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h18, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_WAIT_FOR_READ_DATA;
  • BAR_INIT_P_BAR_RANGE[2] = P_READ_DATA;
  • // Determine Range for BAR3
  • TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h1C, P_ADDRESS_MASK, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_TX_CLK_EAT(100);
  • // Read BAR3 Range
  • TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h1C, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_WAIT_FOR_READ_DATA;
  • BAR_INIT_P_BAR_RANGE[3] = P_READ_DATA;
  • // Determine Range for BAR4
  • TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h20, P_ADDRESS_MASK, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_TX_CLK_EAT(100);
  • // Read BAR4 Range
  • TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h20, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_WAIT_FOR_READ_DATA;
  • BAR_INIT_P_BAR_RANGE[4] = P_READ_DATA;
  • // Determine Range for BAR5
  • TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h24, P_ADDRESS_MASK, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_TX_CLK_EAT(100);
  • // Read BAR5 Range
  • TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h24, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_WAIT_FOR_READ_DATA;
  • BAR_INIT_P_BAR_RANGE[5] = P_READ_DATA;
  • // Determine Range for Expansion ROM BAR
  • TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h30, P_ADDRESS_MASK, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_TX_CLK_EAT(100);
  • // Read Expansion ROM BAR Range
  • TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h30, 4'hF);
  • DEFAULT_TAG = DEFAULT_TAG + 1;
  • TSK_WAIT_FOR_READ_DATA;
  • BAR_INIT_P_BAR_RANGE[6] = P_READ_DATA;
  • end
  • endtask // TSK_BAR_SCAN
  • 复制代码
    查看代码,该子程序主要对几个BAR空间执行了一系列PCI Type0配置读和写,以此确定并获取Endpoint的每个BAR空间的存储器和IO操作要求。获取的信息存储在全局阵列变量BAR_INIT_P_BAR_RANGE[?]之中。注意这个函数只能在系统初始化函数之后被调用。
    代码中Type0读写配置函数的第二个参数对应于每个BAR的基地址,比如BAR0对应h'10。
    BAR

    作者: coyoo, 来源:面包板社区

    链接: https://mbb.eet-china.com/blog/uid-me-1010859.html

    版权声明:本文为博主原创,未经本人允许,禁止转载!

    PARTNER CONTENT

    文章评论0条评论)

    登录后参与讨论
    我要评论
    0
    26
    关闭 站长推荐上一条 /3 下一条