SST  9.1.0
StructuralSimulationToolkit
simpleMem.h
1 // -*- mode: c++ -*-
2 // Copyright 2009-2019 NTESS. Under the terms
3 // of Contract DE-NA0003525 with NTESS, the U.S.
4 // Government retains certain rights in this software.
5 //
6 // Copyright (c) 2009-2019, NTESS
7 // All rights reserved.
8 //
9 // This file is part of the SST software package. For license
10 // information, see the LICENSE file in the top level directory of the
11 // distribution.
12 //
13 
14 #ifndef CORE_INTERFACES_SIMPLEMEM_H_
15 #define CORE_INTERFACES_SIMPLEMEM_H_
16 
17 #include <string>
18 #include <utility>
19 #include <map>
20 #include <atomic>
21 
22 #include <sst/core/sst_types.h>
23 #include <sst/core/warnmacros.h>
24 #include <sst/core/subcomponent.h>
25 #include <sst/core/params.h>
26 #include <sst/core/link.h>
27 
28 namespace SST {
29 
30 class Component;
31 class Event;
32 
33 namespace Interfaces {
34 
35 
36 /**
37  * Simplified, generic interface to Memory models
38  */
39 class SimpleMem : public SubComponent {
40 
41 
42 public:
43  class HandlerBase;
44 
45  SST_ELI_REGISTER_SUBCOMPONENT_API(SST::Interfaces::SimpleMem,TimeConverter*,HandlerBase*)
46  /** All Addresses can be 64-bit */
47  typedef uint64_t Addr;
48 
49  /**
50  * Represents both memory requests and responses.
51  */
52  class Request {
53  public:
54  typedef uint64_t id_t; /*!< Request ID type */
55  typedef uint32_t flags_t; /*!< Flag type */
56 
57  /**
58  * Commands and responses possible with a Request object
59  */
60  typedef enum {
61  Read, /*!< Issue a Read from Memory */
62  Write, /*!< Issue a Write to Memory */
63  ReadResp, /*!< Response from Memory to a Read */
64  WriteResp, /*!< Response from Memory to a Write */
65  FlushLine, /*!< Cache flush request - writeback specified line throughout memory system */
66  FlushLineInv, /*!< Cache flush request - writeback and invalidate specified line throughout memory system */
67  FlushLineResp, /*!< Response to FlushLine; flag F_FLUSH_SUCCESS indicates success or failure */
68  TxBegin, /*!< Start a new transaction */
69  TxEnd, /*!< End the current lowest transaction */
70  TxResp,
71  TxAbort,
72  TxCommit,
73  CustomCmd /*!< Custom memory command: Must also set custCmd opcode */
74  } Command;
75 
76  /**
77  * Flags to specify conditions on a Request
78  */
79  typedef enum {
80  F_NONCACHEABLE = 1<<1, /*!< This request should not be cached */
81  F_LOCKED = 1<<2, /*!< This request should be locked. A LOCKED read should be soon followed by a LOCKED write (to unlock) */
82  F_LLSC = 1<<3,
83  F_LLSC_RESP = 1<<4,
84  F_FLUSH_SUCCESS = 1<<5, /*!< This flag is set if the flush was successful. Flush may fail due to LOCKED lines */
85  F_TRANSACTION = 1<<6
86  } Flags;
87 
88  /** Type of the payload or data */
89  typedef std::vector<uint8_t> dataVec;
90 
91  Command cmd; /*!< Command to issue */
92  std::vector<Addr> addrs; /*!< Target address(es) */
93  Addr addr; /*!< Target address - DEPRECATED but included for backward compatibility, defaults to addrs[0] */
94  size_t size; /*!< Size of this request or response */
95  dataVec data; /*!< Payload data (for Write, or ReadResp) */
96  flags_t flags; /*!< Flags associated with this request or response */
97  flags_t memFlags; /*!< Memory flags - ignored by caches except to be passed through with request to main memory */
98  id_t id; /*!< Unique ID to identify responses with requests */
99  Addr instrPtr; /*!< Instruction pointer associated with the operation */
100  Addr virtualAddr; /*!< Virtual address associated with the operation */
101  uint32_t custOpc; /*!< Custom command opcode for CustomdCmd type commands */
102 
103  /** Constructor */
104  Request(Command cmd, Addr addr, size_t size, dataVec &data, flags_t flags = 0, flags_t memFlags = 0) :
105  cmd(cmd), addr(addr), size(size), data(data), flags(flags), memFlags(memFlags),
106  instrPtr(0), virtualAddr(0), custOpc(0xFFFF)
107  {
108  addrs.push_back(addr);
109  id = main_id++;
110  }
111 
112  /** Constructor */
113  Request(Command cmd, Addr addr, size_t size, flags_t flags = 0, flags_t memFlags = 0) :
114  cmd(cmd), addr(addr), size(size), flags(flags), memFlags(memFlags),
115  instrPtr(0), virtualAddr(0), custOpc(0xFFFF)
116  {
117  addrs.push_back(addr);
118  id = main_id++;
119  }
120 
121  /** Constructor */
122  Request(Command cmd, Addr addr, size_t size, dataVec &data, uint32_t Opc, flags_t flags = 0, flags_t memFlags = 0) :
123  cmd(cmd), addr(addr), size(size), data(data), flags(flags), memFlags(memFlags),
124  instrPtr(0), virtualAddr(0), custOpc(Opc)
125  {
126  addrs.push_back(addr);
127  id = main_id++;
128  }
129 
130  /** Constructor */
131  Request(Command cmd, Addr addr, size_t size, uint32_t Opc, flags_t flags = 0, flags_t memFlags = 0) :
132  cmd(cmd), addr(addr), size(size), flags(flags), memFlags(memFlags),
133  instrPtr(0), virtualAddr(0), custOpc(Opc)
134  {
135  addrs.push_back(addr);
136  id = main_id++;
137  }
138 
139  void addAddress(Addr addr)
140  {
141  addrs.push_back(addr);
142  }
143 
144  /**
145  * @param[in] data_in
146  * @brief Set the contents of the payload / data field.
147  */
148  void setPayload(const std::vector<uint8_t> & data_in )
149  {
150  data = data_in;
151  }
152 
153  /**
154  * @param[in] data_in
155  * @brief Set the contents of the payload / data field.
156  */
157  void setPayload(uint8_t *data_in, size_t len) {
158  data.resize(len);
159  for ( size_t i = 0 ; i < len ; i++ ) {
160  data[i] = data_in[i];
161  }
162  }
163 
164  /**
165  * @param[in] newVA
166  * @brief Set the virtual address associated with the operation
167  */
168  void setVirtualAddress(const Addr newVA) {
169  virtualAddr = newVA;
170  }
171 
172  /**
173  * @returns the virtual address associated with the operation
174  */
175  uint64_t getVirtualAddress() {
176  return (uint64_t) virtualAddr;
177  }
178 
179  /**
180  * @param[in] newIP
181  * @brief Sets the instruction pointer associated with the operation
182  */
183  void setInstructionPointer(const Addr newIP) {
184  instrPtr = newIP;
185  }
186 
187  /**
188  * @returns the instruction pointer associated with the operation
189  */
191  return instrPtr;
192  }
193 
194  /**
195  * @brief Clears the flags associated with the operation
196  */
197  void clearFlags(void) {
198  flags = 0;
199  }
200 
201  /**
202  * @param[in] inValue Should be one of the flags beginning with F_ in simpleMem
203  */
204  void setFlags(flags_t inValue) {
205  flags = flags | inValue;
206  }
207 
208  /**
209  * @returns the flags associated with the operation
210  */
211  flags_t getFlags(void) {
212  return flags;
213  }
214 
215  /**
216  * @brief Clears the memory flags associated with the operation
217  */
218  void clearMemFlags(void) {
219  memFlags = 0;
220  }
221 
222  /**
223  * @param[in] inValue Should be one of the flags beginning with F_ in simpleMem
224  */
225  void setMemFlags(flags_t inValue) {
226  memFlags = memFlags | inValue;
227  }
228 
229  /**
230  * @returns the memory flags associated with the operation
231  */
232  flags_t getMemFlags(void) {
233  return memFlags;
234  }
235 
236  /**
237  * @returns the custom opcode for custom request types
238  */
239  uint32_t getCustomOpc(void){
240  return custOpc;
241  }
242 
243 
244  private:
245  static std::atomic<id_t> main_id;
246 
247  };
248 
249  /** Functor classes for Clock handling */
250  class HandlerBase {
251  public:
252  /** Function called when Handler is invoked */
253  virtual void operator()(Request*) = 0;
254  virtual ~HandlerBase() {}
255  };
256 
257 
258  /** Event Handler class with user-data argument
259  * @tparam classT Type of the Object
260  * @tparam argT Type of the argument
261  */
262  template <typename classT, typename argT = void>
263  class Handler : public HandlerBase {
264  private:
265  typedef void (classT::*PtrMember)(Request*, argT);
266  classT* object;
267  const PtrMember member;
268  argT data;
269 
270  public:
271  /** Constructor
272  * @param object - Pointer to Object upon which to call the handler
273  * @param member - Member function to call as the handler
274  * @param data - Additional argument to pass to handler
275  */
276  Handler( classT* const object, PtrMember member, argT data ) :
277  object(object),
278  member(member),
279  data(data)
280  {}
281 
282  void operator()(Request* req) {
283  return (object->*member)(req,data);
284  }
285  };
286 
287  /** Event Handler class without user-data
288  * @tparam classT Type of the Object
289  */
290  template <typename classT>
291  class Handler<classT, void> : public HandlerBase {
292  private:
293  typedef void (classT::*PtrMember)(Request*);
294  classT* object;
295  const PtrMember member;
296 
297  public:
298  /** Constructor
299  * @param object - Pointer to Object upon which to call the handler
300  * @param member - Member function to call as the handler
301  */
302  Handler( classT* const object, PtrMember member ) :
303  object(object),
304  member(member)
305  {}
306 
307  void operator()(Request* req) {
308  return (object->*member)(req);
309  }
310  };
311 
312 
313  /** Constructor, designed to be used via 'loadSubComponent'. */
314  SimpleMem(SST::Component *comp, Params &UNUSED(params)) :
315  SubComponent(comp)
316  { }
317 
318  /** Constructor, designed to be used via 'loadUserSubComponent and loadAnonymousSubComponent'. */
319  SimpleMem(SST::ComponentId_t id, Params &UNUSED(params)) :
320  SubComponent(id)
321  { }
322 
323  /** Second half of building the interface.
324  * Initialize with link name name, and handler, if any
325  * @return true if the link was able to be configured.
326  */
327  virtual bool initialize(const std::string &linkName, HandlerBase *handler = NULL) = 0;
328 
329  /**
330  * Sends a memory-based request during the init() phase
331  */
332  virtual void sendInitData(Request *req) = 0;
333 
334  /**
335  * Sends a generic Event during the init() phase
336  * (Mostly acts as a passthrough)
337  * @see SST::Link::sendInitData()
338  */
339  virtual void sendInitData(SST::Event *ev) { getLink()->sendInitData(ev); }
340 
341  /**
342  * Receive any data during the init() phase.
343  * @see SST::Link::recvInitData()
344  */
345  virtual SST::Event* recvInitData() { return getLink()->recvInitData(); }
346 
347  /**
348  * Returns a handle to the underlying SST::Link
349  */
350  virtual SST::Link* getLink(void) const = 0;
351 
352  /**
353  * Send a Request to the other side of the link.
354  */
355  virtual void sendRequest(Request *req) = 0;
356 
357  /**
358  * Receive a Request response from the side of the link.
359  *
360  * Use this method for polling-based applications.
361  * Register a handler for push-based notification of responses.
362  *
363  * @return NULL if nothing is available.
364  * @return Pointer to a Request response (that should be deleted)
365  */
366  virtual Request* recvResponse(void) = 0;
367 
368 
369 };
370 
371 }
372 }
373 
374 #endif
virtual SST::Event * recvInitData()
Receive any data during the init() phase.
Definition: simpleMem.h:345
size_t size
Definition: simpleMem.h:94
uint32_t flags_t
Definition: simpleMem.h:55
Request(Command cmd, Addr addr, size_t size, uint32_t Opc, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:131
Addr getInstructionPointer()
Definition: simpleMem.h:190
Command
Commands and responses possible with a Request object.
Definition: simpleMem.h:60
Represents both memory requests and responses.
Definition: simpleMem.h:52
virtual void sendRequest(Request *req)=0
Send a Request to the other side of the link.
std::vector< Addr > addrs
Definition: simpleMem.h:92
virtual SST::Link * getLink(void) const =0
Returns a handle to the underlying SST::Link.
A class to convert between a component&#39;s view of time and the core&#39;s view of time.
Definition: timeConverter.h:25
uint64_t getVirtualAddress()
Definition: simpleMem.h:175
Command cmd
Definition: simpleMem.h:91
Main component object for the simulation.
Definition: component.h:32
Handler(classT *const object, PtrMember member, argT data)
Constructor.
Definition: simpleMem.h:276
dataVec data
Definition: simpleMem.h:95
void setFlags(flags_t inValue)
Definition: simpleMem.h:204
std::vector< uint8_t > dataVec
Type of the payload or data.
Definition: simpleMem.h:89
Request(Command cmd, Addr addr, size_t size, dataVec &data, uint32_t Opc, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:122
void setInstructionPointer(const Addr newIP)
Sets the instruction pointer associated with the operation.
Definition: simpleMem.h:183
void setPayload(const std::vector< uint8_t > &data_in)
Set the contents of the payload / data field.
Definition: simpleMem.h:148
void operator()(Request *req)
Function called when Handler is invoked.
Definition: simpleMem.h:307
Functor classes for Clock handling.
Definition: simpleMem.h:250
virtual void sendInitData(Request *req)=0
Sends a memory-based request during the init() phase.
flags_t flags
Definition: simpleMem.h:96
Simplified, generic interface to Memory models.
Definition: simpleMem.h:39
void operator()(Request *req)
Function called when Handler is invoked.
Definition: simpleMem.h:282
flags_t getMemFlags(void)
Definition: simpleMem.h:232
Handler(classT *const object, PtrMember member)
Constructor.
Definition: simpleMem.h:302
void clearFlags(void)
Clears the flags associated with the operation.
Definition: simpleMem.h:197
Addr instrPtr
Definition: simpleMem.h:99
Request(Command cmd, Addr addr, size_t size, dataVec &data, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:104
Addr virtualAddr
Definition: simpleMem.h:100
flags_t getFlags(void)
Definition: simpleMem.h:211
Event Handler class with user-data argument.
Definition: simpleMem.h:263
virtual void sendInitData(SST::Event *ev)
Sends a generic Event during the init() phase (Mostly acts as a passthrough)
Definition: simpleMem.h:339
virtual void operator()(Request *)=0
Function called when Handler is invoked.
void setMemFlags(flags_t inValue)
Definition: simpleMem.h:225
virtual bool initialize(const std::string &linkName, HandlerBase *handler=NULL)=0
Second half of building the interface.
Parameter store.
Definition: params.h:45
uint64_t Addr
All Addresses can be 64-bit.
Definition: simpleMem.h:43
void setVirtualAddress(const Addr newVA)
Set the virtual address associated with the operation.
Definition: simpleMem.h:168
uint32_t getCustomOpc(void)
Definition: simpleMem.h:239
void setPayload(uint8_t *data_in, size_t len)
Set the contents of the payload / data field.
Definition: simpleMem.h:157
Base class for Events - Items sent across links to communicate between components.
Definition: event.h:31
SimpleMem(SST::ComponentId_t id, Params &UNUSED(params))
Constructor, designed to be used via &#39;loadUserSubComponent and loadAnonymousSubComponent&#39;.
Definition: simpleMem.h:319
uint32_t custOpc
Definition: simpleMem.h:101
SimpleMem(SST::Component *comp, Params &UNUSED(params))
Constructor, designed to be used via &#39;loadSubComponent&#39;.
Definition: simpleMem.h:314
Addr addr
Definition: simpleMem.h:93
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:30
uint64_t id_t
Definition: simpleMem.h:54
id_t id
Definition: simpleMem.h:98
virtual Request * recvResponse(void)=0
Receive a Request response from the side of the link.
void clearMemFlags(void)
Clears the memory flags associated with the operation.
Definition: simpleMem.h:218
Request(Command cmd, Addr addr, size_t size, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:113
flags_t memFlags
Definition: simpleMem.h:97