Jump to content

multiple items, multiple sequence, one sequencer, one driver


Recommended Posts

Hi,

Suppose there is a situation like this,

An env has one DUV, one master agent and one slave agent. DUV has only one slave interface, which is used to receive the transaction from master agent. Now you want to generate different kinds of transactions (not different pattern of the same transaction) to the DUV from master agent, but there are only one driver in the master agent, how will you do with this problem?

I have one idea for this problem, but I am not sure whether it's okay. My idea is something like this:

1) create different item classes as the sub items, such as a_item, b_item and c_item, which are extend from class uvm_sequence_item

2) create one item(my_item) as the top item. a_item, b_item and c_item are my_item's members, then use `uvm_field_object(a_item, UVM_ALL_ON) to factory the sub items in class my_item

3) create a_sequence, b_sequence and c_sequence to generate a_item, b_item and c_item

4) create one virtual sequence(vir_seq) as top sequence. Its body can excute a_sequence, b_sequence and c_sequence concurrently via fork/join.

5) create one sequencer(my_sqr) which can start vir_seq as the default sequence.

6) create one driver(my_dri) to receive my_item from my_sqr.

I don't know whether the macro `uvm_field_object(a_item, UVM_ALL_ON) is okay? If it is okay, how can i compare a_item via my_item when a_item exist in the env independently? Can the virtual sequence be the default sequence of one non-virtual sequencer?

Maybe there is best way to solve the problem.

Thanks

mrforever

Link to comment
Share on other sites

You could have a_item, b_item, etc extend from my_item, and transfer them as my_item through the agent, with the driver downcasting my_item to reveal the actual request. If the transactions aren't related in any way, it would seem better, as you point out, to have separate agents for them. Not sure what you mean by "how does it arbitrates the drivers". If the drivers are going to work with the same interface, but can't do that concurrently for some reason, a semaphore in the interface could be used to enforce serialization.

Erling

Link to comment
Share on other sites

Erling, thanks for your reply.

yes, for the statement “how does it arbitrates the drivers", my meaning is that the different drivers in different agents all connect with the same slave interface, but they cann't transfer the transactions to DUV concurrently. If I don't want to use semaphore, can there be any other way? I still have some problem about your reply. How can it transfer a_item, b_item, etc via driver, which is supposed to transfer my_item transactions?I am sorry for that maybe i didn't state these items clearly. now I will give one example like this

class a_item extends uvm_sequence_item

rand int unsigned a1;

rand int unsigned a2;

//···

endclass

class b_item extends uvm_sequence_item

rand int unsigned b1;

rand int unsigned b2;

rand int unsigned b3;

//···

endclass

class my_item extends uvm_sequence_item

a_item item1;

a_item item2;

enum type ;

//···

if (type =1 )

`uvm_field_object(item1, UVM_ALL_ON) // can it use the macro like this???

else if (type =2 )

`uvm_field_object(item2, UVM_ALL_ON)

//···

endclass

You could have a_item, b_item, etc extend from my_item, and transfer them as my_item through the agent, with the driver downcasting my_item to reveal the actual request. If the transactions aren't related in any way, it would seem better, as you point out, to have separate agents for them. Not sure what you mean by "how does it arbitrates the drivers". If the drivers are going to work with the same interface, but can't do that concurrently for some reason, a semaphore in the interface could be used to enforce serialization.

Erling

Edited by mrforever
Link to comment
Share on other sites

How can it transfer a_item, b_item, etc via driver, which is supposed to transfer my_item transactions?

If the driver is parameterized on my_item, it can also accept any transaction extended from my_item. A sequence producing my_item's could be configured to produce some other item extended from my_item (by means of instance overrides for example). The driver would then have to downcast to determine the actual item type.

Erling

Link to comment
Share on other sites

Maybe I can do like this:

interface fifo_if (input clk)

bit[`DATA_WIDTH-1:0] wdata;

bit[`DATA_WIDTH-1:0] rdata;

bit rw ;

modport fifo_port(

input wdata ,

output rdata ,

input rw

)

endinterface

class my_item extends uvm_sequence_item

//```

typedef enum {A_ITEM, B_ITEEM, C_ITEM} item_type ;

semaphore smp ;

smp = new (1) ;

//```

endclass

class a_item extends my_item

//```

endclass

class b_item extends my_item

//```

endclass

class a_driver extends uvm_driver #(a_item)

//```

a_item aitem;

fifo_if vif ;

task run_phase (uvm_phase phase)

forever begin

if ( ( aitem.item_type = A_ITEM ) && ( aitem.smp.try_get(1)) )

begin

write(aitem.data) ;

aitem.smp.put(1) ;

end

end

endtask

task write (input data)

this.rw = `WRITE ;

this.wdata = data ;

endtask

//```

endclass

class b_driver extends uvm_driver #(b_item)

//```

b_item bitem;

fifo_if vif ;

task run_phase (uvm_phase phase)

forever begin

if ( ( bitem.item_type = B_ITEM ) && ( bitem.smp.try_get(1)) )

begin

write(bitem.data) ;

bitem.smp.put(1) ;

end

end

endtask

task write (input data)

this.rw = `WRITE ;

this.wdata = data ;

endtask

//```

endclass

But I have one question about this, will the uvm report compile error or runtime error while assigning data to the same interface's data in the write() task in different drivers in uvm??? As we know that it's forbidden in verilog.

Or will there be any other problem? such as how will the driver be blocked when it cann't get the semaphore while another driver is doing write task?

If the driver is parameterized on my_item, it can also accept any transaction extended from my_item. A sequence producing my_item's could be configured to produce some other item extended from my_item (by means of instance overrides for example). The driver would then have to downcast to determine the actual item type.

Erling

Edited by mrforever
Link to comment
Share on other sites

>Maybe I can do like this:

Individual semaphores on the items isn't going to help. If you want to serialize access to the interface, have a single semaphore in the interface for this purpose.

>But I have one question about this, will the uvm report compile error or >runtime error while assigning data to the same interface's data in the write() >task in different drivers in uvm???

The last written data will be driven.

>...how will the driver be blocked when it cann't get the semaphore while another driver is doing write task?

Unless the drivers have idle work to do, they could simply block on the semaphore, ie use get() and not try_get.

By the way, what makes you conclude that the transactions need to be of different types, ie what is special about a_item and b_item, so they can't be represented by my_item?

Erling

Link to comment
Share on other sites

> Individual semaphores on the items isn't going to help. If you want to serialize access to the interface, have a single semaphore in the interface for this purpose.

What's the meaning about the saying "have a single semaphore in the interface"? Does that mean interface encapsulating the semaphore and other signals at the same time? If it does, then how create an instance of the semaphore via new()? Could you give the example codes?

> By the way, what makes you conclude that the transactions need to be of different types, ie what is special about a_item and b_item, so they can't be represented by my_item?

The situation is like this,

a_item is used to config the duv, b_item and c_item are different types of packet, such as b_item is a "nap" packet, c_item is a "dma" packet. but a_item, b_item and c_item all need to transfer to duv via the same interface, which is fifo interface or pcie packet interface. Is it difficult for uvm to solve such problem?

it will be better if there are more available ways. thanks a lot.

by the way, is there any other problem if the way is successful, such as the connection with reference model and scoreboard ?

Erling

Edited by mrforever
Link to comment
Share on other sites

>If it does, then how create an instance of the semaphore via new()? Could you give the example codes?

Just declare the semaphore with an initializer in the interface, for example:

interface fifo_if ...

semaphore lock = new(1);

endinterface

>The situation is like this, a_item is used to config the duv, b_item and c_item

>are different types of packet, such as b_item is a "nap" packet, c_item is a

>"dma" packet. but a_item, b_item and c_item all need to transfer to duv via the

>same interface, which is fifo interface or pcie packet interface. Is it

>difficult for uvm to solve such problem?

There is no perfect solution to this problem. It is sometimes feasible to transfer different things through one representation, and sometimes not. If you choose different types extended from the agent transaction type, uvm may be of help at the sender side, as you can use the factory to override what's actually sent. Things will be serialized at the receiver side, since there is only one driver, but there will be downcast to the actual transaction type. To get started, it is probably easier to represent all packets types by one transaction type, i.e have the packet type a rand field of the transaction, and then choose packet type by randomizing the packet with the actual packet type. The receiver will have to use the packet type field to figure out how to interpret the rest of the request, again a cast, sort of, in the driver. You may want to try to get this up and running first, and then consider alternatives as needed.

Erling

Link to comment
Share on other sites

Erling, thanks very much. I want to try this, and run first. If there is any other problem, i can turn to help from this handsome forum. ^_^

mrforever

>i.e have the packet type a rand field of the transaction, and then choose packet type by randomizing the packet with the actual packet type. The receiver will have to use the packet type field to figure out how to interpret the rest of the request, again a cast, sort of, in the driver. You may want to try to get this up and running first, and then consider alternatives as needed.

Erling

Link to comment
Share on other sites

  • 1 month later...

What you are trying to do is create a switch which takes separate transactions (i.e. sequence items A, B ,C) and route to same interface. Please correct if I m wrong here in understanding the problem statement.

In addition to what Erling has suggested, I would suggest using a higer level sequence item class which is parent to A, B and C. Then use TLM fifo of type parent class to route the transactions. Therefore a component that takes transaction items as they come from A, B,C and just route to one FIFO and driver could fetch it from it.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...