- In SystemVerilog, when you instantiate static modules, you create multiple threads running the procedures within each instances.
- Synchronization
- Mailbox
- Streams
- Semaphore
- Use Ports, Exports and TLM_FIFOs
- uvm_put_port # (int) p1;
p1 = new("put_port", this); - uvm_get_port #(int) p2;
- uvm_tlm_fifl #(int) p3;
- m1.p1.connect (p3.put_export);
m2.p2.connect (p3.get_export); - Put shared variable in a package, together with all the classes that share that variable (using `include);
- Blocking Methods vs Non-Blocking Methods
- blocking method
- myport.put(<data>);
- myport.get(<data>);
- non-blocking method (returns 0 if failed)
- myport.try_put();
- myport.try_get();
// in f1.svh, for class c1
uvm_put_port # (int) p1;
p1 = new("put_port", this);
// in f2.svh, for class c2
uvm_get_port #(int) p2;
p2 = new("p2", this);
// in f3.svh, which contains the
// test env for c1 and c2
uvm_tlm_fifo #(int) p3;
p3 = new("p3", this);
c1.p1.connect (p3.put_export);
c2.p2.connect (p3.get_export0;
// c1.p1 -> (put_export of env)
// ->(p3)->
// (get_export of env) -> c2.p2
endtask : run
virtual task run();
integer i;
for (i = 1; i < cnt; i++) begin : loop
uvm_report_info ("run", $psprintf(...));
my_pkg::shared = i; // used by other classes
// for synchronization
// i = my_pkg::shared; // to read from the shared
end : loop
endtask : run
Example
class c1 extends uvm_agent;
uvm_put_port #(int)p1;
`uvm_component_utils(c1)
function new...
virtual function void build_phase (uvm_phase phase);
super.build_phase(phase);
p1 = new("p1", this);
endfunction : build_phase
virtual task run_phase (uvm_phase phase);
phase.raise_objection(this);
for (int i = 0; i < cnt; i++) begin
p1.put(i);
uvm_report_info("run_phase",...);
end : loop
phase.drop_objection(this);
endtask : run_phase
endclass : c1
class c2 extends uvm_agent;
uvm_put_port #(int)p2;
`uvm_component_utils(c2)
function new...
virtual function void build_phase (uvm_phase phase);
super.build_phase(phase);
p2 = new("p2", this);
endfunction : build_phase
virtual task run_phase (uvm_phase phase);
int i;
forever begin : loop
p2.get(i);
uvm_report_info("run_phase",...);
end : loop
endtask : run_phase
endclass : c2
class c3 extends uvm_agent;
`uvm_component_utils(c3)
c1 p1;
c2 p2;
uvm_tlm_fifo #(int) p3;
function new...
virtual function void build_phase (uvm_phase phase);
super.build_phase(phase);
p1 = c1::type_id::create("p1", this);
p2 = c2::type_id::create("p2", this);
p3 = new("p3", this);
endfunction : build_phase
virtual function void connect_phase (uvm_phase phase);
super.connect_phase(phase);
c1.p1.connect(p3.put_export);
c2.p2.connect(p3.get_export);
endfunction : connect_phase
virtual task run_phase (uvm_phase phase);
endtask : run_phase
endclass : c3
Example : Blocking Communication vs Non-blocking Communication
// blocking
// @(posedge clk); // this could be missed
// and block the following
// my_port.get(data);
// bus <= data;
// non-blocking
// @(posedge clk)
// my_port.try_get(data); // won't suspend
// bus <= data;
//
class c1 extends uvm_agent;
`uvm_component_utils(c1)
uvm_put_port #(int)p1;
function new...
virtual function void build_phase (uvm_phase phase);
super.build_phase(phase);
p1 = new("p1", this);
endfunction : build_phase
virtual task run_phase (uvm_phase phase);
phase.raise_objection(this);
for (int i = 0; i < cnt; i++) begin
// p1.put(i);
// uvm_report_info("run_phase",...);
#UNIT_DELAY; // to delay this thread so the following
// is always slower than p2 and
// should never fail
assert (p1.try_put(i)) else
uvm_report_info("run_phase: p1 not connected");
uvm_report_info("run_phase", $psprintf("put: %0d",i));
end : loop
phase.drop_objection(this);
endtask : run_phase
endclass : c1
class c2 extends uvm_agent;
`uvm_component_utils(c2)
uvm_put_port #(int)p2;
function new...
virtual function void build_phase (uvm_phase phase);
super.build_phase(phase);
p2 = new("p2", this);
endfunction : build_phase
virtual task run_phase (uvm_phase phase);
int i;
forever begin : loop
// p2.get(i);
// uvm_report_info("run_phase",...);
if (p2.try_get(i))
uvm_report_info ("run",
$psprintf ("got: %0d",i));
else
uvm_report_info ("run","got nothing");
end : loop
endtask : run_phase
endclass : c2
No comments:
Post a Comment