在线咨询 切换到宽版
eetop公众号 创芯大讲堂 创芯人才网

 找回密码
 注册

手机号码,快捷登录

手机号码,快捷登录

搜全文
查看: 4448|回复: 7

[求助] 求助:sequence如何使用monitor中的变量

[复制链接]
发表于 2019-2-12 12:39:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
大家好,请教一下sequence如何使用monitor中的变量的问题。
如图,sequence_0想根据DUT返回的不同情况,发送不同的sequence。DUT返回的ret由monitor_1监视。在monirot_1中有一个变量是cnt,请问在sequence_0中如何拿到cnt?谢谢。




                               
登录/注册后可看大图
seq.JPG
发表于 2019-2-12 16:10:03 | 显示全部楼层
纯属个人想法:
第一种,在env中将out_agent中的monitor_1 uvm_config_db::set() 到in_agent中的sequencer_0,然后sequence_0中通过uvm_config_db::get()到monitor_1的句柄,通过这个句柄访问变量cnt。
第二种,如果有virtual sequencer,则可以将out_agent中的monitor_1 uvm_config_db::set() 到virtual sequencer中,然后sequence_0中通过uvm_config_db::get()到virtual sequencer中monitor_1的句柄,通过这个句柄访问变量cnt。
第三种,如果只有变量cnt而且功能纯粹,是否可以考虑将这个变量cnt放置在in_agent的monitor中,这样结构会方便一点。

但是总感觉这三种方法都不好,导致结构混乱,复用性变差。
回复 支持 1 反对 0

使用道具 举报

发表于 2019-2-12 16:40:13 | 显示全部楼层
可以试试response,monitor检测信号传给driver,driver给sequence以反馈。
回复 支持 反对

使用道具 举报

发表于 2019-2-12 23:17:07 | 显示全部楼层
看了2楼和3楼的回答,觉着有问题;

我的做法,使用TLM传递:
1. 在moniter_1中增加一个analysis_port,把cnt 广播出去;
2. 在sequencer_0中增加一个imp,接收步骤1中广播的cnt;
3. sequence中可以直接通过sequencer_0中的port得到cnt的值;
回复 支持 2 反对 0

使用道具 举报

发表于 2024-3-2 18:13:22 | 显示全部楼层


   
chaozhanghu 发表于 2019-2-12 23:17
看了2楼和3楼的回答,觉着有问题;

我的做法,使用TLM传递:


楼主说的对,sequencer 是桥接sequence 和component的桥梁

已做验证
回复 支持 反对

使用道具 举报

发表于 2024-6-19 10:23:58 | 显示全部楼层


   
hefuzhang 发表于 2024-3-2 18:13
楼主说的对,sequencer 是桥接sequence 和component的桥梁

已做验证


您好,想请教下连接seq和seqr的这个port怎么实现呢
回复 支持 反对

使用道具 举报

发表于 2025-11-18 15:02:56 | 显示全部楼层


   
dreamer21 发表于 2024-6-19 10:23
您好,想请教下连接seq和seqr的这个port怎么实现呢


先说结论:
这个宏本来是有的,在标准 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 的代码骨架贴出来,我可以直接按你的工程风格帮你改一版能编的完整示例。

回复 支持 反对

使用道具 举报

发表于 2025-11-18 15:04:18 | 显示全部楼层


   
EEnoob 发表于 2025-11-18 15:02
先说结论:
这个宏本来是有的,在标准 UVM 里定义好了,如果你“没有这个宏”,一般就两种情况:


因为 uvm_declare_p_sequencer 这个宏的工作原理就决定了它只能接受“类型名”,绝不能接受“实例名”
不光是这个宏,SystemVerilog 的语法本身也强制区分“类型”和“变量(实例)”,两者不能混用。
下面我从 宏展开原理 + SV 语法原理 + UVM 机制 三个角度给你解释,保证你彻底理解。

🔥 一、宏展开后本质是“声明一个类型为 X 的变量”当你写:
`uvm_declare_p_sequencer(my_sequencer)宏展开成:
my_sequencer p_sequencer;virtual function void m_set_p_sequencer();  super.m_set_p_sequencer();endfunction第一句就是关键:
my_sequencer p_sequencer;这一句在 SystemVerilog 里语义固定为:
“声明一个类型为 my_sequencer 的变量 p_sequencer”
也就是:
  • my_sequencer 必须是一个 class 名字
  • p_sequencer 是一个 实例

🎯 因此:
这里的位置就是给类型用的,不可能放实例名。
你如果传实例名,比如:
`uvm_declare_p_sequencer(sqr_h)那宏展开变成:
sqr_h p_sequencer;    // ❌ 完全非法因为 sqr_h 是一个变量,它不能作为一个类型来声明另一个变量。
就像你不能写:
int a;a b;   // ❌ 因为 a 是变量,不是类型
🔥 二、SystemVerilog 的语法本身就要求:变量声明必须用类型名例如:
my_class obj;      // my_class 是类型名 → 合法obj another;       // obj 是实例名 → 非法所以 uvm_declare_p_sequencer 的参数必然要求是 class 类型名

🔥 三、为什么不是传实例?因为 sequence 不知道 sequencer 的实例是谁sequence 的生命周期如下:
  • test 中 new 出一个 sequence(没有 sequencer 实例)
  • test 或 virtual sequence 调 seq.start(seqr);
  • UVM 在 start() 的过程中,把传进来的 sequencer 实例赋给 m_sequencer

所以:
  • sequence 在 new 的时候完全不知道 sequencer 是哪个实例
  • uvm_declare_p_sequencer 只是 告诉 UVM:我需要的 sequencer 类型是什么

UVM 才能在 start() 时匹配 sequencer 类型是否兼容。
这就是为什么必须写 类型名

🔥 四、你真正想要的实例,是在运行时从 m_sequencer cast 出来的运行时:
$cast(p_sequencer, m_sequencer);这里的 m_sequencer 是 实例(test 通过 seq.start() 传进来的)
而 p_sequencer 的类型必须提前告诉 UVM,就是你写 uvm_declare_p_sequencer(类型名) 的目的。

🧠 五、总结:为什么不能写实例名,而必须写 class 类型名?原因解释
🔹 SystemVerilog 语法限制宏展开后是“类型 变量名;”,类型位置不能放实例
🔹 宏设计机制宏内部就是声明 p_sequencer 为你提供的类型
🔹 UVM start() 机制sequence 不知道 sequencer 实例,需要用类型来匹配
🔹 运行时才会绑定实例实例由 m_sequencer 提供,类型用于静态检查一句话总结:
宏需要类型名来声明句柄,实例名根本无法用于声明句柄,因此不能写实例名。

如果你愿意,我可以根据你当前工程结构,帮你写一个完全可跑的 sequencer + sequence + macro 使用示例,保证你看到就会用。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

X

手机版| 小黑屋| 关于我们| 联系我们| 用户协议&隐私声明| 版权投诉通道| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 ) |网站地图

GMT+8, 2025-12-19 06:06 , Processed in 0.019340 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表