| |
ProtocolModules
协议模块是把DUT接口、相关断言、QVL实例(不允许放在接口内)等等封装在一起的包装模块。当emulation是一个考虑因素时,协议模块提供了一定程度的封装,以隔离在simulation和emulation之间转换时agent和interface中发生的变化。如果测试平台仅用于simulation,那协议模块则不是必需的。然而,它们仍然可以为模块化、可重用性等目的提供有用的封装级别。虽然协议模块不需要与双顶层方法一起使用,但它可能主要用于双顶层方法,因为它也是emulation所必需的。
【此处需一幅图】
通过采用封装,协议模块可以保护顶层不受更改:
例子:
【此处需一幅图】
在该示例中,以太网媒体访问控制器(MAC)是DUT。MAC有多个接口。示例中显示的是媒体独立接口(MII),以太网数据包被传输到物理接口。在此示例中,协议模块包含MII接口实例、QVL MII monitor以及使用UVM Resources将接口实例位置放入配置数据库(config_db)的代码。
module mac_mii_protocol_module #(string INTERFACE_NAME = "") (
input logic wb_rst_i,
// Tx
output logic mtx_clk_pad_o, // Transmit clock (from PHY)
input logic[3:0] mtxd_pad_o, // Transmit nibble (to PHY)
input logic mtxen_pad_o, // Transmit enable (to PHY)
input logic mtxerr_pad_o, // Transmit error (to PHY)
// Rx
output logic mrx_clk_pad_o, // Receive clock (from PHY)
output logic[3:0] mrxd_pad_i, // Receive nibble (from PHY)
output logic mrxdv_pad_i, // Receive data valid (from PHY)
output logic mrxerr_pad_i, // Receive data error (from PHY)
// Common Tx and Rx
output logic mcoll_pad_i, // Collision (from PHY)
output logic mcrs_pad_i, // Carrier sense (from PHY)
// MII Management interface
output logic md_pad_i, // MII data input (from I/O cell)
input logic mdc_pad_o, // MII Management data clock (to PHY)
input logic md_pad_o, // MII data output (to I/O cell)
input logic md_padoe_o // MII data output enable (to I/O cell)
);
import uvm_container_pkg::*;
// Instantiate interface
mii_if miim_if();
// Connect interface to protocol signals through module ports
assign mtx_clk_pad_o = miim_if.mtx_clk;
assign miim_if.MTxD = mtxd_pad_o;
assign miim_if.MTxEn = mtxen_pad_o;
assign miim_if.MTxErr = mtxerr_pad_o ;
assign mrx_clk_pad_o = miim_if.mrx_clk;
assign mrxd_pad_i = miim_if.MRxD;
assign mrxdv_pad_i = miim_if.MRxDV ;
assign mrxerr_pad_i = miim_if.MRxErr ;
assign mcoll_pad_i = miim_if.MColl ;
assign mcrs_pad_i = miim_if.MCrs ;
assign md_pad_i = miim_if.Mdi_I ;
assign miim_if.Mdc_O = mdc_pad_o ;
assign miim_if.Mdo_O = md_pad_o ;
assign miim_if.Mdo_OE = md_padoe_o ;
// Instantiate QVL Checker
qvl_gigabit_ethernet_mii_monitor mii_monitor(
.areset(1'b0),
.reset(wb_rst_i),
.tx_clk(miim_if.mtx_clk),
.txd(miim_if.MTxD),
.tx_en(miim_if.MTxEn),
.tx_er(miim_if.MTxErr),
.rx_clk(miim_if.mrx_clk),
.rxd(miim_if.MRxD),
.rx_dv(miim_if.MRxDV),
.rx_er(miim_if.MRxErr),
.col(miim_if.MColl),
.crs(miim_if.MCrs) ,
.half_duplex(1'b0)
);
// Connect interface to testbench virtual interface
string interface_name = (INTERFACE_NAME == "") ? $sformatf("%m") : INTERFACE_NAME;
initial begin
uvm_container #(virtual mii_if)::set_value_in_global_config(interface_name, miim_if);
end
endmodule
应注意,如果未设置参数INTERFACE _ NAME,则默认值为%m(即,该模块的分层路径)。这保证是独一无二的。如果明确设置了此参数,则设计人员需要确保所选名称在封闭模块中是唯一的。
(在http://verificationacademy.com/uvm-ovm上在线下载源代码示例)。