Parametrized agent

In reply to chr_sue:

Thank for your answer. I tried to implement this approach and it seemed to be working up to the moment when I tried to parametrize transaction. The issue I am facing is that since I do not have much assumption on the content of the transfer I have transaction which contain data as an array [BIT_WIDTH-1:0] data [$] . Therefore I can have straightforward monitor/driver.

The problem appears in sequence, where I created instance of


fb_uvm_sample_stream_transaction#(int BIT_WIDTH=32) extends uvm_sequence_item;

inside my sequence (lets say SEQUENCE_BIT_WIDTH is 64)


    trn = fb_uvm_sample_stream_transaction#(.BIT_WIDTH(SEQUENCE_BIT_WIDTH))::type_id::create(
    .name("sqv"),
    .contxt(get_full_name()));
    start_item(trn);
    assert(trn.randomize()) else `uvm_fatal("SAMPLE_SQV","Randomization failed");
    finish_item(trn);

when finish_item(trn) fails since it contains illegal cast.

Currently, I have parametrized agents but have one transaction which has maximal possible BIT_WIDTH allocated (thus wasting a lot of memory) and some additional logic to ignore unused memory in driver, and in the transaction itself. I am not happy with this solution since

  • it requires the additional configuration of the transaction object in the sequence after creation
  • The BIT_WIDTH is variable and as such it can not be use at all places (for example data[BITH_WIDTH-1:0] is invalid since it leads to the variable range)
  • Further complicates the driver (must ask transaction which bits are valid and which not)

Each of these issues are solvable but the questing that raises is if this is the right way to go? Or is there some other way how to build it in UVM which would be preffered? I guess I am hoping that I miss some obvious solution or language construct that would allow me to have parametrized the transaction as well.

Thank you again
Jan