任意分频的verilog语言实现$ }& M9 H: n% J, ^6 P1 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。 2 k' n8 b- H) o$ x2 i" J. z$ P5 C) U
对于任意的N+A/B倍分频(N、A、B∈Z,A≦B)
& q& s( [' ~+ W# T" _: |分别设计一个分频值为N和分频值N+1的整数分频器,采用脉冲计数来控制单位时间内两个分频器出现的次数,从而获得所需要的小数分频值。可以采取如下方法来计算个子出现的频率: 7 w/ ]/ o; L9 n8 S0 R( x
设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
1 i: M k& \7 `7 G! O; j c( A; W3 v5 M3 j
| //很实用也是笔试面试时常考的,已经经过仿真 占空比要求50%和不要求占空比差别会很大,先看一个占空比50%的描述 ) S, I% H' m. U$ s7 m
module div3(CLKIN,CLKOUT,RESETn); ' R; G6 s/ k$ m
input CLKIN,RESETn;
: p1 s: [+ r3 T3 X: `2 toutput CLKOUT;
; I4 C7 g( a J1 B( n/ w9 f
- ~& Z+ T; S& J& K5 c8 G0 S//internal counter signals 7 E3 f# i3 [# o5 v _5 A
reg[1:0] count_a;
1 Z1 u0 B. [* K- N+ ?reg[1:0] count_b;
# S- e; \/ C5 q" r1 D2 _0 Areg CLKOUT; ( @: S9 G- F9 e" c- c+ a% M# S
9 P% b8 r# Z1 V, x' c
always @(negedge RESETn or posedge CLKIN) & d4 K5 x' m2 B& J( i
begin 2 Y U) `0 \1 A1 ], [" F
if (RESETn==1'b0) 6 j8 [, |" P! K& ?$ b
count_a<=2'b00;
2 @2 w3 t) O; ~: N# t* G else 1 }# J" V! K5 A! ~! e# v$ w
if (count_a==2'b10)
) v% b# ^( G3 g count_a<=2'b00;
2 ]0 t ^% Q2 o& u- v% b" ^# M else 1 ^. S+ |4 O/ d! F5 P
count_a<=count_a+1;
* ^* a. Z, x, L; X' J$ Vend
/ t6 [1 x5 G& d. f# e' d
: v4 d& a, `$ x$ }1 ^0 I* N# [/ dalways @(negedge RESETn or negedge CLKIN) ! Y3 ?0 L4 Q1 a* K+ D' N) i
begin
( v5 P! M% K8 L/ n if (RESETn==1'b0) * v( e9 V4 \7 D* G3 v3 j
count_b<=2'b0; 6 K2 c/ }3 M6 n" I- g% b
else
1 c" ]! A$ W. M9 m% i6 u if (count_b==2'b10) ! A1 h; m7 d9 q
count_b<=2'b00;
: `8 V. ~6 s4 A) T2 C" o else 8 C3 k( y; E' U
count_b<=count_b+1; : z( f* D' x! O+ d: c. q0 I7 O8 U
end ; X/ _/ C J+ R( j' P% D
4 q8 I6 b4 [* y
always @(count_a or count_b or RESETn) , t j: v7 ~ @# |, V- \
begin
k6 p5 a* _' n if (RESETn==1'b0) / V3 L8 k* {0 n: C. j
CLKOUT=1'b0; ' s* w; y6 m% r3 i% O3 G. W
else if((count_a+count_b==4)||(count_a+ count_b==1))
& W) O/ v* |8 W8 Z! ] CLKOUT=~CLKOUT; : J/ w% R- p2 l0 N& M' @1 s
end " S1 s& h8 k# n; ]9 @. |2 r9 K0 M
5 s; E# r/ n ?; n: F
4 y$ q! m+ e% R1 O( _endmodule % O& I* V) E6 t$ X- ?+ R3 M3 }, k# d
% X& }- H. i2 A9 a5 e: a1 ^0 1 2 0 1 2 6 G" c0 A! d {) Z. J
\ / / \ \ / / \ ! m) p' {2 P+ K/ n; @% w7 h& }
0 1 2 0 1 2 . [5 X# P4 d+ ~
% L( A* h' A1 p( U. W
下面是一个非50%的描述,只用了上升沿 % ^. N! B" {" h4 ?
! p/ [& p4 G' w4 ~7 W+ z
module div3(CLKIN,CLKOUT,RESETn);
& e: Q& s) f8 X/ `( c# Y$ Ginput CLKIN,RESETn; / }% O b2 B: l# `
output CLKOUT;
& F# z, l, |4 [8 O: o* [ ; f' U8 }8 ]$ Q. e: i
w9 b: e1 L6 _+ o
wire d; & q9 _1 ~& r6 e, J
reg q1,q2;
# Y% {/ n) R2 ~& W# ^/ kwire CLKOUT;
& n! c6 I8 K8 w* ~2 s0 E% D # ^5 _- [9 C( {4 K
always @(negedge RESETn or posedge CLKIN)
6 k6 q3 }+ j8 F- t. E v4 wbegin . @2 u4 q6 ~5 p L. z8 j9 O
if (RESETn==1'b0)
7 M# `2 p/ y/ R7 b q1<=1'b0;
|' h4 t. J1 Y( T" O! U else
$ j2 y4 c7 Z4 Z$ ] q1<=d;
' s/ M- X' I& z1 aend 1 m( v- O3 U0 v f" r- {: V
Q! c" c7 p; g9 w6 ?( C J" Yalways @(negedge RESETn or posedge CLKIN) ! }) d$ |: v/ C! R k/ K) J
begin 1 t A4 h) y1 V6 j
if (RESETn==1'b0)
- e2 m- c* R0 K5 P+ _9 H8 |, I5 U& \ q2<=1'b0;
* H! y: p0 S; F else 5 G4 M* l8 i# X p4 r# t
q2<=q1;
7 @( d; V. u% M4 T0 ?; ^end
1 V, h; R2 V) T5 W 5 T& \- w! U; r& d( I" Y. b: c. o
assign d=~q1 & ~q2;
: L- s+ O* B" K. p6 a; |. M; V- B % X. z5 {* g: {* \' }* x
assign CLKOUT=q2; * K1 y! I- o4 w# C! ~4 \! _
( C7 J6 a! S( h, ~- Kendmodule ( b9 N. l0 E; L( M% w* l4 B
* K0 f$ A$ {4 D/ R: Z% X7 v9 _ 3 \+ ]1 v3 d+ u: w! V" e7 t9 k
占空比不是50%,只用了单沿触发器,寄存器输出。 至于其他奇数要求50%的或者不要求的占空比的,都可以参照上面两个例子做出。
& }; e5 y" H+ L8 h1 B2 I9 C占空比为50%的一个更好的实现。 - a5 A( D6 C6 `* C8 k
module div3(CLKIN,CLKOUT,RESETn);
9 d5 H# h+ p& \* \' |input CLKIN,RESETn; 7 I% n ~+ b2 ]
output CLKOUT;
, }3 f* F; S' L: d//internal counter signals & M& ?0 A/ s9 q# \
reg[1:0] count_a;
7 X- H9 z8 b5 u5 T$ d' ]: C2 w3 B6 zreg b,c;
% h4 v' o7 |% t0 f3 \//reg CLKOUT;
9 `" o% G& }* a1 U/ y) gwire CLKOUT;
# j$ p m. H1 F, a! B3 t" ?always @(negedge RESETn or posedge CLKIN)
; ]/ y/ L& o; v- jbegin + A. |* M$ L& M
if (RESETn==1'b0)
* i. E7 z! i' D" |1 \0 O6 r' K5 b8 V count_a<=2'b00; . c) y- ?3 ?3 f0 [
else
4 Y5 t, g% R2 T1 B if (count_a==2'b10) * i* O% y# n# g% c% [. j4 k
count_a<=2'b00;
$ M4 m/ q' |% P+ J* J; ~, P else
$ b+ F5 E. o( Z count_a<=count_a+1; / ^( }) R+ f3 \" U: s
end
) k% Q8 O9 D2 o' _8 Q Nalways @(negedge RESETn or negedge CLKIN) 3 d/ m7 o0 P! M. Y
begin
8 X, _$ j D$ |/ c3 C if (RESETn==1'b0)
. v( Y3 Y8 {( `1 ]* h b<=1'b0;
6 U2 T! j, g. V: F9 p4 [ else ' c4 ~. w# d: K1 l
if (count_a==2'b01) ' Y2 K' D4 P) ]. e
b<=2'b0;
4 h/ s1 Y% ?2 V' Y) l% m else 9 r3 M ~+ z0 n& I2 u; Q
b<=1'b1; , l- U# }4 \7 {4 u: g
end
Y' t' l Z6 ~always @(negedge RESETn or posedge CLKIN) ( O: y' j/ _; p. Q! m( b f
begin " D" e, U. K' @
if (RESETn==1'b0)
0 R& Z0 X6 }( b c<=1'b0;
' W. z& Z r! ^8 o5 E* G& O: @- g else ( v$ ~: Q! F+ {8 K% ^% d: {
if (count_a==2'b10) ! ?5 k7 W+ X+ H. }
c<=1'b1; 4 `& ~/ q7 O* |8 ^, C' o& a; k
else if (count_a==2'b01)
5 K# E, g0 j3 V1 Y c<=1'b0; " t. X% c* n+ d8 Z9 x
end 6 n* W1 h6 F% a R# B! x
assign CLKOUT=b & c; endmodule |
| 4 r4 m, [0 {! Q* a$ j) R
: z1 b- Q7 m' H K, V5 d9 `任意奇数分频 //改变FRE_COF即可改变分频系数,这里为7分频 module div7(
8 W% L$ ]& d$ p7 y clk,0 J1 x8 u: B/ u+ y. X
rst_n,; R( I2 c$ L0 W! z, E" f* D, S
clkout, h) V/ J8 ]4 b0 _
clkout1,6 W, l( F! ]) I! {; y2 ^
clkout2); input clk,rst_n;
. X! K/ M6 l6 A! |output clkout,clkout1,clkout2; reg clkout1,clkout2;
$ [, S& p$ N1 `reg[2:0] cnt1,cnt2; parameter FRE_COF=3'b111; //更改分频比,偶数不成立
. u" e5 ]+ s2 g- P H. p7 `& U4 yparameter STOP=FRE_COF-1; & x! ^ _8 q8 J/ i% t: |
parameter THRESHOLD=FRE_COF-1>>1; //除2操作 assign clkout=clkout1|clkout2; //相或! y" c1 g8 u0 u j
& N' k3 d' P7 l1 t F) Xalways @(posedge clk or negedge rst_n)begin //正沿触发
- W: G3 x( \+ v9 p if(!rst_n)( h6 k n) R7 T4 [- {
begin' ?4 l% M7 k* z# ?. L: Z; H0 A
cnt1<=0;
' q) s% [, n. w+ w1 u clkout1<=0;
+ A+ g& c [7 Q end- T* F2 u _$ D% [& U2 ~
else begin# O3 f/ Q" j0 T$ v
if(cnt1==STOP)
# g O/ A9 b5 @( F, X. F& ]# V begin! H" e2 a+ M2 h
cnt1<=0;
Z4 {/ Q6 W4 S( ] clkout1<=~clkout1;
# [$ v @$ _+ ^0 _% |( d end
8 [ u$ _% T2 J* u; H else begin
2 m/ e4 m- p# S$ Z$ N2 t( Y' l cnt1<=cnt1+1;
7 q `5 n1 D: F if(cnt1==THRESHOLD)
( E) Q7 d( r' s: N* N8 x clkout1<=~clkout1;' u, S* ~# O' q2 n
else
" o% a' `; F* V+ v4 e* o6 x% r clkout1<=clkout1;
2 m" u5 Q/ s8 x end
8 t" I* @, }% F. P+ z: a' D+ ` end1 Y& F, E5 ^1 h3 A; Q j8 ]
end always@(negedge clk or negedge rst_n)begin //负沿触发- u4 N% @: @ O( w% O
if(!rst_n)begin
' k4 A, l5 q0 {/ i1 n2 [ cnt2<=0;# ?* f6 g% E( w
clkout2<=0;2 M1 K% i7 h2 c& a, s
end5 n c/ l& \0 m- M
else begin
. Z6 R, f h9 x1 J, r if(cnt2==STOP)
8 E$ {* B6 |2 J- N6 x& D( t) R begin
3 m( c0 W, g! i- v; S" Q cnt2<=0;
, g w1 Y; m3 U clkout2<=~clkout2;
7 F8 z8 I% N' D) c$ ` end
( e1 k! S/ E- C9 p) H" ~) X. ` S else begin3 P+ U6 _+ l; i" l
cnt2<=cnt2+1;/ X3 c8 S2 S3 i3 S8 B( J
if(cnt2==THRESHOLD)3 p- X! {; |% j
clkout2<=~clkout2;
1 b* y% O( S! J) U% r else& ~& |# o7 D' H5 @ x' j
clkout2<=clkout2;4 j* ?/ [; M) `: H
end/ M1 Y0 q! r% z ]/ @
end
0 V0 c: R5 G r c( Y" I end endmodule |