SystemC goes well beyond generic C and C++ to provide a number of semantic constructs that are essential for system-level modeling, design and verification. Among the most powerful of these are threading and concurrency. Using threading is required in order to represent concurrent systems, whether for modeling a system-on-chip, or creating a verification environment with concurrent sequences streaming across multiple interfaces.
But with this power comes responsibility. Threading, when used incorrectly or beyond a modest level of complexity, can quickly become a challenge to debug when things do not behave as expected. Thread debugging tools are needed in these situations. Thread debugging can also be an important analysis tool when working with and attempting to understand code that has been written by other engineers, who may be from other organizations or otherwise unavailable.
Standard command line debuggers such as GDB provide only basic support for thread debugging. The sequential text interface is not a natural representation of the concurrent distributed nature of a threaded system. Such debuggers also do not recognize or natively support SystemC and SystemC threads.
What is needed is a debug environment that understands SystemC threads natively, and can display the concurrent activity in detail to clearly let you see exactly what is going on in your design. Incisive simulation and debugging has multiple ways in which it simplifies thread analysis and debug.
In a typical system model or testbench you have a set of SystemC modules which are producing, processing or consuming data. This is true whether it is a model of a multi-channel network switch, or a testbench driving and monitoring multiple interfaces to a system-level design. Each module may have one or more SystemC threads that respond to data and events from other modules in the design. In analyzing such a design, questions that typically arise include:
Why did one thread respond before another?
- Did a particular thread respond when expected? or not at all?
To what extent does the design behavior depend on the specific order in which threads respond?
To try to begin to answer some of these questions, you could try source line debugging, by setting breakpoints and stepping through them, or stepping line by line, watching for where threads drive data or trigger events and then stepping through until you catch where other threads respond. But unless you know exactly which locations to set breakpoints on and can jump between them, this can quickly become tedious, and even disorienting as you bounce around levels of function calls and multiple source files. It also would require you to know more about your design up front than may be reasonable, especially if someone else wrote a significant part of the code.
Another option is to use Incisive debugging to set process probes on individual SystemC threads. This will allow you to see thread process activity in the Waveform Viewer, alongside signal and transaction probe activity. This is useful, but in the case where you don't yet know which thread is activating just prior to a critical value change or event triggering, you need to set many individual process probes on a set of threads in order to detect which one was active at the time of interest. In this case, it is more useful to have one action you can take to capture a set of thread activations, and still be able to zero in on the point of interest. The summary probe allows you to do this.
The summary probe lets you select not just a thread, but an entire design hierarchy scope level, and it will probe the activations of all threads in that scope. If the scope has multiple levels of hierarchy, you can choose to what depth you want it to descend to capture thread activity, or select "all" to get complete probing of threads under that scope.
To set the summary probe, first select the scope at which you wish to apply it. Then, in the SimVision debugging console window, at the ncsim simulator prompt, use this command:
probe -activations -depth all -waveform
The "-depth all" option is what selects threads in all levels of hierarchy under that scope.
When you apply the summary probe in Incisive and simulate your design, you will be able to see data activity alongside thread process activity in the SimVision Waveform Viewer, on the same timescale.
An example using this is where you have a design with multiple threads writing to the same channel or sc_export. You see a value change occurring which may be incorrect or at an unexpected time, but how do you quickly zero in on which thread wrote the value? Set a summary probe on the scope above the threads of interest and run through the simulation time of interest, then use SimVision to isolate the cause.
In SimVision, open the Waveform Viewer. Next, expand sequence time in order to see details of activity at the delta-cycle level, within a single simulation time step. Sequence time allows you to see events and data recorded to the waveform database, step-by-step, which gives you insight into causality and the ordering of event activity in your design.
In Figure 1, you can see that sequence time has been expanded at 30 ns. The waveform trace of the summary probe (labeled "_2_sc_summary"), shows that at time 30(1) ns (which is time 30 ns, step 1), the thread that is active at the Time A cursor is "scMain.Top.Producer.send_data". This is the send_data thread in the design scope scMain.Top.Producer. This thread is active beginning at time step 1 and ending at time step 2. Immediately after that, at time step 3, the waveform at the top for connect1 transitions its value from 101 to 102. From this information, and knowing that in this design data is written immediately on the next step, you know that the send_data thread is responsible for sending the new data value 102.
Figure 1 - Incisvie Enterprise Simulator debug window
A language such as SystemC with powerful constructs requires powerful debug tools and techniques in order to efficiently get to resolution on whether a given design is behaving as expected. In addition to the summary probe, there are many other SystemC and multi-language debugging features in Incisive that can speed this time to resolution.
For more information, please look at the IES SystemC Advanced Debugging Tutorial in your IES installation documentation. You can also find this tutorial by going to http://sourcelink.cadence.com/.
This Team ESL posting is provided by Michael WIlliamson, Product Engineer for the Cadence SystemC Simulation capabilities in the Incisive Enterprise Simulator.