diff options
Diffstat (limited to 'mem/bridge.cc')
-rw-r--r-- | mem/bridge.cc | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/mem/bridge.cc b/mem/bridge.cc deleted file mode 100644 index c4b137869..000000000 --- a/mem/bridge.cc +++ /dev/null @@ -1,263 +0,0 @@ - -/* - * Copyright (c) 2006 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file Definition of a simple bus bridge without buffering. - */ - - -#include "base/trace.hh" -#include "mem/bridge.hh" -#include "sim/builder.hh" - -void -Bridge::init() -{ - // Make sure that both sides are connected to. - if (sideA == NULL || sideB == NULL) - panic("Both ports of bus bridge are not connected to a bus.\n"); -} - - -/** Function called by the port when the bus is recieving a Timing - * transaction.*/ -bool -Bridge::recvTiming(Packet *pkt, Side id) -{ - if (blockedA && id == SideA) - return false; - if (blockedB && id == SideB) - return false; - - if (delay) { - if (!sendEvent.scheduled()) - sendEvent.schedule(curTick + delay); - if (id == SideA) { - inboundA.push_back(std::make_pair<Packet*, Tick>(pkt, curTick)); - blockCheck(SideA); - } else { - inboundB.push_back(std::make_pair<Packet*, Tick>(pkt, curTick)); - blockCheck(SideB); - } - } else { - if (id == SideB) { - sideA->sendPkt(pkt); - blockCheck(SideB); - } else { - sideB->sendPkt(pkt); - blockCheck(SideA); - } - } - return true; - -} - -void -Bridge::blockCheck(Side id) -{ - /* Check that we still have buffer space available. */ - if (id == SideB) { - if (sideA->numQueued() + inboundB.size() >= queueSizeA && !blockedB) { - sideB->sendStatusChange(Port::Blocked); - blockedB = true; - } else if (sideA->numQueued() + inboundB.size() < queueSizeA && blockedB) { - sideB->sendStatusChange(Port::Unblocked); - blockedB = false; - } - } else { - if (sideB->numQueued() + inboundA.size() >= queueSizeB && !blockedA) { - sideA->sendStatusChange(Port::Blocked); - blockedA = true; - } else if (sideB->numQueued() + inboundA.size() < queueSizeB && blockedA) { - sideA->sendStatusChange(Port::Unblocked); - blockedA = false; - } - } -} - -void Bridge::timerEvent() -{ - Tick t = 0; - - assert(inboundA.size() || inboundB.size()); - if (inboundA.size()) { - while (inboundA.front().second <= curTick + delay){ - sideB->sendPkt(inboundA.front()); - inboundA.pop_front(); - } - if (inboundA.size()) - t = inboundA.front().second + delay; - } - if (inboundB.size()) { - while (inboundB.front().second <= curTick + delay){ - sideB->sendPkt(inboundA.front()); - inboundB.pop_front(); - } - if (inboundB.size()) - if (t == 0) - t = inboundB.front().second + delay; - else - t = std::min(t,inboundB.front().second + delay); - } else { - panic("timerEvent() called but nothing to do?"); - } - - if (t != 0) - sendEvent.schedule(t); -} - - -void -Bridge::BridgePort::sendPkt(Packet *pkt) -{ - if (!sendTiming(pkt)) - outbound.push_back(std::make_pair<Packet*,Tick>(pkt, curTick)); -} - -void -Bridge::BridgePort::sendPkt(std::pair<Packet*, Tick> p) -{ - if (!sendTiming(p.first)) - outbound.push_back(p); -} - - -Packet * -Bridge::BridgePort::recvRetry() -{ - Packet *pkt; - assert(outbound.size() > 0); - assert(outbound.front().second >= curTick + bridge->delay); - pkt = outbound.front().first; - outbound.pop_front(); - bridge->blockCheck(side); - return pkt; -} - -/** Function called by the port when the bus is recieving a Atomic - * transaction.*/ -Tick -Bridge::recvAtomic(Packet *pkt, Side id) -{ - pkt->time += delay; - - if (id == SideA) - return sideB->sendAtomic(pkt); - else - return sideA->sendAtomic(pkt); -} - -/** Function called by the port when the bus is recieving a Functional - * transaction.*/ -void -Bridge::recvFunctional(Packet *pkt, Side id) -{ - pkt->time += delay; - std::list<std::pair<Packet*, Tick> >::iterator i; - bool pktContinue = true; - - for(i = inboundA.begin(); i != inboundA.end(); ++i) { - if (pkt->intersect(i->first)) { - pktContinue &= fixPacket(pkt, i->first); - } - } - - for(i = inboundB.begin(); i != inboundB.end(); ++i) { - if (pkt->intersect(i->first)) { - pktContinue &= fixPacket(pkt, i->first); - } - } - - for(i = sideA->outbound.begin(); i != sideA->outbound.end(); ++i) { - if (pkt->intersect(i->first)) { - pktContinue &= fixPacket(pkt, i->first); - } - } - - for(i = sideB->outbound.begin(); i != sideB->outbound.end(); ++i) { - if (pkt->intersect(i->first)) { - pktContinue &= fixPacket(pkt, i->first); - } - } - - if (pktContinue) { - if (id == SideA) - sideB->sendFunctional(pkt); - else - sideA->sendFunctional(pkt); - } -} - -/** Function called by the port when the bus is recieving a status change.*/ -void -Bridge::recvStatusChange(Port::Status status, Side id) -{ - if (status == Port::Blocked || status == Port::Unblocked) - return ; - - if (id == SideA) - sideB->sendStatusChange(status); - else - sideA->sendStatusChange(status); -} - -void -Bridge::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id) -{ - if (id == SideA) - sideB->getPeerAddressRanges(resp, snoop); - else - sideA->getPeerAddressRanges(resp, snoop); -} - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge) - - Param<int> queue_size_a; - Param<int> queue_size_b; - Param<Tick> delay; - Param<bool> write_ack; - -END_DECLARE_SIM_OBJECT_PARAMS(Bridge) - -BEGIN_INIT_SIM_OBJECT_PARAMS(Bridge) - - INIT_PARAM(queue_size_a, "The size of the queue for data coming into side a"), - INIT_PARAM(queue_size_b, "The size of the queue for data coming into side b"), - INIT_PARAM(delay, "The miminum delay to cross this bridge"), - INIT_PARAM(write_ack, "Acknowledge any writes that are received.") - -END_INIT_SIM_OBJECT_PARAMS(Bridge) - -CREATE_SIM_OBJECT(Bridge) -{ - return new Bridge(getInstanceName(), queue_size_a, queue_size_b, delay, - write_ack); -} - -REGISTER_SIM_OBJECT("Bridge", Bridge) |