文章目录
- 手册阅读
- 典型连接图
- SG模式关闭时的寄存器地址
- SG模式开启时的寄存器地址
- BD设计
- PS端设计
- 对于DMA寄存器的控制
- 对DMA进行初始化
手册阅读
典型连接图
SG模式关闭时的寄存器地址
SG模式开启时的寄存器地址
关于各个bit的功能,具体看数据手册。
BD设计
通过PL侧设计一个流输出接口的主机(可以借助打包一个stream流接口的主机
),将流数据写入到DMA在转换为AXI_FULL类型送入到PS端的HP接口;PS端通过GP接口输出控制DMA的寄存器。
Axi_Stream_Master的代码如下
`timescale 1 ns / 1 psmodule 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) beginif(!M_AXIS_ARESETN)wr_cnt <= 'd0;else if(wr_cnt == 511)wr_cnt <= 'd0;else if(wr_action)wr_cnt <= wr_cnt + 1;elsewr_cnt <= wr_cnt;
endalways @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) beginif(!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;elsero_M_AXIS_TVALID <= ro_M_AXIS_TVALID;
endalways @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) beginif(!M_AXIS_ARESETN)beginro_M_AXIS_TDATA <= 'd0; ro_M_AXIS_TSTRB <= 'd0;endelse if(ro_M_AXIS_TLAST && wr_action)beginro_M_AXIS_TDATA <= 'd0;ro_M_AXIS_TSTRB <= 'd0; endelse if(wr_action)beginro_M_AXIS_TDATA <= ro_M_AXIS_TDATA + 1;ro_M_AXIS_TSTRB <= 8'b1111_1111; endelse beginro_M_AXIS_TDATA <= ro_M_AXIS_TDATA; ro_M_AXIS_TSTRB <= ro_M_AXIS_TSTRB; end
endalways @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) beginif(!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;elsero_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还没有找到原因,希望有大神能有解答。