I was just playing around with lock()/unlock() along with different arbitration schemes and created two seqs staring in a fork join in body of one vseq. Arbitration is set to UVM_SEQ_ARB_STRICT_FIFO. Priority of seq1 is 300 & that of seq2 is 200. I used lock to get control over sequencer in seq2 and was expecting that the output will be in following order as lock calling sequence will be granted
exclusive access to the driver when it gets its next slot via the sequencer arbitration mechanism:
CMD1,CMD1,CMD1,CMD1,CMD1,CMD2,CMD2,CMD2,CMD2,CMD2
But output was:
UVM_INFO @ 0: reporter [RNTST] Running test test…
UVM_INFO driver.sv(12) @ 0: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD1
UVM_INFO driver.sv(12) @ 10: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD2
UVM_INFO driver.sv(12) @ 20: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD2
UVM_INFO driver.sv(12) @ 30: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD2
UVM_INFO driver.sv(12) @ 40: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD2
UVM_INFO driver.sv(12) @ 50: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD2
UVM_INFO driver.sv(12) @ 60: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD1
UVM_INFO driver.sv(12) @ 70: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD1
UVM_INFO driver.sv(12) @ 80: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD1
UVM_INFO driver.sv(12) @ 90: uvm_test_top.my_env.agt.drv [uvm_test_top.my_env.agt.drv] Driving packet:cmd: CMD1
Can anyone please justify the output?
class packet extends uvm_sequence_item;
typedef enum bit[1:0]{CMD0,CMD1,CMD2,CMD3} cmd_e;
rand cmd_e cmd;
function new(string name="");
super.new(name);
endfunction
function string convert2string();
convert2string = $sformatf("cmd: %0s",cmd.name());
endfunction
`uvm_object_utils_begin(packet)
`uvm_field_enum(cmd_e,cmd,UVM_ALL_ON)
`uvm_object_utils_end
endclass:packet
class seq1 extends uvm_sequence;
`uvm_object_utils(seq1)
function new(string name="");
super.new(name);
endfunction
task body;
packet p1;
repeat(5)begin
`uvm_do_pri_with(p1,300,{p1.cmd == CMD1;});
end
endtask
endclass: seq1
class seq2 extends uvm_sequence;
`uvm_object_utils(seq2)
function new(string name="");
super.new(name);
endfunction
task body;
packet p1;
lock();
repeat(5)begin
`uvm_do_pri_with(p1,200,{p1.cmd == CMD2;});
end
unlock();
endtask
endclass: seq2
class vseq extends uvm_sequence;
`uvm_object_utils(vseq)
seq1 s1;
seq2 s2;
function new(string name="");
super.new(name);
endfunction
task body;
s1=seq1::type_id::create("s1");
s2=seq2::type_id::create("s2");
fork
s1.start(m_sequencer);
s2.start(m_sequencer);
join
endtask
endclass: vseq
class test extends uvm_test;
env my_env;
vseq para_seq;
`uvm_component_utils(test)
function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
my_env=env::type_id::create("my_env",this);
para_seq = vseq::type_id::create("p_seq");
endfunction
virtual task run_phase(uvm_phase phase);
phase.raise_objection(this);
my_env.agt.sqr.set_arbitration(UVM_SEQ_ARB_STRICT_FIFO);
para_seq.start(my_env.agt.sqr);
phase.drop_objection(this);
endtask
endclass: test
class env extends uvm_env;
agent agt;
`uvm_component_utils(env)
function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
agt=agent::type_id::create("agt",this);
endfunction
endclass
class agent extends uvm_agent;
my_sequencer sqr;
driver drv;
`uvm_component_utils(agent)
function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
drv=driver::type_id::create("drv",this);
sqr=my_sequencer::type_id::create("sqr",this);
endfunction
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
drv.seq_item_port.connect(sqr.seq_item_export);
endfunction:connect_phase
endclass
class my_sequencer extends uvm_sequencer #(packet);
`uvm_sequencer_utils(my_sequencer)
function new (string name = "my_sequencer", uvm_component parent = null);
super.new(name, parent);
endfunction : new
endclass : my_sequencer
class driver extends uvm_driver#(packet);
`uvm_component_utils(driver)
function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction
task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
`uvm_info(get_full_name(),$sformatf("Driving packet:%0s",req.convert2string()),UVM_LOW)
#10
seq_item_port.item_done();
end
endtask
endclass
`include "uvm_macros.svh"
`include "pkg.sv"
module tb;
import uvm_pkg::*;
import pkg::*;
initial begin
run_test("test");
end
endmodule: tb