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