In reply to shimonc:
Hi Dave,
I wrote the next code (sorry for the length)
It works, I triggered 2 sequences at the same time and I checked the results inside and out side the case and it work fine, I have 3 questions.
- if indeed 2 items arrive at the same time does it means that the first case condition will be executed always?
- in the waves I see that tlma_ev and tlmb_ev dont change at all, not even the usual glitch that I see in events variables, Is it ok?
- when I exit the case conditional does it matter if I write nonblocking {tlma_ev,tlmb_ev}=0; or blocking {tlma_ev,tlmb_ev}<=0;
interface prot_if ();
logic [7:0] data;
endinterface
package rc;
import uvm_pkg::*;
`include "uvm_macros.svh"
`uvm_analysis_imp_decl(_tlma)
`uvm_analysis_imp_decl(_tlmb)
class prot_item extends uvm_sequence_item;
rand bit [7:0] data;
`uvm_object_utils_begin(prot_item);
`uvm_field_int(data,UVM_ALL_ON)
`uvm_object_utils_end
function new (string name="");
super.new(name);
endfunction
function string convert2string();
string s="";
$sformat(s,"%s data=%0h",s,data);
return s;
endfunction
endclass
class prot_driver extends uvm_driver #(prot_item);
virtual prot_if m_prot_if;
`uvm_component_utils(prot_driver)
function new (string name , uvm_component parent);
super.new(name,parent);
endfunction
task run_phase (uvm_phase phase);
super.run_phase(phase);
forever begin
seq_item_port.get_next_item(req);
`uvm_info("DRV",req.convert2string(),UVM_HIGH)
m_prot_if.data <= req.data;
seq_item_port.item_done();
end
endtask
endclass
class prot_monitor extends uvm_monitor;
virtual prot_if m_prot_if;
prot_item collected_item;
uvm_analysis_port #(prot_item) ap;
`uvm_component_utils(prot_monitor)
function new (string name , uvm_component parent);
super.new(name,parent);
ap=new("ap",this);
endfunction
task run_phase (uvm_phase phase);
super.run_phase(phase);
forever begin
@(m_prot_if.data);
collected_item=prot_item::type_id::create("item");
collected_item.data=m_prot_if.data;
`uvm_info("MNTR",collected_item.convert2string(),UVM_HIGH)
ap.write(collected_item);
end
endtask
endclass
typedef uvm_sequencer #(prot_item) prot_sequencer;
class prot_agent extends uvm_agent;
prot_driver drv;
prot_monitor mntr;
prot_sequencer sqr;
`uvm_component_utils(prot_agent)
function new (string name , uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase (uvm_phase phase);
super.build_phase(phase);
drv=prot_driver::type_id::create("drv",this);
mntr=prot_monitor::type_id::create("mntr",this);
sqr=prot_sequencer::type_id::create("sqr",this);
endfunction
function void connect_phase (uvm_phase phase);
super.connect_phase(phase);
drv.seq_item_port.connect(sqr.seq_item_export);
endfunction
endclass
class prot_scb extends uvm_scoreboard;
uvm_analysis_imp_tlma#(prot_item,prot_scb) imp_tlma;
uvm_analysis_imp_tlmb#(prot_item,prot_scb) imp_tlmb;
bit tlma_ev;
bit tlmb_ev;
`uvm_component_utils(prot_scb)
function new (string name, uvm_component parent);
super.new(name,parent);
imp_tlma=new("imp_tlma",this);
imp_tlmb=new("imp_tlmb",this);
endfunction
function void write_tlma (prot_item item);
`uvm_info("TLMA",item.convert2string(),UVM_HIGH)
tlma_ev<=1;
endfunction
function void write_tlmb (prot_item item);
`uvm_info("TLMB",item.convert2string(),UVM_HIGH)
tlmb_ev<=1;
endfunction
task run_phase (uvm_phase phase);
super.run_phase(phase);
change_state();
endtask
task change_state();
string event_type="";
forever @(tlma_ev or tlmb_ev) begin
case (1)
tlma_ev: begin
print_time("tlma_ev");
event_type="tlma_ev";
end
tlmb_ev: begin
print_time("tlmb_ev");
event_type="tlmb_ev";
end
endcase
{tlma_ev,tlmb_ev}=0;
`uvm_info("",$sformatf("event_type=%s",event_type),UVM_MEDIUM)
end
endtask
function void print_time (string str);
`uvm_info("",$sformatf("%s was activated sim time is %0t",str,$time()),UVM_HIGH)
endfunction
endclass
class prot_env extends uvm_env;
prot_agent m_prot_agent_a;
prot_agent m_prot_agent_b;
prot_scb m_prot_scb;
`uvm_component_utils(prot_env)
function new (string name , uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase (uvm_phase phase);
super.build_phase(phase);
m_prot_agent_a=prot_agent::type_id::create("m_prot_agent_a",this);
m_prot_agent_b=prot_agent::type_id::create("m_prot_agent_b",this);
m_prot_scb=prot_scb::type_id::create("m_prot_scb",this);
endfunction
function void connect_phase (uvm_phase phase);
super.connect_phase(phase);
m_prot_agent_a.mntr.ap.connect(m_prot_scb.imp_tlma);
m_prot_agent_b.mntr.ap.connect(m_prot_scb.imp_tlmb);
endfunction
endclass
class prot_seq extends uvm_sequence #(prot_item);
`uvm_object_utils(prot_seq)
function new (string name="");
super.new(name);
endfunction
task body();
`uvm_do(req)
endtask
endclass
class prot_test extends uvm_test;
virtual prot_if m_prot_if_a;
virtual prot_if m_prot_if_b;
prot_env m_prot_env;
prot_seq m_prot_seq_a;
prot_seq m_prot_seq_b;
`uvm_component_utils(prot_test)
function new (string name , uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase (uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(virtual prot_if)::get(this,"","m_prot_if_a",m_prot_if_a)) `uvm_fatal("PROT_IF_A","Failed")
if (!uvm_config_db#(virtual prot_if)::get(this,"","m_prot_if_b",m_prot_if_b)) `uvm_fatal("PROT_IF_B","Failed")
m_prot_env=prot_env::type_id::create("m_prot_env",this);
endfunction
function void connect_phase (uvm_phase phase);
m_prot_env.m_prot_agent_a.drv.m_prot_if=m_prot_if_a;
m_prot_env.m_prot_agent_a.mntr.m_prot_if=m_prot_if_a;
m_prot_env.m_prot_agent_b.drv.m_prot_if=m_prot_if_b;
m_prot_env.m_prot_agent_b.mntr.m_prot_if=m_prot_if_b;
endfunction
task run_phase (uvm_phase phase);
phase.raise_objection(this);
super.run_phase(phase);
m_prot_seq_a=prot_seq::type_id::create("m_prot_seq_a",this);
m_prot_seq_b=prot_seq::type_id::create("m_prot_seq_b",this);
fork
begin
#1ns;
m_prot_seq_a.start(m_prot_env.m_prot_agent_a.sqr);
end
begin
#1ns;
m_prot_seq_b.start(m_prot_env.m_prot_agent_b.sqr);
end
join
#1ns;
m_prot_seq_a.start(m_prot_env.m_prot_agent_a.sqr);
#1ns;
m_prot_seq_b.start(m_prot_env.m_prot_agent_b.sqr);
#5ns;
phase.drop_objection(this);
endtask
endclass
endpackage
module top;
import uvm_pkg::*;
`include "uvm_macros.svh"
import rc::*;
prot_if m_prot_if_a();
prot_if m_prot_if_b();
initial begin
uvm_config_db #(virtual prot_if)::set(null,"uvm_test_top","m_prot_if_a",m_prot_if_a);
uvm_config_db #(virtual prot_if)::set(null,"uvm_test_top","m_prot_if_b",m_prot_if_b);
run_test("prot_test");
end
endmodule