Could anyone show me an example on how to write the Coverage monitor in Systemverilog as I am new to this. I need to understand the monitor any examples or references is also fine
2 Answers
John Aynsley (from Doulos) wrote a good paper about UVM that has a section that can help you out. The paper was published at DVCon 2011 and you can get a free copy of it: "Easier UVM for Functional Verification by Mainstream Users".
As explained in the paper, the idea is that you have a uvm_monitor
and a uvm_subscriber
. Note that even though the paper shows all Functional Coverage code inside the UVM subscriber, nothing prevents you from having that piece of code inside your monitor.
The monitor code would look as shown below:
class my_monitor extends uvm_monitor;
`uvm_component_utils(my_monitor)
uvm_analysis_port #(my_tx) aport;
virtual dut_if dut_vi;
...
task run;
forever
begin
my_tx tx;
// Sense the DUT pins on a clock edge
@(posedge dut_vi.clock);
tx = my_tx::type_id::create("tx");
tx.cmd = dut_vi.cmd;
tx.addr = dut_vi.addr;
tx.data = dut_vi.data;
aport.write(tx);
end
endtask
endclass
Then you create a subscriber as shown in the paper:
class my_subscriber extends uvm_subscriber #(my_tx);
`uvm_component_utils(my_subscriber)
// Coverage registers
bit cmd;
int addr;
int data;
covergroup cover_bus;
coverpoint cmd;
coverpoint addr;
coverpoint data;
endgroup
...
// Function called through analysis port
function void write(my_tx t);
cmd = t.cmd;
addr = t.addr;
data = t.data;
cover_bus.sample();
endfunction
endclass
Finally, you instantiate both the monitor and the subscriber at the next level up in the component hierarchy and connect them as shown in the paper.
class my_env extends uvm_env;
`uvm_component_utils(my_env)
my_monitor monitor;
my_subscriber subscriber;
...
function void build;
super.build();
monitor = my_monitor::type_id::create( "monitor" , this);
subscriber = my_subscriber::type_id::create( "subscriber", this);
endfunction
function void connect;
monitor.aport.connect( subscriber.analysis_export );
endfunction
endclass
PS. All the source files for the code that is shown in the paper can be downloaded from the Doulos website.

- 1,293
- 10
- 19
the demo page can be shown like this:
`ifndef MY_MONITOR__SV
`define MY_MONITOR__SV
import uvm_pkg::*;
`include "uvm_macros.svh"
`include "my_transaction.sv"
class my_monitor extends uvm_monitor;
virtual my_if vif;
uvm_analysis_port #(my_transaction) ap; // to scoreboard
extern function new (string name,uvm_component parent);
extern virtual function void build_phase(uvm_phase phase);
extern virtual task main_phase(uvm_phase phase);
extern virtual task receive_one_pkt(ref my_transaction get_pkt);
`uvm_component_utils(my_monitor)
endclass
function my_monitor::new (string name,uvm_component parent);
super.new(name,parent);
endfunction
function void my_monitor::build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual my_if)::get(this,"","my_if",vif))
`uvm_fatal("my_monitor","Error in Getting interface");
ap=new("ap",this);
endfunction
task my_monitor::main_phase(uvm_phase phase);
my_transaction tr;
super.main_phase(phase);
while(1) begin
tr=new();
receive_one_pkt(tr);
ap.write(tr);
end
endtask
task my_monitor::receive_one_pkt(ref my_transaction get_pkt);
@(negedge vif.drv_cb.enable);
get_pkt.cout_r=vif.mon_cb.cout_r;
get_pkt.sum_r=vif.mon_cb.sum_r;
endtask
`endif
Mainly virtual inf and analysis_port, interfaces are accepted in build_phase, and calls to while(1) in mian_phase accept functions and ap.write(tr).