haijin0829 发表于 2012-7-19 17:06:31

上升沿出发与电平出发的区别

先上程序:
module flash_led(
input clk,sw,
output reg led
   );
integer i;
reg flag;
always@(posedge clk)
       begin
      if(i==25000000)
         begin
             i<=0;
             flag<=~flag;
         end
       else
            i<=i+1;
       end
always@(posedge flag)//标记
      begin
         if(sw==1)
            led<=~led;
         else
               led<=0;
      end
endmodule

用的是XILINX NEXYS3的板子……LED以500ms的周期闪烁。为什么把我写有标记的那行中的敏感信号改成电平出发就不行呢?而上升沿出发却可以正常工作???
跪求答案……

mored 发表于 2012-7-19 17:23:00

电平触发的你可以看作是一堆与或非门
边沿触发的你可以看作是一堆门+触发器
对于你的程序来说,标记的那行改为电平,信号led相当于一个非门的输入输出连在一起了

tastier 发表于 2012-7-19 21:57:05

mark{:kiss:}

haijin0829 发表于 2012-7-20 07:43:38

mored 发表于 2012-7-19 17:23 static/image/common/back.gif
电平触发的你可以看作是一堆与或非门
边沿触发的你可以看作是一堆门+触发器
对于你的程序来说,标记的那行 ...

那什么不能正常工作呢??

2862134638 发表于 2012-7-20 10:49:11

always@( flag)//标记
      begin
         if(sw==1)
            led=~led;
         else
               led=0;
      end

haijin0829 发表于 2012-7-20 22:54:33

2862134638 发表于 2012-7-20 10:49 static/image/common/back.gif
always@( flag)//标记
      begin
         if(sw==1)


什么意思?

2862134638 发表于 2012-7-23 09:36:02

haijin0829 发表于 2012-7-20 22:54 static/image/common/back.gif
什么意思?

这样可以吗?

haijin0829 发表于 2012-7-23 13:58:22

2862134638 发表于 2012-7-23 09:36 static/image/common/back.gif
这样可以吗?

这样不可以啊

haijin0829 发表于 2012-7-23 13:59:17

tastier 发表于 2012-7-19 21:57 static/image/common/back.gif
mark

{:kiss:} {:3_64:} {:2_37:}

shandandan 发表于 2012-7-24 21:51:32

2862134638 发表于 2012-7-20 10:49 static/image/common/back.gif
always@( flag)//标记
      begin
         if(sw==1)


这样写就是典型的零延迟环路了,输出无法预测。可以参考一下环形振荡器的原理就好理解了

shandandan 发表于 2012-7-24 21:52:55

楼主的想法也是,无论阻塞或者非阻塞幅值,综合出来都是零延迟环路

2862134638 发表于 2012-7-25 09:00:40

本帖最后由 2862134638 于 2012-7-25 09:35 编辑

分析下:
always@( flag)//标记
//组合逻辑应该用电平,这点不会错的。
      begin
         if(sw==1)
            led=~led;    //这里led有寄存(右边的~led),所以是时序的。这里我的理解不知道对不对?
         else
               led=0;
      end

我的话就这样写:
always @(posedge clk)
begin
if(i==25000000)
         begin
             i<=0;
             if(sw)led <= 1;
         end
       else
            led <= 0;
            i<=i+1;
end
最简单最轻松,大家请指教下,什么都丢给时序去解决,觉得也不是办法。

2862134638 发表于 2012-7-25 09:01:56

本帖最后由 2862134638 于 2012-7-25 09:34 编辑

shandandan 发表于 2012-7-24 21:51 static/image/common/back.gif
这样写就是典型的零延迟环路了,输出无法预测。可以参考一下环形振荡器的原理就好理解了 ...

至于这个零延迟环路,满头雾水的不懂。请详细说明一下吧。我知道环形振荡器,但是不明白同上面代码的关系

shandandan 发表于 2012-7-25 12:54:08

verilog不同于软件编程,对于写出来的代码必须要知道综合出来大概是个什么东西。初学者在调试简单工程的时候要经常看看综合之后的RTL视图。
光说不练假把式,楼主的代码改成电平敏感后,在quartus11综合后RTL视图如下:


计数器完全不起作用,仔细分析一下代码就可以看出原因:
always@(flag)//首先,敏感信号列表里就一个flag,而这个flag在下面根本就没有引用,因此这个 flag这里写了等于没写,此处等同于无条件的always语句;
                     //其次,应该加入敏感列表的sw却没有加入,好在综合软件会给出警告;
                     //既然输出与flag没有任何关系,那用于产生flag信号的计数器当然就被综合器优化删除了;
      begin   //以下代码很容易跟上面的RTL视图相对照,就是个典型的无延迟环路,要么震荡,要么稳定在某个电平,大小任意;
         if(sw==1)
            led<=~led;//另外要提醒大家的是 reg型变量综合后不一定就是个寄存器,这里定义成reg型,纯粹是因为在always语句内,赋值语句左边必须是寄存器型变量
                              //什么时候综合成锁存看下面的修改
         else
               led<=0;
      end

将楼主的代码稍微修改一下,
always@(flag or sw)
      begin;
         if(sw==1 && flag == 1)//这里删去了else,形成了不完整的条件语句,因为不满足条件时,led值不变,必须要保存先前值,所以综合器才把led综合成了锁存器
            led<=~led;
      end
再编译综合一下,就成了下图这个样子:


但是这样同样不能够工作,因为锁存器在直通的情况下还是形成了零延迟环路。
就本人理解,用电平触发来实现某个寄存器自身的翻转是根本不能实现的
本人同样是新手一个,上面如有错漏还请高手指正。

shandandan 发表于 2012-7-25 13:01:24

再多废话一句,就是自己写出来的代码如果自己用门电路,锁存器等都搭不出来,那就更不要指望综合器能综合出来了,机器比人要笨的。

shandandan 发表于 2012-7-25 13:17:14

本帖最后由 shandandan 于 2012-7-25 13:20 编辑

2862134638 发表于 2012-7-25 09:01 static/image/common/back.gif
至于这个零延迟环路,满头雾水的不懂。请详细说明一下吧。我知道环形振荡器,但是不明白同上面代码的关系 ...

照抄书上的东西吧,我自己语文不太好:

零延迟环路只是组合逻辑电路网中环形传播路径的另一个名字,这类电路的问题是,即使所有输入都是已知的,也不能决定输出的逻辑值,根本原因是某些组合逻辑函数引用了他自己的结果。
例如上面综合的结果中:
http://www.amobbs.com/data/attachment/forum/201207/25/122816jw8ckw7q2f57jdh6.jpg
即使sw=1,led 的值也不能确定,既不能稳定在0,也不能稳定在1.

零延迟环路会导致仿真进入死循环,实际综合到FPGA中则会无法实现功能

2862134638 发表于 2012-7-26 15:08:04

本帖最后由 2862134638 于 2012-7-26 20:09 编辑

感谢shandandan的认真说明。

always@(flag)//首先,敏感信号列表里就一个flag,而这个flag在下面根本就没有引用,因此这个 flag这里写了等于没写,此处等同于无条件的always语句;


这句话我不太同意。ex:always@(flag) led=1

还有商业仿真器死循环也是会停止的,1000步这样。

flyriz 发表于 2012-9-18 14:53:17

本帖最后由 flyriz 于 2012-9-18 14:54 编辑

我也遇到这个问题了,不知楼主解决了没有,求分享。
http://www.amobbs.com/forum.php?mod=viewthread&tid=5497582&pid=6119785&page=1&extra=#pid6119785

flyriz 发表于 2012-9-18 14:54:23

http://www.amobbs.com/forum.php?mod=viewthread&tid=5497582&pid=6119785&page=1&extra=#pid6119785

simpleh 发表于 2012-10-23 10:32:47

学习了先
页: [1]
查看完整版本: 上升沿出发与电平出发的区别