搜索
bottom↓
回复: 26

阻塞和非阻塞

[复制链接]

出0入0汤圆

发表于 2009-2-26 17:19:45 | 显示全部楼层 |阅读模式
有这样一段代码:本来意图是8进制计数器
always @(posedge clk)
    begin
       cnt<=cnt+1;
       if (cnt==8)
          cnt<=0;
    end
同一个块里对cnt两次非阻塞赋值,仿真后变成9进制计数器了?
如果改成阻塞赋值,仿真就对了.

对非阻塞一直理解不对.

谢谢

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

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

出0入0汤圆

发表于 2009-2-26 20:09:17 | 显示全部楼层
当然不是你这么写的啊,这样的话增量和判断是同时进行的.

得用else.

时序逻辑肯定用非阻塞了.

改成阻塞后可以是因为先增量后判断,是分开执行的

出0入0汤圆

 楼主| 发表于 2009-2-27 09:17:50 | 显示全部楼层
非常感谢!

出0入0汤圆

 楼主| 发表于 2009-2-27 11:20:49 | 显示全部楼层
假设要求信号占空比3:5,代码如下:

always @(posedge clk)
        begin
           if (testCnt==0)
              testImg<=1;
           else if (testCnt==3)
                testImg<=0;
           if (testCnt==8)
              begin
                testCnt<=0;
                testImg<=0;
              end
           else testCnt<=testCnt+1;
         end       
如果按上面代码,仿真结果信号占空比3:6,而不是3:5.

只有if (testCnt==7)
   begin
        testCnt<=0;
        testImg<=0;
   end
仿真结果信号占空比3:5.

一直没理解过来,谢谢.

出0入0汤圆

发表于 2009-2-27 11:33:15 | 显示全部楼层
就是这样的,用7就可以了.

出0入0汤圆

 楼主| 发表于 2009-2-27 11:41:44 | 显示全部楼层
是用7,但没弄明白,方便的话能指点吗?谢谢

出0入0汤圆

发表于 2009-2-27 11:52:53 | 显示全部楼层
怎么说呢,你画个图或者看仿真图一下就明白了啊.

本来到8的时候已经过了8个周期(如果这时对img=1的话就是3/8),

但你把cnt,img都置0了,要下一时钟来的时候cnt=0才会对img=1,那你数数实际上用了多少个周期?

所以实际需要设置为"周期-1"(其实就是0也得算上)


另外,建议你以后把增量(计数器)和判断分两个always来写.

出0入0汤圆

 楼主| 发表于 2009-2-27 11:59:48 | 显示全部楼层
谢谢.我来好好学习.

出0入0汤圆

 楼主| 发表于 2009-2-27 12:07:39 | 显示全部楼层
谢谢 Oliver ,我看明白了.
非阻塞可以这样理解吗:
1.非阻塞一定要有个D触发期;
2.非阻塞得到的值一定是下一个CLK才得到?

您说的把增量(计数器)和判断分两个always来写.
always @(posedge clk)
        begin
           if (testCnt==0)
              testImg<=1;
           else if (testCnt==3)
                testImg<=0;
           if (testCnt==8)
              begin
                testCnt<=0;
                testImg<=0;
              end
    end

always @(posedge clk)
testCnt<=testCnt+1;
         end

出0入0汤圆

 楼主| 发表于 2009-2-27 12:07:40 | 显示全部楼层
.

出0入0汤圆

 楼主| 发表于 2009-2-27 12:07:40 | 显示全部楼层
谢谢 Oliver ,我看明白了.
非阻塞可以这样理解吗:
1.非阻塞一定要有个D触发期;
2.非阻塞得到的值一定是下一个CLK才得到?

您说的把增量(计数器)和判断分两个always来写.
always @(posedge clk)
        begin
           if (testCnt==0)
              testImg<=1;
           else if (testCnt==3)
                testImg<=0;
           if (testCnt==8)
              begin
                testCnt<=0;
                testImg<=0;
              end
    end

always @(posedge clk)
testCnt<=testCnt+1;
         end

出0入0汤圆

 楼主| 发表于 2009-2-27 12:08:26 | 显示全部楼层
谢谢 Oliver ,我看明白了.
非阻塞可以这样理解吗:
1.非阻塞一定要有个D触发期;
2.非阻塞得到的值一定是下一个CLK才得到?

您说的把增量(计数器)和判断分两个always来写. 是这样吗?:
always @(posedge clk)
        begin
           if (testCnt==0)
              testImg<=1;
           else if (testCnt==3)
                testImg<=0;
           if (testCnt==8)
              begin
                testCnt<=0;
                testImg<=0;
              end
    end

always @(posedge clk)
   testCnt<=testCnt+1;

出0入0汤圆

发表于 2009-2-27 12:23:31 | 显示全部楼层
testcnt等于0 1 2 3 4 5 6 7 一共8位

出0入0汤圆

发表于 2009-2-27 12:39:23 | 显示全部楼层
阻塞和非阻塞你需要去看一下书到底是如何权威解释的.

记住一点,时序逻辑用非阻塞,组合逻辑用阻塞.这样就对了,至于区别,用法,原理,为什么你可以查书再好好理会.

当然乱用也可以的,不过有些平台会警告甚至编译错误.

always @(posedge clk or negedge rst)begin
    if(!rst)
       cnt <= 'd0;
    else begin
       if(cnt == 3'd7)
          cnt <= 'd0;
       else
          cnt <= cnt + 3'd1;
    end
end
always @(*)begin
    if(!rst)
       img = 1'd0;
    else
       img = (cnt < 3)1'b1:1'b0;
end

再网页上打这个冒火得很,我都是用SI来编辑的.

<<WERILOG HDL设计与验证>>不错的,看看吧.

出0入0汤圆

 楼主| 发表于 2009-2-27 13:37:27 | 显示全部楼层
谢谢大家帮助.
看了本夏宇闻老师的书,感觉非阻塞讲的不是很明白,当然主要是自己领悟力不够.

出0入0汤圆

 楼主| 发表于 2009-2-27 13:49:04 | 显示全部楼层
设计与验证--Verilog HDL     

点击看大图 市 场 价 :  ¥32.00  
会员价 : ¥24.00 (75折)   

购买  收藏  
【作  者】 EDA先锋工作室 吴继华 王诚 [同作者作品]  
【出 版 社】  人民邮电出版社
【书 号】 7115150419
【开 本】 16开
【页 码】 228
【出版日期】 2006年8月

是这本书吗? 谢谢. 周末去买本.

出0入0汤圆

 楼主| 发表于 2009-2-27 15:11:13 | 显示全部楼层
看了王金明老师的书,又做了个例子:
module block(
    input a,
    output b,
    output c,
    output d,
    output e,
    input clk
    );
reg b0,c0,d0,e0;
assign b=b0;
assign c=c0;
assign d=d0;
assign e=e0;
always @(posedge clk)
        begin
                b0=a;
                c0=b0;
        end
       
always @ (posedge clk)
        begin
           d0<=a;
                e0<=d0;
        end
endmodule

综合后的原理图

(原文件名:sch.jpg)

仿真波形

(原文件名:wav.jpg)

出0入0汤圆

 楼主| 发表于 2009-2-27 15:19:08 | 显示全部楼层
b c d 和 a的波形完全一样,d是非阻塞,应该延迟1个时钟吗?

上面做的和王老师的书上讲解不一样.



(原文件名:w0.jpg)


(原文件名:w1.jpg)


(原文件名:w2.jpg)

出0入0汤圆

发表于 2009-2-27 20:23:44 | 显示全部楼层
就是那本书,买来看看吧,入门还是不错的.

方针最好用modelsim se来做,开始定位就定好.

出0入0汤圆

 楼主| 发表于 2009-2-28 23:10:04 | 显示全部楼层
谢谢,今天去没买到,06年出的.

出0入0汤圆

发表于 2009-3-1 00:37:51 | 显示全部楼层
不一定非得这本,我是觉得还不错才说这本的.

PPA2001推荐我的那本没有所以我买了这本.差不多就可以了.

网上很多资料很水的,必须得有本书在身边翻翻

出0入0汤圆

 楼主| 发表于 2009-3-2 09:09:16 | 显示全部楼层
谢谢Oliver,网上可以买到的,您能帮我再推荐几本书吗?我一起去买.
方便的话,能帮我看看17楼的例子吗?
多谢.

出0入0汤圆

发表于 2009-3-3 19:00:25 | 显示全部楼层
唉,奇怪的网络,打一半又不响应,把内容复制下来,结果是一个链接,晕...

感觉你对非阻塞没理解,翻翻书吧.

最典型的就是
b=a;
c=b;
d=c;


b<=a;
c<=b;
d<=c;

出0入0汤圆

 楼主| 发表于 2009-3-4 10:02:51 | 显示全部楼层
谢谢,确实如大侠所说对非阻塞不理解.
b=a: b 和a同步?
b<=a: b滞后a一个时钟?

出0入0汤圆

发表于 2009-3-4 13:31:36 | 显示全部楼层
主要不是延迟一拍,是其他语句是否同时执行.
如:
b=a;
c=b;
d=c;
最后的结果是a=b=c=d,因为他们是阻塞执行的,如当执行c=b时,b的值在上步已经被赋成了a;依此类推

如:
b<=a;
c<=b;
d<=c;
最后的结果是d=c;c=b;b=a(它们不相等),相当于移了1位(d<-c<-b<-a).
因为他们是同时执行的.执行c<=b时,b的值不等于a,都同时赋值.

出0入0汤圆

 楼主| 发表于 2009-3-4 15:04:19 | 显示全部楼层
谢谢oliver,明白好多了.

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-24 19:30

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

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