|
|
发表于 2025-11-18 15:02:56
|
显示全部楼层
先说结论:
这个宏本来是有的,在标准 UVM 里定义好了,如果你“没有这个宏”,一般就两种情况:
- 没 include "uvm_macros.svh"
- 用的是很老/魔改版的 UVM,没有这个宏
我分别给你两种解决方案。
1⃣ 标准做法:确认宏文件 & 正确写法在你的 sequence 源文件 顶部,必须有这两句(顺序也要注意):
`include "uvm_macros.svh"import uvm_pkg::*;然后在 sequence 里就可以这么写了:
class my_sequence extends uvm_sequence #(my_item); `uvm_object_utils(my_sequence) `uvm_declare_p_sequencer(my_sequencer) // 这句需要宏文件 task body(); // 现在可以用 p_sequencer 访问 sequencer 中的变量 `uvm_info("SEQ", $sformatf("cnt = %0d", p_sequencer.cnt), UVM_MEDIUM) p_sequencer.cnt++; // 读写 sequencer 的变量 endtaskendclass如果你忘了 include "uvm_macros.svh",编译器就会提示:
Macro `uvm_declare_p_sequencer is undefined
这种就是典型的“就没有这个宏”的情况。
2⃣ 如果你用的 UVM 版本真的没有这个宏那就自己手动干掉宏,手写一份等价的逻辑就行。
2.1 自己声明一个同名句柄class my_sequence extends uvm_sequence #(my_item); `uvm_object_utils(my_sequence) my_sequencer p_sequencer; // 手动声明 // 推荐写在 pre_body 里做一次绑定 virtual task pre_body(); if (!$cast(p_sequencer, m_sequencer)) begin `uvm_fatal("SEQ", "cast to my_sequencer failed") end endtask task body(); `uvm_info("SEQ", $sformatf("cnt = %0d", p_sequencer.cnt), UVM_MEDIUM) p_sequencer.cnt++; endtaskendclass这里逻辑就是把 m_sequencer(父类里的通用句柄)强制 $cast 成你自己的 my_sequencer,然后存在 p_sequencer 里。
这就是 uvm_declare_p_sequencer 宏背后干的事。
3⃣ 最简替代写法(不用 p_sequencer 名字也行)如果你懒得搞 p_sequencer 这个名字,直接在 body() 里 $cast 用也行:
task body(); my_sequencer seqr; if (!$cast(seqr, m_sequencer)) begin `uvm_fatal("SEQ", "cast to my_sequencer failed") end seqr.cnt++; `uvm_info("SEQ", $sformatf("cnt = %0d", seqr.cnt), UVM_MEDIUM)endtask 4⃣ 小结:sequence 访问 sequencer 变量的几种姿势场景写法
标准 UVM,有宏文件\uvm_declare_p_sequencer(my_sequencer)+p_sequencer.xxx`
没宏文件 / 老 UVM自己声明 my_sequencer p_sequencer; + 在 pre_body() 里 $cast
最轻量做法在 body() 里 my_sequencer seqr; $cast(seqr, m_sequencer); seqr.xxx 如果你愿意把 sequencer 和 sequence 的代码骨架贴出来,我可以直接按你的工程风格帮你改一版能编的完整示例。
|
|