📡 UVM Subscriber (uvm_subscriber
)#
🔍 Introduction#
uvm_subscriber
is a UVM component that receives data from analysis ports and processes or reports it. Subscribers are typically used to collect coverage (e.g., functional coverage) or perform statistical analysis on data flowing through the testbench.
🤔 Why Use uvm_subscriber
?#
✅ Integration with Analysis Ports
uvm_subscriber
is designed to receive data directly from uvm_analysis_port
or uvm_analysis_export
connections.
✅ Coverage or Reporting It’s commonly used to:
- Collect and report coverage metrics.
- Track and report transaction statistics.
✅ Easy Connectivity
Thanks to its uvm_analysis_export
port, it can easily hook into monitors or scoreboards that generate analysis data.
🏗️ Basic Usage of uvm_subscriber
#
📦 Simple Subscriber Example#
virtual class uvm_subscriber #(type T=int) extends uvm_component;
typedef uvm_subscriber #(T) this_type;
uvm_analysis_imp #(T, this_type) analysis_export;
function new (string name, uvm_component parent);
super.new(name, parent);
analysis_export = new("analysis_imp", this);
endfunction
pure virtual function void write(T t);
endclass
// Subscriber for Functional Coverage
class adder_subscriber extends uvm_subscriber #(adder_transaction);
adder_transaction t;
covergroup adder_cg;
option.per_instance = 1;
num1_cov: coverpoint t.num1 {
bins low = {[0:100]};
bins mid = {[101:200]};
bins high = {[201:300]};
bins very_high = {[300:400]};
}
num2_cov: coverpoint t.num2 {
bins low = {[0:100]};
bins mid = {[101:200]};
bins high = {[201:300]};
}
endgroup
function new(string name = "adder_subscriber", uvm_component parent);
super.new(name, parent);
t = new("t");
adder_cg = new();
endfunction
`uvm_component_utils(adder_subscriber)
function void write(adder_transaction t);
this.t = t;
adder_cg.sample(); // Sample coverage directly
`uvm_info("SUBSCRIBER", $sformatf("Monitored: num1=%0d, num2=%0d, result=%0d",
t.num1, t.num2, t.result), UVM_MEDIUM)
endfunction
function void report_phase(uvm_phase phase);
super.report_phase(phase);
`uvm_info("COVERAGE", $sformatf("Coverage Summary: TOTAL=%.2f%%, num1=%.2f%%, num2=%.2f%%",
adder_cg.get_inst_coverage(),
adder_cg.num1_cov.get_inst_coverage(),
adder_cg.num2_cov.get_inst_coverage()), UVM_NONE)
endfunction
endclass
⚙️ How Does It Work?#
1️⃣ Data Reception
Data is received via the write()
method from analysis ports.
2️⃣ Analysis or Processing Inside the subscriber, the data can be analyzed for coverage, counted, or processed for statistics.
3️⃣ Reporting
Results can be reported at the end of the test via report_phase()
or other reporting mechanisms.
🔗 How to Connect#
Typically, a subscriber connects to the analysis port of a monitor:
agent.monitor.adder_send.connect(subscriber.analysis_export);
This way, every adder_packet
object sent by the monitor reaches the subscriber.
🚀 Key Features#
Feature | Description |
---|---|
Generic T | Works generically with any type (uvm_subscriber#(T) ) |
write() | Receives and processes data from analysis ports |
report_phase() | Reports processed results at the end of the test |
🎯 Conclusion#
Using uvm_subscriber
:
- Provides an easy way to collect and process data from the testbench.
- Is essential for collecting coverage or statistics.
- Works seamlessly with UVM’s analysis port infrastructure, making your testbench more modular and powerful.