|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
verilog新手误区 0 j, v6 x8 {$ @0 a; a
2 Z# K8 M+ j" w# z% f3 O# C1 ?5 V
Verilog的两个误区:
8 ~$ f/ H9 i& k- b4 I; e" _# |# q8 T使用Reg类型还是Net类型:
- ?4 D; w; k# _1 D: L2 |* u: H1 AReg类型只在过程块中被赋值;而Net类型则在过程块外面被赋值或者驱动.5 P5 z) R7 S6 A& [4 c5 W9 `6 J
阻塞赋值和非阻塞赋值:
" o, U6 @4 L3 T5 @4 k" Q/ h$ ^' sVerilog中竞争发生的条件:两个或多个语句在执行顺序不同时导致不同的结果,则存在竞争.) G$ f) e' ]& N" n- \" o
Nonblocking不是一个类型;
* ~- X& I7 {( [1 I2 N# RBlocking赋值是一个单步过程,计算RHS,并更形LHS是不可中断的., g2 P6 A- u9 H' T% s7 y- }
七条准则:
) T" Z; ^; F3 m. p1.时序逻辑和锁存器,使用非阻塞赋值
( N; y4 ~) k. Z2 y5 K& N/ x2.always块中的组合逻辑,使用阻塞赋值! d5 p0 R3 z7 F: S1 a' u
3.同一always块,时序组合混合逻辑使用非阻塞赋值5 A6 j8 o5 [1 j8 z# ]
4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值! s. J( t/ Y: T( P& }* P9 s
5.不要在多个always块中对同一变量进行赋值( L! o/ }5 t' t- P) @/ a9 _' v
6.使用$strobe显示非阻塞赋值得信号3 _( K3 o* w5 ~, S: o7 U$ B
7.不要用#0的过程赋值
1 V" e5 ^7 W) c9 X* |Verilog中的分层事件队列:
0 d6 O H* p g; i* J2 ~; U活动事件:阻塞赋值;计算非阻塞赋值的RHS;连续赋值;$display命令;计算输入并改变原语的输出.这些事件可能按照任意次序调度.
+ N, F: e u+ G6 Q+ k非活动事件:#0的阻塞赋值( Q0 r5 E6 Y2 R/ C& Y; \) n
非阻塞事件:更新非阻塞赋值的LHS
8 v$ K8 i4 j/ ~# D& U' y- ]+ y: ^/ w. F监视事件monitor命令;$strobe命令. C5 k9 ?' G X/ |* U: o, l$ U6 O
经验:
/ T/ ?! o j/ }. ^% T1 f# w4 a9 f在always块中使用非阻塞赋值来产生时序逻辑和锁存器
- Z) i3 M8 }$ h& Q/ H" X0 E在always块中使用阻塞赋值来产生组合逻辑! F# @. i4 S8 D3 o2 O$ u' b
在always块中使用非阻塞赋值来产生同一块中的时序和组合逻辑
5 z5 T a6 [) ?6 x/ |5 A4 ^& T在纯组合逻辑中使用非阻塞赋值可能会导致功能错误
9 H# @, l* W( d4 R# W( z* I阻塞赋值和非阻塞赋值混合使用的方式:
5 O+ j( D1 Y/ J/ A9 C" y3 t将组合逻辑赋值通过时序表达式表示" z9 E2 m, M* s0 z0 J* k
或者将组合逻辑赋值与时序逻辑分开,在独立的语句块中描述1 m+ w) p* E& K! C( F I
不推荐在同一always块中混合使用阻塞和非阻塞赋值
, @! L0 [9 i& r! J( R7 |几个关于非阻塞赋值的错误理解:
: Z% @. r. ]; O+ n- ]# @/ ~+ k7 k' E错误1:无法使用$display命令显示非阻塞赋值变量5 {1 g' m# h* C% c
正解:非阻塞赋值变量的更新在所有$display命令之后
' j& Y. q$ D6 [错误2:#0让一个赋值在每个时间步的最后执行/ Q( I7 \7 l) S' i g
正解:#0只会让赋值语句进入非活动事件队列
7 `2 r2 {2 k8 _, _错误3:在同一always块中对同一变量进行多次非阻塞赋值是不允许的
( h2 u, P/ _" v! r6 I正解:在IEEE 1364 verilog标准中定义了上述赋值,最后一个非阻塞赋值起作用1 ^( \. O' j0 ]
模拟开始时候的困难:
$ ~0 ]* u1 s7 E7 h" w不同的模拟器,不同的模拟选项导致开始模拟时现象不同
2 w' L- O1 B0 e2 W3 p建议: 在0时刻通过非阻塞赋值设置reset信号;" \! F( N9 w) A+ O
第一个半周期设置clock为0
8 B/ a+ s- w; t, ~3 `% { }编写Verilog代码的一些经验:# w/ J' E( l4 t- _+ c2 A v* J; u
Verilog文件名和模块名相同: h' C! w2 g0 s/ l2 r( f( p
不要在可综合代码中使用casex语句" |) M5 ~. B7 k; m$ m5 `1 t+ H
当在可综合代码中使用casez语句时要小心
- P. v* W( @9 L: a当写case语句时,对存在不关心的cases时使用casez,使用?代替Z来表示不关心的cases
# v9 j3 X! ]: J1 S" i7 `# ZVerilog编写状态机相关:5 U% ` c, [* X) C* Z
状态机分类:Moore(输出只与当前状态相关)和Mealy(输出与当前状态和输入相关)2 X1 m6 k6 [5 \' t, V, @
二进制编码和One-Hot编码
; x- `. R- s* ^" I4 q状态机的基本块:下一状态度组合逻辑;时钟同步的当前状态逻辑;输出组合逻辑
6 L" Q4 T6 u) j* |- r9 b1 n$ y; z7 P两个always块写状态机,使用三个always块,如果输出需要寄存4 |9 W0 Q9 I* J, l" A, b
使用高效的One-Hot状态编码,组合输出4 f2 t5 [5 r9 x1 |
经验:
8 U# T- O( c" ~1 I1 y; P: W7 l每个状态机作为一个独立的Verilog模块
) z' D2 [& u% F2 U% O. r* W- ~对状态进行预定义,状态赋值使用状态名作参数,不要使用`define,多使用parameter8 W6 Y7 o+ X0 F# @3 d% \& K
两个always语句块的状态机,一个always用来描述状态向量寄存器的时序逻辑.一个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述., f4 N& D- B/ C8 p* H
Verilog的两个误区:
* ~9 u+ H9 d( l- l; |使用Reg类型还是Net类型:1 `; Y' Q9 n7 z. M7 w8 g4 ?9 Z
Reg类型只在过程块中被赋值;而Net类型则在过程块外面被赋值或者驱动." a% Y. y6 \2 R. ?# X) h: f2 X
阻塞赋值和非阻塞赋值:1 a4 o* F$ a! h
Verilog中竞争发生的条件:两个或多个语句在执行顺序不同时导致不同的结果,则存在竞争.
' G: S& \) L; o+ m+ t/ r4 U! N/ DNonblocking不是一个类型;5 s& j* D6 h; c6 U5 [- a8 f. z8 h
Blocking赋值是一个单步过程,计算RHS,并更形LHS是不可中断的.: |/ o) n. t ^8 p
七条准则:* N& i7 |3 X; M& y; N9 ^% u1 n: c
1.时序逻辑和锁存器,使用非阻塞赋值
8 V! r- I. @- ^2.always块中的组合逻辑,使用阻塞赋值
( p& ~5 @# t" t3.同一always块,时序组合混合逻辑使用非阻塞赋值
2 n5 R; P* r7 S1 @4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值( @9 [0 q* ^' O+ k' D5 Z- g6 A
5.不要在多个always块中对同一变量进行赋值% o: ?* P/ I' n1 K
6.使用$strobe显示非阻塞赋值得信号2 v w( y# f( h
7.不要用#0的过程赋值
. k, T& b/ W5 W' o) sVerilog中的分层事件队列:
+ d# q9 n* z% N/ l- J" s& W' P& b活动事件:阻塞赋值;计算非阻塞赋值的RHS;连续赋值;$display命令;计算输入并改变原语的输出.这些事件可能按照任意次序调度.
8 W. b- @2 G& n5 h3 _# G" a非活动事件:#0的阻塞赋值
) k3 L* p+ g( C4 P* h* d3 ^5 Z, X非阻塞事件:更新非阻塞赋值的LHS
1 e: _& K0 ^: s% \8 t& L监视事件monitor命令;$strobe命令2 V) L3 m; X7 S% f& F3 V" B! b
经验:, s# {' T" j0 x A
在always块中使用非阻塞赋值来产生时序逻辑和锁存器
0 D o8 k; ^# Y, u: | Q在always块中使用阻塞赋值来产生组合逻辑
5 X0 n5 k, d" ^( F* [2 o在always块中使用非阻塞赋值来产生同一块中的时序和组合逻辑5 d1 [8 t1 L/ a+ }
在纯组合逻辑中使用非阻塞赋值可能会导致功能错误
6 h0 V! E- m* I9 ~3 I' H8 t/ B& a. q1 D阻塞赋值和非阻塞赋值混合使用的方式:3 ]5 |8 Z9 [) t
将组合逻辑赋值通过时序表达式表示
: J, z6 v0 a* K' m0 a7 g u或者将组合逻辑赋值与时序逻辑分开,在独立的语句块中描述0 R% J7 D' W' T8 n+ ]& ?. n8 V
不推荐在同一always块中混合使用阻塞和非阻塞赋值
# h# U4 }+ N4 s$ U几个关于非阻塞赋值的错误理解:
$ M/ y6 a$ A; S0 u/ m% U9 E* M错误1:无法使用$display命令显示非阻塞赋值变量8 u8 `( |! d1 d# T2 @* e. t
正解:非阻塞赋值变量的更新在所有$display命令之后
# ?4 {# {5 q: Z5 ~" L+ a# x- g8 _错误2:#0让一个赋值在每个时间步的最后执行+ @& v( ~1 u8 q6 e1 n
正解:#0只会让赋值语句进入非活动事件队列
- v; o' [5 Q/ U1 @- \2 m. }7 K, [错误3:在同一always块中对同一变量进行多次非阻塞赋值是不允许的( c& B1 F: b& U0 o
正解:在IEEE 1364 verilog标准中定义了上述赋值,最后一个非阻塞赋值起作用
, p8 Y5 e% @* x* x( P8 C模拟开始时候的困难:
" O3 j1 ]0 E& j- s6 X' d; J不同的模拟器,不同的模拟选项导致开始模拟时现象不同
2 _: k8 u! D2 |3 M' v建议: 在0时刻通过非阻塞赋值设置reset信号;. J; ^1 [6 H6 H! W* h# z9 f* C9 V
第一个半周期设置clock为0& B3 u% l9 q+ |. o6 c9 g4 y
编写Verilog代码的一些经验:% _! z! p7 E/ e* W9 E0 \* k
Verilog文件名和模块名相同
8 A7 N) y: v- X% r' A" [! z. t& @' c) @不要在可综合代码中使用casex语句
* x: ^" ?# T+ d/ f; N当在可综合代码中使用casez语句时要小心
2 t9 K ^$ w3 Y; q y! J当写case语句时,对存在不关心的cases时使用casez,使用?代替Z来表示不关心的cases0 C( _/ t; S3 g" D
Verilog编写状态机相关:
+ }$ ~3 P2 t5 i1 h9 Z$ j3 \4 L* `; h状态机分类:Moore(输出只与当前状态相关)和Mealy(输出与当前状态和输入相关)
! O6 d7 }+ l6 N+ I) `二进制编码和One-Hot编码
3 M8 Q- _) { U! H- z! w8 @; U状态机的基本块:下一状态度组合逻辑;时钟同步的当前状态逻辑;输出组合逻辑$ R" o/ @! K+ Y# K, L+ s- p& B# [
两个always块写状态机,使用三个always块,如果输出需要寄存- y# }% H* z4 n$ f2 ^2 F
使用高效的One-Hot状态编码,组合输出
! ?/ s1 x" @4 n" T5 |* C( B% b' ]) h经验:
$ y9 o" v7 ~# O+ R0 |1 A每个状态机作为一个独立的Verilog模块* e, |4 F: Y, v$ t$ \4 Y3 B
对状态进行预定义,状态赋值使用状态名作参数,不要使用`define,多使用parameter) n- E. u% w9 p4 l6 n- Z. _
两个always语句块的状态机,一个always用来描述状态向量寄存器的时序逻辑.一个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述.7 @0 A7 d$ H: I3 Q, F. [6 j
|
|