上升沿出发与电平出发的区别
先上程序: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的周期闪烁。为什么把我写有标记的那行中的敏感信号改成电平出发就不行呢?而上升沿出发却可以正常工作???
跪求答案…… 电平触发的你可以看作是一堆与或非门
边沿触发的你可以看作是一堆门+触发器
对于你的程序来说,标记的那行改为电平,信号led相当于一个非门的输入输出连在一起了 mark{:kiss:} mored 发表于 2012-7-19 17:23 static/image/common/back.gif
电平触发的你可以看作是一堆与或非门
边沿触发的你可以看作是一堆门+触发器
对于你的程序来说,标记的那行 ...
那什么不能正常工作呢?? always@( flag)//标记
begin
if(sw==1)
led=~led;
else
led=0;
end
2862134638 发表于 2012-7-20 10:49 static/image/common/back.gif
always@( flag)//标记
begin
if(sw==1)
什么意思? haijin0829 发表于 2012-7-20 22:54 static/image/common/back.gif
什么意思?
这样可以吗? 2862134638 发表于 2012-7-23 09:36 static/image/common/back.gif
这样可以吗?
这样不可以啊 tastier 发表于 2012-7-19 21:57 static/image/common/back.gif
mark
{:kiss:} {:3_64:} {:2_37:} 2862134638 发表于 2012-7-20 10:49 static/image/common/back.gif
always@( flag)//标记
begin
if(sw==1)
这样写就是典型的零延迟环路了,输出无法预测。可以参考一下环形振荡器的原理就好理解了 楼主的想法也是,无论阻塞或者非阻塞幅值,综合出来都是零延迟环路 本帖最后由 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:34 编辑
shandandan 发表于 2012-7-24 21:51 static/image/common/back.gif
这样写就是典型的零延迟环路了,输出无法预测。可以参考一下环形振荡器的原理就好理解了 ...
至于这个零延迟环路,满头雾水的不懂。请详细说明一下吧。我知道环形振荡器,但是不明白同上面代码的关系 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: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 20:09 编辑
感谢shandandan的认真说明。
always@(flag)//首先,敏感信号列表里就一个flag,而这个flag在下面根本就没有引用,因此这个 flag这里写了等于没写,此处等同于无条件的always语句;
这句话我不太同意。ex:always@(flag) led=1
还有商业仿真器死循环也是会停止的,1000步这样。 本帖最后由 flyriz 于 2012-9-18 14:54 编辑
我也遇到这个问题了,不知楼主解决了没有,求分享。
http://www.amobbs.com/forum.php?mod=viewthread&tid=5497582&pid=6119785&page=1&extra=#pid6119785 http://www.amobbs.com/forum.php?mod=viewthread&tid=5497582&pid=6119785&page=1&extra=#pid6119785 学习了先
页:
[1]