yidehui 发表于 2013-1-24 10:40:10

关于fpga流水灯非常奇怪现象

请问下,我在流水灯试验中发现修改程序中计数器的数值会发生奇怪现象:
我的部分简单代码如下:

reg cnt;      //计数器a
reg count;      //计数器b

parameter T1MS=15'd19_999;//有源晶振20MHz

always @ (posedge clk or negedge rstn)               //计数器a ,1ms定时,这里没什么问题
      if(!rstn)      cnt<=15'd0;
      else if(cnt==T1MS)cnt<=15'd0;                        
                else cnt<=cnt+1'd1;               
                        
always @ (posedge clk or negedge rstn)               //计数器b ,200ms定时。
      if(!rstn)      count<=1'd0;
      else if(count==10'd200)   //这里是问题关键点,我改成else if(count==10'd201)后,发现蜂鸣器不叫,led闪烁频率正常,但亮度明显降低很多!这是为什么啊!!!中间多计数1点的延时时间段而已,最后count还归零的啊!!!
                count<=10'b0;               
                else if(cnt==T1MS)
                count<=count+10'b1;

//以下是功能控制模块
reg rbuzzer_out;
reg rLed_Out;

always @ (posedge clk or negedge rstn)         
      if(!rstn)      begin rbuzzer_out<=1'b1;rLed_Out<=5'b0; end      //蜂鸣器不叫,led全灭。
      else if(count==10'd200)            //每200ms led和蜂鸣器电平取反
                begin
                        rLed_Out<=~rLed_Out;
                        rbuzzer_out<=~rbuzzer_out;
                end

yutianyiren 发表于 2013-1-24 12:34:10

把这个地方也修改一下试试:
else if(count==10'd201)            //每200ms led和蜂鸣器电平取反
最好应该有个else的吧,要不就修改为:
always @ (posedge clk or negedge rstn)         
   if(!rstn)      begin rbuzzer_out<=1'b1;rLed_Out<=5'b0; end      //蜂鸣器不叫,led全灭。
   else
         begin
             if(count==10'd200)            //每200ms led和蜂鸣器电平取反
                begin
                        rLed_Out<=~rLed_Out;
                        rbuzzer_out<=~rbuzzer_out;
                end
       end

yidehui 发表于 2013-1-24 12:40:32

yutianyiren 发表于 2013-1-24 12:34 static/image/common/back.gif
把这个地方也修改一下试试:
else if(count==10'd201)            //每200ms led和蜂鸣器电平取反
最好应该 ...

之前我试过你那种改法,我就是不明白为什么会这样?中间就多计数了1点,这么一小段时间会有影响。而且counter迟早会计数到200点,所以理论上讲应该没问题

wye11083 发表于 2013-1-24 12:47:10

yidehui 发表于 2013-1-24 12:40 static/image/common/back.gif
之前我试过你那种改法,我就是不明白为什么会这样?中间就多计数了1点,这么一小段时间会有影响。而且cou ...

它理论上就是会出问题,很实际的问题。置位复位不同步。你看到LED闪很正常,LED跟复位有关。蜂鸣器跟计数器有关,现在你计数器不停复位,你让蜂鸣器怎么响?

yidehui 发表于 2013-1-24 12:55:46

wye11083 发表于 2013-1-24 12:47 static/image/common/back.gif
它理论上就是会出问题,很实际的问题。置位复位不同步。你看到LED闪很正常,LED跟复位有关。蜂鸣器跟计数 ...

我不打理解为什么计数器会不停复位?counter从0计数到201,这个过程有什么问题吗?

wye11083 发表于 2013-1-24 13:22:12

yidehui 发表于 2013-1-24 12:55 static/image/common/back.gif
我不打理解为什么计数器会不停复位?counter从0计数到201,这个过程有什么问题吗? ...

复位是200周期,你计数201周期。底下是复位信号。

yidehui 发表于 2013-1-24 14:09:22

wye11083 发表于 2013-1-24 13:22 static/image/common/back.gif
复位是200周期,你计数201周期。底下是复位信号。

还是不大理解为什么计数到200就会复位。从语言的角度上,我怎么都想不通

jlhgold 发表于 2013-1-24 14:12:44

因为逻辑不是C语言!不会等,到了会在下一个时钟周期立即跳过去

yidehui 发表于 2013-1-24 14:25:11

jlhgold 发表于 2013-1-24 14:12 static/image/common/back.gif
因为逻辑不是C语言!不会等,到了会在下一个时钟周期立即跳过去

你的意思就是说无论counter取值是201也好还是1001也好,都会直接从计数到200那一瞬间跳到0?

tanguojian 发表于 2013-1-24 14:38:51

原程序上,counter==200只出现一个周期(20M),LED和BUZZER口在只翻转一次
你修改后,counter==200到counter==201这个时间内,LED和BUZZER口翻转了20000次!
用示波器看IO口的波形,就知道为什么LED亮度变低,蜂鸣器不响了

jlhgold 发表于 2013-1-24 14:38:55

不是 是如果是C代码 会等到下一个周期才变化 而硬件是同步的 你到200的时候 最后一段有可能没有进入或者刚好时钟过了沿变 就会不执行!

yidehui 发表于 2013-1-24 15:13:59

jlhgold 发表于 2013-1-24 14:38 static/image/common/back.gif
不是 是如果是C代码 会等到下一个周期才变化 而硬件是同步的 你到200的时候 最后一段有可能没有进入或者刚 ...

能举一个例子吗?

tanguojian 发表于 2013-1-25 09:53:05

yidehui 发表于 2013-1-24 12:40 static/image/common/back.gif
之前我试过你那种改法,我就是不明白为什么会这样?中间就多计数了1点,这么一小段时间会有影响。而且cou ...

虽然是1点,但是这1点之内20M的时钟有20000次,第三个always模块触发了20000次
第三个always里条件加一个就可以了
always @ (posedge clk or negedge rstn)         
      if(!rstn)      begin rbuzzer_out<=1'b1;rLed_Out<=5'b0; end      //蜂鸣器不叫,led全灭。
      else if(count==10'd200 && cnt==T1MS)            //修改count==10'd201再清0后,这里必须加上才能第二个条件才能保证count的一个计数周期内只触发一次
                begin
                        rLed_Out<=~rLed_Out;
                        rbuzzer_out<=~rbuzzer_out;
                end

yidehui 发表于 2013-1-25 10:17:49

tanguojian 发表于 2013-1-25 09:53 static/image/common/back.gif
虽然是1点,但是这1点之内20M的时钟有20000次,第三个always模块触发了20000次
第三个always里条件加一个 ...

软软的问下,你是怎么知道200到201计数过程是不稳定的,为什么这个过程中这个计数周期那么特殊,可能会触发多次?!!

tanguojian 发表于 2013-1-25 20:30:26

yidehui 发表于 2013-1-25 10:17 static/image/common/back.gif
软软的问下,你是怎么知道200到201计数过程是不稳定的,为什么这个过程中这个计数周期那么特殊,可能会触 ...

因为你全是由clk驱动的呀
页: [1]
查看完整版本: 关于fpga流水灯非常奇怪现象