// First do round robin arbitration on a set of input vc requests
for (int inport = 0; inport < m_num_inports; inport++) {
int invc = m_round_robin_inport[inport];
- m_round_robin_inport[inport]++;
- if (m_round_robin_inport[inport] >= m_num_vcs)
- m_round_robin_inport[inport] = 0;
- for (int j = 0; j < m_num_vcs; j++) {
+ // Select next round robin vc candidate within valid vnet
+ int next_round_robin_invc = invc;
+ do {
+ next_round_robin_invc++;
+
+ if (next_round_robin_invc >= m_num_vcs)
+ next_round_robin_invc = 0;
+ } while (!((m_router->get_net_ptr())->validVirtualNetwork(
+ get_vnet(next_round_robin_invc))));
+
+ m_round_robin_inport[inport] = next_round_robin_invc;
+
+ for (int invc_iter = 0; invc_iter < m_num_vcs; invc_iter++) {
invc++;
if (invc >= m_num_vcs)
invc = 0;
+
+ if (!((m_router->get_net_ptr())->validVirtualNetwork(
+ get_vnet(invc))))
+ continue;
+
if (m_input_unit[inport]->need_stage(invc, ACTIVE_, SA_) &&
m_input_unit[inport]->has_credits(invc)) {
if (is_candidate_inport(inport, invc)) {
// Now there are a set of input vc requests for output vcs.
// Again do round robin arbitration on these requests
for (int outport = 0; outport < m_num_outports; outport++) {
- int in_port = m_round_robin_outport[outport];
+ int inport = m_round_robin_outport[outport];
m_round_robin_outport[outport]++;
if (m_round_robin_outport[outport] >= m_num_outports)
m_round_robin_outport[outport] = 0;
- for (int inport = 0; inport < m_num_inports; inport++) {
- in_port++;
- if (in_port >= m_num_inports)
- in_port = 0;
+ for (int inport_iter = 0; inport_iter < m_num_inports; inport_iter++) {
+ inport++;
+ if (inport >= m_num_inports)
+ inport = 0;
- // in_port has a request this cycle for outport:
- if (m_port_req[outport][in_port]) {
- m_port_req[outport][in_port] = false;
- int invc = m_vc_winners[outport][in_port];
- int outvc = m_input_unit[in_port]->get_outvc(invc);
+ // inport has a request this cycle for outport:
+ if (m_port_req[outport][inport]) {
+ m_port_req[outport][inport] = false;
+ int invc = m_vc_winners[outport][inport];
+ int outvc = m_input_unit[inport]->get_outvc(invc);
// remove flit from Input Unit
- flit_d *t_flit = m_input_unit[in_port]->getTopFlit(invc);
+ flit_d *t_flit = m_input_unit[inport]->getTopFlit(invc);
t_flit->advance_stage(ST_);
t_flit->set_vc(outvc);
t_flit->set_outport(outport);
t_flit->set_time(g_eventQueue_ptr->getTime() + 1);
m_output_unit[outport]->decrement_credit(outvc);
- m_router->update_sw_winner(in_port, t_flit);
+ m_router->update_sw_winner(inport, t_flit);
m_global_arbiter_activity++;
if ((t_flit->get_type() == TAIL_) ||
t_flit->get_type() == HEAD_TAIL_) {
// Send a credit back
// along with the information that this VC is now idle
- m_input_unit[in_port]->increment_credit(invc, true);
+ m_input_unit[inport]->increment_credit(invc, true);
// This Input VC should now be empty
- assert(m_input_unit[in_port]->isReady(invc) == false);
+ assert(m_input_unit[inport]->isReady(invc) == false);
- m_input_unit[in_port]->set_vc_state(IDLE_, invc);
- m_input_unit[in_port]->set_enqueue_time(invc, INFINITE_);
+ m_input_unit[inport]->set_vc_state(IDLE_, invc);
+ m_input_unit[inport]->set_enqueue_time(invc, INFINITE_);
} else {
// Send a credit back
// but do not indicate that the VC is idle
- m_input_unit[in_port]->increment_credit(invc, false);
+ m_input_unit[inport]->increment_credit(invc, false);
}
break; // got a in request for this outport
}
int
SWallocator_d::get_vnet(int invc)
{
- for (int i = 0; i < RubySystem::getNetwork()->getNumberOfVirtualNetworks();
- i++) {
- if (invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet)) {
- return i;
- }
- }
- fatal("Could not determine vc");
+ int vnet = invc/m_vc_per_vnet;
+ assert(vnet < m_router->get_num_vnets());
+ return vnet;
}
void
if (inport >= m_in_link.size())
inport = 0;
int invc = m_round_robin_invc[inport];
- m_round_robin_invc[inport]++;
- if (m_round_robin_invc[inport] >= m_num_vcs)
- m_round_robin_invc[inport] = 0;
+ int next_round_robin_invc = invc;
+ do {
+ next_round_robin_invc++;
+
+ if (next_round_robin_invc >= m_num_vcs)
+ next_round_robin_invc = 0;
+
+ } while (!(m_net_ptr->validVirtualNetwork(
+ get_vnet(next_round_robin_invc))));
+
+ m_round_robin_invc[inport] = next_round_robin_invc;
+
for (int vc_iter = 0; vc_iter < m_num_vcs; vc_iter++) {
invc++;
if (invc >= m_num_vcs)
invc = 0;
+
+ if (!(m_net_ptr->validVirtualNetwork(get_vnet(invc))))
+ continue;
+
InVcState *in_vc_state = m_in_vc_state[inport][invc];
if (in_vc_state->isInState(VC_AB_, g_eventQueue_ptr->getTime())) {
{
for (int port = 0; port < m_out_link.size(); port++) {
int vc_tolookat = m_vc_round_robin[port];
- m_vc_round_robin[port]++;
- if (m_vc_round_robin[port] == m_num_vcs)
- m_vc_round_robin[port] = 0;
+
+ int next_round_robin_vc_tolookat = vc_tolookat;
+ do {
+ next_round_robin_vc_tolookat++;
+
+ if (next_round_robin_vc_tolookat == m_num_vcs)
+ next_round_robin_vc_tolookat = 0;
+ } while (!(m_net_ptr->validVirtualNetwork(
+ get_vnet(next_round_robin_vc_tolookat))));
+
+ m_vc_round_robin[port] = next_round_robin_vc_tolookat;
for (int i = 0; i < m_num_vcs; i++) {
vc_tolookat++;
}
}
+int
+Router::get_vnet(int vc)
+{
+ int vnet = vc/m_vc_per_vnet;
+ assert(vnet < m_virtual_networks);
+ return vnet;
+}
+
void
Router::checkReschedule()
{