TA的每日心情 | 开心 2019-11-19 15:19 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于Verilog的奇数偶数小数分频器设计一:背景
7 Z- v- u7 y; ~. e6 O) x n
( w: f& h3 p/ ^* J 关于光纤通道时钟同步模块的设计。里面需要用到一个10M的时钟,而我的PCIe时钟为125M,所以需要一个12.5分频的分频器。小编偷懒从网上搜了一个,代码简洁,行为仿真也没问题,直接就用上了。昨天组长调用我的设计,发现综合出现了问题,一查代码,把我批了一通,还暂时取消了我带小弟的资格,原因就出在这分频器上。
/ n2 Q0 P- j! E( U" k* ^0 f$ f
6 F5 {, }9 [3 c8 I7 y二:问题代码分析6 I; l+ L1 `0 m. G$ z, W K
# O9 @, `" x/ t; X3 ~+ S复制代码
6 s' C9 N" {) @' {8 P* l1 module divf #
9 u. m" T$ ^0 }2 ( parameter N = 12 , // 分频数& d5 o# a& n; y) w
3 parameter state=1 //奇偶分频为0,半分频为1& `( E/ A4 b3 M L4 e
4 )
! y2 Q" ?0 j7 |% M/ [5 (
& Q; H& @3 g: H7 s6 input clr, + ~8 z1 ^5 a# K! i* F
7 input clk, 4 h. n% h, E# k7 _- P0 |
8 output clkout
2 a1 s& S, w% H9 );9 E: b& @- B- @, l
10
' F; r& }0 Z; S1 ~0 G8 s) F- J+ S11 reg [5:0] M;7 S) R8 u V5 m4 }* ]. [
12 reg [24:0] count;6 e4 s% Z. t5 K* A
13
+ j8 H7 C1 x8 S; S3 q14 always@(posedge clk or negedge clk)8 J; a ~& S1 { M. ~
15 begin" t1 t- g+ a8 Q
16 case(state)
8 H3 U1 @6 C$ b. [% u17 0:begin
, h+ g$ a9 N; m" t, [18 if(!clr) count<=2*N-1; f# |6 }$ ^& J) l+ k3 S8 D) b9 h
19 else if(count==2*N-1)3 ]; Z. d6 H+ O+ s
20 begin * z3 Z% |& W0 Y7 P
21 count<=0;1 u7 k9 `; t# H0 ]: `: S5 l* Z
22 M<=2; //只on一个clk/ \' D( A8 @0 V" `9 E
23 end2 z8 E6 q- k4 n* q) _8 x) d
24 else count<=count+1;
4 q5 g. a' P/ w/ [25 end
$ Y/ e7 A# a, b! [8 ?* j8 e* `/ `26
% _( L* o5 e7 Q; `9 K9 }. E27 1:begin: `9 R H: f8 T. E) T; I" v1 Z
28 if(!clr) count<=2*N;
9 j9 c& G5 K/ E# O: W4 q29 else if(count==2*N)
3 @! \ L8 |8 F' D! r* p: D30 begin , @/ e4 E, ^) S5 B
31 count<=0;) ~; K. T5 f8 d" v
32 M<=N+1;3 H$ p7 J: D7 w0 I# [* @: z
33 end
1 L7 W) O5 M; g+ u. N# I34 else count<=count+1;
8 y1 R6 J$ F5 h2 o7 D; m35 end I- b2 _% J& p* L' H1 ^# [
36
! w# t5 X9 V: m2 {8 a. ?4 N; u4 b37 default:;4 h& `( U, Z! ~( ^ I' S
38 endcase- Q( w5 v! i/ e& u2 f% S: x
39 end, Z) ^+ Y; J7 D7 X( ?8 q" f5 j
40
! a9 C+ Z% v2 O' ?, _41 assign clkout=(count<M)?1:0;' f H2 g' u( l: s, A6 Q, M+ @
42 7 t( o j. a+ ]1 a$ W4 T2 e
43 endmodule
4 T, k! l; L& q0 w' f- b复制代码
1 ~. `7 ]! @ k& C看到这样的代码,像我一样的菜鸟见了都会怦然心动,但仔细分析,问题就出来了。
/ r3 I% J, m3 w) ]' S( ^+ Q* C) q. r
& [# H2 I4 U2 d T4 ?" K: i① always@(posedge clk or negedge clk)4 `$ Z: s) j+ G
) n) t; d& e0 U# n z+ E+ q6 U' H* M
触发器(FF)一般是上升沿触发,我做过实验,即使想要下降沿触发,布局布线后也会有一个反相器反相后用上升沿去触发。若同时使用上升沿和下降沿触发,例如always@(posedge clk or negedge clk),布局布线后等效于always@(posedge clk)。所以上面这种写法,若不是采用特定器件如ODDR,是很难完成上下时钟沿都采数据的(应该还有别的方法,请大牛不吝赐教)。所以如果用在高速时钟上,建议不要采用这种写法。+ T9 G) D8 r# I+ ~# K
" J1 I ~4 f- C$ U9 v. p$ q② assign clkout=(count<M)?1:0;
1 K- }1 S! {$ q& n* W
0 J0 v) i, n: T3 [2 d1 F* c7 j- c 组合逻辑输出问题,如果时钟频率较高,100M以上,组合逻辑的延时很有可能超过时钟的建立时间,会产生毛刺,所以我们一般都要求寄存器打一拍输出。上面这个例子中,clkout=(count<M)?1:0; 比较器是个延时比较多的器件,所以对时钟要求高的情况下不能使用。
+ x& Z& G& _! r x; T" L, ~0 a6 P/ z' Q8 X: `3 @
/ W( Q& I& y+ W$ J" r; F# r! _6 w$ ~2 [
三:解决方案
* ?1 z3 c/ N9 a) b; V/ B
6 o1 i* ?% N/ [; Z1 s$ F$ |① 使用两个always块,但两个always块不能对同一变量进行操作。
9 S5 t$ G4 e# a6 H8 [; Q6 h& C E- B. J$ v2 Q ]; d
Always@(posedge clk) begin … end% \8 i+ R) z5 n- l5 o1 I
! {# q& O$ v' ]- xAlways@(negedge clk) begin … end
' I( t4 e* Q2 u- S6 z c' B3 r" d( E& w9 k# X5 S
或者使用锁相环产生两个频率相同,相位差180度的clk,然后在每个上升沿输出
3 b4 A* B/ }- `8 C
8 A- u& `1 E+ SAlways@(posedge clk1) begin … end, L* U, w' c! Z( U! T
' T" }; B% R2 C* Z$ J* P4 i
Always@(negedge clk2) begin … end
! j/ D/ h P; ?2 Y. e2 x: a
, x$ j' N# _+ ~( s* ?% D② 针对组合逻辑输出问题,能避免使用则避免使用,如果非要使用,也只能使用足够简单的组合逻辑,比如与或非逻辑。
; P! \/ r/ `) t2 W
/ j/ `+ y/ ? G8 [$ r {, |6 u+ h% c! t) u) v: L: I
2 v, Y$ x! f( ]+ w% W+ `四:代码示例0 b7 D% `( G, C( R
& u8 x' P7 w4 v
说明:用一个大case分三类讨论,看上去很挫,实际是为了裁剪方便。
/ b, C. n. Y; o$ }. j: S0 q P1 n! o0 Q) j9 [8 k, [% B
代码功能:完成奇数分频和偶数分频,占空比50%。完成n+0.5分频,占空比无要求。) h7 ]. c6 w N3 c1 y, R7 ?; Q# {3 F
; g- O. o7 p$ ^# Y9 L; C) j" t1 {+ ?复制代码
5 A* R- c) {! q# C2 E% V1 module divf #/ F9 `" z5 j. i4 ~8 J' c
2 ( parameter Div_num = 12 , // 分频数( b7 {) Z: }! M$ G' i
3 parameter state=0 //半分频为0,奇数分频为1,偶数分频为2% R! Q2 _+ Q" X! m8 A p J
4 )
& p- x( R6 Q, s7 e N5 (% w* m# N: b: z( _7 z
6 input clr,
3 k* U8 j8 J. U! r0 y7 input clk, ; m4 @/ K9 E) F9 X4 m7 b
8 output Div_clk; ]0 x H- D1 @3 X
9 );
( A$ @# W' }% Z9 g10 reg [24:0] count;
3 i, {) [9 s2 l3 p6 ?# C7 t" I& z5 }9 W11
( y/ |: \2 S8 w( t3 B+ h12 case(state)
7 I+ Z$ Y9 w0 f) ^; K$ J9 Y13 1: begin //ji_shu
* J) b) s" z ?# j% C7 E M; l14 reg pos_clk;
2 ^& f0 B$ h4 h1 ~" }$ Z( Y: y' M15 reg neg_clk;
8 Y+ u; t F0 W% O4 j/ W% q16
' {- n# v& P( Z, Z- `1 }4 }. ?8 Y17 always@(posedge clk or negedge clr)3 Q4 X' f0 d; R) D3 B* s& y1 z) A
18 if(!clr) count<=0;
; H0 B7 g, H1 k7 x19 else if(count==0 & pos_clk) count<=Div_num/2-1;( L& P) L0 U. Q8 y% H
20 else if(count==0) count<=Div_num/2;
0 A2 R; F4 Y; {. S* e8 B21 else count<=count-1;
1 d+ M1 ~6 D5 i* R/ K4 F& ^22 $ w9 W! U" R. b0 `# ]5 L: W
23 always@(posedge clk or negedge clr)
" @+ k7 o# _9 T0 J1 Q24 if(!clr) pos_clk<=0;
3 I3 a2 O0 e4 T7 W# R8 G! _6 H25 else if(count==0) pos_clk<=~pos_clk;, f* t& {1 P) e2 W& o9 g: ?
26 else pos_clk<=pos_clk;
+ s$ g. h, l5 a6 u6 A X27
4 k" h& [0 P/ P9 d+ b, X# C* Y28 always@(negedge clk or negedge clr)
: F) P+ V8 ~, f+ O7 B29 if(!clr) neg_clk<=0;
7 T7 ]/ d/ r3 Z, t6 e4 f3 d30 else neg_clk<=pos_clk;; ]$ d8 F5 N4 ^* D, t8 Q" E! X
31 2 i* V& j. j+ @8 [
32 assign Div_clk = pos_clk & neg_clk; " d7 ]# D+ R# B
33 end5 Z9 f$ y K) X3 _3 {+ O0 S7 O
34 + {1 h* s: t9 x% L0 s
35 2: begin //ou_shu7 m8 w3 U- ^/ D8 S
36 reg Div_clk1; * W2 K' F O: x `: Q3 G1 l
37
' o( e6 `3 f- O& b3 N& m38 always@(posedge clk or negedge clr)
" M. g1 |% U; }) Y$ Q, b# s39 if(!clr) count<=0;
9 z6 R1 j2 u( ~( W; Q6 p40 else if(count==0) count<=Div_num/2-1; $ L$ ]& k' I6 v+ p' }1 v( a; \
41 else count<=count-1;
" C5 b; \$ I$ D" Y$ \0 w42
% i1 ?; V3 |4 O; R0 `; `7 ~' L43 always@(posedge clk or negedge clr) , }1 s) b* o: A
44 if(!clr) Div_clk1<=0; 0 F# W+ v0 g% m& j$ r
45 else if(count==0) Div_clk1<=~Div_clk1;
; W5 A1 ~/ I p" U9 S46 . C, Q8 u J6 ~" R ~3 Z) r' G
47 assign Div_clk = Div_clk1; + X! H7 d2 `' e2 ~
48 end
- W5 G7 e4 \! v1 F$ e" r49
4 M/ W, i% w, ?2 H% d, N2 e C2 ~50 / A& T! g. h6 x" m6 M( N
51 0: begin //ban_fen_pin N" m; E5 Q6 w5 J/ Y! i7 A; D
52 reg count_div;. X0 I: V+ N1 a( E5 a, F
53 reg count_div2; , e- l4 W+ }+ M
54 wire clk_half;
% c3 Y0 P2 ^7 u2 }3 S# ?7 R55
; L: T: h' N* [/ c" O6 C+ p56 assign clk_half = clk^count_div2;& k/ y% L- H1 k
57 always@(posedge clk_half or negedge clr) //模Div_num 计数
4 [. e/ ~3 p/ n: H% @( y+ x58 if(!clr) count<=0;
% ~- k' R" I8 Z* k* b: Q; Y6 A7 o/ \59 else if(count== Div_num-1) count<=0;
3 m. Y L6 O' y60 else count<=count+1; 1 K. B( S8 `9 [ x b' x- H4 q3 i
61 ! h8 |7 m5 i+ a1 r$ G% j7 | S2 B, Y
62 always@(posedge clk_half or negedge clr) //模Div_num 计数 " {; _% Z& g4 n" ]6 H& X
63 if(!clr) count_div<=0; $ l, z; D, s# Y1 w. G! u
64 else if(count== Div_num-1) count_div<=1;
: b( H2 ]- @3 c4 P65 else count_div<=0;
4 y% V* @9 @% D66
: c% e. }1 G2 \: A67 always@(posedge count_div or negedge clr) //对count_div二分频 $ h: c8 {7 I D4 ^
68 if(!clr) count_div2<=0; : W7 k8 e1 V; M" B9 u
69 else count_div2<=~count_div2;
& m/ N2 q G& n1 {' q70 . ?' N' m2 k( N; @; V
71 assign Div_clk = count_div;
9 t ?' t) w) v* s/ y" ?" Y( q% `72 end
7 y/ f! X- V" d' g3 ]* B2 ^4 X73 endcase " r$ {' z+ V; }. Y8 }' s6 s
74 1 ]* z* Q& V9 P$ ^1 T
75 endmodule! Y: D! k8 k6 P/ N8 _' k }, s
复制代码/ x, r; k( \: i$ _7 `/ V* {
五:仿真代码及结果
$ G9 }/ _1 [8 m9 s% {& l; M9 ]
0 J0 Q4 o! c! N1 N复制代码
( O: z3 s* C- }1 module test_divf;$ r. A3 @ Q8 R( A0 T
2 reg clk;0 i2 Z. ^ n/ N8 l( w% _& N& t
3 reg clr;% [) |& G1 h( K9 C% ~
4 wire Div_clk;
4 H6 K' r5 o# p: V) _- s9 ^, o5
& x. r3 f7 b9 C* Y, R" S5 y6 always #1 clk=~clk; h( O: R2 t6 G; @7 Q6 V9 g
7
; @ j$ p* C7 y' O; @8 r8 initial
d y* v% K" L3 A0 E9 begin- }0 s5 h) P/ s7 b
10 #0 clr=0;clk=1;5 k7 Z- @& P; Y# p A9 Y
11 #99 clr=1;
+ h8 F" r" z3 J; C- M12 //#1000 $stop;
) {+ w- L1 R* f13 end
* r z0 Q) \' `( c- z6 ~2 m: \14 ( ~* E* @7 D% m# I
15 divf #
- Q, u" ?6 j H1 `4 p" o) K16 (7 q! `5 z8 O& L% D4 E
17 .Div_num ( 5 ),
8 w/ c7 e. T1 A M) w$ N+ O" m18 .state ( 1 )
0 y. D2 K6 X0 W; i5 `& J19 )divf(+ {. `2 q) N$ N1 k5 G( i
20 .clr ( clr ),
+ p: S" _$ c" b) J21 .clk ( clk ),% b, ?6 S4 K1 {1 f# w; h
22 .Div_clk ( Div_clk )
2 c$ M# H7 I, @ ]23 ); + \; |( m) c3 M+ c; n2 D7 ^2 p6 z
24 ) Y1 V ]1 q! Y6 N1 H* B
25 endmodule |
; W& T H; {5 l+ g8 f* c# k
" j3 q5 o% p5 K) Z9 C( Z% z+ M
/ y3 A+ P2 j8 V2 r4 K5 o# g( t2 B3 o2 `) n
- c- `9 @6 [+ K1 T8 y
s- A# u! T$ ~7 X! O: Z5 \" Y2 A j
| 2 |8 I4 M$ }$ s% K
| " V8 v' N8 }% S/ \8 q* D/ i
# a) K6 ]+ ?4 y1 F. U
% c {: b. l" O1 g7 o3 k( }
|
|