任意分频的verilog语言实现6 G1 { ]2 G( f) L9 B1 ~' a+ F
网上看到的,很有帮助,zz与此 现来说说分频原理吧,原理通了,什么都好办了。 1. 偶数倍(2N)分频 使用一模N计数器模块即可实现,即每当模N计数器上升沿从0开始计数至N时,输出时钟进行翻转,同时给计数器一复位信号使之从0开始重新计数,以此循环即可。偶数倍分频原理示意图见图1。 2. 奇数倍(2N+1)分频 (1)占空比为X/(2N+1)或(2N+1-X)/(2N+1)分频,用模(2N+1)计数器模块可以实现。取0至2N之间一数值X(0<x<2n),当计数器时钟上升沿从0开始计数到X值时输出时钟翻转一次,在计数器继续计数达到2N+1时,输出时钟再次翻转并对计数器置一复位信号,使之从0开始重新计数,即可实现。</x<2n) (2)占空比为50%的分频,设计思想如下:基于(1)中占空比为非50%的输出时钟在输入时钟的上升沿触发翻转;若在同一个输入时钟周期内,此计数器的两次输出时钟翻转分别在与(1)中对应的下降沿触发翻转,输出的时钟与(1)中输出的时钟进行逻辑或,即可得到占空比为50%的奇数倍分频时钟。当然其输出端再与偶数倍分频器串接则可以实现偶数倍分频。奇数倍分频原理示意图见图2。(这也是许多公司常出的面试题,^_^,是不是很简单?) 3. N-0.5倍分频 采用模N计数器可以实现。具体如下:计数器从0开始上升沿计数,计数达到N-1上升沿时,输出时钟需翻转,由于分频值为N-0.5,所以在时钟翻转后经历0.5个周期时,计数器输出时钟必须进行再次翻转,即当CLK为下降沿时计数器的输入端应为上升沿脉冲,使计数器计数达到N而复位为0重新开始计数同时输出时钟翻转。这个过程所要做的就是对CLK进行适当的变换,使之送给计数器的触发时钟每经历N-0.5个周期就翻转一次。N-0.5倍:取N=3,分频原理示意图见图3。
# l3 W) f. M$ p9 Z* `" F8 b对于任意的N+A/B倍分频(N、A、B∈Z,A≦B) 6 T- x% \% X+ K9 f# ?$ Z
分别设计一个分频值为N和分频值N+1的整数分频器,采用脉冲计数来控制单位时间内两个分频器出现的次数,从而获得所需要的小数分频值。可以采取如下方法来计算个子出现的频率: 6 e- \/ a8 D0 R8 ]
设N出现的频率为a,则N×a+(N+1)×(B-a)=N×B+A 求解a=B-A; 所以N+1出现的频率为A.例如实现7+2/5分频,取a为3,即7×3+8×2就可以实现。但是由于这种小数分频输出的时钟脉冲抖动很大,现实中很少使用。 http://space.ednchina.com/Upload/Blog/2008/4/16/dd3e4984-96b0-4a82-b83e-73160bb4f4c1.jpg / J3 @' L* C; }
) V6 i+ f- |9 X. n; y- R+ P | //很实用也是笔试面试时常考的,已经经过仿真 占空比要求50%和不要求占空比差别会很大,先看一个占空比50%的描述 2 o) j. | a6 G# s9 w9 W- k& X5 F
module div3(CLKIN,CLKOUT,RESETn);
4 s9 M3 z9 @" n z- R/ U3 Kinput CLKIN,RESETn; 5 I0 E' |9 D* `9 F
output CLKOUT;
) j: v- @: R$ Y0 x5 r
1 n4 I/ s8 Z0 P9 e4 Y//internal counter signals
3 ?2 {" w' o. j! i8 i# ]reg[1:0] count_a;
4 L) H; [+ ~ V: areg[1:0] count_b;
1 z# Z. f7 j V4 p+ p3 Ereg CLKOUT; 4 f( Y3 B4 d: W" J, p2 x
5 u+ Y( B$ _* p4 n
always @(negedge RESETn or posedge CLKIN)
; T4 x6 C6 X2 O3 Abegin
6 i3 l2 A! @( u! i. m n if (RESETn==1'b0) : z& t% u, q* K
count_a<=2'b00;
4 {+ C( |7 u! s6 j( G F2 T else ; P8 C. D8 \9 n$ d4 S! U$ I: u
if (count_a==2'b10)
! K. \) B/ L5 e' ^% V count_a<=2'b00; ' H) h$ O+ l1 x9 _9 `# r* i6 v
else
* z4 V% ^0 [+ c+ [: y count_a<=count_a+1; 4 R/ q- m) F/ W" @
end 2 W( _$ _: Y$ Q$ n% s H% M
. ]0 q" e& O7 \2 s) ]; y( kalways @(negedge RESETn or negedge CLKIN) 1 h% P! `# Z3 q# k4 e, `& [
begin % t! ^3 D* F2 `: i
if (RESETn==1'b0)
+ _5 b% W s. H# T( N) n# R, O count_b<=2'b0; 0 B' @/ R% ~: F% D. _5 W% B5 g6 e
else . Y; U8 r6 s: R( ]6 j
if (count_b==2'b10) . C- N: v9 b5 Q
count_b<=2'b00;
6 W' P; H, s; U. K else 6 {8 c, Z; F s" l9 s1 j0 s; }$ s
count_b<=count_b+1;
" \% g% B1 G: X7 }$ D) R( Vend
4 [" Z( Z% e5 J. ~; n
4 }! d t: f+ Z! a. talways @(count_a or count_b or RESETn)
8 _8 r; v# p9 \" ?4 ebegin
( @/ I6 j7 x; W" N/ i& ` if (RESETn==1'b0) - _0 f2 b! {. s' `8 v
CLKOUT=1'b0; / ]0 @2 [ T' {8 R" W1 n
else if((count_a+count_b==4)||(count_a+ count_b==1)) 7 T3 Q8 V0 C) C0 t, w1 t0 k* o, n
CLKOUT=~CLKOUT;
/ [7 l2 K( ~9 Q- jend 8 y/ l$ [5 p4 n( x; A5 ~7 m/ I8 E
6 s" f" q6 r `
. p. t7 P8 n" y$ A/ Z& b/ dendmodule
# i I7 w% ^* @/ Y0 A' ^
- D" t+ T% d* ^$ g0 v- i0 1 2 0 1 2 - D7 u' m5 B3 i( W! i- `
\ / / \ \ / / \ 6 N4 s3 S7 L+ T' D, k% t) {9 L
0 1 2 0 1 2
! @' ~" @# @$ s5 h) E + k9 B; ~/ i# X4 i3 A; {7 h
下面是一个非50%的描述,只用了上升沿 ) t0 R* u- N% h- {) s1 Z
+ y# b5 f! R( I% v, o: ]module div3(CLKIN,CLKOUT,RESETn);
% E' n; H- T5 Q4 g: M, Qinput CLKIN,RESETn; 4 S5 L2 V+ V' k* X) K0 p8 `- C
output CLKOUT;
3 k* y5 h$ W m+ @! G . w, T$ P5 b% x; L
$ `* G- G ?0 _7 |3 R$ F3 L2 n0 |
wire d;
- a; Y# N! `( `" Vreg q1,q2; , L4 g k0 D3 y6 R
wire CLKOUT;
/ {1 ?. m/ ?( L. }4 }2 }8 |9 t k / l' K% r& X7 f( {& c1 f3 ^9 |; X* w
always @(negedge RESETn or posedge CLKIN) 4 k% N, g* y6 F) E2 u; z* Z
begin c8 S2 t8 |) ?5 c3 ]& _3 }
if (RESETn==1'b0)
1 r5 ~, `; @& b9 w& g- S q1<=1'b0;
d0 j' I' O6 ^' p else
" h/ C8 i2 n( v/ X6 I' e7 v: l q1<=d;
: M; S K- H" G0 @end
) O; l- o0 g3 D. D* V! [& c 5 ?! d5 b: U7 \8 K% A* I+ [' t' Q
always @(negedge RESETn or posedge CLKIN)
* K8 M, L5 m& Y7 P8 O" H- O: tbegin u% a! K4 L6 B6 N# l
if (RESETn==1'b0) ( \9 d5 V& z2 j
q2<=1'b0;
2 p2 a. i$ o. f* {% a else 4 ] F# F' N% S0 x" `/ @. C+ X0 k
q2<=q1;
% X5 z! \5 M) y* [$ d1 fend
R0 L4 W- O* f) E6 T# b+ u & a: b2 g/ W* m1 p' ^
assign d=~q1 & ~q2;
: j/ J$ u! [' v# W! e( A' p
9 `9 x$ v/ t! n& i" F% Lassign CLKOUT=q2;
6 [2 C7 c5 w, o/ x* A
" {% n6 p+ M9 q) f4 ]% L; e x5 Oendmodule
; w8 w6 f0 B3 |. ]8 N: F
* M+ n' [/ h7 Q' J6 u0 r
/ [+ u# E. a0 [" q! W8 p占空比不是50%,只用了单沿触发器,寄存器输出。 至于其他奇数要求50%的或者不要求的占空比的,都可以参照上面两个例子做出。/ }9 D$ Y6 X0 m
占空比为50%的一个更好的实现。
; s. B, o2 {- i9 @4 M/ hmodule div3(CLKIN,CLKOUT,RESETn); # |' r5 a5 q% R8 I2 [3 X4 ]; j( ]
input CLKIN,RESETn; ( T% J Z# f; ^4 q( A6 R
output CLKOUT;
( v. U7 Y6 v i6 B. m+ E4 W//internal counter signals
0 H$ C& W/ [% G4 k/ A6 Areg[1:0] count_a;
2 _/ D1 y3 U* s2 J7 [( Sreg b,c; 2 @: j6 Y5 t& F
//reg CLKOUT;
9 f5 d" d# ]+ @1 z/ `* x. G9 N) zwire CLKOUT;
' d, M* ]! B$ J7 E2 [* b7 M8 talways @(negedge RESETn or posedge CLKIN)
# r) \" q9 A7 X3 @ {6 Ubegin ; R. U6 B6 p" Q6 g" y, p R/ g2 L
if (RESETn==1'b0)
0 u/ D% y8 J; c t* ]) }# z+ D count_a<=2'b00; 7 P* P5 [! P) M. f5 u
else - N8 z- w5 N4 G: K9 Y
if (count_a==2'b10) " I" c5 y7 V& U1 O# j- I
count_a<=2'b00;
+ J; y/ v7 ?8 r. Q4 U, d6 q else : p$ o. q, t, H& w9 O6 Y1 v* G# n
count_a<=count_a+1;
' o) g! L# z: ]; f9 w6 @end
9 s9 z. F8 \% `' }* |7 @: O& Nalways @(negedge RESETn or negedge CLKIN)
- U* ^0 j; Q9 I) x8 i2 I" l, C" p& [begin * Q8 \' x& ^4 d( E9 {1 ^) V/ g
if (RESETn==1'b0) M" `2 @* l3 S
b<=1'b0; ' J( Z7 I1 }1 z; K7 C5 `0 C3 G
else
: A: n3 i! M h8 x* k if (count_a==2'b01) # m& M2 w6 z: R9 j6 v
b<=2'b0;
+ r7 C) S1 P+ N5 P else 3 V: g T6 v, L
b<=1'b1;
# Z3 c; m# @3 R6 Fend 3 Y+ v* V* q9 h1 {8 X/ [1 ]
always @(negedge RESETn or posedge CLKIN) & m0 A+ M& }+ I; P0 U: z4 W
begin . `( e, v9 C2 v" C! c5 P1 b
if (RESETn==1'b0) 1 F3 ?* s3 Q' F+ S0 {- [' F
c<=1'b0; ' s% k3 u& p, L' {1 j; e: r- v
else 7 u$ a! K4 P, c2 a
if (count_a==2'b10) . J f- _- U& O1 t
c<=1'b1; 9 i' V3 d5 w' Z$ A% C' X' S+ Q% s
else if (count_a==2'b01)
3 o3 q) S' p9 N" r/ G" }3 E0 a6 V c<=1'b0;
% ^2 g6 \+ x Pend # b% T: @' p+ A) J; F
assign CLKOUT=b & c; endmodule |
| - [4 m/ {( f# A( k, h5 t
8 I" _6 H$ ^* x! X1 a }5 B
任意奇数分频 //改变FRE_COF即可改变分频系数,这里为7分频 module div7(. B' G! {- Z9 X, b' G
clk,
9 [' \& X, A+ P! B' q rst_n,
( u( f( ^7 b7 W# J clkout,' n8 W Z! W, Y- c1 `
clkout1,
' Q" w5 q1 x& u y1 Y7 W clkout2); input clk,rst_n;+ E1 S( ~5 ?" m
output clkout,clkout1,clkout2; reg clkout1,clkout2;* W7 J1 Y, t2 C8 Z
reg[2:0] cnt1,cnt2; parameter FRE_COF=3'b111; //更改分频比,偶数不成立
! b# e8 r* L" l8 ?3 Y' }parameter STOP=FRE_COF-1;
6 m2 s6 |7 ^ S' N' u' a; |. kparameter THRESHOLD=FRE_COF-1>>1; //除2操作 assign clkout=clkout1|clkout2; //相或
; _& W( a0 b1 d: V/ g" x
% g# K' Q4 j3 m: A1 [: Ialways @(posedge clk or negedge rst_n)begin //正沿触发" E% {2 Y3 ^5 {" i& U
if(!rst_n)
- h9 G# h1 T+ ^" W8 j* a5 a' @. s Y begin) V8 h3 N, S/ b7 e9 |, c3 Z3 c
cnt1<=0;
. o: J4 d* t! k, @ clkout1<=0;
' l3 ~8 T1 a' `/ b3 e3 b end6 x! x% m) e! R3 W6 L! x
else begin9 _5 y9 ?5 R, g8 F) L# |2 Y5 S
if(cnt1==STOP)
4 B' U( W/ ?+ r/ c7 W4 Z begin
/ M9 s2 e# Z2 q# j cnt1<=0;9 a# t9 h2 v8 ]& z9 A4 G+ U
clkout1<=~clkout1;, p" B0 x( b9 @1 F/ U5 W d
end
5 D% A: y9 L1 v2 c5 u else begin! a9 |/ e1 Y: X7 ?4 m! Q- @- u
cnt1<=cnt1+1;
N ~6 L: G' P3 V if(cnt1==THRESHOLD)+ `3 V" d: U- O! [# R3 d" t
clkout1<=~clkout1;; g7 s* _3 D+ q) |) J
else6 b* l0 h4 Y4 D2 ^
clkout1<=clkout1;
$ i0 l+ c; k- ~8 A end
! b5 P8 l! z& o% Q, r* J/ a end! _/ U; a% U8 [
end always@(negedge clk or negedge rst_n)begin //负沿触发& q. {- u4 I1 Y H' |- l/ Q' F: A
if(!rst_n)begin
2 [$ Z4 B5 `/ |+ U cnt2<=0;. i; b1 T0 D9 V% _$ h+ g8 {/ J
clkout2<=0;8 `& J6 F }: R
end
B5 O3 R# }1 d- L! f else begin
9 K& N+ R7 u( C0 m: l7 d if(cnt2==STOP)
' c4 Q* y" k, Z( T begin7 D+ g% |# u# c4 w3 m
cnt2<=0;2 D$ r9 F- M G( X( Q3 r
clkout2<=~clkout2;
' A# b A ^6 y& B$ T! d end' O' R r$ s) y" n! V
else begin n! G7 U! O5 Y' D* @: G
cnt2<=cnt2+1;
8 }0 _# c% {. @ if(cnt2==THRESHOLD)
/ x4 T0 _! G' T4 [ clkout2<=~clkout2;5 [$ R" v! o1 h6 f/ d" _
else) w8 O9 M4 k* ^) U, ?
clkout2<=clkout2;
& x! t; u. A K4 J end; g4 L# H2 x' t
end
* M2 B2 E+ O5 P5 o end endmodule |