一、整数分频器
整数分频可以用Moore状态机很容易地实现,如下图:
- 当然,也可以使用计数器cnt对时钟上升沿进行计数,当cnt的值为0-3时,输出为1,cnt的值为4-6时,输出为0;
但是这样简单的逻辑无法产生50%占空比的奇数分频输出。
二、具有50%占空比的奇数分频
理论分析:产生具有50%占空比的奇数分频时钟最简单的方式是
- 以期望输出频率的一半生成两个正交相位时钟(相位差为90°),
- 然后将这两个波形异或得到输出频率。
由于存在固定的90°相位差,每次异或输入只有一端会变化,这样有效消除了输出波形上的毛刺。
奇数分频需要同时用到时钟的上升沿和下降沿,同一个always敏感语句内,不能同时包含时钟的上升沿和下降沿,因此可以产生两个reg信号,分别对上升沿和下降沿敏感
其实,使用或门可以更快地实现:
源代码:
module Div3(clk_in,rst_n,clk_out,clk_out1,clk_out2,cnt);
input clk_in;
input rst_n;
output clk_out,clk_out1,clk_out2;
output [1:0] cnt;
wire clk_out;
reg clk_out1,clk_out2;
reg [1:0] cnt;
assign clk_out = clk_out1 | clk_out2;
always @(posedge clk_in, negedge rst_n) begin
if(!rst_n)
cnt <= 0;
else if(cnt == 3'h2)
cnt <= 0;
else
cnt <= cnt + 1;
end
always @(posedge clk_in) begin
if(cnt == 1)
clk_out1 <= 'b1;
else
clk_out1 <= 'b0;
end
always @(negedge clk_in) begin
if(cnt == 1)
clk_out2 <= 'b1;
else
clk_out2 <= 'b0;
end
endmodule
测试代码:
`timescale 1ns/1ns
module tb_Div3();
reg rst_n,clk;
wire clk_div3;
wire clk_out1,clk_out2;
wire [1:0] cnt;
Div3 my_Div3(
.rst_n(rst_n),
.clk_in(clk),
.clk_out(clk_div3),
.clk_out1(clk_out1),
.clk_out2(clk_out2),
.cnt(cnt)
);
always #5 clk = ~clk;
initial begin
clk = 0;
rst_n = 0;
#10 rst_n = 1;
#100 $stop;
end
endmodule
三、非整数分频
3.1、1.5倍分频(非50%占空比)
1.5倍分频电路可以在3分频的基础上实现,仅从编程来说,是可以实现的。