verilog 语言实现任意分频

1、偶分频

偶分频比较简单,假设为N分频,只需计数到N/2-1,然后时钟翻转、计数清零,如此循环就可以得到N(偶)分频。代码如下。

module fp_even(clk_in,rst_n,clk_out);
    input clk_in;
    input rst_n;
    output clk_out;

    reg [1:0] cnt;
    reg clk_out;
    parameter N=6;

    always @ (posedge clk_in or negedge rst_n) begin
        if(!rst_n)    begin
            cnt <= 0;
            clk_out <= 0;
        end
        else begin
        if(cnt==N/2-1) begin 
            clk_out <= !clk_out; 
            cnt<=0; 
        end
        else
            cnt <= cnt + 1;
        end
end

endmodule

2 、奇分频

 实现奇数(N)分频,分别用上升沿计数到(N-1)/2,再计数到N-1;用下降沿计数到(N-1)/2,再计数到N-1,得到两个波形,然后把它们相或即可得到N分频。代码如下:

module fp_odd(clk_in,rst_n,clk_out);

    input  clk_in,rst_n;
    output clk_out;
 
    reg [2:0] cnt_p,cnt_n;
    reg clk_p,clk_n;
    parameter N=7;
 
    always @ (posedge clk_in or negedge rst_n) begin
        if(!rst_n)     
            cnt_p <= 0;
      else if(cnt_p==N-1)    
            cnt_p <=0;
        else 
            cnt_p <= cnt_p + 1;
    end
    
    always @ (posedge clk_in or negedge rst_n) begin
        if(!rst_n) 
            clk_p <= 0;
        else if(cnt_p==(N-1)/2)
            clk_p <= !clk_p;
        else if(cnt_p==N-1)
            clk_p <= !clk_p;
    end

    always @ (negedge clk_in or negedge rst_n) begin
        if(!rst_n)     
            cnt_n <= 0;
        else if(cnt_n==N-1)    
            cnt_n <=0;
        else 
            cnt_n <= cnt_n + 1;
    end

    always @ (negedge clk_in or negedge rst_n) begin
        if(!rst_n) 
            clk_n <= 0;
        else if(cnt_n==(N-1)/2)
            clk_n <= !clk_n;
        else if(cnt_n==N-1)
            clk_n <= !clk_n;
    end

    assign clk_out = clk_p | clk_n;

endmodule

3 、任意占空比的任意分频

在verilog程序设计中,我们往往要对一个频率进行任意分频,而且占空比也有一定的要求这样的话,对于程序有一定的要求,现在在前面两个实验的基础上做一个简单的总结,实现对一个频率的任意占空比的任意分频。

比如: FPGA系统时钟是50M Hz,而我们要产生的频率是880Hz,那么,我们需要对系统时钟进行分频。很容易想到用计数的方式来分频:50000000/880 = 56818。显然这个数字不是2的整幂次方,那么我们可以设定一个参数,让它到56818的时候重新计数就可以实现了。程序如下:

module div(clk, clk_div);

input clk;

output clk_div;

reg [15:0] counter;

always @(posedge clk)

if(counter==56817) counter <= 0;

else counter <= counter+1;

assign clk_div = counter[15];

endmodule

分频的应用很广泛,一般的做法是先用高频时钟计数,然后使用计数器的某一位输出作为工作时钟进行其他的逻辑设计,上面的程序就是一个体现。

下面我们来算一下它的占空比:我们清楚地知道,这个输出波形在counter为0到32767的时候为低,在32768到56817的时候为高,占空比为40%多一些,如果我们需要占空比为50%,那么我们需要再设定一个参数,使它为56817的一半,使达到它的时候波形翻转,就可以实现结果了。程序如下:

module div(clk, clk_div);

input clk;

output clk_div;

reg [14:0] counter;

always @(posedge clk)

if(counter==28408) counter <= 0;

else counter <= counter+1;

reg clk_div;

always @(posedge clk)

       if(counter==28408) clk_div <= ~clk_div;

endmodule

继续让我们来看如何实现任意占空比,比如还是由50 M分频产生880Hz,而分频得到的信号的占空比为30%。

56818×30%=17045

module div(clk,reset,clk_div,counter);

input clk,reset;

output clk_div;

output [15:0] counter;

reg [15:0] counter;

reg clk_div;

always @(posedge clk)

if(!reset) counter <= 0;

else if(counter==56817) counter <= 0;

else counter <= counter+1;

always @(posedge clk)

if(!reset) clk_div <= 0;

else if(counter<17045) clk_div <= 1;

else clk_div <= 0;

endmodule

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值