In this last segment of the series on performance-aware coding, allow me to share with you two tips on improving the performance of Temporals.
Temporals Performance Tip 1: Setup a "Synch Unit"
If you don't already use a synch unit - I recommend you setup one up now. Here's why: the synch unit contains ports connected to the device under test, and it defines events based on these ports. Thus, when working with very frequent events like clocks, instead of each and every unit having an @sim event (which will trigger many context switches between e and the HDL), all units should base their sampling events on the events defined in the synch unit.
Temporals Trick 2: Beware of Where You Define Them
Another recommendation for temporal expressions is to avoid defining them in data items. Typically, each verification environment contains a small number of units, and a very large number of structs. As such, the difference between having one temporal expression in a unit, e.g. the monitor, vs. having a similar expression in each and every data item - can be huge. Thus, instead of having the data items wait for specific events, just let the monitor and collector do their job. Specifically, when the monitor sees an event that affects the current data item(s) it should perform the required action, such as assigning values to some fields, notify the BFM to stop transmission, etc.
This same rule also goes for expect, which is similar to events. In general, when you avoid defining temporal expressions in the data item you save both CPU time and memory. This is because that as long as there are events in a struct, the given struct will not be cleaned by the memory garbage collector ("GC"). If the struct is waiting for an event, the GC cannot know whether this wait is important or not, it takes the safest path and leaves the struct there. Unfortunately, this can result in hundreds and thousands of useless structs, all waiting for events that will never happen. Thus I must repeat: avoid defining temporal expressions in data items.
As noted earlier in the series, if you are in the early stages of development it would be best to adopt all of these techniques as part of your regular coding style. But even if you are in maintenance or simple test writing stages, I believe it will be well worth the extra time to re-work and improve your environment. In either case, you might want to run Specman CPU and MEM profiler, before and after modifying the code - I believe you will like what you see.
Reference links to prior posts in this series:
Part 1 - Improving the performance of Lists
Part 2 - Memory savings from proper Base types extensions and using CONST fields
Part 3 - Knowing when to turn off the Generator
Part 4 - Using the new Sequence API to improve performance