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

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 6986|回复: 15

[求助] 求助:在systemverilog的task中只能用阻塞赋值么?

[复制链接]
发表于 2013-4-2 11:13:00 | 显示全部楼层 |阅读模式

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

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

x
各位:
      今天突然遇到一个简单的基本问题,但是会导致设计很大的错误。就是在systemverilog的task中使用非阻塞赋值的问题。
      我在写一个task,当valid为高的时候,采集总线上的id信号,并根据id去查id对应的transfer,根据该transfer的延时参数来给出ready信号。那么问题来了:
      刚开始我是这样写的:




  1. @(posedge vif.axi_clock iff(vif.axi_rst_n))
  2.        if(vif.rvalid) begin
  3.            id = vif.RID;
  4.            $display("receive r_id=%h @ %t",id,$time);
  5.            ......
  6.        end


复制代码

然后波形出来一看,有点不对,rvalid是在1550ns时刻拉高,本来应该这个时候就采集到id的,但是打印出来的却是在1570ns的时候才采集到id的值(时钟周期20ns)。所以我就想应该使用"<=",结果ncvlog报错NOAUTO,难道systemverilog的task中不能使用非阻塞赋值么,应该不会吧,应该是我没用对,所以,我想问问各位,这种情况我应该怎么修改我的代码?
发表于 2013-4-2 17:18:01 | 显示全部楼层
楼主能否把波形图贴上,不然很难从你的文字知道电路的运行情况。

还有那个错误,是否是你定义id变量不是寄存器变量造成的,因为非阻塞赋值操作只能用于寄存器变量赋值。
 楼主| 发表于 2013-4-3 10:28:32 | 显示全部楼层
id的定义我后来改了呀,改成logic或者reg都不行。
波形图,由于已经改动了很多,问题已经跟开始描述的有些不一样了,(已经把if(vif.rvalid)改成@(posedge vif.rvalid),这样就能按照我要求的时序采数据。)但是还有个不变的问题就是我没办法在task里面使用“<="赋值。我想知道是确实不能使用么?
发表于 2013-4-11 00:02:39 | 显示全部楼层
valid信号应该是在时钟有效沿之后才被驱动拉高的,
如果valid已被clocking block同步的话,作为input,应该是在时钟有效沿之前被采样,
所以被拉高的时候,没有被采到,直到下一个时钟沿
至于你说的task不能用非blocking,我想是可以的,可能是别的什么问题导致的
你看看的你贴的代码的if下的两个语句末的分号,好像不一样
我的个人观点,最近刚接触,欢迎交流
发表于 2013-4-11 22:47:42 | 显示全部楼层
你的vif 的interface里面是否用clocking block 做信号同步,不然就会出现tb 和 dut的信号竞争问题。

另外1570的rising edge sample到 1550的rising edge 驱动assert的valid信号没有错啊?!
 楼主| 发表于 2013-4-13 09:59:53 | 显示全部楼层
回复 5# tbb2009

1. interface中是已经跟时钟同步了的
2.这个是设计时候想法问题,等发觉到的时候想改已经不容易了。因为我是想把master发出的每个AR传输都存在一个队列中,然后等master收到slave传输的数据的时候,用收到的ID去队列中查找相应的transfer,然后取出transfer中定义的rvalid_to_rready_delay值,用这个值来数时钟,以便产生rready信号。因此只能先sample再drive,没办法做到axi标准里面的在valid与ready同时有效的时候才sample。要改这个问题的话,真的整个架构都要重新推翻了。
发表于 2013-12-26 17:14:51 | 显示全部楼层
马克后看
发表于 2013-12-26 17:31:18 | 显示全部楼层
回复 1# oscillator_cn1

你在1楼的代码没有问题,把打印去掉即可。根据verilog标准,“id = vif.RID;” 和 “$display("receive r_id=%h @ %t",id,$time);” 都是在active区间执行,但是他们的执行顺序是随机的。这里的$display无论是打印id的新值还是打印id的旧值都是正确的。或者你可以display vif.RID而非id,这样可以确保得到consistent的结果。
发表于 2013-12-27 09:34:02 | 显示全部楼层
回复 1# oscillator_cn1

一个信号在时刻1被驱动为高,那么一定是在下一个时刻才能被采到,本来就应该是这样子的啊
发表于 2013-12-27 09:35:17 | 显示全部楼层
回复 3# oscillator_cn1


    task里面当然可以用非阻塞赋值了,毫无疑问的。贴你的代码出来,把编译错误贴出来,看看是啥原因
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-13 22:00 , Processed in 0.024128 second(s), 8 queries , Gzip On, Redis On.

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