找回密码
 注册
关于网站域名变更的通知
查看: 238|回复: 1
打印 上一主题 下一主题

网友经验分享: Verilog设计注意

[复制链接]
  • TA的每日心情
    开心
    2019-11-19 15:19
  • 签到天数: 1 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
    发表于 2018-11-2 10:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

    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
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-7-23 02:46 , Processed in 0.109375 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表