mem-garnet: Add masked functionalRead support
Recently the CHI protocol was introduced in Ruby.
The protocol introduces an alternative interface for
functional reads:
bool functionalRead(PacketPtr, WriteMask&)
This commit adds functionalRead(PacketPtr, WriteMask&)
implementations for various Garnet components.
Change-Id: Idd571899d679407b7b000c1a83a0a5420868cf28
Signed-off-by: Carlos Falquez <c.falquez@fz-juelich.de>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/46900
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Tiago Muck <tiago.muck@arm.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
diff --git a/src/mem/ruby/network/garnet/CrossbarSwitch.cc b/src/mem/ruby/network/garnet/CrossbarSwitch.cc
index cae7113..b4d6696 100644
--- a/src/mem/ruby/network/garnet/CrossbarSwitch.cc
+++ b/src/mem/ruby/network/garnet/CrossbarSwitch.cc
@@ -91,6 +91,17 @@
}
}
+bool
+CrossbarSwitch::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ bool read = false;
+ for (auto& switch_buffer : switchBuffers) {
+ if (switch_buffer.functionalRead(pkt, mask))
+ read = true;
+ }
+ return read;
+}
+
uint32_t
CrossbarSwitch::functionalWrite(Packet *pkt)
{
diff --git a/src/mem/ruby/network/garnet/CrossbarSwitch.hh b/src/mem/ruby/network/garnet/CrossbarSwitch.hh
index 8ab632e..b497078 100644
--- a/src/mem/ruby/network/garnet/CrossbarSwitch.hh
+++ b/src/mem/ruby/network/garnet/CrossbarSwitch.hh
@@ -67,6 +67,7 @@
inline double get_crossbar_activity() { return m_crossbar_activity; }
+ bool functionalRead(Packet *pkt, WriteMask &mask);
uint32_t functionalWrite(Packet *pkt);
void resetStats();
diff --git a/src/mem/ruby/network/garnet/GarnetNetwork.cc b/src/mem/ruby/network/garnet/GarnetNetwork.cc
index 01b2473..5792269 100644
--- a/src/mem/ruby/network/garnet/GarnetNetwork.cc
+++ b/src/mem/ruby/network/garnet/GarnetNetwork.cc
@@ -197,10 +197,12 @@
if (garnet_link->extBridgeEn) {
DPRINTF(RubyNetwork, "Enable external bridge for %s\n",
garnet_link->name());
+ NetworkBridge *n_bridge = garnet_link->extNetBridge[LinkDirection_In];
m_nis[local_src]->
- addOutPort(garnet_link->extNetBridge[LinkDirection_In],
+ addOutPort(n_bridge,
garnet_link->extCredBridge[LinkDirection_In],
dest, m_routers[dest]->get_vc_per_vnet());
+ m_networkbridges.push_back(n_bridge);
} else {
m_nis[local_src]->addOutPort(net_link, credit_link, dest,
m_routers[dest]->get_vc_per_vnet());
@@ -209,10 +211,12 @@
if (garnet_link->intBridgeEn) {
DPRINTF(RubyNetwork, "Enable internal bridge for %s\n",
garnet_link->name());
+ NetworkBridge *n_bridge = garnet_link->intNetBridge[LinkDirection_In];
m_routers[dest]->
addInPort(dst_inport_dirn,
- garnet_link->intNetBridge[LinkDirection_In],
+ n_bridge,
garnet_link->intCredBridge[LinkDirection_In]);
+ m_networkbridges.push_back(n_bridge);
} else {
m_routers[dest]->addInPort(dst_inport_dirn, net_link, credit_link);
}
@@ -266,9 +270,10 @@
if (garnet_link->extBridgeEn) {
DPRINTF(RubyNetwork, "Enable external bridge for %s\n",
garnet_link->name());
+ NetworkBridge *n_bridge = garnet_link->extNetBridge[LinkDirection_Out];
m_nis[local_dest]->
- addInPort(garnet_link->extNetBridge[LinkDirection_Out],
- garnet_link->extCredBridge[LinkDirection_Out]);
+ addInPort(n_bridge, garnet_link->extCredBridge[LinkDirection_Out]);
+ m_networkbridges.push_back(n_bridge);
} else {
m_nis[local_dest]->addInPort(net_link, credit_link);
}
@@ -276,12 +281,14 @@
if (garnet_link->intBridgeEn) {
DPRINTF(RubyNetwork, "Enable internal bridge for %s\n",
garnet_link->name());
+ NetworkBridge *n_bridge = garnet_link->intNetBridge[LinkDirection_Out];
m_routers[src]->
addOutPort(src_outport_dirn,
- garnet_link->intNetBridge[LinkDirection_Out],
+ n_bridge,
routing_table_entry, link->m_weight,
garnet_link->intCredBridge[LinkDirection_Out],
m_routers[src]->get_vc_per_vnet());
+ m_networkbridges.push_back(n_bridge);
} else {
m_routers[src]->
addOutPort(src_outport_dirn, net_link,
@@ -332,8 +339,10 @@
if (garnet_link->dstBridgeEn) {
DPRINTF(RubyNetwork, "Enable destination bridge for %s\n",
garnet_link->name());
- m_routers[dest]->addInPort(dst_inport_dirn,
- garnet_link->dstNetBridge, garnet_link->dstCredBridge);
+ NetworkBridge *n_bridge = garnet_link->dstNetBridge;
+ m_routers[dest]->addInPort(dst_inport_dirn, n_bridge,
+ garnet_link->dstCredBridge);
+ m_networkbridges.push_back(n_bridge);
} else {
m_routers[dest]->addInPort(dst_inport_dirn, net_link, credit_link);
}
@@ -341,11 +350,13 @@
if (garnet_link->srcBridgeEn) {
DPRINTF(RubyNetwork, "Enable source bridge for %s\n",
garnet_link->name());
+ NetworkBridge *n_bridge = garnet_link->srcNetBridge;
m_routers[src]->
- addOutPort(src_outport_dirn, garnet_link->srcNetBridge,
+ addOutPort(src_outport_dirn, n_bridge,
routing_table_entry,
link->m_weight, garnet_link->srcCredBridge,
m_routers[dest]->get_vc_per_vnet());
+ m_networkbridges.push_back(n_bridge);
} else {
m_routers[src]->addOutPort(src_outport_dirn, net_link,
routing_table_entry,
@@ -604,6 +615,33 @@
(*m_ctrl_traffic_distribution[src_node][dest_node])++;
}
+bool
+GarnetNetwork::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ bool read = false;
+ for (unsigned int i = 0; i < m_routers.size(); i++) {
+ if (m_routers[i]->functionalRead(pkt, mask))
+ read = true;
+ }
+
+ for (unsigned int i = 0; i < m_nis.size(); ++i) {
+ if (m_nis[i]->functionalRead(pkt, mask))
+ read = true;
+ }
+
+ for (unsigned int i = 0; i < m_networklinks.size(); ++i) {
+ if (m_networklinks[i]->functionalRead(pkt, mask))
+ read = true;
+ }
+
+ for (unsigned int i = 0; i < m_networkbridges.size(); ++i) {
+ if (m_networkbridges[i]->functionalRead(pkt, mask))
+ read = true;
+ }
+
+ return read;
+}
+
uint32_t
GarnetNetwork::functionalWrite(Packet *pkt)
{
diff --git a/src/mem/ruby/network/garnet/GarnetNetwork.hh b/src/mem/ruby/network/garnet/GarnetNetwork.hh
index d18caae..db37628 100644
--- a/src/mem/ruby/network/garnet/GarnetNetwork.hh
+++ b/src/mem/ruby/network/garnet/GarnetNetwork.hh
@@ -55,6 +55,7 @@
class NetworkInterface;
class Router;
class NetworkLink;
+class NetworkBridge;
class CreditLink;
class GarnetNetwork : public Network
@@ -105,6 +106,7 @@
PortDirection src_outport_dirn,
PortDirection dest_inport_dirn);
+ bool functionalRead(Packet *pkt, WriteMask &mask);
//! Function for performing a functional write. The return value
//! indicates the number of messages that were written.
uint32_t functionalWrite(Packet *pkt);
@@ -208,6 +210,7 @@
std::vector<VNET_type > m_vnet_type;
std::vector<Router *> m_routers; // All Routers in Network
std::vector<NetworkLink *> m_networklinks; // All flit links in the network
+ std::vector<NetworkBridge *> m_networkbridges; // All network bridges
std::vector<CreditLink *> m_creditlinks; // All credit links in the network
std::vector<NetworkInterface *> m_nis; // All NI's in Network
int m_next_packet_id; // static vairable for packet id allocation
diff --git a/src/mem/ruby/network/garnet/InputUnit.cc b/src/mem/ruby/network/garnet/InputUnit.cc
index e8515a6..179bb64 100644
--- a/src/mem/ruby/network/garnet/InputUnit.cc
+++ b/src/mem/ruby/network/garnet/InputUnit.cc
@@ -151,6 +151,17 @@
m_credit_link->scheduleEventAbsolute(m_router->clockEdge(Cycles(1)));
}
+bool
+InputUnit::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ bool read = false;
+ for (auto& virtual_channel : virtualChannels) {
+ if (virtual_channel.functionalRead(pkt, mask))
+ read = true;
+ }
+
+ return read;
+}
uint32_t
InputUnit::functionalWrite(Packet *pkt)
diff --git a/src/mem/ruby/network/garnet/InputUnit.hh b/src/mem/ruby/network/garnet/InputUnit.hh
index cc9bb1a..4c4baeb 100644
--- a/src/mem/ruby/network/garnet/InputUnit.hh
+++ b/src/mem/ruby/network/garnet/InputUnit.hh
@@ -152,7 +152,9 @@
double get_buf_write_activity(unsigned int vnet) const
{ return m_num_buffer_writes[vnet]; }
+ bool functionalRead(Packet *pkt, WriteMask &mask);
uint32_t functionalWrite(Packet *pkt);
+
void resetStats();
private:
diff --git a/src/mem/ruby/network/garnet/NetworkInterface.cc b/src/mem/ruby/network/garnet/NetworkInterface.cc
index 1154718..31d625c 100644
--- a/src/mem/ruby/network/garnet/NetworkInterface.cc
+++ b/src/mem/ruby/network/garnet/NetworkInterface.cc
@@ -668,6 +668,23 @@
out << "[Network Interface]";
}
+bool
+NetworkInterface::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ bool read = false;
+ for (auto& ni_out_vc : niOutVcs) {
+ if (ni_out_vc.functionalRead(pkt, mask))
+ read = true;
+ }
+
+ for (auto &oPort: outPorts) {
+ if (oPort->outFlitQueue()->functionalRead(pkt, mask))
+ read = true;
+ }
+
+ return read;
+}
+
uint32_t
NetworkInterface::functionalWrite(Packet *pkt)
{
diff --git a/src/mem/ruby/network/garnet/NetworkInterface.hh b/src/mem/ruby/network/garnet/NetworkInterface.hh
index b5affa0..d42db5e 100644
--- a/src/mem/ruby/network/garnet/NetworkInterface.hh
+++ b/src/mem/ruby/network/garnet/NetworkInterface.hh
@@ -79,6 +79,7 @@
int get_vnet(int vc);
void init_net_ptr(GarnetNetwork *net_ptr) { m_net_ptr = net_ptr; }
+ bool functionalRead(Packet *pkt, WriteMask &mask);
uint32_t functionalWrite(Packet *);
void scheduleFlit(flit *t_flit);
diff --git a/src/mem/ruby/network/garnet/NetworkLink.cc b/src/mem/ruby/network/garnet/NetworkLink.cc
index 38a8eac..43bb6c3 100644
--- a/src/mem/ruby/network/garnet/NetworkLink.cc
+++ b/src/mem/ruby/network/garnet/NetworkLink.cc
@@ -119,6 +119,12 @@
m_link_utilized = 0;
}
+bool
+NetworkLink::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ return linkBuffer.functionalRead(pkt, mask);
+}
+
uint32_t
NetworkLink::functionalWrite(Packet *pkt)
{
diff --git a/src/mem/ruby/network/garnet/NetworkLink.hh b/src/mem/ruby/network/garnet/NetworkLink.hh
index 449d2bc..b60a513 100644
--- a/src/mem/ruby/network/garnet/NetworkLink.hh
+++ b/src/mem/ruby/network/garnet/NetworkLink.hh
@@ -81,6 +81,7 @@
inline flit* peekLink() { return linkBuffer.peekTopFlit(); }
inline flit* consumeLink() { return linkBuffer.getTopFlit(); }
+ bool functionalRead(Packet *pkt, WriteMask &mask);
uint32_t functionalWrite(Packet *);
void resetStats();
diff --git a/src/mem/ruby/network/garnet/OutputUnit.cc b/src/mem/ruby/network/garnet/OutputUnit.cc
index e669c36..d5ad753 100644
--- a/src/mem/ruby/network/garnet/OutputUnit.cc
+++ b/src/mem/ruby/network/garnet/OutputUnit.cc
@@ -172,6 +172,12 @@
m_out_link->scheduleEventAbsolute(m_router->clockEdge(Cycles(1)));
}
+bool
+OutputUnit::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ return outBuffer.functionalRead(pkt, mask);
+}
+
uint32_t
OutputUnit::functionalWrite(Packet *pkt)
{
diff --git a/src/mem/ruby/network/garnet/OutputUnit.hh b/src/mem/ruby/network/garnet/OutputUnit.hh
index 703c625..b07035c 100644
--- a/src/mem/ruby/network/garnet/OutputUnit.hh
+++ b/src/mem/ruby/network/garnet/OutputUnit.hh
@@ -104,6 +104,7 @@
return m_vc_per_vnet;
}
+ bool functionalRead(Packet *pkt, WriteMask &mask);
uint32_t functionalWrite(Packet *pkt);
private:
diff --git a/src/mem/ruby/network/garnet/Router.cc b/src/mem/ruby/network/garnet/Router.cc
index 2e5b0fe..5232b91 100644
--- a/src/mem/ruby/network/garnet/Router.cc
+++ b/src/mem/ruby/network/garnet/Router.cc
@@ -274,6 +274,26 @@
out << aggregate_fault_prob << std::endl;
}
+bool
+Router::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ bool read = false;
+ if (crossbarSwitch.functionalRead(pkt, mask))
+ read = true;
+
+ for (uint32_t i = 0; i < m_input_unit.size(); i++) {
+ if (m_input_unit[i]->functionalRead(pkt, mask))
+ read = true;
+ }
+
+ for (uint32_t i = 0; i < m_output_unit.size(); i++) {
+ if (m_output_unit[i]->functionalRead(pkt, mask))
+ read = true;
+ }
+
+ return read;
+}
+
uint32_t
Router::functionalWrite(Packet *pkt)
{
diff --git a/src/mem/ruby/network/garnet/Router.hh b/src/mem/ruby/network/garnet/Router.hh
index 874f6f7..dbcdda9 100644
--- a/src/mem/ruby/network/garnet/Router.hh
+++ b/src/mem/ruby/network/garnet/Router.hh
@@ -139,6 +139,7 @@
aggregate_fault_prob);
}
+ bool functionalRead(Packet *pkt, WriteMask &mask);
uint32_t functionalWrite(Packet *);
private:
diff --git a/src/mem/ruby/network/garnet/VirtualChannel.cc b/src/mem/ruby/network/garnet/VirtualChannel.cc
index a473bca..18e89a0 100644
--- a/src/mem/ruby/network/garnet/VirtualChannel.cc
+++ b/src/mem/ruby/network/garnet/VirtualChannel.cc
@@ -75,6 +75,12 @@
return false;
}
+bool
+VirtualChannel::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ return inputBuffer.functionalRead(pkt, mask);
+}
+
uint32_t
VirtualChannel::functionalWrite(Packet *pkt)
{
diff --git a/src/mem/ruby/network/garnet/VirtualChannel.hh b/src/mem/ruby/network/garnet/VirtualChannel.hh
index 29f3698..04b046b 100644
--- a/src/mem/ruby/network/garnet/VirtualChannel.hh
+++ b/src/mem/ruby/network/garnet/VirtualChannel.hh
@@ -95,6 +95,7 @@
return inputBuffer.getTopFlit();
}
+ bool functionalRead(Packet *pkt, WriteMask &mask);
uint32_t functionalWrite(Packet *pkt);
private:
diff --git a/src/mem/ruby/network/garnet/flit.cc b/src/mem/ruby/network/garnet/flit.cc
index b65297c..d31d826 100644
--- a/src/mem/ruby/network/garnet/flit.cc
+++ b/src/mem/ruby/network/garnet/flit.cc
@@ -126,6 +126,13 @@
}
bool
+flit::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ Message *msg = m_msg_ptr.get();
+ return msg->functionalRead(pkt, mask);
+}
+
+bool
flit::functionalWrite(Packet *pkt)
{
Message *msg = m_msg_ptr.get();
diff --git a/src/mem/ruby/network/garnet/flit.hh b/src/mem/ruby/network/garnet/flit.hh
index a84dc57..a52d741 100644
--- a/src/mem/ruby/network/garnet/flit.hh
+++ b/src/mem/ruby/network/garnet/flit.hh
@@ -107,6 +107,7 @@
}
}
+ bool functionalRead(Packet *pkt, WriteMask &mask);
bool functionalWrite(Packet *pkt);
virtual flit* serialize(int ser_id, int parts, uint32_t bWidth);
diff --git a/src/mem/ruby/network/garnet/flitBuffer.cc b/src/mem/ruby/network/garnet/flitBuffer.cc
index b6a2e0a..6b3b56c 100644
--- a/src/mem/ruby/network/garnet/flitBuffer.cc
+++ b/src/mem/ruby/network/garnet/flitBuffer.cc
@@ -85,6 +85,19 @@
max_size = maximum;
}
+bool
+flitBuffer::functionalRead(Packet *pkt, WriteMask &mask)
+{
+ bool read = false;
+ for (unsigned int i = 0; i < m_buffer.size(); ++i) {
+ if (m_buffer[i]->functionalRead(pkt, mask)) {
+ read = true;
+ }
+ }
+
+ return read;
+}
+
uint32_t
flitBuffer::functionalWrite(Packet *pkt)
{
diff --git a/src/mem/ruby/network/garnet/flitBuffer.hh b/src/mem/ruby/network/garnet/flitBuffer.hh
index d37f9a5..089c931 100644
--- a/src/mem/ruby/network/garnet/flitBuffer.hh
+++ b/src/mem/ruby/network/garnet/flitBuffer.hh
@@ -80,6 +80,7 @@
m_buffer.push_back(flt);
}
+ bool functionalRead(Packet *pkt, WriteMask &mask);
uint32_t functionalWrite(Packet *pkt);
private: