I have designed an reactive slave as memory storage component. It simple stores data at specified addr with write and read commands. Since I am running the sequence in forever loop. How do I end the simulation?
class mem_sequence extends uvm_sequence #(mem_seq_item);
`uvm_object_utils(mem_sequence)
mem_sequencer p_sequencer;
function new(string name="mem_sequence");
super.new(name);
endfunction
task pre_body();
$cast(p_sequencer,m_sequencer);
endtask
task body();
mem_seq_item m_item;
mem_seq_item m_req;
forever begin
p_sequencer.m_req_fifo.get(m_req);
if(m_req.write == 1)begin
`uvm_do_with(m_item, {m_item.ack ==1; m_item.read==0;});
end
if(m_req.read == 1)begin
`uvm_do_with(m_item, {m_item.ack ==1; m_item.data_in == m_req.data_in; m_item.write==0; m_item.read==1;});
end
end
endtask
endclass
Objections is how the UVM ends the test. All threads get killed when there are no more objections to the run_phase. See EndOfTest | Verification Academy
Assume that your sequence is started in main phase, the test can query the scoreboard in the environment to know when all the responses to the stimulus have come out of the DUT and drop the objection for the phase in order to move to the next phase. When this occurs, your sequence is killed automatically as Dave pointed out.
PS: there are several sources to get the number of reads from (scoreboard or configuration), scoreboard is basically the sink of all stimulus and response transactions
I’m not sure if this is a good solution. Your env should have seoerate agents for slave and master. This is the common approach for master/slave systems.
You only need to implement one agent for each interface. The agent instantiates appropriate components based on a configuration knob that specifies it’s in master or slave mode.