View Full Version : Passing constraints to randomize() in items
mleino
03-06-2009, 09:39 AM
So I've been told by the project that some sort of "exact" input is also appreciated for some test cases. In our case, one way of doing this would be to have configuration objects in the test.sv, objects having structs with arrays as members. These objects need of course be obtained by the sequences (by p_sequencer.get_config_object), and then these constraints will need to be identified as constraints per transaction member, which of course are the same as those located in the configuration object (?).
Now the problem is that using either structs or arrays as such result in compile errors, and identifying the constraints one by one (e.g. ovm_do_with( xxx...; tr_item.struct.data[0] == conf_item.struct.data[0] ,xxx) will result in randomization failures.
Could someone point out a way to use arrays or such to constraint randomizable data within transactions, any alternative ways to accomplish complex constraining, or direct faults in the way above?
Marko
Marko,
Not clear from the question what you are constraining so this
answer is necessarily generic. Feel free to contact me with
more specific questions.
What it sounds like is that you need to construct an array with
some, or all, specific data embedded in it. This is most often
accomplished through the 'foreach' constraint. Here is a small
example.
class rand_trans extends ovm_sequence_item;
rand unsigned int length;
rand logic [7:0] payload[];
function new( input string name = "rand_trans",
ovm_sequence_base sequencer = null,
ovm_sequence parent_seq = null);
super.new(name_sequencer, parent_seq);
endfunction
constraint size_payload {
payload.size() == length;
}
`ovm_object_utils_begin(rand_trans)
`ovm_field_int (length, OVM_ALL_ON)
`ovm_field_array_int(payload, OVM_ALL_ON)
`ovm_object_utils_end
endclass
class fill_array extends ovm_sequence;
`ovm_sequence_utils(fill_array, ovm_master_sequencer)
rand_trans this_trans;
logic [7:0] this_payload[$]; // this will hold the specific data
int unsigned this_length;
function new(string name = "this_trans");
super.new(name);
endfunction
task pre_body();
//fill this_payload here, assign this_length
endtask
task body();
`ovm_do_with( this_trans,
{ length == this_length;
foreach (payload[j])
payload[j] == this_payload[j];
}) // this will fill payload with this_payload
endtask
endclass
This will fill your trans .payload array with specific data.
JPK
mleino
03-08-2009, 03:36 PM
OK, thanks for the example. Maybe this points out 2 minor problems in my using the OVM:
1) Seems to be I'm not as familiar with all the built-in phase functions & tasks as I should be
2) Perhaps constraining the contents in the sequence_item is not always the best thing to do. It is perhaps just my thinking that things could or should be accomplished this way.
Nevertheless, the error messages I got were, in my opinion, a bit strange (Questa 6.5), as it makes no sense that some constraint types or perhaps even instances/lines give error messages, whereas some don't.
Marko
adityar
03-18-2009, 12:02 AM
I have faced randomization failures when using ovm_do.
especially if you want to turn off/on randomization of item variables depending on the requirements
I would take the same example as JPK, but i want to give a default value for a variable, for example length. Say I would want length to 8 as default, ie., if by using ovm_do, the length would always be 8.
then I would have to constrain length to 8
//--------------------------------------------------------
class rand_trans extends ovm_sequence_item;
rand unsigned int length;
rand logic [7:0] payload[];
//>>
constraint con_length {
length == 8;
}
//<<
endclass
>>
class fill_array_const_length extends ovm_sequence;
`ovm_sequence_utils(fill_array, ovm_master_sequencer)
rand_trans this_trans;
logic [7:0] this_payload[$]; // this will hold the specific data
function new(string name = "this_trans");
super.new(name);
endfunction
task pre_body();
//fill this_payload here
endtask
task body();
//Note here length is not constrained(assigned)
`ovm_do_with( this_trans,
{
foreach (payload[j])
payload[j] == this_payload[j];
}) // this will fill payload with this_payload
endtask
endclass
<<
//--------------------------------------------------------
but under a different circumstance i would need length to be randomized automatically.
//--------------------------------------------------------
class fill_array_rand extends ovm_sequence;
`ovm_sequence_utils(fill_array, ovm_master_sequencer)
rand_trans this_trans;
logic [7:0] this_payload[$]; // this will hold the specific data
function new(string name = "this_trans");
super.new(name);
endfunction
task pre_body();
//fill this_payload here
endtask
task body();
//1) create trans object
`ovm_create(this_trans);
//2) Switch off default constraint for length
this_trans.con_length.constrain_mode(0);
//3) call ovm_rand_send_with
`ovm_rand_send_with( this_trans,
{
foreach (payload[j])
payload[j] == this_payload[j];
}) // this will fill payload with this_payload
endtask
endclass
<<
//--------------------------------------------------------
For more information on ovm_do, create, send, plz look into
ovm-2.0.1/src/macros/ovm_sequence_defines.svh
Powered by vBulletin™ Version 4.0.3 Copyright © 2010 vBulletin Solutions, Inc. All rights reserved.