gem5  v22.1.0.0
AbstractController.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017,2019-2022 ARM Limited
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2009-2014 Mark D. Hill and David A. Wood
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
42 #define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
43 
44 #include <exception>
45 #include <iostream>
46 #include <string>
47 #include <unordered_map>
48 
49 #include "base/addr_range.hh"
50 #include "base/addr_range_map.hh"
51 #include "base/callback.hh"
52 #include "mem/packet.hh"
53 #include "mem/qport.hh"
60 #include "mem/ruby/protocol/AccessPermission.hh"
62 #include "params/RubyController.hh"
63 #include "sim/clocked_object.hh"
64 
65 namespace gem5
66 {
67 
68 namespace ruby
69 {
70 
71 class Network;
72 class GPUCoalescer;
73 class DMASequencer;
74 
75 // used to communicate that an in_port peeked the wrong message type
76 class RejectException: public std::exception
77 {
78  virtual const char* what() const throw()
79  { return "Port rejected message based on type"; }
80 };
81 
83 {
84  public:
85  PARAMS(RubyController);
86  AbstractController(const Params &p);
87  void init();
88 
89  NodeID getVersion() const { return m_machineID.getNum(); }
90  MachineType getType() const { return m_machineID.getType(); }
91 
92  void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; }
93 
94  // return instance name
96  bool isBlocked(Addr) const;
97  void unblock(Addr);
98  bool isBlocked(Addr);
99 
100  virtual MessageBuffer* getMandatoryQueue() const = 0;
101  virtual MessageBuffer* getMemReqQueue() const = 0;
102  virtual MessageBuffer* getMemRespQueue() const = 0;
103  virtual AccessPermission getAccessPermission(const Addr &addr) = 0;
104 
105  virtual void print(std::ostream & out) const = 0;
106  virtual void wakeup() = 0;
107  virtual void resetStats() = 0;
108  virtual void regStats();
109 
110  virtual void recordCacheTrace(int cntrl, CacheRecorder* tr) = 0;
111  virtual Sequencer* getCPUSequencer() const = 0;
112  virtual DMASequencer* getDMASequencer() const = 0;
113  virtual GPUCoalescer* getGPUCoalescer() const = 0;
114 
115  // This latency is used by the sequencer when enqueueing requests.
116  // Different latencies may be used depending on the request type.
117  // This is the hit latency unless the top-level cache controller
118  // introduces additional cycles in the response path.
119  virtual Cycles mandatoryQueueLatency(const RubyRequestType& param_type)
120  { return m_mandatory_queue_latency; }
121 
124  virtual bool functionalReadBuffers(PacketPtr&) = 0;
125  virtual void functionalRead(const Addr &addr, PacketPtr)
126  { panic("functionalRead(Addr,PacketPtr) not implemented"); }
127 
131  virtual void functionalRead(const Addr &addr, PacketPtr pkt,
132  WriteMask &mask)
133  { panic("functionalRead(Addr,PacketPtr,WriteMask) not implemented"); }
134 
139  virtual int functionalWrite(const Addr &addr, PacketPtr) = 0;
141 
143  virtual void enqueuePrefetch(const Addr &, const RubyRequestType&)
144  { fatal("Prefetches not implemented!");}
145 
148  virtual void notifyCoalesced(const Addr& addr,
149  const RubyRequestType& type,
150  const RequestPtr& req,
151  const DataBlock& data_blk,
152  const bool& was_miss)
153  { }
154 
158  virtual void collateStats()
159  {fatal("collateStats() should be overridden!");}
160 
162  virtual void initNetQueues() = 0;
163 
165  Port &getPort(const std::string &if_name,
166  PortID idx=InvalidPortID);
167 
168  void recvTimingResp(PacketPtr pkt);
170 
171  const AddrRangeList &getAddrRanges() const { return addrRanges; }
172 
173  public:
174  MachineID getMachineID() const { return m_machineID; }
175  RequestorID getRequestorId() const { return m_id; }
176 
179  { return *(stats.delayVCHistogram[index]); }
180 
182  {
183  for (auto &range: addrRanges)
184  if (range.contains(addr)) return true;
185  return false;
186  }
187 
201  MachineID mapAddressToMachine(Addr addr, MachineType mtype) const;
202 
215  MachineType mtype = MachineType_NUM) const;
216 
219 
221  const NetDest& allUpstreamDest() const { return upstreamDestinations; }
222 
223  protected:
225  void profileRequest(const std::string &request);
227  void profileMsgDelay(uint32_t virtualNetwork, Cycles delay);
228 
229  // Tracks outstanding transactions for latency profiling
230  struct TransMapPair { unsigned transaction; unsigned state; Tick time; };
231  std::unordered_map<Addr, TransMapPair> m_inTransAddressed;
232  std::unordered_map<Addr, TransMapPair> m_outTransAddressed;
233 
234  std::unordered_map<Addr, TransMapPair> m_inTransUnaddressed;
235  std::unordered_map<Addr, TransMapPair> m_outTransUnaddressed;
236 
251  template<typename EventType, typename StateType>
253  EventType type, StateType initialState, bool retried,
254  bool isAddressed=true)
255  {
256  auto& m_inTrans =
258  assert(m_inTrans.find(addr) == m_inTrans.end());
259  m_inTrans[addr] = {type, initialState, curTick()};
260  if (retried)
262  }
263 
274  template<typename StateType>
275  void incomingTransactionEnd(Addr addr, StateType finalState,
276  bool isAddressed=true)
277  {
278  auto& m_inTrans =
280  auto iter = m_inTrans.find(addr);
281  assert(iter != m_inTrans.end());
282  stats.inTransLatHist[iter->second.transaction]
283  [iter->second.state]
284  [(unsigned)finalState]->sample(
285  ticksToCycles(curTick() - iter->second.time));
286  ++(*stats.inTransLatTotal[iter->second.transaction]);
287  m_inTrans.erase(iter);
288  }
289 
301  template<typename EventType>
303  bool isAddressed=true)
304  {
305  auto& m_outTrans =
307  assert(m_outTrans.find(addr) == m_outTrans.end());
308  m_outTrans[addr] = {type, 0, curTick()};
309  }
310 
321  void outgoingTransactionEnd(Addr addr, bool retried,
322  bool isAddressed=true)
323  {
324  auto& m_outTrans =
326  auto iter = m_outTrans.find(addr);
327  assert(iter != m_outTrans.end());
328  stats.outTransLatHist[iter->second.transaction]->sample(
329  ticksToCycles(curTick() - iter->second.time));
330  if (retried)
331  ++(*stats.outTransLatHistRetries[iter->second.transaction]);
332  m_outTrans.erase(iter);
333  }
334 
335  void stallBuffer(MessageBuffer* buf, Addr addr);
336  void wakeUpBuffer(MessageBuffer* buf, Addr addr);
337  void wakeUpBuffers(Addr addr);
338  void wakeUpAllBuffers(Addr addr);
339  void wakeUpAllBuffers();
340  bool serviceMemoryQueue();
341 
342  protected:
346 
347  // RequestorID used by some components of gem5.
349 
352  std::map<Addr, MessageBuffer*> m_block_map;
353 
355  typedef std::set<MessageBuffer*> MsgBufType;
356  typedef std::map<Addr, MsgVecType* > WaitingBufType;
358 
359  unsigned int m_in_ports;
360  unsigned int m_cur_in_port;
361  const int m_number_of_TBEs;
363  const unsigned int m_buffer_size;
367 
372  class MemoryPort : public RequestPort
373  {
374  private:
375  // Controller that operates this port.
377 
378  public:
379  MemoryPort(const std::string &_name, AbstractController *_controller,
380  PortID id = InvalidPortID);
381 
382  protected:
383  // Function for receiving a timing response from the peer port.
384  // Currently the pkt is handed to the coherence controller
385  // associated with this port.
386  bool recvTimingResp(PacketPtr pkt);
387 
388  void recvReqRetry();
389  };
390 
391  /* Request port to the memory controller. */
393 
394  // State that is stored in packets sent to the memory controller.
396  {
397  // Id of the machine from which the request originated.
399 
401  {}
402  };
403 
404  private:
407 
408  std::unordered_map<MachineType, AddrRangeMap<MachineID, 3>>
410 
413 
414  public:
416  {
418 
419  // Initialized by the SLICC compiler for all combinations of event and
420  // states. Only histograms with samples will appear in the stats
425 
426  // Initialized by the SLICC compiler for all events.
427  // Only histograms with samples will appear in the stats.
430 
434 
439  } stats;
440 
441 };
442 
443 } // namespace ruby
444 } // namespace gem5
445 
446 #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
ClockedObjectParams Params
Parameters of ClockedObject.
Cycles ticksToCycles(Tick t) const
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:79
const std::string _name
Definition: named.hh:41
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
Ports are used to interface objects to each other.
Definition: port.hh:62
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Definition: port.hh:79
Port that forwards requests and receives responses from the memory controller.
MemoryPort(const std::string &_name, AbstractController *_controller, PortID id=InvalidPortID)
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
void initNetworkPtr(Network *net_ptr)
std::vector< MessageBuffer * > MsgVecType
void profileMsgDelay(uint32_t virtualNetwork, Cycles delay)
Profiles the delay associated with messages.
virtual MessageBuffer * getMemReqQueue() const =0
const NetDest & allDownstreamDest() const
List of downstream destinations (towards memory)
std::map< Addr, MsgVecType * > WaitingBufType
virtual GPUCoalescer * getGPUCoalescer() const =0
virtual void initNetQueues()=0
Initialize the message buffers.
virtual void notifyCoalesced(const Addr &addr, const RubyRequestType &type, const RequestPtr &req, const DataBlock &data_blk, const bool &was_miss)
Notifies controller of a request coalesced at the sequencer.
void wakeUpBuffer(MessageBuffer *buf, Addr addr)
virtual MessageBuffer * getMandatoryQueue() const =0
virtual void regStats()
Callback to set stat parameters.
virtual void print(std::ostream &out) const =0
const NetDest & allUpstreamDest() const
List of upstream destinations (towards the CPU)
std::unordered_map< Addr, TransMapPair > m_outTransAddressed
void incomingTransactionStart(Addr addr, EventType type, StateType initialState, bool retried, bool isAddressed=true)
Profiles an event that initiates a protocol transactions for a specific line (e.g.
virtual Cycles mandatoryQueueLatency(const RubyRequestType &param_type)
const AddrRangeList addrRanges
The address range to which the controller responds on the CPU side.
std::unordered_map< MachineType, AddrRangeMap< MachineID, 3 > > downstreamAddrMap
virtual AccessPermission getAccessPermission(const Addr &addr)=0
std::set< MessageBuffer * > MsgBufType
virtual int functionalWrite(const Addr &addr, PacketPtr)=0
virtual void recordCacheTrace(int cntrl, CacheRecorder *tr)=0
virtual bool functionalReadBuffers(PacketPtr &)=0
These functions are used by ruby system to read/write the data blocks that exist with in the controll...
virtual Sequencer * getCPUSequencer() const =0
void outgoingTransactionStart(Addr addr, EventType type, bool isAddressed=true)
Profiles an event that initiates a transaction in a peer controller (e.g.
MachineID mapAddressToDownstreamMachine(Addr addr, MachineType mtype=MachineType_NUM) const
Maps an address to the correct dowstream MachineID (i.e.
virtual void enqueuePrefetch(const Addr &, const RubyRequestType &)
Function for enqueuing a prefetch request.
virtual void collateStats()
Function for collating statistics from all the controllers of this particular type.
statistics::Histogram & getDelayVCHist(uint32_t index)
virtual bool functionalReadBuffers(PacketPtr &, WriteMask &mask)=0
Functional read that reads only blocks not present in the mask.
virtual void functionalRead(const Addr &addr, PacketPtr)
void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
std::unordered_map< Addr, TransMapPair > m_inTransAddressed
std::unordered_map< Addr, TransMapPair > m_inTransUnaddressed
virtual void resetStats()=0
Callback to reset stats.
virtual void functionalRead(const Addr &addr, PacketPtr pkt, WriteMask &mask)
void blockOnQueue(Addr, MessageBuffer *)
MachineID mapAddressToMachine(Addr addr, MachineType mtype) const
Map an address to the correct MachineID.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
A function used to return the port associated with this bus object.
void outgoingTransactionEnd(Addr addr, bool retried, bool isAddressed=true)
Profiles the end of an outgoing transaction.
gem5::ruby::AbstractController::ControllerStats stats
void profileRequest(const std::string &request)
Profiles original cache requests including PUTs.
void incomingTransactionEnd(Addr addr, StateType finalState, bool isAddressed=true)
Profiles an event that ends a transaction.
std::unordered_map< Addr, TransMapPair > m_outTransUnaddressed
std::map< Addr, MessageBuffer * > m_block_map
virtual MessageBuffer * getMemRespQueue() const =0
const AddrRangeList & getAddrRanges() const
statistics::Histogram & getDelayHist()
virtual DMASequencer * getDMASequencer() const =0
void stallBuffer(MessageBuffer *buf, Addr addr)
virtual int functionalWriteBuffers(PacketPtr &)=0
The return value indicates the number of messages written with the data from the packet.
virtual const char * what() const
Statistics container.
Definition: group.hh:94
A simple histogram stat.
Definition: statistics.hh:2127
This is a simple scalar statistic, like a counter.
Definition: statistics.hh:1931
STL vector class.
Definition: stl.hh:37
ClockedObject declaration and implementation.
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
Bitfield< 30, 0 > index
Bitfield< 54 > p
Definition: pagetable.hh:70
Bitfield< 3 > addr
Definition: types.hh:84
unsigned int NodeID
Definition: TypeDefines.hh:42
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
const PortID InvalidPortID
Definition: types.hh:246
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
uint64_t Tick
Tick count type.
Definition: types.hh:58
uint16_t RequestorID
Definition: request.hh:95
Declaration of the Packet class.
Declaration of the queued port.
A virtual base opaque structure used to hold state associated with the packet (e.g....
Definition: packet.hh:468
std::vector< statistics::Scalar * > inTransLatRetries
std::vector< statistics::Scalar * > outTransLatHistRetries
std::vector< std::vector< std::vector< statistics::Histogram * > > > inTransLatHist
statistics::Scalar fullyBusyCycles
Counter for the number of cycles when the transitions carried out were equal to the maximum allowed.
std::vector< statistics::Histogram * > outTransLatHist
std::vector< statistics::Scalar * > inTransLatTotal
statistics::Histogram delayHistogram
Histogram for profiling delay for the messages this controller cares for.
std::vector< statistics::Histogram * > delayVCHistogram
MachineType getType() const
Definition: MachineID.hh:66
NodeID getNum() const
Definition: MachineID.hh:67

Generated on Wed Dec 21 2022 10:22:38 for gem5 by doxygen 1.9.1