bridge.hh (2640:266b80dd5eca) | bridge.hh (2643:67ac7b611c56) |
---|---|
1/* 2 * Copyright (c) 2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 32 unchanged lines hidden (view full) --- 41 42#include "mem/mem_object.hh" 43#include "mem/packet.hh" 44#include "mem/port.hh" 45#include "sim/eventq.hh" 46 47class Bridge : public MemObject 48{ | 1/* 2 * Copyright (c) 2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 32 unchanged lines hidden (view full) --- 41 42#include "mem/mem_object.hh" 43#include "mem/packet.hh" 44#include "mem/port.hh" 45#include "sim/eventq.hh" 46 47class Bridge : public MemObject 48{ |
49 public: 50 enum Side | 49 protected: 50 /** Decleration of the buses port type, one will be instantiated for each 51 of the interfaces connecting to the bus. */ 52 class BridgePort : public Port |
51 { | 53 { |
52 SideA, 53 SideB 54 }; | 54 /** A pointer to the bridge to which this port belongs. */ 55 Bridge *bridge; |
55 | 56 |
56 protected: 57 /** Function called by the port when the bus is recieving a Timing 58 transaction.*/ 59 bool recvTiming(Packet *pkt, Side id); | 57 /** 58 * Pointer to the port on the other side of the bridge 59 * (connected to the other bus). 60 */ 61 BridgePort *otherPort; |
60 | 62 |
61 /** Function called by the port when the bus is recieving a Atomic 62 transaction.*/ 63 Tick recvAtomic(Packet *pkt, Side id); | 63 /** Minimum delay though this bridge. */ 64 Tick delay; |
64 | 65 |
65 /** Function called by the port when the bus is recieving a Functional 66 transaction.*/ 67 void recvFunctional(Packet *pkt, Side id); | 66 class PacketBuffer : public Packet::SenderState { |
68 | 67 |
69 /** Function called by the port when the bus is recieving a status change.*/ 70 void recvStatusChange(Port::Status status, Side id); | 68 public: 69 Tick ready; 70 Packet *pkt; 71 Packet::SenderState *origSenderState; 72 short origSrc; 73 bool expectResponse; |
71 | 74 |
72 /** Process address range request. 73 * @param resp addresses that we can respond to 74 * @param snoop addresses that we would like to snoop 75 * @param id ide of the busport that made the request. 76 */ 77 void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id); | 75 PacketBuffer(Packet *_pkt, Tick t) 76 : ready(t), pkt(_pkt), 77 origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), 78 expectResponse(_pkt->needsResponse()) 79 { 80 pkt->senderState = this; 81 } |
78 | 82 |
83 void fixResponse(Packet *pkt) 84 { 85 assert(pkt->senderState == this); 86 pkt->setDest(origSrc); 87 pkt->senderState = origSenderState; 88 } 89 }; |
|
79 | 90 |
80 /** Event that the SendEvent calls when it fires. This code must reschedule 81 * the send event as required. */ 82 void timerEvent(); | 91 /** 92 * Outbound packet queue. Packets are held in this queue for a 93 * specified delay to model the processing delay of the 94 * bridge. 95 */ 96 std::list<PacketBuffer*> sendQueue; |
83 | 97 |
84 /** Decleration of the buses port type, one will be instantiated for each 85 of the interfaces connecting to the bus. */ 86 class BridgePort : public Port 87 { 88 /** A pointer to the bus to which this port belongs. */ 89 Bridge *bridge; | 98 int outstandingResponses; |
90 | 99 |
91 /** A id to keep track of the intercafe ID this port is connected to. */ 92 Bridge::Side side; | 100 /** Max queue size for outbound packets */ 101 int queueLimit; |
93 | 102 |
103 /** 104 * Is this side blocked from accepting outbound packets? 105 */ 106 bool queueFull() { return (sendQueue.size() == queueLimit); } 107 108 bool queueForSendTiming(Packet *pkt); 109 110 void finishSend(PacketBuffer *buf); 111 112 /** 113 * Handle send event, scheduled when the packet at the head of 114 * the outbound queue is ready to transmit (for timing 115 * accesses only). 116 */ 117 void trySend(); 118 119 class SendEvent : public Event 120 { 121 BridgePort *port; 122 123 public: 124 SendEvent(BridgePort *p) 125 : Event(&mainEventQueue), port(p) {} 126 127 virtual void process() { port->trySend(); } 128 129 virtual const char *description() { return "bridge send event"; } 130 }; 131 132 SendEvent sendEvent; 133 |
|
94 public: 95 96 /** Constructor for the BusPort.*/ | 134 public: 135 136 /** Constructor for the BusPort.*/ |
97 BridgePort(Bridge *_bridge, Side _side) 98 : Port(""), bridge(_bridge), side(_side) 99 { } | 137 BridgePort(const std::string &_name, 138 Bridge *_bridge, BridgePort *_otherPort, 139 int _delay, int _queueLimit); |
100 | 140 |
101 int numQueued() { return outbound.size(); } 102 | |
103 protected: | 141 protected: |
104 /** Data this is waiting to be transmitted. */ 105 std::list<std::pair<Packet*, Tick> > outbound; | |
106 | 142 |
107 void sendPkt(Packet *pkt); 108 void sendPkt(std::pair<Packet*, Tick> p); 109 110 /** When reciving a timing request from the peer port, | 143 /** When receiving a timing request from the peer port, |
111 pass it to the bridge. */ | 144 pass it to the bridge. */ |
112 virtual bool recvTiming(Packet *pkt) 113 { return bridge->recvTiming(pkt, side); } | 145 virtual bool recvTiming(Packet *pkt); |
114 | 146 |
115 /** When reciving a retry request from the peer port, | 147 /** When receiving a retry request from the peer port, |
116 pass it to the bridge. */ 117 virtual Packet* recvRetry(); 118 | 148 pass it to the bridge. */ 149 virtual Packet* recvRetry(); 150 |
119 /** When reciving a Atomic requestfrom the peer port, | 151 /** When receiving a Atomic requestfrom the peer port, |
120 pass it to the bridge. */ | 152 pass it to the bridge. */ |
121 virtual Tick recvAtomic(Packet *pkt) 122 { return bridge->recvAtomic(pkt, side); } | 153 virtual Tick recvAtomic(Packet *pkt); |
123 | 154 |
124 /** When reciving a Functional request from the peer port, | 155 /** When receiving a Functional request from the peer port, |
125 pass it to the bridge. */ | 156 pass it to the bridge. */ |
126 virtual void recvFunctional(Packet *pkt) 127 { bridge->recvFunctional(pkt, side); } | 157 virtual void recvFunctional(Packet *pkt); |
128 | 158 |
129 /** When reciving a status changefrom the peer port, | 159 /** When receiving a status changefrom the peer port, |
130 pass it to the bridge. */ | 160 pass it to the bridge. */ |
131 virtual void recvStatusChange(Status status) 132 { bridge->recvStatusChange(status, side); } | 161 virtual void recvStatusChange(Status status); |
133 | 162 |
134 /** When reciving a address range request the peer port, | 163 /** When receiving a address range request the peer port, |
135 pass it to the bridge. */ | 164 pass it to the bridge. */ |
136 virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) 137 { bridge->addressRanges(resp, snoop, side); } 138 139 friend class Bridge; | 165 virtual void getDeviceAddressRanges(AddrRangeList &resp, 166 AddrRangeList &snoop); |
140 }; 141 | 167 }; 168 |
142 class SendEvent : public Event 143 { 144 Bridge *bridge; | 169 BridgePort portA, portB; |
145 | 170 |
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. */ | 171 /** If this bridge should acknowledge writes. */ 172 bool ackWrites; 173 174 public: 175 176 /** 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 } | 177 virtual Port *getPort(const std::string &if_name); |
197 198 virtual void init(); 199 | 178 179 virtual void init(); 180 |
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 | 181 Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack); |
212}; 213 214#endif //__MEM_BUS_HH__ | 182}; 183 184#endif //__MEM_BUS_HH__ |