对时钟信号进行多级分频, 是在获取多种频率时,充分利用资源的一种方法。本文基于FPGA芯片: Cylone II EP2C8Q208C8 ,将主频50MHz分级为如下几个频率信号:
![](https://i-blog.csdnimg.cn/blog_migrate/238650863c596fed617777524834e9d5.png)
一、五分频器
五分频属于奇分频, 对于信号源来说,我们一般希望它的占空比为50%, 但由于奇数不是2的倍数,所以直接分频得不到50%的占空比。为了解决这个问题, 人门常常先生成两个中间信号, 这两个中间信号分别采用上升沿采样和下降沿采样, 时序相差半个周期, 最后再将它们相或便能得到我们想要的50%占空比信号。如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/8e42f5d7621fbe1c65f70679a943b5f3.png)
代码实现:
module divf_5 //奇分频
(
input sys_clk, //输入信号
output wire f_5_clk //五分频后的信号
);
reg [2:0] cnt;
reg clk_1;
reg clk_2;
always@(posedge sys_clk ) //计数器0~4
if(cnt == 3'd4)
cnt <= 3'd0;
else
cnt <= cnt + 3'd1;
always@(posedge sys_clk ) //中间信号,上升沿采样
if(cnt == 3'd2)
clk_1 <= 1'd1;
else if(cnt == 3'd4)
clk_1 <= 1'd0;
else
clk_1 <= clk_1;
always@(negedge sys_clk ) //中间信号,下降沿采样
if(cnt == 3'd2)
clk_2 <= 1'd1;
else if(cnt == 3'd4)
clk_2 <= 1'd0;
else
clk_2 <= clk_2;
assign f_5_clk = (clk_1 | clk_2); //中间信号相或
endmodule
二、十分频器
十分频属于偶分频, 分频的本质就是计数。对于任意一个输入信号, 我们对其周期进行数数, 当数到第5个时, 就将输出信号的电平切换, 然后继续数5个周期, 再将信号切换回来, 循环往复。这样, 输出信号电平一高一低之间,就实现了对输入信号的10分频。如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/f6e7d837a566b5995f49e363aa2f8bee.png)
代码实现:
module divf_10 //偶分频
(
input clk,
output reg f_10_clk
);
reg [2:0] cnt;
always@(posedge clk ) //计数器0~4
if(cnt == 3'd4)
cnt <= 3'd0;
else
cnt <= cnt + 3'd1;
always@(posedge clk) //数五个数切换一次电平
if(cnt == 3'd4)
f_10_clk <= ~f_10_clk;
else
f_10_clk <= f_10_clk;
endmodule
三、顶层文件
顶层文件,没什么好说的,就是调用分频器。
module signal
(
input wire sys_clk ,
output wire clk_50M,
output wire clk_10M,
output wire clk_1M,
output wire clk_100k,
output wire clk_10k,
output wire clk_1k
);
assign clk_50M = sys_clk;
divf_5 u0
(
.sys_clk(sys_clk),
.f_5_clk(clk_10M)
);
divf_10 u1
(
.clk(clk_10M),
.f_10_clk(clk_1M)
);
divf_10 u2
(
.clk(clk_1M),
.f_10_clk(clk_100k)
);
divf_10 u3
(
.clk(clk_100k),
.f_10_clk(clk_10k)
);
divf_10 u4
(
.clk(clk_10k),
.f_10_clk(clk_1k)
);
endmodule
这些代码只是简易数字频率计的一部分, 这里产生的所有频率信号都可以通过数字频率计输出到数码管,完整代码链接如下, 粉丝免费下载。