一、前言
最近笔者在做项目的时候需要使用zynq中的AXI4-HP总线在PL端读取DDR中的数据这种功能,但是网上很多历程对于这方面只是创建了一个官方提供的IP核用于测试,并且每次写入和读取的长度为4K字节。所以为了满足我自己的项目需求,笔者将官方提供的测试IP核上做修改,主要实现一下功能:
1、上升沿使能读取数据。
2、读使能后,IP核需要从基地址开始,突发读取X次(X数量可控)
3、内置一个同步FIFO将读出的数据暂存在FIFO中。
二、IP核修改过程
第一步:创建一个官方提供的带AXI4的IP核。
可得到两个文件。(创建过程略,网上有很多教程)
其中AXI4_v1_0.v是IP核的顶层文件,AXI4读写逻辑主要在AXI4_v1_0_M00_AXI.v文件中。
创建完成后打开AXI4_v1_0_M00_AXI.v文件,输入的位置增加两个信号分别为
BURST_NUM | 突发总次数 |
RST_FIFO | FIFO复位信号 |
其中BURST_NUM信号为上述的X数量即,读使能后需要突发读的总次数。
第二步:修改读取/写入总长度
官方生成IP核规定了读写最长为4K字节,我们如果需要大数据量的话就需要修改这个读写数据量的总长度。将 C_MASTER_LENGTH 参数修改为22,该参数意为读/写遍历长度的位宽。22bit位宽代表可寻址4194303字节。(在178行)
第三步:修改突发读计数完毕条件
在下图所示的always中修改(718行)
以及最后的reads_done信号的使能条件(892行)
第四步:修改控制状态机
找到控制状态机的位置,修改状态机(737行)
1、 在IDLE状态中调整为触发后跳转至INIT_READ状态
2、INIT_READ状态中,将读取完毕后状态跳转为INIT_COMPARE即可
//implement master command interface state machine
//状态机-控制接口
always @ ( posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 1'b0 )
begin
// reset condition
// All the signals are assigned default values under reset condition
mst_exec_state <= IDLE;
start_single_burst_write <= 1'b0;
start_single_burst_read <= 1'b0;
compare_done <= 1'b0;
ERROR <= 1'b0;
end
else
begin
// state transition
case (mst_exec_state)
IDLE:
// This state is responsible to wait for user defined C_M_START_COUNT
// number of clock cycles.
if ( init_txn_pulse == 1'b1) //===========上升沿触发一次事务
begin
mst_exec_state <= INIT_READ; //触发后状态机跳转至读操作
ERROR <= 1'b0;
compare_done <= 1'b0;
end
else
begin
mst_exec_state <= IDLE;
end
INIT_WRITE:
// This state is responsible to issue start_single_write pulse to
// initiate a write transaction. Write transactions will be
// issued until burst_write_active signal is asserted.
// write controller
if (writes_done)
begin
mst_exec_state <= INIT_READ;//
end
else
begin
mst_exec_state <= INIT_WRITE;
if (~axi_awvalid && ~start_single_burst_write && ~burst_write_active)
begin
start_single_burst_write <= 1'b1;
end
else
begin
start_single_burst_write <= 1'b0; //Negate to generate a pulse
end
end
INIT_READ:
// This state is responsible to issue start_single_read pulse to
// initiate a read transaction. Read transactions will be
// issued until burst_read_active signal is asserted.
// read controller
if (reads_done) //==============读操作是否已经完成
begin
mst_exec_state <= INIT_COMPARE;
end
else
begin
mst_exec_state <= INIT_READ;
if (~axi_arvalid && ~burst_read_active && ~start_single_burst_read)
begin
start_single_burst_read <= 1'b1;
end
else
begin
start_single_burst_read <= 1'b0; //Negate to generate a pulse
end
end
INIT_COMPARE:
// This state is responsible to issue the state of comparison
// of written data with the read data. If no error flags are set,
// compare_done signal will be asseted to indicate success.
//if (~error_reg)
begin
ERROR <= error_reg;
mst_exec_state <= IDLE;
compare_done <= ~compare_done;
end
default :
begin
mst_exec_state <= IDLE;
end
endcase
end
end //MASTER_EXECUTION_PROC
第五步:添加同步FIFO
打开AXI4_V1_0.文件即顶层文件,在文件中添加一个同步FIFO的IP核并使能data_count信号。FIFO核接线如图所示
最后在顶层文件中添加以下接口
信号 | 介绍 |
ext_rd_en | 输入,外部读FIFO使能 |
ext_rd_data | 输出,FIFO读数据 |
ext_count | 输出,FIFO中数据量 |
BURST_NUM | 输入,AXI4突发次数 |
最后
该IP核是为了解决笔者在项目中所遇到的问题,笔者水平有限如有错误欢迎指正。源文件以上传0积分下载仅供参考。文章来源:https://www.toymoban.com/news/detail-413706.html
https://download.csdn.net/download/qq_24025329/87018990文章来源地址https://www.toymoban.com/news/detail-413706.html
到了这里,关于ZYNQ使用AXI4-HP接口总线读取DDR中的数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!