首页 >> 大全

Xilinx PCIe IP核示例工程代码分析与仿真

2024-01-08 大全 26 作者:考证青年

PCIe学习笔记系列:

PCIe基础知识及相关IP核介绍

概念了解:简单学习PCIe的数据链路与拓扑结构,另外看看有什么相关的IP核。【PG054】7 Block for PCI IP核的学习

基础学习:关于Pcie IP核的数据手册,学习PCIe相关的IP核的配置参数及其对应的含义。 PCIe IP核示例工程代码分析与仿真

基础学习:关于PCIe IP核的仿真,学习PCIe的配置流程以及应用过程。 XDMA 例程代码分析与仿真结果

应用学习:关于 PCIe DMA IP核的仿真,学习 PCIe DMA 的配置过程以及具体的数据传输流程。XDMA linux平台调试过程记录

应用学习:关于XDMA的实际调试过程,可在此基础上定制自己的需求。

目录

【PG054】7 Block for PCI IP核的学习中学习了7 Block for PCI IP核的一些基础知识,下面通过仿真进一步理解。

1 工程建立

只进行仿真设计,随便配置成器件就行。

1 page1:Basic

2 page2: IDs

3 page3: BARs

4 page4: Core

5 page5:

设置好IP核之后,右击IP核打开示例工程:

示例工程的文件结构:

 xilinx_pcie_2_1_ep_7x||--pcie_7x_0_support|  |--pcie_7x_0_pipe_clock                                      |  |--pcie_7x_0 (Core Top level module Generated by Vivado in synth directory)|     |--pcie_7x_v3_3_4_top (Static Top level file) |        |--pcie_7x_v3_3_4_core_top|           ||           |--pcie_7x_0_pcie_top|           |  ||           |  |--pcie_7x_0_axi_basic_top|           |  |  ||           |  |  |--pcie_7x_0_axi_basic_rx|           |  |  |  ||           |  |  |  |--pcie_7x_0_axi_basic_rx_pipeline|           |  |  |  |--pcie_7x_0_axi_basic_rx_null_gen|           |  |  ||           |  |  |--pcie_7x_0_axi_basic_tx|           |  |     ||           |  |     |--pcie_7x_0_axi_basic_tx_pipeline|           |  |     |--pcie_7x_0_axi_basic_tx_thrtl_ctl|           |  ||           |  |--pcie_7x_0_pcie_7x|           |  |  ||           |  |  |--pcie_7x_0_pcie_bram_top_7x|           |  |  |  ||           |  |  |  |--pcie_7x_0_pcie_brams_7x (an instance each for Rx & Tx)|           |  |  |     ||           |  |  |     |--pcie_7x_0_pcie_bram_7x|           |  |  ||           |  |  |--PCIE_2_1 (Integrated Block Instance)|           |  ||           |  |--pcie_7x_0_pcie_pipe_pipeline|           |     ||           |     |--pcie_7x_0_pcie_pipe_misc|           |     |--pcie_7x_0_pcie_pipe_lane (per lane)|           ||           |--pcie_7x_0_gt_top|              ||              |--pcie_7x_0_gt_rx_valid_filter|              ||              |--pcie_7x_0_pipe_wrapper|              |  ||              |  |--pcie_7x_0_pipe_reset|              |  |--pcie_7x_0_qpll_reset|              |  |--pcie_7x_0_pipe_user|              |  |--pcie_7x_0_pipe_rate|              |  |--pcie_7x_0_pipe_sync|              |  |--pcie_7x_0_pipe_drp|              |  |--pcie_7x_0_pipe_eq|              |  |  |--pcie_7x_0_rxeq_scan|              |  |  ||              |  |--pcie_7x_0_gt_common|              |  |  |--pcie_7x_0_qpll_drp|              |  |  |--pcie_7x_0_qpll_wrapper|              |  ||              |  |--pcie_7x_0_gt_wrapper||--pcie_app_7x (PIO design, in example_design directory)||--PIO||--PIO_EP|  ||  |--PIO_EP_MEM_ACCESS|  |  ||  |  |--EP_MEM|  |     ||  |     |--RAMB36|  ||  |--PIO_RX_ENGINE|  |--PIO_TX_ENGINE||--PIO_TO_CTRL

2 工程仿真 2.1 代码分析

再回顾一下示例程序的结构:

首先打开中的文件.v, 层次路径为:board/RP/, 重点关注一个块:

其中,名为st0的测试任务的具体内容为:

else if(testname == "pio_writeReadBack_test0")
begin// This test performs a 32 bit write to a 32 bit Memory space and performs a read backboard.RP.tx_usrapp.TSK_SIMULATION_TIMEOUT(10050);board.RP.tx_usrapp.TSK_SYSTEM_INITIALIZATION;board.RP.tx_usrapp.TSK_BAR_INIT;//--------------------------------------------------------------------------
// Event : Testing BARs
//--------------------------------------------------------------------------for (board.RP.tx_usrapp.ii = 0; board.RP.tx_usrapp.ii <= 6; board.RP.tx_usrapp.ii =board.RP.tx_usrapp.ii + 1) beginif (board.RP.tx_usrapp.BAR_INIT_P_BAR_ENABLED[board.RP.tx_usrapp.ii] > 2'b00) // bar is enabledcase(board.RP.tx_usrapp.BAR_INIT_P_BAR_ENABLED[board.RP.tx_usrapp.ii])2'b01 : // IO SPACEbegin$display("[%t] : Transmitting TLPs to IO Space BAR %x", $realtime, board.RP.tx_usrapp.ii);//--------------------------------------------------------------------------// Event : IO Write bit TLP//--------------------------------------------------------------------------board.RP.tx_usrapp.TSK_TX_IO_WRITE(board.RP.tx_usrapp.DEFAULT_TAG,board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii][31:0], 4'hF, 32'hdead_beef);board.RP.com_usrapp.TSK_EXPECT_CPL(3'h0, 1'b0, 1'b0, 2'b0,board.RP.tx_usrapp.COMPLETER_ID_CFG, 3'h0, 1'b0, 12'h4,board.RP.tx_usrapp.COMPLETER_ID_CFG, board.RP.tx_usrapp.DEFAULT_TAG,board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii][31:0], test_vars[0]);board.RP.tx_usrapp.TSK_TX_CLK_EAT(10);board.RP.tx_usrapp.DEFAULT_TAG = board.RP.tx_usrapp.DEFAULT_TAG + 1;//--------------------------------------------------------------------------// Event : IO Read bit TLP//--------------------------------------------------------------------------// make sure P_READ_DATA has known initial valueboard.RP.tx_usrapp.P_READ_DATA = 32'hffff_ffff;forkboard.RP.tx_usrapp.TSK_TX_IO_READ(board.RP.tx_usrapp.DEFAULT_TAG,board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii][31:0], 4'hF);board.RP.tx_usrapp.TSK_WAIT_FOR_READ_DATA;joinif  (board.RP.tx_usrapp.P_READ_DATA != 32'hdead_beef)begin$display("[%t] : Test FAILED --- Data Error Mismatch, Write Data %x != Read Data %x",$realtime, 32'hdead_beef, board.RP.tx_usrapp.P_READ_DATA);test_failed_flag = 1;endelsebegin$display("[%t] : Test PASSED --- Write Data: %x successfully received",$realtime, board.RP.tx_usrapp.P_READ_DATA);endboard.RP.tx_usrapp.TSK_TX_CLK_EAT(10);board.RP.tx_usrapp.DEFAULT_TAG = board.RP.tx_usrapp.DEFAULT_TAG + 1;end2'b10 : // MEM 32 SPACEbegin$display("[%t] : Transmitting TLPs to Memory 32 Space BAR %x", $realtime,board.RP.tx_usrapp.ii);//--------------------------------------------------------------------------// Event : Memory Write 32 bit TLP//--------------------------------------------------------------------------board.RP.tx_usrapp.DATA_STORE[0] = 8'h04;board.RP.tx_usrapp.DATA_STORE[1] = 8'h03;board.RP.tx_usrapp.DATA_STORE[2] = 8'h02;board.RP.tx_usrapp.DATA_STORE[3] = 8'h01;board.RP.tx_usrapp.TSK_TX_MEMORY_WRITE_32(board.RP.tx_usrapp.DEFAULT_TAG,board.RP.tx_usrapp.DEFAULT_TC, 10'd1,board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii][31:0]+8'h10, 4'h0, 4'hF, 1'b0);board.RP.tx_usrapp.TSK_TX_CLK_EAT(10);board.RP.tx_usrapp.DEFAULT_TAG = board.RP.tx_usrapp.DEFAULT_TAG + 1;//--------------------------------------------------------------------------// Event : Memory Read 32 bit TLP//--------------------------------------------------------------------------// make sure P_READ_DATA has known initial valueboard.RP.tx_usrapp.P_READ_DATA = 32'hffff_ffff;forkboard.RP.tx_usrapp.TSK_TX_MEMORY_READ_32(board.RP.tx_usrapp.DEFAULT_TAG,board.RP.tx_usrapp.DEFAULT_TC, 10'd1,board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii][31:0]+8'h10, 4'h0, 4'hF);board.RP.tx_usrapp.TSK_WAIT_FOR_READ_DATA;joinif  (board.RP.tx_usrapp.P_READ_DATA != {board.RP.tx_usrapp.DATA_STORE[3],board.RP.tx_usrapp.DATA_STORE[2], board.RP.tx_usrapp.DATA_STORE[1],board.RP.tx_usrapp.DATA_STORE[0] })begin$display("[%t] : Test FAILED --- Data Error Mismatch, Write Data %x != Read Data %x",$realtime, {board.RP.tx_usrapp.DATA_STORE[3],board.RP.tx_usrapp.DATA_STORE[2],board.RP.tx_usrapp.DATA_STORE[1],board.RP.tx_usrapp.DATA_STORE[0]},board.RP.tx_usrapp.P_READ_DATA);test_failed_flag = 1;endelsebegin$display("[%t] : Test PASSED --- Write Data: %x successfully received",$realtime, board.RP.tx_usrapp.P_READ_DATA);endboard.RP.tx_usrapp.TSK_TX_CLK_EAT(10);board.RP.tx_usrapp.DEFAULT_TAG = board.RP.tx_usrapp.DEFAULT_TAG + 1;end2'b11 : // MEM 64 SPACEbegin$display("[%t] : Transmitting TLPs to Memory 64 Space BAR %x", $realtime,board.RP.tx_usrapp.ii);//--------------------------------------------------------------------------// Event : Memory Write 64 bit TLP//--------------------------------------------------------------------------board.RP.tx_usrapp.DATA_STORE[0] = 8'h64;board.RP.tx_usrapp.DATA_STORE[1] = 8'h63;board.RP.tx_usrapp.DATA_STORE[2] = 8'h62;board.RP.tx_usrapp.DATA_STORE[3] = 8'h61;board.RP.tx_usrapp.TSK_TX_MEMORY_WRITE_64(board.RP.tx_usrapp.DEFAULT_TAG,board.RP.tx_usrapp.DEFAULT_TC, 10'd1,{board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii+1][31:0],board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii][31:0]+8'h20}, 4'h0, 4'hF, 1'b0);board.RP.tx_usrapp.TSK_TX_CLK_EAT(10);board.RP.tx_usrapp.DEFAULT_TAG = board.RP.tx_usrapp.DEFAULT_TAG + 1;//--------------------------------------------------------------------------// Event : Memory Read 64 bit TLP//--------------------------------------------------------------------------// make sure P_READ_DATA has known initial valueboard.RP.tx_usrapp.P_READ_DATA = 32'hffff_ffff;forkboard.RP.tx_usrapp.TSK_TX_MEMORY_READ_64(board.RP.tx_usrapp.DEFAULT_TAG,board.RP.tx_usrapp.DEFAULT_TC, 10'd1,{board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii+1][31:0],board.RP.tx_usrapp.BAR_INIT_P_BAR[board.RP.tx_usrapp.ii][31:0]+8'h20}, 4'h0, 4'hF);board.RP.tx_usrapp.TSK_WAIT_FOR_READ_DATA;joinif  (board.RP.tx_usrapp.P_READ_DATA != {board.RP.tx_usrapp.DATA_STORE[3],board.RP.tx_usrapp.DATA_STORE[2], board.RP.tx_usrapp.DATA_STORE[1],board.RP.tx_usrapp.DATA_STORE[0] })begin$display("[%t] : Test FAILED --- Data Error Mismatch, Write Data %x != Read Data %x",$realtime, {board.RP.tx_usrapp.DATA_STORE[3],board.RP.tx_usrapp.DATA_STORE[2], board.RP.tx_usrapp.DATA_STORE[1],board.RP.tx_usrapp.DATA_STORE[0]}, board.RP.tx_usrapp.P_READ_DATA);test_failed_flag = 1;endelsebegin$display("[%t] : Test PASSED --- Write Data: %x successfully received",$realtime, board.RP.tx_usrapp.P_READ_DATA);endboard.RP.tx_usrapp.TSK_TX_CLK_EAT(10);board.RP.tx_usrapp.DEFAULT_TAG = board.RP.tx_usrapp.DEFAULT_TAG + 1;enddefault : $display("Error case in usrapp_tx\n");endcaseend$display("[%t] : Finished transmission of PCI-Express TLPs", $realtime);if (!test_failed_flag) begin $display ("Test Completed Successfully");end $finish;
end

_编译xilinx仿真库_ip核仿真

可以看到任务功能为:这个测试执行对32位内存空间的32位写操作,并执行回读操作。

2.2 仿真结果

这里使用 进行仿真分析。

仿真完成后,可以在[工程名][工程名].sim\sim_1\behav文件夹中的.log文件查看到仿真过程中打印的一些消息:

# Running default test {pio_writeReadBack_test0}......
# [                   0] : System Reset Asserted...
# [             4995000] : System Reset De-asserted...
# [            64025511] : Transaction Reset Is De-asserted...
# [            65025384] : Transaction Link Is Up...
# [            65057284] : TSK_PARSE_FRAME on Transmit
# [            66473286] : TSK_PARSE_FRAME on Receive
# [            69057326] :    Check Max Link Speed = 2.5GT/s - PASSED
# [            69057326] : Check Negotiated Link Width = 4x - PASSED
# [            69081328] : TSK_PARSE_FRAME on Transmit
# [            70329322] : TSK_PARSE_FRAME on Receive
# [            73081380] :    Check Device/Vendor ID - PASSED
# [            73105380] : TSK_PARSE_FRAME on Transmit
# [            74353380] : TSK_PARSE_FRAME on Receive
# [            77105265] :    Check CMPS ID - PASSED
# [            77105265] : SYSTEM CHECK PASSED
# [            77105265] : Inspecting Core Configuration Space...
# [            77129270] : TSK_PARSE_FRAME on Transmit
# [            77953284] : TSK_PARSE_FRAME on Transmit
# [            78361307] : TSK_PARSE_FRAME on Receive
# [            79201284] : TSK_PARSE_FRAME on Receive
# [            81977392] : TSK_PARSE_FRAME on Transmit
# [            82801289] : TSK_PARSE_FRAME on Transmit
# [            83209392] : TSK_PARSE_FRAME on Receive
# [            84049303] : TSK_PARSE_FRAME on Receive
# [            86825284] : TSK_PARSE_FRAME on Transmit
# [            87649322] : TSK_PARSE_FRAME on Transmit
# [            88057284] : TSK_PARSE_FRAME on Receive
# [            88897326] : TSK_PARSE_FRAME on Receive
# [            91673380] : TSK_PARSE_FRAME on Transmit
# [            92497270] : TSK_PARSE_FRAME on Transmit
# [            92905380] : TSK_PARSE_FRAME on Receive
# [            93745265] : TSK_PARSE_FRAME on Receive
# [            96521284] : TSK_PARSE_FRAME on Transmit
# [            97345392] : TSK_PARSE_FRAME on Transmit
# [            97753284] : TSK_PARSE_FRAME on Receive
# [            98593408] : TSK_PARSE_FRAME on Receive
# [           101369290] : TSK_PARSE_FRAME on Transmit
# [           102193284] : TSK_PARSE_FRAME on Transmit
# [           102601364] : TSK_PARSE_FRAME on Receive
# [           103441284] : TSK_PARSE_FRAME on Receive
# [           106217322] : TSK_PARSE_FRAME on Transmit
# [           107041380] : TSK_PARSE_FRAME on Transmit
# [           107449322] : TSK_PARSE_FRAME on Receive
# [           108289380] : TSK_PARSE_FRAME on Receive
# [           111041269] PCI EXPRESS BAR MEMORY/IO MAPPING PROCESS BEGUN...
# 	BAR 0: VALUE = 00000000 RANGE = ffffe000 TYPE =  MEM32 MAPPED
# 	BAR 1: VALUE = 00000000 RANGE = 00000000 TYPE =      DISABLED
# 	BAR 2: VALUE = 00000000 RANGE = 00000000 TYPE =      DISABLED
# 	BAR 3: VALUE = 00000000 RANGE = 00000000 TYPE =      DISABLED
# 	BAR 4: VALUE = 00000000 RANGE = 00000000 TYPE =      DISABLED
# 	BAR 5: VALUE = 00000000 RANGE = 00000000 TYPE =      DISABLED
# 	EROM : VALUE = 00000000 RANGE = 00000000 TYPE =      DISABLED
# [           111041269] : Setting Core Configuration Space...
# [           111065277] : TSK_PARSE_FRAME on Transmit
# [           111889284] : TSK_PARSE_FRAME on Transmit
# [           112297271] : TSK_PARSE_FRAME on Receive
# [           112713380] : TSK_PARSE_FRAME on Transmit
# [           113129284] : TSK_PARSE_FRAME on Receive
# [           113537290] : TSK_PARSE_FRAME on Transmit
# [           113945411] : TSK_PARSE_FRAME on Receive
# [           114361284] : TSK_PARSE_FRAME on Transmit
# [           114769303] : TSK_PARSE_FRAME on Receive
# [           115185322] : TSK_PARSE_FRAME on Transmit
# [           115593284] : TSK_PARSE_FRAME on Receive
# [           116009380] : TSK_PARSE_FRAME on Transmit
# [           116417326] : TSK_PARSE_FRAME on Receive
# [           116833284] : TSK_PARSE_FRAME on Transmit
# [           117241380] : TSK_PARSE_FRAME on Receive
# [           117657284] : TSK_PARSE_FRAME on Transmit
# [           118065265] : TSK_PARSE_FRAME on Receive
# [           118889284] : TSK_PARSE_FRAME on Receive
# [           125657292] : Transmitting TLPs to Memory 32 Space BAR 0
# [           125681289] : TSK_PARSE_FRAME on Transmit
# [           125785277] : TSK_PARSE_FRAME on Transmit
# [           126993313] : TSK_PARSE_FRAME on Receive
# [           129761284] : Test PASSED --- Write Data: 01020304 successfully received
# [           129841285] : Finished transmission of PCI-Express TLPs
# Test Completed Successfully
# ** Note: $finish    : ../../../imports/sample_tests1.vh(325)
#    Time: 129841285 ps  Iteration: 6  Instance: /board/RP/tx_usrapp
# 1
# Break in Module pci_exp_usrapp_tx at ../../../imports/sample_tests1.vh line 325

2.2.1 用到的任务说明

首先需要大概知道st0调用的一些基本子任务的功能,在【PG054】7 Block for PCI IP核的学习中2.6.1 Root Port模型TPI任务列表 章节介绍了一些,其他在PG054中可以查到。

其中,主要的几个任务功能大致说明:

任务说明

配置0读请求;TLP头大小为3个双字( word);不带数据

配置1读请求;TLP头大小为3个双字( word);不带数据

配置0写请求;TLP头大小为3个双字( word);带数据

配置1写请求;TLP头大小为3个双字( word);带数据

TSK_TX_TYPE0_CONFIGURATION_READ(tag_,reg_addr_,first_dw_be_)
报头byte0-7: trn_td <= #(Tcq){1'b0,2'b00,5'b00100,1'b0,3'b000,4'b0000,1'b0,1'b0,2'b00,2'b00,10'b0000000001,  // 32REQUESTER_ID, //COMPLETER_ID_CFG,tag_,4'b0000,first_dw_be_     // 64};
报头byte8-15:trn_td <= #(Tcq){COMPLETER_ID_CFG,4'b0000,reg_addr_[11:2],2'b00,32'b0};

配置请求报文头格式为:

对照任务与对应的配置请求报文头格式,我们就知道具体请求的含义了。以这个任务为例说明,其他任务的分析方法是类似的。

Non-请求需要完成报文来应答,才能结束一次完成的数据传递。如果发送端没有收到完成报文,则这个tag不能再次使用,直到这个tag的请求结束。

2.2.2 PCIe配置空间

PCIe配置空间包含三个主要的部分:

传统的PCI V3.0 类型0/1 配置空间头: 0x00~0x3F

传统的拓展配置空间: 0x40~0xFF

PCIe拓展配置空间:0x100~0xFFF

2.2.2 仿真执行过程分析: 的相关初始化

可以看到前两条消息为执行的相关初始化过程发出的,表示执行的任务名称为{st0}。

st0.line6: 设置board.RP..的值为10050。

line8: ATION

检查Link Speed/Width:

查找PCIe标准,PCIe配置空间地址12’h70对应的寄存器名称为:Link (31:16) Link (15:0)

关于接收数据这里不细说,大概的路径是:收到数据 -> .对数据进行处理 -> 收到的数据按字节存储在.[.]中,其中指针随着收到的数据自增 -> .对这一帧数据进行解析。其中首先执行对此帧进行解析,输出fmt, , , td, ep, attr, 等信息,然后执行任务根据解析出来的信息进一步解析,然后执行board.RP..将解析后的数据传递给, 在中将收到的数据存在寄存器中。

可以看到=32’=32’。

Link . Link Speed字段 = [19:16] = 4’b0001。所以输出消息“Check Max Link Speed = 2.5GT/s - ”。

Link . Link Width字段 = [23:20] = 4’b0100。所以输出消息“Check Link Width = 4x - ”。

检查Check / ID 与 检查CMPS 的分析过程类似,这里不再赘述。

:

PCI总线规范规定了获取BAR空间的标准实现方法。其步骤是首先向BAR寄存器全写1,之后再读取BAR寄存器的内容,即可获得BAR空间的大小。PCIe兼容PCI。

所以我们可以看到这个任务分别向12’h10(BAR0)、12’h14(BAR1)、12’h18(BAR2)、12’h1C(BAR3)、12’h20(BAR4)、12’h24(BAR5)和12’h30(ROM BAR)写了(32’),再读取BAR的内容即范围并保存到寄存器:

当然,与我们设置的参数一致:

可以看到这里根据读取的一些信息对寄存器ED进行赋值,各BAR对应此寄存器的含义为:

值含义

bar is io

bar is mem32

bar is mem64

消息~53:

~194: 进行BAR映射空间的读写测试

首先判断BAR是否使能,然后判断BAR的映射方式。

往board.RP..[board.RP..ii][31:0]+8’h10,也就是8’h10中写{[0],[1],[2],[3]}={8’h04,8’h03,8’h02,8’h01}。

读取这个地址的数据并进行比对,如果一直输出消息“Test — Write Data: ”。

整个仿真的过程就是这样啦。

//每次摆开阵势想要好好看看,总被打断,耗了这么久终于分析完了,通过这个仿真,可以很好的理解PCIe的相关知识。包括事务类型,BAR的配置与分析等等,还是很不错的过程。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了