zoukankan      html  css  js  c++  java
  • 基础项目(5)任意时钟分频程序设计讲解

    写在前面的话

    在数字逻辑电路设计中,分频器是一种基本的电路单元。通常用来对某个给定频率进行分频,以得到所需的频率。分频在FPGA的设计中一直都担任着很重要的角色,而说到分频,我相信很多人都已经想到了利用计数器计数来得到想要的时钟频率,但问题是仅仅利用计数器来分频,只可以实现偶数分频,而如果需要三分频、五分频、七分频等等奇数类分频,那应该怎么办呢?在这里,梦翼师兄为大家介绍一种可以实现任意整数分频的方法。

    实现原理

    这种方法同样也是利用了计数器来实现,当然我们是使用状态机来实现的。我们首先定义分频时钟高电平的个数和低电平的个数,在第一个状态,当计数器计数值小于分频时钟低电平个数的时候,输出电平为低电平,等于低电平的个数的时候,输出取反同时计数器清零,跳转到下一个状态。在这个状态当计数器计数小于分频时钟高电平个数的时候,输出电平不变,当计数器数值等于高电平个数的时候,输出取反同时计数器清零,跳转到上一个状态,这样就可以实现任意分频。

    系统框架

    顶层模块端口描述

    端口名

    端口说明

    clk

    系统时钟50Mhz

    rst_n

    系统低电平复位信号

    clk_out

    输出分频时钟

    代码分析

    /****************************************************          

     *   Engineer      :   梦翼师兄

     *   QQ             :   761664056

     *   The module function : 任意分频模块 *****************************************************/

    01  module divide(

    02              clk,    //系统时钟输入

    03              rst_n,  //系统低电平复位

    04              clk_out //分频时钟输出

    05              );

    06

    07      parameter HW = 3;   //输出时钟高电平宽度

    08      parameter LW = 2;   //输出时钟低电平宽度

    09      

    10      input clk;     //系统时钟输入

    11      input rst_n;   //系统低电平复位

    12      output clk_out; //分频时钟输出

    13      

    14      reg clk_out;

    15      reg [31:0] count; //计数器

    16      reg state;  //状态寄存器

    17      

    18      always @ (posedge clk or negedge rst_n) 

    19      begin

    20          if (!rst_n)         //异步复位

    21              begin

    22                  clk_out <= 1'b0; //赋初值

    23                  count <= 0;

    24                  state <= 0;

    25              end

    26          else

    27              case (state)

    28                  0 : if (count < LW-1) //输出低电平个数比较器

    29                          begin

    30                              count <= count + 1;

    31                              state <= 0;

    32                          end

    33                      else //输出低电平个数等于设定的低电平个数

    34                          begin

    35                              count <= 0; //计数器清零

    36                              clk_out <= 1'b1; //输出变为1

    37                              state <= 1;

    38                          end

    39                                  

    40                  1 : if (count < HW-1) //输出高电平个数比较器

    41                          begin

    42                              count <= count + 1;

    43                              state <= 1;

    44                          end

    45                      else //输出高电平个数等于设定的高电平个数

    46                          begin

    47                              count <= 0; //计数器清零

    48                              clk_out <= 1'b0; //输出变为0

    49                              state <= 0;

    50                          end

    51                  default : state <= 0;

    52                  endcase

    53      end

    54

    55  endmodule

    7~8行定义了2个参数,一个是输出高电平的个数,一个是低电平的个数,比如HW=3,LW=2输出就是一个5分频的时钟,

    比如HW=3,LW=3输出就是一个6分频的时钟,可见只要改变HW和LW的值就可以实现任意分频。第18~53行就是利用状态机来实现分频的过程,用2个状态来计数输出高电平个数和低电平个数。

    编写测试代码如下:

    /****************************************************          

     *   Engineer      :   梦翼师兄

     *   QQ             :   761664056

     *   The module function : 任意分频测试模块 *****************************************************/

    01  `timescale 1ns/1ps  //仿真时间单位是ns,仿真时间精度是ps         

    02  module tb;

    03

    04  reg clk, rst_n; //仿真激励时钟,复位信号

    05

    06  wire clk_out;     //仿真输出分频信号

    07

    08  initial begin

    09      clk = 0;                //clk时钟信号初始化

    10      rst_n = 0;          //rst_n复位信号初始化

    11      #200.1 

    12      rst_n = 1;          //200.1ns之后,复位结束

    13  end

    14

    15  always #10 clk = ~clk;  //产生50Mhz时钟信号

    16

    17  divide divide(   //把激励信号送进diveder模块       

    18                  .clk(clk),                                  

    19                  .rst_n(rst_n),

    20                  .clk_out(clk_out)

    21                   );

    22              

    23  endmodule

    仿真分析

    我们输入的时钟是50Mhz,一个周期是20ns,输出5分频的时钟,周期是100ns,可见我们的设计是正确的。

    我们修改分频模块的参数将HW改为3,LW改为3,仿真波形如下:

    同样输入的时钟是50Mhz,一个周期是20ns,输出6分频的时钟,周期是120ns,可见我们的设计是正确的。


     

  • 相关阅读:
    Qt 2D绘图之五:图形视图框架的结构和坐标系统
    (转)x264 编码流程
    (转)x264代码详细阅读之x264.c,common.c,encoder.c
    使用ffmepg的lib库调试,debug版本下调试无问题,但release版本会出现跑飞的现象
    (转)视频码率,帧率和分辨率的联系与区别
    (转)windows平台时间函数性能比较QueryPerformanceCounter,GetTickCount,ftime,time,GetLocalTime,GetSystemTimeAsFileTime
    (转)x264源码分析(1):main、parse、encode、x264_encoder_open函数代码分析
    转)x264重要结构体详细说明(2): x264_image_t、x264_picture_t、x264_nal_t
    (转)x264重要结构体详细说明(1): x264_param_t
    (转)SCR, PCR, ESCR, PTS, DTS
  • 原文地址:https://www.cnblogs.com/mengyi1989/p/11518333.html
Copyright © 2011-2022 走看看