diff --git a/fpga/include/villas/fpga/core.hpp b/fpga/include/villas/fpga/core.hpp index acdb1428c..3968b5841 100644 --- a/fpga/include/villas/fpga/core.hpp +++ b/fpga/include/villas/fpga/core.hpp @@ -207,6 +207,13 @@ class CoreFactory : public plugin::Plugin { public: using plugin::Plugin::Plugin; + static std::list parseIpIdentifier(json_t *json_ips); + static std::list reorderIps(std::list allIps); + static std::list> + configureIps(std::list orderedIps, json_t *json_ips, + Card *card); + static void initIps(std::list> orderedIps, Card *card); + // Returns a running and checked FPGA IP static std::list> make(Card *card, json_t *json_ips); diff --git a/fpga/lib/core.cpp b/fpga/lib/core.cpp index 2e3235c5d..d8ee767e8 100644 --- a/fpga/lib/core.cpp +++ b/fpga/lib/core.cpp @@ -37,21 +37,10 @@ static std::list vlnvInitializationOrder = { Vlnv("xilinx.com:ip:axi_iic:"), }; -std::list> CoreFactory::make(Card *card, - json_t *json_ips) { - // We only have this logger until we know the factory to build an IP with - auto loggerStatic = getStaticLogger(); - - std::list allIps; // All IPs available in config - std::list orderedIps; // IPs ordered in initialization order - - std::list> configuredIps; // Successfully configured IPs - - if (!card->ips.empty()) { - loggerStatic->error("IP list of card {} already contains IPs.", card->name); - throw RuntimeError("IP list of card {} already contains IPs.", card->name); - } +std::list CoreFactory::parseIpIdentifier(json_t *json_ips) { // Parse all IP instance names and their VLNV into list `allIps` + std::list allIps; + const char *ipName; json_t *json_ip; json_object_foreach(json_ips, ipName, json_ip) { @@ -64,9 +53,14 @@ std::list> CoreFactory::make(Card *card, allIps.push_back({vlnv, ipName}); } + return allIps; +} +std::list +CoreFactory::reorderIps(std::list allIps) { // Pick out IPs to be initialized first. - // + std::list orderedIps; + // Reverse walktrough, because we push to the // front of the output list, so that the first element will also be the // first to be initialized. @@ -84,11 +78,20 @@ std::list> CoreFactory::make(Card *card, // Insert all other IPs at the end orderedIps.splice(orderedIps.end(), allIps); + auto loggerStatic = CoreFactory::getStaticLogger(); loggerStatic->debug("IP initialization order:"); for (auto &id : orderedIps) { loggerStatic->debug(" " CLR_BLD("{}"), id.getName()); } + return orderedIps; +} + +std::list> +CoreFactory::configureIps(std::list orderedIps, json_t *json_ips, + Card *card) { + std::list> configuredIps; + auto loggerStatic = CoreFactory::getStaticLogger(); // Configure all IPs for (auto &id : orderedIps) { loggerStatic->info("Configuring {}", id); @@ -237,6 +240,12 @@ std::list> CoreFactory::make(Card *card, configuredIps.push_back(std::move(ip)); } + return configuredIps; +} + +void CoreFactory::initIps(std::list> configuredIps, + Card *card) { + auto loggerStatic = CoreFactory::getStaticLogger(); // Start and check IPs now for (auto &ip : configuredIps) { loggerStatic->info("Initializing {}", *ip); @@ -280,6 +289,28 @@ std::list> CoreFactory::make(Card *card, for (auto &ip : card->ips) { loggerStatic->debug(" {}", *ip); } +} + +std::list> CoreFactory::make(Card *card, + json_t *json_ips) { + // We only have this logger until we know the factory to build an IP with + auto loggerStatic = getStaticLogger(); + + if (!card->ips.empty()) { + loggerStatic->error("IP list of card {} already contains IPs.", card->name); + throw RuntimeError("IP list of card {} already contains IPs.", card->name); + } + + std::list allIps = + parseIpIdentifier(json_ips); // All IPs available in config + + std::list orderedIps = + reorderIps(allIps); // IPs ordered in initialization order + + std::list> configuredIps = + configureIps(orderedIps, json_ips, card); // Successfully configured IPs + + initIps(configuredIps, card); return card->ips; }