P_sequencer, m_sequencer

What are these ?

(In a Different post regarding [get_/set_]config*, I was asked to use m_sequencer)

I looked at the Virtual Sequencer documentation there the `ovm_do_on is
pointing to sub_sequencer using p_sequencer…

Who sticks to M and Who goes to P ?

Where can I find documentation on these ?


You can look in to the source files to check …
what p_sequencer is pointing & m_sequencer is pointing.

m_sequencer and p_sequencer both point to the same thing (the sequencer on which the sequence is running). However, there are some important differences:

m_sequencer is a generic ovm_sequencer pointer. It will always exist for an ovm_sequence and is initialized when the sequence is started.

p_sequencer is a type specific sequencer pointer, created by registering the sequence to a sequencer using the ovm_sequence... macros. Being type specific, you will be able to access anything added to the sequencer (i.e. pointers to other sequencers, etc.). p_sequencer will not exist if the ovm_sequence… macros aren’t used.

It is recommended to not use the `ovm_sequence… macros since it creates an additional constraint on where the sequence may be executed. Therefor, m_sequencer is the recommended method to access items available only to a sequencer and not the sequence (i.e. get_config calls).

So if we create a custom sequencer that inherits from ovm_sequencer and has additional members that we need to access from a sequence, we need to $cast the m_sequencer pointer to the appropriate sequencer type in order to access those members?

If this is correct then, would doing this not tie the sequence to the sequencer in much the same way using the `ovm_sequence… macros does?

Ideally there would be nothing in the sequencer that the sequence requires. By using set_config/get_config, you should be able to pull everything into the sequence dynamically and make it independent of the sequencer.

While this isn’t always possible, it can make portability of the sequences easier.

With get_config being a member of ovm_component, does the sequence need to call m_sequencer.get_config_* to obtain access to the config space?

Yes. A sequence needs to use the get_config* methods of it’s sequencer (via m_sequencer.get_config*) as you mentioned.

In order for a sequence to access the items of the sequencer at any time, the macro
can be used, and can save the additionnal code, hassle and dangers of using the get_config().

Note that this macro is implicitly called by macro “`ovm_sequence_…”, … which only exists for the peculiar case of non parameterized sequences.
So if you use parameterized classes, this macro is very useful.

You should not be using the ovm_declare_p_sequencer macro in any user code. It is an internal OVM macro and is subject to change at any time.

The reason for using get_config() is so that the sequence is independent from having to be run on a specific sequencer type. If you create a dependency between a sequence and sequencer, you lose a significant amount of flexibility and reuse of your sequences.

You should not be using the ovm_declare_p_sequencer macro in any user code. It is an internal OVM macro and is subject to change at any time.

I disagree : OVM recommends the use of this macro in the condition I mentioned previously. It is written in the source code of file ovm_sequence_defines.svh - line 40

// MACRO: `ovm_declare_p_sequencer
// This macro is used to set up a specific sequencer type with the
// sequence type the macro is placed in. This macro is implicit in the
// <ovm_sequence_utils> macro, but may be used directly in cases when
// the sequence is not to be registered in the sequencer’s library.

Also, to reply your remark, note that calling “get_config()” in a sequence creates a dependency between sequence and sequencer : the arguments of get_config() being specific to the sequencer.
So I am afraid that the flexibility argument is invalid here.

I think that you shouldn’t use get_config() directly. If you can’t configure your environment without get_config(), it means your components have factory registration issues.
The purpose of set_config() and get_config() is to configure comnponents before they are created. Once they are, then I suppose common sense is to access variable “var” with “x=comp.var” rather than “x=comp.get_config(“var”)”. Not only is it common sense, but relying on get_config() is wrong in this case (the variable may have been updated many times, while the config space value is constant).

Also, further on the use of the “ovm_declare_p_sequencer” which you seem to not recommend : what other solution would you suggest to access “p_sequencer.func()” from a parameterized sequence rather than declaring the p_sequencer this way ?

You are correct about using the ovm_declare_p_sequencer() macro. I didn’t look close enough to validate the usage and you can use it if desired.

I am not sure how you think using get_config_() functions create a dependency on the current sequencer. All the parameters to the get_config_() functions have no relationship to the sequencer, and proper usage allows the user to target a specific sequencer as needed.

The statement ‘If you can’t configure your environment without get_config(), it means your components have factory registration issues.’ makes no sense. The whole purpose of using set_config_()/get_config_() is to allow a top down configuration with or without the factory. They are separate mechanisms which are independent of each other.

The flexibility of set_config()/get_config() also allows you to pass both configuration values as well as handles to current status objects as well. This flexibility allows your sequence to change behavior based on DUT configuration. By passively monitoring DUT configuration, your sequence can change dynamically even if the DUT is configured from outside the OVM environment.

As for functions existing in a sequencer, I would make a case that there should be no functions within a sequencer. While this isn’t absolute and there are always arguments for a specific instance, putting the functions in the sequence itself make them more portable.

I see your point, but I think that the recommendation should be to use set_config with care and not use get_config, and more generally be very very cautious with all these string-based constructs.
Such string based constructs (set/get_config, override_by_name…) are permissive. They indeed provide flexibility, and look nice on small test cases, but they turn a large, real-life env. maintained by several people into a minefield.

Here is 1 line code example :

Then a typo is mistakenly introduced (hard to spot !) :

The bugged code will compile and run. If the simulation completes normally, there is a warning. The regression may run for days before the problems arises, and then, spotting the issue takes a very long time.

Added to this is the run-time penalty. By instance, if “get_config()” is called, the whole config mapping data-base is potentially searched. Imagine if it is called for every sequence_item created, all the code does is browse the data base over and over, What a performance hit.

Anyway, I am not trying to deter people from using OVM, but there is an issue with these string-based constructs and they should be strengthened, so that issues like the one I showed should be caught immediately (compile-time or run-time=0ps).
Configurability shouldn’t be promoted at the expense of reliability.

I agree that there are several pitfalls which come with the current configuration mechanism. It does have some significant limitations which can hamstring large environments.

The UVM will introduce a new configuration mechanism designed to address these shortcomings.