Passing array of PARAMAETERS to class handle in env

Hello,

I have PARAMETERIZED AGENT CLASS, whose multiple instances I will take in the environment, I need to pass different PARAMETERS to different agents.
I have an array of PARAMETERS, which I need to pass in the environment to multiple agents.
e.g PARAMETER ADDR_WIDTH [2:0] = {32,32,64};
PARAMETER DATA_WIDTH [2:0] = {32,32,64};
In env, delaring agent handle
abc_agent_c (ADDR_WIDTH,DATA_WIDTH) agent_h; (typically in env.svh)
How I can pass array of parameters to a single handle declaration. As I see cannot use genvar/for loop for same.
Do I have to define multiple agent handles & pass the array e.g abc_agent_c (ADDR_WIDTH[0],DATA_WIDTH[0]) agent_h_1;
abc_agent_c (ADDR_WIDTH[1],DATA_WIDTH[1]) agent_h_2;
Or is there some other workaround, please suggest.

In reply to deepa.djdoll:

You’re not going to like the answer, but unfortunately you can’t do this in a compact manner. You’re going to have to write each instance out:


abc_agent_c (ADDR_WIDTH[0],DATA_WIDTH[0]) agent_h_0;
abc_agent_c (ADDR_WIDTH[1],DATA_WIDTH[1]) agent_h_1; 
abc_agent_c (ADDR_WIDTH[2],DATA_WIDTH[2]) agent_h_2; 
// ...

In reply to Tudor Timi:

Thanks for your reply Tudor.

I moving ahead with this approach currently.

But, when I have delared e.g 5 Agent_handles.

  • Now I have a PARAMETERIZED AGENT CONFIG CLASS which I need to PASS to base sequence.
  • How I can provide this AGENT_CFG for each AGENT independently(e.g 1 sequence per AGENT_MASTER)?
  • I am able to provide the same to my “master_sequences” which is extended from “base_sequence” but unable to do the same for “base sequence” itself.

In reply to deepa.djdoll:

I don’t get what you mean by “provide the agent_cfg for each agent independently”.

In reply to Tudor Timi:

  • I have multiple agent handles H0,H1,H2,H3
  • I have an agent_cfg class which is used to configure different agents e.g H0,H1,H2,H3
  • I have base sequence which is extended from uvm_sequence
  • If I had a single agent e.g only H0, agent_cfg handle is passed to base sequence, so ideally base sequence captures the configuration and runs sequence for H0 only
  • Now I have multiple agents and I need to reuse same base sequence for multiple agents, How base sequence can bifurcate that the agent_cfg provided to me is for H0 or H1 or so…

In reply to deepa.djdoll:

Where does this base sequence of yours run? On which sequencer? Some agent sequencer or a virtual sequence that is connected to all four agents? Some code of what your doing might also be helpful.

In reply to Tudor Timi:

There is a parameterized packet data class that contains parameterized agent_cfg. This agent cfg is used to randomize few fields
inside packet class. So we want to pass this agent_cfg to each parameterized sequence that are given to each individual
parameterized master agent.For this we have single parameterized virtual sequencer which contains different parameterized physical master sequencers. Master sequencer contains agent_cfg handle. Master sequencer agent cfg handle has already been assigned,
master agent’s agent_cfg in our agent. So our sequencer gets the agent_cfg. We also have parameterized base sequence which
contains agent_cfg handle. And we have master sequence that is extended from base sequence.
So our issue is how to pass agent cfg to base sequence and master sequence??

e.g-
Virtual Sequencer
class multi_master_slave_virtual_sequencer#(int DATA_BUS_WIDTH=32, int ADDR_BUS_WIDTH=32 , int NUM_OF_MASTER = 2, int NUM_OF_SLAVE = 2) extends uvm_sequencer #();

master_sequencer #(write_data_cls#(DATA_BUS_WIDTH,ADDR_BUS_WIDTH),DATA_BUS_WIDTH[0],ADDR_BUS_WIDTH[0]) write_addr_ch_sqr_0 ;
master_sequencer #(write_data_cls#(DATA_BUS_WIDTH,ADDR_BUS_WIDTH),DATA_BUS_WIDTH[1],ADDR_BUS_WIDTH[1]) write_data_ch_sqr_1 ;
endclass

class base_sequence #(int DATA_BUS_WIDTH=32,int ADDR_BUS_WIDTH=32) extends uvm_sequence#(abc_data);
agent_config_c #(DATA_BUS_WIDTH,ADDR_BUS_WIDTH) agent_cfg;
rand bit [ADDR_BUS_WIDTH - 1:0] seq_addr;
constraint burst_c {
if(agent_cfg.DEV_TYPE == ABC)
{
seq_addr == 32’h0000_0000;
}
else
{
seq_addr == 32’h1000_0000;
}

}
endclass

class random_master_seq#(int DATA_BUS_WIDTH=32,int ADDR_BUS_WIDTH=32) extends base_sequence #(DATA_BUS_WIDTH,ADDR_BUS_WIDTH);
void’(uvm_config_db #(agent_config_c#(_DATA_BUS_WIDTH,_ADDR_BUS_WIDTH))::get (null, get_full_name(),“seq_agent_config”,req.agent_cfg));
endclass

In reply to deepa.djdoll:

Have you tried getting the config handle from the sequencer on which the sequence is running?


class base_sequence #(int DATA_BUS_WIDTH=32,int ADDR_BUS_WIDTH=32) extends uvm_sequence#(abc_data);
  `uvm_declare_p_sequencer(master_sequencer #(...))
  // ...
endclass

This macro will create a variable called p_sequencer of the type you pass to it. UVM will take care that it contains the sequencer on which the sequence was started. You can then reference the config with p_sequencer.cfg.

In reply to Tudor Timi:

deepa,

Using a macro ‘uvm_declare_p_sequencer’ is a good idea.
To get a handle of sequencer::cfg, in the sequence pre_randomization can be used.

function void pre_randomize();
  agent_cfg get_cfg;
  // alternate 1 : should be avoided
  get_cfg = p_sequencer.seqr_cfg;

  //alternate 2 : should be used
  p_sequencer.get_cfg(get_cfg); // get_cfg is a method defined in sequencer which 'references' is it's seqr_cfg ! 
                                // This method should be used because if there is any change in agent::seqr_cfg, those changes are available in sequence
  // casting and rest required 
endfunction : pre_randomize