How to identify type of a sequence in driver?

I am new to UVM. I have few implementation level questions
There are 2 ways of looking at the UVM testbench,

  1. Having a complex sequences + simple driver
  2. Having simple sequences + complex driver

I believe usually method 1 chosen for the reusability purpose as we might want to replace driver later.

With our present environment , We have a bfm(where all the core functions are written) + checker(has checker functions),
Simple validation test has following format:

//part of the testbench
initial begin
bfm.reset_block()
bfm.do_config();
bfm.enable_block();
checker.compare();
end

I thought of rewriting same validation with UVM environment. I understand the UVM environment and all the configurations to be made. I am facing lot of implementation level questions to see my approach as best industry practice or not for UVM…

If I decide to make sequences for all of them, i will have reset sequence, configuration sequence, enable sequence.
Following are my questions
1)How do identify the sequence as it’s a reset sequence ? Do I need to keep checking for reset signal in driver and redirect to reset task ? I will have many such tasks and I might want to redirect based on sequence. So should use additional variable like command which is set based on sequence and check for it later in driver ?
2)I don’t see sequences as complex . With my understanding, I will start the item , randomize and finish… I can not create any delays even for reset.
What is the meaning of reset sequence then ? Please direct me to an example code of test, sequence and driver with standard approach .

In reply to Varunshivashankar:

It looks like you are running only a few tests on your current environment using the steps in the initial block.
I do not know all the details of your design. But I beleive you have to have all these steps in eaach of your sequences, assuming the DUT needs to be initialised (reset), configured, enabled and executed with checking.
The driver is implementing the protocol of your functional interface, polling a sequence item from the sequencer, processing this item and optionally generating a response and pass it back to the sequence. Where the quecking will happen depends on your design. It might be in the sequnce or you need a scoreboard.

In reply to Varunshivashankar:

1.) I haven’t done it, but you can get the sequence name from the sequence item (see uvm_sequence_item.get_parent_sequence() and .get_full_name() in Class Ref Manual). I think you are taking the wrong approach. It is not good to make the sequences complex, let the driver handle it (it’s only one component compared to many sequences). You can put anything (i.e. including switches to control the driver) in the uvm_sequence_item. Give the driver all the data and control that it needs to manage interaction with DUT. Every testbench is different and it is impossible (based on the info that you have provided) to say what is the best approach (i.e. how many agents you should have and what each agent is responsible for).

2.) Reset sequence could indicate to the ‘driver’ that it should assert reset for N cycles, where N could be randomized in the sequence. You may consider a separate reset agent if that makes it easier to control (e.g. asserting reset why other drivers are active).

In reply to dhserfer:

I’m not sure what you mean with ‘complex driver’. But the driver has to implement the pin behavior of its pinlevel interface, i.e. bus/interface protocol. It takes a sequence item and provides the data to this interface. Optional it might generate a rsp and give this baack to the sequnence. Sequnces define how the sequence items will be generated. A sequence mighht consist of other sequences, like reset or a config sequence. In special cases you might even implement checker functionality. Because the sequence is on the transaction level it is easy to handle. It does not know anything about clock and timimg. The only scheme is the order of the execution of sub-sequences or sequence items.

In reply to chr_sue:

I am clarifying by questions:
Driver is one which converts the inputs into pin wiggles. I have all tasks(with suitable pin wiggling format) for my design. I have to call those tasks based on the sequence. Tasks can be reset task or scan in task or scan out task etc… I have decide which task to call based on the sequence items

For example
If I want to do reset, following is the order of that things follow

a)set the reset signal 1 in the sequence.
b) Driver receives the sequence items. Now I need to interpret the received sequence item so that I call reset task so that reset signal is sent in required protocol. I implemented this by adding new sequence item called command whose value is set based on the sequence. In this case command=“RESET_SEQ”. Based on the received command, I call suitable tasks

Questions:

  1. is the above approach ok ? is this the normal way of communicating between driver and sequences ? I can figure out the number of agents or any thing needed for the environment.
    2)Other than randomizing the inputs in the required fashion , are there any advantages of defining new sequences ? I understand that sequences are portable and other advantages of laying the sequences etc

In reply to Varunshivashankar:

What I’m recommending is:
You should define for any of your BFM tasks seperate sequences:
bfm.reset_block() - reset_seq
bfm.do_config() - config_seq
bfm.enable_block() - enable_block_seq
checker.compare() - compare_seq

They can be executed in the same order as you do with your BFM tasks.
But I guess you need more than one config_seq compare_seq, because you want to verify different aspects of your design.

If you ha a simple asynchronous rest in your design you might not need a seperate reset_seq. Instead have a data filed like has_rest in your sequence item.

In reply to chr_sue:

In reply to dhserfer:

Thanks for the response. It was really helpful. Also following link gave me very good idea about actual implementation.

https://verificationacademy.com/cookbook/cookbook-code-examples