前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zynq中PS访问BRAM(一)

zynq中PS访问BRAM(一)

作者头像
瓜大三哥
发布2019-11-05 12:36:30
2.1K0
发布2019-11-05 12:36:30
举报
文章被收录于专栏:瓜大三哥瓜大三哥

前情回顾

(1)ZYNQ中PS端MIO操作 (2)ZYNQ中PS端MIO中断 (3)ZYNQ中PS端UART通信

(4)ZYNQ中PS端XADC读取

(5)Zynq中PL读写PS端DDR数据


PS端对PL端进行小批量的数据交换,可以通过BRAM模块,也就是Block RAM实现此要求。通过Zynq的GP Master接口读写PL端的BRAM,实现与PL的交互。

PS端通过AXI BRAM Controller读取BRAM数据,CPU仅配置自定义的PL BRAM Controller的寄存器,不通过它读写数据。

PL端写数据进入BRAM,等待写入完成后产生一个GPIO中断通知PL端可以通过AXI BRAM Controller读写BRAM。

BRAM Controller设置

由于AXI4总线为字节询址,BRAM数据宽度设置也是32位,同样都是32位数据宽度,因此在映射到BRAM地址时,需要按4字节询址,即去掉最后两位,下图为BRAM控制器与BRAM的映射关系。

在Address Editor中设置BRAM大小以及寄存器的地址。

硬件框图如下:

PL端读写RAM控制代码:

module ram_read_write

(

input clk,

input rst_n,

input [31:0] din,

output reg [31:0] dout,

output reg en,

output reg [3:0] we,

output rst,

output reg [31:0] addr,

input start,

input [31:0] init_data,

output reg start_clr,

output reg write_end,

input [31:0] len,

input [31:0] start_addr

);

assign rst = 1'b0 ;

localparam IDLE = 3'd0 ;

localparam READ_RAM = 3'd1 ;

localparam READ_END = 3'd2 ;

localparam WRITE_RAM = 3'd3 ;

localparam WRITE_END = 3'd4 ;

reg [2:0] state ;

reg [31:0] len_tmp ;

reg [31:0] start_addr_tmp ;

//write part

always @(posedge clk or negedge rst_n)

begin

if (~rst_n)

begin

state <= IDLE ;

dout <= 32'd0 ;

en <= 1'b0 ;

we <= 4'd0 ;

addr <= 32'd0 ;

write_end <= 1'b0 ;

start_clr <= 1'b0 ;

len_tmp <= 32'd0 ;

start_addr_tmp <=32'd0 ;

end

else

begin

case(state)

IDLE : begin

if (start)

begin

state <= READ_RAM ;

addr <= start_addr ;

start_addr_tmp <= start_addr ;

len_tmp <= len ;

dout <= init_data ;

en <= 1'b1 ;

start_clr <= 1'b1 ;

end

write_end <= 1'b0 ;

end

READ_RAM : begin

if ((addr - start_addr_tmp)== len_tmp - 4)

begin

state <= READ_END ;

en <= 1'b0 ;

end

else

begin

addr <= addr + 32'd4 ;

end

start_clr<= 1'b0 ;

end

READ_END : begin

addr <= start_addr_tmp ;

en <= 1'b1 ;

we<= 4'hf ;

state <= WRITE_RAM ;

end

WRITE_RAM : begin

if ((addr - start_addr_tmp)== len_tmp - 4)

begin

state <= WRITE_END ;

dout <= 32'd0 ;

en <= 1'b0 ;

we <= 4'd0 ;

end

else

begin

addr <= addr + 32'd4 ;

dout <= dout + 32'd1 ;

end

end

WRITE_END : begin

addr <= 32'd0 ;

write_end<= 1'b1 ;

state <= IDLE ;

end

default : state <= IDLE ;

endcase

end

end

endmodule

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 瓜大三哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档