Last Updated: June 29, 2014
This post will provide an explanation on the SystemVerilog code itself. Please see Recipe for the class diagram.
Transactions
Jelly-Bean Transaction
The jelly_bean_transaction
class defines the jelly-bean recipe based on flavor, color, and other characteristics. It also has the property called taste
to hold the reaction of the jelly_bean_taster
(DUT) to the flavor. The relationship between the flavor and color is defined in the constraint block (line 12). For example, if the flavor is apple, the color must be red or green (not blue).
Update (April 2, 2014): In this example, we used so-called UVM field macros (lines 23 to 27) to save the effort of writing “do-hook” functions. I would recommend writing your own “do-hook” functions instead of using these macros once you become familiar with UVM. For more information, please see Field Macros and “Do” Hooks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | class jelly_bean_transaction extends uvm_sequence_item; typedef enum bit[2:0] { NO_FLAVOR, APPLE, BLUEBERRY, BUBBLE_GUM, CHOCOLATE } flavor_e; typedef enum bit[1:0] { RED, GREEN, BLUE } color_e; typedef enum bit[1:0] { UNKNOWN, YUMMY, YUCKY } taste_e; rand flavor_e flavor; rand color_e color; rand bit sugar_free; rand bit sour; taste_e taste; constraint flavor_color_con { flavor != NO_FLAVOR; flavor == APPLE -> color != BLUE; flavor == BLUEBERRY -> color == BLUE; } function new(string name = ""); super.new(name); endfunction: new `uvm_object_utils_begin(jelly_bean_transaction) `uvm_field_enum(flavor_e, flavor, UVM_ALL_ON) `uvm_field_enum(color_e, color, UVM_ALL_ON) `uvm_field_int(sugar_free, UVM_ALL_ON) `uvm_field_int(sour, UVM_ALL_ON) `uvm_field_enum(taste_e, taste, UVM_ALL_ON) `uvm_object_utils_end endclass: jelly_bean_transaction |
Sugar-Free Jelly Bean
The jelly_bean_transaction
class can be extended to various classes. For example, to create only sugar-free jelly beans, the child class can define the constraint as shown in line 4.
1 2 3 4 5 6 7 8 9 10 11 | class sugar_free_jelly_bean_transaction extends jelly_bean_transaction; `uvm_object_utils(sugar_free_jelly_bean_transaction) constraint sugar_free_con { sugar_free == 1; } function new(string name = ""); super.new(name); endfunction: new endclass: sugar_free_jelly_bean_transaction |
Sequences
One Jelly Bean
The sequence creates the recipes of the jelly beans being generated. The first sequence is the simplest, as it is designed to create a single jelly bean. The line 10 creates a single jelly-bean transaction (a recipe), then the line 12 randomizes the recipe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class one_jelly_bean_sequence extends uvm_sequence#(jelly_bean_transaction); `uvm_object_utils(one_jelly_bean_sequence) function new(string name = ""); super.new(name); endfunction: new task body(); jelly_bean_transaction jb_tx; jb_tx = jelly_bean_transaction::type_id::create(.name("jb_tx"), .contxt(get_full_name())); start_item(jb_tx); assert(jb_tx.randomize()); finish_item(jb_tx); endtask: body endclass: one_jelly_bean_sequence |
Same-Flavored Jelly Beans (Sequence of Transactions)
Now let’s create the multiple jelly beans of the same flavor. The number of jelly beans being created is specified with the class property called num_jelly_beans
. The line 4 constrains the num_jelly_beans
to be between 2 and 4. The line 14 creates a single jelly bean, and the line 15 randomizes its color and flavor. With this jelly bean as the standard, the line 18 creates jelly beans of the same flavor, as many as specified by the num_jelly_beans
. In-line constraint on the line 21 guarantees the same flavor to be generated.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | class same_flavored_jelly_beans_sequence extends uvm_sequence#(jelly_bean_transaction); rand int unsigned num_jelly_beans; // knob constraint num_jelly_beans_con { num_jelly_beans inside { [2:4] }; } function new(string name = ""); super.new(name); endfunction: new task body(); jelly_bean_transaction jb_tx; jelly_bean_transaction::flavor_e jb_flavor; jb_tx = jelly_bean_transaction::type_id::create(.name("jb_tx"), .contxt(get_full_name())); assert(jb_tx.randomize()); jb_flavor = jb_tx.flavor; repeat (num_jelly_beans) begin jb_tx = jelly_bean_transaction::type_id::create(.name("jb_tx"), .contxt(get_full_name())); start_item(jb_tx); assert(jb_tx.randomize() with { jb_tx.flavor == jb_flavor; }); finish_item(jb_tx); end endtask: body `uvm_object_utils_begin(same_flavored_jelly_beans_sequence) `uvm_field_int(num_jelly_beans, UVM_ALL_ON) `uvm_object_utils_end endclass: same_flavored_jelly_beans_sequence |
Gift-Boxed Jelly Beans (Sequence of Sequences)
The code below demonstrates how to create multiple-flavored jelly beans. The number of flavors is specified with the class property called num_jelly_bean_flavors
(line 2). On the 4th line, the sequence randomly picks two to three flavors. The main part of the sequence is the repeat
block (from the line 12), where a sequence of same_flavored_jelly_beans_sequence
s is created.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class gift_boxed_jelly_beans_sequence extends uvm_sequence#(jelly_bean_transaction); rand int unsigned num_jelly_bean_flavors; // knob constraint num_jelly_bean_flavors_con { num_jelly_bean_flavors inside { [2:3] }; } function new(string name = ""); super.new(name); endfunction: new task body(); same_flavored_jelly_beans_sequence jb_seq; repeat (num_jelly_bean_flavors) begin jb_seq = same_flavored_jelly_beans_sequence::type_id::create(.name("jb_seq"), .contxt(get_full_name())); assert(jb_seq.randomize()); jb_seq.start(.sequencer(m_sequencer), .parent_sequence(this)); end endtask: body `uvm_object_utils_begin(gift_boxed_jelly_beans_sequence) `uvm_field_int(num_jelly_bean_flavors, UVM_ALL_ON) `uvm_object_utils_end endclass: gift_boxed_jelly_beans_sequence |
This post has an emphasis on the transactions and sequences in the jelly-bean verification environment. The next post will provide an explanation on the verification components.
This tutorial was very useful to me. Thank you so much for posting it.
Hello Keisuke,
Congratulations for these articles about UVM. I wonder if there is a reason why you do not use the uvm_do macro in your sequence.
Best regards,
Cedric
Hello Cedric,
I did not use the
`uvm_do
macro in case I needed fine control in the sequence.If you want fine control you can use `uvm_do_with or `uvm_do_on_with. Can you explain about what kind of fine control you are talking about ?
Hi Digesh,
For example, if you want to display the
jb_tx
just after you randomize it but before calling thefinish_item()
, then you might want to code like what I did, instead of using these macros. What I meant by “fine control” was anything beyond the macros provide.Hello keisuke,
i belive the UVM automation macro which you have used is for the components and not for sequence…It should have been `uvm_sequence_utils(sequence_name,sequencer_name)…………
Hello Shoaib,
I did not use the
`uvm_sequence_utils
macro because it has been deprecated from the UVM.Hello Shoib ,
I’m still not clear on the automation part . Can we discuss this further?
Very helpful seeing so many different examples. Not much on explanation, but that wasn’t my problem…I needed to see some understandable examples that made my understand of the explanations I have read elsewhere make sense. Thanks much for the posts!!!
I’m a bit new to uvm, what advantage does registering all of your fields for automation have.
i.e why not just use
‘uvm_object_utils(jelly_bean_transaction)
Hello Steve,
The
`uvm_field_*
macros automatically implement methods like copy and compare. But better approach would be creating your owndo_copy
anddo_compare
methods. Please see “do” Hooks for more detail.Ah I see, and understand.
Your examples are superb.
Would you consider adding in a reset, to demonstrate how a dut reset can be detected by transactors and passed to subscribers/scoreboards. This would include an elegant way of terminating an active sequence if one was running.
Keep up the good work
Steve
Though it might not directly answer your request, I have a plan to add a tutorial about UVM phasing.
Hello Shimizu-san,
Thank you very much for your great tutorial.
Could you please explain the advantage, application of implementing the “do” hooks for rand variables in sequence?
Because I think your example runs well without the implementation of “do” hooks ( use `uvm_object_utils(jelly_bean_transaction) as Steve already mentioned )
P.s about the advantage of “do” hooks in transaction class (sequence item) I already see but I’m not clear about advantage of “do” hooks in sequence.
Thank you very much
The benefits of using the “do” hooks over the field macro are more flexibility and much less overhead. I think the same benefits apply to sequences, too.
Your tutorial is very helpful. I have been studying SV and UV for the past couple of weeks and your tutorial has made a lot of the concepts start to “click”. Thank you very much.
Hi Keisuke, thanks for this tutorial. Can you please explain what m_sequencer is in “jb_seq.start(m_sequencer);”. It looks that m_sequencer is used to reference a default sequencer. In the case, the pkg has multiple sequencers, how do I specify a particular sequencer to be run?
Thanks!
Hi Kaushal,
Let’s say you created a
gift_boxed_jelly_beans_sequence
in your test as follows:Then, you start the sequence on a sequencer, say
jb_seqr
.The
start
task will set them_sequencer
to the sequencer you specified. In this case, them_sequencer
is set as thejb_env.jb_agent.jb_seqr
. In other words, the user of thegift_boxed_jelly_beans_sequence
class specifies them_sequencer
.[BEHIND THE SCENES]
Strictly speaking, the
start
task does not set them_sequencer
by itself. Instead, the task callsset_item_context()
function ofuvm_sequence_item
, which in turn callsset_sequencer()
function of the same class. Theset_sequencer()
is the function that actually sets them_sequencer
.Kaushal,
Still not clear. If start task set the m_sequencer to the one you specified, then in jb_seq.start(m_sequencer), m_sequencer is pointed to itself, m_sequencer ? This seems a dead loop. Can you help me on understanding this ?
The
m_sequencer
points to the sequencer thegift_boxed_jelly_beans_sequence
is running on. By callingjb_seq.start( m_sequencer )
, thejb_seq
uses the same sequencer as its parent sequence (gift_boxed_jelly_beans_sequence
) does. There is no loop. Am I making myself clear?I agree with Bo, you need to set somewhere a m_sequencer!=uvm_sequencer before using it. Maybe it is hidden somewhere a set_sequencer in your example that sets the default value of m_sequencer. If nothing is set, then i guess m_sequencer points to null.
Hi Keisuke,
I have a general question on UVM, Can you please explain the usage and importance of p_sequencer and m_sequencer in UVM??
Hi Vittal,
Each sequence has the
m_sequencer
property that points to the sequencer on which the sequence is running. Them_sequencer
can be used to access configuration information and other resources in the component hierarchy from the sequence.For example, if you start a sequence called
foo_sequence
on a sequencer calledbar_sequencer
,foo_sequence.start( bar_sequencer )
, then thestart()
task will assignfoo_sequence.m_sequencer
to be thebar_sequencer
. Now thefoo_sequence
can use them_sequencer
to access the component hierarchy. For example, you can get the full hierarchical name of the sequencer by callingm_sequencer.get_full_name()
. Note that the type of them_sequencer
isuvm_sequencer_base
. This means if you have your own sequencer and you have defined new properties in your sequencer, you cannot access them through them_sequencer
because it does not know them. Now thep_sequencer
comes to the rescue.The
p_sequencer
is instantiated if you use`uvm_declare_p_sequencer
macro in your sequence.For example, you can use the macro in the
foo_sequence
like this:The macro declares the
p_sequencer
using the sequencer type you provided (in this case,bar_sequencer_class
). Then the macro defines the function calledm_set_p_sequencer
which casts them_sequencer
to thep_sequencer
. Now you can access the properties defined in thebar_sequencer_class
through thep_sequencer
likep_sequencer.my_property
from inside thebody
task of thefoo_sequence
.Let me know if you have further questions.
Thanks a ton Keisuke, That was spot on and informative . I will ping you with fresh questions soon 😉
Thanks for clarifying my doubts about p and m sequences.
Hi Keisuke Shimizu,
I am new to UVM.I have a doubt ,can i have a p_sequencer in single agent,As you have told above that if we have own sequencer we can use p_sequencer.As my own sequencer will be extending from the uvm_sequencer class so it can have access to all configuration details .Then why p_sequencer is required.
Yes, once you have a handle to your own sequencer, you can access your own properties in it. The
p_sequencer
is the handle to your own sequencer from your sequence. For example,foo_sequence
accessesmy_property
inbar_sequencer
using thep_sequencer
handle as shown below.Thanks for the explanation Keisuke. One thing I’m not clear is, why are we writing a macro for p_sequencer in the sequence? Same thing can be done with “seqr_class_name hadnle_name”, and call handle name p_sequencer.
You could do that. Make sure you assign your
p_sequencer
before you callstart
, then.Thanks a lot for this thread of question and answer. It cleared my doubt.
I’m glad it was useful.
Simple and straightforward answer! Flowchart is a bonus 🙂
Hi,
What is the need to casting m_sequencer to p_sequencer, while both are pointing to same sequencer?
The type of
m_sequencer
isuvm_sequencer_base
, whereas the type ofp_sequencer
isbar_sequencer_class
in this case, which is a subclass ofuvm_sequencer_base
. You cannot assign the handle of base class to the handle of its subclass unless you cast it.Thanks alot Keisuke for basic understanding about m_sequence and p_sequencer
I have two agents and they both are working on different sequences i.e. seq1,seq2 which consumes different sequence item i.e. seq_item1,seq_item2,Now i want to start sequence (seq1) on sequencer-1(seqr1) and sequence-2 on sequencer-2 from test,could it possible like below:
Moreover,Inside both sequences task body,i am using `uvm_do_with macros (instead start_item etc.)
I am not able to start my sequence using above method could you please guide me on this front.
thanks
Your code looks fine. I assume you were able to start the sequences but the sequences did not finish. Does your driver call
item_done()
orput()
? The`uvm_do_with()
macro might be stuck atwait_for_item_done()
.Yes,item_done is there but that piece of code is not getting executed,but i am getting ‘fatal error: bad handle reference’ in test class(my_test).moreover, sequences are registered with uvm_object_utils and i am not using virtual sequence or sequencer.
kindly suggest forward path.
Something is wrong, but I am not sure what caused the fatal error. If you can post more lines of your code, I might be able to make a suggestion.
Where do you put “raise_objection” and “drop_objection” in your code?
The
raise_objection
and thedrop_objection
are used in therun_phase
function of thejelly_bean_test
class. Please see Tasting for more detail.sorry, Keisuke,
my question is for Vinod and maybe it is the reason his testbench can not run.
Tong
Hi Keisuke,
a little question about class same_flavored_jelly_beans_sequence :
” jelly_bean_transaction::flavor_e jb_flavor;”
is it correct? don’t need to declare flavor_e as static property in class jelly_bean_transaction ?
Tong
The
flavor_e
is a user-defined type defined in thejelly_bean_transaction
class. It is not a property of thejelly_bean_transaction
, so thestatic
is not necessary.Hello!
I noticed that in the section “Same-Flavored Jelly Beans”, inside of the repeat cycle, every time a new transaction is created, the methods start_item() and finish_item() are called in the code (lines 20 and 22) but before that, no start_item() and finish_item() were called for the single transaction. Why?
The lines 14 to 16 are used only for randomizing the flavor. Then, the line 21 uses this flavor in the in-line constraint so that all jelly beans have the same flavor. It is fine to “sandwich” the line 15 with
start_item()
andfinish_item()
as you mentioned. That will create(num_jelly_beans+1)
jelly beans, though.HI Keisuke,
In the Same-Flavored Jelly Beans example, you specified “The line 14 creates a single jelly bean, and the line 15 randomizes its color and flavor”. But in the transaction item there are other properties or types like taste, sugar free etc. defined as rand. Won’t they also get randomized.
Thank You in Advance..!
Yes, the line 15 randomizes all the properties of
jelly_bean_transaction
. The line 21 guarantees the same flavor, but other properties such as color are still randomized.Hi Keisuke,
I found this example very helpful and I will like to see some more complex sequence scenarios.
I am trying to build a AHB vip, just to get hold of the basics of UVM. I am finding difficulty in randomizing the various AHB protocol signals. For e.g, I can randomize HBURST type , HSIZE type and the starting address. But how do i randomize or create the HTRANS, HADDR for the same burst type. Based on the burst type, my HADDR values will change; similarly the HTRANS values. I am presently handling such things in the driver by generating a loop for the number of beat transfer as dictated by HBURST type. What will be the best way to handle this?
I think you are doing fine. You don’t need to randomize the HADDR for each beat because the driver can calculate the next HADDR based on the other information. For the HTRANS, you can also let the driver insert random BUSY cycles. However, this approach will not give you the controllability of the delays. I would create an array of BUSY cycles in the AHB transaction so that I can control the BUSY cycle of each beat. For example, you could have
rand int unsigned busy_cycles[];
in the transaction. You should also have a constraint for thebusy_cycles[]
so that you can have no BUSY-, some BUSY-, or many BUSY-cycle scenarios.Hello,
why are you using the start method within the sequence, I think its good to do that in test. Correct me if I am wrong
Regards
Shreemant
You can start another sequence from within a sequence. In this example,
jb_seq
is started using the same sequencer (m_sequencer
) that thegift_boxed_jelly_beans_sequence
is running on.In that code Shreemant mentions, you are doing a randomize too.
When you call the start on jb_seq, it’s the same_flavored_jelly_beans_sequence that executes, and it does the start_item, randomize, then finish_item. Why are you doing the randomize below, prior to jb_seq.start() if that’s done in the same_flavored_jelly_beans_sequence?
jb_seq.randomize()
randomizes thenum_jelly_beans
ofsame_flavored_jelly_beans_sequence
. Whereas thebody
task ofsame_flavored_jelly_beans_sequence
randomizesjelly_bean_transaction
s.Hi Keisuke,
I have question that the sequence same_flavored_jelly_beans_sequence is not register with any of the sequenceas there is no uvm_sequence_utils or uvm_object_utils so when the sequence start by calling jb_seq.start(.sequencer(m_sequencer), .parent_sequence(this)); on which sequencer will in be run will it run on the parent sequencer
If i want to run the sequence in a particular sequencer then I need to register with that particular sequencer in the sequence right ? please correct me it iam wrong
Thanks
Aditya
Hi Aditya,
same_flavored_jelly_beans_sequence
uses`uvm_object_utils
macros. Please see the lines 26 to 28.`uvm_object_utils
macro is nothing to do with registering the sequence to a sequencer. The macro registers thesame_flavored_jelly_beans_sequence
type with the UVM factory.same_flavored_jelly_beans_sequence
will be run on the same sequencer thegift_boxed_jelly_beans_sequence
runs on. Please see the diagram below.start()
. In the example below, the sequencerjb_env.jb_agent.jb_seqr
is used. Please see this article for how to start thegift_boxed_jelly_beans_sequence
.Hi kesuki,
Thanks for your tutorial and its very useful. If we are having our own sequencer where we have defined new properties then can we use the same m_sequencer – “jb.seq.start (m_sequencer)”?? Or we need to use p_sequencer ?? If we need to use p_sequencer then can you please tell us how to use that. Please correct me if I am wrong.
Thanks
Sharath
You can use the
m_sequencer
if you just want to start a sequence. But if you want to access the new properties, you need to use thep_sequencer
. Please see this answer for more detail.Hi Keisuke, i am new to UVM can u please explain .contxt(get_full_name()) what does this exactly mean ? Thank you
The
jelly_bean_transaction
is auvm_sequence_item
. That means it is auvm_object
, but not auvm_component
. Therefore it does not have a hierarchical name..contxt( get_full_name() )
specifies the context (hierarchical name) of thejelly_bean_transaction
. By specifying the context, we can override a specific instance ofjelly_bean_transaction
later. You can use any string as the context, but in ourone_jelly_bean_sequence
case, we used the return value of theget_full_name
function. Theget_full_name
function is defined in theuvm_sequence_item
class (an ancestor class of theone_jelly_bean_sequence
), and it returns a string that concatenates the full name of the sequencer thisone_jelly_bean_sequence
was started on and the name of thisone_jelly_bean_sequence
instance.thanks Keisuke
Hi keisuke…
I am new to UVM…why sequence is required? I mean if the testcase is simple then driver and interface combination can solve my query…please help like how sequence and driver ia differentiated.
Traditional driver-BFMs use functions and tasks to drive DUT pins. One of the disadvantages of the BFMs is that it is not easy to randomize stimulus. UVM uses sequence objects as the scenario of stimulus. Since they are objects, it is easy to randomize and we often obtain interesting scenarios we have not thought of. UVM drivers get the sequences and converts them into pin-level activity.
Thanks Keisuke…Got it
Hi keisuke,
In jelly_bean_transaction, taste_e is declared so what is the use of that?
Since taste is decided by jelly_bean_taster. Correct me if I am wrong.
Regards,
Sharath H V
I just wanted to use a set of named values (
UNKNOWN
,YUMMY
, andYUCKY
) for the taste rather than using integer values (0, 1, and 2) for the purpose of clarity.Hi Keisuke,
Thank you so much for such a wonderful and detailed tutorial.
Can you tell me the difference between uvm_object_utils and uvm_component_utils. And how to decide which one to use where?
Thank you.
Both macros expand to define the utility functions for factory operation. If you are interested, please see Inside Candy Factory to look under the hood, although you don’t have to know the details. If your class extends
uvm_component
, then use`uvm_component_utils
, otherwise, use`uvm_object_utils
. For example, in our tutorial, we used`uvm_component_utils
forjelly_bean_test
,jelly_bean_env
,jelly_bean_agent
, andjelly_bean_driver
, which are sub-classes ofuvm_component
. On the other hand, we used`uvm_object_utils
forjelly_bean_transaction
and sequences, which areuvm_object
, but notuvm_component
.Can You please explain in detail the difference b/w `uvm_do macros with clear examples ?
All
`uvm_do*
macros call`uvm_do_on_pri_with
macro internally. The`uvm_do_on_pri_with
macro takes four arguments (SEQ_OR_ITEM, SEQR, PRIORITY, and CONSTRAINTS). Each`uvm_do*
macro specifies a subset of the arguments as follows:`uvm_do
m_sequencer
-1
{}
`uvm_do_with
m_sequencer
-1
`uvm_do_pri
m_sequencer
{}
`uvm_do_pri_with
m_sequencer
`uvm_do_on
-1
{}
`uvm_do_on_with
-1
`uvm_do_on_pri
{}
`uvm_do_on_pri_with
The
`uvm_do_on_pri_with
creates a SEQ_OR_ITEM, randomize it with CONSTRAINTS, and start it on the SEQR with specified PRIORITY.Hi Keisuke,
I have a question about the constraints.
say I have the following examples:
=============================
===============================
so when the simulation starts, the data_master in A_seq will be 1. is that correct?
thanks
Your
`uvm_do_with
macro does not constrain thedata_master
. Here is why. The`uvm_do_with
macro expands to arandomize()
function:The names in the in-lined constrait block are searched first in the scope of the
randomize() with
object class (A_seq
) followed by the scope containing the method call (B_seq
). This means bothdata_master
in the above constraint refer to the same variable in theA_seq
, so you do not constrain them. To solve this issue, you can uselocal::
scope resolution:This constrains the
data_master
ofa_seq
to be equal to the value ofdata_master
ofB_seq
.You can see the entire code here.
thanks, that makes me very clear now.
Best regards,
Steve
Hi Keisuke,
It means, I can write above code as below rather using of “local::scope”
a_seq.randomize() with { a_seq.data_master == this.data_master; };
Thanks
RSS
Or we can write like this ?
uvm_do_with (a_seq, {a_seq.data_master == this.data_master})
Thanks
RSS
No.
this
refers toa_seq
, so it doesn’t constrain thedata_master
.Thanks a lot. Now my doubts are clear.
I am new in uvm but after studying your articles and queries making me confident daily.
Hi Keisuke,
Do you know how to debug a test which is getting hung? I am trying one test but the test didn’t actually start running, it stuck at timestamp 0. Also there is no error messages in the NCSIM.
The above is the piece of message from the NCSIM.
thanks
Steve
Check if you have a zero-delay loop in the run_phase of your driver/monitor.
Hi Keisuke,
I read p sequencer and m sequencer concept, still i have not understanding can you please elaborate?
–Taahir
Hi Keisuke
I am still in doubt about the difference between m_sequencer and p_sequencer?
Can you give any specific example where both have their significance?
~Taahir
Have you read this conversation? Let me know if you need more clarification.
Yes Keisuke,i have gone through.
But i m still in doubt like what these sequencer are up to,one live example might?
Keisuke,
can you fix the link to “this conversation”
I have fixed the link. Thank you for pointing this out.
Hi Keisuke,
I have some doubt in same flavoured jelly beans,
In line 16, if you defined jb_flavor = jb_tx.flavor; then in line 21 why in constraint again you are defining -> with { jb_tx.flavor == jb_flavor; });
Can you explain about the 16 and 21 line in – > Same-Flavored Jelly Beans (Sequence of Transactions)
The line 19 creates a new
jelly_bean_transaction
object. This means that thejb_tx
on line 16 and thejb_tx
on line 21 refer different objects even though they have the same name. The line 21 constrains that the newly created object has the same flavor as thejb_tx
created on line 14.Hi Keisuke
I really enjoy learning from your code. I do have one question on gift_boxed_jelly_beans_sequence. I wonder, after repeating num_jelly_bean_flavors times, the jb_seq might produce same favor. I saw “randc flavor_e tmp_flavor” from complete src code, but it was not used in task body. how can we pass tmp_flavor to jb_seq, so that it will not get repeated flavors
Thanks
Scott
This is a good point. Although I am not sure where you get the
tmp_flavor
from (I cannot find it in my code), I created a new article about this issue. Hope it helps.Hi Keisuke,
Can you provide some details about uvm transaction recording with examples?
I wrote a new article about recording.
Thanks Keisuke for your new article.
Hello,
I’ve been struggling with a basic sequence problem: I have the following typical packages apb_pkg, env_pkg, seq_pkg, & test_pkg.
Package apb_pkg has all the code for the apb agent, in it I have sequence apb_io which has task read and virtual task body, also the sequencer is defined.
Package seq_pkg imports apb_pkg::* and extends apb_io to apb_io1 and defines body task which calls read.
The env package has the standard build and connect phase functions.
In test package is the extended uvm_test where instance of apb_io1 is defined, the build phase has its create & run phase has the instance of apb_io1 .start(sequencer).
When I simulate the above everything works fine, the read in apb_io1 executes as expected.
Now in seq_pkg if I change apb_io1 so that it extends uvm_sequence and I create a instance
apb_io ‘apb = new(apb);
and call apb.read in the body task, the code compiles but I get a fatal error:
“neither the item’s sequencer nor dedicated sequencer has been supplied to start item in apb”
I’m wondering if I need to use something called set_sequencer?
The reason I’m using an instance apb_io instead of extending apb_io is that I intend to create a instance of a different agent in apb_io1 sequence and perform calls to its methods. Is this methodology unworkable ?
Thanks for any guidance,
–Ross
I believe I need to change my apb_pkg sequence read and write tasks to make them stand alone class object including the sequencer_base.
How do you start the new
apb
sequence? Did you specify the sequencer when you callapb.start(sequencer)
?Hi,
In seq_pkg apb_io1 class I create a instance of the sequencer then in my uvm_test I assign the target sequencer, so I’m past my stated problem “neither the item’s sequencer …”
Currently debugging why the arguments are ‘x’ at the apb_pkg::apb_io.
Thank you,
–Ross
Hi,
I just wanted to execute body of sequence.
————————–
From testcase.sv
i am gettign this fatal error
1.I dont want to use seq.start(Sequencer);
Can i use seq.start(null)?If yes then how can i assign teh sequencer to that sequence?
I wanted to execute the body of sequence by taking utc_tb_sequencer as its p_sequencer
How can i do that?
Thanks in advance?
As far as I know, the
start
task always uses the given sequencer. So, if the sequencer isnull
, you get the fatal error when thestart_item
is called. I’m still not really clear why you don’t want to do like this:Hello sir,
You are really savior because I’m finding an easy way to learn verification and UVM.
I have 1 question: In your code you use some namespace “type_id” and “create” like below
jb_seq = same_flavored_jelly_beans_sequence::type_id::create(.name(“jb_seq”), .contxt(get_full_name()));
But I don’t know where to find the description about “type_id”. I mean in the website below mentions about “create” but not sure how do you know about “type_id”?
https://verificationacademy.com/verification-methodology-reference/uvm/docs_1.1d/html/
I can read UVM macros to find out but I wonder if we have documents about it or not?
This article explains the
type_id
in detail.Thank you very much. A lot of headache but I’ll try to get the most out of your articles.
Hi Keisuke,
Let’s say I modify your jelly_bean_transaction as such:
1. Let’s change flavor into a dynamic array (i.e. multi-flavor jelly bean)
2. Let’s add a property called “location” that’s of enum type. The location specifies which factory (let’s say you have multiple factories across the world) you are making your jelly bean at. The location will determine the number of flavors a single jelly bean can create in that location’s factory. For example, you have a factory at Los Angeles and at that factory only 3-flavor jelly beans are being made there.
3. From (2), the flavor dynamic array can now be created with size that matches the location.
Now my question is this:
If I was to use SystemVerilog without UVM, this is easy to implement because in my transaction class, I would have a constructor (i.e. new) that accept 1 argument called “location”. Why did I set the argument to be “location”? It is so I, as the user, can choose which location I want to test.
Within the constructor, I can have a case statement that checks the location and then allocate the appropriate size for the dynamic array accordingly.
So how would I implement this in UVM? I see that in uvm_object, the only argument that “new” accepts is “name”.
Thank you.
I would create a method,
set_location( location_e location )
and call it after I create a transaction because theuvm_object::new
does not take other arguments as you mentioned.Hi Keisuke,
Another question if I may.
I see that you have made a separate class for sugar-free jelly bean and in that class you have a single constraint. However, usually in a complex system, you might have tens or hundreds of these kind of “more restricted” class. In your example, you can apple-flavor-only jelly bean, blue-color-only jelly bean and so on… That basically means you’ll have tens or hundreds files for each type of special jelly bean you make.
To solve this case, I would usually make these variables (i.e. flavor, color, etc..) as command line variable. For example, +JELLY_BEAN_FLAVOR=APPLE. Correspondingly, in the sequence class, when you are randomizing the transaction using “randomize() with {}”, you can put if-statement to see if these command line arguments are set, and if set, you can constrain the flavor, color, etc… accordingly.
Is this how you would go about solving this too?
Thank you.
I agree using plusargs would be a convenient way to specify constraint knobs. I usually define the knobs in a transaction class itself so that the user of the class (a sequence, for example) does not have to use “
randomize() with {}
“. The reason I don’t use “randomize with
” is that we cannot override the constraints defined by “with
” as they are hard-coded. The following is what I would do for thejelly_bean_transaction
class to make it more controllable.Hi Keisuke,
For hierarchical sequences, what is the difference between starting the sub-sequence with any of the following methods? Is there any advantage of using one over the others?
You cannot start a sequence using
start_item
.`uvm_do( jb_seq )
and`uvm_do_on( jb_seq, m_sequencer )
are exactly the same. Both will execute`uvm_do_on_pri_with( jb_seq, m_sequencer, -1, {} )
. This macro creates a newjb_seq
object and randomize it before starting the sequence. Using the macro is concise if it does what you want to do.