基础项目(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,可见我们的设计是正确的。

原文地址:https://www.cnblogs.com/mengyi1989/p/11518333.html

时间: 2024-10-03 16:00:01

基础项目(5)任意时钟分频程序设计讲解的相关文章

基础项目(3)三态门程序设计讲解

写在前面的话 我们所接触到的IO都是单纯的输入(input)或者输出(output)类型,而我们的一些总线协议如IIC等,要求信号为三态类型,也就是我们所说的输入输出(inout)类型.那么,本节梦翼师兄将和大家一起来探讨三态门的用法. 项目需求 设计一个三态门电路,可以实现数据的输出和总线“挂起”. 系统架构 模块功能介绍 模块名 功能描述 three_state 控制三态总线Sda是否处于挂起状态 顶层模块端口描述 端口名 端口说明 Clk 系统时钟 Rst_n 系统低电平复位 Data_b

进阶项目(4)蜂鸣器程序设计讲解

写在前面的话 经过前面内容的学习,梦翼师兄相信大家的基础知识水平一定已经很扎实.那么本节,我们就一起来庆祝一下,用播放器奏响一曲<欢乐颂>,奏响我们凯旋的乐章. 什么是蜂鸣器? 蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机.打印机.电子玩具.定时器等电子产品中作为发声器件.蜂鸣器分为有源蜂鸣器和无源蜂鸣器两种,在电路中用字母“H”或“HA”(旧标准用“FM”.“ZZG”.“LB”.“JD”等)表示.那么,怎么区分有源蜂鸣器和无源蜂鸣器呢?有源蜂鸣器内部带震荡源,所以只

进阶项目(7)VGA显示程序设计讲解

 写在前面的话 可能大家觉得之前设计都是各种看波形,比较的单一.乏味.那么本节的内容,一定可以带给大家全新的感受,现代电子技术中,图像处理技术可谓是发展迅猛,其带给大家独特的视觉感受也总是那么的赏心悦目.这里,梦翼师兄和大家一起敲开图像世界的大门,让我们一起为之痴迷,为之陶醉. 什么是VGA? VGA(Video Graphics Array,视频图形阵列),是 IBM 于1987年提出的一个使用类比讯号的电脑显示标准.这个标准已对于现今的个人电脑市场已经十分过 时.即使如此,VGA 仍然是很多

C语言零基础项目驱动式学习第一天

引言: 智能手机(Smart Phone)是一种运算能力及功能比传统手机更强的手机.目前的操作系统基本上有以下几种: 1. Symbian Os 众所周知塞班隶属于NOKIA,Symbian开发之初的目标是保证在较低资源的设备上能长时间的运行,这导致了塞班的应用程序开发有着较为陡峭的学习路线,开发成本高,但是程序的运行的效率很高> 2.Android 开源, 联盟,Android凝聚了几乎遍布全球的力量,这是Android形象及声音能够被传到全球移动互联网市场每一个角落的根本原因.不过, 1).

【项目实战派】触摸屏程序设计要点

[项目实战派]触摸屏程序设计要点            触摸屏作为一种更为直接的人机交互方式,现在广泛运用于智能手机.工业控制.场景展示等许多场合.作为程序员,如何理解触摸屏程序设计?如何做好的触摸屏程序设计?现在已经有的资源包括那些?借着项目牵引,我对这个问题进行一定探索,经验有限,欢迎批评交流. 一.如何理解触摸屏程序设计 操作系统层面已经实现了基础功能,基于触摸屏的界面,从本质上来说和普通的GuI界面是没有区别的.程序的界面设计需要服务于程序的功能,为客户提供直观.易用.体验效果较好的界面

任意整数分频Verilog(占空比50%)

程序实现任意整数分频的功能,已在modelsim中通过验证. 1 //`define N 5 2 module div_N ( 3 input CLK, // 基准时钟 4 output CLK_div_N, // N分频后得到的时钟 5 input rst 6 ); 7 wire [31:0] N=5; // ★ N为分频系数,N≥2即可,N的值为CLK除以CLK_div_N后取整(四舍五入) 8 9 /******************** 产生备用时钟1 ***************/

C语言零基础项目驱动式学习第四天

//类型修饰符  数组名[数组元素个数] = {初始化}; //定义数组的时候[]中必须是常量表达式, 不可以是变量; /* int age[5] = {21, 18, 25, 20, 18}; int array[10] = {0};//代表数组中有10个元素, 每个都是0; int array1[8] = {1};//代表数组中有8个元素,第一个是1,其余的为0; int age2[2 + 3] = {0}; */ //定义数组和使用数组的最大区别是, 前面是否有类型修饰符 //使用数组元素

C语言零基础项目驱动式学习第二天

//BOOL 类型是一种非真即假的数据类型,取值只有YES和NO, //BOOL 其实是OC中得数据类型,在C语言中,认为非0即为真. //BOOL 类型规定的存储空间为一个字节. //    BOOL a = YES; //    BOOL b = NO; //    printf("a = %d, b = %d\n", a, b); //    int a = 15, b = 18; //    BOOL c = a > b; //    printf("c = %

C语言零基础项目驱动式学习第三天

一 while循环二do   while循环三 for循环for循环的执行顺序用如下表达式: for(expression1;expression2;expression3)        循环变量初值; 循环条件; 循环变量增量  {                expression4; }       执行的顺序应该是: 1)第一次循环,即初始化循环.      首先执行表达式expression1(一般为初始化语句):再执行expression2(一般为条件判断语句),判断express