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>
This commit is contained in:
@@ -91,6 +91,17 @@ CrossbarSwitch::wakeup()
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -67,6 +67,7 @@ class CrossbarSwitch : public Consumer
|
||||
|
||||
inline double get_crossbar_activity() { return m_crossbar_activity; }
|
||||
|
||||
bool functionalRead(Packet *pkt, WriteMask &mask);
|
||||
uint32_t functionalWrite(Packet *pkt);
|
||||
void resetStats();
|
||||
|
||||
|
||||
@@ -197,10 +197,12 @@ GarnetNetwork::makeExtInLink(NodeID global_src, SwitchID dest, BasicLink* link,
|
||||
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 @@ GarnetNetwork::makeExtInLink(NodeID global_src, SwitchID dest, BasicLink* link,
|
||||
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 @@ GarnetNetwork::makeExtOutLink(SwitchID src, NodeID global_dest,
|
||||
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 @@ GarnetNetwork::makeExtOutLink(SwitchID src, NodeID global_dest,
|
||||
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 @@ GarnetNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
|
||||
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 @@ GarnetNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
|
||||
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 @@ GarnetNetwork::update_traffic_distribution(RouteInfo route)
|
||||
(*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)
|
||||
{
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace garnet
|
||||
class NetworkInterface;
|
||||
class Router;
|
||||
class NetworkLink;
|
||||
class NetworkBridge;
|
||||
class CreditLink;
|
||||
|
||||
class GarnetNetwork : public Network
|
||||
@@ -105,6 +106,7 @@ class GarnetNetwork : public Network
|
||||
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 @@ class GarnetNetwork : public Network
|
||||
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
|
||||
|
||||
@@ -151,6 +151,17 @@ InputUnit::increment_credit(int in_vc, bool free_signal, Tick curTime)
|
||||
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)
|
||||
|
||||
@@ -152,7 +152,9 @@ class InputUnit : public Consumer
|
||||
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:
|
||||
|
||||
@@ -668,6 +668,23 @@ NetworkInterface::print(std::ostream& out) const
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -79,6 +79,7 @@ class NetworkInterface : public ClockedObject, public Consumer
|
||||
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);
|
||||
|
||||
@@ -119,6 +119,12 @@ NetworkLink::resetStats()
|
||||
m_link_utilized = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
NetworkLink::functionalRead(Packet *pkt, WriteMask &mask)
|
||||
{
|
||||
return linkBuffer.functionalRead(pkt, mask);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
NetworkLink::functionalWrite(Packet *pkt)
|
||||
{
|
||||
|
||||
@@ -81,6 +81,7 @@ class NetworkLink : public ClockedObject, public Consumer
|
||||
inline flit* peekLink() { return linkBuffer.peekTopFlit(); }
|
||||
inline flit* consumeLink() { return linkBuffer.getTopFlit(); }
|
||||
|
||||
bool functionalRead(Packet *pkt, WriteMask &mask);
|
||||
uint32_t functionalWrite(Packet *);
|
||||
void resetStats();
|
||||
|
||||
|
||||
@@ -172,6 +172,12 @@ OutputUnit::insert_flit(flit *t_flit)
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -104,6 +104,7 @@ class OutputUnit : public Consumer
|
||||
return m_vc_per_vnet;
|
||||
}
|
||||
|
||||
bool functionalRead(Packet *pkt, WriteMask &mask);
|
||||
uint32_t functionalWrite(Packet *pkt);
|
||||
|
||||
private:
|
||||
|
||||
@@ -274,6 +274,26 @@ Router::printAggregateFaultProbability(std::ostream& out)
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -139,6 +139,7 @@ class Router : public BasicRouter, public Consumer
|
||||
aggregate_fault_prob);
|
||||
}
|
||||
|
||||
bool functionalRead(Packet *pkt, WriteMask &mask);
|
||||
uint32_t functionalWrite(Packet *);
|
||||
|
||||
private:
|
||||
|
||||
@@ -75,6 +75,12 @@ VirtualChannel::need_stage(flit_stage stage, Tick time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
VirtualChannel::functionalRead(Packet *pkt, WriteMask &mask)
|
||||
{
|
||||
return inputBuffer.functionalRead(pkt, mask);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
VirtualChannel::functionalWrite(Packet *pkt)
|
||||
{
|
||||
|
||||
@@ -95,6 +95,7 @@ class VirtualChannel
|
||||
return inputBuffer.getTopFlit();
|
||||
}
|
||||
|
||||
bool functionalRead(Packet *pkt, WriteMask &mask);
|
||||
uint32_t functionalWrite(Packet *pkt);
|
||||
|
||||
private:
|
||||
|
||||
@@ -125,6 +125,13 @@ flit::print(std::ostream& out) const
|
||||
out << "]";
|
||||
}
|
||||
|
||||
bool
|
||||
flit::functionalRead(Packet *pkt, WriteMask &mask)
|
||||
{
|
||||
Message *msg = m_msg_ptr.get();
|
||||
return msg->functionalRead(pkt, mask);
|
||||
}
|
||||
|
||||
bool
|
||||
flit::functionalWrite(Packet *pkt)
|
||||
{
|
||||
|
||||
@@ -107,6 +107,7 @@ class flit
|
||||
}
|
||||
}
|
||||
|
||||
bool functionalRead(Packet *pkt, WriteMask &mask);
|
||||
bool functionalWrite(Packet *pkt);
|
||||
|
||||
virtual flit* serialize(int ser_id, int parts, uint32_t bWidth);
|
||||
|
||||
@@ -85,6 +85,19 @@ flitBuffer::setMaxSize(int maximum)
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -80,6 +80,7 @@ class flitBuffer
|
||||
m_buffer.push_back(flt);
|
||||
}
|
||||
|
||||
bool functionalRead(Packet *pkt, WriteMask &mask);
|
||||
uint32_t functionalWrite(Packet *pkt);
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user