Home > Community > Blogs > Functional Verification > performance aware e coding guidelines part 5
Login with a Cadence account.
Not a member yet?
Create a permanent login account to make interactions with Cadence more conveniennt.

Register | Membership benefits
Get email delivery of the Functional Verification blog (individual posts).


* Required Fields

Recipients email * (separate multiple addresses with commas)

Your name *

Your email *

Message *

Contact Us

* Required Fields
First Name *

Last Name *

Email *

Company / Institution *

Comments: *

Performance-Aware e Coding Guidelines – Part 5

Comments(5)Filed under: Functional Verification, OVM, IES, e, Specman, IEEE 1647, OVM e, events, IES-XL, tech tips, OVM-e, API, specman elite, performance, temporal expressions

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.


Happy coding!

Efrat Shneydor
Methodology R&D


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


By Mark Strickland on May 20, 2009
Could you post an example of how a unit that includes an @sim clock would be modified to use the synch unit approach?

By Efrat on May 24, 2009
hi, Mark,
We've seen environments in which, for example, each unit defines its own clock (which is defined @sim, connected to the RTL).
Such a clock can be defined once in the synch unit, and all other units shall use this clock event ("event clock is @monitor.qualified_clock").

By Avi Behar on May 28, 2009
Hi Efrat,
I guess Mark is asking about extending legacy environments, where @sim events are common, to take advantage of a new synch unit. I would guess this would be something on the lines of:
Legacy code:
event clk_e is rise(…)@sim;
New code:
!synch_p : synch_u; // use the connect_pointers() hook method of your environment’s
                                    // topmost (the one just under sys) unit to connect these pointers
event clk_e is only cycle@synch_p.clk_e;
I assume another option would be to use one-to-many event ports from the synch unit to the units that require these events, though I'm not sure if it's possible to overwrite an existing event with an event coming from an event port.

By ronen on February 23, 2010
regarding defining temporal events inside structs,
i just want to make sure that when i use on block inside a struct  for example
extend my_sequence {
    on started {
            message(LOW,"I'm here");
it's not implemented with TE which my cause to problems in GC of this struct.

By Efrat on February 24, 2010
hi, Ronen,
Your assumption is correct.
"on event" is just like a method. It's not a TE.
No performance penalties.

Leave a Comment

E-mail (will not be published)
 I have read and agree to the Terms of use and Community Guidelines.
Community Guidelines
The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.