在通常的学习中,或者一些网络课程当中,总会强调使用PLLIP核出来的时钟。但是在实际中并非所有的逻辑都是有那么高的逻辑要求。通过语言进行时钟的分频相移显得十分方便,这种方法可以节省芯片内部的锁相环资源,再者,通过语言设计进行时钟分频,可以锻炼我们对verilog的熟练和理解程度。这里主要讲解奇数倍分频。

奇数倍分频:
  如果不要求占空比为50%的话,也比较容易实现,如进行三分频,通过待分频时钟上升沿触发计数器进行模三计数,当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。即在计数值在邻近的1和2进行了两次翻转。这样实现的三分频占空比为1/3或者2/3。

奇数倍分频操作步骤:
  对于实现占空比为50%的N倍奇数分频,我们可以分解为两个通道:
  第一个通道:  

    第一步:上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,
         第二步:然后经过(N-1)/2再次进行翻转得到一个占空比为非50%奇数N分频时钟;
   第一个通道:

     第一步:下降沿触发进行模N计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟时钟翻转。
      第一步:同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数N分频时钟。
              最后输出:将这两个占空比非50%的N分频时钟或运算,得到占空比为50%的奇数n分频时钟。


具体例子:5分频等占空比,可以通过待分频时钟下降沿和上升沿触发0~4计数,
  ①对于待分频时钟的上升沿,当计数器cnt1计数到1时,
clk_p翻转;当计数器计数到3(1 + (5 - 1) / 2 = 3)时,clk_p再次反转;
  ②对于待分频时钟的下降沿,当计数器cnt2计数到1时,
clk_n翻转;当计数器计数到3(1 + (5 - 1) / 2 = 3)时,clk_n再次反转;
  ③然后下降沿产生的5分频时钟和上升沿产生的5分频时钟进行或运算,
即可得到占空比为50%的N分频时钟。

例程:实现三分频,占空比50%

 1 // *********************************************************************************
 2 // Project Name : 
 3 // weixin       : li15226499835
 4 // Website      : https://www.cnblogs.com/lgy-gdeu/
 5 // Create Time  : 2020// 
 6 // File Name    : .v
 7 // Module Name  : 
 8 // Abstract     :
 9 // editor        : sublime text 3
10 // *********************************************************************************
11 // Modification History:
12 // Date         By              Version                 Change Description
13 // -----------------------------------------------------------------------
14 // 2020//          Liguoyong           1.0                     Original
15 //  
16 // *********************************************************************************
17 `timescale      1ns/1ns
18 module three_clock_divide (
19     //system signals
20     input            wire                 sclk    , 
21     input            wire                 s_rst_n    ,
22     //out  div_three_clock
23     output          wire                div_three_clock
24 
25 );
26 
27 //========================================================================\
28 // =========== Define Parameter and Internal signals =========== 
29 //========================================================================/
30 reg         [1:0]       cnt_1        ;
31 reg            [1:0]        cnt_2         ;
32 reg                     clk_p        ;
33 reg                        clk_n          ;
34 
35 //=============================================================================
36 //****************************     Main Code    *******************************
37 //=============================================================================
38 
39 //cnt_1
40 always @(posedge sclk or negedge s_rst_n)begin
41     if(!s_rst_n)
42         cnt_1 <= 0;
43     else if(cnt_1 == 2'b10)
44         cnt_1 <=  0;
45     else 
46         cnt_1 <= cnt_1  + 1'b1 ;
47                  
48 end
49 
50 //cnt_2
51 always @(negedge sclk or negedge s_rst_n)begin
52     if(!s_rst_n)
53         cnt_2   <=    0 ;
54     else if(cnt_2 == 2'b10)    
55         cnt_2    <=  0 ;
56     else
57         cnt_2    <=  cnt_2 + 1'b1 ;    
58 end
59 
60 //clk_p
61 always @(posedge sclk or negedge s_rst_n)begin
62     if(!s_rst_n)
63         clk_p  <=  1'b0;
64     else if(cnt_1== 2'b01)
65         clk_p  <=  ~clk_p;
66     else if(cnt_1==2'b10)
67         clk_p  <=  ~clk_p;
68     else 
69         clk_p   <=  clk_p;    
70                 
71 end   
72 
73 //clk_n
74 always @(negedge sclk or negedge s_rst_n)begin
75     if(!s_rst_n)
76         clk_n  <=  0 ;
77     else if(cnt_2 == 2'b01)    
78         clk_n  <=  ~clk_n ;
79     else if(cnt_2 == 2'b10)    
80         clk_n  <=  ~clk_n ;
81     else 
82         clk_n  <=  clk_n;
83             
84 end
85 assign div_three_clock =   clk_p | clk_n;
86 
87 endmodule

测试激励:

 1 // *********************************************************************************
 2 // Project Name : 
 3 // weixin       : li15226499835
 4 // Website      : https://www.cnblogs.com/lgy-gdeu/
 5 // Create Time  : 2020// 
 6 // File Name    : .v
 7 // Module Name  : 
 8 // Abstract     :
 9 // editor        : sublime text 3
10 // *********************************************************************************
11 // Modification History:
12 // Date         By              Version                 Change Description
13 // -----------------------------------------------------------------------
14 // 2020//          Liguoyong           1.0                     Original
15 //  
16 // *********************************************************************************
17 `timescale      1ns/1ns
18 
19 module  tb_three_clock_div ();
20   
21 reg        tb_sclk         ;
22 reg        tb_s_rst_n   ;
23 wire       o_clk        ;
24 
25 initial begin
26     tb_sclk    =   1'b1 ;
27     tb_s_rst_n<=   1'b0 ;
28     #100
29     tb_s_rst_n<=   1'b1 ;
30     #10000
31     $finish;
32 end 
33 always #20  tb_sclk = ~tb_sclk ;
34 
35 
36 //例化
37 three_clock_divide three_clock_divide_inst(
38     //system signals
39     .sclk                    (tb_sclk), 
40     .s_rst_n                (tb_s_rst_n),
41     //out  div_three_clock
42     .div_three_clock        (o_clk)
43 
44 );
45 
46 endmodule

仿真: