UVM: Tests without sequence

This post is regarding an unadorned alternative for some straightforward tests in UVM. Lets begin talking about a recent scenario that I faced in a simple UVM test.

The test basically had multiple scenarios and scenario selection was randomized. Each scenario executes a single data traffic sequence and generates a different pulse on different interfaces.

Traditionally, in UVM, we would start the data traffic sequence and then some testcase specific sequence based on selected scenario. Some engineers would also prefer to add a selection/switching logic (bit or something) to testcase specific sequence itself.

The testcase specific sequence will eventually manipulate some fields in transaction class (in randomize with) and generate the required packet. Commonly, something like the following code would do the job.

// In test
task run_phase(uvm_phase phase);
phase.raise_objection(this);
// Start data sequence unconditionally
data_seq.start(some_env.seqr);


// propagate scenario information to interrupt sequence
case(scenario)
0: mytest_seq.v0 = 1; // send a pulse to databus0
1: mytest_seq.intr_databus1 = 1; // send a pulse to databus1
2: mytest_seq.intr_databus2 = 1; // send a pulse to databus2
endcase
mytest_seq.start(some_env.seqr);
phase.drop_objection(this);
endtask


// scenario selection bits in testcase sequence
bit intr_databus0,intr_databus1,intr_databus2;
task body();
tx = trans::type_id::create("tx");
start_item(tx);
if(intr_databus0)
tx.randomize() with {tx.interrupt_db0 == 1};
else if(intr_databus1)
tx.randomize() with {tx.interrupt_db1 == 1};
else if(intr_databus2)
tx.randomize() with {tx.interrupt_db2 == 1};
finish_item(tx);
endtask

This works fine and it causes no harm at all. But, sometimes the testcases are so simple that the sequence is never to be re-used. For example, a specific sequence for register read-write testcases. So, the testcase specific sequence becomes a redundant class for all the tests, except for the targeted test.

In order to avoid this, UVM provides a sequencer method known as execute_item to execute/drive a transaction directly to the driver without need of an extra sequence.

This sounds amazing. You don’t need to have a sequence to execute a particular scenario.

// In test
task run_phase(uvm_phase phase);
phase.raise_objection(this);
// Start data sequence unconditionally
data_seq.start(some_env.seqr);


// propagate scenario information to interrupt sequence
if(!tx.randomize() with {interrupt_db == scenario}) // interrupt_db made an array and scenario is one hot encoded.
begin
`uvm_error(get_type_name(),"Unable to randomize item");
end
some_env.seqr.execute_item(tx);
phase.drop_objection(this);
endtask

The execute_item task internally invokes start_item and finish_item tasks, setting a “this” (current sequencer on which execute_item is call-ed) as an item-executing sequencer.

Reading from UVM source code, following is the description of execute_item task:

This task allows the user to supply an item or sequence to the sequencer and have it be executed procedurally. The parent sequence for the item or sequence is a temporary sequence that is automatically created. There is no capability to retrieve responses. The sequencer will drop responses to items done using this interface.

Prototype: task uvm_sequencer_base::execute_item(uvm_sequence_item item);

This task maybe useful in some really very simple tests. For finer adjustments like delay and response-based scenarios etc., a sequence is still the most preferred entity.

One more advantage of this method comes into picture when you don’t want to call pre_start and post_start methods of any sequence. In general, any sequence’s start method has a call_pre_post bit which is used to bypass pre_body and post_body of that sequence. But there is nothing (as far as I know) to bypass pre_start and post_start methods. Using execute_item, all these methods can be bypassed due to built-in sequence creation.

I have created a small example in execute_item_task file (Just copy-paste the code in your sv file and run the code). Hope this might be useful.

– Sharvil

profile for sharvil111 at Stack Overflow, Q&A for professional and enthusiast programmers

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: