搜索
bottom↓
回复: 27

新手请教一个verilog代码的问题,就一个命令。

[复制链接]

出0入0汤圆

发表于 2016-7-30 23:06:23 | 显示全部楼层 |阅读模式
小弟最近刚学verilog,我看网上的教程中,基本的模子就是 always@(posedge CLK or negedge RESET)
我试着写了如下代码:
(目的是每按一次按键,8个led就翻转一次)
output wire[7:0] ledR,
reg [7:0]rledR;
always@(posedge CLK or negedge key0)
begin
        if(!key0)
                rledR = ~rledR;
end
assign ledR = rledR;

但实际情况是8个led随机亮灭。
但是如果在always敏感条件中去掉"posedge CLK ",结果就正常了。
想问下,是什么原因?
下面是仿真波形:

本帖子中包含更多资源

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

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2016-7-30 23:07:55 | 显示全部楼层
不好意思,图发大了。

出0入0汤圆

 楼主| 发表于 2016-7-30 23:20:32 | 显示全部楼层
在线做等,有人不

出0入0汤圆

 楼主| 发表于 2016-7-31 00:41:50 | 显示全部楼层

出0入0汤圆

发表于 2016-7-31 00:53:00 来自手机 | 显示全部楼层
按键都没消抖处理,正常就怪了

出0入0汤圆

 楼主| 发表于 2016-7-31 02:20:29 | 显示全部楼层
de2的板子已经硬件消抖了

出0入0汤圆

发表于 2016-7-31 07:22:13 | 显示全部楼层
CLK 检测好多次,出现亮或灭,判断按键沿

出0入0汤圆

发表于 2016-7-31 07:35:49 | 显示全部楼层
将key0,打两拍,检测key0的边沿,根据是检测上升沿还是下降沿,能实现按下去就翻转还是松手翻转。

另外外部信号不做时钟同步,不是个好习惯

出0入0汤圆

发表于 2016-7-31 10:02:38 | 显示全部楼层
always@(posedge CLK or negedge key0)
信号别加在敏感列表中,最基本的习惯

出0入4汤圆

发表于 2016-7-31 10:15:30 | 显示全部楼层
你的clk有用吗

出0入0汤圆

发表于 2016-7-31 10:18:13 | 显示全部楼层
没有打拍,而且信号直接搞到了列表中,全是坏习惯。

出0入0汤圆

 楼主| 发表于 2016-7-31 10:25:40 | 显示全部楼层
tangwei039 发表于 2016-7-31 07:22
CLK 检测好多次,出现亮或灭,判断按键沿

但按键下降沿只会检测到一次吧,CLK到来时,我若不按,并不满足条件 if(!key0)吧 ,那就什么也不执行

出0入0汤圆

 楼主| 发表于 2016-7-31 10:29:13 | 显示全部楼层

没有用,所以我只是试一下,但结果就不对了,不知道什么原因

出0入0汤圆

 楼主| 发表于 2016-7-31 10:39:44 | 显示全部楼层
champion_yan 发表于 2016-7-31 07:35
将key0,打两拍,检测key0的边沿,根据是检测上升沿还是下降沿,能实现按下去就翻转还是松手翻转。

另外外 ...

打两拍是什么意思?我现在就是下降沿(按下去)就翻转的,
另外,我这里外部时钟需要同步什么吗?不明白..

出0入0汤圆

发表于 2016-7-31 11:27:26 | 显示全部楼层
试试这个:
always @ (negedge key0)
    rledR <= ~rledR;

出0入0汤圆

 楼主| 发表于 2016-7-31 11:47:47 | 显示全部楼层
stdio 发表于 2016-7-31 11:27
试试这个:
always @ (negedge key0)
    rledR

这个当然可以了,我上面也说过了

出0入0汤圆

发表于 2016-7-31 12:24:50 | 显示全部楼层
always@(posedge CLK)不要把敏感信号key0放里面;虽然always @ (negedge key0)做做代码小实验是可行的,但不实用,因为key0是有抖动的,放always里在抖动的过程会执行若干次并且没有办法做去抖动处理的,led还好,若是白炽灯早被你闪爆了!

出0入0汤圆

 楼主| 发表于 2016-7-31 12:52:41 | 显示全部楼层
why1220 发表于 2016-7-31 12:24
always@(posedge CLK)不要把敏感信号key0放里面;虽然always @ (negedge key0)做做代码小实验是可行的,但不 ...

恩,我知道你的意思,但那8个灯的亮灭是随机的,你看上面的时序就是这样,比如57h,aah,6eh...而不是ffh,00h

出0入0汤圆

发表于 2016-7-31 13:09:46 | 显示全部楼层
"但是如果在always敏感条件中去掉"posedge CLK ",结果就正常了。" 你的复位一直有效的吧;你把RESET的信号也抓出来看一下;

1:对于DE2的板子,判断按键是否按下,应该判断下降沿或者上升沿;
2:还是按键对于clk是异步信号,应该使用两级DFF稳定一下;

出0入0汤圆

发表于 2016-7-31 16:11:00 来自手机 | 显示全部楼层
随机亮灭说的有点模糊,是不是按下按钮有时会有效,有时会无效?

出0入0汤圆

发表于 2016-7-31 17:20:05 | 显示全部楼层
always@(posedge CLK or negedge key0)   ,一看就是错误的。
原因是,在一个基本逻辑的敏感表里,不能有两个以上的不同边沿触发。
试想一下,如果允许两个以上的不同边沿触发发生在一个基本逻辑里,那么你的设计将对应什么样的基本逻辑电路?
答案是,找不到这样的基本逻辑电路来对应,尽管你觉得硬件描述语言语法上似乎是站得住脚的(类似C语言)。但硬件描述语言,必须有对应硬件可实现,软件语言只是个实现硬件设计的载体和工具而已。
解决方法,就是将你的思维再细化一点,一直细分到每个 always@() 里只有一个边沿触发事件(电平敏感可任意),然后再将N个 always@() 关联起来即可。

出0入0汤圆

发表于 2016-7-31 18:40:59 来自手机 | 显示全部楼层
key0 又不是one clk wide pulse 翻转多少次是随机的

出0入0汤圆

发表于 2016-8-1 09:24:07 | 显示全部楼层
本帖最后由 sme 于 2016-8-1 09:26 编辑

晕,这么多人都没扯到点子上。

1
always@(posedge CLK or negedge key0)
begin
        if(!key0)
                rledR = ~rledR;
end
楼主的以上代码的写法,key0是作为异步复位/置位,即异步置数,在这里由于CLK没有使用到,所以电路实际上是一个8位的LATCH,即电平有效的锁存器,其8位输出端/Q接至D,这样即是一个死循环的电路,D -> Q -> /Q -> D,最后Q的状态取决于key0的上升沿。但是在key0为低电平的整个脉宽时间内(再重复,key0是电平信号),LATCH一直在翻转,由于8个LATCH从D至/Q的延时不可能绝对一致,所以虽然每个LATCH都是自身取反,但8个之间并不同步,这样就会出现楼主位的波形,看上去8个LATCH的结果是随机的。

2
但是如果在always敏感条件中去掉"posedge CLK ",结果就正常了。

这样修改后的代码,就变成了8个DFF,所以在key0的每次下降沿,DFF只会翻转一次,而且8个DFF的状态会一致。

出0入0汤圆

发表于 2016-8-1 10:14:30 | 显示全部楼层
你这个是既检测clk  也检测key0

出0入0汤圆

发表于 2016-8-1 10:27:44 来自手机 | 显示全部楼层
不去除clk,当key0按下后它会一直取反跳动,因为变化太快了人眼发现不了的!

出0入4汤圆

发表于 2016-8-1 16:08:23 来自手机 | 显示全部楼层
huanger 发表于 2016-8-1 10:27
不去除clk,当key0按下后它会一直取反跳动,因为变化太快了人眼发现不了的! ...

这是根本原因,人按下键是毫秒级的,你clk是多少?

出0入0汤圆

 楼主| 发表于 2016-8-1 21:42:12 来自手机 | 显示全部楼层
sme 发表于 2016-8-1 09:24
晕,这么多人都没扯到点子上。

1

你说的有道理,不过我不太明白为什么key0是电平信号?为什么成了电平锁存器?不应该是只有当key0下降沿时才满足always的条件吗?其他时候并不满足negedge key0呀,我可能还不太了解verilog是依据什么来对应硬件电路的

出0入0汤圆

发表于 2016-8-2 08:29:57 | 显示全部楼层
945595199 发表于 2016-8-1 21:42
你说的有道理,不过我不太明白为什么key0是电平信号?为什么成了电平锁存器?不应该是只有当key0下降沿时 ...

always @(posedge clk or negedge rst_n)
begin
  if (!rst_n)
  ...
  else
  ...
end
这种写法,rst_n是作为复位信号。而且是异步复位,为低电平有效,非边沿有效。

如果你是一组信号,非单个信号,例如
q <= 8'h5a;

则rst_n对赋值为0的位是复位,对赋值1的位是置位。

同理,如果赋值的不是常量,则是会从RST/SET端赋值过去,例如
q <= a;   // a is some signals

你的写法,实际上是将一组8位寄存器的QB再通过DFF的RST/SET端置进去,同时,因为你没有else部分,因此clk没有起作用。即电路如下:

QB -> SET/RESET -> QB

这形成了一个loop,而且延时就是器件延时。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 19:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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