From 53ddbe4e10ede196a051f3fb651c8d2e0c508f25 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 2 Dec 2022 18:46:00 +0100 Subject: [PATCH] refactor registration of IP core drivers to be aligned with registration of VILLASnode formats and node-types Signed-off-by: Steffen Vogel --- fpga/include/villas/fpga/card.hpp | 2 +- fpga/include/villas/fpga/core.hpp | 53 ++++++++++++++---- fpga/include/villas/fpga/ips/aurora.hpp | 27 --------- .../include/villas/fpga/ips/aurora_xilinx.hpp | 27 --------- fpga/include/villas/fpga/ips/bram.hpp | 25 ++++++--- fpga/include/villas/fpga/ips/dino.hpp | 50 +++++++++++++++++ fpga/include/villas/fpga/ips/dma.hpp | 24 ++++---- fpga/include/villas/fpga/ips/emc.hpp | 27 --------- fpga/include/villas/fpga/ips/fifo.hpp | 55 ------------------- fpga/include/villas/fpga/ips/gpio.hpp | 29 +--------- fpga/include/villas/fpga/ips/gpu2rtds.hpp | 27 --------- fpga/include/villas/fpga/ips/hls.hpp | 27 --------- fpga/include/villas/fpga/ips/intc.hpp | 33 ----------- fpga/include/villas/fpga/ips/pcie.hpp | 32 +++++------ fpga/include/villas/fpga/ips/rtds.hpp | 28 +--------- fpga/include/villas/fpga/ips/rtds2gpu.hpp | 27 --------- fpga/include/villas/fpga/ips/switch.hpp | 32 +++++------ fpga/include/villas/fpga/ips/timer.hpp | 27 --------- fpga/include/villas/fpga/node.hpp | 33 ++++++++++- fpga/lib/CMakeLists.txt | 15 ++--- fpga/lib/card.cpp | 2 +- fpga/lib/core.cpp | 39 ++++++------- fpga/lib/ips/aurora.cpp | 7 ++- fpga/lib/ips/aurora_xilinx.cpp | 5 +- fpga/lib/ips/bram.cpp | 4 +- fpga/lib/ips/dino.cpp | 34 ++++++++++++ fpga/lib/ips/dma.cpp | 5 +- fpga/lib/ips/emc.cpp | 20 +++---- fpga/lib/ips/fifo.cpp | 13 +++-- fpga/lib/ips/gpio.cpp | 9 +-- fpga/lib/ips/intc.cpp | 7 ++- fpga/lib/ips/pcie.cpp | 4 +- fpga/lib/ips/rtds.cpp | 10 ++-- fpga/lib/ips/rtds2gpu/gpu2rtds.cpp | 6 +- fpga/lib/ips/rtds2gpu/rtds2gpu.cpp | 14 ++--- fpga/lib/ips/switch.cpp | 4 +- fpga/lib/ips/timer.cpp | 8 ++- fpga/lib/node.cpp | 3 +- 38 files changed, 312 insertions(+), 482 deletions(-) create mode 100644 fpga/include/villas/fpga/ips/dino.hpp create mode 100644 fpga/lib/ips/dino.cpp diff --git a/fpga/include/villas/fpga/card.hpp b/fpga/include/villas/fpga/card.hpp index 07028bfa4..e43c5b8be 100644 --- a/fpga/include/villas/fpga/card.hpp +++ b/fpga/include/villas/fpga/card.hpp @@ -136,7 +136,7 @@ public: std::list> make(json_t *json, std::shared_ptr pci, std::shared_ptr vc); static - PCIeCard* create() + PCIeCard* make() { return new PCIeCard(); } diff --git a/fpga/include/villas/fpga/core.hpp b/fpga/include/villas/fpga/core.hpp index 9614d5f35..fba7691a1 100644 --- a/fpga/include/villas/fpga/core.hpp +++ b/fpga/include/villas/fpga/core.hpp @@ -305,18 +305,6 @@ protected: void parse(Core &, json_t *) { } -private: - // Create a concrete IP instance - virtual Core* create() = 0; - - virtual - void configurePollingMode(Core &, PollingMode) - { } - - virtual - Vlnv getCompatibleVlnv() const = 0; - -protected: static Logger getStaticLogger() { @@ -324,10 +312,51 @@ protected: } private: + virtual + void configurePollingMode(Core &, PollingMode) + { } + + virtual + Vlnv getCompatibleVlnv() const = 0; + + // Create a concrete IP instance + virtual + Core* make() const = 0; + static CoreFactory* lookup(const Vlnv &vlnv); }; +template +class CorePlugin : public CoreFactory { + +public: +virtual + std::string getName() const + { + return name; + } + + virtual + std::string getDescription() const + { + return desc; + } + +private: + virtual + Vlnv getCompatibleVlnv() const + { + return Vlnv(vlnv); + } + + // Create a concrete IP instance + Core* make() const + { + return new T; + }; +}; + } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/aurora.hpp b/fpga/include/villas/fpga/ips/aurora.hpp index 3fcdcd0e0..84149e0d1 100644 --- a/fpga/include/villas/fpga/ips/aurora.hpp +++ b/fpga/include/villas/fpga/ips/aurora.hpp @@ -66,33 +66,6 @@ private: static constexpr const char registerMemory[] = "reg0"; }; -class AuroraFactory : public NodeFactory { -public: - - Core* create() - { - return new Aurora; - } - - virtual std::string - getName() const - { - return "Aurora"; - } - - virtual std::string - getDescription() const - { - return "Aurora 8B/10B and additional support modules, like an AXI4-Lite register interface."; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv("acs.eonerc.rwth-aachen.de:user:aurora_axis:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/aurora_xilinx.hpp b/fpga/include/villas/fpga/ips/aurora_xilinx.hpp index 5f7275411..a52665632 100644 --- a/fpga/include/villas/fpga/ips/aurora_xilinx.hpp +++ b/fpga/include/villas/fpga/ips/aurora_xilinx.hpp @@ -46,33 +46,6 @@ public: } }; -class AuroraXilinxFactory : public NodeFactory { -public: - - Core* create() - { - return new AuroraXilinx; - } - - virtual std::string - getName() const - { - return "Aurora"; - } - - virtual std::string - getDescription() const - { - return "Xilinx Aurora 8B/10B."; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv("xilinx.com:ip:aurora_8b10b:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/bram.hpp b/fpga/include/villas/fpga/ips/bram.hpp index 19932fec9..aee489f04 100644 --- a/fpga/include/villas/fpga/ips/bram.hpp +++ b/fpga/include/villas/fpga/ips/bram.hpp @@ -29,8 +29,11 @@ namespace villas { namespace fpga { namespace ip { +class BramFactory; + class Bram : public Core { friend class BramFactory; + public: virtual @@ -57,19 +60,12 @@ private: }; class BramFactory : public CoreFactory { + public: - - void parse(Core &ip, json_t *cfg); - - Core* create() - { - return new Bram; - } - virtual std::string getName() const { - return "Bram"; + return "bram"; } virtual @@ -78,11 +74,22 @@ public: return "Block RAM"; } +private: virtual Vlnv getCompatibleVlnv() const { return Vlnv("xilinx.com:ip:axi_bram_ctrl:"); } + + // Create a concrete IP instance + Core* make() const + { + return new Bram; + }; + +protected: + virtual + void parse(Core &, json_t *) override; }; } /* namespace ip */ diff --git a/fpga/include/villas/fpga/ips/dino.hpp b/fpga/include/villas/fpga/ips/dino.hpp new file mode 100644 index 000000000..62d176f5e --- /dev/null +++ b/fpga/include/villas/fpga/ips/dino.hpp @@ -0,0 +1,50 @@ +/** Driver for wrapper around Dino + * + * @file + * @author Steffen Vogel + * @copyright 2020-2022, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASfpga + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#pragma once + +#include + +namespace villas { +namespace fpga { +namespace ip { + +class Dino : public Node { +public: + static constexpr const char* masterPort = "m_axis"; + static constexpr const char* slavePort = "s_axis"; + + const StreamVertex& getDefaultSlavePort() const + { + return getSlavePort(slavePort); + } + + const StreamVertex& getDefaultMasterPort() const + { + return getMasterPort(masterPort); + } +}; + +} /* namespace ip */ +} /* namespace fpga */ +} /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/dma.hpp b/fpga/include/villas/fpga/ips/dma.hpp index 892fd66cf..733f85fe4 100644 --- a/fpga/include/villas/fpga/ips/dma.hpp +++ b/fpga/include/villas/fpga/ips/dma.hpp @@ -40,6 +40,7 @@ public: friend class DmaFactory; ~Dma(); + virtual bool init() override; @@ -151,18 +152,13 @@ private: MemoryBlock::UniquePtr sgRingRx; }; -class DmaFactory : public NodeFactory { +class DmaFactory : NodeFactory { + public: - - Core* create() - { - return new Dma; - } - virtual std::string getName() const { - return "Dma"; + return "dma"; } virtual @@ -171,17 +167,25 @@ public: return "Xilinx's AXI4 Direct Memory Access Controller"; } +private: virtual Vlnv getCompatibleVlnv() const { return Vlnv("xilinx.com:ip:axi_dma:"); } + // Create a concrete IP instance + Core* make() const + { + return new Dma; + }; + +protected: virtual void parse(Core& ip, json_t* json) override; - virtual void - configurePollingMode(Core& ip, PollingMode mode) override + virtual + void configurePollingMode(Core& ip, PollingMode mode) override { dynamic_cast(ip).polling = (mode == POLL); } diff --git a/fpga/include/villas/fpga/ips/emc.hpp b/fpga/include/villas/fpga/ips/emc.hpp index 61a1c329c..40776e0d3 100644 --- a/fpga/include/villas/fpga/ips/emc.hpp +++ b/fpga/include/villas/fpga/ips/emc.hpp @@ -56,33 +56,6 @@ private: } }; -class EMCFactory : public CoreFactory { -public: - - Core* create() - { - return new EMC; - } - - virtual std::string - getName() const - { - return "ExternalMemoryController"; - } - - virtual std::string - getDescription() const - { - return "Xilinx's AXI External Memory Controller (EMC) "; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv("xilinx.com:ip:axi_emc:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/fifo.hpp b/fpga/include/villas/fpga/ips/fifo.hpp index daca91164..ce2be490b 100644 --- a/fpga/include/villas/fpga/ips/fifo.hpp +++ b/fpga/include/villas/fpga/ips/fifo.hpp @@ -63,65 +63,10 @@ private: XLlFifo xFifo; }; -class FifoFactory : public NodeFactory { -public: - - Core* create() - { - return new Fifo; - } - - std::string - getName() const - { - return "Fifo"; - } - - std::string - getDescription() const - { - return "Xilinx's AXI4 FIFO data mover"; - } - - Vlnv getCompatibleVlnv() const - { - return Vlnv("xilinx.com:ip:axi_fifo_mm_s:"); - } -}; - class FifoData : public Node { friend class FifoDataFactory; }; -class FifoDataFactory : public NodeFactory { -public: - - Core* create() - { - return new FifoData; - } - - virtual std::string - getName() const - { - return "FifoData"; - } - - virtual std::string - getDescription() const - { - return "Xilinx's AXI4 data stream FIFO"; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return { - "xilinx.com:ip:axis_data_fifo:" - }; - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/gpio.hpp b/fpga/include/villas/fpga/ips/gpio.hpp index d12effe8f..d9ad9082a 100644 --- a/fpga/include/villas/fpga/ips/gpio.hpp +++ b/fpga/include/villas/fpga/ips/gpio.hpp @@ -30,7 +30,7 @@ namespace villas { namespace fpga { namespace ip { -class GeneralPurposeIO : public Core { +class Gpio : public Core { public: virtual @@ -48,33 +48,6 @@ private: } }; -class GeneralPurposeIOFactory : public CoreFactory { -public: - - Core* create() - { - return new GeneralPurposeIO; - } - - virtual std::string - getName() const - { - return "GeneralPurposeIO"; - } - - virtual std::string - getDescription() const - { - return "Xilinx's AXI4 general purpose IO"; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv("xilinx.com:ip:axi_gpio:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/gpu2rtds.hpp b/fpga/include/villas/fpga/ips/gpu2rtds.hpp index 03444ebcd..daed0c4b1 100644 --- a/fpga/include/villas/fpga/ips/gpu2rtds.hpp +++ b/fpga/include/villas/fpga/ips/gpu2rtds.hpp @@ -66,33 +66,6 @@ public: bool started; }; -class Gpu2RtdsFactory : public NodeFactory { -public: - - Core* create() - { - return new Gpu2Rtds; - } - - virtual std::string - getName() const - { - return "Gpu2Rtds"; - } - - virtual std::string - getDescription() const - { - return "HLS Gpu2Rtds IP"; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv("acs.eonerc.rwth-aachen.de:hls:gpu2rtds:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/hls.hpp b/fpga/include/villas/fpga/ips/hls.hpp index 23e9127e7..6bcbbcf78 100644 --- a/fpga/include/villas/fpga/ips/hls.hpp +++ b/fpga/include/villas/fpga/ips/hls.hpp @@ -150,33 +150,6 @@ protected: bool running; }; -class HlsFactory : public CoreFactory { -public: - - Core* create() - { - return new Hls; - } - - virtual std::string - getName() const - { - return "HighLevelSynthesis"; - } - - virtual std::string - getDescription() const - { - return "Xilinx's HLS IP Cores"; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv("acs.eonerc.rwth-aachen.de:hls:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/intc.hpp b/fpga/include/villas/fpga/ips/intc.hpp index c4fe8fcac..e1e9084b7 100644 --- a/fpga/include/villas/fpga/ips/intc.hpp +++ b/fpga/include/villas/fpga/ips/intc.hpp @@ -84,39 +84,6 @@ private: bool polling[maxIrqs]; }; -class InterruptControllerFactory : public CoreFactory { -public: - - static constexpr const char* - getCompatibleVlnvString() - { - return "xilinx.com:module_ref:axi_pcie_intc:"; - } - - Core* create() - { - return new InterruptController; - } - - virtual std::string - getName() const - { - return "InterruptController"; - } - - virtual std::string - getDescription() const - { - return "Xilinx's programmable interrupt controller"; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv(getCompatibleVlnvString()); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/pcie.hpp b/fpga/include/villas/fpga/ips/pcie.hpp index 9b8269b99..cef19c838 100644 --- a/fpga/include/villas/fpga/ips/pcie.hpp +++ b/fpga/include/villas/fpga/ips/pcie.hpp @@ -59,26 +59,13 @@ private: std::map pcieToAxiTranslations; }; -class AxiPciExpressBridgeFactory : public CoreFactory { +class AxiPciExpressBridgeFactory : CoreFactory { + public: - - static constexpr - const char* getCompatibleVlnvString() - { - return "xilinx.com:ip:axi_pcie:"; - } - - void parse(Core &ip, json_t *cfg); - - Core* create() - { - return new AxiPciExpressBridge; - } - virtual std::string getName() const { - return "AxiPciExpressBridge"; + return "pcie"; } virtual @@ -87,11 +74,22 @@ public: return "Xilinx's AXI-PCIe Bridge"; } +private: virtual Vlnv getCompatibleVlnv() const { - return Vlnv(getCompatibleVlnvString()); + return Vlnv("xilinx.com:ip:axi_pcie:"); } + + // Create a concrete IP instance + Core* make() const + { + return new AxiPciExpressBridge; + }; + +protected: + virtual + void parse(Core &, json_t *) override; }; } /* namespace ip */ diff --git a/fpga/include/villas/fpga/ips/rtds.hpp b/fpga/include/villas/fpga/ips/rtds.hpp index 7c38bce28..ba80de1fe 100644 --- a/fpga/include/villas/fpga/ips/rtds.hpp +++ b/fpga/include/villas/fpga/ips/rtds.hpp @@ -29,7 +29,7 @@ namespace villas { namespace fpga { namespace ip { -class Rtds : public Node { +class RtdsGtfpga : public Node { public: static constexpr const char* masterPort = "m_axis"; static constexpr const char* slavePort = "s_axis"; @@ -65,32 +65,6 @@ private: static constexpr const char* irqCase = "irq_case"; }; -class RtdsFactory : public NodeFactory { -public: - Core* create() - { - return new Rtds; - } - - virtual std::string - getName() const - { - return "rtds"; - } - - virtual std::string - getDescription() const - { - return "RTDS's AXI4-Stream - GTFPGA interface"; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv("acs.eonerc.rwth-aachen.de:user:rtds_axis:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/rtds2gpu.hpp b/fpga/include/villas/fpga/ips/rtds2gpu.hpp index d44fdb330..43fdef3dd 100644 --- a/fpga/include/villas/fpga/ips/rtds2gpu.hpp +++ b/fpga/include/villas/fpga/ips/rtds2gpu.hpp @@ -84,33 +84,6 @@ private: bool started; }; -class Rtds2GpuFactory : public NodeFactory { -public: - - Core* create() - { - return new Rtds2Gpu; - } - - virtual std::string - getName() const - { - return "Rtds2Gpu"; - } - - virtual std::string - getDescription() const - { - return "HLS RTDS2GPU IP"; - } - - virtual Vlnv - getCompatibleVlnv() const - { - return Vlnv("acs.eonerc.rwth-aachen.de:hls:rtds2gpu:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/ips/switch.hpp b/fpga/include/villas/fpga/ips/switch.hpp index eb8cd1cb2..083b0ab3a 100644 --- a/fpga/include/villas/fpga/ips/switch.hpp +++ b/fpga/include/villas/fpga/ips/switch.hpp @@ -69,26 +69,13 @@ private: std::map portMapping; }; -class AxiStreamSwitchFactory : public NodeFactory { +class AxiStreamSwitchFactory : NodeFactory { + public: - - static constexpr - const char* getCompatibleVlnvString() - { - return "xilinx.com:ip:axis_switch:"; - } - - void parse(Core &ip, json_t *cfg); - - Core* create() - { - return new AxiStreamSwitch; - } - virtual std::string getName() const { - return "AxiStreamSwitch"; + return "switch"; } virtual @@ -97,11 +84,22 @@ public: return "Xilinx's AXI4-Stream switch"; } +private: virtual Vlnv getCompatibleVlnv() const { - return Vlnv(getCompatibleVlnvString()); + return Vlnv("xilinx.com:ip:axis_switch:"); } + + // Create a concrete IP instance + Core* make() const + { + return new AxiStreamSwitch; + }; + +protected: + virtual + void parse(Core &, json_t *) override; }; } /* namespace ip */ diff --git a/fpga/include/villas/fpga/ips/timer.hpp b/fpga/include/villas/fpga/ips/timer.hpp index 6491c3c37..e557bdf3c 100644 --- a/fpga/include/villas/fpga/ips/timer.hpp +++ b/fpga/include/villas/fpga/ips/timer.hpp @@ -79,33 +79,6 @@ private: XTmrCtr xTmr; }; -class TimerFactory : public CoreFactory { -public: - - Core* create() - { - return new Timer; - } - - virtual - std::string getName() const - { - return "Timer"; - } - - virtual - std::string getDescription() const - { - return "Xilinx's programmable timer / counter"; - } - - virtual - Vlnv getCompatibleVlnv() const - { - return Vlnv("xilinx.com:ip:axi_timer:"); - } -}; - } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/include/villas/fpga/node.hpp b/fpga/include/villas/fpga/node.hpp index fe712e584..1d0259928 100644 --- a/fpga/include/villas/fpga/node.hpp +++ b/fpga/include/villas/fpga/node.hpp @@ -162,7 +162,38 @@ public: using CoreFactory::CoreFactory; virtual - void parse(Core &ip, json_t *cfg); + void parse(Core &, json_t *); +}; + + +template +class NodePlugin : public NodeFactory { + +public: +virtual + std::string getName() const + { + return name; + } + + virtual + std::string getDescription() const + { + return desc; + } + +private: + virtual + Vlnv getCompatibleVlnv() const + { + return Vlnv(vlnv); + } + + // Create a concrete IP instance + Core* make() const + { + return new T; + }; }; } /* namespace ip */ diff --git a/fpga/lib/CMakeLists.txt b/fpga/lib/CMakeLists.txt index 8998b1799..ed7085438 100644 --- a/fpga/lib/CMakeLists.txt +++ b/fpga/lib/CMakeLists.txt @@ -27,18 +27,19 @@ set(SOURCES node.cpp fpgaHelper.cpp - ips/timer.cpp - ips/switch.cpp + ips/aurora_xilinx.cpp + ips/aurora.cpp + ips/bram.cpp + ips/dino.cpp + ips/dma.cpp ips/emc.cpp ips/fifo.cpp + ips/gpio.cpp ips/intc.cpp ips/pcie.cpp - ips/dma.cpp - ips/bram.cpp ips/rtds.cpp - ips/aurora.cpp - ips/aurora_xilinx.cpp - ips/gpio.cpp + ips/switch.cpp + ips/timer.cpp ips/rtds2gpu/rtds2gpu.cpp ips/rtds2gpu/xrtds2gpu.c diff --git a/fpga/lib/card.cpp b/fpga/lib/card.cpp index e59e90a43..83a96bcb2 100644 --- a/fpga/lib/card.cpp +++ b/fpga/lib/card.cpp @@ -73,7 +73,7 @@ std::list> PCIeCardFactory::make(json_t *json, std::sh if (ret != 0) throw ConfigError(json_card, err, "", "Failed to parse card"); - auto card = std::unique_ptr(create()); + auto card = std::unique_ptr(make()); // Populate generic properties card->name = std::string(card_name); diff --git a/fpga/lib/core.cpp b/fpga/lib/core.cpp index 314771f0e..7c72e627a 100644 --- a/fpga/lib/core.cpp +++ b/fpga/lib/core.cpp @@ -45,13 +45,12 @@ using namespace villas::fpga::ip; // first. static std::list vlnvInitializationOrder = { - Vlnv(AxiPciExpressBridgeFactory::getCompatibleVlnvString()), - Vlnv(InterruptControllerFactory::getCompatibleVlnvString()), - Vlnv(AxiStreamSwitchFactory::getCompatibleVlnvString()), + Vlnv("xilinx.com:ip:axi_pcie:"), + Vlnv("xilinx.com:module_ref:axi_pcie_intc:"), + Vlnv("xilinx.com:ip:axis_switch:"), }; -std::list> -CoreFactory::make(PCIeCard* card, json_t *json_ips) +std::list> CoreFactory::make(PCIeCard* card, json_t *json_ips) { // We only have this logger until we know the factory to build an IP with auto loggerStatic = getStaticLogger(); @@ -110,16 +109,15 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips) // This is the magic part! Factories automatically register as a // plugin as soon as they are instantiated. If there are multiple // candidates, the first suitable factory will be used. - CoreFactory* CoreFactory = lookup(id.getVlnv()); - - if (CoreFactory == nullptr) { + auto* f = lookup(id.getVlnv()); + if (f == nullptr) { loggerStatic->warn("No plugin found to handle {}", id.getVlnv()); continue; } else - loggerStatic->debug("Using {} for IP {}", CoreFactory->getName(), id.getVlnv()); + loggerStatic->debug("Using {} for IP {}", f->getName(), id.getVlnv()); - auto logger = CoreFactory->getLogger(); + auto logger = f->getLogger(); // Create new IP instance. Since this function is virtual, it will // construct the right, specialized type without knowing it here @@ -127,11 +125,10 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips) // If something goes wrong with initialization, the shared_ptr will // take care to desctruct the Core again as it is not pushed to // the list and will run out of scope. - auto ip = std::unique_ptr(CoreFactory->create()); + auto ip = std::unique_ptr(f->make()); if (ip == nullptr) { - logger->warn("Cannot create an instance of {}", - CoreFactory->getName()); + logger->warn("Cannot create an instance of {}", f->getName()); continue; } @@ -247,10 +244,10 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips) } // IP-specific setup via JSON config - CoreFactory->parse(*ip, json_ip); + f->parse(*ip, json_ip); // Set polling mode - CoreFactory->configurePollingMode(*ip, (card->polling ? PollingMode::POLL : PollingMode::IRQ)); + f->configurePollingMode(*ip, (card->polling ? PollingMode::POLL : PollingMode::IRQ)); // IP has been configured now configuredIps.push_back(std::move(ip)); @@ -306,8 +303,7 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips) return initializedIps; } -void -Core::dump() +void Core::dump() { logger->info("IP: {}", *this); for (auto& [num, irq] : irqs) { @@ -320,8 +316,7 @@ Core::dump() } } -CoreFactory* -CoreFactory::lookup(const Vlnv &vlnv) +CoreFactory* CoreFactory::lookup(const Vlnv &vlnv) { for (auto &ip : plugin::registry->lookup()) { if (ip->getCompatibleVlnv() == vlnv) @@ -331,8 +326,7 @@ CoreFactory::lookup(const Vlnv &vlnv) return nullptr; } -uintptr_t -Core::getLocalAddr(const MemoryBlockName &block, uintptr_t address) const +uintptr_t Core::getLocalAddr(const MemoryBlockName &block, uintptr_t address) const { // Throws exception if block not present auto &translation = addressTranslations.at(block); @@ -340,8 +334,7 @@ Core::getLocalAddr(const MemoryBlockName &block, uintptr_t address) const return translation.getLocalAddr(address); } -InterruptController* -Core::getInterruptController(const std::string &interruptName) const +InterruptController* Core::getInterruptController(const std::string &interruptName) const { try { const IrqPort irq = irqs.at(interruptName); diff --git a/fpga/lib/ips/aurora.cpp b/fpga/lib/ips/aurora.cpp index ffa515b4d..5aa346325 100644 --- a/fpga/lib/ips/aurora.cpp +++ b/fpga/lib/ips/aurora.cpp @@ -65,8 +65,6 @@ using namespace villas::fpga::ip; -static AuroraFactory auroraFactoryInstance; - void Aurora::dump() { // Check Aurora AXI4 registers @@ -112,3 +110,8 @@ void Aurora::resetFrameCounters() writeMemory(registerMemory, AURORA_AXIS_CR_OFFSET, cr); } + +static char n[] = "aurora"; +static char d[] = "Aurora 8B/10B and additional support modules, like an AXI4-Lite register interface."; +static char v[] = "acs.eonerc.rwth-aachen.de:user:aurora_axis:"; +static NodePlugin f; diff --git a/fpga/lib/ips/aurora_xilinx.cpp b/fpga/lib/ips/aurora_xilinx.cpp index 23651dd7a..97f963910 100644 --- a/fpga/lib/ips/aurora_xilinx.cpp +++ b/fpga/lib/ips/aurora_xilinx.cpp @@ -28,4 +28,7 @@ using namespace villas::fpga::ip; -static AuroraXilinxFactory auroraFactoryInstance; +static char n[] = "aurora_xilinx"; +static char d[] = "Xilinx Aurora 8B/10B."; +static char v[] = "xilinx.com:ip:aurora_8b10b:"; +static NodePlugin f; diff --git a/fpga/lib/ips/bram.cpp b/fpga/lib/ips/bram.cpp index e1ac43c80..78d1821fc 100644 --- a/fpga/lib/ips/bram.cpp +++ b/fpga/lib/ips/bram.cpp @@ -23,10 +23,9 @@ #include #include +using namespace villas; using namespace villas::fpga::ip; -static BramFactory factory; - void BramFactory::parse(Core &ip, json_t* cfg) { CoreFactory::parse(ip, cfg); @@ -49,3 +48,4 @@ bool Bram::init() return true; } +static BramFactory f; diff --git a/fpga/lib/ips/dino.cpp b/fpga/lib/ips/dino.cpp new file mode 100644 index 000000000..2c8156660 --- /dev/null +++ b/fpga/lib/ips/dino.cpp @@ -0,0 +1,34 @@ +/** Driver for wrapper around standard Xilinx Aurora (xilinx.com:ip:aurora_8b10b) + * + * @author Steffen Vogel + * @copyright 2017-2022, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASfpga + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include + +#include + +#include + +using namespace villas::fpga::ip; + +static char n[] = "dino"; +static char d[] = "Analog and Digital IO"; +static char v[] = "xilinx.com:module_ref:dino:"; +static NodePlugin f; diff --git a/fpga/lib/ips/dma.cpp b/fpga/lib/ips/dma.cpp index cc9bb9356..81ed216e7 100644 --- a/fpga/lib/ips/dma.cpp +++ b/fpga/lib/ips/dma.cpp @@ -37,9 +37,6 @@ using namespace villas::fpga::ip; -// Instantiate factory to make available to plugin infrastructure -static DmaFactory factory; - bool Dma::init() { // Check if configJson has been called @@ -672,3 +669,5 @@ void DmaFactory::parse(Core &ip, json_t *cfg) dma.configDone = true; } + +static DmaFactory f; diff --git a/fpga/lib/ips/emc.cpp b/fpga/lib/ips/emc.cpp index c4eeabba5..15badb057 100644 --- a/fpga/lib/ips/emc.cpp +++ b/fpga/lib/ips/emc.cpp @@ -27,11 +27,7 @@ using namespace villas::fpga::ip; -// Instantiate factory to make available to plugin infrastructure -static EMCFactory factory; - -bool -EMC::init() +bool EMC::init() { int ret; const uintptr_t base = getBaseAddr(registerMemory); @@ -57,8 +53,7 @@ EMC::init() return XFlash_IsReady(&xflash); } -bool -EMC::read(uint32_t offset, uint32_t length, uint8_t *data) +bool EMC::read(uint32_t offset, uint32_t length, uint8_t *data) { int ret; @@ -79,8 +74,7 @@ EMC::read(uint32_t offset, uint32_t length, uint8_t *data) // objcopy -I ihex -O binary somefile.mcs somefile.bin -bool -EMC::flash(uint32_t offset, const std::string &filename) +bool EMC::flash(uint32_t offset, const std::string &filename) { bool result; uint32_t length; @@ -107,8 +101,7 @@ EMC::flash(uint32_t offset, const std::string &filename) } // Based on xilflash_readwrite_example.c -bool -EMC::flash(uint32_t offset, uint32_t length, uint8_t *data) +bool EMC::flash(uint32_t offset, uint32_t length, uint8_t *data) { int ret = XST_FAILURE; uint32_t start = offset; @@ -164,3 +157,8 @@ EMC::flash(uint32_t offset, uint32_t length, uint8_t *data) return true; } + +static char n[] = "emc"; +static char d[] = "Xilinx's AXI External Memory Controller"; +static char v[] = "xilinx.com:ip:axi_emc:"; +static CorePlugin f; diff --git a/fpga/lib/ips/fifo.cpp b/fpga/lib/ips/fifo.cpp index 3e4a9f7f9..a901a224c 100644 --- a/fpga/lib/ips/fifo.cpp +++ b/fpga/lib/ips/fifo.cpp @@ -33,10 +33,6 @@ using namespace villas::fpga::ip; -// Instantiate factory to make available to plugin infrastructure -static FifoFactory factory; -static FifoDataFactory factoryData; - bool Fifo::init() { XLlFifo_Config fifo_cfg; @@ -109,3 +105,12 @@ size_t Fifo::read(void *buf, size_t len) return nextlen; } +static char n1[] = "fifo"; +static char d1[] = "Xilinx's AXI4 FIFO data mover"; +static char v1[] = "xilinx.com:ip:axi_fifo_mm_s:"; +static NodePlugin p1; + +static char n2[] = "fifo_data"; +static char d2[] = "Xilinx's AXI4 data stream FIFO"; +static char v2[] = "xilinx.com:ip:axis_data_fifo:"; +static NodePlugin p2; diff --git a/fpga/lib/ips/gpio.cpp b/fpga/lib/ips/gpio.cpp index 669ca2b1a..6e0fe6f3b 100644 --- a/fpga/lib/ips/gpio.cpp +++ b/fpga/lib/ips/gpio.cpp @@ -26,14 +26,15 @@ using namespace villas::fpga::ip; -// Instantiate factory to make available to plugin infrastructure -static GeneralPurposeIOFactory factory; - bool -GeneralPurposeIO::init() +Gpio::init() { //const uintptr_t base = getBaseAddr(registerMemory); return true; } +static char n[] = "gpio"; +static char d[] = "Xilinx's AXI4 general purpose IO"; +static char v[] = "xilinx.com:ip:axi_gpio:"; +static CorePlugin f; diff --git a/fpga/lib/ips/intc.cpp b/fpga/lib/ips/intc.cpp index 20d10dcaf..754ae8574 100644 --- a/fpga/lib/ips/intc.cpp +++ b/fpga/lib/ips/intc.cpp @@ -33,9 +33,6 @@ using namespace villas::fpga::ip; -// Instantiate factory to make available to plugin infrastructure -static InterruptControllerFactory factory; - InterruptController::~InterruptController() { card->vfioDevice->pciMsiDeinit(this->efds); @@ -167,3 +164,7 @@ InterruptController::waitForInterrupt(int irq) } } +static char n[] = "intc"; +static char d[] = "Xilinx's programmable interrupt controller"; +static char v[] = "xilinx.com:module_ref:axi_pcie_intc:"; +static CorePlugin f; diff --git a/fpga/lib/ips/pcie.cpp b/fpga/lib/ips/pcie.cpp index 383bdaafd..0345a1f73 100644 --- a/fpga/lib/ips/pcie.cpp +++ b/fpga/lib/ips/pcie.cpp @@ -31,8 +31,6 @@ using namespace villas::fpga::ip; -static AxiPciExpressBridgeFactory factory; - bool AxiPciExpressBridge::init() { @@ -162,3 +160,5 @@ AxiPciExpressBridgeFactory::parse(Core &ip, json_t *cfg) } } } + +static AxiPciExpressBridgeFactory p; diff --git a/fpga/lib/ips/rtds.cpp b/fpga/lib/ips/rtds.cpp index a84a5deb5..a9f76e4ae 100644 --- a/fpga/lib/ips/rtds.cpp +++ b/fpga/lib/ips/rtds.cpp @@ -53,9 +53,7 @@ using namespace villas::fpga::ip; -static RtdsFactory rtdsFactoryInstance; - -void Rtds::dump() +void RtdsGtfpga::dump() { // Check RTDS_Axis registers const uint32_t sr = readMemory(registerMemory, RTDS_AXIS_SR_OFFSET); @@ -81,9 +79,13 @@ void Rtds::dump() logger->info("RTDS timestep period: {:.3f} us", getDt() * 1e6); } -double Rtds::getDt() +double RtdsGtfpga::getDt() { const auto dt = readMemory(registerMemory, RTDS_AXIS_TS_PERIOD_OFFSET); return (dt == 0xFFFF) ? 0.0 : (double) dt / RTDS_HZ; } +static char n[] = "rtds_gtfpga"; +static char d[] = "RTDS's AXI4-Stream - GTFPGA interface"; +static char v[] = "acs.eonerc.rwth-aachen.de:user:rtds_axis:"; +static NodePlugin f; diff --git a/fpga/lib/ips/rtds2gpu/gpu2rtds.cpp b/fpga/lib/ips/rtds2gpu/gpu2rtds.cpp index 9d55b95cd..a20960ee3 100644 --- a/fpga/lib/ips/rtds2gpu/gpu2rtds.cpp +++ b/fpga/lib/ips/rtds2gpu/gpu2rtds.cpp @@ -7,8 +7,6 @@ using namespace villas::fpga::ip; -static Gpu2RtdsFactory factory; - bool Gpu2Rtds::init() { Hls::init(); @@ -125,3 +123,7 @@ Gpu2Rtds::getMaxFrameSize() // logger->info(" Seq. number: {}", (int) doorbell.seq_nr); //} +static char n[] = "gpu2rtds"; +static char d[] = "HLS Gpu2Rtds IP"; +static char v[] = "acs.eonerc.rwth-aachen.de:hls:gpu2rtds:"; +static NodePlugin p; diff --git a/fpga/lib/ips/rtds2gpu/rtds2gpu.cpp b/fpga/lib/ips/rtds2gpu/rtds2gpu.cpp index fee80a37a..bf2863164 100644 --- a/fpga/lib/ips/rtds2gpu/rtds2gpu.cpp +++ b/fpga/lib/ips/rtds2gpu/rtds2gpu.cpp @@ -6,7 +6,6 @@ #include using namespace villas::fpga::ip; -static Rtds2GpuFactory factory; bool Rtds2Gpu::init() { @@ -77,8 +76,7 @@ bool Rtds2Gpu::startOnce(const MemoryBlock &mem, size_t frameSize, size_t dataOf return start(); } -bool -Rtds2Gpu::updateStatus() +bool Rtds2Gpu::updateStatus() { if (not XRtds2gpu_Get_status_vld(&xInstance)) return false; @@ -88,8 +86,7 @@ Rtds2Gpu::updateStatus() return true; } -size_t -Rtds2Gpu::getMaxFrameSize() +size_t Rtds2Gpu::getMaxFrameSize() { XRtds2gpu_Set_frame_size(&xInstance, 0); @@ -100,8 +97,7 @@ Rtds2Gpu::getMaxFrameSize() return status.max_frame_size; } -void -Rtds2Gpu::dumpDoorbell(uint32_t doorbellRegister) const +void Rtds2Gpu::dumpDoorbell(uint32_t doorbellRegister) const { auto &doorbell = reinterpret_cast(doorbellRegister); @@ -111,3 +107,7 @@ Rtds2Gpu::dumpDoorbell(uint32_t doorbellRegister) const logger->info(" Seq. number: {}", (int) doorbell.seq_nr); } +static char n[] = "Rtds2Gpu"; +static char d[] = "HLS RTDS2GPU IP"; +static char v[] = "acs.eonerc.rwth-aachen.de:hls:rtds2gpu:"; +static NodePlugin f; diff --git a/fpga/lib/ips/switch.cpp b/fpga/lib/ips/switch.cpp index 86db05ab3..9c39e652a 100644 --- a/fpga/lib/ips/switch.cpp +++ b/fpga/lib/ips/switch.cpp @@ -33,8 +33,6 @@ namespace villas { namespace fpga { namespace ip { -static AxiStreamSwitchFactory factory; - bool AxiStreamSwitch::init() { if (XAxisScr_CfgInitialize(&xSwitch, &xConfig, getBaseAddr(registerMemory)) != XST_SUCCESS) { @@ -150,6 +148,8 @@ void AxiStreamSwitchFactory::parse(Core &ip, json_t *cfg) axiSwitch.xConfig.MaxNumSI = num_si; } +static AxiStreamSwitchFactory f; + } /* namespace ip */ } /* namespace fpga */ } /* namespace villas */ diff --git a/fpga/lib/ips/timer.cpp b/fpga/lib/ips/timer.cpp index d1a675ece..975972c1f 100644 --- a/fpga/lib/ips/timer.cpp +++ b/fpga/lib/ips/timer.cpp @@ -32,9 +32,6 @@ using namespace villas::fpga::ip; -// Instantiate factory to make available to plugin infrastructure -static TimerFactory factory; - bool Timer::init() { XTmrCtr_Config xtmr_cfg; @@ -77,3 +74,8 @@ uint32_t Timer::remaining() { return XTmrCtr_GetValue(&xTmr, 0); } + +static char n[] = "timer"; +static char d[] = "Xilinx's programmable timer / counter"; +static char v[] = "xilinx.com:ip:axi_timer:"; +static CorePlugin f; diff --git a/fpga/lib/node.cpp b/fpga/lib/node.cpp index 67c7933b6..51cc78369 100644 --- a/fpga/lib/node.cpp +++ b/fpga/lib/node.cpp @@ -33,8 +33,7 @@ using namespace villas::fpga::ip; -StreamGraph -Node::streamGraph; +StreamGraph Node::streamGraph; void NodeFactory::parse(Core &ip, json_t *cfg) {