任意分频的verilog语言实现% D0 c% ~2 D" l$ i
网上看到的,很有帮助,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。 . a% ^' j8 d4 q- E# p- _ P: H
对于任意的N+A/B倍分频(N、A、B∈Z,A≦B) 1 j( m9 v8 H) `7 _) \4 J
分别设计一个分频值为N和分频值N+1的整数分频器,采用脉冲计数来控制单位时间内两个分频器出现的次数,从而获得所需要的小数分频值。可以采取如下方法来计算个子出现的频率:
# ~9 D& u6 \+ C+ e/ S设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 " B: K$ r6 x' P* o
7 @" C8 Y+ z: ?* m0 M | //很实用也是笔试面试时常考的,已经经过仿真 占空比要求50%和不要求占空比差别会很大,先看一个占空比50%的描述 9 w+ p6 |0 i0 w: L1 b; |( l8 U! H
module div3(CLKIN,CLKOUT,RESETn);
3 H7 T! n) [* F J7 w4 tinput CLKIN,RESETn; 5 G! D5 A2 _; ]$ I( E# C
output CLKOUT;
: p3 ^) @; @6 k % e- G, V# }6 }, j
//internal counter signals ) |5 _+ c% E2 S7 ~. [2 T
reg[1:0] count_a; 6 `8 s' O- n j* X8 `
reg[1:0] count_b;
/ F6 t& R9 G3 d. l0 z Zreg CLKOUT; 9 U/ l0 x9 K: x, U4 c8 O4 I: F
9 w0 }+ w- q- j8 V, I. Z& [/ }6 Lalways @(negedge RESETn or posedge CLKIN) ( N- ]3 N& E1 h5 M( _7 z# v. s
begin 8 m" E0 m1 G7 S3 _, i8 q) x
if (RESETn==1'b0)
) W2 X# E2 A, {5 H! R+ p' G count_a<=2'b00; & G% c6 Q: V B4 J: d
else 3 J- t) Q2 i# ~ M$ p6 T5 P
if (count_a==2'b10)
$ x2 P) U& W' Y3 B7 p( ~5 Q" c count_a<=2'b00; ; [) t+ C2 K0 H# A
else
( h2 c o/ G7 ^9 B( L- g count_a<=count_a+1; 7 C1 x5 w7 u" B
end
$ m( N ?, Y3 c: N 1 C7 U* x3 V$ g% R- d5 o
always @(negedge RESETn or negedge CLKIN)
$ {/ q- {9 s! w9 \begin
& \# _+ b& c( I9 N" u( P if (RESETn==1'b0)
) W: M' v5 M! \4 K4 v1 U count_b<=2'b0;
3 a* S& ` ~/ Y# r else 1 \+ r3 K& D% Q( b6 Q) U3 X4 V! W! l8 X
if (count_b==2'b10) - x0 N% e& \7 e8 W) }. d. _
count_b<=2'b00; # X2 ?5 l, r3 f
else ) u+ g9 {4 f8 k) b3 y3 W
count_b<=count_b+1;
: V( m4 E! I) e Y% Z3 U) A' J) send U( W! P3 T1 o; l0 ?6 D* ~9 }
- P: i9 `% \/ @9 r; Q3 x
always @(count_a or count_b or RESETn) + }+ p/ `0 L# B% @$ @
begin 1 ]) C1 Q9 e% z. Q
if (RESETn==1'b0)
, d0 q# T0 Q" o d" K CLKOUT=1'b0;
* \: f B: `% C else if((count_a+count_b==4)||(count_a+ count_b==1)) 4 O+ x4 h0 H, D
CLKOUT=~CLKOUT;
% g! t* d$ q; ]1 Tend " m9 t4 E- N- A
. O7 R$ a- Q8 p# q& c6 E
+ `" r5 A, ~8 W$ eendmodule 6 P; [6 k: u. n' F2 f
3 g( @* X5 x& _: c4 Q8 U7 f# C% R
0 1 2 0 1 2 ^" {+ k6 A/ ^1 z! V- a
\ / / \ \ / / \ / c# H0 V8 D6 b
0 1 2 0 1 2
9 g2 p W& x4 M- \) l 6 ^' p9 {1 A( L/ i2 E8 t
下面是一个非50%的描述,只用了上升沿 / H$ F" J$ r% r
# G4 e& }9 M6 O) }module div3(CLKIN,CLKOUT,RESETn); 9 {" G" x+ R8 _/ U
input CLKIN,RESETn;
* ~0 }! c7 h! j6 t; eoutput CLKOUT;
4 R8 z! ^) P# m, h 5 \3 x- U, S; l
5 \( @: @3 ^. V( E
wire d;
. t& f8 r& k% s1 p7 V% greg q1,q2;
5 U$ w& r: D' {) y& B5 Kwire CLKOUT;
4 q3 m% f7 C/ F% Z# [! G% q / |5 l W5 v. q/ k( U1 d
always @(negedge RESETn or posedge CLKIN)
! V8 |8 ^/ C) |% R5 vbegin 4 D. `; b, S# K, A4 V1 J& C
if (RESETn==1'b0)
( l/ s: ~4 O* ?0 n" ]" z q1<=1'b0; 1 L U2 P0 e+ k
else
; z6 s% j8 y" ~6 Y" n; B+ D- M, d q1<=d;
& y- V8 r$ m, e2 Bend
1 A; |1 P" Q1 O5 B3 F' g, C# U) f * M" c( X) H% s6 T0 c# I6 }
always @(negedge RESETn or posedge CLKIN) ) }# g3 [/ t4 K9 L* U6 A6 `, Z# Y/ k
begin
" C9 J: Y' r$ t$ j if (RESETn==1'b0)
( { _6 t- }0 F* B0 P K { q2<=1'b0; " a2 V& n$ Y+ g3 `# Y1 l
else + w6 s0 t! b0 r P
q2<=q1;
9 ], H- J. P" L2 u: d2 C3 ]; Xend
5 F; x2 i/ K' O* p" O1 e1 J$ Q
" \/ u0 a6 X ?$ X; f# ?: lassign d=~q1 & ~q2; / {! x% f. B! [& [. Q0 H
7 N% d( T, `, |- a* B2 q' yassign CLKOUT=q2;
7 E3 Q4 l, D1 t
# E. s/ p8 \ ?) a1 |endmodule
6 @) r; G% `" C # f5 ?4 A, s4 d2 \ V
( ~1 H$ n3 b9 U7 E; q* N1 ^: L占空比不是50%,只用了单沿触发器,寄存器输出。 至于其他奇数要求50%的或者不要求的占空比的,都可以参照上面两个例子做出。: M0 p8 T% J/ C) B. H+ W
占空比为50%的一个更好的实现。
E2 e8 |+ {) }' S3 S' \) pmodule div3(CLKIN,CLKOUT,RESETn); % w6 W3 ~4 b! _7 ^! Z
input CLKIN,RESETn;
/ V4 ?0 {, z& ]( u' ooutput CLKOUT;
! {6 c9 h$ e z# H0 w7 G, p//internal counter signals
8 E6 e s0 Q0 E6 Rreg[1:0] count_a;
5 g, D8 p1 | \& V) \reg b,c;
9 P/ c0 U+ ?2 [; e p- z/ ?& P5 V//reg CLKOUT;
1 m/ H* ~, H K7 o2 u6 o) n, e+ L( hwire CLKOUT;
+ z$ r) j. v; x- D2 Palways @(negedge RESETn or posedge CLKIN) ) z7 x7 E( x% f# L5 f! d/ v4 s- u
begin
7 X0 o" H8 g9 t, } H7 c if (RESETn==1'b0) " N. X( Q5 f7 r% N/ Q$ S C
count_a<=2'b00; * D0 i L9 H* Q8 E
else 5 {% M2 ]9 G: b, R
if (count_a==2'b10) + @1 l# }, H/ D9 T; C S
count_a<=2'b00; 9 z9 c( \ n+ E/ L. x
else
1 i& [% B' d% {, s8 d count_a<=count_a+1;
2 I, G- C5 t+ _4 w x, F" Xend
& T$ k+ C7 P. D& l. U% _9 Y8 Qalways @(negedge RESETn or negedge CLKIN)
, m4 J9 b8 A. ?begin - B: O. W6 H( P- J& ?9 k! t
if (RESETn==1'b0) , B2 K9 @% [, t/ o* U
b<=1'b0; 9 ^& o* V# h2 u0 x
else
" R/ x2 q: j5 i0 Y: H/ T V3 N if (count_a==2'b01)
0 y* v. d( @, e: @ v b<=2'b0; 5 b) N, N9 Z( v
else
1 ~' T6 C4 j5 ] _* ^/ u% u) } b<=1'b1;
S+ B3 k$ K, P9 G* P, F2 A6 `& b- Bend
0 }1 \9 Y S Q% p% {0 y" U- Ualways @(negedge RESETn or posedge CLKIN)
g. C5 q+ E' d# [begin
) x8 W! r* }- g5 w: ] if (RESETn==1'b0) 9 s8 @& m4 h% b5 g
c<=1'b0; ; X* |; P+ v; Z8 S% x1 m" E; h
else
9 w0 D. e x, P' j& H; P- Z if (count_a==2'b10) 3 D2 ~# ]1 A" L5 Z. {
c<=1'b1; % {8 g" P: b/ B; c, D# M9 I
else if (count_a==2'b01) ' C5 |3 p9 g* T% Z
c<=1'b0;
6 {8 @; Z& P% E& l/ hend 4 |9 r/ n6 W( F9 _1 F! H7 m
assign CLKOUT=b & c; endmodule |
|
" ] t9 O* `9 e1 Q7 u O: ]& o, J+ T" m6 |2 E
任意奇数分频 //改变FRE_COF即可改变分频系数,这里为7分频 module div7(
" i0 |; c3 Q- f7 Y! x) U clk,: m) ~$ x; L# q* p/ f7 G" u5 }; j, |* @
rst_n,
3 @! H* U- X7 v* \8 A clkout,
$ Z0 y' g' D* f2 u$ e- U4 v clkout1,# {$ F6 o X9 F3 J; O' F
clkout2); input clk,rst_n;
" Y; `3 n3 {8 s* goutput clkout,clkout1,clkout2; reg clkout1,clkout2;
, x7 D- u+ o4 Breg[2:0] cnt1,cnt2; parameter FRE_COF=3'b111; //更改分频比,偶数不成立0 u4 R& t- P. g% R
parameter STOP=FRE_COF-1;
2 H$ x$ {7 T6 F. d9 |: {parameter THRESHOLD=FRE_COF-1>>1; //除2操作 assign clkout=clkout1|clkout2; //相或
/ z$ C1 F8 U1 K; @
/ c/ f0 }. s3 } m5 Q3 Ialways @(posedge clk or negedge rst_n)begin //正沿触发
3 \& C0 A% q- S5 M0 X( j7 S if(!rst_n)
N5 y. Z; F* }* s4 l4 ] begin
8 j0 K. L* o1 R2 t% _ cnt1<=0;
% z7 h5 C5 v* M6 C1 c clkout1<=0;
& s/ G# h! B E3 _) a: Z end* {. ]8 z( d o% t! |" j; `
else begin
$ Y+ \5 g( I [ if(cnt1==STOP)
2 |3 Y' D9 G$ ^( `' U& ^8 q begin
. d _ e6 w. s: }6 m cnt1<=0;$ L" K2 w% U8 G, N% [
clkout1<=~clkout1;9 g3 y- c) T# j% Y% m0 V0 o/ Y
end
' |, j, q6 G; G1 v: L4 C% H else begin- i. @3 W4 A/ w3 x3 j+ H" k
cnt1<=cnt1+1;
8 H4 @( j& U" L X: H# t9 i if(cnt1==THRESHOLD)& d' A/ [ m. N9 v! n+ k8 b& `
clkout1<=~clkout1;
{* y+ q0 J! k; F else7 N- C3 q- x+ R, e' u- e* F; y
clkout1<=clkout1;
7 ]$ ]' A! j% n" y9 w4 e: S9 A end: \) W" A6 a6 l, \8 A4 k
end
. E y$ U: \1 ]- Q* W end always@(negedge clk or negedge rst_n)begin //负沿触发! D" o! o5 |; c5 _, Y
if(!rst_n)begin9 J0 E$ u1 C6 m( L
cnt2<=0;
% K a) {# |5 v6 ?. f/ Q, ?* @ clkout2<=0;+ p# @6 M/ t& c( z
end0 E/ ]. \0 ?7 n: B
else begin
' T) ?2 V$ x7 ~4 T- c1 I if(cnt2==STOP)
/ i, ]' b5 |* H$ ? begin$ X: P% g* v6 K7 h4 E: J. }8 h0 D- [: S
cnt2<=0; H# c) t6 v- C, J; Y
clkout2<=~clkout2;
( M: c% }% `6 Y1 j! J8 s$ c. K end
/ C; m; e/ L7 t5 }1 y else begin: k0 {, |/ `7 ^. M% U
cnt2<=cnt2+1;
0 g0 C5 A- f( A- G9 r/ @ if(cnt2==THRESHOLD)" i4 E" {" y) L+ f' r4 R, U) ?; S
clkout2<=~clkout2;
0 z& i! M) M& o+ L. i/ u! J# |$ Q else$ t R, k' ?# Z
clkout2<=clkout2;; c3 }8 ^9 O" p5 l0 C: Q" W
end( @/ X4 h0 W# L
end i0 I- j( }- L: `2 D) e
end endmodule |