uvm_factory f = uvm_factory::get();
时间: 2024-05-25 22:19:26 浏览: 207
This line of code retrieves a singleton instance of the UVM factory, which is responsible for creating and managing UVM components. The factory can be used to create new instances of components based on their type names, and to register new component types with the UVM framework.
相关问题
请逐行注释下面的代码:class riscv_instr_base_test extends uvm_test; riscv_instr_gen_config cfg; string test_opts; string asm_file_name = "riscv_asm_test"; riscv_asm_program_gen asm_gen; string instr_seq; int start_idx; uvm_coreservice_t coreservice; uvm_factory factory; uvm_component_utils(riscv_instr_base_test) function new(string name="", uvm_component parent=null); super.new(name, parent); void'($value$plusargs("asm_file_name=%0s", asm_file_name)); void'($value$plusargs("start_idx=%0d", start_idx)); endfunction virtual function void build_phase(uvm_phase phase); super.build_phase(phase); coreservice = uvm_coreservice_t::get(); factory = coreservice.get_factory(); uvm_info(gfn, "Create configuration instance", UVM_LOW) cfg = riscv_instr_gen_config::type_id::create("cfg"); uvm_info(gfn, "Create configuration instance...done", UVM_LOW) uvm_config_db#(riscv_instr_gen_config)::set(null, "*", "instr_cfg", cfg); if(cfg.asm_test_suffix != "") asm_file_name = {asm_file_name, ".", cfg.asm_test_suffix}; // Override the default riscv instruction sequence if($value$plusargs("instr_seq=%0s", instr_seq)) begin factory.set_type_override_by_name("riscv_instr_sequence", instr_seq); end if (riscv_instr_pkg::support_debug_mode) begin factory.set_inst_override_by_name("riscv_asm_program_gen", "riscv_debug_rom_gen", {gfn, ".asm_gen.debug_rom"}); end endfunction function void report_phase(uvm_phase phase); uvm_report_server rs; int error_count; rs = uvm_report_server::get_server(); error_count = rs.get_severity_count(UVM_WARNING) + rs.get_severity_count(UVM_ERROR) + rs.get_severity_count(UVM_FATAL); if (error_count == 0) begin uvm_info("", "TEST PASSED", UVM_NONE); end else begin uvm_info("", "TEST FAILED", UVM_NONE); end uvm_info("", "TEST GENERATION DONE", UVM_NONE); super.report_phase(phase); endfunction virtual function void apply_directed_instr(); endfunction task run_phase(uvm_phase phase); int fd; for(int i = 0; i < cfg.num_of_tests; i++) begin string test_name; randomize_cfg(); riscv_instr::create_instr_list(cfg); riscv_csr_instr::create_csr_filter(cfg); asm_gen = riscv_asm_program_gen::type_id::create("asm_gen", , gfn); asm_gen.cfg = cfg; asm_gen.get_directed_instr_stream(); test_name = $sformatf("%0s_%0d.S", asm_file_name, i+start_idx); apply_directed_instr(); uvm_info(gfn, "All directed instruction is applied", UVM_LOW) asm_gen.gen_program(); asm_gen.gen_test_file(test_name); end endtask virtual function void randomize_cfg(); DV_CHECK_RANDOMIZE_FATAL(cfg); uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s", cfg.sprint()), UVM_LOW) endfunction endclass
这是一个 SystemVerilog 类定义,定义了一个名为 riscv_instr_base_test 的类,继承自 uvm_test。下面是代码解释:
```
class riscv_instr_base_test extends uvm_test;
```
定义一个名为 riscv_instr_base_test 的类,继承自 uvm_test。
```
riscv_instr_gen_config cfg;
```
定义一个名为 cfg 的 riscv_instr_gen_config 类型变量。
```
string test_opts;
```
定义一个名为 test_opts 的字符串类型变量。
```
string asm_file_name = "riscv_asm_test";
```
定义一个名为 asm_file_name 的字符串类型变量,并将其初始化为 "riscv_asm_test"。
```
riscv_asm_program_gen asm_gen;
```
定义一个名为 asm_gen 的 riscv_asm_program_gen 类型变量。
```
string instr_seq;
```
定义一个名为 instr_seq 的字符串类型变量。
```
int start_idx;
```
定义一个名为 start_idx 的整型变量。
```
uvm_coreservice_t coreservice;
```
定义一个名为 coreservice 的 uvm_coreservice_t 类型变量。
```
uvm_factory factory;
```
定义一个名为 factory 的 uvm_factory 类型变量。
```
uvm_component_utils(riscv_instr_base_test)
```
宏定义,用于简化组件注册过程。
```
function new(string name="", uvm_component parent=null);
```
定义一个构造函数 new。
```
super.new(name, parent);
```
调用父类 uvm_test 的构造函数。
```
void'($value$plusargs("asm_file_name=%0s", asm_file_name));
void'($value$plusargs("start_idx=%0d", start_idx));
```
从命令行参数中获取 asm_file_name 和 start_idx 的值。
```
endfunction
```
构造函数结束。
```
virtual function void build_phase(uvm_phase phase);
```
定义一个虚函数 build_phase,用于实现组件的构建过程。
```
super.build_phase(phase);
```
调用父类 uvm_test 的 build_phase 函数。
```
coreservice = uvm_coreservice_t::get();
factory = coreservice.get_factory();
```
获取 uvm_coreservice_t 和 uvm_factory 实例。
```
uvm_info(gfn, "Create configuration instance", UVM_LOW)
cfg = riscv_instr_gen_config::type_id::create("cfg");
```
创建 riscv_instr_gen_config 的实例 cfg。
```
uvm_info(gfn, "Create configuration instance...done", UVM_LOW)
```
输出一条消息,表示创建配置实例完成。
```
uvm_config_db#(riscv_instr_gen_config)::set(null, "*", "instr_cfg", cfg);
```
将 cfg 对象存储到配置数据库中。
```
if(cfg.asm_test_suffix != "") asm_file_name = {asm_file_name, ".", cfg.asm_test_suffix};
```
如果配置文件中指定了 asm_test_suffix,则将其添加到 asm_file_name 的末尾。
```
if($value$plusargs("instr_seq=%0s", instr_seq)) begin
factory.set_type_override_by_name("riscv_instr_sequence", instr_seq);
end
```
如果命令行参数中指定了 instr_seq,则使用该指令序列进行测试。
```
if (riscv_instr_pkg::support_debug_mode) begin
factory.set_inst_override_by_name("riscv_asm_program_gen", "riscv_debug_rom_gen", {gfn, ".asm_gen.debug_rom"});
end
```
如果支持调试模式,则为 riscv_asm_program_gen 组件设置调试 ROM。
```
endfunction
```
build_phase 函数结束。
```
function void report_phase(uvm_phase phase);
```
定义一个 report_phase 函数,用于在测试结束时输出测试结果。
```
uvm_report_server rs;
int error_count;
rs = uvm_report_server::get_server();
```
获取 uvm_report_server 实例。
```
error_count = rs.get_severity_count(UVM_WARNING) + rs.get_severity_count(UVM_ERROR) + rs.get_severity_count(UVM_FATAL);
```
获取测试过程中出现的警告、错误和致命错误的数量。
```
if (error_count == 0) begin
uvm_info("", "TEST PASSED", UVM_NONE);
end else begin
uvm_info("", "TEST FAILED", UVM_NONE);
end
```
根据错误数量输出测试结果。
```
uvm_info("", "TEST GENERATION DONE", UVM_NONE);
```
输出一条消息,表示测试生成完成。
```
super.report_phase(phase);
```
调用父类 uvm_test 的 report_phase 函数。
```
endfunction
```
report_phase 函数结束。
```
virtual function void apply_directed_instr();
```
定义一个虚函数 apply_directed_instr,用于实现针对指定指令的测试。
```
endfunction
```
apply_directed_instr 函数结束。
```
task run_phase(uvm_phase phase);
```
定义一个任务 run_phase,用于执行测试过程。
```
int fd;
for(int i = 0; i < cfg.num_of_tests; i++) begin
string test_name;
randomize_cfg();
riscv_instr::create_instr_list(cfg);
riscv_csr_instr::create_csr_filter(cfg);
asm_gen = riscv_asm_program_gen::type_id::create("asm_gen", , gfn);
asm_gen.cfg = cfg;
asm_gen.get_directed_instr_stream();
test_name = $sformatf("%0s_%0d.S", asm_file_name, i+start_idx);
apply_directed_instr();
uvm_info(gfn, "All directed instruction is applied", UVM_LOW)
asm_gen.gen_program();
asm_gen.gen_test_file(test_name);
end
```
根据配置文件中指定的测试数量循环执行测试:
- 调用 randomize_cfg 函数,随机生成测试配置。
- 调用 create_instr_list 函数,生成指令序列。
- 调用 create_csr_filter 函数,生成 CSR 过滤器。
- 创建 riscv_asm_program_gen 组件实例 asm_gen。
- 将 cfg 对象赋值给 asm_gen 的 cfg 变量。
- 调用 get_directed_instr_stream 函数,获取指定指令流。
- 为测试生成一个文件名,格式为 asm_file_name_测试编号.S。
- 调用 apply_directed_instr 函数,应用指定指令。
- 输出一条消息,表示所有指定指令已经被应用。
- 调用 gen_program 函数,生成汇编代码。
- 调用 gen_test_file 函数,生成测试文件。
```
endtask
```
run_phase 任务结束。
```
virtual function void randomize_cfg();
```
定义一个虚函数 randomize_cfg,用于随机生成测试配置。
```
DV_CHECK_RANDOMIZE_FATAL(cfg);
uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s", cfg.sprint()), UVM_LOW)
```
调用 DV_CHECK_RANDOMIZE_FATAL 宏检查随机化过程是否成功,并输出配置信息。
```
endfunction
```
randomize_cfg 函数结束。
```
endclass
```
riscv_instr_base_test 类定义结束。
uvm_factory 全局改变所有组件类型
uvm_factory 可以用来改变所有组件类型,但这并不是一个好的实践。通过全局改变组件类型,可能会导致系统的行为变得不可预测,因为所有组件的行为都会被影响。
更好的实践是在需要改变组件类型时,只对特定的组件进行修改。这可以通过在需要修改的组件中使用 uvm_object_param_utils 宏来实现。这个宏会创建一个名为 "type_name" 的参数,并在组件的构造函数中使用这个参数来设置组件的类型。
例如,假设我们有一个名为 my_component 的组件,它的类型为 my_component_type。如果我们想要将它的类型改为 my_new_component_type,我们可以在 my_component 中添加以下代码:
```verilog
class my_component extends uvm_component;
// Declare the type_name parameter
`uvm_object_param_utils(my_component)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// Set the component type based on the type_name parameter
uvm_factory #(my_new_component_type)::type_id::set_type_override_by_name(get_full_name(), "my_new_component_type", "my_component_type");
endfunction
endclass
```
这样,只有 my_component 的类型会被改变,而其他组件的类型仍然保持不变。
阅读全文
相关推荐
![-](https://img-home.csdnimg.cn/images/20241231044930.png)
![-](https://img-home.csdnimg.cn/images/20241231044930.png)
![-](https://img-home.csdnimg.cn/images/20241231044930.png)
![-](https://img-home.csdnimg.cn/images/20241231044901.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)