- 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