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:
parent
b66733640a
commit
40d0452b0a
3 changed files with 124 additions and 37 deletions
|
@ -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 */
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue