发 帖  
原厂入驻New
申请华秋企业认证 多层板首单免费打样!
30s提交资料,10分钟通过审核(免费赔付+顺丰包邮)>>立即报名

[经验] 【梦翼师兄今日分享】 任意时钟分频程序设计讲解

2019-12-11 10:15:33  898 FPGA 时钟
分享
6
写在前面的话
在数字逻辑电路设计中,分频器是一种基本的电路单元。通常用来对某个给定频率进行分频,以得到所需的频率。分频在FPGA的设计中一直都担任着很重要的角色,而说到分频,我相信很多人都已经想到了利用计数器计数来得到想要的时钟频率,但问题是仅仅利用计数器来分频,只可以实现偶数分频,而如果需要三分频、五分频、七分频等等奇数类分频,那应该怎么办呢?在这里,梦翼师兄为大家介绍一种可以实现任意整数分频的方法。
实现原理
这种方法同样也是利用了计数器来实现,当然我们是使用状态机来实现的。我们首先定义分频时钟高电平的个数和低电平的个数,在第一个状态,当计数器计数值小于分频时钟低电平个数的时候,输出电平为低电平,等于低电平的个数的时候,输出取反同时计数器清零,跳转到下一个状态。在这个状态当计数器计数小于分频时钟高电平个数的时候,输出电平不变,当计数器数值等于高电平个数的时候,输出取反同时计数器清零,跳转到上一个状态,这样就可以实现任意分频。
系统框架
111.png
顶层模块端口描述
端口名
端口说明
clk
系统时钟50Mhz
rst_n
系统低电平复位信号
clk_out
输出分频时钟
代码分析
/****************************************************         
*   Engineer      :   梦翼师兄
*   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      :   梦翼师兄
*   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
仿真分析
111.png
我们输入的时钟是50Mhz,一个周期是20ns,输出5分频的时钟,周期是100ns,可见我们的设计是正确的。
我们修改分频模块的参数将HW改为3,LW改为3,仿真波形如下:
111.png
同样输入的时钟是50Mhz,一个周期是20ns,输出6分频的时钟,周期是120ns,可见我们的设计是正确的。

相关经验

思念的风 2019-12-12 19:16:14
思念的风邀请您访问中国电子技术论坛
http://bbs.elecfans.com/?fromuid=3551116
回复

举报

zgy-chenxin 2019-12-13 21:37:37
学习了,谢谢分享!
回复

举报

chalo 2019-12-23 16:49:24
本帖最后由 chalo 于 2020-1-7 10:55 编辑

谢谢分享,学习了
回复

举报

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

发经验
关闭

站长推荐 上一条 /5 下一条

快速回复 返回顶部 返回列表