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