在UART项目的学习过程中,发现对于uart_env层次的各组件连接关系理解易于混淆,于是梳理了一下各组件的连接关系,绘制如下所示层次图。下面会简述一下各组件的连接方法。
- 首先,对于一个uart_env模块,其内部例化了uart_env_config的配置模块,可以对apb,uart, modem这三个不同协议的agent进行配置。
- 在apb_agent模块中,有一个analysis_port端口,连接reg_predictor,通过ap端口,将apb_agent中由monitor收集到的数据交给寄存器模型,更新镜像值和期望值。在predictor中也实例了一个adapter,用来实现seq_item和reg_item间的转化。
- 同样,将ap端口连接到uart_interrupt_coverage_monitor模块,收集不同中断信号覆盖率。
- ap端口连接uart_modem_coverage_monitor模块,uart_modem_coverage_monitor是uvm_subscriber的拓展类,uvm_subscriber用于功能覆盖率收集,字面意思即订阅者,ap端口就相当于一个中央系统,当他发出数据时,所有订阅它的组件均会收到ap发出的数据。uvm_subscriber其中有内建的端口analysis_export,实际为imp类型。拓展类中需要定义write函数,uvm_subscriber中write为pure virtual型,必须重载后拓展类才能实例化。 write在apb_monitor中由port发起。
- ap端口连接uart_reg_access_coverage_monitor,同样,这也是一个覆盖率收集模块,用于监测是否寄存器的通路被打通,每个寄存器是否被访问到。
- apb_agent中的ap端口同样分别连接了uart_rx_scoreboard,uart_tx_scoreboard和modem_scoreboard。分别实现RXD 接收数据相关的数据比对;TXD 接收数据相关的数据比对; modem有关数据的比对。与baud_rate_checker连接,通过其中的fifo实现了对时钟和分频相关的检测。
部分代码如下:
function void uart_env::connect_phase(uvm_phase phase);
// Register model connections
m_cfg.rm.map.set_sequencer(m_apb_agent.m_sequencer, reg_adapter);//将adapter和bus_sequencer通过set_sequencer函数告知reg_model的default_map
reg_predictor.map = m_cfg.rm.map;
reg_predictor.adapter = reg_adapter;
m_apb_agent.ap.connect(reg_predictor.bus_in);
// Analysis component connections:
m_apb_agent.ap.connect(tx_sb.apb_fifo.analysis_export);
m_tx_uart_agent.ap.connect(tx_sb.uart_fifo.analysis_export);
tx_sb.rm = m_cfg.rm;
m_apb_agent.ap.connect(rx_sb.apb_fifo.analysis_export);
m_rx_uart_agent.ap.connect(rx_sb.uart_fifo.analysis_export);
rx_sb.rm = m_cfg.rm;
m_apb_agent.ap.connect(modem_sb.apb_fifo.analysis_export);
m_modem_agent.ap.connect(modem_sb.modem_fifo.analysis_export);
tx_sb.ap.connect(tx_cov.analysis_export);
m_apb_agent.ap.connect(int_cov.apb_fifo.analysis_export);
int_cov.cfg = m_cfg;
int_cov.rm = m_cfg.rm;
modem_cov.rm = m_cfg.rm;
m_apb_agent.ap.connect(modem_cov.analysis_export);
rx_sb.ap.connect(rx_cov.analysis_export);
br_sb.rm = m_cfg.rm;
br_sb.IRQ = m_cfg.IRQ;
m_apb_agent.ap.connect(br_sb.apb_fifo.analysis_export);
m_apb_agent.ap.connect(reg_cov.analysis_export);
endfunction: connect_phase