bridge.hh revision 2632:1bb2f91485ea
112855Sgabeblack@google.com/* 212855Sgabeblack@google.com * Copyright (c) 2006 The Regents of The University of Michigan 312855Sgabeblack@google.com * All rights reserved. 412855Sgabeblack@google.com * 512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412855Sgabeblack@google.com * this software without specific prior written permission. 1512855Sgabeblack@google.com * 1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712855Sgabeblack@google.com */ 2812855Sgabeblack@google.com 2912855Sgabeblack@google.com/** 3012855Sgabeblack@google.com * @file Decleration of a simple bus bridge object with no buffering 3112855Sgabeblack@google.com */ 3212855Sgabeblack@google.com 3312855Sgabeblack@google.com#ifndef __MEM_BRIDGE_HH__ 3412855Sgabeblack@google.com#define __MEM_BRIDGE_HH__ 3512855Sgabeblack@google.com 3612855Sgabeblack@google.com#include <string> 3712855Sgabeblack@google.com#include <list> 3812855Sgabeblack@google.com#include <inttypes.h> 3912855Sgabeblack@google.com#include <queue> 4012855Sgabeblack@google.com 4112855Sgabeblack@google.com 4212855Sgabeblack@google.com#include "mem/mem_object.hh" 4312855Sgabeblack@google.com#include "mem/packet.hh" 4412855Sgabeblack@google.com#include "mem/port.hh" 4512855Sgabeblack@google.com#include "sim/eventq.hh" 4612855Sgabeblack@google.com 4712855Sgabeblack@google.comclass Bridge : public MemObject 4812855Sgabeblack@google.com{ 4912855Sgabeblack@google.com public: 5012855Sgabeblack@google.com enum Side 5112855Sgabeblack@google.com { 5212855Sgabeblack@google.com SideA, 5312855Sgabeblack@google.com SideB 5412855Sgabeblack@google.com }; 5512855Sgabeblack@google.com 5612855Sgabeblack@google.com protected: 5712855Sgabeblack@google.com /** Function called by the port when the bus is recieving a Timing 5812855Sgabeblack@google.com transaction.*/ 5912855Sgabeblack@google.com bool recvTiming(Packet *pkt, Side id); 6012855Sgabeblack@google.com 6112855Sgabeblack@google.com /** Function called by the port when the bus is recieving a Atomic 6212855Sgabeblack@google.com transaction.*/ 6312855Sgabeblack@google.com Tick recvAtomic(Packet *pkt, Side id); 6412855Sgabeblack@google.com 6512855Sgabeblack@google.com /** Function called by the port when the bus is recieving a Functional 6612855Sgabeblack@google.com transaction.*/ 6712855Sgabeblack@google.com void recvFunctional(Packet *pkt, Side id); 6812855Sgabeblack@google.com 6912855Sgabeblack@google.com /** Function called by the port when the bus is recieving a status change.*/ 7012855Sgabeblack@google.com void recvStatusChange(Port::Status status, Side id); 7112855Sgabeblack@google.com 7212855Sgabeblack@google.com /** Process address range request. 7312855Sgabeblack@google.com * @param resp addresses that we can respond to 7412855Sgabeblack@google.com * @param snoop addresses that we would like to snoop 7512855Sgabeblack@google.com * @param id ide of the busport that made the request. 7612855Sgabeblack@google.com */ 7712855Sgabeblack@google.com void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id); 7812855Sgabeblack@google.com 7912855Sgabeblack@google.com 8012855Sgabeblack@google.com /** Event that the SendEvent calls when it fires. This code must reschedule 8112855Sgabeblack@google.com * the send event as required. */ 8212855Sgabeblack@google.com void timerEvent(); 8312855Sgabeblack@google.com 8412855Sgabeblack@google.com /** Decleration of the buses port type, one will be instantiated for each 8512855Sgabeblack@google.com of the interfaces connecting to the bus. */ 8612855Sgabeblack@google.com class BridgePort : public Port 8712855Sgabeblack@google.com { 88 /** A pointer to the bus to which this port belongs. */ 89 Bridge *bridge; 90 91 /** A id to keep track of the intercafe ID this port is connected to. */ 92 Bridge::Side side; 93 94 public: 95 96 /** Constructor for the BusPort.*/ 97 BridgePort(Bridge *_bridge, Side _side) 98 : bridge(_bridge), side(_side) 99 { } 100 101 int numQueued() { return outbound.size(); } 102 103 protected: 104 /** Data this is waiting to be transmitted. */ 105 std::list<std::pair<Packet*, Tick> > outbound; 106 107 void sendPkt(Packet *pkt); 108 void sendPkt(std::pair<Packet*, Tick> p); 109 110 /** When reciving a timing request from the peer port, 111 pass it to the bridge. */ 112 virtual bool recvTiming(Packet *pkt) 113 { return bridge->recvTiming(pkt, side); } 114 115 /** When reciving a retry request from the peer port, 116 pass it to the bridge. */ 117 virtual Packet* recvRetry(); 118 119 /** When reciving a Atomic requestfrom the peer port, 120 pass it to the bridge. */ 121 virtual Tick recvAtomic(Packet *pkt) 122 { return bridge->recvAtomic(pkt, side); } 123 124 /** When reciving a Functional request from the peer port, 125 pass it to the bridge. */ 126 virtual void recvFunctional(Packet *pkt) 127 { bridge->recvFunctional(pkt, side); } 128 129 /** When reciving a status changefrom the peer port, 130 pass it to the bridge. */ 131 virtual void recvStatusChange(Status status) 132 { bridge->recvStatusChange(status, side); } 133 134 /** When reciving a address range request the peer port, 135 pass it to the bridge. */ 136 virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) 137 { bridge->addressRanges(resp, snoop, side); } 138 139 friend class Bridge; 140 }; 141 142 class SendEvent : public Event 143 { 144 Bridge *bridge; 145 146 SendEvent(Bridge *b) 147 : Event(&mainEventQueue), bridge(b) {} 148 149 virtual void process() { bridge->timerEvent(); } 150 151 virtual const char *description() { return "bridge delay event"; } 152 friend class Bridge; 153 }; 154 155 SendEvent sendEvent; 156 157 /** Sides of the bus bridges. */ 158 BridgePort* sideA; 159 BridgePort* sideB; 160 161 /** inbound queues on both sides. */ 162 std::list<std::pair<Packet*, Tick> > inboundA; 163 std::list<std::pair<Packet*, Tick> > inboundB; 164 165 /** The size of the queue for data coming into side a */ 166 int queueSizeA; 167 int queueSizeB; 168 169 /* if the side is blocked or not. */ 170 bool blockedA; 171 bool blockedB; 172 173 /** Miminum delay though this bridge. */ 174 Tick delay; 175 176 /** If this bridge should acknowledge writes. */ 177 bool ackWrites; 178 179 public: 180 181 /** A function used to return the port associated with this bus object. */ 182 virtual Port *getPort(const std::string &if_name) 183 { 184 if (if_name == "side_a") { 185 if (sideA != NULL) 186 panic("bridge side a already connected to."); 187 sideA = new BridgePort(this, SideA); 188 return sideA; 189 } else if (if_name == "side_b") { 190 if (sideB != NULL) 191 panic("bridge side b already connected to."); 192 sideB = new BridgePort(this, SideB); 193 return sideB; 194 } else 195 return NULL; 196 } 197 198 virtual void init(); 199 200 Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack) 201 : MemObject(n), sendEvent(this), sideA(NULL), sideB(NULL), 202 queueSizeA(qsa), queueSizeB(qsb), blockedA(false), blockedB(false), 203 delay(_delay), ackWrites(write_ack) 204 {} 205 206 /** Check if the port should block/unblock after recieving/sending a packet. 207 * */ 208 void blockCheck(Side id); 209 210 friend class Bridge::SendEvent; 211 212}; 213 214#endif //__MEM_BUS_HH__ 215