> 技术文档 > FPGA----ZYNQ7020系列的PS侧与PL侧通过AXI-HP交互(全网唯一最详)_zynq 7020 ps

FPGA----ZYNQ7020系列的PS侧与PL侧通过AXI-HP交互(全网唯一最详)_zynq 7020 ps

问题的由来:国产的芯片太难用了,必须要用例程设定好的程序才能读写。而且文档错误巨多。

实验设置:ZYNQ7020B、Vivado 2019.1

1、PS侧工程建立

1)点击“Create Block Design\",创建一个 Block 设计,也就是图形化设计

 2)搜索“zynq”,在搜索结果列表中双击“ZYNQ7 Processing System“。

3)双击 Block图中的“processing_system7_0”,配置相关参数。

4) PS-PL Configuration 界面,这个界面主要是进行 PS与PL之间接口的配置,主要是 AXI 接口,这些接口可以扩展 PL 端的 AX 接口外设,所以 PL如果要和 PS 进行数据交互,都要按照 AXI总线协议进行,xilinx 为我们提供了大量的 AXI接口的IP 核。在这里我打开了HP0通道(带宽是64bit,150MHz,但我们只能设置100MHz,后面会详细说)。

5)所需要的外设,打开 Eth0、SD0、UART1并且设备Bank0的电压3.3V,Bank1的电压1.8V。点方块就能变成绿色的了。

6)修改 Enet0 的电平标准为 HSTL 1.8V,Speed 为 fast,这些参数非常重要,如果不修改,网络可能不通。其他部分保持默认。

 7)如果上述都按我说的设置,那么在此处的时钟,FCLK_CLK0(AXI-HP0)通道就无法设置为150MHz(应该是142MHz),所以为了兼容设置,我们设置AXI-HP通道的速率为100MHz。

8)DDR配置:在“DDR Configuration”选项卡中可以配置 Ps 端 ddr 的参数,配置 DDR3 型号为“MT41J256M16 RE-125”,这里ddr3 型号并不是板子上的ddr3 型号,而是参数最接近的型号。Effective DRAM Bus Width\",选择“32 Bit\'

 至此,PS端的CPU就配置好了,点击左下角的OK即可。

2、添加下述模块,并依据我的接线连接。地址自动分配。

 3、axi_interconnect_0的配置:这是一个AXI4转AXI3协议的模块。

 4、proc_sys_reset_0不需要额外配置。

5、S00_AXI端子的配置:时钟域选axi_hp_clk

6、axi_hp_clk的时钟选100MHz

7、FCLK_CLK0填100MHz

 8、axim_rst_n的时钟域选axi_hp_clk。

9、Generate Output Products 生成输出文件。

10、编写代码,这里仅给出数据生成文件,其余代码联系作者。整个项目结构如下

//////////////////////////////////////////////////////////////////////////////////// Company: 东北电力大学// Engineer: 杨政// // Create Date: 2025/03/26 10:27:06// Design Name: // Module Name: mem_test// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module mem_test#(parameter MEM_DATA_BITS = 64,parameter ADDR_BITS = 32)(input rst,  /*复位*/input mem_clk, /*接口时钟*/output reg rd_burst_req, /*读请求*/output reg wr_burst_req, /*写请求*/output reg[9:0] rd_burst_len,  /*读数据长度*/output reg[9:0] wr_burst_len,  /*写数据长度*/output reg[ADDR_BITS - 1:0] rd_burst_addr, /*读首地址*/output reg[ADDR_BITS - 1:0] wr_burst_addr, /*写首地址*/input rd_burst_data_valid,  /*读出数据有效*/input wr_burst_data_req,  /*写数据信号*/input[MEM_DATA_BITS - 1:0] rd_burst_data, /*读出的数据*/output[MEM_DATA_BITS - 1:0] wr_burst_data, /*写入的数据*/input rd_burst_finish,/*读完成*/input wr_burst_finish,/*写完成*/output reg error);parameter IDLE = 3\'d0;parameter MEM_READ = 3\'d1;parameter MEM_WRITE = 3\'d2;parameter BURST_LEN = 2;(*mark_debug=\"true\"*)reg[2:0] state;(*mark_debug=\"true\"*)reg[7:0] wr_cnt;reg[MEM_DATA_BITS - 1:0] wr_burst_data_reg;assign wr_burst_data = wr_burst_data_reg;(*mark_debug=\"true\"*)reg[7:0] rd_cnt;reg[31:0] write_read_len;//assign error = (state == MEM_READ) && rd_burst_data_valid && (rd_burst_data != {(MEM_DATA_BITS/8){rd_cnt}});always@(posedge mem_clk or posedge rst)beginif(rst)error <= 1\'b0;else if(state == MEM_READ && rd_burst_data_valid && rd_burst_data != {(MEM_DATA_BITS/8){rd_cnt}})error <= 1\'b1;endalways@(posedge mem_clk or posedge rst)beginif(rst)beginwr_burst_data_reg <= {MEM_DATA_BITS{1\'b0}};wr_cnt <= 8\'d0;endelse if(state == MEM_WRITE)beginif(wr_burst_data_req)beginwr_burst_data_reg <= {(MEM_DATA_BITS/8){wr_cnt}};wr_cnt <= wr_cnt + 8\'d1;endelse if(wr_burst_finish)wr_cnt <= 8\'d0;endendalways@(posedge mem_clk or posedge rst)beginif(rst)beginrd_cnt <= 8\'d0;endelse if(state == MEM_READ)beginif(rd_burst_data_valid)beginrd_cnt <= rd_cnt + 8\'d1;endelse if(rd_burst_finish)rd_cnt <= 8\'d0;endelserd_cnt <= 8\'d0;endalways@(posedge mem_clk or posedge rst)beginif(rst)beginstate <= IDLE;wr_burst_req <= 1\'b0;rd_burst_req <= 1\'b0;rd_burst_len <= BURST_LEN;wr_burst_len <= BURST_LEN;rd_burst_addr <= 0;wr_burst_addr <= 0;write_read_len <= 32\'d0;endelsebegincase(state)IDLE:beginstate <= MEM_WRITE;wr_burst_req <= 1\'b1;wr_burst_len <= BURST_LEN;wr_burst_addr <=\'h2000000;write_read_len <= 32\'d0;endMEM_WRITE:beginif(wr_burst_finish)beginstate <= MEM_READ;wr_burst_req <= 1\'b0;rd_burst_req <= 1\'b1;rd_burst_len <= BURST_LEN;rd_burst_addr <= \'h2000000 + \'h20;//读取h2000020地址数据write_read_len = 32\'d5) beginrd_burst_req <= 1\'b0;state <= IDLE; end else beginstate <= MEM_WRITE;wr_burst_req <= 1\'b1;wr_burst_len <= BURST_LEN;rd_burst_req <= 1\'b0;wr_burst_addr <= wr_burst_addr + BURST_LEN;endendenddefault:state <= IDLE;endcaseendendendmodule

上述代码需要注意的就是,其地址必须是\'h2000000,不知道为啥别的会报错!!! 我到现在都完全不理解这是怎么映射的,我当初做ZCU106根本没遇到这个问题。

11、生成bit,添加bit,luanch SDK

12、如果均按我上述配置,那么可以在SDK中建立hello word.c工程(不开UART是无法建立的)。

13、启动工程,右下角添加监测点可以看到我们PL侧写入的数据。

14、PS侧代码:必须关闭缓存,Xil_DCacheDisable() 。这在我以前的文章提到过。

问题记录:PS端往DDR3输入数据,PL端读出却是错误的_zynq mpsoc ps ddr读写错误-CSDN博客文章浏览阅读530次。今天遇到一个问题,PS端往DDR3输入数据,PL端读出却是错误的。因为ZYNQ7020是双核,正常的HELLO world模板没有禁用CASHE,使用调试窗口可以发现CPU0/1相同地址的数据是不一样的,此时假如SDK使用CPU0往DDR3中填入数据,其实是存入了CASHE,也只改变了CPU0下的该地址的数据,而PL端读取的却是CPU1的数据。解决方法:要么使用hello world模板时用函数手动禁用cashe,或者使用memory test模板,后者在初始化时帮你禁用了。更换完以后读取就正确了。_zynq mpsoc ps ddr读写错误 https://blog.csdn.net/footprintk/article/details/139550641附上PS侧内存读写代码。

#include #include \"platform.h\"#include \"xil_printf.h\"#include \"util.h\"#include \"xil_cache.h\"#include \"sleep.h\"#include \"xparameters.h\"int main() {init_platform();Xil_DCacheDisable();memory_write_u32(0x02000020, 0xfafbfcfd);memory_write_u32(0x02000030, 0xf2f3f4f5);memory_write_u32(0x1000110, 0xf6f7f8f9);print(\"Hello World\\n\\r\");while (1) {print_memory_value(0x02000020, 32, 1);print_memory_value(0x02000030, 32, 1);print_memory_value(0x1000110, 32, 1); // STM32 RCC寄存器基地址sleep(1);}//cleanup_platform();return 0;}

当然,我们建立内存读写程序也是可以的,需要注意的就是memory_config_g.c文件。

 

 15、写在最后,大家看两个文件lscript.ld、system.hdf

 lscript.ld定义了内存大小、堆栈的大小、以及配置文件的启动区域,这些在我之前的文章都提到过。但我主要是想说为什么必须从\'h200_0000开始读写,不然会报错。

FPGA----ZCU106更换DDR4解决方案(全网唯一)_fpga ddr4-CSDN博客文章浏览阅读916次,点赞4次,收藏4次。每个数字在对应位置上选好即可,需要注意的是。其次是序号8,我买的DDR是2666MHz的,但是Vivado没有这个频率,不过没关系,仍然可以正常运行,需要注意的是,选择序号8的时候,将鼠标移动到下拉菜单,可以出现如下图所示的黄色方框,依据序号1、2、3选择即可。step2:打开淘宝,搜索笔记本DDR4购买内存条,我买的是骇客2666MHz 16G金士顿内存条。2、问题的提出:在xilinx SDK中进行大批量数组运算时,如果板子的自带的DDR不够,则需要购买新的内存条,此时我们应当如何设置呢?_fpga ddr4 https://blog.csdn.net/qq_37912811/article/details/131873424

 system.hdf描述了我们的设备信息,这和我们在Vivado中配置的是一样的。但为什么必须从\'h200_0000开始读写DDR,我仍然没有找到答案,还请各位大神赐教!