ZYNQ PS-PL数据交互方式总结

一,中断:

二,IO方式:MIO EMIO GPIO

MIO分配在bank0和bank1直接与PS部分相连,EMIO分配在bank2和接和PL部分相连。除了bank1是22-bit之外,其他的bank都是32-bit。所以MIO有53个引脚可供我们使用,而EMIO有64个引脚可供我们使用。
使用EMIO的好处就,当MIO不够用时,PS可以通过驱动EMIO控制PL部分的引脚,接下来就来详细介绍下EMIO的使用。
EMIO的使用和MIO的使用其实是非常相似的。区别在于,EMIO的使用相当于,是一个PS + PL的结合使用的例子。所以,EMIO需要分配引脚,以及编译综合生成bit文件。
1 MIO与EMIO概念
MIO:多功能IO接口,属于Zynq的PS部分,在芯片外部有54个引脚。这些引脚可以用在GPIO、SPI、UART、TIMER、Ethernet、USB等功能上,每个引脚都同时具有多种功能,故叫多功能。
EMIO:扩展MIO,依然属于Zynq的PS部分,只是连接到了PL上,再从PL的引脚连到芯片外面实现数据输入输出。
 
2 MIO与EMIO的使用例程(双串口、双网口等的实现)
以双串口为例:
实现功能:
①   实现数据直接从PS的MIO口接收与发送
②   通过PL口实现数据的接收与发送
③   实现数据的双串口接收与发送(即PS可同时从两个UART口接收或发送数据)

例如:https://blog.csdn.net/wangjie36/article/details/104765783

三,BRAM或FIFO或EMIF

1,通过BRAM实现PL/PS之间交互

(1)PS 的配置如下图所示。使能 M_AXI_GP0 口,将 FCLK_CLK0 设为 100MHz ,使能 PL PS 的中断。
(2)AXI BRAM Controller   IP 核连接 PS M_AXI_GP0 口和 BRAM ,完成 AXI 接口至 BRAM 接口的转换。
(3)添加 BRAM ,将 BRAM 设置为双口 RAM ,将 PORTA AXI BRAM Controller 连接, PS 通过 PORTA 读写 BRAM ,将 PORTB 引出至外部模块, PL 通过 PORTB 读写 BRAM
(4)由于要与 AXI BRAM Controller 进行连接, BRAM 接口的位宽固定为 32 位。 BRAM 的深度无法在该 IP 中进行设置,需要在所有模块连接完成后,在 Address Editor 里对 AXI BRAM Controller 的地址范围进行设置,这里 设置为 4KB。该地址范围即对应 BRAM 的深度。Other Options中去掉 Enable Safety Circuit的勾选。

2,通过AXI-Stream FIFO完成PS和PL部分的数据交互

S_AXI,PS读写FIFO数据接口;AXI_STR_TXC,发送控制端口;AXI_STR_TXD,发送数据端口;AXI_STR_RXD,接收数据端口

AXI DATA FIFO,读接口AXI4-FILL,写接口AXI4-FULL。

AXI-Stream FIFO,读接口PS AXI4-LITTLE,写接口PL AXI4-LITTLE。

使用AXI-Stream FIFO,FCLK_CLK0使用100MHz时,有警告。50MHz,125MHz没有发现警告

3,通过 EMIF 进行 PS 与 PL 间数据交互

(1)位宽设置为 32bit 其他参数默认,其中 Base Address High Address AXI_EMC IP ZYNQ 4GB 地址空间中的分配的地址
(2)设置 Memory Type Async SRAM , 也就是异步 SRAM 。这种 SRAM 读写起来比较方便。位宽设置为 32bit Timing Parameters AXI 系统时钟为 100M 的情况下的时间参数,如果采用其他时钟可能要修改时间参数。

四,AXI DMA:PS通过AXI-lite向AXI DMA发送指令,AXI DMA通过HP通路和DDR交换数据,PL通过AXI-S读写DMA的数据。

此处详细讲,很多内容敬请期待一步步更新:

首先PS通过AXI-lite配置DMA的工作模式,然后,PS将数据写入DDR,再然后,PS控制DMA读出之前写入的数据,将数据流写入FIFO(读完后DMA会向PS发送中断),再然后,PS控制DMA将FIFO的数据流再通过AXI总线写回DDR(写完后DMA会向PS发送中断),PS判断写入的数据和读出的数据是否一致。

Tries为测试次数,TxBufferPtr的地址为DMA发送的数据到设备的地址,RxBufferPtr地址则是设备发给DMA的存储地址,MAX_PKT_LEN为一次测试的测试长度,数据从0x55开始递增。

一次测试的过程:

PS的 for 循环产生数据—>PS的数据写入DDR—>PS配置DMA接收通道—>PS配置DMA发送通道(数据开始发送)—>发送的数据经过FIFO回到DMA—>DMA中断到达后观察数据—>进行下一次测试

五,DDR3:通过对AXI HP接口的操作来实现。

PL实现AXI4接口,通过S AXI HP接口读取ps侧DDR3数据. 例程功能:PL,PS向指定地址写数据,对方来读。

AXI-DMA:实现从PS内存到PL高速传输高速通道AXI-HP<---->AXI-Stream的转换
AXI-Datamover:实现从PS内存到PL高速传输高速通道AXI-HP<---->AXI-Stream的转换,完全由PL控制的,PS是完全被动的。
AXI-VDMA:实现从PS内存到PL高速传输高速通道AXI-HP<---->AXI-Stream的转换,是专门针对视频、图像等二维数据的。
AXI-CDMA IP: 这个是由PL完成的将数据从内存的一个位置搬移到另一个位置,无需CPU来插手。和Stream没有关系。

六,AXI_HP总线:只能单向传输,从PL到PS端,适用于大数据传输。

1,无DMA的HP总线:https://blog.csdn.net/wangjie36/article/details/119297947

2,使用DMA的HP总线:https://blog.csdn.net/wangjie36/article/details/119110701

七,AXI_GP总线:可以从PS到PL传输,也可以PL到PS传输,适用于数据量不大的数据传输。

https://blog.csdn.net/wangjie36/article/details/115486926

八,内部回环串口

module system_wrapper
   (
    //uart_rtl_0_rxd,
    //uart_rtl_0_txd,
    uart_rtl_1_rxd,
    uart_rtl_1_txd,
    sys_clk,
    sys_rst_n);

  //input uart_rtl_0_rxd;
  //output uart_rtl_0_txd;
  input uart_rtl_1_rxd;
  output uart_rtl_1_txd;
  input sys_rst_n;
  input sys_clk;

  wire [7:0]gpio_rtl_0_tri_o;
  wire uart_rtl_0_rxd;
  wire uart_rtl_0_txd;
  wire uart_rtl_1_rxd;
  wire uart_rtl_1_txd;

  system system_i
       (
        .uart_rtl_0_rxd(uart_rtl_0_rxd),
        .uart_rtl_0_txd(uart_rtl_0_txd),
        .uart_rtl_1_rxd(uart_rtl_1_rxd),
        .uart_rtl_1_txd(uart_rtl_1_txd));
        
        
        //parameter define
        parameter  CLK_FREQ = 100000000;         //定义系统时钟频率
        parameter  UART_BPS = 115200;           //定义串口波特率
     
        //wire define   
        wire       uart_recv_done;              //UART接收完成
        wire [7:0] uart_recv_data;              //UART接收数据
        wire       uart_send_en;                //UART发送使能
        wire [7:0] uart_send_data;              //UART发送数据
        wire       uart_tx_busy;                //UART发送忙状态标志
        
        //*****************************************************
        //**                    main code
        //*****************************************************
       // assign uart_rxd=uart_rtl_0_txd;
      //  assign uart_txd=uart_rtl_0_rxd;
        //串口接收模块     
        uart_recv #(                          
            .CLK_FREQ       (CLK_FREQ),         //设置系统时钟频率
            .UART_BPS       (UART_BPS))         //设置串口接收波特率
        u_uart_recv(                 
            .sys_clk        (sys_clk),
            .sys_rst_n      (sys_rst_n),
            .uart_rxd       (uart_rtl_0_txd),//uart_rtl_0_txd
            .uart_done      (uart_recv_done),
            .uart_data      (uart_recv_data)
            );
        
        //串口发送模块    
        uart_send #(                          
            .CLK_FREQ       (CLK_FREQ),         //设置系统时钟频率
            .UART_BPS       (UART_BPS))         //设置串口发送波特率
        u_uart_send(                 
            .sys_clk        (sys_clk),
            .sys_rst_n      (sys_rst_n),
            .uart_en        (uart_send_en),
            .uart_din       (uart_send_data),
            .uart_tx_busy   (uart_tx_busy),
            .uart_txd       (uart_rtl_0_rxd )//uart_rtl_0_rxd
            );
            
        //串口环回模块    
        uart_loop u_uart_loop(
            .sys_clk        (sys_clk),             
            .sys_rst_n      (sys_rst_n),          
            .recv_done      (uart_recv_done),   //接收一帧数据完成标志信号
            .recv_data      (uart_recv_data),   //接收的数据
            .tx_busy        (uart_tx_busy),     //发送忙状态标志      
            .send_en        (uart_send_en),     //发送使能信号
            .send_data      (uart_send_data)    //待发送数据
            );
        
endmodule

九,AXI4转各种接口:比如转IIC,转SPI等等

https://blog.csdn.net/wangjie36/article/details/119224642

十,其它自定义IP

猜你喜欢

转载自blog.csdn.net/wangjie36/article/details/107025003