ash123 Posted December 30, 2011 Report Share Posted December 30, 2011 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 ? Quote Link to comment Share on other sites More sharing options...
dave_59 Posted January 2, 2012 Report Share Posted January 2, 2012 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. Quote Link to comment Share on other sites More sharing options...
ash123 Posted January 2, 2012 Author Report Share Posted January 2, 2012 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. Quote Link to comment Share on other sites More sharing options...
dave_59 Posted January 2, 2012 Report Share Posted January 2, 2012 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.