TA的每日心情 | 开心 2019-11-19 15:19 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于Verilog的奇数偶数小数分频器设计一:背景
, C. @+ D5 l8 \8 k' ~
0 f, E/ ?$ e. V5 e7 O' Y 关于光纤通道时钟同步模块的设计。里面需要用到一个10M的时钟,而我的PCIe时钟为125M,所以需要一个12.5分频的分频器。小编偷懒从网上搜了一个,代码简洁,行为仿真也没问题,直接就用上了。昨天组长调用我的设计,发现综合出现了问题,一查代码,把我批了一通,还暂时取消了我带小弟的资格,原因就出在这分频器上。- u" V5 b" r" H/ p# S$ X$ A
, Q. g2 v- W/ z8 Z# q7 c# ^二:问题代码分析
/ C" t/ j8 s: y: a/ I0 ]' B* \. m! s1 R. B- R+ i/ h' x
复制代码
! n! Q% |9 v( V- s2 M8 c1 module divf #& `$ [6 y [1 s6 `( g0 z% }/ c. D
2 ( parameter N = 12 , // 分频数7 K- g, l3 w* r7 B5 m i2 }
3 parameter state=1 //奇偶分频为0,半分频为18 c) m6 w; t3 w6 n
4 )
, C$ u$ V! n5 B1 e5 (
0 t- L7 F1 c% u J/ r1 v- T6 input clr, 2 S! W4 j) V+ R7 m
7 input clk, * z% o! v3 _' J6 ~" ?, w" g
8 output clkout
7 z' m# P' \. P: F% d9 );1 t R! ]! {7 V( z7 |! ^ p6 ^2 u# A
10 1 ?4 S9 a& |! C! b
11 reg [5:0] M;
; }/ n- s2 J# P$ f' }' d. L0 _) O12 reg [24:0] count;
: C* X! a- G9 d5 g* i; u3 i4 ]13
% w2 y/ S. A! z# W1 k1 W; x% J14 always@(posedge clk or negedge clk)
8 I* j8 A$ i$ R% M" g" u% g+ c15 begin Q' P7 F C" _/ i! z- l$ |0 @" l6 l
16 case(state)
; Z% Q! [# Q+ U* A+ |2 \( H17 0:begin
9 f, ?& b- M" y/ w, k0 i18 if(!clr) count<=2*N-1;
' Z9 ^: v% [4 {) W' P19 else if(count==2*N-1)3 q3 E3 \( k3 I6 F* a/ u1 z8 P- c
20 begin
& }' b5 d2 I0 x6 N( L* q ?21 count<=0;' b5 s: ~* B4 p: S
22 M<=2; //只on一个clk
( g! e2 `# p4 W23 end
+ E0 J1 y2 K) m24 else count<=count+1;9 H8 m* w2 Z/ Z3 B; \0 X; Y
25 end3 }6 j1 R J0 v+ L: S1 @5 ?: O7 b, h
26 : B0 {% k/ k3 s/ C
27 1:begin1 b' a+ s' [+ P
28 if(!clr) count<=2*N;/ j; {! c* h& @' R c6 S4 k
29 else if(count==2*N)
8 E1 U$ F" `' Y30 begin 5 Q; t1 J3 n2 W; ~$ p
31 count<=0;$ K$ l) j- n5 x
32 M<=N+1;
N9 g! S6 J4 Q2 K6 L& B33 end1 S& }5 o' J& o9 G T0 v2 h% l# R! @
34 else count<=count+1;3 S% g* y+ f ~% r3 i" H' }
35 end " F4 K7 m" p' Y6 e/ Q* w
36
0 V0 t, Z6 T, {/ n. E% m/ ]4 z37 default:;: z. ?% {' r- T8 Z; \
38 endcase9 \5 b: H H: ^
39 end
: s" z& x5 d' @40 3 @; @* `) {6 w# q9 l( e
41 assign clkout=(count<M)?1:0; y7 t- ]/ M& C' ]6 r3 z
42 # z2 {' X& Q$ r
43 endmodule
' J+ l7 Q: n9 ^1 T$ [) a复制代码0 k1 g' X0 X) T/ U& D8 M
看到这样的代码,像我一样的菜鸟见了都会怦然心动,但仔细分析,问题就出来了。
9 G3 C& i/ o: Q" n
s; O9 r8 \" w) n }# V① always@(posedge clk or negedge clk)3 S, N7 I6 k, z* j! ]) D
9 M' u2 _/ E( x( {* b" _; t! x; [
触发器(FF)一般是上升沿触发,我做过实验,即使想要下降沿触发,布局布线后也会有一个反相器反相后用上升沿去触发。若同时使用上升沿和下降沿触发,例如always@(posedge clk or negedge clk),布局布线后等效于always@(posedge clk)。所以上面这种写法,若不是采用特定器件如ODDR,是很难完成上下时钟沿都采数据的(应该还有别的方法,请大牛不吝赐教)。所以如果用在高速时钟上,建议不要采用这种写法。: p- M3 k2 _8 K* m7 F/ H
8 D# _) {: h7 [' q" z7 E$ W
② assign clkout=(count<M)?1:0;
7 p, j- ]/ x) s9 [1 D+ D6 R/ z( |6 a4 n/ V
组合逻辑输出问题,如果时钟频率较高,100M以上,组合逻辑的延时很有可能超过时钟的建立时间,会产生毛刺,所以我们一般都要求寄存器打一拍输出。上面这个例子中,clkout=(count<M)?1:0; 比较器是个延时比较多的器件,所以对时钟要求高的情况下不能使用。( n7 C6 {: T0 H7 ^7 G! b4 x
, w3 O; \# [4 X/ [
; h7 W g$ W, q$ p7 f% W F; D s' V4 k" E3 F0 m
三:解决方案+ ]+ T* I" k8 G8 Y, J9 I
( s& f1 K4 M* E8 i0 S
① 使用两个always块,但两个always块不能对同一变量进行操作。
% t: M) r2 F* T2 m* A( W
% L: k; b: C+ x. r7 ^" @Always@(posedge clk) begin … end
4 F5 P& Y- ]% b# E. z- }" ~8 d" S4 d
Always@(negedge clk) begin … end
9 S( z2 k+ ]: w8 u4 N5 V( C* `5 M9 N
或者使用锁相环产生两个频率相同,相位差180度的clk,然后在每个上升沿输出
( w0 _: C8 @/ p' l0 m: t3 q& C J b5 l- S: V9 D) ?) H& D; ^+ S
Always@(posedge clk1) begin … end( ^1 i4 l7 D- w1 v, b- H' _
( D1 _ K0 h& i5 j6 s- ZAlways@(negedge clk2) begin … end
" I3 h# `2 P! R- w0 i0 ]) o: U X3 P) |8 u# ?! ?/ e/ e3 c
② 针对组合逻辑输出问题,能避免使用则避免使用,如果非要使用,也只能使用足够简单的组合逻辑,比如与或非逻辑。
4 \. r4 B1 H, a" K9 c+ y! F" P
R J5 Q4 E, d0 f+ I* S8 r" }$ _6 B& e7 C( L5 y4 v: q7 a" X
7 L* v7 c' |* w" r
四:代码示例+ i7 o0 `- a* r9 B5 Y) s
' ?4 O% P* ^* P7 X8 b
说明:用一个大case分三类讨论,看上去很挫,实际是为了裁剪方便。
V/ E" M p1 i& F+ t& C. G8 V+ j y: f3 y/ \# _/ B& e
代码功能:完成奇数分频和偶数分频,占空比50%。完成n+0.5分频,占空比无要求。
/ k' ]2 {8 G7 q! r0 H/ s: L# m9 ?; w, V0 S- x$ h7 [- t3 K
复制代码+ ?( _7 \, l; C
1 module divf #3 p" F+ h: M' r6 u Y: H8 Z# O/ a
2 ( parameter Div_num = 12 , // 分频数
( U# Q' s$ \& }8 o9 H/ f3 parameter state=0 //半分频为0,奇数分频为1,偶数分频为2
6 f" r( Z" m& j& O4 ) 8 n. n8 J1 j/ Z& i, v, g
5 (+ v, H# n" p# L& x) l; q! A" d0 z" ]
6 input clr, % X: ]" V0 t8 v* Y: X7 M# V! F
7 input clk,
/ u! D5 Y' F) O6 Q' W @8 output Div_clk
9 c2 X9 `5 V+ s& p9 );
. X+ |1 I. W- R* x& v/ k10 reg [24:0] count; j! x' d) ?; O' q; h7 H, [
11 T. r0 i$ B/ E; y9 ~
12 case(state)6 L% c W" g- r' ~2 U/ k( P
13 1: begin //ji_shu' H7 o, H: r c a" s2 a5 G7 a
14 reg pos_clk;: u$ S2 ^ a" P2 r( q
15 reg neg_clk;
9 r9 x+ l( V& Y/ @16 4 [4 p# N+ g$ f0 R6 v
17 always@(posedge clk or negedge clr)
! z! `2 }) y3 @! c) N! a/ B18 if(!clr) count<=0;
9 n. {: J e" I0 v19 else if(count==0 & pos_clk) count<=Div_num/2-1;
3 o0 ^% L& @. | o. |20 else if(count==0) count<=Div_num/2;
& y+ ?. s9 H* Z+ y21 else count<=count-1;2 z4 M& {) {" d2 z
22 8 L; c# S& D, J# |* e+ J! f
23 always@(posedge clk or negedge clr)$ l9 |0 w7 n" y+ D- x
24 if(!clr) pos_clk<=0;
2 K& |) O8 M3 z' v25 else if(count==0) pos_clk<=~pos_clk;
/ I: P' o" _( ^( D" }26 else pos_clk<=pos_clk;
) d) k7 {3 Y5 r27 3 Z2 e2 t3 i7 i G
28 always@(negedge clk or negedge clr)
9 ~2 G7 ]$ U1 h8 s( F& G29 if(!clr) neg_clk<=0;
: }5 \6 b+ _1 V0 ^) H4 k) K30 else neg_clk<=pos_clk;( T1 V: j" x6 @6 D$ w! M T
31
( C+ S+ j. K5 D. |& J& ^32 assign Div_clk = pos_clk & neg_clk; : N3 e$ j1 A" Q8 {5 F4 k- _
33 end
. T6 {8 j% Z6 }5 `( A7 S34
/ A, J' G, P6 v0 R7 A35 2: begin //ou_shu
& V/ c4 [5 d1 I |5 @( S4 [; e0 R36 reg Div_clk1;
9 E0 x" }+ E9 a( `( L37
$ d1 R$ W& h; D5 F0 `38 always@(posedge clk or negedge clr) 4 J8 V/ @+ d% `5 _4 B* k
39 if(!clr) count<=0;
# m& z2 |: S! C' v$ s: w- p! Q40 else if(count==0) count<=Div_num/2-1;
- ^" m, F; [1 F8 R1 X1 J9 y; E41 else count<=count-1;
; a; v" \9 d$ m1 D L# y42 / @9 N" d$ f* N1 t( W3 N4 f
43 always@(posedge clk or negedge clr)
; `+ X' [8 n' E7 i+ |44 if(!clr) Div_clk1<=0;
: W8 e- r, t6 \45 else if(count==0) Div_clk1<=~Div_clk1; ; ?7 c, E$ I, ]
46
$ f- q2 q/ j, V8 V+ m- l' F% L" O& ?47 assign Div_clk = Div_clk1;
& L2 K. b7 O$ Y7 Q9 x48 end
7 Y, P9 ?" w! E# B0 H1 U. v* d49 6 Y+ C+ U+ ]; O+ z! Y, q0 a
50
. @9 S5 Y* @ R: ]. c9 |4 F# S51 0: begin //ban_fen_pin& E8 V/ q$ d5 n- R* {& A" T4 ^" i
52 reg count_div;
' V* g# } w, v' k9 @3 C l/ |53 reg count_div2; - d! d0 W5 o5 e7 p' o) C! L* s8 Z
54 wire clk_half;. X! G! Z% f* @6 v
55 * X& p' a9 q1 R: W
56 assign clk_half = clk^count_div2;, q: ^4 t4 {# g
57 always@(posedge clk_half or negedge clr) //模Div_num 计数 , i* e+ m; B9 B6 Y# P2 C7 L) _9 j# g
58 if(!clr) count<=0;
6 z# y# _0 J6 v; d% c% n59 else if(count== Div_num-1) count<=0; 1 f3 T' `# z6 I! J* i
60 else count<=count+1; - g- ?) z4 \8 b
61 % j+ o, t( c, }* |: p: K. X/ _% b
62 always@(posedge clk_half or negedge clr) //模Div_num 计数
3 E7 j' A1 v& f5 g63 if(!clr) count_div<=0;
, _/ D* s$ S5 |7 Z: Q64 else if(count== Div_num-1) count_div<=1;
n% B! B: a# O& y65 else count_div<=0;
|! C" Q$ D$ ^5 R2 J66 7 \% r V! b) q5 i
67 always@(posedge count_div or negedge clr) //对count_div二分频
4 m% b( S$ _( W' s( B68 if(!clr) count_div2<=0;
# A) }0 B3 ^; A$ D% e: M) z6 p69 else count_div2<=~count_div2;
5 R$ i+ s5 `9 o2 F3 {" Z5 d70
0 F# V7 \" |% r6 B71 assign Div_clk = count_div;' f. C2 m2 Z% O2 V
72 end7 e( O4 ?8 K7 h
73 endcase
: Q' d6 @4 ]) v5 O4 f4 Y0 L& A74 9 ]2 @$ U5 i7 ?; N# t
75 endmodule3 A6 t) n# e; J( [4 z# i- A
复制代码7 ~# U7 P6 N7 n: n
五:仿真代码及结果3 \0 p/ E3 ]2 f4 \1 r2 l
3 H& B: z l2 \' Q复制代码0 z5 U9 C2 e' }; W- ~
1 module test_divf;
k: Y9 [- w2 t2 b7 B2 reg clk;1 A4 V4 q$ {% {" _0 S) {1 W
3 reg clr;' y! [# k0 ?6 Q$ r3 O! j
4 wire Div_clk;8 y3 X9 t0 a! c I3 u
5 / P- U+ v* j' E
6 always #1 clk=~clk;1 D$ z( o {( D* I0 _
7 1 Z4 C2 Q0 A m
8 initial- _4 M3 ?0 E1 f- l; ]3 ^2 }
9 begin
1 Z2 U2 {0 a2 b( q$ U) J10 #0 clr=0;clk=1;- I, p! W+ y( G/ [% E) M; \
11 #99 clr=1;3 R- N+ _# ?$ ]; D
12 //#1000 $stop;
4 K/ L' I- H( I& ]: I! C13 end
% k8 a5 Q. L7 [6 c14 & s) a- j% F. P! b }
15 divf #
6 t' f" {8 H# o, ?3 V3 ?16 (
- w" S7 ^" y2 K- `" y" g17 .Div_num ( 5 ),
3 i L+ u6 X( ]! Y1 Z18 .state ( 1 )3 Y' X. E5 G* o
19 )divf(
5 l1 l8 D9 m2 H% i20 .clr ( clr ),
& {7 S# q7 t0 T6 D; l21 .clk ( clk ),
O" h7 K8 J* }, W$ X c22 .Div_clk ( Div_clk )
& W5 l( i6 I- T4 e) M* d! D9 U23 );
1 c8 U1 M* A9 X24
% E% P7 L, I4 Y( w1 @( `25 endmodule | / Y: A* I p% _4 D9 b
4 q' \& H4 z" X: D6 S; V
% C, _# _% G- U0 Y' P3 q3 z- s
7 N- j# N3 x6 z2 o5 Z# @' A
" @6 m* o0 H6 D8 A9 c0 ]2 E& E5 G6 s5 M3 f: N3 e
|
) \* {0 I, p4 U- X" F* R# ? | 0 E! p" b F: K5 _: }
- Q' i2 L3 O0 |4 L$ S) F# p! [
+ X7 K! f3 b3 N |
|