| |
ResourceAccessForSequences
Sequences通常需要访问测试平台资源,例如寄存器模型或配置对象。执行此操作的方法是使用uvm_config_db访问资源,并将访问功能放入sequence基类的body()method中,该方法由从基类扩展的其他sequence使用。
有几种方法可以使用uvm_config_db来访问资源:
// Resource access using m_sequencer:
spi_env_config m_cfg;
task body();
if(!uvm_config_db #(spi_env_config)::get(m_sequencer, "", "spi_env_config", m_cfg)) begin
`uvm_error("BODY", "spi_env_config config_db lookup failed")
end
endtask: body
// Resource access using get_full_name():
spi_env_config m_cfg;
task body();
if(!uvm_config_db #(spi_env_config)::get(null, get_full_name(), "spi_env_config", m_cfg)) begin
`uvm_error("BODY", "spi_env_config config_db lookup failed")
end
endtask: body
// Resource access using pre-assigned lookup:
spi_env_config m_cfg;
task body();
if(!uvm_config_db #(spi_env_config)::get(null, "SPI_ENV::", "spi_env_config", m_cfg)) begin
`uvm_error("BODY", "spi_env_config config_db lookup failed")
end
endtask: body
前两个方法大多是等效的,因为它们是基于测试平台层次结构中的m_sequencer位置或测试平台层次结构中sequence的伪造位置创建范围路径字符串。第一种方法和第二种方法的区别在于,当m_sequencer作为参数传入get()函数时,get()函数将调用m_sequencer.get_full_name()。这将形成一个测试平台层次结构中的sequencer路径。这方面的一个例子可能是“uvm_test_top.env.my_agent.sequencer“。第二种方法是在sequence上调用get_full_name()。如果已在sequencer上启动sequence(m_sequencer句柄不为空),则sequence的get_full_name()调用将返回一个以 sequence的名称附加到sequencer后边作为结尾的路径。这方面的一个例子可能是“uvm_test_top.env.my_agent.sequencer.my_seq”。这对于在特定sequencer上运行的特定sequence上定位特定配置信息非常有用。第三种方法基于用户同意不同配置域的命名约定,这可能在特定项目或工作组内工作,但可能由于名称冲突而导致重用问题。
下面显示了一个base sequence实现的完整示例。然后,任何继承sequence都会调用base sequence 的body()method,以确保在开始生成激励进程之前设置资源句柄。
//
// Sequence that needs to access a test bench resource via
// the configuration space
//
// Note that this is a base class any class extending it would
// call super.body() at the start of its body task to get set up
//
class register_base_seq extends uvm_sequence #(bus_seq_item);
`uvm_object_utils(register_base_seq)
// Handle for the actual sequencer to be used:
bus_sequencer BUS;
// Handle for the environment configuration object:
bus_env_config env_cfg;
// Handle for the register model
dut_reg_model RM;
function new(string name = "register_base_seq");
super.new(name);
endfunction
task body;
// Get the configuration object for the env - using get_full_name()
if(!uvm_config_db #(bus_env_config)::get(null, get_full_name(), "bus_config", env_cfg)) begin
`uvm_error("BODY", "Failed to find bus_env_config in the config_db")
end
// Assign a pointer to the register model which is inside the env config object:
RM = env_cfg.register_model;
endtask: body
endclass: register_base_seq
//
// An inheriting sequence:
//
class initialisation_seq extends register_base_seq;
`uvm_object_utils(initialisation_seq)
task body;
super.body(); // assign the resource handles
//
// Sequence body code
//
endtask: body
endclass: initialistion_seq
使用此技术的另一个示例是访问配置对象中的虚拟接口以等待硬件事件。