4

I have a slave model implemented in uvm_agent. By "slave" I meant that it can not initiate transaction by itself. Transaction is always initiated by the other side (master DUT). So it is kind of passive agent (although it is still able to transmit reply packet).
When the slave detect a packet from DUT, it will response/reply automatically (based on its protocol) with another packet. The slave agent has a monitor to listen to DUT's initiate transfer. And since it is able to transmit packet, the slave agent also does have a driver to send a reply packet.

+------------+  master initiate transfer  +------------------------+
| Master DUT |  ------------------------> | UVM Agent - slave mode |
|            |                            | Monitor                |
|            |                            | Driver     Sequencer   |
+------------+                            +------------------------+


+------------+                            +------------------------+
| Master DUT |                            | UVM Agent - slave mode |
|            |   slave auto reply         | Monitor                |
|            | <------------------------- | Driver     Sequencer   |
+------------+                            +------------------------+

My question is how does it suppose to send the reply packet? Directly from its driver? Since in uvm way, the driver item is always from a sequencer that is executing sequence from user test level. But now in this case, there is no sequence - only a detected packet from monitor.

My first idea is that I need to provide sort of feedback from monitor to sequencer and implement my protocol function there.
Or should I pass the packet directly from monitor to driver, and let it process it and send reply? If so, how do I do that? Is there any better way?

AldoT
  • 913
  • 1
  • 8
  • 34

1 Answers1

7

What you want is also referred to as a reactive agent. Don't confuse it with a passive agent, which is an agent that only monitors signals, but doesn't drive them.

What you would do in such an agent is just start an endless loop on the sequencer that drives slave items.

class slave_sequence extends uvm_sequence;
  task body();
    forever begin
      `uvm_do(slave_item)
    end
  endtask
endclass

The driver would wait for the master to start a transaction (how it does that depends on the protocol) and when it sees one it would call get_next_item(...), drive the response and go back to waiting for another transaction.

class slave_driver extends uvm_driver;
  task run_phase(uvm_phase phase);
    forever begin
      wait @(master_requests);
      seq_item_port.get_next_item(req);
      drive_response(req);
      seq_item_port.item_done();
    end
  endtask
endclass

The sequence item the slave agent uses is mostly used to randomize response delays and the read data. You can even create something more fancy, like a memory model inside the slave sequence (a simple array). When a read from a certain address comes, you deliver the data from your memory model and you just randomize your delay.

Have a look at the following link for a concrete example: https://verificationacademy.com/cookbook/sequences/slave

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53