diff options
author | Jason Lowe-Power <jason@lowepower.com> | 2017-10-06 14:43:09 -0700 |
---|---|---|
committer | Jason Lowe-Power <jason@lowepower.com> | 2017-12-05 02:09:25 +0000 |
commit | 46ec9df617df23d6bb00f6337e61e6d85038ec7e (patch) | |
tree | f38e06526221ce084873052a63abd468cbe335da /src/learning_gem5/part2/simple_memobj.hh | |
parent | 25daea0e6fd12b8ce3c282b49b3fd334d1871975 (diff) | |
download | gem5-46ec9df617df23d6bb00f6337e61e6d85038ec7e.tar.xz |
learning_gem5: Adds the simple MemObject code
Adding more code from Learning gem5 Part II
See http://learning.gem5.org/book/part2/memoryobject.html
Change-Id: Iaa9480c5cdbe4090364f02e81dc1d0a0ddac392a
Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-on: https://gem5-review.googlesource.com/5022
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Diffstat (limited to 'src/learning_gem5/part2/simple_memobj.hh')
-rw-r--r-- | src/learning_gem5/part2/simple_memobj.hh | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/learning_gem5/part2/simple_memobj.hh b/src/learning_gem5/part2/simple_memobj.hh new file mode 100644 index 000000000..a44d4336c --- /dev/null +++ b/src/learning_gem5/part2/simple_memobj.hh @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2017 Jason Lowe-Power + * 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. + * + * Authors: Jason Lowe-Power + */ + +#ifndef __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ +#define __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ + +#include "mem/mem_object.hh" +#include "params/SimpleMemobj.hh" + +/** + * A very simple memory object. Current implementation doesn't even cache + * anything it just forwards requests and responses. + * This memobj is fully blocking (not non-blocking). Only a single request can + * be outstanding at a time. + */ +class SimpleMemobj : public MemObject +{ + private: + + /** + * Port on the CPU-side that receives requests. + * Mostly just forwards requests to the owner. + * Part of a vector of ports. One for each CPU port (e.g., data, inst) + */ + class CPUSidePort : public SlavePort + { + private: + /// The object that owns this object (SimpleMemobj) + SimpleMemobj *owner; + + /// True if the port needs to send a retry req. + bool needRetry; + + /// If we tried to send a packet and it was blocked, store it here + PacketPtr blockedPacket; + + public: + /** + * Constructor. Just calls the superclass constructor. + */ + CPUSidePort(const std::string& name, SimpleMemobj *owner) : + SlavePort(name, owner), owner(owner), needRetry(false), + blockedPacket(nullptr) + { } + + /** + * Send a packet across this port. This is called by the owner and + * all of the flow control is hanled in this function. + * + * @param packet to send. + */ + void sendPacket(PacketPtr pkt); + + /** + * Get a list of the non-overlapping address ranges the owner is + * responsible for. All slave ports must override this function + * and return a populated list with at least one item. + * + * @return a list of ranges responded to + */ + AddrRangeList getAddrRanges() const override; + + /** + * Send a retry to the peer port only if it is needed. This is called + * from the SimpleMemobj whenever it is unblocked. + */ + void trySendRetry(); + + protected: + /** + * Receive an atomic request packet from the master port. + * No need to implement in this simple memobj. + */ + Tick recvAtomic(PacketPtr pkt) override + { panic("recvAtomic unimpl."); } + + /** + * Receive a functional request packet from the master port. + * Performs a "debug" access updating/reading the data in place. + * + * @param packet the requestor sent. + */ + void recvFunctional(PacketPtr pkt) override; + + /** + * Receive a timing request from the master port. + * + * @param the packet that the requestor sent + * @return whether this object can consume the packet. If false, we + * will call sendRetry() when we can try to receive this + * request again. + */ + bool recvTimingReq(PacketPtr pkt) override; + + /** + * Called by the master port if sendTimingResp was called on this + * slave port (causing recvTimingResp to be called on the master + * port) and was unsuccesful. + */ + void recvRespRetry() override; + }; + + /** + * Port on the memory-side that receives responses. + * Mostly just forwards requests to the owner + */ + class MemSidePort : public MasterPort + { + private: + /// The object that owns this object (SimpleMemobj) + SimpleMemobj *owner; + + /// If we tried to send a packet and it was blocked, store it here + PacketPtr blockedPacket; + + public: + /** + * Constructor. Just calls the superclass constructor. + */ + MemSidePort(const std::string& name, SimpleMemobj *owner) : + MasterPort(name, owner), owner(owner), blockedPacket(nullptr) + { } + + /** + * Send a packet across this port. This is called by the owner and + * all of the flow control is hanled in this function. + * + * @param packet to send. + */ + void sendPacket(PacketPtr pkt); + + protected: + /** + * Receive a timing response from the slave port. + */ + bool recvTimingResp(PacketPtr pkt) override; + + /** + * Called by the slave port if sendTimingReq was called on this + * master port (causing recvTimingReq to be called on the slave + * port) and was unsuccesful. + */ + void recvReqRetry() override; + + /** + * Called to receive an address range change from the peer slave + * port. The default implementation ignores the change and does + * nothing. Override this function in a derived class if the owner + * needs to be aware of the address ranges, e.g. in an + * interconnect component like a bus. + */ + void recvRangeChange() override; + }; + + /** + * Handle the request from the CPU side + * + * @param requesting packet + * @return true if we can handle the request this cycle, false if the + * requestor needs to retry later + */ + bool handleRequest(PacketPtr pkt); + + /** + * Handle the respone from the memory side + * + * @param responding packet + * @return true if we can handle the response this cycle, false if the + * responder needs to retry later + */ + bool handleResponse(PacketPtr pkt); + + /** + * Handle a packet functionally. Update the data on a write and get the + * data on a read. + * + * @param packet to functionally handle + */ + void handleFunctional(PacketPtr pkt); + + /** + * Return the address ranges this memobj is responsible for. Just use the + * same as the next upper level of the hierarchy. + * + * @return the address ranges this memobj is responsible for + */ + AddrRangeList getAddrRanges() const; + + /** + * Tell the CPU side to ask for our memory ranges. + */ + void sendRangeChange(); + + /// Instantiation of the CPU-side ports + CPUSidePort instPort; + CPUSidePort dataPort; + + /// Instantiation of the memory-side port + MemSidePort memPort; + + /// True if this is currently blocked waiting for a response. + bool blocked; + + public: + + /** constructor + */ + SimpleMemobj(SimpleMemobjParams *params); + + /** + * Get a master port with a given name and index. This is used at + * binding time and returns a reference to a protocol-agnostic + * base master port. + * + * @param if_name Port name + * @param idx Index in the case of a VectorPort + * + * @return A reference to the given port + */ + BaseMasterPort& getMasterPort(const std::string& if_name, + PortID idx = InvalidPortID) override; + + /** + * Get a slave port with a given name and index. This is used at + * binding time and returns a reference to a protocol-agnostic + * base master port. + * + * @param if_name Port name + * @param idx Index in the case of a VectorPort + * + * @return A reference to the given port + */ + BaseSlavePort& getSlavePort(const std::string& if_name, + PortID idx = InvalidPortID) override; +}; + + +#endif // __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ |