Jump to content

Controlling the slave sequence response from the test case


Recommended Posts

My requirement is that based on the master's request (master is the DUT), I have to generate response from the slave (ie., TB). The response generated could be random or directed.

With the code mentioned below in apb example, I tried to generate a random response always from the test bench.

class apb_monitor extends uvm_monitor;

...

uvm_blocking_peek_imp#(apb_transfer, apb_monitor) addr_trans_export;

...

task apb_monitor::run_phase(uvm_phase phase);

forever begin

// start collecting a transaction - when the address phase is complete

-> trans_addr_grabbed;

...

end

endtask : run_phase

task apb_monitor::peek(output apb_transfer trans);

@(trans_addr_grabbed)

trans = trans_collected;

endtask

// Now your sequencer has a port so the sequences can access the data from the monitor

class apb_slave_sequencer extends uvm_sequencer #(apb_transfer);

uvm_blocking_peek_port#(apb_transfer) addr_trans_port;

...

endclass

class simple_response_seq extends uvm_sequence #(apb_transfer);

function new(...);

`uvm_object_utils(simple_response_seq)

`uvm_declare_p_sequencer(apb_slave_sequencer) // allows your sequence to look at his parent sequencer

apb_transfer util_transfer;

virtual task body();

forever begin

p_sequencer.addr_trans_port.peek(util_transfer); // waits until it sees a valid address on the bus

`uvm_do(req); //always random req

end

endtask

// connection between a bus monitor and the sequencer is done in the connect phase of the env:

function void apb_env::connect_phase(uvm_phase phase);

..

foreach(slaves)

if (slaves.is_active == UVM_ACTIVE)

slaves.sequencer.addr_trans_port.connect(bus_monitor.addr_trans_export);

But the question is how can I control the response from the test case, say, if I want to provide a directed response for a particular transaction?

Can you please provide me your inputs on this?

Link to comment
Share on other sites

Hi

Rather than having one-sequence running forever, why not use the uvm_driver to wait (monitor.trans_addr_grabbed.triggered) then you can use req & rsp from the driver and sequences to communicate.

In your sequences you can evaluate and control req & rsp accordingly.

See section 3.5.4 in the UVM Users Guide.

thanks,

Adiel.

Link to comment
Share on other sites

Hi,

Can you please be more elaborative? I am a beginner with UVM and trying to understand the methodology.

Say, In driver if we wait for an event from the monitor,

wait (monitor.trans_addr_grabbed.triggered) // waited for event from monitor;

//when should we start sending response from the driver? - I believe this can be done only after receiving a request from sequence - In such a case, how would the sequence know when to send a request

seq_item_port.put_response(rsp);

Even with the method suggested, I feel that forever block is mandatory in sequence block so as to handle 1000's of transactions. Am I missing something here?

And also Is it possible to collect the response from the sequencer pertained to one sequence from a different sequence?

Thanks in advance for your patience,

Pradeep

Link to comment
Share on other sites

Hi,

Have a look at $UVM_HOME/examples/simple/sequence/basic_read_write_sequence

Your uvm_driver will have the forever-loop and whenever it needs to place an item on the bus it will call seq_item_port.get(req);

You can see num_loops is defined for the number of items to send. (in your code it might make more sense to make it a random runtime variable)

In the sequence you can see the usage of wait_for_grant() & send_request(req) to give the driver the required data. You can randomize or direct the data of req within your sequences.

The point being that for stimulus control there is already a mechanism to communicate between driver and sequences.

It looks like you have duplicated this for monitor to sequencer. Whereas the only part you are actually using is the control flag to say when the bus available for the Slave to send its item to the bus.

It might be that a simple get_next_item(req) is sufficient for your case.

In any case your constrainted-random control can be done inthe sequences. Either by upfront control of req or by using `uvm_do_with().

You can send me your code offline and I'll show you the various options we are discussing.

thanks,

adiel@synopsys.com

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...