Why Is My Simulation So Slow?

The problem may have something to do with not understanding transaction-driven models.

popularity

By Jon McDonald
I am amazed how often simulation performance comes up when discussing SystemC and transaction-level modeling. Some of this I can understand. If you are new to transaction-level modeling the implications can take a while to get a handle on.

Fundamentally it is difficult to justify the investment in TLM if the models are not significantly simpler to write and significantly faster in simulation. Many times I’ve heard the complaint that the simulation is too slow and when I look closer at what is happening the problem is not in the SystemC simulation or the transaction-level concepts, but in the way the models are being written.

Today this came up from someone who had been using SystemC for quite a while to do what they thought of as transaction-level modeling. In looking at their example it struck me that most of the problems I see in users trying to move to the transaction level are caused by the fact that they don’t really understand what it means for the model to be driven by the transactions.

A simple example might help me articulate the point. Think of a timer that you program with a value and it counts down triggering an event at 0. One way I see this coded would be the following:

while (count != 0) {
count = count – 1;
wait (clock period); }
myevent.notify();

This is fairly simple but very inefficient and does not align with the transaction-driven concept of TLM. If you switch to a transaction-driven way of modeling you could write this as:

wait(clockperiod * count);
myevent.notify();

In the first example the cycles are counted to identify the point at which the action should be taken. In the second case the single wait is executed waiting the appropriate amount of time before the action is taken. This simple concept comes up over and over again when I look at new, and sometimes not so new, users creating what they think are transaction-level models.

In my mind the first case is not a transaction-level model; this snippet is really modeling the cycle by cycle activity of the model. All of that cycle activity is happening without any outside interaction, nothing comes in and nothing goes out, but the model is doing some work every cycle. In the second example the calculation is done to identify the time at which some action should be taken and the model simply waits for that long. There is no need to perform any of the cycle-by-cycle activity. The second approach is slightly simpler and significantly more efficient from a simulation perspective. I’ve seen examples where correcting this type of problem can take a simulation of a few hours down to a few minutes.

From what I’ve seen many of the complaints about simulation, performance of TLM-based SystemC designs can be addressed by fixing the models. If the models communicate with transactions and only send the transactions that need to be sent then the SystemC TLM approach can be comparable to a dedicated C/C++ model.

–Jon McDonald is a technical marketing engineer for the design and creation business at Mentor Graphics.