ruby: Fix garnet's round robin arbitration for vc selection

Garnet utilizes round robin policy to select a VC for
transmission ar Network Interface and Routers. The current logic
for round robin is only fair if all the virtual networks are active
at a given router. If the router or network interface is not
receiving traffic in from any vnet then the priority is always taken
up by the next vnet in numerically (or loops back to 0).

This fix changes the way we perform round robin arbitration. When
a VC is selected in a cycle, the round robin pointer is set to the VC
next to it and is iterated from there on. If any VC does not have a
flit in a given cycle, it will lose its turn until the next round.
At maximum traffic this will model round robin correctly even if
a certain VNET is not active at that unit.

Change-Id: I9bf805221054f9f25bee14b57ff521f4ce4ca980
Reviewed-on: https://gem5-review.googlesource.com/c/16688
Reviewed-by: Jieming Yin <Jieming.Yin@amd.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
Srikant Bharadwaj
2019-02-22 17:43:33 -05:00
parent 365ed5b916
commit 21a4cc9692
2 changed files with 6 additions and 7 deletions

View File

@@ -437,9 +437,6 @@ void
NetworkInterface::scheduleOutputLink()
{
int vc = m_vc_round_robin;
m_vc_round_robin++;
if (m_vc_round_robin == m_num_vcs)
m_vc_round_robin = 0;
for (int i = 0; i < m_num_vcs; i++) {
vc++;
@@ -470,6 +467,8 @@ NetworkInterface::scheduleOutputLink()
if (!is_candidate_vc)
continue;
m_vc_round_robin = vc;
m_out_vc_state[vc]->decrement_credit();
// Just removing the flit
flit *t_flit = m_ni_out_vcs[vc]->getTopFlit();

View File

@@ -136,8 +136,8 @@ SwitchAllocator::arbitrate_inports()
m_port_requests[outport][inport] = true;
m_vc_winners[outport][inport]= invc;
// Update Round Robin pointer
m_round_robin_invc[inport]++;
// Update Round Robin pointer to the next VC
m_round_robin_invc[inport] = invc + 1;
if (m_round_robin_invc[inport] >= m_num_vcs)
m_round_robin_invc[inport] = 0;
@@ -252,7 +252,7 @@ SwitchAllocator::arbitrate_outports()
m_port_requests[outport][inport] = false;
// Update Round Robin pointer
m_round_robin_inport[outport]++;
m_round_robin_inport[outport] = inport + 1;
if (m_round_robin_inport[outport] >= m_num_inports)
m_round_robin_inport[outport] = 0;
@@ -393,4 +393,4 @@ SwitchAllocator::resetStats()
{
m_input_arbiter_activity = 0;
m_output_arbiter_activity = 0;
}
}