Slave sequence & driver cookbook example

seems that some crucial lines are missing in order to understand the driver<->sequence flow

in the driver:

seq_item_port.item_done(req); //driver assigns addr & rwn value

in the sequence:

get_responsn(req)
assert(rsp.randomize with {rsp.addr ==req.addr; rsp.rwn == req.rwn;});

In reply to meir:

To which example or article or you referring?

In reply to tfitz:

https://verificationacademy.com/cookbook/sequences/slave

In reply to meir:

Sorry, but I don’t see the code to which you are referring. What exactly is your question?

In reply to tfitz:

task apb_slave_sequence::body;
apb_slave_agent_config m_cfg = apb_slave_agent_config::get_config(m_sequencer);
apb_slave_seq_item req;
apb_slave_seq_item rsp;

wait (m_cfg.APB.PRESETn);
forever begin

req = apb_slave_seq_item::type_id::create("req");
rsp = apb_slave_seq_item::type_id::create("rsp");

// Slave request:
start_item(req);
finish_item(req);
get_responso(req); **//MISSING ?**

// Slave response:	
if (req.rw) begin
    memory[req.addr] = req.wdata;
end	
start_item(rsp);
rsp.copy(req);
assert (rsp.randomize() with {if(!rsp.rw) rsp.rdata == memory[rsp.addr];}); **//MAYBE rsp.randomize() with {if(![b]req**.rw) rsp.rdata == memory[**req**.addr];});[/b]
finish_item(rsp);

end

endtask:body
Example slave driver code:

task apb_slave_driver::run_phase(uvm_phase phase);
apb_slave_seq_item req;
apb_slave_seq_item rsp;

forever
begin
if (!APB.PRESETn) begin
APB.PREADY = 1’b0;
APB.PSLVERR = 1’b0;
@(posedge APB.PCLK);
end
else begin
// Setup Phase
seq_item_port.get_next_item(req);

   // Setup phase activity

   seq_item_port.item_done(); **//SHOULD BE seq_item_port.item_done(req); ??**

   // Access Phase
   seq_item_port.get_next_item(rsp);

   // Access phase activity

   seq_item_port.item_done();
 end

end

endtask: run_phase

Hi meir,

Driver first copies wdata, addr, rw into ‘req’ in setup phase, then driver calls item_done(). The change in ‘req’ inside driver, automatically reflects in ‘req’ inside sequence after finish_item, so no need to use get_response in sequence or item_done(req) in driver.

Also for ‘rsp’ inside sequence, driver just needs rdata (if !rw), slverr and delay, so sequence just send them in ‘rsp’. Driver knows that after item_done() of setup phase, again calling get_next_item(rsp) in access phase, will have all those response things(rdata, slverr, delay) which it need to drive at pin level in access phase.

In reply to shreypatel7:

Also for your query to do as following:
"
get_responsn(req)
assert(rsp.randomize with {rsp.addr ==req.addr; rsp.rwn == req.rwn;});
"

‘rsp’ in sequence has already been copied from ‘req’, before randomizing ‘rsp’.

In reply to shreypatel7:

Hi shreypatel

In my requirement in the below example
i am collecting request from my driver ( logic in driver which collect and stores in queue and pushes to req)

task apb_slave_sequence::body;
  apb_slave_agent_config m_cfg = apb_slave_agent_config::get_config(m_sequencer);
  apb_slave_seq_item req;
  apb_slave_seq_item rsp;
 
  wait (m_cfg.APB.PRESETn);
  forever begin
 
    req = apb_slave_seq_item::type_id::create("req");
    rsp = apb_slave_seq_item::type_id::create("rsp");
 
    // Slave request:
    start_item(req);
    finish_item(req);
 
    // Slave response:	
    if (req.rw) begin
        memory[req.addr] = req.wdata;
    end	
    start_item(rsp);
    rsp.copy(req);
    assert (rsp.randomize() with {if(!rsp.rw) rsp.rdata == memory[rsp.addr];});
    finish_item(rsp);
  end
 
endtask:body

i am using this sequence in my vertual sequence and sending via virtual sequencer.

class my_virual_sequence extends uvm_sequence;

task body();
first_seq.start(p_sequencer.my_firstseqr)
copy_apb_slave_sequenc.start (p_sequencer.my_apb_seqr);
//here i want to collect the transaction (req) and decode
//Drive response packet 

Question : How to collect the req from my sequence to virtual sequence

In reply to Var56:

Modified the sequence as below.
moved req and res outside body


  apb_slave_seq_item req;
  apb_slave_seq_item rsp;
task apb_slave_sequence::body;
  apb_slave_agent_config m_cfg = apb_slave_agent_config::get_config(m_sequencer);

 
  wait (m_cfg.APB.PRESETn);
  forever begin
 
    req = apb_slave_seq_item::type_id::create("req");
    rsp = apb_slave_seq_item::type_id::create("rsp");