如何在UVM派生序列类中重写cfg成员变量?
解决UVM序列类中配置对象的继承与类型匹配问题
方案一:使用参数化基类(推荐)
把基类base_seq设计成参数化类,将配置对象的类型作为参数传入,这样派生类可以指定自己专属的配置类型,同时保证基类中的cfg与派生类的配置类型兼容,且能直接访问基类配置的成员(比如sqr)。
修改后的代码如下:
virtual class base_seq_cfg extends uvm_object; my_sequencer_c sqr; endclass // 定义参数化基类,默认参数为base_seq_cfg virtual class base_seq#(type CFG_T = base_seq_cfg) extends uvm_object; CFG_T cfg; // 这里的cfg类型由派生类指定 task send_item(); basic_seq_c basic_seq; basic_seq.start(cfg.sqr, this); // 基类可直接访问cfg中的sqr endtask endclass class test_seq1_cfg extends base_seq_cfg; int iterations; endclass // 派生类指定自己的配置类型为test_seq1_cfg class test_seq1 extends base_seq#(test_seq1_cfg); task body(); for (int i = 0; i < cfg.iterations; ++i) begin send_item(); // 正常调用基类任务,cfg.sqr有效 end endtask endclass
这种方式类型安全,编译时就能检查配置类型是否匹配,避免运行时类型转换的风险,同时每个派生类都能拥有自己专属的配置对象,基类的通用逻辑不受影响。
方案二:类型转换(兼容已有代码结构)
如果不想修改基类的参数化设计,可以在派生类中保留父类的base_seq_cfg成员,通过向下类型转换将其转为派生类的配置类型,从而访问派生类特有的成员。
修改后的代码如下:
virtual class base_seq_cfg extends uvm_object; my_sequencer_c sqr; endclass virtual class base_seq extends uvm_object; base_seq_cfg cfg; task send_item(); basic_seq_c basic_seq; basic_seq.start(cfg.sqr, this); endtask endclass class test_seq1_cfg extends base_seq_cfg; int iterations; endclass class test_seq1 extends base_seq; // 不重定义cfg,而是在需要时转换类型 task body(); test_seq1_cfg local_cfg; // 确保cfg实际指向的是test_seq1_cfg对象,否则会报错 if (!$cast(local_cfg, cfg)) begin `uvm_fatal("CFG_TYPE_ERR", "配置对象类型不匹配") end for (int i = 0; i < local_cfg.iterations; ++i) begin send_item(); end endtask endclass
使用这种方式时,需要确保实例化test_seq1时,传入的cfg确实是test_seq1_cfg类型的对象,否则$cast会失败,需通过uvm_fatal抛出错误避免运行时异常。
注意事项
- 无论哪种方案,实例化序列时都要正确给
cfg成员赋值,确保其指向对应类型的配置对象。 - 参数化基类的方式更符合UVM模块化设计思想,便于后续扩展更多序列和配置类型。
内容的提问来源于stack exchange,提问作者Melandru's Square
相关产品推荐
相关产品推荐

