verilog 中forever always_求职攻略| 8个case学会FPGA中的阻塞与非阻塞

不想错过我的推送,记得右上角-查看公众号-设为星标,摘下星星送给我

925fa6af856ce24b4a8bffdc1b4924c7.gif b581450ff91dd0fc53fdfbac08987302.gif 笔试、面试中,有很多大家很容易迷惑的知识点,其中就有阻塞与非阻塞相关的问题。熟悉Verilog语言的同学都知道一个规范: 在always块中描述组合逻辑电路时使用阻塞(=)赋值的方式,在always块中描述时序逻辑电路时使用非阻塞(<=)赋值的方式 。但是出题人往往喜欢考不按照这个规范写出的代码会出现什么情况,其RTL视图又是怎样的。接下来让我们来看几个例子。

我们之前讲过跨时钟域相关的问题,知道单比特信号从慢速时钟域跨到快速时钟域需要进行打两拍的操作,那我们就以此为例,看看下面的这8种打两拍的代码,其RTL代码如下所示:

//----------------------------------------- 001`define CASE1 002 003module test( 004     input   wire    sclk   , 005     input   wire    rst_n  , 006     input   wire    in     , 007     008     output  reg     out      009); 010 011reg temp; 012 013//第1种情况:使用一个always块,并使用非阻塞赋值方式 014`ifdef CASE1 015always@(posedge sclk ornegedge rst_n) 016     if(rst_n ==1'b0)begin 017         temp <=1'b0; 018         out <=1'b0; 019     end 020     else begin 021         temp <= in; 022         out <= temp; 023     end 024`endif 025 026//第2种情况:使用一个always块,并使用阻塞赋值方式 027`ifdef CASE2 028always@(posedge sclk ornegedge rst_n) 029     if(rst_n ==1'b0)begin 030         temp =1'b0; 031         out =1'b0; 032     end 033     else begin 034         temp = in; 035         out = temp; 036     end 037`endif 038 039//第3种情况:使用一个always块,并使用非阻塞赋值方式,且输出信号和中间变量的赋值顺序进行了调换 040`ifdef CASE3 041always@(posedge sclk ornegedge rst_n) 042     if(rst_n ==1'b0)begin 043         temp <=1'b0; 044         out <=1'b0; 045     end 046     else begin      047         out <= temp; 048         temp <= in; 049     end 050`endif 051 052//第4种情况:使用一个always块,并使用阻塞赋值方式,且输出信号和中间变量的赋值顺序进行了调换 053`ifdef CASE4 054always@(posedge sclk ornegedge rst_n) 055     if(rst_n ==1'b0)begin 056         temp =1'b0; 057         out =1'b0; 058     end 059     else begin   060         out = temp; 061         temp = in; 062     end 063`endif 064 065//第5种情况:使用两个always块,并使用非阻塞赋值方式 066`ifdef CASE5 067always@(posedge sclk ornegedge rst_n) 068     if(rst_n ==1'b0)   069         temp <=1'b0;  070     else  071         temp <= in; 072   073always@(posedge sclk ornegedge rst_n) 074     if(rst_n ==1'b0)   075         out <=1'b0; 076     else        077         out <= temp; 078`endif 079 080//第6种情况:使用两个always块,并使用阻塞赋值方式 081`ifdef CASE6 082always@(posedge sclk ornegedge rst_n) 083     if(rst_n ==1'b0)   084         temp =1'b0;  085     else  086         temp = in; 087   088always@(posedge sclk ornegedge rst_n) 089     if(rst_n ==1'b0)   090         out =1'b0; 091     else        092         out = temp; 093  `endif 094 095//第7种情况:使用一个always块,并使用非阻塞赋值方式,且使用位拼接的方式 096`ifdef CASE7 097always@(posedge sclk ornegedge rst_n) 098     if(rst_n ==1'b0)   099         {out,temp}<=2'b0; 100     else        101         {out,temp}<={temp,in}; 102  `endif 103 104//第8种情况:使用一个always块,并使用阻塞赋值方式,且使用位拼接的方式 105`ifdef CASE8 106always@(posedge sclk ornegedge rst_n) 107     if(rst_n ==1'b0)   108         {out,temp}=2'b0; 109     else        110         {out,temp}={temp,in}; 111  `endif 112  113endmodule //------------------------

如果不先看我们综合与仿真的结果就能够把上面8种情况综合的RTL视图和仿真波形正确画出的同学,说明你对阻塞和非阻塞这块的了解已经很透彻了。

我们分别使用Quartus_13.0和Vivado_19.1工具来查看综合结果,使用Modelism_10.5SE和Vivado_19.1 Simulator工具来查看仿真波形图。下面就让我们依次查看以上8种情况的RTL视图与仿真波形图。

CASE1:根据下图可以看出无论是RTL视图还是仿真波形图都是我们预想的常规打两拍的结果。

bacfa4a2b3096d8bae28bdfc48fac1a0.png

4dd898a8ef0985134dc5649f7dfa48ba.png

7b0d31df3faa22b68b70d95fb134e1c3.png

7943e3c5991e55aebd5c432f270e053e.png

CASE2:根据下图可以看出无论是RTL视图还是仿真波形图都不是我们预想的常规打两拍的结果,显然是出现了错误。

d4a982f5ea9bc68fc15bc3fe63035f7e.png

9c4c3e4d3e736b25c57997e0050fe3df.png

b6e7ede8be16885fd68f191010741986.png

528ddc9f9bcc3b52d6dbe3cee3ba9801.png

CASE3、CASE4、CASE5,都与CASE1结果完全相同。

CASE6:根据下图可以看出RTL视图是我们预想的常规打两拍的方式,而仿真的波形图因仿真工具的不同,而产生了不同的效果,这是及其危险的情况,在设计中如果出现了该问题很难排查错误的原因。

bacfa4a2b3096d8bae28bdfc48fac1a0.png

70d276b0dbf2e5d9b77f12b5f30502f2.png

7501567a8bccffee26ddd42a33f98cde.png

7943e3c5991e55aebd5c432f270e053e.png

CASE7、CASE8:与CASE1结果完全相同。

我们根据实验的结果列出如下表格进行对比:

情况

RTL视图

仿真波形图

CASE1

正确

正确

CASE2

错误

错误

CASE3

正确

正确

CASE4

正确

正确

CASE5

正确

正确

CASE6

正确

错误

CASE7

正确

正确

CASE8

正确

正确

出问题的两种情况都是在always块描述时序逻辑的时候使用了阻塞赋值的方式,虽然CASE4和CASE8也使用了阻塞赋值方式而没有出现问题,但是绝对不能有这种侥幸心理,这也是为什么一直强调在编写Verilog代码的时候一定要按照规范来写的原因,否则在某些情况下连这种简单的打拍都会出现不可预测的错误,更不用说大型复杂的设计了。

另外再给大家看一个相似的例子,RTL代码如下所示:

//------------------------- 01 module test ( 02      input    wire     sclk    , 03      input    wire     rst_n   , 04      input    wire     in1     , 05      input    wire     in2     , 06      input    wire     in3     , 07      08      output   reg      out      09 ); 10 11 always @( posedge sclk or negedge rst_n ) 12      if ( rst_n == 1'b0 ) begin 13          out <= 1'b0 ; 14          out <= 1'b0 ; 15          out <= 1'b0 ; 16      end 17      else begin 18          out <= in1 ; 19          out <= in2 ; 20          out <= in3 ; 21      end 22 23 endmodule //--------------------------

看到RTL视图我们就知道结果了,直接等于最后赋值的结果。有人会说如果分成三个always来写是什么情况呢?大家不要忘记多个always块是并行执行的,同一个变量在多个always块中赋值,综合工具会报出现多驱动的报错。

3522681fbf91ca63c43490949681943a.png 33c7932051ed0784dd762857eda2a0ea.png

最后考察一下大家的掌握情况,留个题目大家做一做。

1e9afff96249ddfaf15a654c0039c8b9.png

假设初始值a=1,b=2,c=3,请问下一个时间,A,B模块代码中a,b,c的值分别为多少?

A 1,1,1;1,1,1   

B 1,1,1;3,1,2

C 3,1,2;1,1,1      

D 3,1,2;3,1,2   

END d12fbb1a89875f60f5466818861ae40b.png

目前,我们正在通过大疆硬件岗和FPGA逻辑岗的题目,为大家带来笔试题的解析,以及知识的补充。如果有想要解析的题目,可以发给达尔闻安排。同时,欢迎加入达尔闻求职技术交流群,进群方式:添加妮姐微信(459888529),并备注求职,即可邀请进群

达尔闻求职系列: 华为海思校招机考范围 求职攻略| 运放压摆率&三运放仪表放大电路分析,含仿真文件 磁珠的用法、PCB布线3W规则

单比特信号跨时钟域问题详解

如何搞定状态机问题 电容击穿表现为短路? MOS管导通损耗和什么有关?

毛刺滤除的代码应该如何写

资深工程师总结减小串扰的7种方法

二进制数11.101对应的十进制数是多少

FGPA时序分析看这篇就够了 逻辑电路24种表达式

芯片工艺28nm的28是指什么

FPGA设计中的时序收敛准则 华为硬件逻辑岗(FPGA) 紫光展锐数字IC岗(编程题) 从无人机爱好者到获得DJI大疆Offer offer拿到手软,最后选华为!

IO的时序约束该如何设置

典型FPGA器件常用资源

死活清除不了的亚稳态,怎么减少出现概率?

典型5级流水线RSIC结构中的5大功能

三步优化FPGA时序设计

噪声还分颜色?粉红、白噪声解析

电源拓扑别再傻傻搞不清楚

开关电源中的MOS功耗来源

晶体管的静态工作点一步快速搞定!

老司机也复习功率二极管、三相半波可控整流电路

2021年校招提前批第一枪(vivo芯片设计岗)

建立时间VS保持时间,竞争VS冒险(紫光展锐IC笔试题)

RAM的大小为520*8bit,其地址需要多少位

有符号4位二进制数运算0101+1000,还会计算吗

错综复杂的建立保持时间路径你能搞明白吗

关于稳压二极管的坑,你一定要知道

学会分频,“为所欲为”

一网打尽状态机的套路

ee0cd86b06e3a68acd8a7fc7368724f2.png

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页