|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
verilog新手误区 O1 H: x- L) c$ ^0 x) G
0 r* O4 F- O1 _9 \+ h) P: `
Verilog的两个误区:
0 \" v2 c. a, t0 e9 n. w8 a& G使用Reg类型还是Net类型:6 j( V0 |- w9 w% a0 A
Reg类型只在过程块中被赋值;而Net类型则在过程块外面被赋值或者驱动.
0 W/ k/ z5 t0 i阻塞赋值和非阻塞赋值:
5 `/ P s1 ?2 V5 q) hVerilog中竞争发生的条件:两个或多个语句在执行顺序不同时导致不同的结果,则存在竞争.8 ?, X/ ~! I6 G; M) b& c) g) E8 f( H
Nonblocking不是一个类型;
- W; Z4 d' _7 i- A3 ?( fBlocking赋值是一个单步过程,计算RHS,并更形LHS是不可中断的.1 r4 f9 v3 T2 N0 T
七条准则:
5 p$ y' J/ ^8 n+ ~/ D1.时序逻辑和锁存器,使用非阻塞赋值
0 I" U7 c, e( S( U2.always块中的组合逻辑,使用阻塞赋值8 G, q) \1 s- k% S& Y. }; a' P
3.同一always块,时序组合混合逻辑使用非阻塞赋值
( j9 C% j& ?! T4 c/ u9 k1 n4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值
5 x2 @5 z, P( s( I% [: k0 H9 y5.不要在多个always块中对同一变量进行赋值
3 [5 e# w' c1 t( ~& i6.使用$strobe显示非阻塞赋值得信号7 T, G7 h; ]& b
7.不要用#0的过程赋值 [6 z6 @. [( L* P
Verilog中的分层事件队列:9 ?' l6 u4 R; d3 W) R( N
活动事件:阻塞赋值;计算非阻塞赋值的RHS;连续赋值;$display命令;计算输入并改变原语的输出.这些事件可能按照任意次序调度.; p( B. p5 J; S+ M) n
非活动事件:#0的阻塞赋值3 E$ o. R" A4 \% B* _" B
非阻塞事件:更新非阻塞赋值的LHS: k# [: Z$ I. D) ]
监视事件monitor命令;$strobe命令
% v8 M' [9 e8 f+ c, V# I0 q, q经验:5 Q7 Z6 g0 {6 B; j/ w* \8 r, V
在always块中使用非阻塞赋值来产生时序逻辑和锁存器$ Q! `" C0 W+ N# I9 S' K
在always块中使用阻塞赋值来产生组合逻辑
! r8 N. y. G& e0 ?' _$ j# L( j9 z! O在always块中使用非阻塞赋值来产生同一块中的时序和组合逻辑" @; [8 O/ O& S6 Q( J- t0 |
在纯组合逻辑中使用非阻塞赋值可能会导致功能错误% Y2 N$ w( R( [
阻塞赋值和非阻塞赋值混合使用的方式:: m4 m4 z- K( x8 f- [
将组合逻辑赋值通过时序表达式表示4 d4 w% l$ l& D1 M$ k# U
或者将组合逻辑赋值与时序逻辑分开,在独立的语句块中描述+ x1 o3 b; A2 l7 ~/ F/ P$ F" [$ G
不推荐在同一always块中混合使用阻塞和非阻塞赋值9 ?, h$ C/ m4 X- R% R0 Y
几个关于非阻塞赋值的错误理解:
# m, ^. d" `: k" i错误1:无法使用$display命令显示非阻塞赋值变量
; Q' o% a! g' T6 v+ a( K6 e正解:非阻塞赋值变量的更新在所有$display命令之后
. c! u! P9 {, Q6 B2 n. q! {错误2:#0让一个赋值在每个时间步的最后执行
5 Y( d4 i" a$ s) V1 k正解:#0只会让赋值语句进入非活动事件队列
1 G2 |; f, d! p7 D+ g; y) B! H错误3:在同一always块中对同一变量进行多次非阻塞赋值是不允许的
& |+ _( x! D& H- w$ p' A! S正解:在IEEE 1364 verilog标准中定义了上述赋值,最后一个非阻塞赋值起作用
, V. s, j$ ~) V0 l/ i模拟开始时候的困难:+ M" @2 L5 U! j5 g: w
不同的模拟器,不同的模拟选项导致开始模拟时现象不同. C1 }1 e! h4 l' c3 J5 F
建议: 在0时刻通过非阻塞赋值设置reset信号;
8 C6 ~, g8 a( f% Y6 X第一个半周期设置clock为0 d7 Q1 Z4 i- q- e2 I+ v
编写Verilog代码的一些经验:5 |7 N% w& @, f2 {; T
Verilog文件名和模块名相同 r7 _& n, T; ~6 D- C
不要在可综合代码中使用casex语句5 `- l% d7 V7 o2 ?% |8 d+ ?4 G
当在可综合代码中使用casez语句时要小心
( ~3 `. Z. g; c8 V$ l7 D当写case语句时,对存在不关心的cases时使用casez,使用?代替Z来表示不关心的cases
' D# C& @8 Y+ l1 [Verilog编写状态机相关:4 _3 T, D2 O! `0 u2 k
状态机分类:Moore(输出只与当前状态相关)和Mealy(输出与当前状态和输入相关)* \- s+ ]# ]" H) f3 y
二进制编码和One-Hot编码
# G% W/ d% ]0 ^9 b3 @状态机的基本块:下一状态度组合逻辑;时钟同步的当前状态逻辑;输出组合逻辑
! o# K5 \, ]# n+ m3 {( I2 _. e% ?两个always块写状态机,使用三个always块,如果输出需要寄存8 [/ F) G3 M7 I/ C5 n% ~
使用高效的One-Hot状态编码,组合输出
, y/ [. e3 M! ]经验:
/ o8 N2 c3 j- q" _' i每个状态机作为一个独立的Verilog模块
! h, r/ o% J) ?+ Z; p& Q对状态进行预定义,状态赋值使用状态名作参数,不要使用`define,多使用parameter1 U% l5 D" [+ C( M: }1 s" O5 L
两个always语句块的状态机,一个always用来描述状态向量寄存器的时序逻辑.一个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述.
/ ]3 k2 _+ A5 @6 S2 y3 P! `Verilog的两个误区:$ b+ `( {" M' |
使用Reg类型还是Net类型:7 j3 r/ T, T, k( ~/ u" f
Reg类型只在过程块中被赋值;而Net类型则在过程块外面被赋值或者驱动.8 C# f [; e- t+ V! v
阻塞赋值和非阻塞赋值: I/ H3 `$ x f
Verilog中竞争发生的条件:两个或多个语句在执行顺序不同时导致不同的结果,则存在竞争.# P5 ^& c$ c% N! J$ L! H5 P% [1 u
Nonblocking不是一个类型;- s0 s$ A- m, ?2 {' a
Blocking赋值是一个单步过程,计算RHS,并更形LHS是不可中断的.( n8 I7 O$ s0 P
七条准则:
, v, F! a, A5 ^# A' |+ u# n: U) b1.时序逻辑和锁存器,使用非阻塞赋值
9 V+ d) b! G8 D2 Y; g l2 G; ]0 ]2.always块中的组合逻辑,使用阻塞赋值
" { R& p6 \* e' \+ z; V5 b3.同一always块,时序组合混合逻辑使用非阻塞赋值4 p1 S% O1 L* e% y/ |3 G; v
4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值
4 }5 W. D- [" J$ M4 d' v5.不要在多个always块中对同一变量进行赋值5 s. K! ?4 `; g4 {/ B/ K
6.使用$strobe显示非阻塞赋值得信号
3 C' N V- q" i( ~- j6 h! t( }7.不要用#0的过程赋值
* w0 Z( Z7 l$ C0 k/ r) SVerilog中的分层事件队列:2 J+ g% C; X7 P
活动事件:阻塞赋值;计算非阻塞赋值的RHS;连续赋值;$display命令;计算输入并改变原语的输出.这些事件可能按照任意次序调度.) Q% u; A: M: E: U
非活动事件:#0的阻塞赋值2 ^; u( C1 \; ^1 G `: Y$ r( v, a
非阻塞事件:更新非阻塞赋值的LHS" }1 n8 s' V. Q$ L0 s$ I4 h1 h
监视事件monitor命令;$strobe命令0 \ |6 o2 M) j) `+ |3 g2 a
经验:
" `2 r3 \! e4 U; D7 w/ s0 [, [在always块中使用非阻塞赋值来产生时序逻辑和锁存器& n C# p4 V5 c1 w
在always块中使用阻塞赋值来产生组合逻辑( c8 y, v' t G0 W3 Z+ k) {3 L
在always块中使用非阻塞赋值来产生同一块中的时序和组合逻辑
; d3 ~/ \6 `+ o! ?在纯组合逻辑中使用非阻塞赋值可能会导致功能错误& \# D5 |4 z, ^- O
阻塞赋值和非阻塞赋值混合使用的方式:
8 V A+ b& a9 e }9 _1 H4 j将组合逻辑赋值通过时序表达式表示& ^4 p7 R- W; E+ S! {7 F' D) m8 O0 V' ?
或者将组合逻辑赋值与时序逻辑分开,在独立的语句块中描述. h- ^% n. I9 |
不推荐在同一always块中混合使用阻塞和非阻塞赋值/ y9 x7 _" D8 C' V1 {' s" h6 D
几个关于非阻塞赋值的错误理解:4 _" \0 U E' s$ U6 V/ E3 C+ q
错误1:无法使用$display命令显示非阻塞赋值变量
# y3 g4 _6 g H3 l0 w* q! `正解:非阻塞赋值变量的更新在所有$display命令之后
% W7 n5 B0 E# }错误2:#0让一个赋值在每个时间步的最后执行
+ Z+ `' @( n. s; y正解:#0只会让赋值语句进入非活动事件队列! Z- Q. V+ f( [! q8 _
错误3:在同一always块中对同一变量进行多次非阻塞赋值是不允许的
0 k# o/ @6 T3 N4 ]. U, f8 {1 U正解:在IEEE 1364 verilog标准中定义了上述赋值,最后一个非阻塞赋值起作用
2 }" u: ]' C. [4 |# U模拟开始时候的困难:- l$ J8 ^9 x- B; p- V9 K
不同的模拟器,不同的模拟选项导致开始模拟时现象不同* ?+ _3 s8 O ^4 y7 Z2 k
建议: 在0时刻通过非阻塞赋值设置reset信号;
]! \' y$ p2 w; K第一个半周期设置clock为0
5 ~ d2 a# m0 N( f; ~' B编写Verilog代码的一些经验:, c2 J, p& N) _, Q
Verilog文件名和模块名相同
9 C" X; q) y8 s不要在可综合代码中使用casex语句
8 x( Q! ^9 t- u: ]& L当在可综合代码中使用casez语句时要小心
& ~% [- P& A/ Y9 T |当写case语句时,对存在不关心的cases时使用casez,使用?代替Z来表示不关心的cases
! X/ p4 G7 o' @Verilog编写状态机相关:2 X+ ^# ?- p; ^1 ~! Q0 C
状态机分类:Moore(输出只与当前状态相关)和Mealy(输出与当前状态和输入相关)" S' r( B( `/ e( R
二进制编码和One-Hot编码% J$ l* J: L1 X" ]! N: l. T3 \
状态机的基本块:下一状态度组合逻辑;时钟同步的当前状态逻辑;输出组合逻辑
& Z3 ~8 g. ?; R+ ^5 }两个always块写状态机,使用三个always块,如果输出需要寄存6 w- v& N1 c& x$ W- b
使用高效的One-Hot状态编码,组合输出
2 y. Q5 B N- G" v6 }/ l9 H. d$ t4 E% p经验:- U, _/ X/ b& V- w5 x9 Y m" ?) W
每个状态机作为一个独立的Verilog模块( X: g+ |, C6 z2 e$ _
对状态进行预定义,状态赋值使用状态名作参数,不要使用`define,多使用parameter
2 x' E) ^) s% N# I两个always语句块的状态机,一个always用来描述状态向量寄存器的时序逻辑.一个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述.5 T/ U4 O2 V. N$ V% R
|
|