OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9780|回复: 26

[ALTERA] 请问always块电平触发时,每次电平改变,always块只执行一次吗?

[复制链接]

2

主题

11

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2019-7-17
在线时间
5 小时
发表于 2019-9-2 17:11:12 | 显示全部楼层 |阅读模式
1金钱
在触摸按键那一节的实验中,我想这个触摸键应该不用按键消抖,就准备不用时钟信号,直接电平触发了,下面是我写的代码:
module key_touch(input touch,output reg led);
always@(touch)
begin
  if(touch==1)
   led=~led ;
end
endmodule
我的想法是每次检测到电平变化,就检测一次电平信号是不是高电平,如果是高的话就改变led信号变化,结果把程序烧到fpga里并不能达到触摸按键改变灯亮灭。
检查rtl视图发现quartus是只生成了一个锁存器,然后touch接锁存器的使能端,锁存器的输出取反接输入。
这样的话,只要是touch为高电平,led的信号就一直发生变化,并不是我所设想的touch信号变一次,always块执行一次而是always块一直在执行。
请问问题出在哪,是我对always的理解有问题还是这段程序逻辑有什么错误?

最佳答案

查看完整内容[请看2#楼]

不是你对alway理解有问题,是你用软件的思维去设计硬件。综合结果是没有问题的,硬件行为也是按照你描述的去做的。就这个例子来说,你硬件描述语言被综合之后,就会生成这个锁存器,而不是在运行的时候,或者说touch改变的时候才生产的,它就是个硬件电路,就一直在那里,但是这个电路的行为是在描述语言里面定义的,硬件是没有什么运行的概念的。你这里是描述了一个锁存器的功能,就是在touch有效的时候,取反led。硬件是一直有效 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

37

主题

594

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1566
金钱
1566
注册时间
2017-7-17
在线时间
307 小时
发表于 2019-9-2 17:11:13 | 显示全部楼层
本帖最后由 candylife9 于 2019-9-9 09:52 编辑

不是你对alway理解有问题,是你用软件的思维去设计硬件。综合结果是没有问题的,硬件行为也是按照你描述的去做的。就这个例子来说,你硬件描述语言被综合之后,就会生成这个锁存器,而不是在运行的时候,或者说touch改变的时候才生产的,它就是个硬件电路,就一直在那里,但是这个电路的行为是在描述语言里面定义的,硬件是没有什么运行的概念的。你这里是描述了一个锁存器的功能,就是在touch有效的时候,取反led。硬件是一直有效的,而你是把verilog当成了软件,想成了他是一条一条执行的。------------我的想法是每次检测到电平变化,就检测一次电平信号是不是高电平,如果是高的话就改变led信号变化-------------,你这个想法,很明显就是软件思维,硬件的思维是:不管touch有没有变化,led都会有输出的(不管touch有没有变化,touch的电平都会对led状态有影响,而不是变的时候才检测一次)。

重点:1.你这个例子,begin--end里面的行为就是描述了一个带使能的反相器。(alway描述的就是使能端有效或无效)
          2.你没有理解硬件描述语言。
          3.verilog是硬件描述语言,它描述硬件的行为,是描述,描述,描述,而不是硬件需要执行的代码,代码,代码。
回复

使用道具 举报

558

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
164897
金钱
164897
注册时间
2010-12-1
在线时间
2100 小时
发表于 2019-9-3 02:45:09 | 显示全部楼层
帮顶
回复

使用道具 举报

1

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2019-3-5
在线时间
42 小时
发表于 2019-9-3 09:33:45 | 显示全部楼层
电平发生变化的时候,不论从高到底还是从低到高,都会触发,这个程序我也不知道错在哪儿了,帮顶,或者你可以改成touch边沿触发试试
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2019-7-17
在线时间
5 小时
 楼主| 发表于 2019-9-3 17:35:54 | 显示全部楼层
LíuQían 发表于 2019-9-3 09:33
电平发生变化的时候,不论从高到底还是从低到高,都会触发,这个程序我也不知道错在哪儿了,帮顶,或者你可 ...

改成边沿触发就得用原子的代码检测高电平了,我就想看看这个这个代码的问题错误出现在哪
回复

使用道具 举报

1

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2019-3-5
在线时间
42 小时
发表于 2019-9-3 19:19:17 | 显示全部楼层
kqkqk 发表于 2019-9-3 17:35
改成边沿触发就得用原子的代码检测高电平了,我就想看看这个这个代码的问题错误出现在哪

会不会是 硬件的问题 你知道modlesim吗,装一个 然后写一下测试代码 看一下结果,可能触摸了以后,电平就是不稳定,会来回跳
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2019-7-17
在线时间
5 小时
 楼主| 发表于 2019-9-4 11:37:57 | 显示全部楼层
LíuQían 发表于 2019-9-3 19:19
会不会是 硬件的问题 你知道modlesim吗,装一个 然后写一下测试代码 看一下结果,可能触摸了以后,电平就 ...

应该不是硬件的问题,电路图生成锁存器就应该是错的,而且如果有按键抖动的话,原子的代码也不对
回复

使用道具 举报

0

主题

97

帖子

0

精华

高级会员

Rank: 4

积分
654
金钱
654
注册时间
2015-5-23
在线时间
125 小时
发表于 2019-9-4 16:42:54 | 显示全部楼层
本帖最后由 denike 于 2019-9-4 16:44 编辑

module key_touch(input touch,output reg led);
always@(touch)
begin
  if(touch==1)
   led=~led ;
else
led=led ;
end
endmodule
改成这样才不会生成锁存器,if else 最好要写全
回复

使用道具 举报

3

主题

1921

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5336
金钱
5336
注册时间
2018-10-21
在线时间
1484 小时
发表于 2019-9-6 16:01:56 | 显示全部楼层
直接 assign led = touch即可。
回复

使用道具 举报

37

主题

594

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1566
金钱
1566
注册时间
2017-7-17
在线时间
307 小时
发表于 2019-9-6 16:31:48 | 显示全部楼层
FPGA是数字电路,一个上升沿对应着一次电路状态的刷新,就跟刷新一个网页一样,不要按照代码的思维去理解FPGA的verilog。另外,这不叫作代码,叫硬件描述语言。
回复

使用道具 举报

17

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
365
金钱
365
注册时间
2012-6-20
在线时间
99 小时
发表于 2019-9-6 18:01:40 | 显示全部楼层
always@(posedge touch)
        begin
        led<=!led ;
          end
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2019-7-17
在线时间
5 小时
 楼主| 发表于 2019-9-6 19:14:56 | 显示全部楼层
QinQZ 发表于 2019-9-6 16:01
直接 assign led = touch即可。

那样的话,不就是触碰按键,led亮,离开按键led灭了吗,和要求不符啊
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2019-7-17
在线时间
5 小时
 楼主| 发表于 2019-9-6 19:16:07 | 显示全部楼层
candylife9 发表于 2019-9-6 16:31
FPGA是数字电路,一个上升沿对应着一次电路状态的刷新,就跟刷新一个网页一样,不要按照代码的思维去理解FP ...

谢谢 你回复,但我感觉你好像没明白我的问题……
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2019-7-17
在线时间
5 小时
 楼主| 发表于 2019-9-6 19:23:39 | 显示全部楼层
MY40130064 发表于 2019-9-6 18:01
always@(posedge touch)
        begin
        led

这两个逻辑应该是一样的吧,把你代码综合后生成的rtl图还是和之前一样的
回复

使用道具 举报

3

主题

1921

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5336
金钱
5336
注册时间
2018-10-21
在线时间
1484 小时
发表于 2019-9-8 09:15:13 | 显示全部楼层
kqkqk 发表于 2019-9-6 19:14
那样的话,不就是触碰按键,led亮,离开按键led灭了吗,和要求不符啊

如果你想触摸一次,改变LED的状态,那么只能像例程一样去采上升沿了
回复

使用道具 举报

17

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
365
金钱
365
注册时间
2012-6-20
在线时间
99 小时
发表于 2019-9-9 09:09:02 | 显示全部楼层
1.jpg
回复

使用道具 举报

37

主题

594

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1566
金钱
1566
注册时间
2017-7-17
在线时间
307 小时
发表于 2019-9-9 09:33:31 | 显示全部楼层
本帖最后由 candylife9 于 2019-9-9 09:34 编辑
LíuQían 发表于 2019-9-3 09:33
电平发生变化的时候,不论从高到底还是从低到高,都会触发,这个程序我也不知道错在哪儿了,帮顶,或者你可 ...

哎,没想到这么多人,连硬件和软件的区别都没有搞清楚,连基本的硬件思维都不具备,居然把verilog叫做程序。。。。
回复

使用道具 举报

37

主题

594

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1566
金钱
1566
注册时间
2017-7-17
在线时间
307 小时
发表于 2019-9-9 10:49:38 | 显示全部楼层
denike 发表于 2019-9-4 16:42
module key_touch(input touch,output reg led);
always@(touch)
begin

你这个描述类似于一个两路选择器的功能,也不能实现他的要求。
选择器.jpg
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2019-7-17
在线时间
5 小时
 楼主| 发表于 2019-9-9 10:54:35 | 显示全部楼层
candylife9 发表于 2019-9-2 17:11
不是你对alway理解有问题,是你用软件的思维去设计硬件。综合结果是没有问题的,硬件行为也是按照你描述的 ...

可是如果按照我always块功能定义和我描述的逻辑,它综合出的电路不应该是在我touch信号有变化且变为高电平时led只取一次反吗?为什么生成的电路的逻辑是在touch为高时led一直取反呢?综合出来的电路功能和我描述的电路逻辑不一样,怎么能叫综合结果没问题呢?
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2019-7-17
在线时间
5 小时
 楼主| 发表于 2019-9-9 10:56:47 | 显示全部楼层

这个是你之前发的那段代码仿真出来的波形吗?我之前把你那段代码综合后看电路图和我之前的一样就没有烧到板子上试,我今天回去试一试
回复

使用道具 举报

1

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2019-3-5
在线时间
42 小时
发表于 2019-9-9 11:14:43 | 显示全部楼层
candylife9 发表于 2019-9-9 09:33
哎,没想到这么多人,连硬件和软件的区别都没有搞清楚,连基本的硬件思维都不具备,居然把verilog叫做程 ...

感谢 受教了  硬件描述语言 不是程序代码
回复

使用道具 举报

37

主题

594

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1566
金钱
1566
注册时间
2017-7-17
在线时间
307 小时
发表于 2019-9-9 22:36:29 | 显示全部楼层
kqkqk 发表于 2019-9-9 10:54
可是如果按照我always块功能定义和我描述的逻辑,它综合出的电路不应该是在我touch信号有变化且变为高电 ...

因为你一旦touch改变,那么begin--end里面的描述就开始生效(不要理解为执行一次)。所以当touch由0变为1的时候,touch为高满足,led取反这个动作就会生效,而不是执行一次。当touch由1变为0时,begin--end里描述的行为同样生效,但是由于touch为低,所以被输出信号被锁存。
回复

使用道具 举报

37

主题

594

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1566
金钱
1566
注册时间
2017-7-17
在线时间
307 小时
发表于 2019-9-9 22:50:01 | 显示全部楼层
kqkqk 发表于 2019-9-9 10:54
可是如果按照我always块功能定义和我描述的逻辑,它综合出的电路不应该是在我touch信号有变化且变为高电 ...

还要纠正一个问题,就是alway敏感事件的发生和if(touch)的判断是没有先后的,不是touch改变后,再判断touch高低。而是,touch改变时,根据touch的高低,决定led信号的输出,因为硬件是“并行”的。所以,touch由0变为1时,touch到底是高还是低,还要看综合的结果。
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2020-3-29
在线时间
1 小时
发表于 2020-3-29 13:21:19 | 显示全部楼层
led没有初始值执行结果是未知的,所以达不到你想要的效果。就像在c语言中对一个未初始化的变量进行操作一样,结果也无法确定。
下面这段代码能实现你想要的功能,但是由于没有时钟所以输出无法与系统时钟同步,这可能会对后级电路造成未知的错误
module beep(
    input       sys_rst_n,
    input       ctrl,              //控制信号,下降沿蜂鸣器状态改变
   
    output  reg beep        //蜂鸣器输出
);

always @(*) begin
    if(!sys_rst_n)
        beep <= 1'b0;
    else if(ctrl == 0)
        beep = ~beep ;
    else
        beep = beep;
end

endmodule

回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
3
金钱
3
注册时间
2020-4-2
在线时间
0 小时
发表于 2020-4-2 21:39:41 | 显示全部楼层
行为仿真的结果应该和你的想法一致,而最终的结果和行为仿真不同。
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
3
金钱
3
注册时间
2020-4-2
在线时间
0 小时
发表于 2020-4-2 21:40:59 | 显示全部楼层
生成的硬件电路touch就只是一个使能信号。
回复

使用道具 举报

1

主题

21

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2019-5-3
在线时间
7 小时
发表于 2020-5-13 23:49:04 | 显示全部楼层
我从来不会这么写代码,FPGA研发工程师两年了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-6-8 10:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表