任意分频的verilog语言实现8 X. {; Q2 ?- [7 T! B
网上看到的,很有帮助,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。
1 X3 b. G8 X0 p$ x8 {- E" e对于任意的N+A/B倍分频(N、A、B∈Z,A≦B) & R, n( K1 V6 @6 K8 [
分别设计一个分频值为N和分频值N+1的整数分频器,采用脉冲计数来控制单位时间内两个分频器出现的次数,从而获得所需要的小数分频值。可以采取如下方法来计算个子出现的频率: ! ~! `4 \4 `5 b. E2 H4 @
设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
+ t/ y' F; i- a8 C- s" l
- K+ r$ m% `* I. I% ^" c2 V | //很实用也是笔试面试时常考的,已经经过仿真 占空比要求50%和不要求占空比差别会很大,先看一个占空比50%的描述
9 q) S3 n9 v5 v& \4 d: Lmodule div3(CLKIN,CLKOUT,RESETn); / h. t- e$ N* C9 b/ D
input CLKIN,RESETn; , h/ C! w7 }+ p& C1 X o G% R
output CLKOUT;
$ p6 \+ f5 e0 t; t$ T5 X8 | 4 j3 |' z) R5 c& [$ [
//internal counter signals
& w% A6 m0 h4 t# _" qreg[1:0] count_a; 1 a! a7 p/ n/ r5 O t6 q
reg[1:0] count_b;
% E& p: |8 l7 b: Areg CLKOUT; 9 W( K3 y) p A; ]) h9 ?. R
) d* `8 x' h- ]- O/ E. Halways @(negedge RESETn or posedge CLKIN) 5 n6 e7 I5 ^/ O0 _7 ~* X5 U/ ~4 N" r
begin 0 j# f7 [. x+ Y# y* |5 y
if (RESETn==1'b0)
7 W' K7 I" h. L4 v1 V count_a<=2'b00;
3 w. {0 R: L& H) ]8 t9 X Z$ E6 E$ ^ else
& n- G# n: V! f if (count_a==2'b10)
* ^4 g, L# e/ z z count_a<=2'b00; 6 N9 J8 B0 y: T: t/ S( J' J( p" s
else
~9 C- M$ X% { count_a<=count_a+1;
- f( R/ T, J9 p Aend
* G& R: ?# G& q `5 C $ `1 n2 A4 W6 N8 H* N
always @(negedge RESETn or negedge CLKIN) 6 d2 L1 [* i, m! C% d9 c
begin
2 W* \ E! N" X3 j if (RESETn==1'b0) ( k6 t7 D7 D4 f8 n. o, _
count_b<=2'b0; . H" A9 L2 J( u) h: {, D+ u0 f
else ( E6 ^. @' D. H! l' ~1 Z
if (count_b==2'b10) 0 @8 i. u2 c3 C7 l, j
count_b<=2'b00;
0 ?, q( ~- u6 g- o! e7 G( p5 ^ else
4 M# `+ T8 g+ b: Q9 j$ U8 Y count_b<=count_b+1;
. V" V2 @; }6 |# x9 M: Lend
T( [5 G& w; E
: K* a: q8 {" E/ v/ i: ealways @(count_a or count_b or RESETn) ( T |5 a8 R7 _
begin
' e9 o& ^. Q" R/ H, W4 l- @' D# ^) f if (RESETn==1'b0) ( o) M* T) c" g( h
CLKOUT=1'b0;
6 ]& v5 \* \. p7 F8 H6 Y else if((count_a+count_b==4)||(count_a+ count_b==1)) J( N4 R; F2 \) h. n, ^
CLKOUT=~CLKOUT; , K" y: T/ o8 S9 u/ D* F4 i3 ], F
end
1 B+ b, Z V# Q& q6 }$ O- b
& z3 C) ^" d. n, Z. |3 g" b
1 f+ i/ s$ P3 {0 o4 A a7 Cendmodule 4 j, N! d$ o* J" E) J( x* t2 U
0 p$ W7 A9 R2 \1 y0 1 2 0 1 2
' n: x( O: V& r; j\ / / \ \ / / \
/ g' A/ U/ S) T$ d. s 0 1 2 0 1 2 + ^# @; U: s1 j+ d
l: |; s+ w- u5 i3 H
下面是一个非50%的描述,只用了上升沿 + t; J9 @: W6 s7 x! ?' S7 F4 i
) X8 D% ?" Q, p6 O6 @' i/ Mmodule div3(CLKIN,CLKOUT,RESETn);
$ I0 q. |9 @# U Z$ i1 b Cinput CLKIN,RESETn;
% p/ M+ ]! z! D) v* Y; P/ y* S6 ioutput CLKOUT;
6 t, J' H4 `0 P: p# `: {% T % a. U! d4 a4 o' A/ q" r
5 k3 x0 r- t' z$ E' [* rwire d;
& Y, N0 f1 V# N3 ^& O+ Areg q1,q2; 9 m1 s8 X* q/ _! u
wire CLKOUT;
' Y% g! t* b6 h& {& l ) g0 m) `1 x/ S/ s
always @(negedge RESETn or posedge CLKIN)
' n4 s/ v" ]+ n2 A* O" bbegin P( L9 I; K4 |, D; R3 t$ P
if (RESETn==1'b0)
, n# m1 g3 X4 G: X t% x q1<=1'b0;
X0 G5 \% A0 f' x% O M else
8 [# `' K& i4 D q1<=d; 4 d0 L; R! q) r* y
end 7 c) o8 e- t3 K
. y" V7 Z3 V) E- [% A
always @(negedge RESETn or posedge CLKIN) : @% N' P* m: e) c! f- |
begin & Q% }4 j' H! {5 X' X
if (RESETn==1'b0)
. c, f$ {. ?0 p* z" J: ~9 z q2<=1'b0;
! c t D% [4 r$ f6 ~$ R, L0 k3 A else
- Q% @* ^6 O. C& g; N" W* L6 u q2<=q1; - g2 Z: q( N: V% ]
end
, M) b. ~! t' d Q
, K; E' ~# o- R9 @; s( Rassign d=~q1 & ~q2;
, _% b4 ~8 Y( C7 p4 Z% I - L7 V! f0 n P1 `! a" ]. V2 O) M
assign CLKOUT=q2; 5 U2 T# K) o; o4 C9 N
7 Z2 l% V. p/ h# Q$ H
endmodule
j+ X5 w, _6 Z' A. j4 L* x) ~8 o : W/ ~1 f p1 Z2 C& d) z
K. _; [; w' U. ?1 U; ~6 s+ \. G
占空比不是50%,只用了单沿触发器,寄存器输出。 至于其他奇数要求50%的或者不要求的占空比的,都可以参照上面两个例子做出。
9 o/ ^) z6 y0 s6 l5 i6 L占空比为50%的一个更好的实现。 , Y* y% u" x5 K* d6 O
module div3(CLKIN,CLKOUT,RESETn);
0 {2 j. B7 }& f7 Cinput CLKIN,RESETn;
6 L2 x! X! n' ]) r* j7 z' Woutput CLKOUT;
* w$ p# z3 n) P) [# D: Y/ [//internal counter signals h8 x& v0 _9 d* g5 W) j- V
reg[1:0] count_a; ) Z$ s; d5 H2 y O& [+ u" y) h
reg b,c;
1 W6 g$ P0 ~6 {1 T6 E$ x//reg CLKOUT; : B# E# P( `7 e0 ?: F
wire CLKOUT;
9 ]5 F" x5 h$ N3 ^" y7 Falways @(negedge RESETn or posedge CLKIN) 4 c6 e5 c% B; P; }, p5 S1 |
begin 0 i) d* i* R0 d
if (RESETn==1'b0) 0 b. n* I$ f9 J6 }" v G5 g
count_a<=2'b00;
" v- R* z9 I, X7 L# U+ w7 M2 O else
9 v# p3 s2 X. e. b J, d) k- { if (count_a==2'b10)
) E8 }. N! W! R, w# M/ Z count_a<=2'b00; $ S; V$ u" X7 U! j2 Q
else
. m) V+ ?% X! I7 |6 e count_a<=count_a+1;
: q% [/ f% q3 c* X2 [end
5 r) r" \0 U! @& n( Y2 Oalways @(negedge RESETn or negedge CLKIN)
- r6 o6 V4 `% M! S( Fbegin
( W! h; s6 M0 f5 t4 d if (RESETn==1'b0) ' W2 g) ~) ]2 _0 B
b<=1'b0;
" T& ~. T6 M7 Y$ E else % t& S: F) I1 c" z
if (count_a==2'b01) 7 _" ?- ?0 o% l7 Y1 {+ B
b<=2'b0;
( ^- L3 F" P4 {3 |+ x else 2 E, @: H. M0 J) ^# Q2 q9 M
b<=1'b1; . v# b6 a$ R) D3 }( W; U4 C
end
3 a8 ?, ]+ a; e8 falways @(negedge RESETn or posedge CLKIN) * c, g+ y c" U* t n# V3 Q
begin 1 \ x, D6 k5 x
if (RESETn==1'b0) % p; J2 }4 V% d5 j
c<=1'b0; 9 z% s! e, p0 {3 r& ?3 z3 W: q
else 2 ?/ X' p% V+ H3 x' B/ m
if (count_a==2'b10) + B2 Z" w& T6 l) J
c<=1'b1;
- [+ K4 @& o. W0 E! ]- d p else if (count_a==2'b01)
8 L: |+ X6 B0 X, d c<=1'b0; 1 m: e" p" I' D. m1 D8 F3 c- u
end
" @7 ^8 D8 A$ ^+ Q5 K' Dassign CLKOUT=b & c; endmodule |
|
9 N+ u5 k# E# u: y! ]1 T( X# S. J' x) j
任意奇数分频 //改变FRE_COF即可改变分频系数,这里为7分频 module div7(
" ~6 p0 v- d1 x clk,, t q0 Z* h3 @6 K" b, D/ h7 t% l
rst_n,
! E+ I0 p9 b0 s3 y E clkout,) g5 K0 v( s! F4 G7 D
clkout1,8 f, J0 z5 b+ S0 H! A
clkout2); input clk,rst_n;
6 @ J& B u" \) toutput clkout,clkout1,clkout2; reg clkout1,clkout2;
* h" L% I/ `$ Q$ H4 t8 Z6 r0 U* {reg[2:0] cnt1,cnt2; parameter FRE_COF=3'b111; //更改分频比,偶数不成立
5 n+ {& Q( @" ~# x/ H: m* Xparameter STOP=FRE_COF-1; ; f: X7 U/ P% W# I; P& h
parameter THRESHOLD=FRE_COF-1>>1; //除2操作 assign clkout=clkout1|clkout2; //相或! a- Z( j+ V7 L O( D( Z- n( e$ M
5 V. X" I* e! f) O4 X6 aalways @(posedge clk or negedge rst_n)begin //正沿触发 y! B1 Y A! i r
if(!rst_n)
. a* Z6 a) E' a( C& P' {5 A" r$ @ begin) L' w# ~2 U9 P! C
cnt1<=0;
9 C# q, x/ H3 y9 m4 ] clkout1<=0;+ m7 r' i* r4 f
end. C( t- m$ y \7 Q0 B& b! t% ?4 K0 H9 H
else begin
7 _) s7 U( V& y! T" n3 r! j' n" T7 [ if(cnt1==STOP)
! Y; X6 W0 F% u begin7 i2 y7 V8 r# K. v! ~7 b
cnt1<=0;
- a1 `# R' G9 l' U clkout1<=~clkout1;* J6 e9 d8 E j9 [) b3 _% R% Y% X* _
end1 A( l. ^& A2 k. y1 k! r& H1 L
else begin
% D( {7 W3 m; G" T cnt1<=cnt1+1;' P) ]. f4 l6 P9 q5 l' p
if(cnt1==THRESHOLD)
1 G! R _, T7 r2 X clkout1<=~clkout1;
- Q' @# I% H* P, E else
# k1 |: A; a. V# T( X- w clkout1<=clkout1;) ]- x8 t$ h I5 G S, P `
end
2 C" _( R9 ~# R0 F2 F8 n end
8 a- E3 A; z! H- [& J( W$ Z4 v# q end always@(negedge clk or negedge rst_n)begin //负沿触发
$ e7 e9 W' \8 L. j, Vif(!rst_n)begin X* Q& u! C5 O
cnt2<=0;
: e: b! c4 {; \2 W6 d: F clkout2<=0; [( R# Y2 g T: o2 k
end/ g: a& A4 [' i: O0 a2 s
else begin
& Z0 |! A9 }, I- [$ K: K if(cnt2==STOP)8 l, l3 }9 D7 n: e5 c$ C
begin% a4 R& r1 y3 z2 B: C
cnt2<=0;
5 C; }( S, Z# o; Y0 [% z clkout2<=~clkout2;6 A) o3 s9 D9 n
end
& t. a) r5 W4 x D0 n! ~5 D, ^ else begin
4 W+ z5 x3 O/ s' U4 a cnt2<=cnt2+1;
# B, N8 _& D! D1 { if(cnt2==THRESHOLD)$ H5 F2 B& j/ q4 f
clkout2<=~clkout2;
: J9 B, E {8 X9 t, [; ] else; h; c5 P6 C" k
clkout2<=clkout2;- N: q% K( D" `+ M! ]+ w
end
2 W1 k u7 X0 o+ x+ f9 h# Q; | end
+ y6 \" N: E# B# g0 O. A) a end endmodule |