// Includes injection channel and 2 extra channels that are not used. protected override void _doStep() { #if DEBUG Console.WriteLine("INITIAL dostep"); #endif Flit[] eject = new Flit[Config.ejectCount]; for (int i = 0; i < Config.ejectCount; i++) { if (Config.calf_new_inj_ej) { eject[i] = ejectLocalNew(); } else { eject[i] = ejectLocal(); } #if DEBUG Console.WriteLine("eject"); #endif } #if DEBUG Console.WriteLine("after ejection"); #endif for (int dir = 0; dir < TOTAL_DIR; dir++) { if (linkIn[dir] != null && linkIn[dir].Out != null) { input[dir] = linkIn[dir].Out; input[dir].inDir = dir; } else { input[dir] = null; } } Flit inj = null; bool injected = false; if (m_injectSlot2 != null) { inj = m_injectSlot2; m_injectSlot2 = null; } else if (m_injectSlot != null) { inj = m_injectSlot; m_injectSlot = null; } #if DEBUG if (inj != null) { Console.WriteLine("cyc {0} @ coord ({1},{2}) inject flit w/ PID: {3}.{4}", Simulator.CurrentRound, coord.x, coord.y, inj.packet.ID, inj.flitNr); } #endif input[LOCAL_INDEX] = inj; if (inj != null) { inj.inDir = -1; } for (int i = 0; i < TOTAL_PORTS; i++) { if (input[i] != null) { PreferredDirection pd = determineDirection(input[i]); if (pd.xDir != Simulator.DIR_NONE) { input[i].prefDir = pd.xDir; } else { input[i].prefDir = pd.yDir; } // // Flattened butterfly optimization - if a flit doesn't get to win ejection, forward it // to the loopback port, instead of making it deflect to some random port. // if (Config.bFtfly && Config.bDeflectLoopback) { if (input[i].prefDir == Simulator.DIR_NONE) { Flit loopBackX = m_sort.loopBackX; Flit loopBackY = m_sort.loopBackY; if (loopBackX == null) { m_sort.loopBackX = input[i]; input[i] = null; } else if (loopBackY == null) { m_sort.loopBackY = input[i]; input[i] = null; } } } } } #if DEBUG Console.WriteLine("INITIAL route"); #endif m_sort.route(input, out injected); // Basically, inputs becomes outputs after routing in the sorting // network. for (int i = 0; i < TOTAL_DIR; i++) { if (input[i] != null) { #if DEBUG Console.WriteLine("cyc {4} @ coord ({5},{6}) input dir {0} pref dir {1} output dir {2} age {3}", input[i].inDir, input[i].prefDir, i, Router_Flit_OldestFirst.age(input[i]), Simulator.CurrentRound, coord.x, coord.y); #endif input[i].Deflected = input[i].prefDir != i; } } if (Config.calf_new_inj_ej) { if (inj != null && input[inj.prefDir] == null) { input[inj.prefDir] = inj; injected = true; } } if (!injected) { if (m_injectSlot == null) { m_injectSlot = inj; } else { m_injectSlot2 = inj; } } else { statsInjectFlit(inj); } for (int i = 0; i < Config.ejectCount; i++) { if (eject[i] == null) { break; } else { acceptFlit(eject[i]); } } for (int dir = 0; dir < TOTAL_DIR; dir++) { if (input[dir] != null) { #if DEBUG Console.WriteLine("cyc {0} @ coord ({1},{2})->arb output dir:{3} w/ ID: {4}", Simulator.CurrentRound, coord.x, coord.y, dir, input[dir].packet.ID); #endif if (linkOut[dir] == null) { throw new Exception(String.Format("router {0} does not have link in dir {1}", coord, dir)); } linkOut[dir].In = input[dir]; } } #if DEBUG Console.WriteLine("-END OF DOSTEP-"); #endif }
Flit[] input = new Flit[5]; // 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() { if (Config.InfEjectBuffer) { for (int dir = 0; dir < 4; dir++) { if (linkIn[dir] != null && linkIn[dir].Out != null && linkIn[dir].Out.packet.dest.ID == ID) { ejectBuffer[dir].Enqueue(linkIn[dir].Out); linkIn[dir].Out = null; } } int bestdir = -1; for (int dir = 0; dir < 4; dir++) { if (ejectBuffer[dir].Count > 0 && (bestdir == -1 || ejectBuffer[dir].Peek().injectionTime < ejectBuffer[bestdir].Peek().injectionTime)) { bestdir = dir; } } if (bestdir != -1) { acceptFlit(ejectBuffer[bestdir].Dequeue()); } } else if (Config.EjectBufferSize != -1) { for (int dir = 0; dir < 4; dir++) { if (linkIn[dir] != null && linkIn[dir].Out != null && linkIn[dir].Out.packet.dest.ID == ID && ejectBuffer[dir].Count < Config.EjectBufferSize) { ejectBuffer[dir].Enqueue(linkIn[dir].Out); linkIn[dir].Out = null; } } int bestdir = -1; for (int dir = 0; dir < 4; dir++) { if (ejectBuffer[dir].Count > 0 && (bestdir == -1 || ejectBuffer[dir].Peek().injectionTime < ejectBuffer[bestdir].Peek().injectionTime)) { bestdir = dir; } } if (bestdir != -1) { acceptFlit(ejectBuffer[bestdir].Dequeue()); } } else { Flit eject = null; if (Config.calf_new_inj_ej) { eject = ejectLocalNew(); } else { Flit f1 = null, f2 = null; int flitsTryToEject = 0; for (int dir = 0; dir < 4; dir++) { if (linkIn[dir] != null && linkIn[dir].Out != null && linkIn[dir].Out.dest.ID == ID) { flitsTryToEject++; } } Simulator.stats.flitsTryToEject[flitsTryToEject].Add(); for (int i = 0; i < Config.meshEjectTrial; i++) { eject = ejectLocal(); if (i == 0) { f1 = eject; } else if (i == 1) { f2 = eject; } if (eject != null) { acceptFlit(eject); } } if (f1 != null && f2 != null && f1.packet == f2.packet) { Simulator.stats.ejectsFromSamePacket.Add(1); } else if (f1 != null && f2 != null) { Simulator.stats.ejectsFromSamePacket.Add(0); } } } for (int dir = 0; dir < 4; dir++) { if (linkIn[dir] != null && linkIn[dir].Out != null) { input[dir] = linkIn[dir].Out; input[dir].inDir = dir; } else { input[dir] = null; } } Flit inj = null; bool injected = false; if (m_injectSlot2 != null) { inj = m_injectSlot2; m_injectSlot2 = null; } else if (m_injectSlot != null) { inj = m_injectSlot; m_injectSlot = null; } input[4] = inj; if (inj != null) { inj.inDir = -1; } for (int i = 0; i < 5; i++) { if (input[i] != null) { PreferredDirection pd = determineDirection(input[i]); if (pd.xDir != Simulator.DIR_NONE) { input[i].prefDir = pd.xDir; } else { input[i].prefDir = pd.yDir; } } } m_sort.route(input, out injected); //Console.WriteLine("---"); for (int i = 0; i < 4; i++) { if (input[i] != null) { //Console.WriteLine("input dir {0} pref dir {1} output dir {2} age {3}", // input[i].inDir, input[i].prefDir, i, Router_Flit_OldestFirst.age(input[i])); input[i].Deflected = input[i].prefDir != i; } } if (Config.calf_new_inj_ej) { if (inj != null && input[inj.prefDir] == null) { input[inj.prefDir] = inj; injected = true; } } if (!injected) { if (m_injectSlot == null) { m_injectSlot = inj; } else { m_injectSlot2 = inj; } } else { statsInjectFlit(inj); } for (int dir = 0; dir < 4; dir++) { if (input[dir] != null) { if (linkOut[dir] == null) { throw new Exception(String.Format("router {0} does not have link in dir {1}", coord, dir)); } linkOut[dir].In = input[dir]; } } }