我是靠谱客的博主 调皮信封,最近开发中收集的这篇文章主要介绍NO.1 基于verilogHDL的时钟分频与任意占空比调节基于verilogHDL的时钟分频与任意占空比调节,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

基于verilogHDL的时钟分频与任意占空比调节

学生,小白,刚开始了解FPGA,想要深入学习verilog这一硬件描述语言。
就从我学到的东西开始谈起吧。
我们在做fpga项目绝大部分要用到分频计数器及其占空比的调节,可以说是必备的技能。

时钟分频(偶数)

我们所写的程序将下载烧录到basys2FPGA开发板上,而开发板spartan-3E的时钟频率为50MHZ(周期为20ns),而我们在做譬如流水灯等实验时,需要观察LED灯的亮灭需要将其频率调至1HZ左右,即每一秒输出时钟沿跳变一次。

module div(clk_in,clk_out,rst);

    input clk_in;       //输入时钟,频率为50Mhz
    input rst;          //复位信号,低电平有效
    output reg clk_out;   //输出时钟信号
    reg [25:0]cn;        //模25计数器


    always@(posedge clk_in or negedge rst)begin
        if(~rst)
            begin
                cn <= 0;
                clk_out <= 0;
           end
        else if(cn == 24999999)    //计数器记到24_999_999,即2500个clk_in上升沿后,输出波形翻转         
                begin
                    cn <= 0;
                    clk_out <= ~clk_out;
                end
        else
                cn <= cn + 1;
    end

测试激励:

module tb_div;

    // Inputs
    reg clk_in;
    reg rst;

    // Outputs
    wire clk_out;

    // Instantiate the Unit Under Test (UUT)
    div uut (
        .clk_in(clk_in), 
        .clk_out(clk_out), 
        .rst(rst)
    );
  always #10 clk_in = ~clk_in;     //每10ns输入时钟翻转一次,且正好符合时钟频率的要求
    initial begin
        // Initialize Inputs
        clk_in = 0;
        rst = 0;

        // Wait 100 ns for global reset to finish
        #100;
      rst = 1;  
        // Add stimulus here

    end

endmodule

但是我第一次看仿真波形时,输入时钟clk_in走到100ns就不往后走了,所以就把上面一个小框框里的1.00us改成了1s,就看到了一秒时候输出时钟波形的跳转。

这里写图片描述
这里写图片描述将其改为1s,得到下面能看到跳转的波形:
这里写图片描述
另一种分频,采用50M/50,即50个时钟周期翻转一次。一个时钟周期20ns,1000ns后,输出时钟翻转

module div(clk_in,clk_out,rst);

    input clk_in;
    input rst;
    output reg clk_out;
    reg [25:0]cn;


    always@(posedge clk_in or negedge rst)begin
        if(~rst)
            begin
                cn <= 0;
                clk_out <= 0;
           end
        else if(cn == 49)              
                begin
                    cn <= 0;
                    clk_out <= ~clk_out;
                end
        else
                cn <= cn + 1;
    end

endmodule

其波形:
因为1HZ分频不好观察,所以采用50M/50,即50个时钟周期翻转一次

与1HZ分频相比,1MHZ分频的区别就是计数器计数的不同,记满50个clk_in的上升沿,clk_out翻转。我感觉,这就是实现任意偶数分频的关键。(奇数分频还没了解,以后补充)。

占空比调节

下面大概了解一下占空比。占空比就是高电平所占周期的比率,如占空比为0.5即高电平持续时间占整个周期的二分之一。
显而易见,我们上面的分频输出时钟都是占空比为0.5,怎样才能调节才能使占空比改变。

module fpzkb(clk,m,n,out);
    input clk;
    input [13:0] m;             //占空比调节,设占空比为0.8,占空比为m/n,m=4000
    input [13:0] n;              //n分频,输出频率为50M/n,设n=5000,输出频率为10KHZ
    output reg out;
    parameter bitsize = 14;
    reg [bitsize:0] cn ;            //以5000分频为例
always@(posedge clk)
    begin
        if(m==0)                       //占空比为0,输出时钟总为0
            out <= 0;
        else
            begin
                if(m>=n)                   //占空比大于1
                    out <= 1;                //输出时钟总为1
                else
                    begin
                        if(cn<(m-1))              
                            out <= 1;
                        else
                            out <= 0; //cn小于m-1时,输出高电平,否则输出低电平
                                begin                 //这里的begin很奇怪,不知道是谁的begin啊
                                    if(cn<(n-1))
                                        cn <= cn + 1;
                                    else
                                        begin
                                            out <= ~out;    //计数器记到n-1时,输出时钟翻转
                                            cn <= 0;
                                        end
                                end
                    end
                end
        end

endmodule

测试激励:

module tb_fpzkb;

    // Inputs
    reg clk;
    reg [13:0] m;
    reg [13:0] n;

    // Outputs
    wire out;

    // Instantiate the Unit Under Test (UUT)
    fpzkb uut (
        .clk(clk), 
        .m(m), 
        .n(n), 
        .out(out)
    );
always #10 clk = ~clk;
    initial begin
        // Initialize Inputs
        clk = 0;
        m = 4000;
        n = 5000;

        // Wait 100 ns for global reset to finish
        #100;

        // Add stimulus here
    end

详细解释见注释
波形图如下,可以看出,一个输出时钟周期为100us即1/10kHZ秒,占空比为80%。
这里写图片描述
占空比调节的代码里有一个begin,不知道是谁的,但是仿真没问题,可能是没见过这种写法,以后会看书的时候会留神。

注:仿真工具我用的是ISE自带的;
仿真的最后要写仿真多少秒停止,不然仿真会一直进行,可以设置一个比较大的时间,如#1000 $stop;(学长教的)
如果else下面的话过两句,就要用begin和end;
奇数分频等学懂了写;

代码风格非常一般,可以说乱,加油改进。

最后

以上就是调皮信封为你收集整理的NO.1 基于verilogHDL的时钟分频与任意占空比调节基于verilogHDL的时钟分频与任意占空比调节的全部内容,希望文章能够帮你解决NO.1 基于verilogHDL的时钟分频与任意占空比调节基于verilogHDL的时钟分频与任意占空比调节所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(103)

评论列表共有 0 条评论

立即
投稿
返回
顶部