Hi everyone!
When I try to run a UVM platform,I meet a error after the ‘vsim’ command,the prompt message as follow:
** Error: (vsim-7020) my_case0.sv(14): Illegal attempt to resize random dynamic array ‘$rand.pload’ to 1322392965 elements. (SolveArrayResizeMax=2000)
But I still can get the expect result,I am wondering wheather the error has adverse effect and how to correct it.Thank you!
Here is my 'my_case0’code:
class case0_sequence extends uvm_sequence #(my_transaction);
my_transaction m_trans;
function new(string name= "case0_sequence");
super.new(name);
endfunction
virtual task body();
if(starting_phase != null)
starting_phase.raise_objection(this);
repeat (10) begin
`uvm_do(m_trans)
end
#100;
if(starting_phase != null)
starting_phase.drop_objection(this);
endtask
`uvm_object_utils(case0_sequence)
endclass
class my_case0 extends base_test;
function new(string name = "my_case0", uvm_component parent = null);
super.new(name,parent);
endfunction
extern virtual function void build_phase(uvm_phase phase);
`uvm_component_utils(my_case0)
endclass
function void my_case0::build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(uvm_object_wrapper)::set(this,
"env.i_agt.sqr.main_phase",
"default_sequence",
case0_sequence::type_id::get());
endfunction
Thank you very much!Yes,I have used a dynamic array.But I don’t think the constrained the size of the dynamic array is wrong.Here is my 'my_transaction’module.Could you please help me check it?
class my_transaction extends uvm_sequence_item;
rand bit[47:0] dmac;
rand bit[47:0] smac;
rand bit[15:0] ether_type;
rand byte pload[];
rand bit[31:0] crc;
constraint pload_cons{
pload.size>=46;
pload.size<=1500;
}
function bit [31:0] calc_crc();
return 32'h0;
endfunction
function void post_randomize();
crc=calc_crc;
endfunction
`uvm_object_utils_begin(my_transaction) //fulfill the factory login of my_transaction
`uvm_field_int(dmac,UVM_ALL_ON)
`uvm_field_int(smac,UVM_ALL_ON)
`uvm_field_int(ether_type,UVM_ALL_ON)
`uvm_field_array_int(pload,UVM_ALL_ON)
`uvm_field_int(crc,UVM_ALL_ON)
`uvm_object_utils_end
function new(string name="my_transaction");
super.new();
endfunction
endclass
Hi xcxfly,
I see only two errors. This is the missing argument when calling the constructor of the parent/super class and you have to construct the dynamic array in the constructor.
Using the built-in function with/without brackets () should not be an issue. But this might depend on the simulator. Questa is accepting both. Your constraints are also correct. basheer55 is recommending only a one line constraint. It looks smarter.
But having the constraint inside the transaction is not a good coding style. Then you do not really need a dynamic array. rand byte [46:1500] is more or less the same.
Another question: why you are using the uvm_field macros?
Hi,the first issue have been solved as your method.Thank you!
But I still don’t understand the second issue.How to pass the argument?Could you describe it in detail?
Thank you for your reply!
I know little about the argument when calling the constructor of the parent/super class because I just started learning.
Using the uvm_field macros because I need to login ‘my_transaction’ into the factory,in order to use some in-build function.
The second issue is not actually causing the error you were having.
It is actually a guideline and if you don’t propagate the name of the constructor to the super class’s constructor.
Then when you create a my_transaction’s instance with different name, it will not take effect.
With your earlier code (name was not propagated):
my_transaction item;
item = my_transaction::type_id::create("item");
`uvm_info(get_type_name(), item.get_name, UVM_MEDIUM) // displays as uvm_sequence_item in log file.
With my suggested fix:
my_transaction item;
item = my_transaction::type_id::create("item");
`uvm_info(get_type_name(), item.get_name, UVM_MEDIUM) // displays as item in log file
constraint pload_cons{pload.size() == len;}
function new(string name="my_transaction");
super.new(name);
pload = new[len];
endfunction : new
Although this is perfectly legal you do not want to be initialising dynamic arrays in the constructor. Everytime you create a sequence_item you will allocate memory space.
The preferred solution is to randomize len according to the constraints, and then allocate space in post_randomise() instead of new(). This allows you much greater flexibiilty when creating and populating the sequencE_item
I’m not sure if this is really working. But you can randomize len in pre_randomize() and construct pload with len. Then you’ll get pload also randomized when randomize is called.
Agreed you can, but for performance reasosn you don’t want to over subscribe .randomize() with massive amounts of data to randomize. Remember the constraints manager and randomize have a lot of code behind them
In this case, randomising len in randomize() gives you a simple number in one dimension. Then on post_randomize() initialise the array and file it with whatver ever data you need, including the really quick $urandom.