1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

fpga: enable using Xilinx xdma IP as DMA to AXI bridge as required for Ultrascale+ FPGAs

Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
Niklas Eiling 2024-03-14 11:49:51 +01:00 committed by Niklas Eiling
parent d99d0918ad
commit ca03e1d406
4 changed files with 30 additions and 5 deletions

View file

@ -24,8 +24,8 @@ public:
virtual bool init() override;
private:
static constexpr char axiInterface[] = "M_AXI";
protected:
virtual const char *getAxiInterfaceName() { return "M_AXI"; };
static constexpr char pcieMemory[] = "BAR0";
struct AxiBar {
@ -42,6 +42,11 @@ private:
std::map<std::string, PciBar> pcieToAxiTranslations;
};
class XDmaBridge : public AxiPciExpressBridge {
protected:
virtual const char *getAxiInterfaceName() { return "M_AXI_B"; };
};
class AxiPciExpressBridgeFactory : CoreFactory {
public:
@ -63,6 +68,20 @@ protected:
virtual void parse(Core &, json_t *) override;
};
class XDmaBridgeFactory : public AxiPciExpressBridgeFactory {
public:
virtual std::string getDescription() const {
return "Xilinx's XDMA IP configured as AXI-PCIe Bridge";
}
private:
virtual Vlnv getCompatibleVlnv() const { return Vlnv("xilinx.com:ip:xdma:"); }
// Create a concrete IP instance
Core *make() const { return new XDmaBridge; };
};
} // namespace ip
} // namespace fpga
} // namespace villas

View file

@ -31,6 +31,7 @@ using namespace villas::fpga::ip;
// first.
static std::list<Vlnv> vlnvInitializationOrder = {
Vlnv("xilinx.com:ip:axi_pcie:"),
Vlnv("xilinx.com:ip:xdma:"),
Vlnv("xilinx.com:module_ref:axi_pcie_intc:"),
Vlnv("xilinx.com:ip:axis_switch:"),
Vlnv("xilinx.com:ip:axi_iic:"),

View file

@ -22,7 +22,7 @@ bool AxiPciExpressBridge::init() {
// Throw an exception if the is no bus master interface and thus no
// address space we can use for translation -> error
card->addrSpaceIdHostToDevice = busMasterInterfaces.at(axiInterface);
card->addrSpaceIdHostToDevice = busMasterInterfaces.at(getAxiInterfaceName());
// Map PCIe BAR0 via VFIO
const void *bar0_mapped =
@ -139,3 +139,4 @@ void AxiPciExpressBridgeFactory::parse(Core &ip, json_t *cfg) {
}
static AxiPciExpressBridgeFactory p;
static XDmaBridgeFactory p2;

View file

@ -43,6 +43,7 @@ whitelist = [
["xilinx.com", "ip", "axi_gpio"],
["xilinx.com", "ip", "axi_bram_ctrl"],
["xilinx.com", "ip", "axi_pcie"],
["xilinx.com", "ip", "xdma"],
["xilinx.com", "ip", "axi_iic"],
["xilinx.com", "module_ref", "dinoif_fast"],
["xilinx.com", "module_ref", "dinoif_dac"],
@ -322,7 +323,7 @@ for bram in brams:
if instance in ips:
ips[instance]["size"] = int(size)
pcies = root.xpath('.//MODULE[@MODTYPE="axi_pcie"]')
pcies = root.xpath('.//MODULE[@MODTYPE="axi_pcie" or @MODTYPE="xdma"]')
for pcie in pcies:
instance = pcie.get("INSTANCE")
axi_bars = ips[instance].setdefault("axi_bars", {})
@ -332,8 +333,11 @@ for pcie in pcies:
("AXIBAR", "PCIEBAR", axi_bars),
("PCIEBAR", "AXIBAR", pcie_bars),
):
barnum = pcie.find('.//PARAMETER[@NAME="C_{}_NUM"]'.format(from_bar))
if barnum == None:
barnum = pcie.find('.//PARAMETER[@NAME="{}_NUM"]'.format(from_bar))
from_bar_num = int(
pcie.find('.//PARAMETER[@NAME="C_{}_NUM"]'.format(from_bar)).get("VALUE")
barnum.get("VALUE")
)
for i in range(0, from_bar_num):