在fpga如何实现任意分频呢?

偶数分频比较简单,而比较困难的是奇数分频。请看下图:

 

 

 

   如上图所示是三分频的分析图,黑色的为两路时钟,相位差180°,可以取反获得其中的任意一路,最终的蓝色波形是输出波形,紫色的是计数器,假设计数3个也就是0  1  2,两个红色框是计数器表示2,黄色框其实就是我们需要的半个时钟,只要将两个红色框中的信号或起来就可以实现奇分频了,其他奇分频类似。代码如下:

module fenpin
#(parameter YINZI = 8)
(
    input  clk_p ,
    input     clk_n ,
    input  aclr,
    input [YINZI-1:0]  fenpin,
    output reg out_clk
);

reg [YINZI-1:0] cnt,cnt_n;
reg flag_a,flag_b;

//assign clk_n =!clk_p;

always @(posedge clk_p,negedge aclr)
    if(!aclr)
        cnt <= 0;
    else if(cnt==fenpin-1)
        cnt <= 0;
    else    
        cnt <= cnt+1;

always @(posedge clk_p,negedge aclr)
    if(!aclr)
        flag_a <= 0;
    else if(cnt==fenpin-1)
        flag_a <= 0;
    else if(cnt==fenpin[YINZI-1:1]+fenpin[0]-1)    
        flag_a <= 1;    

always @(posedge clk_n,negedge aclr)
    if(!aclr)
        cnt_n <= 0;
    else if(cnt_n==fenpin-1)
        cnt_n <= 0;
    else    
        cnt_n <= cnt+1;

always @(posedge clk_n,negedge aclr)
    if(!aclr)
        flag_b <= 0;
    else if(cnt_n==fenpin-1)
        flag_b <= 0;
    else if(cnt_n==fenpin[YINZI-1:1]+fenpin[0]-1)    
        flag_b <= 1;    
                
        //output
        
always @( * )
    if(fenpin[0]==1) //奇数
        out_clk = flag_a | flag_b;
    else
        out_clk = flag_a;    
        
        
    endmodule    

 

 

 

仿真代码如下:

`timescale 1 ns / 1 ns

module fenpin_tb;

parameter PERIOD = 10;

    reg  clk_p ;
    wire     clk_n ;
    reg  aclr;
    reg [7:0]  fenpin;
    wire out_clk;


fenpin        fenpin_u0(
    .clk_p         (clk_p     ),
    .clk_n         (clk_n     ),
    .aclr            (aclr        ),
    .fenpin        (fenpin    ),
    .out_clk  (out_clk)
);

always begin
    clk_p = 0;
    #PERIOD;
    clk_p = 1;
    #PERIOD;
end

assign clk_n = !clk_p;

initial begin
    #2;
    aclr = 0;
    fenpin = 5;
    #(10*PERIOD);
    aclr = 1;
end


endmodule

 

仿真图:

 

 

如上图所示,是五分频的仿真图,高低电平各位2.5个clk。欢迎大家一起交流,Q群:912014800。

posted on 2019-12-11 21:20  洋葱洋葱  阅读(1076)  评论(0编辑  收藏  举报