Debugging in simulation
For simulation we use Mentor's Questa Sim (formerly known as Modelsim), because Xilinx's xsim was deemed to be insufficient for the project, mainly because of random fatal errors with no further information when using SystemVerilog interface expressions. Other simulators from the 'top 3' should work as well: Synopsys VCS and Cadence Xcelium. To use these, just add appropriate configuration to the FuseSoC core file.
Prerequisites
The project uses Xilinx's IP. Xilinx's own simulator, xsim, links all of these automatically. However, we use a third-party simulator, Questa Sim, where we need to specify paths to those IPs manually. Sadly all of them are non-public, this means that you need to obtain them by yourself (by default all of them are included in Vivado installation) and edit paths in FuseSoC. Before proceeding, change all paths in xilinx_ip fileset in FuseSoC core file according to your installation. Don't commit these changes.
Running a simulation
To generate simulation configuration, we use FuseSoC. To run a unit testbench, use target with the name of the unit testbench you want to run (have a look at the wb_modules.core):
fusesoc run --target xpm_ram_tb wb-modules
This command will generate a project in build directory and run a simulation. The simulation will output a log to the console and to a transcript file. Also, waveform log will be produced, by default to a vsim.wlf file. This file contains logs of all static signals except memories and is viewable by using command vsim -view vsim.wlf. If you make any changes to the RTL when viewing the log, just relaunch FuseSoC and after the simulation finished, just click Refresh button in vsim; all data will be updated.
Debugging classes or memories
Note that no class variables (or memories) are logged to the waveform log, unless they are explicitly specified. Some of these are already specified in the FuseSoC core file. To specify more (or newly created classes) or memories, launch the GUI and find signal names. After that, you can continue to debug using the GUI or add the crafted log commands to the FuseSoC config for the signals to be always included in the wlf file.
To debug classes/memories with Questa Sim GUI, you need to:
1. (Only for class debugging.) Pass -classdebug to the vsim command. This is already passed by FuseSoC to the generated Makefile automatically.
2. Run Questa Sim manually via generated Makefile: enter the generated directory and run make run-gui.
3. In the GUI, look for the class type in the Structure window. Then, open Class Instances via View menu and select class instance. Select Add Wave in right click menu.
4. Class variables are still not logged: to log these, write log -class to the Transcript console and drag the class type to the console. Hit enter. Now restart and rerun the simulation, class variables of class instances of this type will be now logged.
Please note that when running Questa Sim GUI manually, no changes will be to the source RTL will be reflected until regenerating the project using FuseSoC and relaunching the Questa.
Notes about adding more objects to the log
By default, Questa does not log neither class variables nor memories. To do that in GUI, log <...> command is used in the Transcript console. It can be done also when using the CLI: you need to add one or more of these commands to the 'do' files or specify them directly in the -do argument. The second method is used in this project as well. Because FuseSoC allows to specify arbitrary extra command to be passed to vsim and Questa allows more -do arguments in a single invocation, we can misuse the FuseSoC's functionality to inject our own 'do' commands. This is perfect for configuring the simulator to our liking, such as adding more objects to be logged. Although this method can be fragile (change of Questa or FuseSoC will break it), it does not require any changes to FuseSoC or any manual copying to a project generated by FuseSoC. Also, this method allows way quicker debugging - on every change to RTL, you only need to recompile a relaunch simulation using FuseSoC and hit Refresh button in vsim viewer -- no need to relaunch Questa every time as is needed in interactive GUI sessions.