完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
图一 图二 图三 图四 最近写了一个16位二级流水线加法器,并进行了一下仿真。发现在always块中采用阻塞赋值(=)和非阻塞赋值(<=)的结果是不一样的,书上的例程以及网上很多例程的流水线加法器都采用的是阻塞赋值。 书上对流水线加法器的描述是这样的:“采用流水线,能将一个算术操作分解为一些小规模的基本操作,将进位和中间值存储在寄存器中,并在下一个时钟周期内继续运算”。 如上图所示,图一、图二是采用非阻塞赋值的代码及仿真波形图,图三、图四是采用阻塞赋值的代码及波形图。明显可以看出,采用阻塞赋值的仿真结果是在一个时钟周期内得到结果,并没有像描述的那样在每个时钟周期内分级运算,也没有体现出流水线的特点;而非阻塞赋值好像更符合“下一个时钟周期内继续运算”的描述,也体现出了流水线的执行特点。 求大神指点! |
|
相关推荐
17个回答
|
|
采用阻塞赋值在这里是很危险的行为,仿真和综合的结果可能会不同,两个always执行的顺序实际上是不固定的(虽然我们理解时认为是并行执行,但是因为时钟延时,时钟实际到达寄存器的时间是不同的),不过也可能会被综合成我们想要的电路,虽然比非阻塞赋值运算结果快了一个时钟周期,不过不建议使用阻塞赋值
|
|
|
|
小白报道 发表于 2016-09-09 10:24 你了解流水线加法器吗?书上用的是阻塞赋值,但是仿真结果却跟我想象的不一样。我感觉非阻塞赋值的仿真结果更符合流水线执行的特点。是否是我对流水线的理解有偏差? |
|
|
|
渊底一尾 发表于 2016-9-9 10:46 我要是说这里用阻塞赋值是错误的,会不会有人喷死我 |
|
|
|
讲讲你的依据吧,我也感觉这里用阻塞赋值有问题,但是没有足够理论支撑 |
|
|
|
什么依据?流水线需要控制事件发生的前后顺序,上面的阻塞赋值并不能控制两个always事件发生的前后顺序,这算依据吗?你仿真只用了低8位,可以用满16位来仿真,再看一下综合后的RTL图,应该就可以看出来不同了 |
|
|
|
always@(posedege clk) 语句说明你要做的是同步逻辑设计,后面只能跟“非阻塞”赋值,而且你要做流水设计的话,就更应该是非阻塞赋值了;至于阻塞赋值,从语法上讲没有问题,但是最终综合成什么逻辑电路,就要完全看综合器对你这段代码的理解了,所以不同的软件版本之间,同一版本不同综合次数之间,不同的综合工具之间,最终综合结果都有可能不一样,属于不规范语法描述方式。所以不用去纠结第二代码了。
最后为什么不直接用 always@(posedge clk) begin {cout,sum}<=cina+cinb; end 不知道你把它分解成,高8Bit和低8bit分别相加是想干什么 ? |
|
|
|
同意楼上的观点 LS+1
|
|
|
|
同意楼上的观点 LS+1
|
|
|
|
alasga 发表于 2016-09-10 15:13 1、因为要采用流水线设计,所以没有直接用{cout,sum}。 2、采用图一代码,我发现仿真结果不对。上图中,我没有对高8位赋值。在我对高8位赋值后,发现:输出结果(cout)的高8位是当前输入高8位的和,而低8位则是上一个时钟输入低8位的和。请问应如何解决?不知您之前是否写过流水线加法器?求指教。 |
|
|
|
alasga 发表于 2016-09-10 15:13 上面说错了一点,是输出结果(sum),而不是(cout),cout是进位位 |
|
|
|
本帖最后由 hqbenson 于 2016-9-12 16:34 编辑 您好楼主。您再仔细分析一下您的代码就可以发现问题了。其实这和阻塞非阻塞没太大关系。(当然时序电路还是必须要用非阻塞的) 主要有 1.流水线的编写思路不太清晰。 2.always里面的加法和拼接符用的也有点问题。(写的是:{cout1,sum1}<={cina[7],cina[7:0]}+{cinb[7],cinb[7:0]}+cin;举个例子,如果低八位cina=a0;cinb=00;那么结果将是{1,a0},显示进位了。但实际并没有进位。所以有误。) 最主要的问题是流水线结构不对,根据您写的代码,我画了个RTL图,您看了图之后应该会很清楚了。 流水线的每一步都需要一个寄存器。 按图所示第一个时钟沿时,寄存器sum1寄存低八位的和值,但寄存器sum寄存的是上个时钟低八位部分的和值与当前输入值的和值。根本原因是因为高八位的加法器的输入随着cina和cinb改变而立即改变。所以才会出现您所说的高八位是当前的值,而低八位是上一个时钟的值。 正确的方法是要在画红圈处加一个寄存器锁存值。(可以锁存输入值,也可以锁存和值) |
|
|
|
非阻塞,用assign语句的话,可以用阻塞!
|
|
|
|
|
|
|
|
hqbenson 发表于 2016-9-12 16:23 您好!首先感谢您对我的问题作出如此详细的解答。 关于您所说的进位位以及每一级增加寄存器的问题,我后来也已经发现并改正了,但是使用阻塞赋值和非阻塞赋值的仿真结果仍然是不同的。阻塞赋值的仿真结果:输入和输出仍然是在一个时钟周期内完成,而非阻塞赋值的仿真结果:输入和输出却是阶梯状。 还望指点!谢谢! |
|
|
|
渊底一尾 发表于 2016-9-14 10:19 指点不敢..我也在学习中,只能按我理解的观点谈一下问题点... 楼主您可以试一下,源代码中,在用阻塞赋值时,如果将两个always调换位置(将第二个always写在前面,第一个always写在后面),仿真出来的结果会和原来的不一样。(sum要从第二个时钟沿才有输出,并且与当前的输入值之和不一致) 在用非阻塞赋值时,就算将两个always调换位置,仿真出来的结果是一样的。 根本原因在于,当仿真器运行到阻塞赋值语句时,先计算等号右边的值并更新,这时候赋值语句不允许任何别的verilog语句干扰,直到把该值赋值完成为止。 如果是非阻塞赋值语句,计算等号右边的值时,其他的verilog语句,非阻塞赋值语句都可以同时计算等号右边的值。非阻塞语句允许其他的语句同时操作。 按此理解,如果 1.原本代码,用阻塞:仿真器执行语句,按代码所述,第一个上升沿事件开始→计算出sum1和count1并立即赋值→计算cout和sum并立即赋值→结束上升沿事件。 2.原代码,用阻塞,将两个always对调:仿真器执行语句,第一个上升沿事件开始→计算出count和sum并立即赋值→计算出sum1和count1并立即赋值→结束上升沿事件。 3.原代码,用非阻塞:仿真器执行语句,第一个上升沿事件开始→计算出sum1和count1的值,同时计算sum,count的值(目标还未更新赋值)→更新赋值目标的值→结束上升沿事件。 情况1中,计算sum1与count1的阻塞赋值语句在前面,在sum与count执行之前,sum1与count1已经得到更新,所以第一个上升沿就有值输出。 情况2里面,由于把sum和count的语句写在了前面,仿真器先计算并更新它们俩的值,但由于此时sum1和count1仍是未知值,所以第一个时钟沿输出仍是未知值(红线),更新完sum与count后,才计算写在后面的always里面的sum1与count1的值并立即更新。 由于有这样的歧异,所以才可综合代码里,规定在含有时序逻辑的always块里面必须使用非阻塞。 由于流水线是典型的,严格的时序逻辑电路,所以必须使用非阻塞。 如果楼主您还不太理解,建议多写一些测试的小代码,用两种赋值修改看看仿真有什么不同然后用自己的想法去理解。当理解的差不多了,再写一些测试代码预测一下仿真结果,或者多看书上的例子。 |
|
|
|
本帖最后由 alasga 于 2016-9-14 22:38 编辑
渊底一尾 发表于 2016-9-12 08:34 简单,你把输入数据cina和cinb延迟1级,简称cina_d1和cinb_d1,在你的第二个always块中,高8bit的运算用cina_d1和cinb_d1代替就OK了,改完相信你就知道你的问题在哪了。另外刚才看了12楼的解说,他说的完全正解!!!,低8位相加时,应该不需要进行符号位扩展,毕竟这里的第8bit不是符号位。这一点倒是看了12楼的观点才发现。 |
|
|
|
hqbenson 发表于 2016-09-14 12:36 按照您所说的,我又试了多种情况,发现:代码写在一个always块和写在两个always块中的仿真结果是一样的,那么问题来了:如果触发条件相同,一个always块是否和多个always块的效果相同呢?多个always块的意义又何在呢? |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1512 浏览 1 评论
1295 浏览 0 评论
矩阵4x4个按键,如何把识别结果按编号01-16(十进制)显示在两个七段数码管上?
1503 浏览 0 评论
922 浏览 0 评论
2300 浏览 0 评论
1453 浏览 35 评论
5641 浏览 113 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 02:10 , Processed in 1.027790 second(s), Total 103, Slave 85 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号