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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 2830|回复: 10

[求助] 老是抓不住最后一个数据,江郎才进,大家给个思路。

[复制链接]
发表于 2017-12-21 11:54:12 | 显示全部楼层 |阅读模式

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

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

x
捕获.PNG

大家重点看ACCUM1这组数据,还有ACCUM_OUT这组数据。
ACCUM1想必大家心里有数了,是个累加器,完成16个数的累加,如图所示,16个数累加的最终结果是000008da.
ACCUM_OUT是用来处理ACCUM1累加后的数据,希望这个模块的输出是000008da,但是无论如何都无法实现,我的尝试的方法如下:

1.
在ACCUM_OUT模块中,我在时钟上升沿判断mult_out_valid信号(也就是CE信号),为1的话,计数到15,然后捕捉000008da.但是大家注意到没有,16个数据处理完后,过了一段时间,第二组16个数据来的时候,Q滞后CE一个时钟,然而在第一组中,Q滞后CE两个时钟(第一组数据特殊,之后的数据组是一样的,都是滞后一个时钟)。所以用CE来做判断,不能兼顾第一组数据与以后的其他组数据。

2.
后来我发现CE的下降沿对于各组数据是一样的,如获至宝,但是仍然捉不到000008da。
negedge_sig是用来捕捉下降沿的。
always@(posedge clk)
  if(negedge_sig)
  accu_add_out<=Q;

这样捕捉到的数据是8da之后的0.我把<=换成=似乎没用。
always(negedge CE)
   accu_add_out<=Q;

这样捕捉到的数据是8da之前的一个数据。

还有什么好的思路呢,变动大一点也很好,传输的数据是对的,控制不是很好,导致上述问题。
发表于 2017-12-21 14:35:16 | 显示全部楼层
always(negedge CE)
   accu_add_out<=Q;

这是什么代码风格,得吊打。。。
发表于 2017-12-21 14:47:03 | 显示全部楼层
先把accu_out数据打一拍,再用你的negedge_sig去采
 楼主| 发表于 2017-12-21 15:23:12 | 显示全部楼层
回复 2# rvisk


    您的意思是?
    1.不能是CE,而应该是mult_out_valid,即
       always@(negedge mult_out_valid)
         ...
    2.所有的操作最好放在时钟沿下,即
       always@(posedge clk)
         ...
    您应该说的是第二种意思。其实我一直有种疑问,就是关于状态机,他会有除时钟以外的触发信号,我老是怀疑这样写更像是逻辑电路,觉得非常不友好,但又说不出原因来,隐隐的觉得不跟着时钟就有点无法控制的感觉,总感觉有一天会出问题。
    但是,状态机也没说有什么缺点啊,用的地方太多了,我有看过一点代码,每个模块都是状态机,弄的我整个状态都不是很好,看来啊您是写CODE 的专家,您能给我答一下疑吗?
   再次感谢您的回复。
 楼主| 发表于 2017-12-21 15:51:50 | 显示全部楼层
回复 3# yujuntao
恕我直言,您是真叼,一眼看出了问题,一句话解决了问题,按您的说法,仿真正确。

我原来的程序,这样捕到的是8da后面的数据。
  always@(posedge clk)
  if(negedge_sig)
    accu_add_out<=accu_out;
        ..........
您给的思路:
always@(posedge clk)
  data_reg<=accu_out;
  if(negedge_sig)
    accu_add_out<=data_reg;
      .............
我仔细想了想,确实没有像我那么写程序的,是要缓存一下的,然后再做以后的处理。我以前可能也缓存,但是在我的脑海中确实是模糊地带,导致今天的问题。
因为两个模块之间是连线的关系,所以直接用negedge_sig判断,而不加以缓存的话,会直接缓存到后面的0,而不是8da.
有缓存的话,data_reg会滞后accu_out一个时钟,在negedge_sig上升沿确实读到8da,不加缓存,读到0,总而言之,读的是沿后面的数据
这样能解释的很清楚。
发表于 2017-12-22 09:00:17 | 显示全部楼层
hdl是用来描述硬件电路的,是先有了电路后,在电路图以外的另一种表现形式。是在作者设计出电路后不需要劳费大量精力画图,且为了工具间更方便解析,所以利用ascii字符方式存储的hdl描述方式才会兴起。hdl写的绝对不是程序。如果不能很好地写hdl,就先锻炼用门画电路。
发表于 2018-1-5 22:07:13 | 显示全部楼层
本帖最后由 glace12123 于 2018-1-5 22:11 编辑




  1. always @(posedge sys_clk or posedge rst)
  2. begin
  3.     if(rst == 1'b1)
  4.         begin
  5.             ce_dly <= 1'b0;
  6.             accu_add_out <= 32'h0;
  7.         end
  8.     else
  9.         begin
  10.             ce_dly <= ce;

  11.             if(~ce & ce_dly)
  12.                 accu_add_out <= q;
  13.             else
  14.                 ;
  15.         end
  16. end


复制代码



看你搞得这么辛苦,何必呢,思维问题而已。。。既然你的CE对于所有数据都是一样,那么我把CE打一拍,用CE自身和CE延迟拍来检测CE下降沿,不就完了。。。你自己的那个negedge_sig思路是对的,但是不该做时序逻辑,导致延迟一拍抓到后面的无效数据了,画蛇添足
发表于 2018-1-6 09:11:04 | 显示全部楼层
always@(negedge CE)
这种写法也不是不可以,其实我就喜欢这样用,但这样用有它的缺点。
首先,CE绝对不能有毛刺,系统会把CE当做时钟信号,那么就必须保证它是干净的。
其次,CE作为时钟信号之后,在设计上是要求对其做时序约束的,虽然一般频率不高,但是也多一个过程或者报警。
总之就是不规范,而且容易出现坑。
所以,最好还是用always@(negedge clk)吧。
++++++++
然后,比如三段式状态机,的确要用经常用组合逻辑,
但是其不出问题是因为时序逻辑模块对组合逻辑的输出结果做了到打拍处理的。
所以节奏仍然是可控的,每一个输出仍然是在时钟的控制下产生的。
++++++++++++++++++++++++++++++++++++++++++
你上面程序没检测到,本质上是因为你的输出信号是在clk上升沿到来之后的一小段时间之后才会有效,
在仿真的时候,仅仅在视觉上是同时的。
而你用同一时钟的上升沿来检测,显然是检测不到的。
这个时候打一拍就行了。
+++++++++++
 楼主| 发表于 2018-1-6 11:50:15 | 显示全部楼层
回复 8# YYFFLLMMNN


    谢谢大牛的回答,很有用。
 楼主| 发表于 2018-1-6 11:51:35 | 显示全部楼层
回复 7# glace12123


    谢谢您的指教,很有用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

×

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

GMT+8, 2024-4-24 09:44 , Processed in 0.058469 second(s), 7 queries , Gzip On, Redis On.

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