TA的每日心情 | 开心 2019-11-19 15:19 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
7 e8 g& I( y) d2 V4 g网友经验分享: Verilog设计注意 3 g+ _2 B! @% M' p
组合逻辑
) n) d3 H, X' B" X1.敏感变量的描述完备性
( h* A, s. w- o& A$ aVerilog中,用always块设计组合逻辑电路时,在赋值表达式右端参与赋值的所有信号都必须在always @(敏感电平列表)中列出,always中if语句的判断表达式必须在敏感电平列表中列出。如果在赋值表达式右端引用了敏感电平列表中没有列出的信号,在综合时将会为没有列出的信号隐含地产生一个透明锁存器。这是因为该信号的变化不会立刻引起所赋值的变化,而必须等到敏感电平列表中的某一个信号变化时,它的作用才表现出来,即相当于存在一个透明锁存器,把该信号的变化暂存起来,待敏感电平列表中的某一个信号变化时再起作用,纯组合逻辑电路不可能作到这一点。综合器会发出警告。
- N: }8 k0 R' L; @ V
+ L6 a. X8 L$ o, ?Example1:. i. j9 R8 u8 F. L m: P
input a,b,c;3 R3 W! j$ z2 w- Q) ~; d8 N$ w
reg e,d;
8 ^+ U8 A& @8 x7 ^+ H9 M: ~always @(a or b or c)
9 X0 b* A$ @; H$ |: p begin
! b: U" l. d2 G6 ^& e `: l$ j e=d&a&b; /*d没有在敏感电平列表中,d变化时e不会立刻变化,直到a,b,c中某一个变9 l, K E3 k6 x# ^9 U: o
化*/' {$ y. ~; m+ {% A
d=e |c;; w- k% f, f- a1 `1 s
end
9 g1 p6 P7 G: n : l) F+ q/ k$ N U9 f
Example2:
5 g2 j) ^" E, z) t1 Z0 jinput a,b,c;4 J, a0 ^2 |: {) ^6 `
reg e,d;
- ^ N4 ~ p) M. I& \always @(a or b or c or d). s. I' [3 _' U( ^- C4 E3 E+ g
begin1 C/ F: u. l, s1 b% H" p6 v! T
e=d&a&b; /*d在敏感电平列表中,d变化时e立刻变化*/
1 [5 S: r1 S' r2 v d=e |c;
4 {, d" `& k4 b" d- R) y end
+ n$ g) E9 [+ W n2.条件的描述完备性; P4 {9 V3 F- g C
如果if语句和case语句的条件描述不完备,也会造成不必要的锁存器。
& s) q: z2 k" _% X1 N4 C/ J7 k. a% ?# Y4 j
Example1: , i/ j. f) y' x4 e! x9 f4 a
if (a==1'b1) q=1'b1;//如果a==1'b0,q=? q将保持原值不变,生成锁存器!# p/ O& r8 X. k1 o7 F3 j- C' }
Example2: 4 g4 ?( {2 M6 H8 u( r
if (a==1'b1) q=1'b1;
1 ~0 j5 @$ i6 Y, `else q=1'b0;//q有明确的值。不会生成锁存器!
) M8 i! h5 a4 Z" Y5 s- m: L2 J& m* Z6 N( P. s3 H: O- }9 H8 S/ R
Example3:' f) D. |; ^! L6 H7 L
reg[1:0] a,q;* h$ Y* E# K1 ~$ r
....0 G( v( [% x3 w I- q9 g
case (a)3 \9 Z3 c6 H) B6 z9 n! f6 \
2'b00 : q=2'b00;
$ h9 L( y V% M8 `: K( a+ P 2'b01 : q=2'b11;//如果a==2'b10或a==2'b11,q=? q将保持原值不变,锁存器!4 n6 \4 Z' ]9 t" N
endcase) `( p* Q: t% r
3 J! }( \6 f- d& r, r
Example4:
& r9 ~5 n( B# k7 Y' t% f! p# i reg[1:0] a,q;2 X1 i! v" a, w- f _
....
% T* x* L! v5 N4 X7 ] case (a)
2 H E3 v8 X- P( C, ~# E# D; l 2'b00 : q=2'b00;6 W2 F) s* g* n1 d! J
2'b01 : q=2'b11;
1 v# |/ N1 E. Z$ @ default: q=2'b00;//q有明确的值。不会生成锁存器!
, x: K/ ^! H! E endcase
: B, `& B/ z# [+ u9 A- q+ Y' u8 h. C
3 z4 I; H/ V; r8 KVerilog中端口的描述
/ a1 x' G0 r9 _ J7 Z1.端口的位宽最好定义在I/O说明中,不要放在数据类型定义中;
1 v' B3 {" K1 XExample1: 0 u' t; A/ ^9 d2 o
module test(addr,read,write,datain,dataout)+ I' h' B" J7 F/ w; _: [
input[7:0] datain;, `- Z" \, K s& I. L
input[15:0] addr;; a3 \0 ^) V3 Q- C9 b
input read,write;* w) r8 P9 i$ g4 D5 r& d
output[7:0] dataout; //要这样定义端口的位宽!, Y" H* c' ~ {2 v) c' t, U5 b
( z. l" X; o; B0 U' Wwire addr,read,write,datain;& n7 T. V2 X% ], J S, q
reg dataout;
( y; U" C! s& w N! z; p" ~. Y% j+ x4 Q& X
Example2:
2 H+ b3 {- B, T9 T/ [4 ]module test(addr,read,write,datain,dataout)
: c9 l3 d2 P" ninput datain,addr,read,write;8 `- N) s) V0 e' _; c
output dataout;8 u: ^" ^5 E @9 j
1 m' u! m; N" J9 u3 o; f" F: Bwire[15:0] addr;4 w+ v* Z% m) ^- d& m8 D4 s: R, m6 x
wire[7:0] datain;
3 d% M* r, `6 C+ s8 e) Fwire read,write;
( X& k' _3 g6 U _4 w& `1 n3 Ureg[7:0] dataout; // 不要这样定义端口的位宽!!
, }: A5 V6 e2 |9 f- Y' i/ `7 P- X7 _2.端口的I/O与数据类型的关系:
. g# D2 B8 p" j2 Z 端口的I/O 端 口 的 数 据 类 型
9 F$ q0 w! l3 t+ [. E4 `4 l, G6 W module内部 module外部
# s: g( Z# r4 |6 C* J+ N1 | input wire wire或reg
3 H) @9 m" Y2 v" S6 l. C output wire或reg wire
" I& M/ q% A5 o$ S1 j9 x. N/ l& j inout wire wire
& \+ o5 [" E" C! J+ H+ X3.assign语句的左端变量必须是wire;直接用"="给变量赋值时左端变量必须是reg!
2 e# a: v9 o/ C9 i2 I2 \- q _$ c
3 M' a% w/ W) l# D6 DExample:
. N" ]) v$ M5 Bassign a=b; //a必须被定义为wire!!3 _# q$ w0 Y# m% b$ U
********
2 _& }" O2 K# O3 Gbegin
4 @$ y) Q( e" B) V) G1 C a=b; //a必须被定义为reg! g! ?! E& b2 e5 w9 `# z1 h: O
end
* e8 I- e' j7 X* ]! @ a. p6 \+ q, f% R6 c
VHDL中STD_LOGIC_VECTOR 和 INTEGER 的区别例如 A 是INTEGER型,范围从0到255;B是STD_LOGIC_VECTOR,定义为8位。A累加到255时,再加1就一直保持255不变,不会自动反转到0,除非令其为0;而B累加到255时,再加1就会自动反转到0。所以在使用时要特别注意!, j& z: B% e$ _
1.无置位/清零的时序逻辑. U- t7 {" ]/ z) v% y* z
always @( posedge CLK)
1 D7 X. z* i8 k6 T3 E/ G1 c begin
9 V" o! o+ R4 }8 l Q<=D;* k1 n% W1 k0 E) |4 ~) a3 m
end% _; e; t0 A% k! O- s# A
2.有异步置位/清零的时序逻辑 ; g5 F8 o) r5 E! _, s; D
异步置位/清零是与时钟无关的,当异步置位/清零信号到来时,触发器的输出立即/ L+ _- z! ^" a0 T- A0 B! v
被置为1或0,不需要等到时钟沿到来才置位/清零。所以,必须要把置位/清零信号
; k1 v6 Z/ V6 {( c2 H+ e0 P 列入always块的事件控制表达式。$ ?. ?+ `5 v& i5 n! ~- m3 [' |
always @( posedge CLK or negedge RESET)
2 h( X' b9 J/ z: o+ _5 W4 ]* T. y begin. N. Y F) |. Y
if (!RESET)
2 B1 c' k, }0 Q9 S* m5 N* p Q=0;
( J8 I6 {0 c6 ^2 u( t ]( A6 j else6 D& A* w) \% M, t4 Z
Q<=D;
& Y$ \1 L. [2 h- G! v end , m+ Y0 |3 f; b) {' D+ t
3.同步置位/清零的时序逻辑
1 ~6 I* E5 Q3 }; K5 F" r 同步置位/清零是指只有在时钟的有效跳变时刻置位/清零,才能使触发器的输出分/ S+ {6 Z0 K# b/ S6 E
别转换为1或0。所以,不要把置位/清零信号列入always块的事件控制表达式。但是; {: n2 |; D1 ~5 @8 G
必须在always块中首先检查置位/清零信号的电平。
$ K# i6 [* s N5 O; ?# b- M always @( posedge CLK )
- `: \0 W7 u6 {: q$ F: k, h- [ begin
6 H' u- `; y! S' m: d if (!RESET)) f$ n) S/ y9 m( [, R" G& p3 _% a
Q=0;
4 u1 q. U E2 @3 [ else
+ U. K: B6 i3 x7 ?8 e" U- s Q<=D;# ?$ C2 m5 g/ w( C1 N" z1 _# M' [
end
7 u$ q: u. b7 f5 l ! r* s6 F5 f( Z3 g
结构规范性
' g3 m. Z: |( O- C1 l 在整个芯片设计项目中,行为设计和结构设计的编码是最重要的一个步骤。2 c* y# {- I. @+ }$ R7 o" E
它对逻辑综合和布线结果、时序测定、校验能力、测试能力甚至产品支持都有重要的影响。考虑到仿真器和真实的逻辑电路之间的差异,为了有效的进行仿真测试:
! a# v- K' B5 P$ [+ }, A1.避免使用内部生成的时钟. }- B3 i* ]4 q' Y2 {: f
内部生成的时钟称为门生时钟(gated clock)。如果外部输入时钟和门生时钟同1 N1 }) B+ J# N; z+ a
时驱动,则不可避免的两者的步调不一致,造成逻辑混乱。而且,门生时钟将会增加测试的$ t- H5 p; y0 c$ o2 m. @- u, E
难度和时间。
+ Q9 E% I7 R6 L9 {- f5 e2.绝对避免使用内部生成的异步置位/清零信号
! U9 K. h; S# J; k1 b( X) [ 内部生成的置位/清零信号会引起测试问题。使某些输出信号被置位或清零,无法正常测试。
* H/ j1 k* H5 X9 {0 H/ B7 g3.避免使用锁存器: W2 M0 ?* R4 T/ A% ]& b
锁存器可能引起测试问题。对于测试向量自动生成(ATPG),为了使扫描进行,锁存器需要置为透明模式(transparent mode),反过来,测试锁存器需要构造特定的向量,这可非同一般。
9 ~% r/ @+ U! f4 f# ~* G8 K4.时序过程要有明确的复位值
) |- Q3 |$ M' M 使触发器带有复位端,在制造测试、ATPG以及模拟初始化时,可以对整个电路进行快速复位。- K/ T k4 O# @7 d; _) |
5.避免模块内的三态/双向1 U6 \0 e: y4 I, S& ^, O$ ?
内部三态信号在制造测试和逻辑综合过程中难于处理.
" @- b9 e$ a( E% _+ n. u0 M4 d! p |
|