.. _U_SST: Understanding SST ================== .. note:: Information in this entire section has been adapted from: Ziqi Wang, `"Understanding Memory Hierarchy Simulation in SST" `_ SST is used to simulate the memory hierarchy in SimEng. Since the entire simulation runs inside SST, SimEng needs to interact (send and recieve requests) with the memory hierarchy inside SST through an interface. The rest is handled by SST. To make sure the desired behaviour is achieved, SST needs to be appropriately configured. The SST simulation is configured using a ``config.py`` python file, which contains all components and connections between them. Main Classes ************ This section only provides a brief overview of classes in the SST-Core API which are fundamental to running a simulation in SST. For more information regarding the SST-Core API please check the official `SST-Core API documentation `_. SST::Component ~~~~~~~~~~~~~~ SST Component is a class in SST which represents any entity that takes in a clock from SST and performs an action on every clock tick. It is the main object for simulation and all models inherit from SST Component. Each component inside SST has to be registered with **SST-Core.** To find information about any component, the ``sst-info`` command can be used to display details such as configuration options, ports, etc. The output of the ``sst-info`` command can be filtered using the ``--libs`` flag. .. note:: All SST components can be instantiated and configured via the use of a ``config.py`` file. SST::SubComponent ~~~~~~~~~~~~~~~~~ SubComponent is a class loadable through the ``SST::Factory`` class which allows dynamic functionality to be added to a Component. The SubComponent API is nearly identical to the Component API and all the calls are forwarded to the parent Component. SubComponents are always attached to Components via slots and communicate with the component via the same. SST::Link ~~~~~~~~~ Links in SST are used to establish communication between two SST components. Links are attached to SST components at ports. These ports are defined for each Component and are documented via the registration ``MACROS`` provided by SST. SST Memory Model **************** .. image:: ../assets/sst_mem_model.png :alt: SST Memory Model :align: center This section describes details about components that are fundamental to the SST memory model and required for configuring a SST simulation. Each of the components mentioned here has configuration parameters which need to be specified in order for the SimEng SST simulation to work. .. note:: Some configuration parameters, ports and subcomponent slots necessary for understanding the memory model are not mentioned in this section. More information about configuration parameters and connecting components through ports and subcomponents slots will be provided in :ref:`Running SimEng with SST.` SimEng Core ~~~~~~~~~~~~ For the SST simulation, the actual SimEng core is instantiated in a wrapper class and registered as a custom SST component, so it can receive clock ticks from SST. This component is called ``SimengCore``. StandardMem ~~~~~~~~~~~~ ``StandardMem`` is an interface defined in SST-Core present at the namespace ``SST::Interfaces::StandardMem``. This interface acts as an entry point between the SimEng core and SST’s memory model. Memory requests are generated by the SimEng core in the form of class  ``SST::Interfaces::StandardMem::Request`` objects, and then given to the interface class via function calls. The interface class then translates the memory requests into memory event objects that are internally used by the memory hierarchy. When a response event is received from the SST memory model, the interface class finds the matching request object, generates a response object of class ``SST::Interfaces::StandardMem::Response`` and returns it to the SimEng core via a callback function. StandardInterface ~~~~~~~~~~~~~~~~~~ ``StandardInterface`` is a subcomponent which implements the ``StandardMem`` interface. It is present in the ``memHierarchy`` module and needs to be configured before the simulation starts. ``StandardInterface`` is instantiated as a subcomponent of the SimEng core. ``SimengCore`` uses ``StandardInterface`` for communicating memory requests. The ``StandardInterface`` component communicates with the SimEng core using the port ``port``. The same port is used to communicate with the highest-level component in the memory hierarchy. Communication with memory components can also be established using the subcomponent slot ``cpulink``. Configuration details about ``StandardInterface`` can be found using the command: ``sst-info memHierarchy.standardInterface`` Cache ~~~~~~ Because of its size and complexity, the implementation of Cache simulation in SST is divided over multiple files. However, the ``CacheController`` class is the main contact during simulation. The ``CacheController`` class is aliased as **Cache** in SST. Caches in SST communicate through ports ``low_network_0`` and ``high_network_0``. The ``high_network_0`` port is used to connect to either the SimEng core (via ``StandardMem`` interface) or to higher levels of cache, whereas the ``low_network_0`` port is used to connect to lower levels of cache or the main memory of the SST memory model. The Cache component also has some subcomponent slots (``memlink`` and ``cpulink``) which can be used instead of ports to establish communication as well. Information about different configuration parameters, ports and subcomponent slots required for simulation can be found using the command: ``sst-info memHierarchy.Cache`` MemoryController ~~~~~~~~~~~~~~~~~ The ``MemoryController`` class implements the memory controller interface. The memory controller object sits between the last level cache and the memory backend and it serves as an entry point for accessing the main memory. It is a SubComponent slot called ``backendConverter`` which stores a reference to the backend convertor object that is responsible for translating between memory hierarchy’s event type and the backend’s event type. The memory controller object is derived from the ``Component`` class, meaning that it can be instantiated in the configuration file, and connected to the upper-level components. All memory requests to the main memory (e.g RAM) go through the ``MemoryController``. The controller object also serves as an upper-level container for other memory-related components. These related components are loaded into subcomponent slots. Its ``backend`` slot stores a reference to the memory backend that implements the timing of the main memory. Its ``cpulink`` slot stores a reference to the memory link object (either a direct link or a network-on-chip endpoint) that the controller uses to communicate with upper-level components in the memory hierarchy. However, instead of using the ``cpulink`` slot, the controller can also communicate with higher memory components through the ``direct_link`` port. In addition, the ``backendConvertor`` slot stores a reference to a memory backend convertor object which is responsible for converting memory events coming from the cache hierarchy to requests used by the memory backend. Information about the different configuration parameters, ports and subcomponent slots required for simulation can be found using the command: ``sst-info memHierarchy.MemController`` MemoryBackend ~~~~~~~~~~~~~~ The memory backend implements the timing model of the main memory. All memory backend implementations must inherit from the base abstract class ``MemBackend`` present in the file ``memBackend.h`` in the **SST-Elements** source code. Class ``MemBackend`` is an abstract class and hence cannot be directly instantiated. The abstract class inherits the ``SubComponent`` class and must be loaded into the slot of the memory controller, as we have already discussed above. All memory backend models defined in SST inherit one of the three abstract classes i.e ``SimpleMemBackend``, ``FlagMemBackend`` and ``ExtMemBackend``; All these abstract classes inherit the ``MemBackend`` abstract class and require a different kind of memory backend convertor. ``SimpleMemBackend`` requires a ``SimpleMemoryBackendConvertor`` specified as ``memHierarchy.simpleMemBackendConvertor``, ``FlagMemBackend`` requires a ``FlagMemBackendConvertor`` specified as ``memHierarchy.flagMemBackendConvertor`` and ``ExtMemBackend`` requires a ``ExtMemBackendConvertor`` specified as ``memHierarchy.extMemBackendConvertor``. Most of the memory timing models present inside SST inherit the ``SimpleMemBackend`` abstract class and SST provides a variety of memory backends to choose from e.g. ``memHierarchy.simpleMem``, ``memHierarchy.simpleDRAM``, etc. By default the ``MemoryController`` equips the ``backend`` SubComponent slot with ``memHierarchy.simpleMem`` and ``backendConvertor`` SubComponent slot with ``memHierarchy.simpleMemBackendConvertor``. Different memory backends and backend memory convertors can be specified in the configuration params for ``MemoryController``. The memory backend is the last level in the memory hierarchy and does not need to connect to any component further down.