#include <cassert>
#include <cmath>
+#include "base/cast.hh"
#include "base/stl_helpers.hh"
#include "debug/RubyNetwork.hh"
-#include "mem/ruby/buffers/MessageBuffer.hh"
+#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh"
#include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh"
#include "mem/ruby/slicc_interface/NetworkMessage.hh"
using namespace std;
using m5::stl_helpers::deletePointers;
-NetworkInterface_d::NetworkInterface_d(int id, int virtual_networks,
- GarnetNetwork_d *network_ptr)
+NetworkInterface_d::NetworkInterface_d(const Params *p)
+ : ClockedObject(p), Consumer(this)
{
- m_id = id;
- m_net_ptr = network_ptr;
- m_virtual_networks = virtual_networks;
- m_vc_per_vnet = m_net_ptr->getVCsPerClass();
+ m_id = p->id;
+ m_virtual_networks = p->virt_nets;
+ m_vc_per_vnet = p->vcs_per_vnet;
m_num_vcs = m_vc_per_vnet*m_virtual_networks;
m_vc_round_robin = 0;
m_ni_buffers.resize(m_num_vcs);
m_ni_enqueue_time.resize(m_num_vcs);
- inNode_ptr.resize(m_virtual_networks);
- outNode_ptr.resize(m_virtual_networks);
creditQueue = new flitBuffer_d();
// instantiating the NI flit buffers
for (int i = 0; i < m_num_vcs; i++) {
m_ni_buffers[i] = new flitBuffer_d();
- m_ni_enqueue_time[i] = INFINITE_;
+ m_ni_enqueue_time[i] = Cycles(INFINITE_);
}
+
m_vc_allocator.resize(m_virtual_networks); // 1 allocator per vnet
for (int i = 0; i < m_virtual_networks; i++) {
m_vc_allocator[i] = 0;
}
+}
+void
+NetworkInterface_d::init()
+{
for (int i = 0; i < m_num_vcs; i++) {
m_out_vc_state.push_back(new OutVcState_d(i, m_net_ptr));
- m_out_vc_state[i]->setState(IDLE_, g_eventQueue_ptr->getTime());
}
}
}
void
-NetworkInterface_d::addNode(vector<MessageBuffer *>& in,
- vector<MessageBuffer *>& out)
+NetworkInterface_d::addNode(map<int, MessageBuffer *>& in,
+ map<int, MessageBuffer *>& out)
{
- assert(in.size() == m_virtual_networks);
inNode_ptr = in;
outNode_ptr = out;
- for (int j = 0; j < m_virtual_networks; j++) {
+ for (auto& it : in) {
// the protocol injects messages into the NI
- inNode_ptr[j]->setConsumer(this);
+ it.second->setConsumer(this);
+ it.second->setReceiver(this);
+ }
+
+ for (auto& it : out) {
+ it.second->setSender(this);
}
}
// flitisized and an output vc is acquired
net_msg_ptr->getInternalDestination().removeNetDest(personal_dest);
}
- if (num_flits > 1) { // data packet
- // defining ctrl vnet to be 1-flit packets
- // and data vnet to be > 1 flit packets
- m_net_ptr->set_vnet_type(vc, DATA_VNET_);
- m_out_vc_state[vc]->set_credit_count();
- }
for (int i = 0; i < num_flits; i++) {
- m_net_ptr->increment_injected_flits();
- flit_d *fl = new flit_d(i, vc, vnet, num_flits, new_msg_ptr);
- fl->set_delay(g_eventQueue_ptr->getTime() - msg_ptr->getTime());
+ m_net_ptr->increment_injected_flits(vnet);
+ flit_d *fl = new flit_d(i, vc, vnet, num_flits, new_msg_ptr,
+ curCycle());
+
+ fl->set_delay(curCycle() - ticksToCycles(msg_ptr->getTime()));
m_ni_buffers[vc]->insert(fl);
}
- m_ni_enqueue_time[vc] = g_eventQueue_ptr->getTime();
- m_out_vc_state[vc]->setState(ACTIVE_, g_eventQueue_ptr->getTime());
+
+ m_ni_enqueue_time[vc] = curCycle();
+ m_out_vc_state[vc]->setState(ACTIVE_, curCycle());
}
return true ;
}
m_vc_allocator[vnet] = 0;
if (m_out_vc_state[(vnet*m_vc_per_vnet) + delta]->isInState(
- IDLE_, g_eventQueue_ptr->getTime())) {
+ IDLE_, curCycle())) {
return ((vnet*m_vc_per_vnet) + delta);
}
}
void
NetworkInterface_d::wakeup()
{
- DPRINTF(RubyNetwork, "m_id: %d woke up at time: %lld",
- m_id, g_eventQueue_ptr->getTime());
+ DPRINTF(RubyNetwork, "m_id: %d woke up at time: %lld", m_id, curCycle());
MsgPtr msg_ptr;
// Checking for messages coming from the protocol
// can pick up a message/cycle for each virtual net
- for (int vnet = 0; vnet < m_virtual_networks; vnet++) {
- while (inNode_ptr[vnet]->isReady()) { // Is there a message waiting
- msg_ptr = inNode_ptr[vnet]->peekMsgPtr();
+ for (auto it = inNode_ptr.begin(); it != inNode_ptr.end(); ++it) {
+ int vnet = (*it).first;
+ MessageBuffer *b = (*it).second;
+
+ while (b->isReady()) { // Is there a message waiting
+ msg_ptr = b->peekMsgPtr();
if (flitisizeMessage(msg_ptr, vnet)) {
- inNode_ptr[vnet]->pop();
+ b->dequeue();
} else {
break;
}
/*********** Picking messages destined for this NI **********/
- if (inNetLink->isReady()) {
+ if (inNetLink->isReady(curCycle())) {
flit_d *t_flit = inNetLink->consumeLink();
bool free_signal = false;
if (t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_) {
free_signal = true;
outNode_ptr[t_flit->get_vnet()]->enqueue(
- t_flit->get_msg_ptr(), 1);
+ t_flit->get_msg_ptr(), Cycles(1));
}
// Simply send a credit back since we are not buffering
// this flit in the NI
- flit_d *credit_flit = new flit_d(t_flit->get_vc(), free_signal);
+ flit_d *credit_flit = new flit_d(t_flit->get_vc(), free_signal,
+ curCycle());
creditQueue->insert(credit_flit);
- g_eventQueue_ptr->scheduleEvent(m_ni_credit_link, 1);
-
- m_net_ptr->increment_received_flits();
- int network_delay = g_eventQueue_ptr->getTime() -
- t_flit->get_enqueue_time();
- int queueing_delay = t_flit->get_delay();
- m_net_ptr->increment_network_latency(network_delay);
- m_net_ptr->increment_queueing_latency(queueing_delay);
+ m_ni_credit_link->
+ scheduleEventAbsolute(clockEdge(Cycles(1)));
+
+ int vnet = t_flit->get_vnet();
+ m_net_ptr->increment_received_flits(vnet);
+ Cycles network_delay = curCycle() - t_flit->get_enqueue_time();
+ Cycles queueing_delay = t_flit->get_delay();
+
+ m_net_ptr->increment_network_latency(network_delay, vnet);
+ m_net_ptr->increment_queueing_latency(queueing_delay, vnet);
delete t_flit;
}
/****************** Checking for credit link *******/
- if (m_credit_link->isReady()) {
+ if (m_credit_link->isReady(curCycle())) {
flit_d *t_flit = m_credit_link->consumeLink();
m_out_vc_state[t_flit->get_vc()]->increment_credit();
if (t_flit->is_free_signal()) {
- m_out_vc_state[t_flit->get_vc()]->setState(IDLE_,
- g_eventQueue_ptr->getTime());
+ m_out_vc_state[t_flit->get_vc()]->setState(IDLE_, curCycle());
}
delete t_flit;
}
vc = 0;
// model buffer backpressure
- if (m_ni_buffers[vc]->isReady() && m_out_vc_state[vc]->has_credits()) {
+ if (m_ni_buffers[vc]->isReady(curCycle()) &&
+ m_out_vc_state[vc]->has_credits()) {
+
bool is_candidate_vc = true;
int t_vnet = get_vnet(vc);
int vc_base = t_vnet * m_vc_per_vnet;
for (int vc_offset = 0; vc_offset < m_vc_per_vnet;
vc_offset++) {
int t_vc = vc_base + vc_offset;
- if (m_ni_buffers[t_vc]->isReady()) {
+ if (m_ni_buffers[t_vc]->isReady(curCycle())) {
if (m_ni_enqueue_time[t_vc] < m_ni_enqueue_time[vc]) {
is_candidate_vc = false;
break;
m_out_vc_state[vc]->decrement_credit();
// Just removing the flit
flit_d *t_flit = m_ni_buffers[vc]->getTopFlit();
- t_flit->set_time(g_eventQueue_ptr->getTime() + 1);
+ t_flit->set_time(curCycle() + Cycles(1));
outSrcQueue->insert(t_flit);
// schedule the out link
- g_eventQueue_ptr->scheduleEvent(outNetLink, 1);
+ outNetLink->scheduleEventAbsolute(clockEdge(Cycles(1)));
if (t_flit->get_type() == TAIL_ ||
t_flit->get_type() == HEAD_TAIL_) {
- m_ni_enqueue_time[vc] = INFINITE_;
+ m_ni_enqueue_time[vc] = Cycles(INFINITE_);
}
return;
}
int
NetworkInterface_d::get_vnet(int vc)
{
- for (int i = 0; i < m_net_ptr->getNumberOfVirtualNetworks(); i++) {
+ for (int i = 0; i < m_virtual_networks; i++) {
if (vc >= (i*m_vc_per_vnet) && vc < ((i+1)*m_vc_per_vnet)) {
return i;
}
void
NetworkInterface_d::checkReschedule()
{
- for (int vnet = 0; vnet < m_virtual_networks; vnet++) {
- if (inNode_ptr[vnet]->isReady()) { // Is there a message waiting
- g_eventQueue_ptr->scheduleEvent(this, 1);
+ for (const auto& it : inNode_ptr) {
+ MessageBuffer *b = it.second;
+
+ while (b->isReady()) { // Is there a message waiting
+ scheduleEvent(Cycles(1));
return;
}
}
+
for (int vc = 0; vc < m_num_vcs; vc++) {
- if (m_ni_buffers[vc]->isReadyForNext()) {
- g_eventQueue_ptr->scheduleEvent(this, 1);
+ if (m_ni_buffers[vc]->isReady(curCycle() + Cycles(1))) {
+ scheduleEvent(Cycles(1));
return;
}
}
}
void
-NetworkInterface_d::printConfig(std::ostream& out) const
+NetworkInterface_d::print(std::ostream& out) const
{
- out << "[Network Interface " << m_id << "] - ";
- out << "[inLink " << inNetLink->get_id() << "] - ";
- out << "[outLink " << outNetLink->get_id() << "]" << std::endl;
+ out << "[Network Interface]";
}
-void
-NetworkInterface_d::print(std::ostream& out) const
+uint32_t
+NetworkInterface_d::functionalWrite(Packet *pkt)
{
- out << "[Network Interface]";
+ uint32_t num_functional_writes = 0;
+ for (unsigned int i = 0; i < m_num_vcs; ++i) {
+ num_functional_writes += m_ni_buffers[i]->functionalWrite(pkt);
+ }
+
+ num_functional_writes += outSrcQueue->functionalWrite(pkt);
+ return num_functional_writes;
+}
+
+NetworkInterface_d *
+GarnetNetworkInterface_dParams::create()
+{
+ return new NetworkInterface_d(this);
}
+