基于XILINX的PCIE XDMA IP用户层逻辑的设计
Vivado平台,XDMA IP核,用户逻辑层实现dma功能
一、资料
本设计参考了《pg195-pcie-dma》、《pg054-7series-pcie》、《ug476 7 Series GTX/GTH Transceivers》等官方资料,有需要的同学可自行前往查阅!(广子:前往xianyu找用户麻酱就烧饼获取Xilinx全系列手册文档和项目工程)
二、设计(对于赛灵思提供的xdma ip核)
1、概述
DMA 数据移动器:
作为 DMA,该核可通过 AXI4 接口或者通过 AXI 串流接口来配置,以支持直接连接至 RTL 逻辑。在 PCIe 地址空间与 AXI 地址空间之间可使用所提供的字符驱动程序通过以上任一接口进行高性能块数据移动。除了基本 DMA 功能外,DMA 还支持最多 4 条上游和下游通道、支持 PCIe 流量绕过 DMA 引擎(主机 DMA 旁路),还支持通过可选描述符旁路来管理来自 FPGA 互连结构的描述符,以满足需要最高性能和最低时延的应用的需求。
PCIe 与 AXI 存储器之间的桥接器:
配置为 PCIe Bridge 时,接收到的 PCIe 数据包将被转换为 AXI 流量,接收到的 AXI 流量则将被转换为 PCIe 流量。桥接功能适合需要快速轻松访问 PCI Express 子系统的 AXI 外设使用。桥接功能可用作为端点 (Endpoint) 或根端口 (Root Port)。仅限 AMD UltraScale+™ 器件才支持 PCIe Bridge 功能。对于 7 系列非 XT 器件以及只需 Bridge 选项的情况,应使用 AXI Memory Mapped to PCI Express (PCIe) Gen2。欲知详情,请参阅 AXI Memory Mapped to PCI Express (PCIe) Gen2 LogiCORE IP 产品指南(PG055)。对于 7 系列 XT 和 UltraScale 器件,应使用 AXI Bridge for PCI Express Gen3。欲知详情,请参阅 AXI Bridge for PCI Express Gen3 Subsystem 产品指南(PG194)。
2、框架结构
如下图DMA/Bridge Subsystem for PCI Express 概述:

此图展示了请求器请求 (RQ) 接口、请求器完成 (RC) 接口、完成器请求 (CQ) 接口和完成器完成 (CC) 接口。如需了解有关这些接口的更多信息,请参阅 UltraScale+ Integrated Block for PCI Express LogiCORE IP 产品指南(PG213)
目标桥接器:
目标桥接器用于接收来自主机的请求。根据 BAR,请求将通过 AXI4-Lite 主接口转发至内部目标用户或 CQ 旁路端口。 在下游用户逻辑返回非转发请求的数据后,目标桥接器就会生成读取完成 TLP,并通过 CC 总线将其发送至 PCIe IP。
在下表中,PCIe BAR 选择对应于“IP Configuration”(IP 配置)GUI 中的“PCIe BARs”选项卡下设置的选项。

本设计采用如下设置:
勾选PCIe to AXI Lite Master Interface,其余设置选项默认即可

H2C 通道
H2C 通道负责处理从主机到卡的 DMA 传输。它负责根据最大读取请求大小和可用内部资源来拆分读取请求。DMA 通道可保留未完成的请求,其最大数量取决于 RNUM_RIDS(即未完成的 H2C 通道请求 ID 参数)。每次拆分(如有)读取请求都会额外耗用一项读取请求。从 DMA 通道向 PCIe RQ 块发出读取后开始,请求即处于未完成状态,直至该通道接收到在用户接口上已按顺序完成写入的确认为止。完成传输后,DMA 通道会发出写回或中断以告知主机传输完成。
C2H 通道
C2H 通道负责处理从卡到主机的 DMA 传输。同样,未完成的传输数量通过 WNUM_RIDS(即 C2H 通道请求 ID 数量)来配置。在 AXI4-Stream 配置中,先设置 DMA 传输详细信息,然后才会在 AXI4-Stream 接口上接收到数据。这通常是通过接收 DMA 描述符来完成的。在准备好请求 ID 并启用通道后,该通道的 AXI4-Stream 接口即可接收数据并向主机执行 DMA。在 AXI4 MM 接口配置中,向 AXI4 MM 接口发出读取请求时就会分配请求 ID。与 H2C 通道类似,给定请求 ID 保持处于未完成状态,直至完成写入请求为止。对于 C2H 通道,当按 PCIe IP 指示发出写入请求后,写入请求即告完成。
AXI4-Lite 主接口
此模块用于实现 AXI4-Lite 主接口总线协议。主机可使用此接口来向用户逻辑生成 32 位读取请求和 32 位写入请求。这些读取或写入请求是通过 PCIe 到 AXI4-Lite 主接口 BAR 来接收的。读取完成数据将通过目标桥接器的 PCIe IP CC 总线返回至主机。
AXI4-Lite 从接口
此模块用于实现 AXI4-Lite 从接口总线协议。用户逻辑只能负责主控该接口上针对 DMA 内部寄存器的 32 位读取或写入操作。您无法通过此接口访问 PCIe 集成块寄存器。此接口不会生成发射到主机的请求。
主机到卡旁路主接口
到达 PCIe 到 DMA 旁路 BAR 的主机请求都将被发送到此模块。旁路主端口属于 AXI4 MM 接口,支持读写访问。
IRQ 模块
RQ 模块会接收到来自用户逻辑的中断连线,其数量可配置,每个 DMA 通道 1 条中断连线。此模块负责基于 PCIe 生成中断。可在 IP 配置期间指定对 MSI-X、MSI 和遗留中断的支持。
3、IP配置
本设计IP配置如下所示,具体配置选项请查阅《pg054-7series-pcie》手册中IP配置部分,这里不过多解释:





然后配置完成,生成IP。
三、编码
本设计编码依照XILINX IP核提供的例程进行修改,可以实现dma大数据量的的传输和用户寄存器的读写操作,可用于上位机和板卡之间的通信功能。
1、结构
此设计,dma数据传输操作和用户寄存器读写操作分别独立进行


2、细节
XDMA_TOP
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: FPGA MJSB
//
// Create Date: 2025/04/17 16:15:13
// Design Name:
// Module Name: XDMA_TOP
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module XDMA_TOP(
//-------------CLK ----------------------------------
input clk,
//-------------PCIE ----------------------------------
output [3:0] PCIE_TXP,
output [3:0] PCIE_TXN,
input [3:0] PCIE_RXP,
input [3:0] PCIE_RXN,
input PCIE_RST_n,
input PCIE_CLK_P,
input PCIE_CLK_N
);
//-----------------PCIE REG-----------------------------------
wire sys_rst;
wire sys_clk;
wire soft_rst;
wire user_reset;
wire user_lnk_up;
wire pcie_reg_clk;
wire dma_tx_rdy;
wire [127:0] dma_tx_data;
wire dma_tx_data_vld;
wire [31:0] dma_tx_cnt;
wire dma_rx_rdy;
wire [127:0] dma_rx_data;
wire dma_rx_data_vld;
wire [31:0] dma_rx_cnt;
reg [31:0] pcie_dma_wr_cnt;
reg [31:0] pcie_dma_rd_cnt;
wire [15:0] pcie_reg_wr_addr;
wire pcie_reg_wr_en;
wire [31:0] pcie_reg_wr_data;
wire [15:0] pcie_reg_rd_addr;
wire pcie_reg_rd_en;
wire [31:0] pcie_reg_rd_data;
wire pcie_reg_rd_vld;
wire pcie_access_reg_rdy;
wire [15:0] client_reg_wr_addr;
wire client_reg_wr_en;
wire [31:0] client_reg_wr_data;
wire [15:0] client_reg_rd_addr;
wire client_reg_rd_en;
wire [31:0] client_reg_rd_data;
wire pcie_irq_req;
wire pcie_irq_ack;
//-----------------PCIE DUT-----------------------------------
xilinx_dma_pcie_ep inst_xilinx_dma_pcie_ep(
.pci_exp_txp (PCIE_TXP),
.pci_exp_txn (PCIE_TXN),
.pci_exp_rxp (PCIE_RXP),
.pci_exp_rxn (PCIE_RXN),
.sys_clk_p (PCIE_CLK_P),
.sys_clk_n (PCIE_CLK_N),
.sys_rst_n (PCIE_RST_n),
//-----------------USER Interface------------------
.user_lnk_up (user_lnk_up),
.reg_clk (pcie_reg_clk),
.reg_rst (user_reset),
.sys_log_rst (sys_rst),
.reg_wr (pcie_reg_wr_en),
.reg_wr_addr (pcie_reg_wr_addr),
.reg_wr_data (pcie_reg_wr_data),
.reg_rd (pcie_reg_rd_en),
.reg_rd_addr (pcie_reg_rd_addr),
.reg_rd_data (pcie_reg_rd_data),
.reg_rd_data_vld (pcie_reg_rd_vld),
.dma_rx_clk (sys_clk),
.dma_rx_fifo_empty (),
.dma_rx_fifo_almost_empty (),
.dma_rx_rdy (dma_rx_rdy),
.dma_rx_dout_vld (dma_rx_data_vld),
.dma_rx_dout (dma_rx_data),
.dma_tx_clk (sys_clk),
.dma_tx_fifo_full (),
.dma_tx_fifo_prog_full (),
.dma_tx_rdy (dma_tx_rdy),
.dma_tx_din_vld (dma_tx_data_vld),
.dma_tx_din (dma_tx_data),
.usr_irq_clk (sys_clk),
.usr_irq_req_i (pcie_irq_req),
.usr_irq_ack_o (pcie_irq_ack)
);
assign dma_rx_rdy = 'h1;
// ---------PCIE 逻辑功能寄存器配置-----------------------
client_reg_access_part client_reg_access_part(
.access_clk (pcie_reg_clk),
.sys_clk (sys_clk),
.sys_rst (sys_rst),
.access_reg_wr_addr (pcie_reg_wr_addr),
.access_reg_wr_data (pcie_reg_wr_data),
.access_reg_wr_en (pcie_reg_wr_en),
.access_reg_rd_addr (pcie_reg_rd_addr),
.access_reg_rd_en (pcie_reg_rd_en),
.access_reg_rd_data (pcie_reg_rd_data),
.access_reg_rd_data_vld (pcie_reg_rd_vld),
.access_reg_rdy (),
.reg200_o (),
.reg204_o (),
.reg208_o (),
.reg20C_o (),
.reg210_o (),
.reg214_o (),
.reg218_o (),
.reg21C_o (),
.reg220_o (),
.reg224_o (),
.reg228_o (),
.reg22C_o (),
.reg230_o (),
.reg234_o (),
.reg238_o (),
.reg23C_o (),
.reg500_i (),
.reg504_i (),
.reg508_i (),
.reg50C_i (),
.reg510_i (),
.reg514_i (),
.reg518_i (),
.reg51C_i (),
.reg520_i (),
.reg524_i (),
//
.access_status ()
);
endmodule
xilinx_dma_pcie_ep
//-----------------------------------------------------------------------------
//
// Project : The Xilinx PCI Express DMA
// File : xilinx_dma_pcie_ep.sv
// Version : 4.1
//-----------------------------------------------------------------------------
//Engineer: FPGA MJSB
//-----------------------------------------------------------------------------
`timescale 1ps / 1ps
module xilinx_dma_pcie_ep #
(
parameter PL_LINK_CAP_MAX_LINK_WIDTH = 2, // 1- X1; 2 - X2; 4 - X4; 8 - X8
parameter PL_SIM_FAST_LINK_TRAINING = "FALSE", // Simulation Speedup
parameter PL_LINK_CAP_MAX_LINK_SPEED = 2, // 1- GEN1; 2 - GEN2; 4 - GEN3
parameter C_DATA_WIDTH = 64 ,
parameter EXT_PIPE_SIM = "FALSE", // This Parameter has effect on selecting Enable External PIPE Interface in GUI.
parameter C_ROOT_PORT = "FALSE", // PCIe block is in root port mode
parameter C_DEVICE_NUMBER = 0, // Device number for Root Port configurations only
parameter AXIS_CCIX_RX_TDATA_WIDTH = 256,
parameter AXIS_CCIX_TX_TDATA_WIDTH = 256,
parameter AXIS_CCIX_RX_TUSER_WIDTH = 46,
parameter AXIS_CCIX_TX_TUSER_WIDTH = 46
)
(
output [(PL_LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pci_exp_txp,
output [(PL_LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pci_exp_txn,
input [(PL_LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pci_exp_rxp,
input [(PL_LINK_CAP_MAX_LINK_WIDTH - 1) : 0] pci_exp_rxn,
//VU9P_TUL_EX_String= FALSE
input sys_clk_p,
input sys_clk_n,
input sys_rst_n,
input sys_log_rst,
//-----------------USER Interface--------------------------------
output user_lnk_up,
output reg_clk,
output reg_rst,
output reg_wr,
output [31:0] reg_wr_addr,
output [31:0] reg_wr_data,
output reg_rd,
output [31:0] reg_rd_addr,
input [31:0] reg_rd_data,
input reg_rd_data_vld,
input dma_rx_clk,
output dma_rx_fifo_empty,
output dma_rx_fifo_almost_empty,
input dma_rx_rdy,
output dma_rx_dout_vld,
output [127:0] dma_rx_dout,
input dma_tx_clk,
output dma_tx_fifo_full,
output dma_tx_fifo_prog_full,
output dma_tx_rdy,
input dma_tx_din_vld,
input [127:0] dma_tx_din,
input usr_irq_clk,
input usr_irq_req_i,
output usr_irq_ack_o
);
//-----------------------------------------------------------------------------------------------------------------------
// Local Parameters derived from user selection
localparam integer USER_CLK_FREQ = ((PL_LINK_CAP_MAX_LINK_SPEED == 3'h4) ? 5 : 4);
localparam TCQ = 1;
localparam C_S_AXI_ID_WIDTH = 4;
localparam C_M_AXI_ID_WIDTH = 4;
localparam C_S_AXI_DATA_WIDTH = C_DATA_WIDTH;
localparam C_M_AXI_DATA_WIDTH = C_DATA_WIDTH;
localparam C_S_AXI_ADDR_WIDTH = 64;
localparam C_M_AXI_ADDR_WIDTH = 64;
localparam C_NUM_USR_IRQ = 1;
wire user_lnk_up;
//----------------------------------------------------------------------------------------------------------------//
// AXI Interface //
//----------------------------------------------------------------------------------------------------------------//
wire user_clk;
wire user_resetn;
// Wires for Avery HOT/WARM and COLD RESET
wire avy_sys_rst_n_c;
wire avy_cfg_hot_reset_out;
reg avy_sys_rst_n_g;
reg avy_cfg_hot_reset_out_g;
assign avy_sys_rst_n_c = avy_sys_rst_n_g;
assign avy_cfg_hot_reset_out = avy_cfg_hot_reset_out_g;
initial begin
avy_sys_rst_n_g = 1;
avy_cfg_hot_reset_out_g =0;
end
//----------------------------------------------------------------------------------------------------------------//
// System(SYS) Interface //
//----------------------------------------------------------------------------------------------------------------//
wire sys_clk;
wire sys_clk_gt;
wire sys_rst_n_c;
// User Clock LED Heartbeat
reg [25:0] user_clk_heartbeat;
reg [((2*C_NUM_USR_IRQ)-1):0] usr_irq_function_number=0;
reg [C_NUM_USR_IRQ-1:0] usr_irq_req = 0;
wire [C_NUM_USR_IRQ-1:0] usr_irq_ack;
//-- AXI Master Write Address Channel
wire [C_M_AXI_ADDR_WIDTH-1:0] m_axi_awaddr;
wire [C_M_AXI_ID_WIDTH-1:0] m_axi_awid;
wire [2:0] m_axi_awprot;
wire [1:0] m_axi_awburst;
wire [2:0] m_axi_awsize;
wire [3:0] m_axi_awcache;
wire [7:0] m_axi_awlen;
wire m_axi_awlock;
wire m_axi_awvalid;
wire m_axi_awready;
//-- AXI Master Write Data Channel
wire [C_M_AXI_DATA_WIDTH-1:0] m_axi_wdata;
wire [(C_M_AXI_DATA_WIDTH/8)-1:0] m_axi_wstrb;
wire m_axi_wlast;
wire m_axi_wvalid;
wire m_axi_wready;
//-- AXI Master Write Response Channel
wire m_axi_bvalid;
wire m_axi_bready;
wire [C_M_AXI_ID_WIDTH-1 : 0] m_axi_bid ;
wire [1:0] m_axi_bresp ;
//-- AXI Master Read Address Channel
wire [C_M_AXI_ID_WIDTH-1 : 0] m_axi_arid;
wire [C_M_AXI_ADDR_WIDTH-1:0] m_axi_araddr;
wire [7:0] m_axi_arlen;
wire [2:0] m_axi_arsize;
wire [1:0] m_axi_arburst;
wire [2:0] m_axi_arprot;
wire m_axi_arvalid;
wire m_axi_arready;
wire m_axi_arlock;
wire [3:0] m_axi_arcache;
//-- AXI Master Read Data Channel
wire [C_M_AXI_ID_WIDTH-1 : 0] m_axi_rid;
wire [C_M_AXI_DATA_WIDTH-1:0] m_axi_rdata;
wire [1:0] m_axi_rresp;
wire m_axi_rvalid;
wire m_axi_rready;
////////////////////////////////////////////////// LITE
//-- AXI Master Write Address Channel
wire [31:0] m_axil_awaddr;
wire [2:0] m_axil_awprot;
wire m_axil_awvalid;
wire m_axil_awready;
//-- AXI Master Write Data Channel
wire [31:0] m_axil_wdata;
wire [3:0] m_axil_wstrb;
wire m_axil_wvalid;
wire m_axil_wready;
//-- AXI Master Write Response Channel
wire m_axil_bvalid;
wire m_axil_bready;
//-- AXI Master Read Address Channel
wire [31:0] m_axil_araddr;
wire [2:0] m_axil_arprot;
wire m_axil_arvalid;
wire m_axil_arready;
//-- AXI Master Read Data Channel
wire [31:0] m_axil_rdata;
wire [1:0] m_axil_rresp;
wire m_axil_rvalid;
wire m_axil_rready;
wire [1:0] m_axil_bresp;
wire [2:0] msi_vector_width;
wire msi_enable;
wire [3:0] leds;
wire free_run_clock;
wire [5:0] cfg_ltssm_state;
// Ref clock buffer
IBUFDS_GTE2 refclk_ibuf (.O(sys_clk), .ODIV2(), .I(sys_clk_p), .CEB(1'b0), .IB(sys_clk_n));
// Reset buffer
IBUF sys_reset_n_ibuf (.O(sys_rst_n_c), .I(sys_rst_n));
//-------------------STATUS REG-------------------------------
wire [5:0] cfg_ltssm_state;
wire [7:0] c2h_sts_0;
wire [7:0] h2c_sts_0;
// Core Top Level Wrapper
xdma_0 xdma_0_i
(
//---------------------------------------------------------------------------------------//
// PCI Express (pci_exp) Interface //
//---------------------------------------------------------------------------------------//
.sys_rst_n ( sys_rst_n_c ),
.sys_clk ( sys_clk ),
// Tx
.pci_exp_txn ( pci_exp_txn ),
.pci_exp_txp ( pci_exp_txp ),
// Rx
.pci_exp_rxn ( pci_exp_rxn ),
.pci_exp_rxp ( pci_exp_rxp ),
// AXI MM Interface
//-----------AXIR存储器映射写入地址接口信号----------------
.m_axi_awid (m_axi_awid ), //output
.m_axi_awaddr (m_axi_awaddr), //output
.m_axi_awlen (m_axi_awlen), //output
.m_axi_awsize (m_axi_awsize), //output
.m_axi_awburst (m_axi_awburst), //output
.m_axi_awprot (m_axi_awprot), //output 3'h0
.m_axi_awvalid (m_axi_awvalid), //output
.m_axi_awready (m_axi_awready), //input
.m_axi_awlock (m_axi_awlock), //output 1'h0
.m_axi_awcache (m_axi_awcache), //output 4'h0
//-----------AXIR存储器映射写入接口信号-------------------
.m_axi_wdata (m_axi_wdata), //output
.m_axi_wstrb (m_axi_wstrb), //output
.m_axi_wlast (m_axi_wlast), //output
.m_axi_wvalid (m_axi_wvalid), //output
.m_axi_wready (m_axi_wready), //input
//-----------AXIR存储器映射写入响应接口信号-------------------
.m_axi_bid (m_axi_bid), //input 主响应ID
.m_axi_bresp (m_axi_bresp), //input
.m_axi_bvalid (m_axi_bvalid), //input
.m_axi_bready (m_axi_bready), //output
//-----------AXIR存储器映射读取地址接口信号----------------
.m_axi_arid (m_axi_arid), //output
.m_axi_araddr (m_axi_araddr), //output
.m_axi_arlen (m_axi_arlen), //output
.m_axi_arsize (m_axi_arsize), //output
.m_axi_arburst (m_axi_arburst), //output
.m_axi_arprot (m_axi_arprot), //output
.m_axi_arvalid (m_axi_arvalid), //output
.m_axi_arready (m_axi_arready), //input
.m_axi_arlock (m_axi_arlock), //output
.m_axi_arcache (m_axi_arcache), //output
//-----------AXIR存储器映射读取接口信号---------------------
.m_axi_rid (m_axi_rid), //input
.m_axi_rdata (m_axi_rdata), //input
.m_axi_rresp (m_axi_rresp), //input
.m_axi_rlast (m_axi_rlast), //input
.m_axi_rvalid (m_axi_rvalid), //input
.m_axi_rready (m_axi_rready), //output
// LITE interface
//-- AXI Master Write Address Channel
.m_axil_awaddr (m_axil_awaddr), //output 此信号为存储器映射写入地址(H2C)
.m_axil_awprot (m_axil_awprot), //output 3'h0
.m_axil_awvalid (m_axil_awvalid), //output
.m_axil_awready (m_axil_awready), //input
//-- AXI Master Write Data Channel //output
.m_axil_wdata (m_axil_wdata), //output
.m_axil_wstrb (m_axil_wstrb), //output
.m_axil_wvalid (m_axil_wvalid), //output
.m_axil_wready (m_axil_wready), //input
//-- AXI Master Write Response Channel //
.m_axil_bvalid (m_axil_bvalid), //input
.m_axil_bresp (m_axil_bresp), //input
.m_axil_bready (m_axil_bready), //output
//-- AXI Master Read Address Channel //
.m_axil_araddr (m_axil_araddr), //output
.m_axil_arprot (m_axil_arprot), //output
.m_axil_arvalid (m_axil_arvalid), //output
.m_axil_arready (m_axil_arready), //input
.m_axil_rdata (m_axil_rdata), //input
//-- AXI Master Read Data Channel //
.m_axil_rresp (m_axil_rresp), //input
.m_axil_rvalid (m_axil_rvalid), //input
.m_axil_rready (m_axil_rready), //output
.c2h_sts_0 (c2h_sts_0), //output
.h2c_sts_0 (h2c_sts_0), //output
.usr_irq_req (usr_irq_req), //input 此信号断言有效即生成中断,保持断言有效直至中断处理完成为止
.usr_irq_ack (usr_irq_ack), //output 表示在pcie上已发送中断,针对遗留中断会生成2次确认,针对MIS中断会生成1次确认
.msi_enable (msi_enable), //output 表示何时启用MSI
.msi_vector_width (msi_vector_width),//output 表示MSI字段的大小(分配到器件的MSI矢量数)
// Config managemnet interface
.cfg_mgmt_addr ( 19'b0 ),
.cfg_mgmt_write ( 1'b0 ),
.cfg_mgmt_write_data ( 32'b0 ),
.cfg_mgmt_byte_enable ( 4'b0 ),
.cfg_mgmt_read ( 1'b0 ),
.cfg_mgmt_read_data (),
.cfg_mgmt_read_write_done (),
.cfg_mgmt_type1_cfg_reg_access ( 1'b0 ),
//-- AXI Global
.axi_aclk ( user_clk ),
.axi_aresetn ( user_resetn ),
.user_lnk_up ( user_lnk_up )
);
//---------------中断处理--------------------------------
(* ASYNC_REG="true" *)reg [3:0] usr_irq_req_r;
(* ASYNC_REG="true" *)reg [3:0] usr_irq_ack_r;
always@(posedge usr_irq_clk) usr_irq_ack_r <= {usr_irq_ack_r[2:0],usr_irq_ack};
assign usr_irq_ack_o = usr_irq_ack_r[3];
reg [15:0] init_cnt;
always@(posedge user_clk)begin
if(~sys_rst_n_c)
usr_irq_req_r <= 4'b1111;
else if(init_cnt[15])
usr_irq_req_r <= {usr_irq_req_r[2:0],usr_irq_req_i};
end
//assign usr_irq_req = usr_irq_req_r[3];
always@(posedge user_clk)begin
if(~sys_rst_n_c)
init_cnt <= 0;
else if(init_cnt[15])
init_cnt <= init_cnt;
else
init_cnt <= init_cnt +1;
end
// XDMA taget application
axi_lite_local #(
.C_M_AXI_ID_WIDTH(C_M_AXI_ID_WIDTH)
) axi_lite_local_i (
// AXI Lite Master Interface connections
.s_axil_awaddr (m_axil_awaddr),
.s_axil_awvalid (m_axil_awvalid),
.s_axil_awready (m_axil_awready),
.s_axil_wdata (m_axil_wdata),
.s_axil_wstrb (m_axil_wstrb),
.s_axil_wvalid (m_axil_wvalid),
.s_axil_wready (m_axil_wready),
.s_axil_bresp (m_axil_bresp),
.s_axil_bvalid (m_axil_bvalid),
.s_axil_bready (m_axil_bready),
.s_axil_araddr (m_axil_araddr),
.s_axil_arvalid (m_axil_arvalid),
.s_axil_arready (m_axil_arready),
.s_axil_rdata (m_axil_rdata),
.s_axil_rresp (m_axil_rresp),
.s_axil_rvalid (m_axil_rvalid),
.s_axil_rready (m_axil_rready),
.user_clk (user_clk),
.user_resetn (user_resetn),
.user_lnk_up (user_lnk_up),
.reg_wr_addr (reg_wr_addr),
.reg_wr (reg_wr),
.reg_wr_data (reg_wr_data),
.reg_rd (reg_rd),
.reg_rd_addr (reg_rd_addr),
.reg_rd_data (reg_rd_data),
.reg_rd_data_vld (reg_rd_data_vld)
);
xdma_ctrl xdma_ctrl_i(
.clk (user_clk),
.rst (~user_resetn),
.sys_log_rst (sys_log_rst),
.m_axi_awid (m_axi_awid ),
.m_axi_awaddr (m_axi_awaddr),
.m_axi_awlen (m_axi_awlen),
.m_axi_awsize (m_axi_awsize),
.m_axi_awburst (m_axi_awburst),
.m_axi_awprot (m_axi_awprot),
.m_axi_awvalid (m_axi_awvalid),
.m_axi_awready (m_axi_awready),
.m_axi_awlock (m_axi_awlock),
.m_axi_awcache (m_axi_awcache),
.m_axi_wdata (m_axi_wdata),
.m_axi_wstrb (m_axi_wstrb),
.m_axi_wlast (m_axi_wlast),
.m_axi_wvalid (m_axi_wvalid),
.m_axi_wready (m_axi_wready),
.m_axi_bid (m_axi_bid),
.m_axi_bresp (m_axi_bresp),
.m_axi_bvalid (m_axi_bvalid),
.m_axi_bready (m_axi_bready),
.m_axi_arid (m_axi_arid),
.m_axi_araddr (m_axi_araddr),
.m_axi_arlen (m_axi_arlen),
.m_axi_arsize (m_axi_arsize),
.m_axi_arburst (m_axi_arburst),
.m_axi_arprot (m_axi_arprot),
.m_axi_arvalid (m_axi_arvalid),
.m_axi_arready (m_axi_arready),
.m_axi_arlock (m_axi_arlock),
.m_axi_arcache (m_axi_arcache),
.m_axi_rid (m_axi_rid),
.m_axi_rdata (m_axi_rdata),
.m_axi_rresp (m_axi_rresp),
.m_axi_rlast (m_axi_rlast),
.m_axi_rvalid (m_axi_rvalid),
.m_axi_rready (m_axi_rready),
.c2h_sts_0 (c2h_sts_0),
.h2c_sts_0 (h2c_sts_0),
.tx_clk (dma_tx_clk),
.fifo_full (dma_tx_fifo_full),
.fifo_prog_full (dma_tx_fifo_prog_full),
.fifo_wr_rdy (dma_tx_rdy),
.fifo_din (dma_tx_din),
.fifo_wr (dma_tx_din_vld),
.rx_clk (dma_rx_clk),
.fifo_empty (dma_rx_fifo_empty),
.fifo_almost_empty (dma_rx_fifo_almost_empty),
.fifo_rd (dma_rx_rdy),
.fifo_dout_vld (dma_rx_dout_vld),
.fifo_dout (dma_rx_dout)
);
endmodule
axi_lite_local
xdma_ctrl
xdma_rx
xdma_tx
四、仿真
基于XDMAIP的功能仿真放到下一节专门进行设计,如有问题,同学们可以指出来,后面咱们一起讨论。
留赞在走,集赞互动环节接力开始哈哈哈哈哈哈哈哈哈
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)