TA的每日心情 | 开心 2019-11-19 15:19 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于Verilog的奇数偶数小数分频器设计一:背景/ r% K& E8 s0 a0 f6 q
+ o4 R3 o* F( D8 R, Y/ K
关于光纤通道时钟同步模块的设计。里面需要用到一个10M的时钟,而我的PCIe时钟为125M,所以需要一个12.5分频的分频器。小编偷懒从网上搜了一个,代码简洁,行为仿真也没问题,直接就用上了。昨天组长调用我的设计,发现综合出现了问题,一查代码,把我批了一通,还暂时取消了我带小弟的资格,原因就出在这分频器上。
) D6 i; P1 U+ I( D0 b" \. I& l& t1 ?2 H/ n( m X
二:问题代码分析
/ ^8 P% d0 p8 e6 e, E: L. h* e0 u( z0 |* i- D, d
复制代码, f3 Q, f) k& h9 P# s: d6 y" T
1 module divf #, q4 g& F, n6 ]: N
2 ( parameter N = 12 , // 分频数6 E- J6 x' f( w# K6 I3 S
3 parameter state=1 //奇偶分频为0,半分频为1- y A4 v6 A+ Z( M7 m& f2 F" Z
4 )
: Z+ |7 j; C; ]5 n$ K5 (
2 C" L& H9 i5 T4 p$ p Y8 {6 input clr,
* z. f9 [/ U) M. D' G7 input clk, # w; P' N& _/ L0 r1 H2 `- d
8 output clkout4 T H# z* j) s
9 );% K [( j$ ~( [9 Q* V C+ q
10 ; K; g: ^7 [# T' C2 L4 x( C4 h5 B4 i
11 reg [5:0] M;
; o9 r( X/ X- u% _9 i% [. G12 reg [24:0] count;0 t% ^8 Z1 X! l
13
" x/ B2 g3 B1 m14 always@(posedge clk or negedge clk)8 y3 G3 r1 W8 v- L( t" B, |1 h6 E
15 begin/ W& O3 \; j. o! ~; b2 Q2 d3 g* P E
16 case(state)" h5 L, ~+ A* H( o
17 0:begin! }" \* L4 y" B0 m0 B
18 if(!clr) count<=2*N-1;
( M5 c. g$ D( H# d, z4 s19 else if(count==2*N-1)$ P! k# @0 a$ u% g7 g5 P7 Q
20 begin
4 U/ k$ P, ^8 D: Y. s" K& ?21 count<=0;. ~4 E J z# u# a5 m Q) W) H5 w
22 M<=2; //只on一个clk
- i5 r3 P: E+ `$ ]$ G) e/ l& C" }23 end
" @0 S( J) I1 T, P" I24 else count<=count+1;
5 Q0 [. L6 p4 b+ p$ I25 end% {# J, [! t [6 x
26
+ a8 ^" a0 S* r; ]1 U6 H1 g4 V* M27 1:begin; Z% l& j4 _ ~2 J% y
28 if(!clr) count<=2*N;" Y% h7 ?" r2 p: Q& {
29 else if(count==2*N)
& `# k' h* E" a30 begin
) ?3 a/ C7 Q) J31 count<=0;
- }) o7 L5 N9 Y# {32 M<=N+1;$ ?1 d! O* z- |
33 end' x' q$ c! f/ R9 N+ ^! }
34 else count<=count+1;
5 T9 [3 ] ^4 V6 n35 end
/ F" E% Q8 r! c& G% z6 }36
1 z0 ]+ C Q' @5 c37 default:;
/ m% g4 a2 h) Q: `$ |7 F& h38 endcase
. S t0 }9 P4 F% d+ R, t39 end3 M4 G8 v$ G* ^+ a" Z6 m$ g0 z
40 , c, ^7 e# V% X! D! X- O j2 O) w
41 assign clkout=(count<M)?1:0;6 i7 X' _) [6 A7 f
42
8 m0 d: ]. [* V( C/ w43 endmodule6 ^$ y5 m6 K) c' L2 A
复制代码
. E5 g! n& L5 j3 |看到这样的代码,像我一样的菜鸟见了都会怦然心动,但仔细分析,问题就出来了。/ ?! ^5 [% A7 R' `4 F& z& j: |' H4 _
% R; M, `) N) P, T! n% O
① always@(posedge clk or negedge clk)' T$ k1 t4 `, b4 O
$ f* L1 o) p' H! [: J) a1 w
触发器(FF)一般是上升沿触发,我做过实验,即使想要下降沿触发,布局布线后也会有一个反相器反相后用上升沿去触发。若同时使用上升沿和下降沿触发,例如always@(posedge clk or negedge clk),布局布线后等效于always@(posedge clk)。所以上面这种写法,若不是采用特定器件如ODDR,是很难完成上下时钟沿都采数据的(应该还有别的方法,请大牛不吝赐教)。所以如果用在高速时钟上,建议不要采用这种写法。, K* u9 r( u& l& F v F, g( O: ^
# `* Y9 w1 ^/ Y$ l: ?5 x② assign clkout=(count<M)?1:0;1 i H7 i9 L1 H) G4 V
* T/ J! [6 v1 H- U5 J% o7 V 组合逻辑输出问题,如果时钟频率较高,100M以上,组合逻辑的延时很有可能超过时钟的建立时间,会产生毛刺,所以我们一般都要求寄存器打一拍输出。上面这个例子中,clkout=(count<M)?1:0; 比较器是个延时比较多的器件,所以对时钟要求高的情况下不能使用。
! Y6 H0 b* L; I+ C/ b+ @2 I: E5 S. v# b$ ~
" E! Z: h/ h9 P# d- a
; G- V5 R% t; D) L三:解决方案2 v( @. s+ G" `; S4 ?
1 O+ E, u' T! W7 l9 F4 g① 使用两个always块,但两个always块不能对同一变量进行操作。
( P' @% @( V. v' k
7 X7 r! Y) Q1 f1 U; T6 Y% O; \ cAlways@(posedge clk) begin … end
$ \2 S- N7 o( T( m; Y! C$ N. I5 S( y% | p
Always@(negedge clk) begin … end
1 b1 E- ?4 ]9 M% I2 I! @, l! g# d
或者使用锁相环产生两个频率相同,相位差180度的clk,然后在每个上升沿输出
% P/ A x" Q7 X; ~/ k h
$ x# S; l2 ^; S- n: |Always@(posedge clk1) begin … end
! g" r8 w' J" q2 D. i6 T, s4 _
$ ^) o9 g8 c, pAlways@(negedge clk2) begin … end& V0 G2 J+ ^; i, Z! t' f
/ ~7 J, L% g- b0 N0 Z+ D$ S8 y② 针对组合逻辑输出问题,能避免使用则避免使用,如果非要使用,也只能使用足够简单的组合逻辑,比如与或非逻辑。
" U+ V- [$ d) ]. A2 [
$ K a8 `3 q+ X3 W& [3 w o- o4 w u7 H: C
! I1 d( N6 I8 E1 f; T% b四:代码示例# M' b$ R5 n9 i0 S+ J5 ?
6 t) x e$ r! o; d! M说明:用一个大case分三类讨论,看上去很挫,实际是为了裁剪方便。5 R4 E( ^2 z7 F% [* K
! G8 x' l/ X, B E
代码功能:完成奇数分频和偶数分频,占空比50%。完成n+0.5分频,占空比无要求。7 Q* g" R5 A& {! O6 H9 D. l; B
+ Y$ ^' H0 ~. ?' U! N, D$ X复制代码
* A) F @* }6 m, Y1 module divf #
" s. E1 c/ U' {' z0 L' J2 ( parameter Div_num = 12 , // 分频数
4 l+ z! k6 ]# `/ M) ]& v; E3 parameter state=0 //半分频为0,奇数分频为1,偶数分频为2
# L! d" M" o( v) g; w4 )
& b8 u5 C. z* a: w: z5 (
g) [2 T. k, q x+ t+ }6 input clr, 0 Y$ X+ @. a' q* E' t% p3 ~) B
7 input clk,
! h$ N R8 _4 {4 x0 q5 l% M' q8 output Div_clk& _( C7 L B1 ~+ h6 V" R/ ^* ]. l- e
9 );
; K O. F; a O1 P! F10 reg [24:0] count;5 i/ h7 G$ W. C! k0 ]
11
/ F' T; Z* q7 f) W j5 \6 R9 W0 x3 d12 case(state)
5 A$ Z4 m. a! k5 r13 1: begin //ji_shu" [9 W" ?' f: a0 w6 ?
14 reg pos_clk;
: I6 ]8 B1 A V9 r% b15 reg neg_clk;, A' Q, Z2 |9 X8 u
16
1 X7 |6 j) L s17 always@(posedge clk or negedge clr)# u8 a3 b. v! T: B: h: H: d
18 if(!clr) count<=0;9 N( @* B, ?, \# z, S
19 else if(count==0 & pos_clk) count<=Div_num/2-1;% ?( n$ ]- Q9 p7 h: `1 Z/ Q
20 else if(count==0) count<=Div_num/2;& J* l# x- `) s% e' l; o8 s
21 else count<=count-1;
3 G+ c$ a9 Z4 X' e2 c7 o1 c, S$ t22 3 j% L7 J) S2 s. _5 p3 Z
23 always@(posedge clk or negedge clr)
0 @) U9 g, \' j# X' W! b4 D; m24 if(!clr) pos_clk<=0;! w5 t- M! d; J! |
25 else if(count==0) pos_clk<=~pos_clk;
" K- U5 \ H) @0 j26 else pos_clk<=pos_clk;; M P+ S6 U; H2 F4 C+ ]! [ x
27
2 f+ ?- V6 ^( M1 N, e/ b" V/ z/ D28 always@(negedge clk or negedge clr)
0 h# a1 k$ F' b( A( a" N29 if(!clr) neg_clk<=0;
7 h d5 u B. i9 C) |% E30 else neg_clk<=pos_clk;0 z( X% L9 L: ^8 G
31
" i/ c2 b+ }* y* A( N& g# y32 assign Div_clk = pos_clk & neg_clk; 1 Q( F& J) ^, }8 i/ z. z
33 end
) Z& ?, x3 d( {8 v34 O( z, {( j$ g2 a. |% l
35 2: begin //ou_shu
5 i4 R% H+ M1 \* s7 g6 e) d/ h36 reg Div_clk1; ( k( |7 j8 ~9 [* E5 k: G( C8 s
37
8 _7 J1 q X4 }38 always@(posedge clk or negedge clr)
) d; I3 g! y: ?% Z# Y: t/ Y39 if(!clr) count<=0; ) M, z }& U$ o9 R
40 else if(count==0) count<=Div_num/2-1; - Q( V' \5 W' d% V, k6 M
41 else count<=count-1;
O5 t- j c9 \5 s# O; g+ m4 ]42
O5 |: C3 W3 F5 L- L! ?- h" [43 always@(posedge clk or negedge clr)
; A4 c5 f; Q& b44 if(!clr) Div_clk1<=0;
7 h( P: p, }, z5 @: J6 [! i/ {* K45 else if(count==0) Div_clk1<=~Div_clk1; 7 A& R3 ] s8 `/ b( _" H
46 - _( H1 {$ c' \
47 assign Div_clk = Div_clk1; , o W/ }& }8 p: K u
48 end
1 t$ w5 ^0 i: L$ j& P# q, Z; b49 2 v1 ] g7 }8 ~# I9 w' R z
50
! ^2 H3 z& {8 t" ]0 X0 [( H" V51 0: begin //ban_fen_pin9 _' @* r/ g B; A
52 reg count_div; k+ Z+ ?$ i" h2 m' o
53 reg count_div2;
/ Z, ~0 j8 {0 `0 p54 wire clk_half;9 w4 [9 c2 m2 ~# U- U0 V8 h
55
5 e! m7 a& Y. l) _7 J4 u6 O56 assign clk_half = clk^count_div2;: ~- d0 G: @ I" V4 D$ c
57 always@(posedge clk_half or negedge clr) //模Div_num 计数
0 y7 S I' g/ S, w58 if(!clr) count<=0;
/ z4 Q Z( j l0 G1 A59 else if(count== Div_num-1) count<=0; & B1 _4 G3 F1 X; t9 y/ A) j
60 else count<=count+1;
/ ]) L. k1 t: {5 j61 & L" b: C& i* H/ v9 w+ `' w% ]3 K
62 always@(posedge clk_half or negedge clr) //模Div_num 计数
' {% x2 B; C9 H63 if(!clr) count_div<=0;
* u' ^8 R6 {; A# u64 else if(count== Div_num-1) count_div<=1;
' x( i4 ? p# `; }2 I" ^/ g' W) @65 else count_div<=0;
) I3 r* A/ H1 u5 x1 g- l6 j: G66 , t1 Z+ Z3 j2 q- ]
67 always@(posedge count_div or negedge clr) //对count_div二分频
, {! ]7 L# \3 [/ l2 s68 if(!clr) count_div2<=0;
4 N1 ^$ e1 n3 m9 V9 M69 else count_div2<=~count_div2;
% \! M7 \; P+ a* d L/ h70
. y" U4 u& W& B) x71 assign Div_clk = count_div;
& B* i+ m' A: |' H1 l# z7 h72 end9 x6 W2 n' ^2 m" p
73 endcase 6 J7 V6 }( g# k$ f# o( C; E
74
; p% G1 F9 l# v$ k# s75 endmodule, p% _- Q* i( z5 W% I& D4 G
复制代码! o2 t; a0 J; R1 K. l) q# M$ \
五:仿真代码及结果
+ H5 ]) I0 g) e# c6 |
K1 z* }+ Q# M. _6 y复制代码, o3 B& `+ P' S4 r
1 module test_divf;
" ?$ L% W) ] _5 U6 I8 k0 [' B2 reg clk;
& \" E( v* k$ J1 y1 Q z* a3 reg clr;
6 W" V# m1 c8 C+ x5 W4 wire Div_clk;* i- h5 G2 v) U; [6 o3 R
5 + Q" |0 Y' K; z) _) t$ ^: U) b
6 always #1 clk=~clk;( A9 A! ^. `0 S7 s4 f1 {' M
7
1 _+ l: B! J6 ^, P q x, ?# \8 initial$ L' {* T, B; F9 N- r5 G& G
9 begin
; v! [# y7 s3 d4 h) k" p10 #0 clr=0;clk=1;
3 a# X4 T8 r2 ^* ~% H11 #99 clr=1;
, j+ A" K4 ]! b# M1 o12 //#1000 $stop;; z4 ~# P" r! W& R' ~
13 end
* @$ R b9 i6 \14 1 w! J' g( E; Z) P0 l0 }, Z5 o
15 divf #
; T' ^+ s* i! v3 U+ j' M$ D- M16 (* r1 ^, s% `4 w" Q6 y, q# w$ a! F
17 .Div_num ( 5 ),
& d+ |, L1 r6 e18 .state ( 1 )' T7 t( q" c" y3 ?# e/ x/ G
19 )divf(
6 q. O( z. i: N- i+ I/ Y$ x" a: t: j20 .clr ( clr ),
7 e s" ^4 m) Z5 w( p' {) p21 .clk ( clk ),
6 x0 i& e8 M/ U7 G- J& r3 p) y22 .Div_clk ( Div_clk )
/ F! r1 V4 _! ~# i23 ); v- t. X4 J" {
24
0 e5 y9 a+ |' e6 w* T. _ f3 G25 endmodule | 0 b1 r9 }2 I0 c! P
! M& K1 B: a, P( c% v
4 ?1 U6 x1 i! r5 N
# @6 T( I& m4 h2 M* u/ w
6 l- T/ E2 L0 w5 v0 p3 M; g
" q% r1 | G& W: b6 W8 e7 R | o/ y6 ?& h% }' X! _0 I
| 3 t/ E* Z' U$ j4 V6 h$ P5 Y3 r
- z' k5 z6 G( k- ?+ H5 z9 S: A
4 o7 ]5 P: Z# S! y* p% D
|
|