class mcdf_env extends uvm_env;
// Array of channel agents (4 channels)
chnl_agent chnl_agts[4];
// APB master agent for register access
apb_master_agent reg_agt;
// Formatter agent
fmt_agent fmt_agt;
// Scoreboard for checking data correctness
mcdf_checker chker;
// Virtual sequencer for coordinating transactions
mcdf_virtual_sequencer virt_sqr;
// Register model
mcdf_rgm rgm;
// Adapter between register and mcdf
reg2mcdf_adapter adapter;
// Bus analyzer for performance analysis
mcdf_bus_analyzer analyzer;
// Register predictor
uvm_reg_predictor #(apb_transfer) predictor;
`uvm_component_utils(mcdf_env)
// Constructor
function new (string name = "mcdf_env", uvm_component parent);
super.new(name, parent);
endfunction
// Build phase: Create and instantiate components
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// Create checker
this.chker = mcdf_checker::type_id::create("chker", this);
// Create channel agents
foreach(chnl_agts[i]) begin
this.chnl_agts[i] = chnl_agent::type_id::create($sformatf("chnl_agts[%0d]",i), this);
end
// Create register agent
this.reg_agt = apb_master_agent::type_id::create("reg_agt", this);
// Create formatter agent
this.fmt_agt = fmt_agent::type_id::create("fmt_agt", this);
// Create virtual sequencer
virt_sqr = mcdf_virtual_sequencer::type_id::create("virt_sqr", this);
// Create register model
rgm = mcdf_rgm::type_id::create("rgm", this);
rgm.build(); // Build the register model
// Set register model in the config DB (accessible by other components)
uvm_config_db#(mcdf_rgm)::set(this,"*","rgm", rgm);
// Create adapter
adapter = reg2mcdf_adapter::type_id::create("adapter", this);
// Create register predictor
predictor = uvm_reg_predictor#(apb_transfer)::type_id::create("predictor", this);
// Create bus analyzer
analyzer = mcdf_bus_analyzer::type_id::create("analyzer", this);
endfunction
// Connect phase: Connect components
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
// Connect channel agent monitors to checker and analyzer
foreach(chnl_agts[i]) begin
chnl_agts[i].monitor.mon_ana_port.connect(chker.chnl_tlm_fifos[i].analysis_export);
chnl_agts[i].monitor.mon_ana_port.connect(analyzer.chnl_tlm_fifos[i].analysis_export);
end
// Connect register agent monitor to analyzer
reg_agt.monitor.item_collected_port.connect(analyzer.reg_tlm_fifo.analysis_export);
// Connect formatter agent monitor to checker and analyzer
fmt_agt.monitor.mon_ana_port.connect(chker.fmt_tlm_fifo.analysis_export);
fmt_agt.monitor.mon_ana_port.connect(analyzer.fmt_tlm_fifo.analysis_export);
// Connect virtual sequencer to agent sequencers
virt_sqr.reg_sqr = reg_agt.sequencer;
virt_sqr.fmt_sqr = fmt_agt.sequencer;
foreach(virt_sqr.chnl_sqrs[i]) virt_sqr.chnl_sqrs[i] = chnl_agts[i].sequencer;
// Set sequencer for register map
rgm.map.set_sequencer(reg_agt.sequencer, adapter);
// Connect register agent monitor to predictor
reg_agt.monitor.item_collected_port.connect(predictor.bus_in);
// Set predictor parameters
predictor.map = rgm.map;
predictor.adapter = adapter;
endfunction
endclass: mcdf_env
功能分析:
mcdf_env类设置了一个完整的验证环境。它实例化并连接了几个关键组件:
agent:chnl_agts(通道agent)、reg_agt(寄存器agent)和fmt_agt(整形器agent)在各自的接口上驱动和监视事务。每个代理可能都有一个驱动程序、监视器和序列器。
比较器:chker(mcdf_checker)将监控的事务与参考模型中的预期值进行比较,以验证功能的正确性。
Virtual Sequencer:virt_sqr协调多个代理之间的事务顺序,确保正确的排序和同步。
寄存器模型:rgm提供寄存器的模型,包括它们的地址和字段。这对于注册访问验证至关重要。
适配(转换)器:适配器可能处理注册代理和mcdf之间的任何必要的数据转换。
总线分析器:分析器监控总线活动以进行性能分析,计算带宽和延迟等指标。
寄存器预测器:预测器根据事务预测寄存器值,可能用于性能优化或覆盖率分析。
build_phase创建所有这些组件。connect_phase建立它们之间的连接,定义事务数据和控制信号的流。数据通过监视器流向记分板(chker)进行功能验证,并流向分析器(analyzer)进行性能分析。寄存器预测器(预测器)从寄存器代理的监视器接收数据。虚拟定序器(virt_sqr)协调整个过程。rgm(寄存器模型)至关重要;它被构建并放置在UVM配置数据库中,以便其他组件可以访问它。适配器可能有助于在不同数据格式之间进行转换。
该环境专为综合验证策略而设计,结合了功能和性能检查。通过FIFO使用TLM(事务级建模)在监视器和其他组件之间的连接中显而易见。使用uvm_reg_presearcher表明采用了先进的验证技术。每个组件的具体功能取决于它们各自的实现(此代码片段中未显示)。