axi ps读写pl_【干货分享】Xilinx MPSoC PS/PL之间的数据交互和外设设计

0 1 概述

MPSoC是Xilinx基于16nm工艺推出的异构计算平台,由于灵活、稳定,在业界得到了广泛的使用。异构计算是一个比较新的领域,需要协调硬件设计、逻辑设计、软件设计,对工程师的要求很高。实际设计过程中,很多工程师对实现PS/PL之间的数据交互感到头疼。

本文将介绍主要的PS/PL之间的数据交互办法。

0 2 MPSoC PS/PL之间的数据通路

在开始之前,首先简要介绍PS/PL之间的数据通路,请参考 《UG1085 Zynq UltraScale+ MPSoC Technical Reference Manual》的Figure 1-1: AXI Interconnect。

75398748540e8c70534e3e075b0dbb75.png

PS/PL之间的数据通路主要是通用的AXI Memory接口,其中PS作为主设备的接口有128-bit位宽的HPM0/HPM1, 64-bit位宽的LPD_PL; PL作为主设备的接口有ACP/ACE/HPC0/HPC1/HP0/HP1/HP2/HP3。所有AXI Memory接口的位宽最高都可以支持到128-bit。

PS/PL之间主要通过PS-DDR交互大块数据。从Figure 1-1可以看到,PS-DDR控制器有六个AXI Slave接口,与PL直接相关的是S3、S4、S5。HPC0/HPC1都连接到了CCI Interconnect。DP和HP0连接到了S3。HP1和HP2连接到了S4。HP3和FP DMA连接到了S5。如果需要提高带宽,要充分利用PS-DDR控制器的AXI Slave接口。如果可能,HP1和HP2最好不要同时用,因为HP1和HP2都连接到了S4,最后会彼此竞争带宽。

UG1085的Figure 1-1提供了最详细的信息, 也有点复杂。为了简单,也可以参考下面来自于《Zynq UltraScale+ MPSoC Technical Overview》的简化示意图。

41c8e30d31d2c04e6f79f1423203ead2.png

在Vivado的IP 里,使能相关接口后,接口如下。

fae5fad5e1e4c051442fcbb29d14e83f.png
0 3 MPSoC PS/PL之间的简单数据通路和简单外设设计

很多时候,PS/PL之间只需要简单的数据通路。PS只需要下发有限的参数给PL,PL只需要向PS反馈有限的状态数据。串口、SPI设备、IIC等低速接口,就属于这种设备。这种情况下,PL内部只需要实现AXI Slave接口和一些寄存器就可以,PS通过AXI接口去访问寄存器,既向PL提供参数,也可以读回PL的状态。

客户可以自己设计AXI接口和寄存器,也可以使用Vivado里的工具Create and Package IP。

0 4 使用Vivado里的工具Create and Package IP创建IP

如果使用Vivado里的工具Create and Package IP创建IP,可以参照下列步骤。

1) 调用Vivado的Create and Package IP 模板

d85b32846254cd49e2c25207d11746db.png

2) Create and Package IP 模板介绍

352630723aa204335122f3269d9acb0d.png

3)新建IP
这一步选择"Create a new AXI4 peripheral"。

127b9456c114e0f660be66fb404c9365.png

4) IP命名和目录
根据自己需要,指定IP的名称和目录。

39d0d01c069aef56538ed2cd3930b4da.png

5) IP接口选择
可以看到,只为新的IP选择了AXI Lite接口,并实现了16个寄存器。工程师可以根据需要选择寄存器个数,最小4个,最多512个。对于AXI Lite接口,数据位宽是32-bit。

e2c7eb60b564f61606bc0ce1e20c49e0.png

6) 完成IP创建
选择“Add IP to the repository”, 点击"Finish", 完成IP创建。

424bff36380db10462da344d20a0e767.png

7) BD框图
在Block Design中,选择对应的IP。示例中是MyIP。添加后,在Block Design中,得到如下IP。可以看到,MyIP有一个AXI Slave接口,及其对应的时钟和复位信号。

332639a2e334603d6bd766ae46540c8d.png

8) BD设计
AXI Lite的外设很简单,只有一个AXI Slave接口,及其对应的时钟和复位信号。把AXI Slave接口通过AXI Interconnect连接到某个PS的AXI Master接口,示例是M_AXI_HPM0_FPD,再提供对应的时钟和复位信号就可以。AXI连接两侧的Mater和Slave必须使用同一个时钟和复位信号。

5b9f414566d0ac5aff89471d9e6debb4.png

9) 代码分析
创建IP后,在指定的目录下,得到如下的文件夹和和文件。

myip_1.0
│ component.xml

├─bd
│ bd.tcl

├─example_designs
│ ├─bfm_design
│ │ design.tcl
│ │ myip_v1_0_tb.sv
│ │
│ └─debug_hw_design
│ design.tcl
│ myip_v1_0_hw_test.tcl

├─hdl
│ myip_v1_0.v
│ myip_v1_0_S00_AXI.v

└─xgui
myip_v1_0.tcl

myip_v1_0_S00_AXI.v里实现了寄存器及其读写逻辑。

实现寄存器的Verilog HDL代码:

//----------------------------------------------
//-- Signals for user logic register space example
//------------------------------------------------
//-- Number of Slave Registers 16
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg4;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg5;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg6;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg7;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg8;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg9;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg10;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg11;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg12;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg13;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg14;
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg15;

寄存器写操作的Verilog HDL代码的部分片段:

 if (slv_reg_wren)
begin
case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
4'h0:
for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
if ( S_AXI_WSTRB[byte_index] == 1 ) begin
// Respective byte enables are asserted as per write strobes
// Slave register 0
slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
end
... ...
default : begin
slv_reg0 <= slv_reg0;
... ...
slv_reg15 <= slv_reg15;
end
endcase
end

寄存器读操作的Verilog HDL代码的部分片段:

// Implement memory mapped register select and read logic generation
// Slave register read enable is asserted when valid address is available
// and the slave is ready to accept the read address.
assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
always @(*)
begin
// Address decoding for reading registers
case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
4'h0 : reg_data_out <= slv_reg0;
4'h1 : reg_data_out <= slv_reg1;
4'h2 : reg_data_out <= slv_reg2;
4'h3 : reg_data_out <= slv_reg3;
4'h4 : reg_data_out <= slv_reg4;
4'h5 : reg_data_out <= slv_reg5;
4'h6 : reg_data_out <= slv_reg6;
4'h7 : reg_data_out <= slv_reg7;
4'h8 : reg_data_out <= slv_reg8;
4'h9 : reg_data_out <= slv_reg9;
4'hA : reg_data_out <= slv_reg10;
4'hB : reg_data_out <= slv_reg11;
4'hC : reg_data_out <= slv_reg12;
4'hD : reg_data_out <= slv_reg13;
4'hE : reg_data_out <= slv_reg14;
4'hF : reg_data_out <= slv_reg15;
default : reg_data_out <= 0;
endcase
end

根据需要,可以将寄存器的某个bit,作为控制信号,连接到应用的逻辑代码。也可以将应用逻辑代码的某些信号,作为状态信号,连接到寄存器的某个bit,做状态信号,供CPU读取。

软件

简单外设只有寄存器,软件靠读写寄存器,就能实现对硬件的控制。

0 5 DMA外设设计

如果外设的数据量大,速率要求高,建议使用DMA搬移数据,使PS和PL通过DDR共享数据。

Vivado的工具Create and Package IP同样可以创建支持DMA功能的IP。大部分步骤,和前述“简单数据通路”一样。在“AXI Interfaces”窗口,除了“AXI Lite”接口以外,还要增加“AXI Full Master”接口。

1) 新建AXI接口
在“AXI Interfaces”窗口,点击“+”按钮,能创建一个新的接口。

5e0c00825ed3c29f1d048f07810ac571.png

2) 添加AXI Master接口
在弹出的接口中,为“Interface Type”选择"Full",为“Interface Mode”选择"Master"。


后续操作,和简单外设的操作一样。

1fa672be0881e3084d94569b4df300c9.png

3)BD框图
在Block Design中,选择对应的IP。示例中是myip_dma。添加后,在Block Design中,得到如下IP。可以看到,myip_dma多了一个AXI Master接口“M00_AXI”和对应的时钟和复位信号。值得注意的是,myip_dma还多了输入信号m00_axi_init_axi_txn,输出信号m00_axi_txn_done和m00_axi_error。m00_axi_init_axi_txn用于发起写/读传输;m00_axi_txn_done和m00_axi_error由于指示传输是否完成。

6642a612bad54222f002d7b7c98b87f4.png

4) 代码分析
带有DMA的IP的文件如下。

myip_dma_1.0
│ component.xml

├─bd
│ bd.tcl

├─example_designs
│ ├─bfm_design
│ │ design.tcl
│ │ myip_dma_v1_0_tb.sv
│ │
│ └─debug_hw_design
│ design.tcl
│ myip_dma_v1_0_hw_test.tcl

├─hdl
│ myip_dma_v1_0.v
│ myip_dma_v1_0_M00_AXI.v
│ myip_dma_v1_0_S00_AXI.v

└─xgui
myip_dma_v1_0.tcl

AXI Master的HDL代码在文件myip_dma_v1_0_M00_AXI.v中,它实现了通过AXI Master端口写数据、读数据的功能。读写的地址由参数C_M_TARGET_SLAVE_BASE_ADDR指定。

工程师需要根据自己的需要,修改相关逻辑。上述AXI Master示例中,只能向固定地址发起成对的写、读操作。在实际工程中,地址通常由软件配置,写、读操作也经常分开。

软件

DMA外设通常需要由软件配置DMA操作的目标内存。如果是standalone(baremetal,裸核)代码,缺省情况下物理地址和软件地址一样,直接向DMA的内存地址寄存器写入软件得到的地址就可以。如果是Linux下,需要先把软件地址转换成硬件地址,再写入DMA的内存地址寄存器。

0 6 AXI Stream外设设计

在自己IP里集成DMA,可以根据项目需求定制DMA的功能,实现最优的性能,但是也会带来设计和维护的工作量。

为了降低工作量,可以使用现成的DMA,并在IP里增加AXI Stream接口,对接AXI DMA,实现DMA功能。

 大部分步骤,仍然和前述“简单数据通路”一样。在“AXI Interfaces”窗口,除了“AXI Lite”接口以外,选择要增加“AXI Stream Slave”接口, 和“AXI Stream MasterMaster”接口。

1) 新建AXI接口
在“AXI Interfaces”窗口,点击“+”按钮,能创建一个新的接口。

85faafaf2d4141deecf7d61e5518d87b.png

2) 添加AXI Streamm口
在弹出的接口中,为“Interface Type”选择"Stream",为“Interface Mode”选择"Master"或者"Slave"。示例中,既添加了AXI Streamm的Master,也添加了AXI Streamm的Master。实际工程中,工程师可以根据需要只添加其中一个,或者添加多个同样的接口。AXI Streamm的Slave,也被称为Sink;AXI Streamm的Master,也被称为Source。

后续操作,和简单外设的操作一样。

3) BD框图
在Block Design中,选择对应的IP。示例中是myip_stream。添加后,在Block Design中,得到如下IP。可以看到,myip_stream多了一个AXI Stream Master接口,也多了一个AXI Streamm Slave,及其对应的时钟和复位信号。

e7cefcd40dd4fee597f48d9ced6ac362.png

4) AXI-DMA接口
AXI Streamm需要和IP AXI DMA搭配使用。使用AXI DMA的简单配置就可以,比如如下配置。

a0750b7610c32fb6b0a17ce066939340.png

AXI DMA有一个AXI Lite接口,用于PS配置;有3个 AXI Master接口,M_AXI_SG, M_AXI_MM2S, M_AXI_S2MM,用于访问DDR等存储器;另外还有两个Stream接口,M_AXIS_MM2S, M_AXIS_S2MM,用于通过AXI Streamm接口交换数据。

AXI-DMA连接

如下图所示,AXI DMA的AXI Lite接口,通过AXI Interconnect 连接到PS AXI Master接口,比如HPM0_FPD,供PS访问。

AXI DMA的3个AXI Master接口,M_AXI_SG, M_AXI_MM2S, M_AXI_S2MM,通过AXI Interconnect 连接到PS的AXI Slave接口,比如S_AXI_HP0_FPD。AXI DMA的两个Stream接口,M_AXIS_MM2S连接到用户IP的S00_AXIS, M_AXIS_S2MM连接到用户IP的M00_AXIS。

通过AXI DMA的驱动,软件可以发起MM2S传输,AXI DMA先通过M_AXI_SG从PS-DDR里读取DMA的描述符,得到数据的源地址,再通过M_AXIS_MM2S从PS-DDR里读取数据。软件也可以发起S2MM传输,AXI DMA先通过M_AXI_SG从PS-DDR里读取DMA的描述符,得到数据的目标地址,再通过M_AXIS_S2MM向PS-DDR里写数据。MM2S传输和S2MM传输既可以分开使用,也可以联合使用。如果联合使用,相当于从PS-DDR到PS-DDR的内存搬移工作。

4258ccc329acb3ed22e3d9eab28ce093.png

软件

AXI-DMA的相关软件设计,请参考 MPSoC逻辑加速模块数据通道快速设计。

0 7 PL外设其它接口 7.1. 中断接口

用户外设还经常用到中断,用于向PS产生中断,通知某些事件。Vivado的工具Create and Package IP也可以创建支持中断功能的IP。大部分步骤,和前述“简单数据通路”一样。在“AXI Interfaces”窗口,勾选“Enable Interrupt Support”, 会得到一个S_AXI_INTR接口和一个中断输出信号irq。

284c54c6e0308139cc1d08c220b53533.png

通过AXI Interconnect,把S00_AXI和S_AXI_INTR接口连接连接到PS AXI Master接口,比如HPM0_FPD,供PS访问。把中断输出信号irq,通过IP Concat连接到PS的输入pl_ps_irq。

b4d52c5e37cf2531186b2f5497f7c5ce.png

EMIO接口

PS还提供了简单的GPIO接口:EMIO。

fc4d885412d57e1e500d78068ee0949d.png

在PS的配置界面下的GPIO里,使能EMIO,根据自己的需要选择数量。然后在BD界面下,就能看见EMIO的信号,包括输出、输入、和三态信号。工程师可以把自己的信号连接到EMIO信号上,就能使用。

4e912d4959e3271947f02e3d5215778d.png

软件通过访问GGPIO的Bank 3/4/5,可以控制GPIO,包括操作输出状态,和读取输入电平。

软件经常需要检查PL是否正常工作。很多时候,软件靠检查PL加载的done信号来确定。但done只能保证PL已经被加载,不能保证PL已经正常工作。比如,如果PL使用外部时钟,在外部时钟故障时,PL即使已经被加载,也没有工作。这时候,PS去访问PL的寄存器,会导致PS死机。更好的办法是,PL通过EMIO向PS反馈PL是否已经正常工作。比如PL实现计数器,把计数器的输出连接到EMIO的输入。软件读取EMIO的输入值,如果在变化,说明PL的计数器已经正常工作,那么就代表PL已经正常工作。

0 8 AXI Firewall

在开发过程中,可能有各种异常状况。如果 AXI传输出现异常,可能导致PS死机,影响调试。为了提高系统可靠性,可以使用Xilinx提供的IP -- AXI Firewall,把它插在正常的AXI Master和 AXI Slave接口之间。下图是AXI Firewall的连接示例。

c84b0964dbe2b607051492deb66f8f5c.png

使用软件使能 AXI Firewall后,如果AXI传输出现异常,AXI Firewall会正常结束AXI传输,保证软件继续运行,工程师可以检查AXI传输的错误。AXI Firewall输出的错误信号和中断信号,都可以连接到PS GPIO,或者ILA。工程师可以读出具体的错误信息。

0 9 参考文档

Zynq UltraScale+ MPSoC Embedded Design Methodology Guide 2017-03-31

Zynq UltraScale+ MPSoC Software Developers Guide 2019-07-01
Zynq UltraScale+ MPSoC Embedded Design Tutorial 2018-07-31
Zynq UltraScale+ MPSoC Technical Reference Manual 2019-08-21
UltraFast Embedded Design Methodology Guide 2018-04-20
Introducing the UltraFAST Embedded Design Methodology Checklist 2014-06-10

682b4b1820afe87a8d0d99672f003581.gif 932dd766dd6eda0e79c5710ffcd484c5.gif 98d1812cf8e5b36caff172974ec23c0a.png 932dd766dd6eda0e79c5710ffcd484c5.gif 关注我们

770b899758ecb36ca91525ca25a0518d.png

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页

打赏

帝哲

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者