赞
踩
BD框图:
PL端在BRAM地址0-39当中写入40个字节数据,然后PS端去读该数据
注: 写代码的时候需要注意一点,在平时我们使用BRAM时候,如果位宽为32,那么地址加一时候的单位是以4字节为单位,但是在BD里面通过AXI BRAM CTRL去控制BRAM的时候,地址加一对应的是一个byte数据,我们位宽为32,那么写一个数据,地址就应该加32/8,也就是4。
module RAM_WR#( parameter P_OPERATION_NUM = 40 , parameter P_DATA_WIDTH = 32 , parameter P_WRITE_BASEADDR= 0 , parameter P_READ_BASEADDR = 40 )( input i_clk , input i_rst , output [31:0] o_bram_addr , output [31:0] o_bram_data , output o_bram_en , output o_bram_wen , input [31:0] i_bram_data ); localparam P_BURST_LEN = P_OPERATION_NUM/(P_DATA_WIDTH/8); reg [31:0] ro_bram_addr ; reg [31:0] ro_bram_data ; reg ro_bram_en ; reg ro_bram_wen ; reg [15:0] r_cnt ; assign o_bram_addr = ro_bram_addr ; assign o_bram_data = ro_bram_data ; assign o_bram_en = ro_bram_en ; assign o_bram_wen = ro_bram_wen ; always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_cnt <= 'd0; else if(r_cnt == 1000) r_cnt <= 'd0; else r_cnt <= r_cnt + 1; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ro_bram_addr <= 'd0; ro_bram_data <= 'd0; ro_bram_en <= 'd0; ro_bram_wen <= 'd0; end else if(r_cnt >= 100 && r_cnt < 100 + P_BURST_LEN) begin ro_bram_addr <= P_WRITE_BASEADDR + ((r_cnt - 100) << 2); ro_bram_data <= r_cnt - 100; ro_bram_en <= 'd1; ro_bram_wen <= 'd1; end else if(r_cnt >= 800 && r_cnt < 800 + P_BURST_LEN) begin ro_bram_addr <= P_READ_BASEADDR + ((r_cnt - 800) << 2); ro_bram_data <= 'd0; ro_bram_en <= 'd1; ro_bram_wen <= 'd0; end else begin ro_bram_addr <= 'd0; ro_bram_data <= 'd0; ro_bram_en <= 'd0; ro_bram_wen <= 'd0; end end endmodule
PS端在BRAM地址0-39当中读出PL写入的40个字节数据
首先上电禁用cache,让ARM直接从DDR当中读取数据;
while循环当中使用Xil_In32()函数将BARM地址0-39当中的40个字节读出,一次读出4byte,也就是32bit,并且写入数组BramReadData[]当中XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR 为BRAM控制器基地址,同样要记得地址加1对应一个byte,所以地址一次加4。usleep(5000)表示延时5ms,usleep函数单位为us。
读完数据延时5ms后PS端在BRAM地址40-79当中写入40byte数据,一次写入32bit,所以地址一次加4.
#include <stdio.h> #include "platform.h" #include "xil_printf.h" #include "xil_cache.h"//禁用cache,让CPU直接访问DDR,否则是先将DDR数据读到cache里,CPU再去读数据 #include "sleep.h"//延时函数 #include "xil_io.h"//输入输出库,包含了写内存函数 #include "xparameters.h" int main() { init_platform(); Xil_DCacheDisable(); Xil_ICacheDisable(); print("Cache is disabled\n\r"); int i = 0; u32 BramReadData[10]; while(1){ for(i=0; i<10; i++){ BramReadData[i] = Xil_In32(XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR + i*4); } usleep(5000); for(i=0; i<10; i++){ Xil_Out32(XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR + 40 + i*4,i); } usleep(5000); } cleanup_platform(); return 0; }
成功关闭cache,PS端成功将PL端写入的数据1-10读出。
PL端加入了俩个ILA,一个用来捕获我们自己写的BRAM_WR模块是如何进行读写BRAM,一个用来捕获PS端如何通过AXI接口进行读写BRAM。
ILA1:
PL端写入数据过程:
PL端在BRAM地址0-39写入十个从0开始的递增数据,然后让PS端去读
PL端读出数据过程:
PS端在BRAM地址40-79写入十个从0开始的递增数据,然后让PL端去读
ILA2:
PS端读出数据过程:
PL端在BRAM地址0-39写入十个从0开始的递增数据,然后让PS端去读
从波形图可以看出PS端GP_Master_AXI接口其实是一个AXI_Lite接口,一次读写都只能读写一个数据
PS端写入数据过程:
PS端在BRAM地址40-79写入十个从0开始的递增数据,然后让PL端去读
实验结果一切正常!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。