前言
本文简单介绍通过bram在ps和pl间进行数据的传输以及命令的交互
1.pl部分
1.1设计文件代码
module bram_pl
(
input clk,
input rst,
input [31:0] bram_dout,
output bram_en,
output[31:0] bram_din,
output[3:0] bram_we,
output[31:0] bram_addr
);
reg[31:0] addrb;
reg[1:0] bram_st;
reg[3:0] web;
reg[31:0] data;
always@(posedge clk)begin
if(rst)begin
addrb <= 32'h000003fc;
bram_st <= 2'd0;
web <= 4'b0000;
end else begin
case(bram_st)
0:begin
if(bram_dout == 32'h0000_00ff)begin
bram_st <= 2'd1;
addrb <= 32'h00000400;
end else begin
bram_st <= 2'd0;
addrb <= 32'h000003fc;
end
end
1:begin
addrb <= addrb + 4;
if(addrb == 32'h000007fc)begin
bram_st <= 2'd3;
end
else begin
bram_st <= 2'd2;
end
end
2:begin
bram_st <= 2'd1;
end
3:begin
bram_st <= 2'd3;
end
endcase
end
end
assign bram_we = (bram_st == 2'd1) ? 4'b1111 : 4'b0000;
assign bram_en = 1'b1;
assign bram_addr = (bram_st == 2'd2) ? addrb - 4 : addrb;
assign bram_din = bram_dout + 1;
endmodule
1.2block design
添加zynq模块,打开AXI master接口
添加block memory generate模块,配置如下,这里选择真双端口,一个用于PS读写数据,另一个用于PL读写数据,注意mode选择bram controller
添加bram ctrl模块,配置如下
将设计文件作为模块添加到block design。注意设计文件的模块命不能和block design相同,否则可能添加不了,也要注意设计文件的正确性,如果设计文件有问题,编译不了,同样不能作为模块添加到block design内
如图进行连线,注意需要手动的接连自己添加的模块与block memory generate之间的端口
生成比特流并导出platform
2.ps部分
PS部分代码如下
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xil_io.h"
int main()
{
init_platform();
u32 Addr;
u32 i;
u32 bram_base_addr = 0x40000000;
print("bram app start...\n\n\r");
print("bram ps write...\n\r");
for(i = 0; i < 256; i = i + 1){
Addr = bram_base_addr + 4*i;
Xil_Out32(Addr,i);
if(i == 255)
print("bram write end\n\r");
}
print("bram app end\n\r");
cleanup_platform();
return 0;
}
ps先向bram内写如数据,从0开始写到256,地址每次加4,最后一位地址是3fc,当pl端检测到ps部分数据写完后,即检测到3fc地址上的数为256后,开始向后面继续写256个数。
需要注意的是,在PL端控制BRAM时,地址是从0x00000000开始的,在PS端控制BRAM时,地址是从0x40000000开始的,这里0x40000000的地址是zynq自己分配的,可以在bd内查看,也可以自己手动分配地址和大小。