Jump to content

declarative vs procedural constraints


ash123

Recommended Posts

Hi Experts,

Do the declarative and procedural constraints in UVM work in tandem or is their some priority that the constraint solver takes into account ?

Please provide pointers to existing examples, if any.

Also, what is the suggested way of specifying constraints in UVM ? Any pros and cons of these two styles ?

Link to comment
Share on other sites

If by procedural constraints you mean the ones added by calling randomize() with {extra_constraints}, they work in tandem, or added, with the constraints declared in the class.

Although it is quick and easy to add constraints this way, in my opinion it is better to extend the class to be randomized with constraints you want to add or override with another class. If you need to override the constraints added procedurally using the with clause, you will have to extend the procedure with another class anyways.

Link to comment
Share on other sites

Hi dave_59 et al,

Thanks for your reply.

I tried experimenting with the following uvm sequence class:

class insn_sequence extends uvm_sequence #(insn);

insn items[20];

/* Declarative Style */

constraint no_branch {

foreach (items) {

!(items.kind

inside { insn::insn_branches_ds, instruction::insn_branches }

);

}

}

`uvm_sequence_utils(insn_sequence, instruction_sequencer)

virtual task body();

foreach(items)

begin

items = insn::type_id::create("req");

wait_for_grant();

assert(items.randomize());

send_request(items);

wait_for_item_done();

end

endtask

endclass

I noticed that the constraint 'no_branch' DOES NOT work at all. Could you see something obviously wrong in the above code.

However, when I specified the same constraint procedurally as below, it WORKED as desired!

class insn_sequence extends uvm_sequence #(insn);

insn items[20];

`uvm_sequence_utils(insn_sequence, instruction_sequencer)

virtual task body();

foreach(items)

begin

items = insn::type_id::create("req");

wait_for_grant();

assert(items.randomize() with {

!(items.kind

inside { insn::insn_branches_ds, insn::insn_branches }

);

});

send_request(items);

wait_for_item_done();

end

endtask

endclass

Could you please guide me on this ?

About the code: The uvm sequence class is generating instructions for a processor and the constraint is about not generating branch instructions.

Link to comment
Share on other sites

The reason the constraint 'no_branch' does not work is because that constraint belongs to an insn_sequence object, and you are calling randomize() on an insn object. You would need to put the no_branch constraint inside the insn class. Even better is to extend the insn class into another class with a no_branch constraint. Then either create that class directly, or use factory overrides for the construction of the insn class. That way you can represent a hierarchy of instruction sequences based on extensions to the insn base class.

BTW, the `uvm_sequence_utils macros was deprecated in UVM 1.1. Just use `uvm_object_utils to register a sequence with the factory.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...