自动化生成UVM代理的脚本工具介绍

需积分: 50 11 下载量 186 浏览量 更新于2024-11-05 2 收藏 12KB ZIP 举报
资源摘要信息:"uvm_agent_gen:UVM代理生成器" UVM代理生成器是针对UVM(Universal Verification Methodology)环境的一个工具,其作用是自动化地生成UVM代理所需的代码。UVM代理是UVM验证环境中用来封装信号收集、通信和任务功能的组件。在UVM结构中,代理(Agent)是构建验证环境的一个核心组件,通常包括驱动器(Driver)、监视器(Monitor)和序列器(Sequencer)三个主要部分。 ### UVM代理生成器的关键知识点: 1. **UVM结构模板化**:UVM代理生成器允许用户根据UVM推荐的文件结构快速创建一套完整的代理模板。模板化意味着可以重复使用相同的结构来生成具有标准组织和命名规则的文件集。 2. **IDE模板局限性**:尽管许多集成开发环境(IDE)提供模板功能,但它们通常是针对单一文件。UVM代理包含多个相关联的文件,这些文件共同定义了代理的结构和功能。直接在IDE中生成模板可能会导致需要手动创建和维护这些关联文件,操作繁琐且容易出错。 3. **UVM文件结构**:UVM推荐的文件结构包括代理、驱动器、监视器和序列器各自的类定义文件,以及相应的事务(Transaction)、配置(Configuration)、代理控制(Agent Control)和功能覆盖(Functional Coverage)等文件。所有这些文件需要以一种协调一致的方式组织起来,以确保代理能正确运行。 4. **安装流程**:UVM代理生成器目前尚未被打包,因此用户需要通过git从仓库中克隆其源代码。这需要用户具备基本的git操作知识,能够使用命令行工具执行克隆(clone)操作。 5. **使用脚本生成代理**:用户通过命令行运行名为agent_gen.py的脚本,该脚本会根据用户提供的参数自动生成UVM代理的代码文件。这些参数包括代理名称和目标目录。 6. **参数说明**: - `--agent_name [name_of_your_agent]`:指定生成的代理文件中将要使用的名称。该名称将成为类定义和其他相关文件名的一部分。 - `--dest [generated_agent_directory]`:指定代理代码生成的目标文件夹路径。这是生成文件存放的目录,用户需要确保有相应的写入权限。 7. **SystemVerilog语言**:UVM是建立在SystemVerilog语言基础之上的,是专门为硬件验证而设计的超集语言。SystemVerilog提供了丰富的数据类型、设计和验证构造,使得创建可重用的、面向对象的验证组件变得更加容易。在使用UVM代理生成器时,用户需要熟悉SystemVerilog,以便能够理解和修改自动生成的代码。 8. **Python脚本**:agent_gen.py是一个Python脚本,它通常会使用一种模板引擎(如Jinja2)来填充模板文件,生成特定于用户需求的UVM代理代码。Python作为一种高级语言,在脚本编写和自动化任务中具有广泛的应用,尤其是在处理文本文件和执行系统操作方面。 9. **仓库目录结构**:压缩包子文件的文件名称列表显示的“uvm_agent_gen-master”表明了这是一个典型的源代码仓库目录结构。仓库中可能包含了用于生成代理的各种模板文件、脚本文件和可能的文档说明。 通过以上知识点的介绍,用户能够理解UVM代理生成器的主要作用、安装和使用方法以及它在UVM验证环境中的重要性。熟练掌握这些内容将有助于用户在使用UVM进行硬件验证时提高效率,减少重复性工作,并确保验证代码的一致性和可维护性。

请逐行注释下面的代码: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

2023-05-24 上传

class vbase_test extends uvm_test; `uvm_component_utils(vbase_test) env m_env; vseqr m_vseqr; int unsigned simSeed; function new(string name, uvm_component parent); super.new(name, parent); endfunction : new extern function void build_phase (uvm_phase phase); extern function void connect_phase (uvm_phase phase); extern task reset_phase(uvm_phase phase); extern task reset_reg_model(); extern function void end_of_elaboration_phase(uvm_phase phase); extern function void start_of_simulation_phase(uvm_phase phase); extern task main_phase(uvm_phase phase); // report test result extern virtual function void report_phase(uvm_phase phase); endclass : vbase_test function void vbase_test::build_phase (uvm_phase phase); super.build_phase(phase); m_env = env::type_id::create(.name("m_env"), .parent(this)); // virtual sequencer m_vseqr = vseqr::type_id::create(.name("m_vseqr"), .parent(this)); uvm_config_db# (uvm_object_wrapper)::set(this,"m_vseqr.main_phase","default_sequence",vBaseSeq::type_id::get()); //uvm_config_db# (uvm_object_wrapper)::set(this,"m_vseqr.main_phase","default_sequence",vUniBaseSeq#()::type_id::get()); endfunction : build_phase function void vbase_test::connect_phase (uvm_phase phase); m_vseqr.p_rm = m_env.m_reg_model; m_vseqr.i2c_seqr = m_env.m_i2c_agent.m_seqr; endfunction : connect_phase task vbase_test::reset_phase(uvm_phase phase); //`uvm_info(get_type_name(), {"REGISTER MODEL:\n", m_reg_model.sprint()}, UVM_MEDIUM) reset_reg_model(); super.reset_phase(phase); endtask task vbase_test::reset_reg_model(); forever begin wait (tb_top.reset_n == 0); m_env.m_reg_model.reset(); `uvm_info(get_type_name(), "Reseting Complete", UVM_MEDIUM) wait (tb_top.reset_n == 1); end endtask function void vbase_test::end_of_elaboration_phase(uvm_phase phase); int handle; $system("rm -rf TEST_RUNNING"); simSeed = $get_initial_random_seed(); handle = $fopen($psprintf("TEST_RUNNING_%0d",simSeed),"w"); $fclose(handle); handle = $fopen("caseSeed","w"); $fwrite(handle,"%0d",simSeed); $fclose(handle); if($test$plusargs("uvm_tree")) uvm_top.print_topology(); endfunction : end_of_elaboration_phase function void vbase_test::start_of_simulation_phase(uvm_phase phase); `uvm_info(get_type_name(), {"start of simulation for ", get_full_name()}, UVM_HIGH); endfunction : start_of_simulation_phase task vbase_test::main_phase(uvm_phase phase); phase.phase_done.set_drain_time(this, 200ns); endtask : main_phase // report test result function void vbase_test::report_phase(uvm_phase phase); uvm_report_server server; int handle; int unsigned err_num; super.report_phase(phase); server = get_report_server(); err_num = (server.get_severity_count(UVM_ERROR) + server.get_severity_count(UVM_FATAL)); simSeed = $get_initial_random_seed(); $display("\n********************************************************************************************\n"); if (err_num != 0) begin $display("TEST CASE FAILED!!!"); handle = $fopen($psprintf("TEST_FAILED_%0d",simSeed),"w"); end else begin $display("TEST CASE PASSED!!!"); handle = $fopen($psprintf("TEST_PASSED_%0d",simSeed),"w"); end $fclose(handle); $display("\n********************************************************************************************\n"); $system("rm -rf TEST_RUNNING*"); endfunction `endif

2023-07-25 上传