SST  11.0.0
StructuralSimulationToolkit
simpleMem.h
1 // -*- mode: c++ -*-
2 // Copyright 2009-2021 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-2021, 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 SST_CORE_INTERFACES_SIMPLEMEM_H_
15 #define SST_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  Inv, /*!< Notification of L1 cache invalidation to core */
69  TxBegin, /*!< Start a new transaction */
70  TxEnd, /*!< End the current lowest transaction */
71  TxResp,
72  TxAbort,
73  TxCommit,
74  CustomCmd /*!< Custom memory command: Must also set custCmd opcode */
75  } Command;
76 
77  /**
78  * Flags to specify conditions on a Request
79  */
80  typedef enum {
81  F_NONCACHEABLE = 1<<1, /*!< This request should not be cached */
82  F_LOCKED = 1<<2, /*!< This request should be locked. A LOCKED read should be soon followed by a LOCKED write (to unlock) */
83  F_LLSC = 1<<3,
84  F_LLSC_RESP = 1<<4,
85  F_FLUSH_SUCCESS = 1<<5, /*!< This flag is set if the flush was successful. Flush may fail due to LOCKED lines */
86  F_TRANSACTION = 1<<6
87  } Flags;
88 
89  /** Type of the payload or data */
90  typedef std::vector<uint8_t> dataVec;
91 
92  Command cmd; /*!< Command to issue */
93  std::vector<Addr> addrs; /*!< Target address(es) */
94  Addr addr; /*!< Target address - DEPRECATED but included for backward compatibility, defaults to addrs[0] */
95  size_t size; /*!< Size of this request or response */
96  dataVec data; /*!< Payload data (for Write, or ReadResp) */
97  flags_t flags; /*!< Flags associated with this request or response */
98  flags_t memFlags; /*!< Memory flags - ignored by caches except to be passed through with request to main memory */
99  id_t id; /*!< Unique ID to identify responses with requests */
100  Addr instrPtr; /*!< Instruction pointer associated with the operation */
101  Addr virtualAddr; /*!< Virtual address associated with the operation */
102  uint32_t custOpc; /*!< Custom command opcode for CustomdCmd type commands */
103 
104  /** Constructor */
105  Request(Command cmd, Addr addr, size_t size, dataVec &data, flags_t flags = 0, flags_t memFlags = 0) :
106  cmd(cmd), addr(addr), size(size), data(data), flags(flags), memFlags(memFlags),
107  instrPtr(0), virtualAddr(0), custOpc(0xFFFF)
108  {
109  addrs.push_back(addr);
110  id = main_id++;
111  }
112 
113  /** Constructor */
114  Request(Command cmd, Addr addr, size_t size, flags_t flags = 0, flags_t memFlags = 0) :
115  cmd(cmd), addr(addr), size(size), flags(flags), memFlags(memFlags),
116  instrPtr(0), virtualAddr(0), custOpc(0xFFFF)
117  {
118  addrs.push_back(addr);
119  id = main_id++;
120  }
121 
122  /** Constructor */
123  Request(Command cmd, Addr addr, size_t size, dataVec &data, uint32_t Opc, flags_t flags = 0, flags_t memFlags = 0) :
124  cmd(cmd), addr(addr), size(size), data(data), flags(flags), memFlags(memFlags),
125  instrPtr(0), virtualAddr(0), custOpc(Opc)
126  {
127  addrs.push_back(addr);
128  id = main_id++;
129  }
130 
131  /** Constructor */
132  Request(Command cmd, Addr addr, size_t size, uint32_t Opc, flags_t flags = 0, flags_t memFlags = 0) :
133  cmd(cmd), addr(addr), size(size), flags(flags), memFlags(memFlags),
134  instrPtr(0), virtualAddr(0), custOpc(Opc)
135  {
136  addrs.push_back(addr);
137  id = main_id++;
138  }
139 
140  void addAddress(Addr addr)
141  {
142  addrs.push_back(addr);
143  }
144 
145  /**
146  * @param[in] data_in
147  * @brief Set the contents of the payload / data field.
148  */
149  void setPayload(const std::vector<uint8_t> & data_in )
150  {
151  data = data_in;
152  }
153 
154  /**
155  * @param[in] data_in
156  * @brief Set the contents of the payload / data field.
157  */
158  void setPayload(uint8_t *data_in, size_t len) {
159  data.resize(len);
160  for ( size_t i = 0 ; i < len ; i++ ) {
161  data[i] = data_in[i];
162  }
163  }
164 
165  /**
166  * @param[in] newVA
167  * @brief Set the virtual address associated with the operation
168  */
169  void setVirtualAddress(const Addr newVA) {
170  virtualAddr = newVA;
171  }
172 
173  /**
174  * @returns the virtual address associated with the operation
175  */
176  uint64_t getVirtualAddress() {
177  return (uint64_t) virtualAddr;
178  }
179 
180  /**
181  * @param[in] newIP
182  * @brief Sets the instruction pointer associated with the operation
183  */
184  void setInstructionPointer(const Addr newIP) {
185  instrPtr = newIP;
186  }
187 
188  /**
189  * @returns the instruction pointer associated with the operation
190  */
192  return instrPtr;
193  }
194 
195  /**
196  * @brief Clears the flags associated with the operation
197  */
198  void clearFlags(void) {
199  flags = 0;
200  }
201 
202  /**
203  * @param[in] inValue Should be one of the flags beginning with F_ in simpleMem
204  */
205  void setFlags(flags_t inValue) {
206  flags = flags | inValue;
207  }
208 
209  /**
210  * @returns the flags associated with the operation
211  */
212  flags_t getFlags(void) {
213  return flags;
214  }
215 
216  /**
217  * @brief Clears the memory flags associated with the operation
218  */
219  void clearMemFlags(void) {
220  memFlags = 0;
221  }
222 
223  /**
224  * @param[in] inValue Should be one of the flags beginning with F_ in simpleMem
225  */
226  void setMemFlags(flags_t inValue) {
227  memFlags = memFlags | inValue;
228  }
229 
230  /**
231  * @returns the memory flags associated with the operation
232  */
233  flags_t getMemFlags(void) {
234  return memFlags;
235  }
236 
237  /**
238  * @returns the custom opcode for custom request types
239  */
240  uint32_t getCustomOpc(void){
241  return custOpc;
242  }
243 
244 
245  private:
246  static std::atomic<id_t> main_id;
247 
248  };
249 
250  /** Functor classes for Clock handling */
251  class HandlerBase {
252  public:
253  /** Function called when Handler is invoked */
254  virtual void operator()(Request*) = 0;
255  virtual ~HandlerBase() {}
256  };
257 
258 
259  /** Event Handler class with user-data argument
260  * @tparam classT Type of the Object
261  * @tparam argT Type of the argument
262  */
263  template <typename classT, typename argT = void>
264  class Handler : public HandlerBase {
265  private:
266  typedef void (classT::*PtrMember)(Request*, argT);
267  classT* object;
268  const PtrMember member;
269  argT data;
270 
271  public:
272  /** Constructor
273  * @param object - Pointer to Object upon which to call the handler
274  * @param member - Member function to call as the handler
275  * @param data - Additional argument to pass to handler
276  */
277  Handler( classT* const object, PtrMember member, argT data ) :
278  object(object),
279  member(member),
280  data(data)
281  {}
282 
283  void operator()(Request* req) {
284  return (object->*member)(req,data);
285  }
286  };
287 
288  /** Event Handler class without user-data
289  * @tparam classT Type of the Object
290  */
291  template <typename classT>
292  class Handler<classT, void> : public HandlerBase {
293  private:
294  typedef void (classT::*PtrMember)(Request*);
295  classT* object;
296  const PtrMember member;
297 
298  public:
299  /** Constructor
300  * @param object - Pointer to Object upon which to call the handler
301  * @param member - Member function to call as the handler
302  */
303  Handler( classT* const object, PtrMember member ) :
304  object(object),
305  member(member)
306  {}
307 
308  void operator()(Request* req) {
309  return (object->*member)(req);
310  }
311  };
312 
313 
314  /** Constructor, designed to be used via 'loadUserSubComponent and loadAnonymousSubComponent'. */
315  SimpleMem(SST::ComponentId_t id, Params &UNUSED(params)) :
316  SubComponent(id)
317  { }
318 
319  /** Second half of building the interface.
320  * Initialize with link name name, and handler, if any
321  * @return true if the link was able to be configured.
322  */
323  virtual bool initialize(const std::string& linkName, HandlerBase *handler = nullptr) = 0;
324 
325  /**
326  * Sends a memory-based request during the init() phase
327  */
328  virtual void sendInitData(Request *req) = 0;
329 
330  /**
331  * Sends a generic Event during the init() phase
332  * (Mostly acts as a passthrough)
333  * @see SST::Link::sendInitData()
334  */
335  virtual void sendInitData(SST::Event *ev) { getLink()->sendInitData(ev); }
336 
337  /**
338  * Receive any data during the init() phase.
339  * @see SST::Link::recvInitData()
340  */
341  virtual SST::Event* recvInitData() { return getLink()->recvInitData(); }
342 
343  /**
344  * Returns a handle to the underlying SST::Link
345  */
346  virtual SST::Link* getLink(void) const = 0;
347 
348  /**
349  * Send a Request to the other side of the link.
350  */
351  virtual void sendRequest(Request *req) = 0;
352 
353  /**
354  * Receive a Request response from the side of the link.
355  *
356  * Use this method for polling-based applications.
357  * Register a handler for push-based notification of responses.
358  *
359  * @return nullptr if nothing is available.
360  * @return Pointer to a Request response (that should be deleted)
361  */
362  virtual Request* recvResponse(void) = 0;
363 
364  /**
365  * Get cache/memory line size from the memory system
366  *
367  * The memory system should provide this and it should be
368  * valid after the init() phase is complete, so processors
369  * can call this function during setup().
370  *
371  * For backward compatibiity, the function returns 0 by default.
372  * Eventually, interfaces will be required to implement this
373  * function.
374  *
375  * @return 0 if the interface does not provide this capability
376  * @return line size of the memory system
377  */
378  virtual Addr getLineSize() { return 0; }
379 
380 };
381 
382 }
383 }
384 
385 #endif
virtual SST::Event * recvInitData()
Receive any data during the init() phase.
Definition: simpleMem.h:341
size_t size
Definition: simpleMem.h:95
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:132
Addr getInstructionPointer()
Definition: simpleMem.h:191
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:93
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:176
Command cmd
Definition: simpleMem.h:92
Handler(classT *const object, PtrMember member, argT data)
Constructor.
Definition: simpleMem.h:277
dataVec data
Definition: simpleMem.h:96
void setFlags(flags_t inValue)
Definition: simpleMem.h:205
std::vector< uint8_t > dataVec
Type of the payload or data.
Definition: simpleMem.h:90
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:123
void setInstructionPointer(const Addr newIP)
Sets the instruction pointer associated with the operation.
Definition: simpleMem.h:184
void setPayload(const std::vector< uint8_t > &data_in)
Set the contents of the payload / data field.
Definition: simpleMem.h:149
void operator()(Request *req)
Function called when Handler is invoked.
Definition: simpleMem.h:308
Functor classes for Clock handling.
Definition: simpleMem.h:251
virtual void sendInitData(Request *req)=0
Sends a memory-based request during the init() phase.
flags_t flags
Definition: simpleMem.h:97
virtual bool initialize(const std::string &linkName, HandlerBase *handler=nullptr)=0
Second half of building the interface.
Simplified, generic interface to Memory models.
Definition: simpleMem.h:39
void operator()(Request *req)
Function called when Handler is invoked.
Definition: simpleMem.h:283
flags_t getMemFlags(void)
Definition: simpleMem.h:233
Handler(classT *const object, PtrMember member)
Constructor.
Definition: simpleMem.h:303
void clearFlags(void)
Clears the flags associated with the operation.
Definition: simpleMem.h:198
Addr instrPtr
Definition: simpleMem.h:100
Request(Command cmd, Addr addr, size_t size, dataVec &data, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:105
virtual Addr getLineSize()
Get cache/memory line size from the memory system.
Definition: simpleMem.h:378
Addr virtualAddr
Definition: simpleMem.h:101
flags_t getFlags(void)
Definition: simpleMem.h:212
Event Handler class with user-data argument.
Definition: simpleMem.h:264
virtual void sendInitData(SST::Event *ev)
Sends a generic Event during the init() phase (Mostly acts as a passthrough)
Definition: simpleMem.h:335
virtual void operator()(Request *)=0
Function called when Handler is invoked.
void setMemFlags(flags_t inValue)
Definition: simpleMem.h:226
Parameter store.
Definition: params.h:44
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:169
uint32_t getCustomOpc(void)
Definition: simpleMem.h:240
void setPayload(uint8_t *data_in, size_t len)
Set the contents of the payload / data field.
Definition: simpleMem.h:158
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:315
uint32_t custOpc
Definition: simpleMem.h:102
Addr addr
Definition: simpleMem.h:94
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:29
uint64_t id_t
Definition: simpleMem.h:54
id_t id
Definition: simpleMem.h:99
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:219
Request(Command cmd, Addr addr, size_t size, flags_t flags=0, flags_t memFlags=0)
Constructor.
Definition: simpleMem.h:114
flags_t memFlags
Definition: simpleMem.h:98