zynq 黑金AX7020 SDK实验——PL读写PS端DDR数据教程 程序注释
zynq 黑金AX7020 SDK实验——PL读写PS端DDR数据教程 程序理解
自学zynq SDK过程中,在按照官方教程学习PL端读写PS端DDR数据这一节内容时,对里面的一部分程序自己又添加了一些指令的注释,因为初学对一些构架还不是很熟悉,如果有错误之处希望能够和大家多多交流~
(这是官方视频中给出的程序,应该算是开源的吧)
这个程序时top.v中的子模块mem_test.v的程序,这里的内容比较重要,主要是构成了时序图的功能,仅供参考学习哈
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, /*写入的数据*/ /*信号类型为输出*/ /*【】中的内容是指信号是6位的*/input rd_burst_finish, /*读完成*/input wr_burst_finish, /*写完成*/output reg error
);
parameter IDLE = 3'd0; /*IDLE=000; MEM_READ=001;MEM_WRITE=010;BURST_LEN=128*/
parameter MEM_READ = 3'd1;
parameter MEM_WRITE = 3'd2;
parameter BURST_LEN = 128;(*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; /*将寄存器中要写的数据赋值给wr_burst_data*/
(*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) /*当mem_clk的上升沿到来或者rst的上升沿到来,执行always语句*/
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;
end
always@(posedge mem_clk or posedge rst)
beginif(rst)beginwr_burst_data_reg <= {MEM_DATA_BITS{1'b0}};/*将64个二进制零赋值给写数据寄存器*/wr_cnt <= 8'd0; /*赋值八位二进制零给wr_cnt*/endelse if(state == MEM_WRITE)beginif(wr_burst_data_req) /*监控wr_burst_data_req是否为1,如果不为1则不进行赋值*/beginwr_burst_data_reg <= {(MEM_DATA_BITS/8){wr_cnt}}; /*{}为拼接计算符,例如{4{w}}={w,w,w,w} {b{3{a,b}}}= {b,a,b,a,b,a,b}*/wr_cnt <= wr_cnt + 8'd1; /*wr_cnt是计时器,每个循环都在加1,进行拼接之后传入wr_burst_data_reg*/endelse if(wr_burst_finish)wr_cnt <= 8'd0;end
endalways@(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) /*此时wr_burst_finish=1,写入操作已经结束,故可以在此时就配置读取的操作内容*/beginstate <= MEM_READ;wr_burst_req <= 1'b0;rd_burst_req <= 1'b1; /*开始读取数据*/rd_burst_len <= BURST_LEN; rd_burst_addr <= wr_burst_addr; /*将数据写入的寄存器起始地址赋值给去取寄存器的首地址*/write_read_len <= write_read_len + BURST_LEN; /*一次写入128个数据*/endendMEM_READ:beginif(rd_burst_finish)beginif(write_read_len == 32'h2000000) /*当写入的数据和h2000000相等时,则停止读操作,设备进入等待状态*/beginrd_burst_req <= 1'b0;state <= IDLE;endelse /*当写入的数据值还没有达到规定的数值时,就一直进行写的操作*/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;endcaseend
endendmodule
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
