任意分频 奇数偶数分频

任意分频的方法从网上看了有不少东西,主要有奇数分频,偶数分频,再就是任意分频。

  1、先说一下任意分频,任意分频的方法类似于DDS的产生方法,Fo/Fclk = fword / 2^N; N为计数器位宽,位宽越大,计数器越精确,

如果产生1_000_010Hz频率的信号,假设位宽是32位,时钟是50M,fword = 1_000_010 * 2^32 /50_000_000 = 85900204.913 四舍五入

fword为85900205;以2^31当作门限电压,当计数器小于2^32一半的时候,div_clk输出低电平,否则输出高电平,不过存在相位抖动的

情况,一般情况采用这种方法分频是ok的。

/*-----------------------------------------------------------------------

Date                :        2017--XX
Description            :        Design for LCD1602 Display.

-----------------------------------------------------------------------*/

module pro_clk
(
    //global clock
    input                    clk,            //system clock
    input                    rst_n,             //sync reset
    
    //XXX interface
    output        reg            div_clk       //

    
); 


//--------------------------------
//Funtion :       pinlv控制字
parameter        fword  =  32'd85900205;
reg        [31:0]    cnt;


always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        cnt <= 32'd0;
    else
        cnt <= cnt + fword;
end

//--------------------------------
//Funtion :       方波合成

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        div_clk <= 1'd0;
    else if(cnt < 32'h7fff_ffff)
        div_clk <= 1'd0;
    else
        div_clk <= 1'd1;
end

//--------------------------------
//Funtion :       检测上升沿
reg                div_clk_r;

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        div_clk_r <= 1'd0;
    else
        div_clk_r <= div_clk;
end

wire        div_value;
assign        div_value = (div_clk == 1'b1 && div_clk_r == 1'b0) ? 1'b1 : 1'b0;


endmodule
    

   2、偶数分频就是平常大家最常用的一种方法,比如进行N分频,N为偶数,那么通过计数器从0计数到N/2 - 1,输出时钟进行反转,这样最终输出的信号就是

N倍偶数分频了。

/*-----------------------------------------------------------------------

Date : 2017-07-29
Description : Design for 奇数分频.

-----------------------------------------------------------------------*/

module pro_clk
(
//global clock
input clk, //system clock
input rst_n, //sync reset

//div_clk interface
output div_clk //


);


//--------------------------------
//Funtion : counter1
parameter N = 32'd11;
reg [31:0] cnt;


always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 32'd0;
else if(cnt == N - 1'b1)
cnt <= 32'd0;
else
cnt <= cnt + 1'd1;
end
//--------------------------------
//Funtion : counter2
parameter N1 = 32'd11;
reg [31:0] cnt1;


always @(negedge clk or negedge rst_n)
begin
if(!rst_n)
cnt1 <= 32'd0;
else if(cnt1 == N1 - 1'b1)
cnt1 <= 32'd0;
else
cnt1<= cnt1 + 1'd1;
end

 

//--------------------------------
//Funtion : 方波合成
reg div_clk1;

always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
div_clk1 <= 1'd0;
else if(cnt == ((N >> 1'b1) - 1'b1))
div_clk1 <= 1'b0;
else if(cnt == N - 1'b1)
div_clk1 <= 1'b1;
end

//--------------------------------
//Funtion : 方波合成
reg div_clk2;

always @(negedge clk or negedge rst_n)
begin
if(!rst_n)
div_clk2 <= 1'd0;
else if(cnt1 == ((N1 >> 1'b1) - 1'b1))
div_clk2 <= 1'b0;
else if(cnt1 == N1 - 1'b1)
div_clk2 <= 1'b1;
end

//--------------------------------
//Funtion : 方波合成

assign div_clk = div_clk1 | div_clk2;

//--------------------------------
//Funtion : 检测上升沿
reg div_clk_r;

always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
div_clk_r <= 1'd0;
else
div_clk_r <= div_clk;
end

wire div_value;
assign div_value = (div_clk == 1'b1 && div_clk_r == 1'b0) ? 1'b1 : 1'b0;


endmodule

posted @ 2017-07-28 19:43  peng_blog  阅读(728)  评论(0编辑  收藏  举报