日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

從計(jì)數(shù)器到分頻電路(完結(jié))

 共同成長(zhǎng)888 2019-01-26

  本文介紹常見(jiàn)的電路——計(jì)數(shù)器,然后我們由計(jì)數(shù)器電路講解到分頻電路。


一、計(jì)數(shù)器


  (1)計(jì)數(shù)器代碼


  計(jì)數(shù)器,顧名思義就是在時(shí)鐘的節(jié)拍下進(jìn)行計(jì)數(shù),一個(gè)簡(jiǎn)單的N位計(jì)數(shù)器的代碼如下所示,這個(gè)計(jì)數(shù)器從0計(jì)數(shù)到2^N - 1(共計(jì)數(shù)了2^N個(gè)數(shù),也就是N位計(jì)數(shù)器):


復(fù)制代碼

 1 module count#(parameter N=8)(
 2 input clk,
 3 input clear,
 4 output[N-1:0] cnt_Q
 5 );
 6 reg[N-1:0] cnt;
 7 assign cnt_Q = cnt;
 8 
 9 always@(posedge clk)
10   if(clear)
11     cnt <= 'h0;      //同步清 0,高電平有效
12   else
13     cnt <= cnt+1'b1; //加法計(jì)數(shù)
14 
15 endmodule

復(fù)制代碼

上述描述的計(jì)數(shù)器通過(guò) clear 信號(hào)清除計(jì)數(shù)值,然后下一周期開始加 1 計(jì)數(shù);當(dāng)計(jì)數(shù)器計(jì)到能夠存儲(chǔ)的最大數(shù)值時(shí), 例如本例為 8 個(gè) 1,即 8'hff 就會(huì)自動(dòng)回到 0,然后開始下一輪計(jì)數(shù)。


綜合得帶的電路如下所示:



 


  (2)計(jì)數(shù)器改進(jìn)


  如果想要實(shí)現(xiàn) 0~k 范圍內(nèi)計(jì)數(shù),其中k ≠ 2^N ,可以將 always 語(yǔ)句修改為:


復(fù)制代碼

always@(posedge clk)
    if(clear)
        cnt <=  'h0;    //同步清 0,高電平有效
    else if(cnt==K)
        cnt <= 'h0;
    else
        cnt <= cnt+1'b1; //減法計(jì)數(shù)            

復(fù)制代碼

 


  


  前面是累加計(jì)數(shù),下面是一個(gè)既可以遞增也能遞減,且具備初始值裝載和復(fù)位的計(jì)數(shù)器,代碼如下所示:


復(fù)制代碼

 1 module updown_count#(parameter N=8)(
 2     input clk,
 3     input clear,
 4     input load,
 5     input up_down,
 6     input [N-1:0] preset_D,
 7     output[N-1:0] cnt_Q
 8 );
 9 reg[N-1:0] cnt;
10 assign cnt_Q = cnt;
11 
12 always@(posedge clk)
13   if(clear)
14     cnt <= 'h0;      //同步清 0,高電平有效
15   else if(load)
16     cnt <= preset_D; //同步預(yù)置
17   else if(up_down)
18     cnt <= cnt+1;    //加法計(jì)數(shù)
19   else
20     cnt <= cnt-1;    //減法計(jì)數(shù)
21 
22 endmodule

復(fù)制代碼

 


 


 


二、計(jì)數(shù)器的用途


 ?。?)基本的計(jì)數(shù)功能與分頻


  計(jì)數(shù)器的基本功能顧名思義就是計(jì)數(shù)了,用來(lái)計(jì)數(shù),產(chǎn)生某個(gè)信號(hào)等等。利用這個(gè)功能,可以實(shí)現(xiàn)信號(hào)的分頻,具體會(huì)在后面的分頻電路中進(jìn)行描述。


 ?。?)看門狗


  計(jì)數(shù)器其實(shí)就可以設(shè)計(jì)成看門狗。在初始狀態(tài)時(shí),看門狗電路首先裝載一個(gè)大數(shù);當(dāng)狀態(tài)機(jī)或者程序開始運(yùn)行后,看門狗開始倒計(jì)數(shù)。如果狀態(tài)機(jī)或程序運(yùn)行正常,每隔一段時(shí)間應(yīng)發(fā)出指令或信號(hào)讓看門狗重新裝載一個(gè)大的初始值,并再次開始倒計(jì)數(shù)。如果看門狗減到 0 就認(rèn)為程序或狀態(tài)機(jī)沒(méi)有正常工作,就需要強(qiáng)制整個(gè)系統(tǒng)復(fù)位。


  上面的第二處改進(jìn)的計(jì)數(shù)器電路描述就是一個(gè)看門狗電路,只要加上 cnt==0 作為看門復(fù)位狀態(tài)即可;而 load 信號(hào)則是狀態(tài)機(jī)或軟件給出的喂狗動(dòng)作。


 ?。?)特殊的有限狀態(tài)機(jī)


  當(dāng)狀態(tài)機(jī)要求沒(méi)有那么嚴(yán)格的時(shí)候,這個(gè)時(shí)候就可以用計(jì)數(shù)器的計(jì)數(shù)值當(dāng)做狀態(tài)機(jī)的狀態(tài),計(jì)數(shù)增加或者減少就是改變狀態(tài)。


 


 


三、分頻電路


  (1)簡(jiǎn)單的計(jì)數(shù)器


  計(jì)數(shù)器實(shí)質(zhì)是對(duì)輸入的驅(qū)動(dòng)時(shí)鐘進(jìn)行計(jì)數(shù),所以計(jì)數(shù)器在某種意義上講,等同于對(duì)時(shí)鐘進(jìn)行分頻。例如一個(gè)最大計(jì)數(shù)長(zhǎng)度為N=2^n(從0計(jì)數(shù)到N-1)的計(jì)數(shù)器,也就是寄存器位數(shù)位n,那么寄存器最高位的輸出為N=2^n分頻,次高位為N/2分頻...例如下面的代碼:


復(fù)制代碼

 1 module test#(parameter N=3)(
 2 input clk,
 3 input rst_n,
 4 output clk_div
 5 );
 6 
 7 reg [N-1:0] div_reg        ;//分頻計(jì)數(shù)器
 8 always @(posedge clk or negedge rst_n)
 9     if (rst_n == 1'b0 )
10         div_reg    <= 0 ;
11     else 
12         div_reg    <= div_reg + 1'b1 ;
13 
14 assign clk_div = div_reg[N-1] ;
15 
16 
17 endmodule

復(fù)制代碼

 該代碼描述的將一個(gè)3位的計(jì)數(shù)器最高位輸出,也就是計(jì)數(shù)長(zhǎng)度為8(計(jì)數(shù)從0~7)波形如下所示:


    


可以看到最高位的輸出為輸入時(shí)鐘的8分頻。


 


  當(dāng)N不是2的整數(shù)次冪時(shí),即N≠2^n時(shí),從0計(jì)數(shù)到N-1,其最高位作為時(shí)鐘輸出(占空比不一定為 1:1)是輸入時(shí)鐘的1/N,也就是N分頻。我們來(lái)舉個(gè)例子,比如最大計(jì)數(shù)長(zhǎng)度為5的計(jì)數(shù)器,即從0計(jì)數(shù)到4后又返回0,那么需要定義一個(gè)三位的寄存器。寄存器的計(jì)數(shù)過(guò)程為:


  000-001-010-011-100-000-001-010-011-100-000-001-010-011-100-000-001-010-011-100······


我們?nèi)∽罡呶?,得到的信?hào)變化就是:


  0-0-0-0-1-0-0-0-0-0-1-0-0-0-0-1-0-0-0-0-1···


 代碼如下所示:


復(fù)制代碼

 1 module test#(parameter N=3)(
 2 input clk,
 3 input rst_n,
 4 output clk_div
 5 );
 6 
 7 reg [N-1:0] div_reg        ;//分頻計(jì)數(shù)器
 8 always @(posedge clk or negedge rst_n)
 9     if (rst_n == 1'b0 )
10         div_reg    <= 0 ;
11     else if(div_reg == 3'd4)//從0計(jì)數(shù)到4,然后返回到0,5分頻
12         div_reg    <= 0;
13     else
14         div_reg    <= div_reg + 1'b1 ;
15 
16 assign clk_div = div_reg[N-1] ;
17 
18 
19 endmodule

復(fù)制代碼

 


仿真波形如下所示:


      


由此可以看到,每一個(gè)分頻后的時(shí)鐘周期=5倍原來(lái)的時(shí)鐘周期,因此是5分頻。


 


  那么這個(gè)情況是不是也可以包含第一種情況呢?我們那設(shè)置為8分頻看看,即前面的3'd4改成3'd7,得到的仿真波形如下所示:


      


可以看到,計(jì)數(shù)器的最高位輸出也是輸入頻率的1/N。


 


 因此我們得到結(jié)論一個(gè)最大計(jì)數(shù)長(zhǎng)度為N(從0計(jì)數(shù)到N-1)的計(jì)數(shù)器,其最高位的輸出,是輸入頻率的N分頻。


  通常 ASIC 和 FPGA 中,時(shí)鐘都是全局信號(hào),都需要通過(guò) PLL 處理才能使用,但某些簡(jiǎn)易場(chǎng)合,采用計(jì)數(shù)器輸出時(shí)鐘也是能夠使用的,只是需要注意時(shí)序約束。


 


  (2)偶數(shù)倍分頻(占空比50%)


   偶數(shù)分頻,也就是2分頻、4分頻、6分頻...這個(gè)還是比較簡(jiǎn)單的,N(N當(dāng)然是2的倍數(shù))分頻,那么計(jì)數(shù)到N/2-1,然后時(shí)鐘翻轉(zhuǎn)


 例如N=6時(shí),代碼如下所示:


復(fù)制代碼

 1 module test#(parameter N=6)(
 2 input clk,
 3 input rst_n,
 4 output clk_div
 5 );
 6 reg div_reg ;
 7 reg [N-1:0] div_cnt        ;//分頻計(jì)數(shù)器
 8 always @(posedge clk or negedge rst_n)
 9     if (rst_n == 1'b0 )begin
10         div_cnt    <= 0 ;
11         div_reg    <= 0 ;
12     end 
13     else if(div_cnt == (N/2 - 1))begin
14         div_cnt    <= 0;
15         div_reg    <= ~div_reg ;
16     end 
17     else
18         div_cnt    <= div_cnt + 1'b1 ;
19 
20 assign clk_div = div_reg ;

復(fù)制代碼

仿真波形如下所示:


      


當(dāng)N=2的仿真波形如下所示:


        


 


 


 


  (3)奇數(shù)倍分頻


    ①占空比接近50%


   對(duì)于占空比不是50%的計(jì)數(shù)分頻,我們可以直接用上面的計(jì)數(shù)器方法,這里就不說(shuō)了,我們介紹其他接近50%的占空比的方法,比如下面使用的狀態(tài)機(jī)分頻:


      


上圖的狀態(tài)機(jī)除了用一般的狀態(tài)機(jī)設(shè)計(jì)方式之外,我們也可以用簡(jiǎn)單的計(jì)數(shù)器實(shí)現(xiàn),這種方法如下所示:


  假設(shè)時(shí)鐘分頻是N,則設(shè)置一個(gè)計(jì)數(shù)器,計(jì)數(shù)長(zhǎng)度是N(即從0計(jì)數(shù)到N-1),然后在計(jì)數(shù)器為計(jì)數(shù)到(N-1)/2的時(shí)候,翻轉(zhuǎn)一下分頻時(shí)鐘信號(hào);在計(jì)數(shù)器計(jì)數(shù)到為N-1的時(shí)候,再翻轉(zhuǎn)一下時(shí)鐘。


代碼如下所示:


復(fù)制代碼

 1 module test#(parameter N=3)(//N分頻,這里是3分頻
 2 input clk,
 3 input rst_n,
 4 output clk_div
 5 );
 6 
 7 reg [N-1:0] div_cnt        ;//分頻計(jì)數(shù)器
 8 reg div_reg ;
 9 always @(posedge clk or negedge rst_n)begin
10     if (rst_n == 1'b0 )begin
11         div_cnt    <= 0 ;
12         div_reg        <= 1 ;
13     end else if (div_cnt == (N-1)/2)begin//計(jì)數(shù)到(N-1)/2,進(jìn)行翻轉(zhuǎn)和繼續(xù)計(jì)數(shù)
14         div_reg        <= ~div_reg;
15         div_cnt    <= div_cnt + 1'b1 ;
16     end else if ( div_cnt == (N-1) )begin//計(jì)數(shù)到N-1,進(jìn)行清零和翻轉(zhuǎn)
17         div_cnt        <= 0 ;
18         div_reg        <= ~div_reg;
19     end else 
20         div_cnt    <= div_cnt + 1'b1 ;
21         
22 end         
23 assign clk_div = (N == 1)?clk:div_reg ;//注意這里
24 
25 
26 endmodule

復(fù)制代碼

代碼中我們需要注意,在N= 1的情況,也就是不分頻的情況。仿真電路如下圖所示:


3分頻,N = 3:


      


5分頻,N= 5 :


         


 


不分頻,即N=1的仿真如下所示:


      


 


    ②占空比50%


      產(chǎn)生具有50%占空比的奇數(shù)分頻時(shí)鐘的算法如下所示,假設(shè)N分頻(N是計(jì)數(shù)):


  設(shè)置一個(gè)計(jì)數(shù)長(zhǎng)度為N的上升沿計(jì)數(shù)器,和一個(gè)信號(hào)寄存器;信號(hào)寄存器在上升沿計(jì)數(shù)器為(N-1)/2的時(shí)候進(jìn)行翻轉(zhuǎn),然后再在計(jì)數(shù)到N-1的時(shí)候進(jìn)行翻轉(zhuǎn)(這里相當(dāng)于得到一個(gè)N分頻信號(hào)A)。


  再設(shè)置一個(gè)計(jì)數(shù)長(zhǎng)度為N的下降沿計(jì)數(shù)器,和另一個(gè)信號(hào)寄存器;信號(hào)寄存器在下降沿計(jì)數(shù)器為(N-1)/2的時(shí)候進(jìn)行翻轉(zhuǎn),然后再在計(jì)數(shù)到N-1的時(shí)候進(jìn)行翻轉(zhuǎn)(這里相當(dāng)于得到一個(gè)N分頻信號(hào)B)。


  將A和B相或就可以得到占空比50%的奇數(shù)分頻信號(hào);代碼實(shí)現(xiàn)如下:


復(fù)制代碼

 1 module test#(parameter N=5)(//N分頻
 2 input clk,
 3 input rst_n,
 4 output clk_div
 5 );
 6 
 7 reg sig_r ;//定義一個(gè)上升沿翻轉(zhuǎn)的信號(hào)
 8 reg sig_f ;//定義一個(gè)下降沿翻轉(zhuǎn)的信號(hào)
 9 reg [N-1:0]    cnt_r;//上升沿計(jì)數(shù)器
10 reg [N-1:0]    cnt_f;//下降沿計(jì)數(shù)器
11 
12 wire clk_f ;
13 assign clk_f = ~clk ;//用來(lái)觸發(fā)下降沿計(jì)數(shù)器的時(shí)鐘
14                     //由于同時(shí)使用上升沿和下降沿觸發(fā)器不好,因此我們?yōu)橥贿呇?,都使用上升沿觸發(fā)
15                     //只不過(guò)是將時(shí)鐘進(jìn)行反向
16                     
17 always @(posedge clk or negedge rst_n)begin//上升沿計(jì)數(shù)
18     if(rst_n == 1'b0)begin
19         sig_r    <= 0 ;
20         cnt_r    <= 0 ;
21     end else if( cnt_r == (N-1)/2 )begin
22         sig_r    <= ~sig_r ;
23         cnt_r    <= cnt_r + 1 ;
24     end else if ( cnt_r == (N-1) )begin
25         sig_r    <= ~sig_r ;
26         cnt_r    <= 0 ;
27     end else 
28         cnt_r    <= cnt_r + 1 ;
29 end                     
30 
31 always @(posedge clk_f or negedge rst_n)begin//下降沿計(jì)數(shù)
32     if(rst_n == 1'b0)begin
33         sig_f    <= 0 ;
34         cnt_f    <= 0 ;
35     end else if( cnt_f == (N-1)/2 )begin
36         sig_f    <= ~sig_f ;
37         cnt_f    <= cnt_f + 1 ;
38     end else if ( cnt_f == (N-1) )begin
39         sig_f    <= ~sig_f ;
40         cnt_f    <= 0 ;
41     end else 
42         cnt_f    <= cnt_f + 1 ;
43 end 
44 
45 assign clk_div = sig_f || sig_r ;
46                     
47 endmodule

復(fù)制代碼

 


仿真波形如下所示:


3分頻:


  


5分頻:


    


 


 


 


 ?。?)任意整數(shù)倍分頻(接近50%)


  在前面中,我們知道了一個(gè)最大計(jì)數(shù)長(zhǎng)度為N(從0計(jì)數(shù)到N-1)的計(jì)數(shù)器,其最高位的輸出,是輸入頻率的N分頻,因此最簡(jiǎn)單的任意分頻電路就是設(shè)計(jì)一個(gè)計(jì)數(shù)器,然后最高位輸出就是分頻的頻率了。雖然這這種方法很簡(jiǎn)單,但是很顯然,這種方法的占空比是很糟糕的。因此我們要用其他的方法,也就是用其他的組合方式。


   ①占空比接近50%任意整數(shù)分頻


  這種方法是取自偶數(shù)分頻和奇數(shù)分頻里面的接近50%占空比,實(shí)現(xiàn)的代碼如下所示:


復(fù)制代碼

 1 module test #( parameter cfactor= 5)(
 2   input clk,
 3   input rst_n,
 4   output clk_div
 5 );
 6 reg clk_loc;
 7 //reg [15:0] cnt;//allowed maximum clock division factor is 65536
 8 reg [7:0] cnt;//allowed maximum clock division factor is 256
 9 
10 assign clk_div = (cfactor==1)? clk : clk_loc;
11 //assign clk_div = ((rst==1) || (cfactor==1))? clk : clk_loc;
12 
13 always@(posedge clk or negedge rst_n)
14   if(!rst_n)begin
15     cnt <= 'd0;
16     clk_loc = 1;
17   end
18   else begin
19     cnt <= cnt + 1'b1;
20     if(cnt==cfactor/2-1)
21       clk_loc = 0;
22     else if(cnt==cfactor-1) begin
23       cnt <= 'd0;
24       clk_loc = 1;
25     end
26   end
27 
28 endmodule

復(fù)制代碼

 


2分頻的仿真圖,如下所示:


    


5分頻的仿真波形如下所示:


    


 


 


    ②占空比50%的任意整數(shù)分頻(重點(diǎn))


    這種方法是取自偶數(shù)分頻和奇數(shù)分頻都是50%占空比的組合,代碼如下所示:


復(fù)制代碼

 1 module test#(parameter N=1)(//N分頻
 2 input clk,
 3 input rst_n,
 4 output clk_div
 5 );
 6 
 7 //奇數(shù)分頻
 8 reg sig_r ;//定義一個(gè)上升沿翻轉(zhuǎn)的信號(hào)
 9 reg sig_f ;//定義一個(gè)下降沿翻轉(zhuǎn)的信號(hào)
10 reg [N-1:0]    cnt_r;//上升沿計(jì)數(shù)器
11 reg [N-1:0]    cnt_f;//下降沿計(jì)數(shù)器
12 
13 wire clk_f ;
14 assign clk_f = ~clk ;//用來(lái)觸發(fā)下降沿計(jì)數(shù)器的時(shí)鐘
15                     //由于同時(shí)使用上升沿和下降沿觸發(fā)器不好,因此我們?yōu)橥贿呇?,都使用上升沿觸發(fā)
16                     //只不過(guò)是將時(shí)鐘進(jìn)行反向
17                     
18 always @(posedge clk or negedge rst_n)begin//上升沿計(jì)數(shù)
19     if(rst_n == 1'b0)begin
20         sig_r    <= 0 ;
21         cnt_r    <= 0 ;
22     end 
23     else begin
24         cnt_r    <= cnt_r + 1 ;
25         if( cnt_r == (N-1)/2 )begin
26             sig_r    <= ~sig_r ;
27         end else if ( cnt_r == (N-1) )begin
28             sig_r    <= ~sig_r ;
29             cnt_r    <= 0 ;
30         end 
31     end 
32 end                     
33 
34 always @(posedge clk_f or negedge rst_n)begin//下降沿計(jì)數(shù)
35     if(rst_n == 1'b0)begin
36         sig_f    <= 0 ;
37         cnt_f    <= 0 ;
38     end 
39     else begin
40         cnt_f    <= cnt_f + 1 ;
41         if( cnt_f == (N-1)/2 )begin
42             sig_f    <= ~sig_f ;
43         end else if ( cnt_f == (N-1) )begin
44             sig_f    <= ~sig_f ;
45             cnt_f    <= 0 ;
46         end 
47     end     
48 end 
49 
50 //偶數(shù)分頻
51 reg div_reg ;
52 reg [N-1:0] div_cnt        ;//分頻計(jì)數(shù)器
53 always @(posedge clk or negedge rst_n)begin
54     if (rst_n == 1'b0 )begin
55         div_cnt    <= 0 ;
56         div_reg    <= 0 ;
57     end 
58     else begin
59         div_cnt    <= div_cnt + 1'b1 ;
60         if(div_cnt == (N/2 - 1))begin
61             div_cnt    <= 0;
62             div_reg    <= ~div_reg ;
63         end 
64     end
65 end        
66 assign clk_div = (N == 1)?clk:
67                 ( N%2 == 1)?(sig_f || sig_r ): div_reg;//這里用來(lái)輸出分頻值。對(duì)2的取余操作是綜合的
68                     
69 endmodule 

復(fù)制代碼

 


仿真波形如下所示:


5分頻:


    


6分頻:


      


 


   


 總結(jié):本文介紹了計(jì)數(shù)器及其功能,主要是介紹了作為分頻器的功能。對(duì)于分頻器,如下所示:


          


 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多