class_start main 执行了啥?

本文介绍了init.rc配置文件中的关键部分及其工作原理,特别是如何通过mount_all指令实现文件系统的挂载,并触发nonencrypted动作,进而启动系统的主要服务。


init.rc中是import init.${hardware}.rc, 中定义

on fs
    mount_all /fstab.chipset
    mount pstore pstore /sys/fs/pstore
    setprop ro.crypto.fuse_sdcard true
	symlink /system/res /res
	symlink /system/bin /bin


mount_all对应于:

KEYWORD(mount_all,   COMMAND, 1, do_mount_all)


else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED || !enusure_data_mounted()) {
    /* @} */
        property_set("ro.crypto.state", "unencrypted");
        /* If fs_mgr determined this is an unencrypted device, then trigger
         * that action.
         */
        action_for_each_trigger("nonencrypted", action_add_queue_tail);
    }

mount_all里面会触发nonencrypted的action
on nonencrypted
     class_start main
     class_start late_start

只是加入action_queue的队列中:

之后在init的for(;;)中执行class_start main?


<think>我们正在讨论UVM中的`uvm_sequence_library`如何执行sequence。根据提供的引用,我们可以总结如下: 1. **创建sequence library**:首先需要定义一个继承自`uvm_sequence_library`的类,并调用`init_sequence_library()`进行初始化[^1]。 2. **添加sequence**:可以通过`add_sequence()`, `add_typewide_sequence()`或`add_typewide_sequences()`方法将sequence添加到library中[^2]。 3. **执行机制**:`uvm_sequence_library`在启动时,会从其包含的sequence集合中随机选择并执行sequence。具体来说,它通过`execute()`方法使用`uvm_rand_send`宏来启动子sequence[^3]。 4. **调度模式**:`uvm_sequence_library`支持两种调度模式:`UVM_SEQ_LIB_RAND`(完全随机)和`UVM_SEQ_LIB_RANDC`(循环随机)[^4]。 ### 执行流程详解 1. **配置阶段**: - 在test的build_phase中,将sequence library设置为sequencer的default_sequence: ```systemverilog uvm_config_db#(uvm_object_wrapper)::set(this, "env.agent.sqr.main_phase", "default_sequence", my_sequence_lib::get_type()); ``` - 或者通过`uvm_config_db`设置library的`selection_mode`属性(可选,默认为UVM_SEQ_LIB_RAND)。 2. **添加sequence到library**: - 在sequence library的构造函数中,使用`add_sequence`或`add_typewide_sequence`添加具体的sequence类型: ```systemverilog function my_sequence_lib::new(string name="my_sequence_lib"); super.new(name); add_sequence(seq1::get_type()); // 添加单个sequence add_typewide_sequences({seq2::get_type(), seq3::get_type()}); // 添加多个 init_sequence_library(); // 必须调用 endfunction ``` 注意:`add_sequence`添加的sequence仅对当前实例有效,而`add_typewide_sequence`添加的sequence对该类型的所有实例都有效[^2]。 3. **启动阶段**: - 当UVM运行到相应phase(如main_phase)时,sequencer会启动sequence library的body任务。 - `uvm_sequence_library`的body任务会循环执行以下操作: - 根据`selection_mode`(UVM_SEQ_LIB_RAND或UVM_SEQ_LIB_RANDC)选择一个子sequence。 - 使用`uvm_rand_send`宏启动该子sequence。 4. **子sequence的执行**: - `uvm_rand_send`宏实际上调用了子sequence的`start_item`和`finish_item`,但注意它**不会调用子sequence的`pre_body()`和`post_body()`方法**[^3]。 - 因此,如果子sequence有需要在执行前初始化的操作,应该放在`body()`任务中,而不是`pre_body()`中。 ### 关键注意事项 1. **`pre_body`不被调用**:由于`uvm_sequence_library`使用`uvm_rand_send`启动子sequence,这会绕过子sequence的`pre_body`和`post_body`方法[^3]。因此,必须将初始化代码放在`body()`中。 2. **调度模式**: - `UVM_SEQ_LIB_RAND`:每次随机选择任意sequence,可能连续多次选择同一个sequence。 - `UVM_SEQ_LIB_RANDC`:循环随机,确保每个sequence在循环中都被执行一次,然后再重新排列[^4]。 3. **控制执行次数**: - 可以通过设置`min_random_count`和`max_random_count`属性来控制sequence library执行子sequence的次数范围。 - 例如:在test中配置: ```systemverilog uvm_config_db#(int)::set(this, "env.agent.sqr.main_phase.default_sequence", "min_random_count", 5); uvm_config_db#(int)::set(this, "env.agent.sqr.main_phase.default_sequence", "max_random_count", 10); ``` 这样,sequence library会随机执行5到10个子sequence。 ### 示例代码 ```systemverilog // 定义两个子sequence class short_packet_seq extends uvm_sequence #(my_transaction); `uvm_object_utils(short_packet_seq) task body(); `uvm_do_with(req, {data.size() < 10;}) endtask endclass class long_packet_seq extends uvm_sequence #(my_transaction); `uvm_object_utils(long_packet_seq) task body(); `uvm_do_with(req, {data.size() >= 10;}) endtask endclass // 定义sequence library class my_seq_lib extends uvm_sequence_library #(my_transaction); `uvm_object_utils(my_seq_lib) `uvm_sequence_library_utils(my_seq_lib) function new(string name="my_seq_lib"); super.new(name); // 添加sequence add_sequence(short_packet_seq::get_type()); add_sequence(long_packet_seq::get_type()); init_sequence_library(); endfunction endclass // 在test中设置 class my_test extends uvm_test; function void build_phase(uvm_phase phase); // 设置default_sequence为sequence library uvm_config_db#(uvm_object_wrapper)::set(this, "env.agent.sqr.main_phase", "default_sequence", my_seq_lib::get_type()); // 设置调度模式为RANDC(可选) uvm_config_db#(int)::set(this, "env.agent.sqr.main_phase.default_sequence", "selection_mode", UVM_SEQ_LIB_RANDC); endfunction endclass ``` ### 总结 - `uvm_sequence_library`提供了一种便捷的方式来随机或循环执行一组预定义的sequence。 - 注意子sequence的`pre_body`和`post_body`不会被调用,因此相关逻辑应放在`body()`中。 - 通过`selection_mode`控制调度策略,通过`min_random_count`和`max_random_count`控制执行次数。 §§相关问题§§ 1. 如何在UVM sequence library中控制不同sequence的执行权重? 2. UVM sequence library的`selection_mode`具体实现原理是什么? 3. 为什么`uvm_sequence_library`不调用子sequence的`pre_body`和`post_body`方法? 4. 如何动态修改UVM sequence library中可用的sequence集合? 5. 在UVM中,sequence library与virtual sequence有何区别和联系?</think>### UVM sequence_library 执行 sequence 的机制和流程 在UVM中,`uvm_sequence_library` 是一种特殊类型的sequence,用于管理和执行一组预定义的子sequence。其核心机制如下: #### 一、执行流程 1. **初始化阶段** - 创建sequence library时需调用 `init_sequence_library()`[^1] - 通过 `add_sequence()`, `add_typewide_sequence()` 或 `add_typewide_sequences()` 添加子sequence[^2] ```systemverilog function new(string name = "my_sequence_lib"); super.new(name); add_sequence(seq_A::get_type()); // 添加单个sequence add_typewide_sequences({seq_B::get_type(), seq_C::get_type()}); // 添加多个 init_sequence_library(); // 关键初始化 endfunction ``` 2. **启动阶段** - 在目标phase(如main_phase)通过sequencer启动: ```systemverilog uvm_config_db#(uvm_object_wrapper)::set(this, "env.agent.sqr.main_phase", "default_sequence", my_sequence_lib::get_type()); ``` 3. **调度执行阶段** - 通过 `execute()` 方法使用宏 `uvm_rand_send(seq_or_item)` 启动子sequence[^3] - 此宏等效于: ```systemverilog seq.start(p_sequencer, this, priority, call_pre_post); ``` - **关键特性**:此方式会绕过子sequence的 `pre_body()` 和 `post_body()` 方法[^3] 4. **调度策略** - `UVM_SEQ_LIB_RAND`:完全随机选择子sequence,可能连续选择相同类型[^4] - `UVM_SEQ_LIB_RANDC`:循环随机,保证每个子sequence在循环中执行一次(类似randc)[^4] ```systemverilog // 设置调度模式 uvm_config_db#(int)::set(this, "env.agent.sqr.main_phase.default_sequence", "selection_mode", UVM_SEQ_LIB_RANDC); ``` #### 二、执行机制特点 1. **子sequence调用方式** - 使用 `uvm_rand_send` 直接启动 `body()` 任务 - `pre_body()` 和 `post_body()` **不会被执行**[^3] - 若需初始化操作,必须放在子sequence的 `body()` 内 2. **执行控制参数** | 参数 | 作用 | 默认值 | |--------------------|-------------------------------|--------| | `min_random_count` | 最小执行sequence次数 | 10 | | `max_random_count` | 最大执行sequence次数 | 10 | | `selection_mode` | UVM_SEQ_LIB_RAND/RANDC | RAND | 3. **执行过程伪代码** ```systemverilog task body(); int count = $urandom_range(min_random_count, max_random_count); repeat(count) begin uvm_sequence_base seq = select_sequence(); // 根据selection_mode选择 `uvm_rand_send(seq) // 关键执行点 end endtask ``` #### 三、使用示例 ```systemverilog // 定义子sequence class short_pkt_seq extends uvm_sequence #(my_transaction); task body(); `uvm_do_with(req, {data.size() < 10}) // 初始化放在body内 endtask endclass // 配置sequence library class test extends uvm_test; function void build_phase(uvm_phase phase); // 设置library为default sequence uvm_config_db#(uvm_object_wrapper)::set(this, "env.agent.sqr.main_phase", "default_sequence", my_sequence_lib::get_type()); // 设置执行参数 uvm_config_db#(int)::set(this, "env.agent.sqr.main_phase.default_sequence", "min_random_count", 5); uvm_config_db#(int)::set(this, "env.agent.sqr.main_phase.default_sequence", "selection_mode", UVM_SEQ_LIB_RANDC); endfunction endclass ``` #### 四、注意事项 1. **避免使用pre_body** 子sequence的初始化必须放在 `body()` 中而非 `pre_body()`[^3] 2. **随机控制** 通过 `constraint_mode()` 可动态启用/禁用特定sequence的随机选择 3. **调试建议** 重载 `do_print()` 方法打印当前选择的sequence: ```systemverilog function void do_print(uvm_printer printer); printer.print_string("Current Sequence", seq.get_name()); endfunction ``` > 典型应用场景:回归测试中随机激励生成、多场景组合验证、协议兼容性测试等[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值