summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system/MemoryControl.hh
blob: 3419f8c40471005b705b3b62259a6426984ea463 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

/*
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * 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.
 */

/*
 * MemoryControl.hh
 *
 * Description:  See MemoryControl.cc
 *
 * $Id: $
 *
 */

#ifndef MEMORY_CONTROL_H
#define MEMORY_CONTROL_H

#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/system/System.hh"
#include "mem/ruby/slicc_interface/Message.hh"
#include "mem/gems_common/util.hh"
#include "mem/ruby/system/MemoryNode.hh"
// Note that "MemoryMsg" is in the "generated" directory:
#include "mem/protocol/MemoryMsg.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/system/AbstractMemOrCache.hh"

#include <list>

// This constant is part of the definition of tFAW; see
// the comments in header to MemoryControl.cc
#define ACTIVATE_PER_TFAW 4

//////////////////////////////////////////////////////////////////////////////

class Consumer;

class MemoryControl : public Consumer, public AbstractMemOrCache {
public:

  // Constructors
  MemoryControl(const string & name);
  void init(const vector<string> & argv);

  // Destructor
  ~MemoryControl ();

  // Public Methods

  void wakeup() ;

  void setConsumer (Consumer* consumer_ptr);
  Consumer* getConsumer () { return m_consumer_ptr; };
  void setDescription (const string& name) { m_description = name; };
  string getDescription () { return m_description; };

  // Called from the directory:
  void enqueue (const MsgPtr& message, int latency );
  void enqueueMemRef (MemoryNode& memRef);
  void dequeue ();
  const Message* peek ();
  MemoryNode peekNode ();
  bool isReady();
  bool areNSlotsAvailable (int n) { return true; };  // infinite queue length

  //// Called from L3 cache:
  //void writeBack(physical_address_t addr);

  void printConfig (ostream& out);
  void print (ostream& out) const;
  void setDebug (int debugFlag);


  //added by SS
  int getBanksPerRank() { return m_banks_per_rank; };
  int getRanksPerDimm() { return m_ranks_per_dimm; };
  int getDimmsPerChannel() { return m_dimms_per_channel; }

private:

  void enqueueToDirectory (MemoryNode req, int latency);
  int getBank (physical_address_t addr);
  int getRank (int bank);
  bool queueReady (int bank);
  void issueRequest (int bank);
  bool issueRefresh (int bank);
  void markTfaw (int rank);
  void executeCycle ();

  // Private copy constructor and assignment operator
  MemoryControl (const MemoryControl& obj);
  MemoryControl& operator=(const MemoryControl& obj);

  // data members
  Consumer* m_consumer_ptr;  // Consumer to signal a wakeup()
  string m_name;
  string m_description;
  int m_version;
  int m_msg_counter;
  int m_awakened;

  int m_mem_bus_cycle_multiplier;
  int m_banks_per_rank;
  int m_ranks_per_dimm;
  int m_dimms_per_channel;
  int m_bank_bit_0;
  int m_rank_bit_0;
  int m_dimm_bit_0;
  unsigned int m_bank_queue_size;
  int m_bank_busy_time;
  int m_rank_rank_delay;
  int m_read_write_delay;
  int m_basic_bus_busy_time;
  int m_mem_ctl_latency;
  int m_refresh_period;
  int m_mem_random_arbitrate;
  int m_tFaw;
  int m_mem_fixed_delay;

  int m_total_banks;
  int m_total_ranks;
  int m_refresh_period_system;

  // queues where memory requests live

  list<MemoryNode> m_response_queue;
  list<MemoryNode> m_input_queue;
  list<MemoryNode>* m_bankQueues;

  // Each entry indicates number of address-bus cycles until bank
  // is reschedulable:
  int* m_bankBusyCounter;
  int* m_oldRequest;

  uint64* m_tfaw_shift;
  int* m_tfaw_count;

  // Each of these indicates number of address-bus cycles until
  // we can issue a new request of the corresponding type:
  int m_busBusyCounter_Write;
  int m_busBusyCounter_ReadNewRank;
  int m_busBusyCounter_Basic;

  int m_busBusy_WhichRank;  // which rank last granted
  int m_roundRobin;         // which bank queue was last granted
  int m_refresh_count;      // cycles until next refresh
  int m_need_refresh;       // set whenever m_refresh_count goes to zero
  int m_refresh_bank;       // which bank to refresh next
  int m_ageCounter;         // age of old requests; to detect starvation
  int m_idleCount;          // watchdog timer for shutting down
  int m_debug;              // turn on printf's
};

#endif  // MEMORY_CONTROL_H