/*
- * Copyright (c) 2012-2014 ARM Limited
+ * Copyright (c) 2012-2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#include <deque>
#include <string>
+#include <unordered_set>
#include "base/statistics.hh"
#include "enums/AddrMap.hh"
class MemoryPort : public QueuedSlavePort
{
- SlavePacketQueue queue;
+ RespPacketQueue queue;
DRAMCtrl& memory;
public:
*/
MemoryPort port;
+ /**
+ * Remeber if the memory system is in timing mode
+ */
+ bool isTimingMode;
+
/**
* Remember if we have to retry a request when available.
*/
*/
void startup(Tick ref_tick);
+ /**
+ * Stop the refresh events.
+ */
+ void suspend();
+
/**
* Check if the current rank is available for scheduling.
*
* controller is switching command type.
*
* @param queue Queued requests to consider
- * @param switched_cmd_type Command type is changing
+ * @param extra_col_delay Any extra delay due to a read/write switch
* @return true if a packet is scheduled to a rank which is available else
* false
*/
- bool chooseNext(std::deque<DRAMPacket*>& queue, bool switched_cmd_type);
+ bool chooseNext(std::deque<DRAMPacket*>& queue, Tick extra_col_delay);
/**
* For FR-FCFS policy reorder the read/write queue depending on row buffer
- * hits and earliest banks available in DRAM
- * Prioritizes accesses to the same rank as previous burst unless
- * controller is switching command type.
+ * hits and earliest bursts available in DRAM
*
* @param queue Queued requests to consider
- * @param switched_cmd_type Command type is changing
+ * @param extra_col_delay Any extra delay due to a read/write switch
* @return true if a packet is scheduled to a rank which is available else
* false
*/
- bool reorderQueue(std::deque<DRAMPacket*>& queue, bool switched_cmd_type);
+ bool reorderQueue(std::deque<DRAMPacket*>& queue, Tick extra_col_delay);
/**
* Find which are the earliest banks ready to issue an activate
* Also checks if the bank is already prepped.
*
* @param queue Queued requests to consider
- * @param switched_cmd_type Command type is changing
+ * @param time of seamless burst command
* @return One-hot encoded mask of bank indices
+ * @return boolean indicating burst can issue seamlessly, with no gaps
*/
- uint64_t minBankPrep(const std::deque<DRAMPacket*>& queue,
- bool switched_cmd_type) const;
+ std::pair<uint64_t, bool> minBankPrep(const std::deque<DRAMPacket*>& queue,
+ Tick min_col_at) const;
/**
* Keep track of when row activations happen, in order to enforce
*/
void printQs() const;
+ /**
+ * Burst-align an address.
+ *
+ * @param addr The potentially unaligned address
+ *
+ * @return An address aligned to a DRAM burst
+ */
+ Addr burstAlign(Addr addr) const { return (addr & ~(Addr(burstSize - 1))); }
+
/**
* The controller's main read and write queues
*/
std::deque<DRAMPacket*> readQueue;
std::deque<DRAMPacket*> writeQueue;
+ /**
+ * To avoid iterating over the write queue to check for
+ * overlapping transactions, maintain a set of burst addresses
+ * that are currently queued. Since we merge writes to the same
+ * location we never have more than one address to the same burst
+ * address.
+ */
+ std::unordered_set<Addr> isInWriteQueue;
+
/**
* Response queue where read packets wait after we're done working
* with them, but it's not time to send the response yet. The
*/
std::deque<DRAMPacket*> respQueue;
- /**
- * If we need to drain, keep the drain manager around until we're
- * done here.
- */
- DrainManager *drainManager;
-
/**
* Vector of ranks
*/
DRAMCtrl(const DRAMCtrlParams* p);
- unsigned int drain(DrainManager* dm);
+ DrainState drain() M5_ATTR_OVERRIDE;
virtual BaseSlavePort& getSlavePort(const std::string& if_name,
PortID idx = InvalidPortID);
- virtual void init();
- virtual void startup();
+ virtual void init() M5_ATTR_OVERRIDE;
+ virtual void startup() M5_ATTR_OVERRIDE;
+ virtual void drainResume() M5_ATTR_OVERRIDE;
protected: