xbar.cc (10713:eddb533708cb) | xbar.cc (10719:b4fc9ad648aa) |
---|---|
1/* 2 * Copyright (c) 2011-2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 42 unchanged lines hidden (view full) --- 51#include "base/trace.hh" 52#include "debug/AddrRanges.hh" 53#include "debug/Drain.hh" 54#include "debug/XBar.hh" 55#include "mem/xbar.hh" 56 57BaseXBar::BaseXBar(const BaseXBarParams *p) 58 : MemObject(p), | 1/* 2 * Copyright (c) 2011-2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 42 unchanged lines hidden (view full) --- 51#include "base/trace.hh" 52#include "debug/AddrRanges.hh" 53#include "debug/Drain.hh" 54#include "debug/XBar.hh" 55#include "mem/xbar.hh" 56 57BaseXBar::BaseXBar(const BaseXBarParams *p) 58 : MemObject(p), |
59 headerCycles(p->header_cycles), width(p->width), | 59 frontendLatency(p->frontend_latency), 60 forwardLatency(p->forward_latency), 61 responseLatency(p->response_latency), 62 width(p->width), |
60 gotAddrRanges(p->port_default_connection_count + 61 p->port_master_connection_count, false), 62 gotAllAddrRanges(false), defaultPortID(InvalidPortID), 63 useDefaultRange(p->use_default_range) 64{} 65 66BaseXBar::~BaseXBar() 67{ --- 29 unchanged lines hidden (view full) --- 97 // the slave port index translates directly to the vector position 98 return *slavePorts[idx]; 99 } else { 100 return MemObject::getSlavePort(if_name, idx); 101 } 102} 103 104void | 63 gotAddrRanges(p->port_default_connection_count + 64 p->port_master_connection_count, false), 65 gotAllAddrRanges(false), defaultPortID(InvalidPortID), 66 useDefaultRange(p->use_default_range) 67{} 68 69BaseXBar::~BaseXBar() 70{ --- 29 unchanged lines hidden (view full) --- 100 // the slave port index translates directly to the vector position 101 return *slavePorts[idx]; 102 } else { 103 return MemObject::getSlavePort(if_name, idx); 104 } 105} 106 107void |
105BaseXBar::calcPacketTiming(PacketPtr pkt) | 108BaseXBar::calcPacketTiming(PacketPtr pkt, Tick header_delay) |
106{ 107 // the crossbar will be called at a time that is not necessarily 108 // coinciding with its own clock, so start by determining how long 109 // until the next clock edge (could be zero) 110 Tick offset = clockEdge() - curTick(); 111 | 109{ 110 // the crossbar will be called at a time that is not necessarily 111 // coinciding with its own clock, so start by determining how long 112 // until the next clock edge (could be zero) 113 Tick offset = clockEdge() - curTick(); 114 |
112 // Determine how many cycles are needed to send the data 113 // If the packet has no data we take into account just the cycle to send 114 // the header. 115 unsigned dataCycles = pkt->hasData() ? divCeil(pkt->getSize(), width) : 0; | 115 // the header delay depends on the path through the crossbar, and 116 // we therefore rely on the caller to provide the actual 117 // value 118 pkt->headerDelay += offset + header_delay; |
116 | 119 |
117 // before setting the bus delay fields of the packet, ensure that 118 // the delay from any previous crossbar has been accounted for 119 if (pkt->headerDelay != 0 || pkt->payloadDelay != 0) 120 panic("Packet %s already has delay (%d, %d) that should be " 121 "accounted for.\n", pkt->cmdString(), pkt->headerDelay, 122 pkt->payloadDelay); | 120 // note that we add the header delay to the existing value, and 121 // align it to the crossbar clock |
123 | 122 |
124 // The headerDelay takes into account the relative time to deliver the 125 // header of the packet. It will be charged of the additional delay of 126 // the xbar if the packet goes through it. 127 pkt->headerDelay = (headerCycles + 1) * clockPeriod() + offset; | 123 // do a quick sanity check to ensure the timings are not being 124 // ignored, note that this specific value may cause problems for 125 // slower interconnects 126 panic_if(pkt->headerDelay > SimClock::Int::us, 127 "Encountered header delay exceeding 1 us\n"); |
128 | 128 |
129 // The payloadDelay takes into account the relative time to deliver the 130 // payload of the packet. If the packet has no data its value is just one 131 // tick (due to header) plus the offset value. 132 pkt->payloadDelay = (headerCycles + dataCycles) * clockPeriod() + offset; | 129 if (pkt->hasData()) { 130 // the payloadDelay takes into account the relative time to 131 // deliver the payload of the packet, after the header delay, 132 // we take the maximum since the payload delay could already 133 // be longer than what this parcitular crossbar enforces. 134 pkt->payloadDelay = std::max<Tick>(pkt->payloadDelay, 135 divCeil(pkt->getSize(), width) * 136 clockPeriod()); 137 } 138 139 // the payload delay is not paying for the clock offset as that is 140 // already done using the header delay, and the payload delay is 141 // also used to determine how long the crossbar layer is busy and 142 // thus regulates throughput |
133} 134 135template <typename SrcType, typename DstType> 136BaseXBar::Layer<SrcType,DstType>::Layer(DstType& _port, BaseXBar& _xbar, 137 const std::string& _name) : 138 port(_port), xbar(_xbar), _name(_name), state(IDLE), drainManager(NULL), 139 waitingForPeer(NULL), releaseEvent(this) 140{ --- 128 unchanged lines hidden (view full) --- 269 SrcType* retryingPort = waitingForLayer.front(); 270 waitingForLayer.pop_front(); 271 272 // tell the port to retry, which in some cases ends up calling the 273 // layer again 274 sendRetry(retryingPort); 275 276 // If the layer is still in the retry state, sendTiming wasn't | 143} 144 145template <typename SrcType, typename DstType> 146BaseXBar::Layer<SrcType,DstType>::Layer(DstType& _port, BaseXBar& _xbar, 147 const std::string& _name) : 148 port(_port), xbar(_xbar), _name(_name), state(IDLE), drainManager(NULL), 149 waitingForPeer(NULL), releaseEvent(this) 150{ --- 128 unchanged lines hidden (view full) --- 279 SrcType* retryingPort = waitingForLayer.front(); 280 waitingForLayer.pop_front(); 281 282 // tell the port to retry, which in some cases ends up calling the 283 // layer again 284 sendRetry(retryingPort); 285 286 // If the layer is still in the retry state, sendTiming wasn't |
277 // called in zero time (e.g. the cache does this), burn a cycle | 287 // called in zero time (e.g. the cache does this when a writeback 288 // is squashed) |
278 if (state == RETRY) { 279 // update the state to busy and reset the retrying port, we 280 // have done our bit and sent the retry 281 state = BUSY; 282 | 289 if (state == RETRY) { 290 // update the state to busy and reset the retrying port, we 291 // have done our bit and sent the retry 292 state = BUSY; 293 |
283 // occupy the crossbar layer until the next cycle ends 284 occupyLayer(xbar.clockEdge(Cycles(1))); | 294 // occupy the crossbar layer until the next clock edge 295 occupyLayer(xbar.clockEdge()); |
285 } 286} 287 288template <typename SrcType, typename DstType> 289void 290BaseXBar::Layer<SrcType,DstType>::recvRetry() 291{ 292 // we should never get a retry without having failed to forward --- 327 unchanged lines hidden --- | 296 } 297} 298 299template <typename SrcType, typename DstType> 300void 301BaseXBar::Layer<SrcType,DstType>::recvRetry() 302{ 303 // we should never get a retry without having failed to forward --- 327 unchanged lines hidden --- |