bridge.hh revision 2632:1bb2f91485ea
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;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @file Decleration of a simple bus bridge object with no buffering
31 */
32
33#ifndef __MEM_BRIDGE_HH__
34#define __MEM_BRIDGE_HH__
35
36#include <string>
37#include <list>
38#include <inttypes.h>
39#include <queue>
40
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
51    {
52        SideA,
53        SideB
54    };
55
56  protected:
57    /** Function called by the port when the bus is recieving a Timing
58        transaction.*/
59    bool recvTiming(Packet *pkt, Side id);
60
61    /** Function called by the port when the bus is recieving a Atomic
62        transaction.*/
63    Tick recvAtomic(Packet *pkt, Side id);
64
65    /** Function called by the port when the bus is recieving a Functional
66        transaction.*/
67    void recvFunctional(Packet *pkt, Side id);
68
69    /** Function called by the port when the bus is recieving a status change.*/
70    void recvStatusChange(Port::Status status, Side id);
71
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);
78
79
80    /** Event that the SendEvent calls when it fires. This code must reschedule
81     * the send event as required. */
82    void timerEvent();
83
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;
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