Simics Modeling Extension
The Simics modeling extension is a collection of capabilities helping model developers to become more effective in implementing, debugging and testing Simics device models. It contains or will contain the following high level features:
- Simics project awareness
- DML-1.4 awareness (language server, linting, syntax highlighting and snippets)
- Mixed language debug sessions (debug Python and DML/C/C++ simultaneously)
- Simics Python awareness (Pylance has knowledge of Simics Python libraries)
This document gives an overview of the main features and functionality of the extension.
Requirements
There are a few requirements for running the Simics Modeling Extension.
- VS Code 1.85 or higher
- CMake based Simics project (for the full set of features provided by this extension)
- The Microsoft C/C++ Extension Pack
- The Microsoft Python Extension
- Simics 7.30.0 or higher for host Python usage (not required when using Python included with Simics)
- Host Python (version 3.12 or later) must be used for multi-threaded Python debugging
It's good to have an understanding of VS Code Workspaces and how debugging works in VS Code. It's also good to be familiarized with the CMake Tools Extension (included with the C/C++ Extension Pack).
Activation
The extension gets activated when either a Simics project is opened as a VS Code Workspace, or if a .dml file is opened even outside of a Simics project workspace. However, in order to get the full feature set of the extension, a Simics project must be opened as a VS Code Workspace. A Simics project is identified by finding .project-properties/project-version file. If no project is found, the extension cannot find the paths to Simics Base or any add-ons and a lot of the functionality of the extension will not work. The language server is started when a .dml file is opened.
DML 1.4 Awareness
The extension includes several helpful features for writing DML 1.4 code. This includes a DML language server, linting, syntax highlighting, and snippets.
DML Language Server (DLS)
The extension makes it convenient to write DML 1.4 based code with the help of the DLS, syntax highlighting and snippets. DLS provides powerful features such as Go to Definition, Go to references, syntax error messages in the editor, error messages for templates instantiated incorrectly, a configurable linter and more. The implementation of DLS resides in a separate repo. Feature requests and bug reports that are related to the language server should be submitted to the issue tracker of that repo.
Examples
Language Server Requirements
DLS is started automatically when a DML file is opened. For all of the features of the language server to work properly, a dml_compile_commands.json file must be generated (analogous to compile_commands.json which is frequently utilized by C/C++ language servers). A dml_compile_commands.json file can only be (automatically) generated for CMake based Simics projects. Thus, the full capabilities of the DLS are not supported for Makefile based Simics projects. For CMake based Simics projects, setting the CMake cache variable CMAKE_EXPORT_COMPILE_COMMANDS to 1,TRUE,On or ON during CMake configuration will ensure that a properly populated dml_compile_commands.json file is created and will be placed at the top level of the CMake build tree (also known as CMAKE_BINARY_DIR). Cache variables for CMake configuration can be set in different ways. When it comes to CMAKE_EXPORT_COMPILE_COMMANDS, the CMake Tools extension will automatically set it if configuring with no preset. If presets are used, it's worth setting up a preset that sets the CMAKE_EXPORT_COMPILE_COMMANDS cache variable:
{
"version": 2,
"configurePresets": [
{
"name": "debug-compile-commands",
"displayName": "Debug with compile_commands",
"inherits": [
"<an-existing-debug-preset>"
],
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "TRUE",
}
}
]
}
The extension needs to know the location of the dml_compile_commands.json file in order to propagate this information to DLS when it eventually launches it. This is automatically handled when using the CMake Tools Extension to configure the CMake based Simics project. If CMake is invoked in a CLI using cmake to configure/build the project, then the extension's simics-modeling.dls.compileInfoPath configuration parameter must be set to the absolute path of the dml_compile_commands.json file in the settings.json file of the VS Code Workspace. An example of this (where <cmake-binary-dir> is replaced by the relative path relative from Workspace Root directory to the top-level CMake build tree, commonly "build"):
{
"simics-modeling.dls.compileInfoPath": "${workspaceFolder}/<cmake-binary-dir>/dml_compile_commands.json"
}
Language Server Context
DLS operates on a device level scope. This means that to get the full functionality of DLS, a DML file that has a device declaration must be opened. After this has been done, all the language server features supported by DLS will work accordingly in other DML files as well that are imported by this device. For files that are not imported by any open 'device' file, only non-semantic information is available (such as syntax errors and linting feedback).
Linting
DLS supports linting which is configurable. There are sane default values for the linting configuration, but to customize it, set the simics-modeling.dls.lintCfgPath configuration parameter to the absolute path of the lint configuration file in the settings.json file of the VS Code Workspace. To disable linting, set the simics-modeling.dls.lintingEnabled to false.
Restarting the Language Server (Troubleshooting)
There's a command in the extension that restarts the Language Server. Use the keyboard shortcut F1 and start typing "Restart the DML language server".
Simics Python Awareness
The extension automatically adds applicable paths containing Simics Python libraries to the python.analysis.extraPaths parameter in settings.json so that the Python language server in VS Code, Pylance, can provide language server features for Python libraries provided by Simics. This simplifies writing unit tests and platform scripts in Python greatly. Simics normally automatically imports a number of packages and functions (such as simics and conf). This is not the case with Pylance, so code that references e.g. pre_conf objects in conf. or SIM_ functions will result in undefined variable errors reported. As a workaround you may import those packages explicitly and avoid using the bare SIM_ functions.
Debugging
The Simics Modeling Extension supports debugging Python and DML/C/C++ simultaneously. This can be very helpful to modelers who are writing their models in DML and the unit tests for the models in Python. The ability to have to have a debugger attached to both the test context and the device model context creates a powerful setup for debugging a device model. This can also be used to debug a model while running a platform, essentially debugging a model that is exercised by software running in a Simics target.
The type for the debuggers provided by this extension is simicsdbg. It has support for two requests, launch and attach. launch should be used when you want to start a debugging session by running a test or script. attach should be used when you have a Simics session already running, and you want to have a debugging session on that existing Simics process.
Requirements
The device models must have been built with debug information in order to debug them. This can be done by ensuring that the CMake cache variable CMAKE_BUILD_TYPE is set to Debug during CMake configuration of the Simics project.
Setup
The extension provides something called debug configurations. The launch.json file of the VS Code Workspace is populated with debug configurations to enable debugging within VS Code. An example of how to add the debug configurations provided by this extension to a VSCode Workspace is shown below.
Here we have populated the launch.json file with a simicsdbg launch debugger and a simicsdgb attach debugger. Note that the extension includes snippets for these debug configurations which automatically appear when you start typing in the launch.json file.
Taking a closer look at the configurations themselves, we see that the snippet for the launch configuration,
{
"name": "Simics Mixed Debug (Launch)",
"type": "simicsdbg",
"request": "launch",
"program": "${command:debugger.openFileIf}",
"ctest": {
"cmakeTestWorkingDirectory": "${cmake.testWorkingDirectory}",
"cmakeTestArgs": [
"${cmake.testArgs}"
]
}
}
has the program set to ${command:debugger.openFileIf}. This essentially means that debugging is started with this configuration (by for example pressing "F5" on the keyboard), a mixed language debug session will be started using the file among the editor tabs where the type cursor is. Such a file would typically be a unit test for a device model, or a script that would perhaps launch a Simics target. One can of course hard-code this field to the absolute path of say a unit test. The ctest ensures that this debug configuration can also be utilized when starting a debug session from the Test Explorer implementation of the CMake Tools Extension. An example of this can be found at Using the CMake Tools Test Explorer View.
The attach configuration,
{
"name": "Simics Mixed Debug (Attach)",
"type": "simicsdbg",
"request": "attach",
"processId": "${command:debugger.pickSimicsProcess}",
"internalConsoleOptions": "neverOpen"
}
has the processId field set to ${command:debugger.pickSimicsProcess}. When starting the debugger with this processId, a process picker that only shows active Simics processes will appear if there is at least one Simics process running on the host machine (should be Simics processes that are running the Simics executable found in the project). This makes it simple to attach to an existing Simics process for a mixed language debug session. This however only works when running the extension on Linux (including using the Remote - SSH extension). On Windows, the process picker will simply revert to the default VS Code process picker which shows all the processes running on the host.
Frame Filtering
The extension has a GDB frame filter which filters the call stack view in VS Code for the cppdbg debugger. This filter removes unnecessary frames from the call stack view and demangles some DML function names. This can be enabled by setting the enableFrameFilter parameter to true in debug configurations of type simicsdbg. Note that this is a preview feature and has in some scenarios resulted in debugging hanging when a breakpoint is hit.
Debug
The following section includes some examples of how a mixed language debug session can be started. Note that are more ways of actually triggering the start of a debug session rather than pressing the play button as done in some the examples. One can also press F5 on the keyboard to start a debugging session using the currently selected debug configuration in the "Run and Debug" tab of the VS Code Activity Bar. Another option is to press F1 and start typing "Select and Start Debugging".
launch Using Open File
Let's have a look at starting a mixed language debug session using the launch debug configuration that we added earlier. In the GIF below, note that we have added breakpoints in the unit test (s-sample-device.py) at line 30, and another breakpoint in the device model (sample-device-dml.dml) at line 51. Essentially we have breakpoint just before the unit test reads from register r1, and then have a breakpoint in the read implementation of the r1 register in the device model.
We can also use the Test Explorer implementation provided by the CMake Tools extension to start a mixed language debug session. It's important here to select the launch configuration when prompted to select a debug configuration.
attach
Here we show an example of where have started a Simics process in a CLI, and then we start a mixed language debug session by attaching to the process.
Notes
Note that hitting a breakpoint stops the Simics process and thus the simulation. The simulation cannot continue until the debugger continues from the breakpoint. Thus, it is not possible to interact with Simics (for example if the debugging session is of type attach), when the debugger is in a breakpoint.
Coverage
This section will show an example of how coverage can be displayed in the editor when using the CMake Tools extension in a Simics project. It's the CMake Tools extension that provides this functionality, but was in fact implemented in that extension by developers of this extension. To utilize this feature, version 1.20.52 or later of the CMake Tools extension is required.
Simics has a CMake Coverage module that can be added to CMake based Simics projects. Of course, one can build their own coverage infrastructure, but the module that is provided by Simics serves as a good starting point. Refer to the "Coverage with GCOV/LCOV" section of the CMake chapter in the Simics documentation for more details on how to use this in a Simics project. Assuming the Coverage module provided by Simics is utilized, in the settings.json file of the VS Code Workspace add the following configuration parameters:
"cmake.preRunCoverageTarget": "init-coverage",
"cmake.postRunCoverageTarget": "generate-coverage-report",
"cmake.coverageInfoFiles": [
"${workspaceFolder}/<cmake-binary-dir>/lcov.info"
]
To run tests in a mode that adds coverage related information to the editor, go to the Testing tab in the Activity Bar and using the CMake Tools Test Explorer implementation and press the "Run Test with Coverage" button.
Miscellaneous
The are some helpful commands that are provided by the extension.
Simics instance as an editor tab
The command "Start a new Simics Shell" will start a Simics instance and place it as an editor tab.