protected bool rb_inject(Flit[] input) { bool redirection = false; Flit temp = null; if (rbuf.isEmpty()) { rb_inject_block_count = 0; } if (rb_inject_block_count > Config.redirectThreshold) { redirection = true; } if (redirection) { int rand = Simulator.rand.Next(TOTAL_DIR); if (input[rand] != null && !Simulator.network.golden.isGolden(input[rand])) { temp = input[rand]; input[rand] = null; rb_inject_block_count = 0; } } int injectedCount = 0; // Resubmit Buffer Injection for (int i = 0; i < TOTAL_DIR; i++) { if (rbuf.isEmpty() || injectedCount == Config.rbInjectCount) { break; } if (input[i] == null) { input[i] = rbuf.removeFlit(); injectedCount++; Simulator.stats.rb_injectCount.Add(); } } if (!rbuf.isEmpty() && injectedCount == 0) { rb_inject_block_count++; } if (redirection && temp != null) { Simulator.stats.redirectedFlits.Add(); Simulator.stats.rb_ejectCount.Add(); rbuf.addFlit(temp); } return(redirection); }
Flit[] input = new Flit[4]; // keep this as a member var so we don't // have to allocate on every step (why can't // we have arrays on the stack like in C?) protected override void _doStep() { Flit[] eject = new Flit[4]; eject[0] = eject[1] = eject[2] = eject[3] = null; int wantToEject = 0; for (int i = 0; i < 4; i++) { if (linkIn[i] != null && linkIn[i].Out != null) { if (linkIn[i].Out.dest.x == coord.x && linkIn[i].Out.dest.y == coord.y) { wantToEject++; } } } switch (wantToEject) { case 0: Simulator.stats.eject_0.Add(); break; case 1: Simulator.stats.eject_1.Add(); break; case 2: Simulator.stats.eject_2.Add(); break; case 3: Simulator.stats.eject_3.Add(); break; case 4: Simulator.stats.eject_4.Add(); break; default: throw new Exception("Eject problem"); } for (int i = 0; i < Config.ejectCount; i++) { eject[i] = ejectLocal(); } for (int i = 0; i < 4; i++) { input[i] = null; } // grab inputs into a local array so we can sort int c = 0; for (int dir = 0; dir < 4; dir++) { if (linkIn[dir] != null && linkIn[dir].Out != null) { input[c++] = linkIn[dir].Out; linkIn[dir].Out.inDir = dir; linkIn[dir].Out = null; } } int before = 0; for (int i = 0; i < 4; i++) { if (input[i] != null) { before++; } } int reinjectedCount = 0; if (Config.resubmitBuffer) { if (!rBuf.isEmpty()) { for (int i = 0; i < 4; i++) { if (reinjectedCount < Config.rebufInjectCount) { if (input[i] == null && !rBuf.isEmpty()) { input[i] = rBuf.removeFlit(); input[i].nrInRebuf++; reinjectedCount++; } } } } } int after = 0; for (int i = 0; i < 4; i++) { if (input[i] != null) { after++; } } if (before + reinjectedCount != after) { throw new Exception("Something weird happened on resubmit buffer"); } /*for (int i = 0; i < 4; i++) * for (int j = 0; j < 4; j++) * { * if (input[i] == null || input[j] == null) * continue; * if (i != j && input[i].Equals(input[j])) * throw new Exception("DUPLICATING"); * } */ // sometimes network-meddling such as flit-injection can put unexpected // things in outlinks... int outCount = 0; for (int dir = 0; dir < 4; dir++) { if (linkOut[dir] != null && linkOut[dir].In != null) { outCount++; } } bool wantToInject = m_injectSlot2 != null || m_injectSlot != null; bool canInject = (c + outCount) < neighbors; bool starved = wantToInject && !canInject; if (starved) { Flit starvedFlit = null; if (starvedFlit == null) { starvedFlit = m_injectSlot2; } if (starvedFlit == null) { starvedFlit = m_injectSlot; } Simulator.controller.reportStarve(coord.ID); statsStarve(starvedFlit); } if (canInject && wantToInject) { Flit inj_peek = null; if (m_injectSlot2 != null) { inj_peek = m_injectSlot2; } else if (m_injectSlot != null) { inj_peek = m_injectSlot; } if (inj_peek == null) { throw new Exception("Inj flit peek is null!!"); } if (!Simulator.controller.ThrottleAtRouter || Simulator.controller.tryInject(coord.ID)) { Flit inj = null; if (m_injectSlot2 != null) { inj = m_injectSlot2; m_injectSlot2 = null; } else if (m_injectSlot != null) { inj = m_injectSlot; m_injectSlot = null; } else { throw new Exception("what???inject null flits??"); } input[c++] = inj; #if DEBUG Console.WriteLine("injecting flit {0}.{1} at node {2} cyc {3}", m_injectSlot.packet.ID, m_injectSlot.flitNr, coord, Simulator.CurrentRound); #endif #if memD int r = inj.packet.requesterID; if (r == coord.ID) { Console.WriteLine("inject flit at node {0}<>request:{1}", coord.ID, r); } else { Console.WriteLine("Diff***inject flit at node {0}<>request:{1}", coord.ID, r); } #endif statsInjectFlit(inj); } } for (int i = 0; i < Config.ejectCount; i++) { if (eject[i] != null) { acceptFlit(eject[i]); } } // inline bubble sort is faster for this size than Array.Sort() // sort input[] by descending priority. rank(a,b) < 0 iff a has higher priority. for (int i = 0; i < 4; i++) { for (int j = i + 1; j < 4; j++) { if (input[j] != null && (input[i] == null || rank(input[j], input[i]) < 0)) { Flit t = input[i]; input[i] = input[j]; input[j] = t; } } } //int resubmittedCount = 0; //int numDeflected = 0; int[] deflected = new int[4]; deflected[0] = deflected[1] = deflected[2] = deflected[3] = -1; // assign outputs for (int i = 0; i < 4 && input[i] != null; i++) { PreferredDirection pd = determineDirection(input[i], coord); int outDir = -1; Flit tempFlit = input[i]; if (pd.xDir != Simulator.DIR_NONE && linkOut[pd.xDir].In == null) { linkOut[pd.xDir].In = input[i]; outDir = pd.xDir; /* Refresh wasInBuf */ if (Config.wasInRebufCycleRefresh) { tempFlit.wasInRebuf = false; } } else if (pd.yDir != Simulator.DIR_NONE && linkOut[pd.yDir].In == null) { linkOut[pd.yDir].In = input[i]; outDir = pd.yDir; /* Refresh wasInBuf */ if (Config.wasInRebufCycleRefresh) { tempFlit.wasInRebuf = false; } } // deflect! else { input[i].Deflected = true; int dir = 0; /*deflected[numDeflected] = i; * numDeflected++; * */ if (Config.randomize_defl) { dir = Simulator.rand.Next(4); // randomize deflection dir (so no bias) } for (int count = 0; count < 4; count++, dir = (dir + 1) % 4) { if (linkOut[dir] != null && linkOut[dir].In == null) { linkOut[dir].In = input[i]; outDir = dir; break; } } if (outDir == -1) { throw new Exception( String.Format("Ran out of outlinks in arbitration at node {0} on input {1} cycle {2} flit {3} c {4} neighbors {5} outcount {6}", coord, i, Simulator.CurrentRound, input[i], c, neighbors, outCount)); } } } /* * if (Config.resubmitBuffer) * sortDeflected(deflected); * * for (int i = 0; i < 4; i++) * { * if (deflected[i] == -1) * break; * else * { * int dir = 0; * if (Config.randomize_defl) * dir = Simulator.rand.Next(4); * * for (int count = 0; count < 4; count++, dir = (dir + 1) % 4) { * if(linkOut[dir] != null && linkOut[dir].In == null) { * linkOut[dir].In = input[deflected[i]]; * //outDir = dir; * break; * } * } * } * } */ }
Flit[] input = new Flit[6]; // keep this as a member var so we don't // have to allocate on every step (why can't // we have arrays on the stack like in C?) // --- because we have a garbage collector instead and want to dynamically allocate everything protected override void _doStep() { int tempCount = 0; /* Setup the inputs */ for (int dir = 0; dir < 6; dir++) { if (linkIn[dir] != null && linkIn[dir].Out != null) { tempCount++; input[dir] = linkIn[dir].Out; input[dir].inDir = dir; } else { input[dir] = null; } } //To avoid the create / remove counter exception if (injectPlaceholder > 0) { tempCount++; } /* Only used when forcing a placeholder into the system */ int tempDir = (clockwise) ? Simulator.DIR_CCW : Simulator.DIR_CW; if (input[tempDir] == null && !rBuf.isEmpty()) { input[tempDir] = rBuf.removeFlit(); } else if (input[connectionDirection] == null && !rBuf.isEmpty()) { input[connectionDirection] = rBuf.removeFlit(); } route(); int endCount = 0; /* Assign outputs */ for (int dir = 0; dir < 6; dir++) { if (input[dir] != null) { #if FLIT Console.WriteLine("flit {0}.{1} at node {2} cyc {3} \t | dir:{4} | dest: {5} connectionDir {6} productive: {7} isDest {8}", input[dir].packet.ID, input[dir].flitNr, ringCoord, Simulator.CurrentRound, dir, input[dir].packet.ringdest, connectionDirection, isRingProductive(input[dir], connectionDirection), isDestRing(input[dir])); Console.WriteLine("\tflit {0}.{1} currentRing = {2} destRing = {3},{4}", input[dir].packet.ID, input[dir].flitNr, ringCoord, input[dir].tempX, input[dir].tempY); #endif endCount++; if (linkOut[dir] == null) { throw new Exception(String.Format("connector {0} does not have link in dir {1}", ringCoord, dir)); } linkOut[dir].In = input[dir]; } } if (endCount != tempCount) { throw new Exception(String.Format("connector {0} created or destroyed flits. Before: {1} | After: {2}", ringCoord, tempCount, endCount)); } }