diff options
author | Andreas Hansson <andreas.hansson@arm.com> | 2012-09-18 10:30:02 -0400 |
---|---|---|
committer | Andreas Hansson <andreas.hansson@arm.com> | 2012-09-18 10:30:02 -0400 |
commit | 7c55464aac2bcab15699e563f18a7d3d565d949a (patch) | |
tree | bb507025ea2dc209b9d80367665ea3af682b4146 /src/mem/simple_mem.hh | |
parent | d1f3a3b91a2370c5e8fae2951a3ee6231158d4f4 (diff) | |
download | gem5-7c55464aac2bcab15699e563f18a7d3d565d949a.tar.xz |
Mem: Add a maximum bandwidth to SimpleMemory
This patch makes a minor addition to the SimpleMemory by enforcing a
maximum data rate. The bandwidth is configurable, and a reasonable
value (12.8GB/s) has been choosen as the default.
The changes do add some complexity to the SimpleMemory, but they
should definitely be justifiable as this enables a far more realistic
setup using even this simple memory controller.
The rate regulation is done for reads and writes combined to reflect
the bidirectional data busses used by most (if not all) relevant
memories. Moreover, the regulation is done per packet as opposed to
long term, as it is the short term data rate (data bus width times
frequency) that is the limiting factor.
A follow-up patch bumps the stats for the regressions.
Diffstat (limited to 'src/mem/simple_mem.hh')
-rw-r--r-- | src/mem/simple_mem.hh | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/src/mem/simple_mem.hh b/src/mem/simple_mem.hh index 95bfa57ad..4f7af864b 100644 --- a/src/mem/simple_mem.hh +++ b/src/mem/simple_mem.hh @@ -55,17 +55,22 @@ /** * The simple memory is a basic single-ported memory controller with - * an infinite throughput and a fixed latency, potentially with a - * variance added to it. It uses a SimpleTimingPort to implement the - * timing accesses. + * an configurable throughput and latency, potentially with a variance + * added to the latter. It uses a QueueSlavePort to avoid dealing with + * the flow control of sending responses. */ class SimpleMemory : public AbstractMemory { private: - class MemoryPort : public SimpleTimingPort + class MemoryPort : public QueuedSlavePort { + + private: + + /// Queue holding the response packets + SlavePacketQueue queueImpl; SimpleMemory& memory; public: @@ -74,11 +79,13 @@ class SimpleMemory : public AbstractMemory protected: - virtual Tick recvAtomic(PacketPtr pkt); + Tick recvAtomic(PacketPtr pkt); + + void recvFunctional(PacketPtr pkt); - virtual void recvFunctional(PacketPtr pkt); + bool recvTimingReq(PacketPtr pkt); - virtual AddrRangeList getAddrRanges() const; + AddrRangeList getAddrRanges() const; }; @@ -87,10 +94,32 @@ class SimpleMemory : public AbstractMemory Tick lat; Tick lat_var; + /// Bandwidth in ticks per byte + const double bandwidth; + + /** + * Track the state of the memory as either idle or busy, no need + * for an enum with only two states. + */ + bool isBusy; + + /** + * Remember if we have to retry an outstanding request that + * arrived while we were busy. + */ + bool retryReq; + + /** + * Release the memory after being busy and send a retry if a + * request was rejected in the meanwhile. + */ + void release(); + + EventWrapper<SimpleMemory, &SimpleMemory::release> releaseEvent; + public: - typedef SimpleMemoryParams Params; - SimpleMemory(const Params *p); + SimpleMemory(const SimpleMemoryParams *p); virtual ~SimpleMemory() { } unsigned int drain(Event* de); @@ -98,17 +127,12 @@ class SimpleMemory : public AbstractMemory virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1); virtual void init(); - const Params * - params() const - { - return dynamic_cast<const Params *>(_params); - } - protected: Tick doAtomicAccess(PacketPtr pkt); void doFunctionalAccess(PacketPtr pkt); - virtual Tick calculateLatency(PacketPtr pkt); + bool recvTimingReq(PacketPtr pkt); + Tick calculateLatency(PacketPtr pkt); }; |