|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
verilog新手误区
. Z3 l* ?5 j- A
5 C7 j) z$ L% e) Q9 K# |Verilog的两个误区:. f: |6 P7 ?1 n3 R+ d; d5 F
使用Reg类型还是Net类型:
7 _4 ~$ i6 x, PReg类型只在过程块中被赋值;而Net类型则在过程块外面被赋值或者驱动.5 o1 n/ Q! {3 |* w% k' r
阻塞赋值和非阻塞赋值:$ U& y/ i2 |9 I( x8 x& C
Verilog中竞争发生的条件:两个或多个语句在执行顺序不同时导致不同的结果,则存在竞争.
. S$ g# B' B7 J6 N; z+ Z }Nonblocking不是一个类型;
6 X: ~6 l- V) |, c% |- W$ V/ nBlocking赋值是一个单步过程,计算RHS,并更形LHS是不可中断的.
0 [# i* E% V6 S2 j4 t0 o" [2 |' Q七条准则:: d( V1 V" J9 r) H$ L. {& {& l
1.时序逻辑和锁存器,使用非阻塞赋值$ N0 d. @# d3 q. ]; }: h3 W
2.always块中的组合逻辑,使用阻塞赋值9 N& a8 o$ M# E1 ^; ^( A. {
3.同一always块,时序组合混合逻辑使用非阻塞赋值7 r4 R0 d2 n4 n% U
4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值
4 {) o* C2 j" g) h5.不要在多个always块中对同一变量进行赋值% O# h, y! _% f# y" x
6.使用$strobe显示非阻塞赋值得信号( W. c' u z& ^, y0 Q0 v9 ^& W( D) Y
7.不要用#0的过程赋值" ]3 H. o( ^6 I- P/ M1 S
Verilog中的分层事件队列:; [6 |4 O9 H: P* U H5 [; N
活动事件:阻塞赋值;计算非阻塞赋值的RHS;连续赋值;$display命令;计算输入并改变原语的输出.这些事件可能按照任意次序调度." ]! ?; S% T. m: ~ M) H
非活动事件:#0的阻塞赋值, }& w8 `) J H8 F& {8 o
非阻塞事件:更新非阻塞赋值的LHS4 k6 }4 q0 ? U
监视事件monitor命令;$strobe命令$ h7 ^" P5 x6 W' T) M# E( f
经验:& Q+ H! o2 ]6 t. W2 |+ W/ F
在always块中使用非阻塞赋值来产生时序逻辑和锁存器9 P0 V1 f' a8 ^
在always块中使用阻塞赋值来产生组合逻辑3 `# c( l) G4 k" |; s/ P
在always块中使用非阻塞赋值来产生同一块中的时序和组合逻辑& X& n1 i2 h" `1 L
在纯组合逻辑中使用非阻塞赋值可能会导致功能错误7 j) y$ n, C% n/ N0 r w0 c4 B. ]/ a
阻塞赋值和非阻塞赋值混合使用的方式:& V. E& T, D# ]% ?
将组合逻辑赋值通过时序表达式表示
B0 J6 D' q! V* m W2 [( I* `或者将组合逻辑赋值与时序逻辑分开,在独立的语句块中描述
9 w1 n+ a: M2 V/ O; A) l" G* P不推荐在同一always块中混合使用阻塞和非阻塞赋值
# m9 E" l8 \+ y5 i, G几个关于非阻塞赋值的错误理解: d) W4 j9 W0 i9 \
错误1:无法使用$display命令显示非阻塞赋值变量/ U# o' A) e5 K
正解:非阻塞赋值变量的更新在所有$display命令之后
2 O# [' O' [* p4 e+ `错误2:#0让一个赋值在每个时间步的最后执行3 i/ z( p; f) U" O4 l9 c
正解:#0只会让赋值语句进入非活动事件队列
7 W( L4 \9 D1 m+ l错误3:在同一always块中对同一变量进行多次非阻塞赋值是不允许的- K/ ]; V1 n0 v
正解:在IEEE 1364 verilog标准中定义了上述赋值,最后一个非阻塞赋值起作用
( Y0 N# B8 j" f9 |模拟开始时候的困难:
) L: p( {8 n" x& v5 ?6 F+ Y8 F9 B, V$ u不同的模拟器,不同的模拟选项导致开始模拟时现象不同
1 ]4 t2 r4 v- L) U+ Z6 \# R建议: 在0时刻通过非阻塞赋值设置reset信号;; i" e y1 r& Z* `/ C! w
第一个半周期设置clock为0
! ?5 m9 _" `2 x$ d' H' D编写Verilog代码的一些经验:
4 S" Q& S }5 XVerilog文件名和模块名相同* b% s( @$ X, X. @, r9 L
不要在可综合代码中使用casex语句
2 F5 p2 p* M# P v6 j当在可综合代码中使用casez语句时要小心
# ]; Q( q# t, d当写case语句时,对存在不关心的cases时使用casez,使用?代替Z来表示不关心的cases* s4 [; U/ N; w5 a
Verilog编写状态机相关:9 N) R( _1 ^, B2 ]
状态机分类:Moore(输出只与当前状态相关)和Mealy(输出与当前状态和输入相关)4 V) Z0 ? P- i8 H( {8 Z
二进制编码和One-Hot编码& W, I( e5 @5 K7 L2 c
状态机的基本块:下一状态度组合逻辑;时钟同步的当前状态逻辑;输出组合逻辑$ e( Z; o5 c0 m# A* l+ e* R* U
两个always块写状态机,使用三个always块,如果输出需要寄存
3 d, E' w5 |* x4 `) D使用高效的One-Hot状态编码,组合输出
# {/ u* W/ N/ L+ ~# k. h5 g经验:6 l3 e h) p+ K1 [* L
每个状态机作为一个独立的Verilog模块
; v: I3 C+ g5 w5 w; G: {对状态进行预定义,状态赋值使用状态名作参数,不要使用`define,多使用parameter7 e m& R* _5 Q( {# Q9 l5 Z
两个always语句块的状态机,一个always用来描述状态向量寄存器的时序逻辑.一个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述." V. R: }' b4 x, H( P
Verilog的两个误区: n) p) l9 Z+ c) `/ z( C
使用Reg类型还是Net类型:
9 H8 W. O: E8 e. C$ T4 ^Reg类型只在过程块中被赋值;而Net类型则在过程块外面被赋值或者驱动.
1 q4 s$ n2 C! ~) [阻塞赋值和非阻塞赋值:! e# |2 |5 A+ `8 z6 J+ l
Verilog中竞争发生的条件:两个或多个语句在执行顺序不同时导致不同的结果,则存在竞争.' H! `( f& s& A8 c# S/ i i
Nonblocking不是一个类型;
& a' {- t3 R ^% Y- xBlocking赋值是一个单步过程,计算RHS,并更形LHS是不可中断的.
& M0 @6 H1 E% e# O0 F/ R' P* u七条准则:
0 X1 `1 u/ H( n) c0 p$ Q1.时序逻辑和锁存器,使用非阻塞赋值
# u0 \1 d f: `, u2.always块中的组合逻辑,使用阻塞赋值
7 }3 }( Y- t0 K- G7 h/ s3.同一always块,时序组合混合逻辑使用非阻塞赋值
- i0 V- j& `' b y6 U. {4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值6 f+ [9 b; A$ z& y% `! p
5.不要在多个always块中对同一变量进行赋值
0 n( r4 ~$ }$ ?6.使用$strobe显示非阻塞赋值得信号
+ h' i2 j- Z. k3 K7.不要用#0的过程赋值4 {0 M, _7 f* h* s1 m( m
Verilog中的分层事件队列:
$ J+ A( Z, ?3 ^$ C! [$ H5 l, t9 y5 R; Z3 h活动事件:阻塞赋值;计算非阻塞赋值的RHS;连续赋值;$display命令;计算输入并改变原语的输出.这些事件可能按照任意次序调度.5 h' G0 c9 S& C: X+ U
非活动事件:#0的阻塞赋值
, ?; F# v) a1 v3 C! M: Z非阻塞事件:更新非阻塞赋值的LHS
T2 b {3 F/ n l* o/ S4 K监视事件monitor命令;$strobe命令0 A% [2 Z) P5 H- r) J8 T0 y) |
经验:+ W: @0 n9 f/ m! r
在always块中使用非阻塞赋值来产生时序逻辑和锁存器) N3 c W8 x3 F2 p; i0 I; s
在always块中使用阻塞赋值来产生组合逻辑; \" n J+ Z/ g! a: W3 m3 @
在always块中使用非阻塞赋值来产生同一块中的时序和组合逻辑& `" \* c! l2 X
在纯组合逻辑中使用非阻塞赋值可能会导致功能错误
& y' w( x* f2 ^8 c阻塞赋值和非阻塞赋值混合使用的方式:! ]5 F8 D- G$ M
将组合逻辑赋值通过时序表达式表示 C8 b: t9 t+ z% z3 [4 i- M( K9 Y* g
或者将组合逻辑赋值与时序逻辑分开,在独立的语句块中描述
+ F& @9 n) @6 m) C; r& J- m不推荐在同一always块中混合使用阻塞和非阻塞赋值
+ x9 q" V: s, b& l) v- |2 a; Q8 I几个关于非阻塞赋值的错误理解:6 o$ r: U( Z) ?: |1 e e( T
错误1:无法使用$display命令显示非阻塞赋值变量: Y( o2 F+ D8 m ?3 h4 S
正解:非阻塞赋值变量的更新在所有$display命令之后; |, e! n" D$ D: L* a5 W' Y
错误2:#0让一个赋值在每个时间步的最后执行
* {0 E. E7 F: I" _( F正解:#0只会让赋值语句进入非活动事件队列0 s% E' m9 w" C9 I
错误3:在同一always块中对同一变量进行多次非阻塞赋值是不允许的3 ?* W4 h+ ]6 Z3 d2 E
正解:在IEEE 1364 verilog标准中定义了上述赋值,最后一个非阻塞赋值起作用: f* B* T6 K: c3 l( j6 Y
模拟开始时候的困难:
5 s" Z& n! R; X, u1 g不同的模拟器,不同的模拟选项导致开始模拟时现象不同' @3 b. H0 S" \
建议: 在0时刻通过非阻塞赋值设置reset信号;
. ?5 j. I* ~& X: N+ ~9 |第一个半周期设置clock为0
P8 e' R8 s& [7 Q. Z# j- {+ q编写Verilog代码的一些经验: Y# L8 S: ?6 Z7 q; u6 }6 E. c
Verilog文件名和模块名相同
) J* `) N/ [9 d0 |6 ]不要在可综合代码中使用casex语句0 |+ h" ?4 D: h4 v
当在可综合代码中使用casez语句时要小心
) B" ^8 g9 Y8 ]: q当写case语句时,对存在不关心的cases时使用casez,使用?代替Z来表示不关心的cases
# O3 C( z }( U% r' u) n! n4 f/ TVerilog编写状态机相关:
1 X% }8 i' `7 h3 ~0 ?) N0 S状态机分类:Moore(输出只与当前状态相关)和Mealy(输出与当前状态和输入相关)) W5 E- g4 R- Q8 t
二进制编码和One-Hot编码* ]: X2 z/ c6 {2 e: [' p% D
状态机的基本块:下一状态度组合逻辑;时钟同步的当前状态逻辑;输出组合逻辑
3 E2 ^! @) K0 O5 ?. k# ]6 ~两个always块写状态机,使用三个always块,如果输出需要寄存2 K" z( p4 L3 Z% M5 [
使用高效的One-Hot状态编码,组合输出
# h( a+ h8 Y. E+ A: G经验:
_& {! b. J% x( ^ Y5 h每个状态机作为一个独立的Verilog模块
% Z& G6 V. l9 N7 l8 D对状态进行预定义,状态赋值使用状态名作参数,不要使用`define,多使用parameter4 z% c" K1 L0 e) `" G
两个always语句块的状态机,一个always用来描述状态向量寄存器的时序逻辑.一个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述.
; y3 i9 m/ I: z( V& @0 o; B8 X1 I |
|