我在block design中添加了一个自定义IP核和DMA IP核,其中自定义IP核的axi master总线是我自己写的,就是当DMA发起一次接收时往出发32bits的数据,然后DMA IP核的设置就是简单DMA IP核(没有钩SG和micro)
问题:我在调试的时候发现,只能进行1次DMA接收,再次发起传输时AXI总线就不工作了,显示inactive,DMA的接收中断应该是正常的(我查过第一次传输的数据,基本上是我期望的数值)
下面是block链接图
然后是自定义IP核中的代码
assign M_AXIS_tkeep = 4'b1111;
assign FCLK_CLK0_0 = s00_axis_aclk;
assign peripheral_aresetn_0 = s00_axis_aresetn;
assign m_axis_tdata= S_AXIS_0_tdata;
assign M_AXIS_tlast=S_AXIS_0_tlast;
assign M_AXIS_tvalid=S_AXIS_0_tvalid;
assign S_AXIS_0_tready=M_AXIS_tready;
assign GPIO_0_tri_o=gpio;
integer i,j,k;
reg [3:0] pp,qq;
reg [31:0] trans_data_1;
reg S_AXIS_0_tready_delay;
reg [63:0] data_debug;
reg [31:0] send_data_reg [1:0];
always@(posedge FCLK_CLK0_0)
begin
if(!peripheral_aresetn_0) begin
S_AXIS_0_tvalid <= 1'b0;
S_AXIS_0_tdata <= 32'd0;
S_AXIS_0_tlast <= 1'b0;
state <=0;
data_debug<=64'd0;
for (i = 0; i < 2; i = i + 1)
begin
send_data_reg[i]=32'd0;
end
trans_data_1<=32'd0;
S_AXIS_0_tready_delay<=1'b0;
pp<=4'd0;
end
else begin
S_AXIS_0_tready_delay<=S_AXIS_0_tready;
case(state)
0: begin
if(S_AXIS_0_tready) begin
S_AXIS_0_tvalid <= 1'b1;
state <= 1;
for(j=0;j<2;j=j+1) begin
send_data_reg[j]=received_data[i*32 +: 32];
end
end
else begin
S_AXIS_0_tvalid <= 1'b0;
state <= 0;
end
end
1:begin
if(S_AXIS_0_tready) begin
if(pp<2) begin
S_AXIS_0_tdata<=send_data_reg[pp];//这个是输入的数据
S_AXIS_0_tlast <= 1'b0;
state <= 1;
pp<=pp+1;
end
else begin
S_AXIS_0_tlast <= 1'b1;
state <= 2;
end
end
else begin
S_AXIS_0_tdata <= S_AXIS_0_tdata;
state <= 1;
end
end
2:begin
if(!S_AXIS_0_tready) begin
pp<=0;
S_AXIS_0_tvalid <= 1'b1;
S_AXIS_0_tlast <= 1'b1;
S_AXIS_0_tdata <= S_AXIS_0_tdata;
state <= 2;
end
else begin
pp<=0;
S_AXIS_0_tvalid <= 1'b0;
S_AXIS_0_tlast <= 1'b0;
S_AXIS_0_tdata <= 32'd0;
state <= 0;
end
end
default: state <=0;
endcase
end
end
然后是SDK的代码
if(packet_trans_done==1)
{
i=0;
xil_printf( "----DMA Test----\r\n");
for(i = 0; i < Tries; i ++)
{
if(RX_ready)
{
// xil_printf("1\n");
RX_ready=0;
Status = XAxiDma_SimpleTransfer(&AxiDma,(u32)RxBufferPtr,
2048, XAXIDMA_DEVICE_TO_DMA);
if (Status != XST_SUCCESS) {xil_printf("dma failed");}
}
if(RxDone)
{
//确保cache的数据都进入DDR
Xil_DCacheInvalidateRange(RxBufferPtr, MAX_PKT_LEN_rx);
RxDone=0;
RX_ready=1;
RX_success++;
}
packet_trans_done=0;
if (Error) {
xil_printf("Failed test transmit%s done, "
"receive%s done\r\n", TxDone? "":" not",
RxDone? "":" not");
goto Done;
}
}
然后RxBufferPtr的地址定义如下:
u8 *RxBufferPtr=(u8 *)RX_BUFFER_BASE;
#define RX_BUFFER_BASE (MEM_BASE_ADDR + 0x01000000)
#define RX_BUFFER_HIGH (MEM_BASE_ADDR + 0x0FFFFFFF)
我个人感觉像是2048这个数字引起的,因为我发现当增大2048这个数字后能多发两次,但是多发两次后又不行了,不像之前做dma loop试验是可以一直发一直收,(我希望是当这个packet_trans_done中断触发一次能收一次,这个过程能重复成千上万次),我是刚开始弄这个也不懂,如果有描述不到位的地方回答中讨论,希望能详细解释一下问题的原因并给出意见,感激不尽
参考gpt:
结合自己分析给你如下建议:
有可能是你的自定义IP核的AXI master总线没有正确地实现AXI协议的状态机和握手信号,导致DMA IP核无法识别传输的结束或者开始。你可以参考Xilinx提供的AXI接口代码,或者使用Vivado的IP编辑器创建一个带AXI接口的IP模板,来检查你的代码是否符合AXI协议的要求。
有可能是你的DMA IP核的配置有问题,导致DMA无法正确地响应中断或者重复发起传输。你可以检查你的DMA IP核是否设置了循环模式,是否使能了中断输出,是否正确地连接了中断控制器和处理器。你可以参考Xilinx提供的DMA IP核的文档 ,或者使用Xilinx提供的DMA示例工程,来验证你的DMA IP核的配置是否正确。
有可能是你的测试程序或者驱动有问题,导致DMA无法正确地初始化或者控制DMA IP核。你可以检查你的程序或者驱动是否正确地设置了DMA IP核的寄存器,是否正确地处理了DMA IP核发出的中断,是否正确地分配了内存空间给DMA IP核。你可以参考Xilinx提供的DMA驱动和库 ,或者使用Xilinx提供的DMA测试程序,来检查你的程序或者驱动是否正确。
正确地配置了DMA的源和目的地地址,以及传输的大小