UVM技术问询:非uvm_subscriber类中uvm_analysis_export与write函数的连接方法
Background
I'm familiar with two design patterns for writing UVM subscribers:
- Inherit from
uvm_subscriber, override thewritefunction which gets called automatically by the built-in analysis port. - Inherit from
uvm_component, instantiate auvm_analysis_exportanduvm_tlm_analysis_fifo, connect them, and process transactions in therun_phase.
Question
If I instead inherit from uvm_component, instantiate a uvm_analysis_export, and write my own write function, how can I hook up the export to call this write function when the corresponding analysis port sends a transaction? Is this even feasible?
Answer
Great question! This is totally feasible—you just need a uvm_analysis_imp to bridge the uvm_analysis_export and your custom write function. Let me walk you through exactly how to do this with code examples:
Set up your component structure
Create your custom component extendinguvm_component, and declare two key TLM objects:- A
uvm_analysis_exportto accept connections from external analysis ports. - A
uvm_analysis_imp—this is the "implementation" layer that links directly to yourwritefunction.
- A
Implement the required
writefunction
Theuvm_analysis_impexpects awritefunction with a signature matching your transaction type. Make itvirtualto follow UVM best practices.Connect export and imp in the connect phase
After instantiating both objects, connect the export to the imp. This routes any transactions sent to the export straight to your customwritefunction.
Example Code
class my_custom_subscriber extends uvm_component; // Replace with your actual transaction type typedef my_transaction trans_type; // TLM interfaces uvm_analysis_export#(trans_type) analysis_export; uvm_analysis_imp#(trans_type, my_custom_subscriber) analysis_imp; `uvm_component_utils(my_custom_subscriber) function new(string name = "my_custom_subscriber", uvm_component parent = null); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); // Instantiate export and imp analysis_export = new("analysis_export", this); analysis_imp = new("analysis_imp", this); endfunction function void connect_phase(uvm_phase phase); super.connect_phase(phase); // Link export to imp to forward transactions to our write function analysis_export.connect(analysis_imp); endfunction // Custom transaction handling logic virtual function void write(trans_type t); `uvm_info("CUSTOM_SUBSCRIBER", $sformatf("Received transaction: %s", t.convert2string()), UVM_MEDIUM) // Add your transaction processing code here endfunction endclass
Why this works
- The
uvm_analysis_exportacts as a public entry point for external analysis ports to connect to your component. - The
uvm_analysis_impis a TLM implementation interface that enforces the component to provide awritemethod. When you connect the export to the imp, anywritecalls from external ports are forwarded to the imp, which triggers your customwritefunction.
This approach gives you the flexibility of using a plain uvm_component while still leveraging UVM's TLM analysis infrastructure—you don't need a uvm_tlm_analysis_fifo unless you specifically want to buffer transactions for processing in the run_phase.
内容的提问来源于stack exchange,提问作者Andy




