手册阅读
典型连接图
SG模式关闭时的寄存器地址
SG模式开启时的寄存器地址
关于各个bit的功能,具体看数据手册。
BD设计
通过PL侧设计一个流输出接口的主机(可以借助打包一个stream流接口的主机
),将流数据写入到DMA在转换为AXI_FULL类型送入到PS端的HP接口;PS端通过GP接口输出控制DMA的寄存器。
Axi_Stream_Master的代码如下
`timescale 1 ns / 1 ps
module Axi_Stream_Master#
(
parameter integer C_M_AXIS_TDATA_WIDTH = 64,
parameter integer C_M_START_COUNT = 32
)
(
input wire M_AXIS_ACLK ,
input wire M_AXIS_ARESETN ,
output wire M_AXIS_TVALID ,
output wire [C_M_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA ,
output wire [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0] M_AXIS_TSTRB ,
output wire M_AXIS_TLAST ,
input wire M_AXIS_TREADY
);
reg ro_M_AXIS_TVALID ;
reg [C_M_AXIS_TDATA_WIDTH-1 : 0] ro_M_AXIS_TDATA ;
reg [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0] ro_M_AXIS_TSTRB ;
reg ro_M_AXIS_TLAST ;
reg wr_action ;
reg [5:0] wr_cnt ;
assign M_AXIS_TVALID = ro_M_AXIS_TVALID;
assign M_AXIS_TDATA = ro_M_AXIS_TDATA ;
assign M_AXIS_TSTRB = ro_M_AXIS_TSTRB ;
assign M_AXIS_TLAST = ro_M_AXIS_TLAST ;
assign wr_action = M_AXIS_TVALID & M_AXIS_TREADY ;
always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
if(!M_AXIS_ARESETN)
wr_cnt <= 'd0;
else if(wr_cnt == 511)
wr_cnt <= 'd0;
else if(wr_action)
wr_cnt <= wr_cnt + 1;
else
wr_cnt <= wr_cnt;
end
always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
if(!M_AXIS_ARESETN)
ro_M_AXIS_TVALID <= 'd0;
else if(wr_cnt == 511)
ro_M_AXIS_TVALID <= 'd0;
else if(wr_cnt == 0)
ro_M_AXIS_TVALID <= 'd1;
else
ro_M_AXIS_TVALID <= ro_M_AXIS_TVALID;
end
always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
if(!M_AXIS_ARESETN)begin
ro_M_AXIS_TDATA <= 'd0;
ro_M_AXIS_TSTRB <= 'd0;
end
else if(ro_M_AXIS_TLAST && wr_action)begin
ro_M_AXIS_TDATA <= 'd0;
ro_M_AXIS_TSTRB <= 'd0;
end
else if(wr_action)begin
ro_M_AXIS_TDATA <= ro_M_AXIS_TDATA + 1;
ro_M_AXIS_TSTRB <= 8'b1111_1111;
end
else begin
ro_M_AXIS_TDATA <= ro_M_AXIS_TDATA;
ro_M_AXIS_TSTRB <= ro_M_AXIS_TSTRB;
end
end
always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
if(!M_AXIS_ARESETN)
ro_M_AXIS_TLAST <= 'd0;
else if(wr_cnt == 511 && wr_action == 1)
ro_M_AXIS_TLAST <= 'd0;
else if(wr_cnt == 510 && wr_action == 1)
ro_M_AXIS_TLAST <= 'd1;
else
ro_M_AXIS_TLAST <= ro_M_AXIS_TLAST;
end
endmodule
PS端设计
对于DMA寄存器的控制
在BD中,有ZYNQ核引出GP口去控制DMA,映射到PS端就是DMA设备。对于DMA寄存器的操作就是DMA的初始化等一系列操作。下图是GP所分配的地址空间,与PS端DMA设备的基址一致。
对DMA进行初始化
int Axi_Dma_Initial(XAxiDma* xdma)
{
int status = 0;
XAxiDma_Config *xaxidmafig;
xaxidmafig = XAxiDma_LookupConfig(XPAR_AXI_DMA_0_DEVICE_ID);
status = XAxiDma_CfgInitialize(xdma,xaxidmafig);
if(status != XST_SUCCESS)
{
return XST_FAILURE;
}
XAxiDma_Reset(xdma);
while(!XAxiDma_ResetIsDone(xdma));
return status;
}
status = XAxiDma_SimpleTransfer(xdma,XPAR_PS7_RAM_0_S_AXI_BASEADDR,512,XAXIDMA_DEVICE_TO_DMA);
usleep(5000);
数据分析:在PL侧写入了512个64bit的数据,等于512Byte个字节。
由于BASE_ADDRESS=0x00000000,所以HIGH_ADDRESS=0x00000200,也就是512个字节单位。
从图中可以看出,起始数据从0x0000000开始,也就是少写了8个64bit数据。再看末尾地址,也是对应的上8个64位地址,所以写数据操作整体没有问题。但开始会丢失8个数据。
目前这个BUG还没有找到原因,希望有大神能有解答。