Question on Directed Testing & OVM Concepts

We are trialing OVM in our FPGA development process and although we’ve read lots of material (OVM User Guide, OVM Cookbook, some of Step-By-Step-FV-w/SV&V) there’s still an aspect that is causing us some confusion.

We come from a background of heavy directed testing. Constrained random tests are interesting and we hope to use this soon, but to get started we want to move some of our directed tests into OVM. I know that OVM is not focused on directed testing, but I am led to believe it is possible.

Consider a packet-based bus interface. It’s fairly clear to me how one would use OVM to conduct random tests (packet length, gap, bursts, etc) on this interface. You’d use a sequencer to provide the bus driver with transactions describing each packet, and a monitor/scoreboard would oversee the activity and pass judgement on the test. The top-level test would configure the test-bench to use a particular sequence depending on the purpose of the test. A directed test in this case might be a custom-defined sequence item, set up to be used by the top-level test.

But what about the configuration of the DUT prior to these tests? Although not specifically a real “test”, it is highly directed. In our example, we have a CPU register interface that needs certain registers set before the packet bus can be used. Would it make sense to write a driver that accepts “register read” and “register write” transactions, and to construct small sequences of these transactions that configure various parts of the DUT? Then at the start of the test, before the packet bus sequencer is enabled, this configuration sequencer sends through all its config sequences to the CPU register interface driver?

Or would it make more sense to forget sequences and simply construct and send specific transactions to the driver directly from the top-level test?

Secondly, what about the situation where the DUT is capable of performing some of its own internal tests? In this situation, a register is written, some time elapses, and the result is read from another register. How would this be handled in OVM? The Scoreboard is watching register monitor transactions, looking for a did-it-work result, but it has no control over the test so how will it know when to look for a successful result transaction?

Or is the answer to create a higher level transaction that represents this entire process, and in turn spawns the register transactions? Then set the scoreboard to watch these higher level transactions. This seems to imply some sort of “directed test” component that knows how to convert these high level “internal test” sequence items into register read/write transactions.

I think the problem we have is “closing the loop” - we understand each component’s role and how they fit together. What we don’t quite understand is how everything is orchestrated. Where is the overall control? If the Scoreboard is responsible for determining whether the test succeeded or failed, but has no control over the running of the test, then how can such directed testing be made to work?

Ok, the first question is really the most important one. Let me rephrase it:

How are people handling static configuration of their DUT prior to CRV testing? For example, our DUT requires the setting of various registers via a CPU register interface.

Are you creating a “CPU interface driver” and using a library of configuration sequences?

Or are you creating a “CPU interface master” and explicitly sending it individual transactions to write registers?

Or have you created an abstraction and are simply sending abstract transactions (e.g. “configure for 100MHz”, or “Set interrupt flags for mode yellow”) that are decoded into specific register writes lower down?

Or are you directly accessing the CPU register interface at the top level of the test (either in-line or with a function or task)?

David,

You may want to look at [thread]928[/thread], or other similar posts.

In my opinion, using sequences is an all or nothing endeavor and the choice is independent of directed versus random testing methodology.

The OVM is certainly set up to facilitate random testing, but there is no requirement to ever call randomize() to be compliant with the OVM. Although we promote the use of random testing, the OVM class library doesn’t care and is not even aware if randomization has taken place (OK, for the pedantic user, there is a sequence arbitration mode that has a random setting). In general we recoommnd that you set up for random testing, and make a directed test as a special case where the constraints do not allow for random values.
Regarding to use sequences or not, the AVM, one of the predecessors to the OVM, did not have any kind of sequence mechanism, and that was fine many users. However, once you start using sequences, it’s hard to think of any other way of writing tests. It’s also difficult to coordinate communication between sequecne and non-sequence based stimulus generators.

Dave

This is a typical scenario and addressed in OVM through the use of sequences. There are many other ways also that you may find in forums.

I’d suggest to model your bus OVC such that it can be used to verify the interface (randomizing transaction properties such as address, data, direction, burst size, etc. and timing). A good example to follow is the xbus OVC packaged with the OVM library. Now you can write a directed sequence to constrain address, data, direction of the item to program the DUT with a set of do macro calls. You can also define variables in the sequences that can be used as knobs from a higher level to program the DUT in mode RED, BLUE or GREEN. This sequence is now reusable and can be used in directed or random test cases. It is a function of how the sequence call uses them.

You can use a virtual sequencer to first program your DUT registers then kick-off other I/O sequences that drive the DUT into interesting corner cases for that configuration or keep the test very random.

In short, the sequence mechanism allows you to create a directed test or a very random test and reuse the sequence in many tests.

You can look at an example of a complete testbench by downloading the INCISV92 release from downloads.cadence.com in the Incisive Verification Kit. We package a DUT with a complete verification environment that shows how you can configure the DUT and then send traffic on various I/Os using the virtual sequence concept that I described above.

Umer

You may want to look at [thread]9288[/thread], or other similar posts.

That link seems to take me nowhere unfortunately:>

No Thread specified. If you followed a valid link, please notify the administrator

In my opinion, using sequences is an all or nothing endeavor and the choice is independent of directed versus random testing methodology.

However, once you start using sequences, it’s hard to think of any other way of writing tests. It’s also difficult to coordinate communication between sequecne and non-sequence based stimulus generators.

Thank you very much for your reply. It is good to know that sequences are best used throughout, rather than here and there. I don’t think it would be too difficult to set up a collection of non-random sequences of register configuration data that can be used to set up the DUT prior to a test.

This is a typical scenario and addressed in OVM through the use of sequences.

You can use a virtual sequencer to first program your DUT registers then kick-off other I/O sequences that drive the DUT into interesting corner cases for that configuration or keep the test very random.

Thank you very much for your reply, Umer. It is good to hear that this is a legitimate use of sequences. Thanks also for the INCIS info.

Sorry, the correct link is [thread]928[/thread]

You can look at an example of a complete testbench by downloading the INCISV92 release from downloads.cadence.com in the Incisive Verification Kit.

Unfortunately I don’t seem to be able to access this repository, because I do not have a Cadence Host ID or Reference Key.

You can use a virtual sequencer to first program your DUT registers then kick-off other I/O sequences that drive the DUT into interesting corner cases for that configuration or keep the test very random.

I’m interested in knowing a bit more about how this would work - the examples that I’ve seen online and in textbooks indicates that multiple sequences are associated with a single sequencer, which is associated with a single driver. So that set of sequences is associated with just one driver. If you had a second driver then the associated sequences would be independent of the first’s sequences.

But what I think I’d really need to do is have one top-level sequence (that coordinates the configuration & I/O stages of the test) that can start up other sequences attached to multiple drivers.

For example, the top-level sequence might kick off a configuration sequence (for the CPU register driver), and when that’s finished kick off other sequences for the I/O drivers as the main part of the test.

Is this possible to do elegantly with OVM? This post seems to suggest it is:

http://www.ovmworld.org/forums/showpost.php?p=3507&postcount=1

Or would it be simpler to block all the I/O sequences until the configuration sequence raises some sort of global semaphore to indicate configuration is complete?

But what I think I’d really need to do is have one top-level sequence (that coordinates the configuration & I/O stages of the test) that can start up other sequences attached to multiple drivers.

I’ve discovered the Virtual Sequences section in the 2.0 User Guide, and yes it does appear possible for a VS to kick off sequences to multiple drivers.