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

  • Post author:
  • Post category:其他


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

925fa6af856ce24b4a8bffdc1b4924c7.gif
b581450ff91dd0fc53fdfbac08987302.gif
笔试、面试中,有很多大家很容易迷惑的知识点,其中就有

阻塞与非阻塞

相关的问题。熟悉Verilog语言的同学都知道一个规范:
在always块中描述组合逻辑电路时使用阻塞(=)赋值的方式,在always块中描述时序逻辑电路时使用非阻塞(<=)赋值的方式
。但是出题人往往喜欢考不按照这个规范写出的代码会出现什么情况,其RTL视图又是怎样的。接下来让我们来看几个例子。

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

//—————————————–
001`define CASE1
002
003

module

test

(

004

input


wire

sclk

,

005

input


wire

rst_n

,

006

input


wire

in

,

007    
008

output


reg

out     
009

);

010
011

reg

temp

;

012
013//第1种情况:使用一个always块,并使用非阻塞赋值方式
014`ifdef CASE1
015

always


@(


posedge

sclk

or


negedge

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
028

always


@(


posedge

sclk

or


negedge

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
041

always


@(


posedge

sclk

or


negedge

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
054

always


@(


posedge

sclk

or


negedge

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
067

always


@(


posedge

sclk

or


negedge

rst_n

)

068

if


(

rst_n

==

1’b0

)

069         temp

<=

1’b0

;

070

else

071         temp

<=

in

;

072  
073

always


@(


posedge

sclk

or


negedge

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
082

always


@(


posedge

sclk

or


negedge

rst_n

)

083

if


(

rst_n

==

1’b0

)

084         temp

=

1’b0

;

085

else

086         temp

=

in

;

087  
088

always


@(


posedge

sclk

or


negedge

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
097

always


@(


posedge

sclk

or


negedge

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
106

always


@(


posedge

sclk

or


negedge

rst_n

)

107

if


(

rst_n

==

1’b0

)

108

{


out

,

temp

}


=

2’b0

;

109

else

110

{


out

,

temp

}


=


{


temp

,

in

};

111  `endif
112 
113

endmodule

//————————

如果不先看我们综合与仿真的结果就能够把上面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