diff -r bd4fc2b06322 -r 212f4fdb3eaa src/mem/cache/cache_impl.hh --- a/src/mem/cache/cache_impl.hh Thu Feb 19 08:02:55 2015 +0000 +++ b/src/mem/cache/cache_impl.hh Thu Feb 19 08:03:06 2015 +0000 @@ -1596,15 +1596,16 @@ // invalidate it. pkt->cmd = MemCmd::ReadRespWithInvalidate; } - DPRINTF(Cache, "%s created response: %s address %x size %d\n", - __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize()); - // Here we condiser forward_time, paying for just forward latency and + // Here we consider forward_time, paying for just forward latency and // also charging the delay provided by the xbar. // forward_time is used as send_time in next allocateWriteBuffer(). Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay; // Here we reset the timing of the packet. pkt->headerDelay = pkt->payloadDelay = 0; - memSidePort->schedTimingSnoopResp(pkt, forward_time); + DPRINTF(Cache, "%s created response: %s address %x size %d tick: %lu\n", + __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(), + forward_time); + memSidePort->schedTimingSnoopResp(pkt, forward_time, true); } template diff -r bd4fc2b06322 -r 212f4fdb3eaa src/mem/packet_queue.hh --- a/src/mem/packet_queue.hh Thu Feb 19 08:02:55 2015 +0000 +++ b/src/mem/packet_queue.hh Thu Feb 19 08:03:06 2015 +0000 @@ -180,8 +180,10 @@ * * @param pkt Packet to send * @param when Absolute time (in ticks) to send packet + * @param force_order Do not reorder packets despite timing, but keep them + * in insertion order. */ - void schedSendTiming(PacketPtr pkt, Tick when); + void schedSendTiming(PacketPtr pkt, Tick when, bool force_order = false); /** * Retry sending a packet from the queue. Note that this is not diff -r bd4fc2b06322 -r 212f4fdb3eaa src/mem/packet_queue.cc --- a/src/mem/packet_queue.cc Thu Feb 19 08:02:55 2015 +0000 +++ b/src/mem/packet_queue.cc Thu Feb 19 08:03:06 2015 +0000 @@ -100,10 +100,11 @@ } void -PacketQueue::schedSendTiming(PacketPtr pkt, Tick when) +PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order) { - DPRINTF(PacketQueue, "%s for %s address %x size %d\n", __func__, - pkt->cmdString(), pkt->getAddr(), pkt->getSize()); + DPRINTF(PacketQueue, "%s for %s address %x size %d when %lu ord: %i\n", + __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(), when, + force_order); // we can still send a packet before the end of this tick assert(when >= curTick()); @@ -118,9 +119,26 @@ name()); } + // if requested, force the timing to be in-order by changing the when + // parameter + if (force_order && !transmitList.empty()) { + Tick back = transmitList.back().tick; + + // fudge timing if required; relies on the code below to do the right + // thing (push_back) with the updated time-stamp + if (when < back) { + DPRINTF(PacketQueue, "%s force_order shifted packet %s address "\ + "%x from %lu to %lu\n", __func__, pkt->cmdString(), + pkt->getAddr(), when, back); + when = back; + } + } + // nothing on the list, or earlier than current front element, // schedule an event if (transmitList.empty() || when < transmitList.front().tick) { + // force_order-ed in here only when list is empty + assert(!force_order || transmitList.empty()); // note that currently we ignore a potentially outstanding retry // and could in theory put a new packet at the head of the // transmit list before retrying the existing packet @@ -143,6 +161,9 @@ return; } + // forced orders never need insertion in the middle + assert(!force_order); + // this belongs in the middle somewhere, insertion sort auto i = transmitList.begin(); ++i; // already checked for insertion at front diff -r bd4fc2b06322 -r 212f4fdb3eaa src/mem/qport.hh --- a/src/mem/qport.hh Thu Feb 19 08:02:55 2015 +0000 +++ b/src/mem/qport.hh Thu Feb 19 08:03:06 2015 +0000 @@ -155,8 +155,9 @@ * @param pkt Packet to send * @param when Absolute time (in ticks) to send packet */ - void schedTimingSnoopResp(PacketPtr pkt, Tick when) - { snoopRespQueue.schedSendTiming(pkt, when); } + void schedTimingSnoopResp(PacketPtr pkt, Tick when, bool force_order = + false) + { snoopRespQueue.schedSendTiming(pkt, when, force_order); } /** Check the list of buffered packets against the supplied * functional request. */