diff --git a/fpga/include/villas/fpga/card.hpp b/fpga/include/villas/fpga/card.hpp index 3b77fd85e..80c10dc59 100644 --- a/fpga/include/villas/fpga/card.hpp +++ b/fpga/include/villas/fpga/card.hpp @@ -63,6 +63,7 @@ private: public: static void loadIps(std::shared_ptr card, json_t *json_ips, const std::filesystem::path &searchPath); + static void loadSwitch(std::shared_ptr card, json_t *json_paths); }; } // namespace fpga diff --git a/fpga/lib/card.cpp b/fpga/lib/card.cpp index 71136571b..bb100d1bd 100644 --- a/fpga/lib/card.cpp +++ b/fpga/lib/card.cpp @@ -10,6 +10,7 @@ #include #include +#include using namespace villas; using namespace villas::fpga; @@ -168,3 +169,46 @@ void CardFactory::loadIps(std::shared_ptr card, json_t *json_ips, throw ConfigError(json_ips, "node-config-fpga-ips", "Cannot initialize IPs of FPGA card {}", card->name); }; + +void CardFactory::loadSwitch(std::shared_ptr card, json_t *json_paths) { + // Additional static paths for AXI-Stream switch + json_error_t err; + if (json_paths != nullptr) { + if (not json_is_array(json_paths)) + throw ConfigError(json_paths, err, "", + "Switch path configuration must be an array"); + + size_t i; + json_t *json_path; + json_array_foreach(json_paths, i, json_path) { + const char *from, *to; + int reverse = 0; + + int ret = json_unpack_ex(json_path, &err, 0, "{ s: s, s: s, s?: b }", + "from", &from, "to", &to, "reverse", &reverse); + if (ret != 0) + throw ConfigError(json_path, err, "", + "Cannot parse switch path config"); + + auto masterIpCore = card->lookupIp(from); + if (!masterIpCore) + throw ConfigError(json_path, "", "Unknown IP {}", from); + + auto slaveIpCore = card->lookupIp(to); + if (!slaveIpCore) + throw ConfigError(json_path, "", "Unknown IP {}", to); + + auto masterIpNode = std::dynamic_pointer_cast(masterIpCore); + if (!masterIpNode) + throw ConfigError(json_path, "", "IP {} is not a streaming node", from); + + auto slaveIpNode = std::dynamic_pointer_cast(slaveIpCore); + if (!slaveIpNode) + throw ConfigError(json_path, "", "IP {} is not a streaming node", to); + + if (not masterIpNode->connect(*slaveIpNode, reverse != 0)) + throw ConfigError(json_path, "", "Failed to connect node {} to {}", + from, to); + } + } +} diff --git a/fpga/lib/pcie_card.cpp b/fpga/lib/pcie_card.cpp index 403f68c0c..fd43b82fc 100644 --- a/fpga/lib/pcie_card.cpp +++ b/fpga/lib/pcie_card.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -98,45 +97,8 @@ PCIeCardFactory::make(json_t *json_card, std::string card_name, if (not card->check()) throw RuntimeError("Checking of FPGA card {} failed", card_name); - // Additional static paths for AXI-Stream switch - if (json_paths != nullptr) { - if (not json_is_array(json_paths)) - throw ConfigError(json_paths, err, "", - "Switch path configuration must be an array"); + CardFactory::loadSwitch(card, json_paths); - size_t i; - json_t *json_path; - json_array_foreach(json_paths, i, json_path) { - const char *from, *to; - int reverse = 0; - - ret = json_unpack_ex(json_path, &err, 0, "{ s: s, s: s, s?: b }", "from", - &from, "to", &to, "reverse", &reverse); - if (ret != 0) - throw ConfigError(json_path, err, "", - "Cannot parse switch path config"); - - auto masterIpCore = card->lookupIp(from); - if (!masterIpCore) - throw ConfigError(json_path, "", "Unknown IP {}", from); - - auto slaveIpCore = card->lookupIp(to); - if (!slaveIpCore) - throw ConfigError(json_path, "", "Unknown IP {}", to); - - auto masterIpNode = std::dynamic_pointer_cast(masterIpCore); - if (!masterIpNode) - throw ConfigError(json_path, "", "IP {} is not a streaming node", from); - - auto slaveIpNode = std::dynamic_pointer_cast(slaveIpCore); - if (!slaveIpNode) - throw ConfigError(json_path, "", "IP {} is not a streaming node", to); - - if (not masterIpNode->connect(*slaveIpNode, reverse != 0)) - throw ConfigError(json_path, "", "Failed to connect node {} to {}", - from, to); - } - } // Deallocate JSON config json_decref(json_ips); return card;