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

move connectString parsing into separate class

Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
Niklas Eiling 2023-01-05 10:50:27 +01:00
parent b66733640a
commit 40d0452b0a
3 changed files with 124 additions and 37 deletions

View file

@ -1,9 +1,24 @@
/** Helper function for directly using VILLASfpga outside of VILLASnode
*
* Author: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
* SPDX-FileCopyrightText: 2022 Steffen Vogel <post@steffenvogel.de>
* SPDX-FileCopyrightText: 2022 Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
* SPDX-License-Identifier: Apache-2.0
* @file
* @author Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
* @copyright 2022, Steffen Vogel, Niklas Eiling
* @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 <http://www.gnu.org/licenses/>.
*********************************************************************************/
#pragma once
@ -17,11 +32,36 @@ namespace fpga {
std::shared_ptr<fpga::PCIeCard>
setupFpgaCard(const std::string &configFile, const std::string &fpgaName);
void configCrossBarUsingConnectString(std::string connectString,
std::shared_ptr<villas::fpga::ip::Dma> dma,
std::vector<std::shared_ptr<fpga::ip::AuroraXilinx>>& aurora_channels);
void setupColorHandling();
class ConnectString {
public:
ConnectString(std::string& connectString, int maxPortNum = 7);
void parseString(std::string& connectString);
int portStringToInt(std::string &str) const;
void configCrossBar(std::shared_ptr<villas::fpga::ip::Dma> dma,
std::vector<std::shared_ptr<fpga::ip::AuroraXilinx>>& aurora_channels) const;
bool isBidirectional() const { return bidirectional; };
bool isDmaLoopback() const { return dmaLoopback; };
bool isSrcStdin() const { return srcIsStdin; };
bool isDstStdout() const { return dstIsStdout; };
int getSrcAsInt() const { return srcAsInt; };
int getDstAsInt() const { return dstAsInt; };
protected:
villas::Logger log;
int maxPortNum;
bool bidirectional;
bool invert;
int srcAsInt;
int dstAsInt;
bool srcIsStdin;
bool dstIsStdout;
bool dmaLoopback;
};
} /* namespace fpga */
} /* namespace villas */

View file

@ -35,46 +35,42 @@ using namespace villas;
static std::shared_ptr<kernel::pci::DeviceList> pciDevices;
static auto logger = villas::logging.get("streamer");
const std::shared_ptr<villas::fpga::ip::Node> portStringToStreamVertex(std::string &str,
std::shared_ptr<villas::fpga::ip::Dma> dma,
std::vector<std::shared_ptr<fpga::ip::AuroraXilinx>>& aurora_channels)
fpga::ConnectString::ConnectString(std::string& connectString, int maxPortNum) :
log(villas::logging.get("ConnectString")),
maxPortNum(maxPortNum),
bidirectional(false),
invert(false),
srcAsInt(-1),
dstAsInt(-1),
srcIsStdin(false),
dstIsStdout(false),
dmaLoopback(false)
{
if (str == "stdin" || str == "stdout") {
return dma;
} else {
int port = std::stoi(str);
if (port > 7 || port < 0)
throw std::runtime_error("Invalid port number");
return aurora_channels[port];
}
parseString(connectString);
}
// parses a string lik "1->2" or "1<->stdout" and configures the crossbar
void fpga::configCrossBarUsingConnectString(std::string connectString,
std::shared_ptr<villas::fpga::ip::Dma> dma,
std::vector<std::shared_ptr<fpga::ip::AuroraXilinx>>& aurora_channels)
void fpga::ConnectString::parseString(std::string& connectString)
{
bool bidirectional = false;
bool invert = false;
if (connectString.empty())
return;
if (connectString == "loopback") {
logger->info("Connecting loopback");
// is this working?
dma->connectLoopback();
srcIsStdin = true;
dstIsStdout = true;
bidirectional = true;
dmaLoopback = true;
return;
}
static std::regex re("([0-9]+)([<\\->]+)([0-9]+|stdin|stdout)");
std::regex regex("([0-9]+)([<\\->]+)([0-9]+|stdin|stdout)");
std::smatch match;
if (!std::regex_match(connectString, match, re)) {
if (!std::regex_match(connectString, match, regex) || match.size() != 4) {
logger->error("Invalid connect string: {}", connectString);
throw std::runtime_error("Invalid connect string");
}
if (match[2] == "<->") {
bidirectional = true;
} else if(match[2] == "<-") {
@ -83,11 +79,61 @@ void fpga::configCrossBarUsingConnectString(std::string connectString,
std::string srcStr = (invert ? match[3] : match[1]);
std::string dstStr = (invert ? match[1] : match[3]);
logger->info("Connect string {}: Connecting {} to {}, {}directional",
connectString, srcStr, dstStr,
srcAsInt = portStringToInt(srcStr);
dstAsInt = portStringToInt(dstStr);
if (srcAsInt == -1) {
srcIsStdin = true;
}
if (dstAsInt == -1) {
dstIsStdout = true;
}
}
int fpga::ConnectString::portStringToInt(std::string &str) const
{
if (str == "stdin" || str == "stdout") {
return -1;
} else {
const int port = std::stoi(str);
if (port > maxPortNum || port < 0)
throw std::runtime_error("Invalid port number");
return port;
}
}
// parses a string lik "1->2" or "1<->stdout" and configures the crossbar
void fpga::ConnectString::configCrossBar(std::shared_ptr<villas::fpga::ip::Dma> dma,
std::vector<std::shared_ptr<fpga::ip::AuroraXilinx>>& aurora_channels) const
{
if (dmaLoopback) {
log->info("Configuring DMA loopback");
dma->connectLoopback();
return;
}
log->info("Connecting {} to {}, {}directional",
(srcAsInt==-1 ? "stdin" : std::to_string(srcAsInt)),
(dstAsInt==-1 ? "stdout" : std::to_string(dstAsInt)),
(bidirectional ? "bi" : "uni"));
auto src = portStringToStreamVertex(srcStr, dma, aurora_channels);
auto dest = portStringToStreamVertex(dstStr, dma, aurora_channels);
std::shared_ptr<fpga::ip::Node> src;
std::shared_ptr<fpga::ip::Node> dest;
if (srcIsStdin) {
src = dma;
} else {
src = aurora_channels[srcAsInt];
}
if (dstIsStdout) {
dest = dma;
} else {
dest = aurora_channels[dstAsInt];
}
src->connect(src->getDefaultMasterPort(), dest->getDefaultSlavePort());
if (bidirectional) {
dest->connect(dest->getDefaultMasterPort(), src->getDefaultSlavePort());

View file

@ -99,7 +99,8 @@ int main(int argc, char* argv[])
aurora->dump();
// Configure Crossbar switch
fpga::configCrossBarUsingConnectString(connectStr, dma, aurora_channels);
const fpga::ConnectString parsedConnectString(connectStr);
parsedConnectString.configCrossBar(dma, aurora_channels);
if (!noDma) {
for (auto b : block) {