mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
ip-node: implement connect interface and update AxiStreamSwitch implementation
This commit is contained in:
parent
a1daf95202
commit
a0c5acce4c
4 changed files with 105 additions and 36 deletions
|
@ -101,7 +101,7 @@ public:
|
|||
std::string nodeName;
|
||||
};
|
||||
|
||||
bool connect(std::string portName, const StreamPort& to);
|
||||
bool connect(const StreamVertex& from, const StreamVertex& to);
|
||||
bool disconnect(std::string portName);
|
||||
|
||||
const StreamVertex&
|
||||
|
@ -115,6 +115,11 @@ public:
|
|||
bool loopbackPossible() const;
|
||||
bool connectLoopback();
|
||||
|
||||
protected:
|
||||
virtual bool
|
||||
connectInternal(const std::string& slavePort,
|
||||
const std::string& masterPort);
|
||||
|
||||
private:
|
||||
std::pair<std::string, std::string> getLoopbackPorts() const;
|
||||
|
||||
|
|
|
@ -46,13 +46,14 @@ public:
|
|||
|
||||
bool init();
|
||||
|
||||
bool connect(int portSlave, int portMaster);
|
||||
bool disconnectMaster(int port);
|
||||
bool disconnectSlave(int port);
|
||||
bool connectInternal(const std::string& slavePort,
|
||||
const std::string& masterPort);
|
||||
|
||||
private:
|
||||
static constexpr int PORT_DISABLED = -1;
|
||||
int portNameToNum(const std::string& portName);
|
||||
|
||||
private:
|
||||
static constexpr const char* PORT_DISABLED = "DISABLED";
|
||||
static constexpr char registerMemory[] = "Reg";
|
||||
|
||||
std::list<MemoryBlockName> getMemoryBlocks() const
|
||||
|
@ -65,7 +66,7 @@ private:
|
|||
|
||||
int num_ports;
|
||||
XAxis_Switch xSwitch;
|
||||
std::map<int, int> portMapping;
|
||||
std::map<std::string, std::string> portMapping;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -93,6 +93,56 @@ IpNode::getLoopbackPorts() const
|
|||
return { "", "" };
|
||||
}
|
||||
|
||||
bool IpNode::connect(const StreamVertex& from, const StreamVertex& to)
|
||||
{
|
||||
StreamGraph::Path path;
|
||||
if(not streamGraph.getPath(from.getIdentifier(), to.getIdentifier(), path)) {
|
||||
logger->error("No path from {} to {}", from, to);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(path.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto currentEdge = path.begin();
|
||||
auto firstEdge = streamGraph.getEdge(*currentEdge);
|
||||
auto firstHopNode = streamGraph.getVertex(firstEdge->getVertexTo());
|
||||
|
||||
auto nextHopNode = firstHopNode;
|
||||
|
||||
// check if next hop is an internal connection
|
||||
if(firstHopNode->nodeName == getInstanceName()) {
|
||||
|
||||
if(not connectInternal(from.portName, firstHopNode->portName)) {
|
||||
logger->error("Making internal connection from {} to {} failed",
|
||||
from, *firstHopNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
// we have to advance to next hop
|
||||
if(++currentEdge == path.end()) {
|
||||
// arrived at the end of path
|
||||
return true;
|
||||
}
|
||||
|
||||
auto secondEdge = streamGraph.getEdge(*currentEdge);
|
||||
auto secondHopNode = streamGraph.getVertex(secondEdge->getVertexTo());
|
||||
nextHopNode = secondHopNode;
|
||||
}
|
||||
|
||||
auto nextHopNodeIp = reinterpret_cast<IpNode*>
|
||||
(card->lookupIp(nextHopNode->nodeName));
|
||||
|
||||
if(nextHopNodeIp == nullptr) {
|
||||
logger->error("Cannot find IP {}, this shouldn't happen!",
|
||||
nextHopNode->nodeName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return nextHopNodeIp->connect(*nextHopNode, to);
|
||||
}
|
||||
|
||||
bool
|
||||
IpNode::loopbackPossible() const
|
||||
{
|
||||
|
@ -100,6 +150,17 @@ IpNode::loopbackPossible() const
|
|||
return (not ports.first.empty()) and (not ports.second.empty());
|
||||
}
|
||||
|
||||
bool
|
||||
IpNode::connectInternal(const std::string& slavePort,
|
||||
const std::string& masterPort)
|
||||
{
|
||||
(void) slavePort;
|
||||
(void) masterPort;
|
||||
|
||||
logger->warn("This IP doesn't implement an internal connection");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
IpNode::connectLoopback()
|
||||
{
|
||||
|
|
|
@ -52,19 +52,36 @@ AxiStreamSwitch::init()
|
|||
XAxisScr_MiPortDisableAll(&xSwitch);
|
||||
XAxisScr_RegUpdateEnable(&xSwitch);
|
||||
|
||||
// initialize internal mapping
|
||||
for(size_t portMaster = 0; portMaster < portsMaster.size(); portMaster++) {
|
||||
portMapping[portMaster] = PORT_DISABLED;
|
||||
for(auto& [masterName, masterPort] : portsMaster) {
|
||||
|
||||
// initialize internal mapping
|
||||
portMapping[masterName] = PORT_DISABLED;
|
||||
|
||||
// each slave port may be internally routed to a master port
|
||||
for(auto& [slaveName, slavePort] : portsSlave) {
|
||||
(void) slaveName;
|
||||
|
||||
streamGraph.addDefaultEdge(slavePort->getIdentifier(),
|
||||
masterPort->getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AxiStreamSwitch::connect(int portSlave, int portMaster)
|
||||
AxiStreamSwitch::connectInternal(const std::string& portSlave,
|
||||
const std::string& portMaster)
|
||||
{
|
||||
if(portSlave.substr(0, 1) != "S" or
|
||||
portMaster.substr(0, 1) != "M") {
|
||||
logger->error("sanity check failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(portMapping[portMaster] == portSlave) {
|
||||
logger->debug("Ports already connected");
|
||||
logger->debug("Ports already connected (slave {} to master {}",
|
||||
portSlave, portMaster);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -75,45 +92,30 @@ AxiStreamSwitch::connect(int portSlave, int portMaster)
|
|||
slave, master, master);
|
||||
|
||||
XAxisScr_RegUpdateDisable(&xSwitch);
|
||||
XAxisScr_MiPortDisable(&xSwitch, master);
|
||||
XAxisScr_MiPortDisable(&xSwitch, portNameToNum(master));
|
||||
XAxisScr_RegUpdateEnable(&xSwitch);
|
||||
|
||||
portMapping[master] = PORT_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reconfigure switch */
|
||||
XAxisScr_RegUpdateDisable(&xSwitch);
|
||||
XAxisScr_MiPortEnable(&xSwitch, portMaster, portSlave);
|
||||
XAxisScr_MiPortEnable(&xSwitch, portNameToNum(portMaster), portNameToNum(portSlave));
|
||||
XAxisScr_RegUpdateEnable(&xSwitch);
|
||||
|
||||
portMapping[portMaster] = portSlave;
|
||||
|
||||
logger->debug("Connect slave {} to master {}", portSlave, portMaster);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AxiStreamSwitch::disconnectMaster(int port)
|
||||
int
|
||||
AxiStreamSwitch::portNameToNum(const std::string& portName)
|
||||
{
|
||||
logger->debug("Disconnect slave {} from master {}",
|
||||
portMapping[port], port);
|
||||
|
||||
XAxisScr_MiPortDisable(&xSwitch, port);
|
||||
portMapping[port] = PORT_DISABLED;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AxiStreamSwitch::disconnectSlave(int port)
|
||||
{
|
||||
for(auto [master, slave] : portMapping) {
|
||||
if(slave == port) {
|
||||
logger->debug("Disconnect slave {} from master {}", slave, master);
|
||||
XAxisScr_MiPortDisable(&xSwitch, master);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
logger->debug("Slave {} hasn't been connected to any master", port);
|
||||
return true;
|
||||
const std::string number = portName.substr(1, 2);
|
||||
return std::stoi(number);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
Loading…
Add table
Reference in a new issue