【常用電路】奇數/偶數分頻電路


一、偶數分頻電路

  偶數倍分頻是最簡單的一種分頻模式,完全可通過計數器計數實現。

 1 //////////////////////////////////////////////////////////////////////////////////
 2 // 偶數分頻電路
 3 // 這個分頻模塊適用於待分頻時鍾和目標時鍾的頻率呈整倍數關系
 4 // 通過改變cnt_values確定是N分頻,cnt_values應該等於N/2-1,以16分頻為例,cnt_values=7;
 5 
 6 module clk_div_even(
 7     clk_in,
 8     reset,
 9     clk_out
10     );
11     
12 input       clk_in;
13 input       reset;
14 output      clk_out;
15 
16 reg             clk_out;
17 reg    [15:0]   cnt;
18 
19 parameter       cnt_values = 'd7;
20 
21 always @ ( posedge clk_in ) begin
22     if ( reset ) begin
23         cnt <= 16'b0;
24         clk_out <= 1'b0;
25         end
26     else if ( cnt == cnt_values ) begin
27         cnt <= 16'b0;
28         clk_out <= ~clk_out;
29         end
30     else begin
31         cnt <= cnt + 1'b1;
32         clk_out <= clk_out;
33         end
34     end
35         
36 endmodule

 

二、奇數分頻電路

  相較於偶數倍分頻,奇數倍分頻要復雜一些。奇數倍分頻有多種方法,下面介紹錯位“異或”法。

 1 //////////////////////////////////////////////////////////////////////////////////
 2 // 奇數分頻電路
 3 // 這個分頻模塊適用於待分頻時鍾和目標時鍾的頻率呈整倍奇數關系
 4 // 通過相或運算實現50%占空比的奇數N分頻,N=cnt_values;
 5 
 6 module clk_div_odd(
 7     clk_in,
 8     reset,
 9     clk_out
10     );
11     
12 input       clk_in;
13 input       reset;
14 output      clk_out;
15 
16 reg    [15:0]   cnt_p, cnt_n;
17 reg    [15:0]   cnt_values = 'd3;
18 reg             clk_p, clk_n;
19 
20 always @ ( posedge clk_in ) begin
21     if ( reset ) begin
22         cnt_p <= 16'b0;
23         clk_p <= 1'b0;
24         end
25     else if ( cnt_p == 16'b0 ) begin
26         cnt_p <= cnt_p + 16'b1;
27         //cnt_p <= 16'b0;
28         clk_p <= ~clk_p;
29         end
30         
31     else if ( cnt_p == (cnt_values - 16'b1)/2 ) begin
32         cnt_p <= cnt_p + 16'b1;
33         //cnt_p <= 16'b0;
34         clk_p <= ~clk_p;
35         end
36     else if ( cnt_p == (cnt_values - 16'b1))begin
37         cnt_p <= 16'b0;
38         //cnt_p <= cnt_p + 16'b1;
39         clk_p <= clk_p;
40         end
41     else begin
42         cnt_p <= cnt_p + 16'b1;
43         clk_p <= clk_p;
44         end
45     end
46         
47 
48 always @ ( negedge clk_in ) begin
49     if ( reset ) begin
50         cnt_n <= 16'b0;
51         clk_n <= 1'b0;
52         end
53     else if ( cnt_n == 16'b0 ) begin
54         cnt_n <= cnt_n + 16'b1;
55         //cnt_p <= 16'b0;
56         clk_n <= ~clk_n;
57         end
58     else if ( cnt_n == (cnt_values - 16'b1)/2 ) begin
59         cnt_n <= cnt_n + 16'b1;
60         //cnt_p <= 16'b0;
61         clk_n <= ~clk_n;
62         end
63     else if ( cnt_n == (cnt_values - 16'b1))begin
64         cnt_n <= 16'b0;
65         //cnt_p <= cnt_p + 16'b1;
66         clk_n <= clk_n;
67         end
68     else begin
69         cnt_n <= cnt_n + 16'b1;
70         clk_n <= clk_n;
71         end
72     end
73 
74 
75 assign clk_out = clk_p | clk_n;         //兩個占空比非50%的時鍾相或之后,得到占空比50%的時鍾
76     
77 endmodule

 

三、仿真

附上tb文件

 1 module odd_sim;
 2 
 3 
 4 reg     clk_in;
 5 reg     reset;
 6 wire    clk_out;
 7 
 8 initial
 9 begin
10     clk_in = 1'b0;
11     reset = 1'b1;
12     
13     #1000
14     reset = 1'b0;
15     
16 end
17 
18 always #50 clk_in = ~clk_in;       //給時鍾激勵,即50ns翻轉一次,10MHz
19 
20 clk_div_odd        odd_sim(
21     .clk_in         (clk_in),
22     .reset          (reset),
23     .clk_out        (clk_out)          
24 );
25 endmodule

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM