搜索
bottom↓
回复: 16

一个关于时序逻辑的困惑,希望大家一起讨论

[复制链接]

出0入0汤圆

发表于 2012-6-25 15:12:32 | 显示全部楼层 |阅读模式
本帖最后由 lijieamd 于 2012-6-25 15:13 编辑

我在用verilog描述时序电路时,始终有一个问题困扰我,可能确实有这个问题存在,也可能是我的理解不到位,现在我将问题描述出来,希望大家能一起讨论。

always@(negedge rst or posedge clk)
        begin
                if(~rst)
                begin
                        counter = 8'd0;
                end
                else
                begin
                        counter = counter + 8'd1;
                end       
        end

        always@(negedge rst or posedge clk)
        begin
                if(~rst)
                begin
                        A = 1'b0;
                end
                else if(counter == 8'd2)
                begin
                        A = 1'b1;
                end
        end

很简单的一个代码,clk上升沿驱动counter计数,在clk上升沿判断counter值,如果等于2,输出A=1

生成的RTL图和仿真波形如下




我对RTL图的理解是这样,在第一个clk上升沿到来之前,counter[7..0]的触发器输出是8’d0,输入是8’d1,第一个clk上升沿到来后,输出8’d1,第二个clk上升沿到来后,输出8’d2。
此时Equal0将输出1,A的触发器被使能,而同时第二个clk上升沿会使A的Q=D。

问题就在这里,也就是A触发器的ENA和触发端信号的先后问题。
从仿真图来看,触发端的clk上升沿应该来的更快,因为第二个clk上升沿的时候,A输出任然为0,到第三个clk上升沿,A才输出1。实际上我是想让第二个clk上升沿就输出A=1

如果出现下面这种情况



也就是在FPGA内部,clk到A触发器的走线长度远远大于到counter触发器的走线。那么在A和counter的触发端会有一个可观的延时,也就是时钟偏斜(SKEW),那么这样的话,在第二个clk上升沿到达A触发器的时候, A触发器的ENA端已经是1了,也就是说,在第二个clk上升沿,A就已经输出1了,这和仿真就不同了。

这是否意味着,这个verilog描述本就存在问题?
如果我想在任何情况下,都会稳定的在第二个clk上升沿使A输出1,应该如何实现呢?

希望大家能给我一些帮助,谢谢。

本帖子中包含更多资源

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

x

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-6-25 15:32:04 | 显示全部楼层
本帖最后由 lanliang714 于 2012-6-25 15:48 编辑

verilog描述问题,
可改为:assign A = (counter >= 8'd2) ? 1'b1 : 1'b0;

或者
always@(negedge rst or posedge clk)
        begin
                if(~rst)
                begin
                        A = 1'b0;
                end
                else if(counter == 8'd1)
                begin
                        A = 1'b1;
                end
        end

出0入0汤圆

发表于 2012-6-25 16:36:43 | 显示全部楼层
时钟线走全局时钟网络,它可以保证时钟信号到达各个目标逻辑单元的时延基本相同。
有条件的话,把代码下载到板子上跑一下,用逻辑分析仪看结果。

出0入0汤圆

 楼主| 发表于 2012-6-25 19:25:09 | 显示全部楼层
lanliang714 发表于 2012-6-25 15:32
verilog描述问题,
可改为:assign A = (counter >= 8'd2) ? 1'b1 : 1'b0;

写成 (counter == 8'd1) 的确能使得在第二个clk上升沿输出A=1,但是如果发生时钟偏斜,是不是可能像我上面所说的那样,就在第一个clk上升沿就已经输出A了呢

因为我想在多个counter值进行不同的逻辑操作,如果用组合逻辑的话,还行吗?

出0入0汤圆

 楼主| 发表于 2012-6-25 19:28:00 | 显示全部楼层
pocker5200 发表于 2012-6-25 16:36
时钟线走全局时钟网络,它可以保证时钟信号到达各个目标逻辑单元的时延基本相同。
有条件的话,把代码下载 ...

那有没有一种时序逻辑描述方法,即使发生了一定程度的时钟偏斜,任然会正常工作呢?

出0入442汤圆

发表于 2012-6-25 23:16:37 | 显示全部楼层
只要你的设计能满足时序约束,下到板子上就跟仿真一样。唯一要注意的是仿真时使用的一些信号要做一些调整,否则仿真结果不正确。

出0入0汤圆

发表于 2012-6-26 00:09:21 | 显示全部楼层
如果这样写呢?

always@(negedge rst or posedge clk)
        begin
                if(~rst)
                begin
                        counter = 8'd0;
                        A=1'b0;
                end
                else
                begin
                        counter = counter + 8'd1;
                        if (counter==8'b2) A=1'b1;
                end        
        end

出0入0汤圆

发表于 2012-6-26 09:11:09 | 显示全部楼层
lijieamd 发表于 2012-6-25 19:25
写成 (counter == 8'd1) 的确能使得在第二个clk上升沿输出A=1,但是如果发生时钟偏斜,是不是可能像我上 ...


多个counter值进行不同的逻辑操作??
不明白是啥意思?说具体点

出0入0汤圆

 楼主| 发表于 2012-6-26 13:27:41 | 显示全部楼层
岭上开花 发表于 2012-6-26 00:09
如果这样写呢?

always@(negedge rst or posedge clk)

谢谢,这样写是没问题,但是如果有多种输出,需要每种输出一个always的话,好像就没办法这样了

出0入0汤圆

 楼主| 发表于 2012-6-26 13:28:41 | 显示全部楼层
lanliang714 发表于 2012-6-26 09:11
多个counter值进行不同的逻辑操作??
不明白是啥意思?说具体点

也就是说有很多输出或者其他逻辑依赖于这个counter,如果每种一个always的话,不知道应该如何描述

出0入0汤圆

发表于 2012-6-26 14:20:03 | 显示全部楼层
lijieamd 发表于 2012-6-25 19:25
写成 (counter == 8'd1) 的确能使得在第二个clk上升沿输出A=1,但是如果发生时钟偏斜,是不是可能像我上 ...

如果时钟偏斜达到足以引起逻辑错误,布局布线工具会给出报告的。

出0入0汤圆

发表于 2012-6-26 15:22:32 | 显示全部楼层
lijieamd 发表于 2012-6-26 13:27
谢谢,这样写是没问题,但是如果有多种输出,需要每种输出一个always的话,好像就没办法这样了
...

多输出的话这样写:
always@(negedge rst or posedge clk)
        begin
                if(~rst)
                begin
                        counter = 8'd0;
                end
                else
                begin
                        counter = counter + 8'd1;
                end        
        end

always@(counter)
begin
        if (counter==8'd0)
        begin
                A<=1'b0;
                ......
        end
        else if (counter==8'd2)
        begin
                A<=1'b1;
                ......
        end
end

出0入0汤圆

发表于 2012-6-26 19:36:30 | 显示全部楼层
这些问题尽可能交给综合器去解决吧……

出0入90汤圆

发表于 2012-6-26 19:53:19 | 显示全部楼层
这个跟时钟的延时没关系,时钟上升沿到来时计数器从一变到二,而这一时刻触发器A的输入仍然为0。跟两个触发器串联起来是一个道理的。

出0入90汤圆

发表于 2012-6-26 19:57:55 | 显示全部楼层
想在第二个时钟的上升沿让A稳定的输出1,可以考虑让计数器在下降沿计数,判断的always块在上升沿判断,让他们的时钟错开,复位也要用同步的。

出0入90汤圆

发表于 2012-6-26 20:05:30 | 显示全部楼层
7楼的的写法用的阻塞赋值,同一个块中的语句是按顺序执行的,而不是并发的,所以没问题。一般推荐用<=非阻塞赋值的方式。

出0入0汤圆

 楼主| 发表于 2012-6-26 20:39:33 | 显示全部楼层
aammoo 发表于 2012-6-26 20:05
7楼的的写法用的阻塞赋值,同一个块中的语句是按顺序执行的,而不是并发的,所以没问题。一般推荐用 ...

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

本版积分规则

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

GMT+8, 2024-7-24 09:23

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

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