Using Interface
- Virtual interface
- Static interface
Example 1
`include "uvm_macros.svh" package my_pkg; import uvm_pkg::*; int shared_int; int shared_count; virtual interface mem_if global_vmi; `include "uvm_macros.svh" `include "test_1.svh" `include "test_2.svh" endpackage: my_pkg import uvm_pkg::*; import my_pkg::*; module top; mem_if mi(); sram dut (mi.mem_modport); initial begin string test_name; my_pkg::global_vmi = mi; run_test(); end endmodule: top // typedef struct packed typedef struct { bit sign; bit[24:0] mantissa; bit[ 5:0] exponent; } ieee_sp_float; union packed { bit [7:0] data[1500]; struct packed { bit [7:0] dsap; bit [7:0] ssap; bit [7:0] control; bit [7:0] data[1497]; } label; } payload; class test_1 extends uvm_test; `uvm_component_utils(test_1) ieee_sp_float v1, v2; v1 = {1, 24'h800, 6'h0}; v1 = abs(v1); virtual interface mem_if mi; function new (string name, uvm_component base); super.new(name, base); endfunction : new virtual function void build_phase(uvm_phase phase); super.build_phase(phase); mi = my_pkg::global_vmi; endfunction : build_phase virtual task run_phase(uvm_phase phase); int cnt=5; logic [3:0] sub_addr; rand logic [11:0] upper_addr; sub_addr = $urandom($random); phase.raise_objection(this); mi.wr = 1'b1; mi.rd = ~mi.wr; mi.wr_data = $urandom($random); `uvm_info("TESTER", $psprintf("addr: %2h data: %2h rd: %1b wr: %1b", mi.addr, mi.data, mi.rd, mi.wr), UVM_INFO); super.run(); mi.addr = {upper_addr, sub_addr}; repeat (cnt) begin @(posedge mi.clk); ... end @(posedge mi.clk); phase.drop_objection(this); endtask // run_phase
Example 2
import my_pkg::*; // Virtual interface in driver class my_driver extends uvm_driver #(my_transaction); `uvm_component_utils(my_driver) virtual dut_if dut_vi; function new(string name, uvm_component parent); super.new(name, parent); endfunction: new // function void build; virtual function void build_phase (uvm_phase phase); super.build(); dut_vi = global_dutvi; endfunction : build_phase // task run; task run_phase (uvm_phase phase); repeat(4) begin phase.raise_objection(this); my_transaction tx; @(posedge dut_vi.clock); // Driver consumes the transactions generated by // my_transaction and wiggles the pins on the DUT seq_item_port.get(tx); // Pin Wiggling dut_vi.cmd = tx.cmd; dut_vi.addr = tx.addr; dut_vi.data = tx.data; end @(posedge dut_vi.clock) top.stop_request(); phase.drop_objection(this); endtask: run endclass : my_driver
Example 3, connecting sequencer to driver
class my_sequencer extends uvm_sequencer; ... uvm_put_port #(int) port1; port1 = new ("port1", this); endclass class my_driver extends uvm_driver; ... uvm_get_port #(int) port2; port2 = new ("port2", this); endclass class my_agent extends uvm_agent; `uvm_component_utils(my_agent) // register for type_id my_sequencer my_sequencer_h; my_driver my_driver_h; function new(string name, uvm_component parent); super.new(name, parent); endfunction: new function void build; super.build(); my_sequencer_h = my_sequencer::type_id::create("my_sequencer_h", this); // instance name, parent my_driver_h = my_driver::type_id::create ("my_driver_h" , this); endfunction: build // Lower level connection in another function is good practice // seq_item_port is the handler of the ports function void connect; my_driver_h.seq_item_port.connect( my_sequencer_h.seq_item_export ); endfunction: connect endclass : my_agent
Example 4, connecting through top module
`timescale 1ns/1ns module top; mem_if mi(); sram dut (mi.mem_modport); tester tst (mi.test_modport); endmodule // top interface mem_if; bit clk, rd, wr; logic [15:0] wr_data; wire [15:0] data; logic [15:0] addr; modport mem_modport ( inout data, input addr, input clk, input rd, input wr ); modport test_modport ( input clk, output wr_data, output addr, output rd, output wr ); clocking cb @ (negedge clk); output data <= ...; output addr <= ...; endclocking: cb initial begin @(cb) ; wr_data <= ...; @(cb) ; wr <= $urandom; end assign rd = ~wr; assign data = (wr) ? wr_data : 16'hzzzz; initial begin clk = 0; $monitor (); end always #10 clk = ~clk; endinterface // mem_if
Example 5, connecting in tester
module top; mem_if mi(); sram dut (mi.mem_modport); tester tst; initial begin tst = new(mi); fork tst.run; join_none end endmodule // top class tester; // driver logic [3:0] sub_addr; virtual interface mem_if tmi; function new (virtual interface mem_if vmi); tmi = vmi; endfunction // new task run; // generate transaction data tmi.wr = 1'b1; @ (posedge tmi.clk); repeat (100) begin @ (posedge tmi.clk); tmi.wr = $random; tmi.rd = ~tmi.wr; tmi.addr = $random; tmi.wr_data = $urandom($random); end $stop; endtask // run endclass // tester
Example 6, use wrapper_if
module top; import uvm_pkg::*; import my_pkg::*; mem_if mi(); sram dut (mi.mem_modport); // tester tst; // replaced by if_wrapper initial begin: blk dut_if_wrapper if_wrapper = new ("if_wrapper", dut_if_inst1); // path field_name value 0: don't clone set_config_object("*", "dut_if_wrapper", if_wrapper, 0); run_test ("my_test"); end endmodule : top class dut_if_wrapper extends uvm_object; virtual dut_if dut_vi; function new (string s, virtual dut_if if_arg); super.new(s); dut_vi = if_arg; endfunction : new // you can have task run; here endclass : dut_if_wrapper `include "uvm_macros.svh" package my_pkg; import uvm_pkg::*; // Fixed test environment class my_env extends uvm_env; `uvm_component_utils (my_env) virtual dut_if dut_virtual_if_inst; // constructor function new (string s, uvm_component inst_parent); super.new (s, inst_parent); endfunction : new function void build; super.build (); begin uvm_object obj; dut_if_wrapper if_wrapper; get_config_object("dut_if_wrapper", obj, 0); assert( $cast(if_wrapper, obj) ); dut_virtual_if_inst = if_wrapper.dut_vi; end endfunction : build task run; #10 dut_virtual_if_inst.data = 0; #10 dut_virtual_if_inst.data = 1; #10 stop_request(); endtask : run endclass : my_env
Example 7, use uvm_get_port and uvm_put_port in tlm_fifo / tlm_analysis_fifo
class producer extends uvm_agent; uvm_put_port #(int) phone1; ... virtual function void build_phase (uvm_phase phase); super.build_phase(phase); phone1 = new("phone1", this); endfunction virtual task run_phase (uvm_phase phase); phase.raise_objection(this); for (int i = 0; i < count; i++) begin : loop phone1.put(i); uvm_report_into ("run_phase", $psprintf("..."); end : loop phase.drop_objection(this); endtask : run_phase endclass : producer class consumer extends uvm_agent; uvm_get_port #(int) phone2; ... virtual function void build_phase (uvm_phase phase); super.build_phase(phase); phone2 = new("phone2", this); endfunction virtual task run_phase (uvm_phase phase); phase.raise_objection(this); for (int i = 0; i < count; i++) begin : loop phone1.put(i); uvm_report_into ("run_phase", $psprintf("..."); end : loop phase.drop_objection(this); endtask : run_phase endclass : producer class test_env extends uvm_env; producer p; consumer c; uvm_tlm_fifo #(int) tlmff; function new () ... virtual function void build_phase (uvm_phase phase); super.build_phase (phase); p = producer::type_id::create ("p", this); p = producer::type_id::create ("p", this); tlmff = new ("tlmff", this); endfunction : build_phase virtual function void connect_phase (uvm_phase phase); super.connect_phase (phase); p.phone1.connect (tlmff.put_export); c.phone2.connect (tlmff.get_export); endfunction : connect_phase
Example 8, using uvm_config_db
module top; ... dut_if dut_if1 (); initial begin: blk // type of value prefix path uvm_config_db #(virtual dut_if)::set(null, “uvm_test_top”, "dut_vi", dut_if1); // field name, value run_test("my_test"); end endmodule: top class my_test extends uvm_test; ... my_dut_config dut_config_0; ... function void build_phase(uvm_phase phase); dut_config_0 = new(); // type of value prefix path if(!uvm_config_db #(dut_if)::get( this, “”, “dut_vi”, dut_config_0.dut_vi)) `uvm_fatal(“MY_TEST”, “No DUT_IF”); // other DUT configuration settings uvm_config_db#(my_dut_config)::set(this, “*”, “dut_config”, dut_config_0); endfunction endclass class my_driver extends uvm_driver; `uvm_component_utils(my_driver) virtual dut_if dut_vi; function new(string name, uvm_component parent); ... function void build_phase(uvm_phase phase); ... task run_phase(uvm_phase phase); phase.raise_objection(this); #10 dut_vi.data = 0; #10 dut_vi.data = 1; #10 phase.drop_objection(this); endtask: run_phase endclass
No comments:
Post a Comment