1.二分频
最简单时钟分频,每个时钟翻转一次,频率/2,占空比50%。
module div2 (
input clk,
input rst_n,
output reg clk_div2
);
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
clk_div2 <= 1'b0;
else
clk_div2 <= ~clk_div2; // 每个时钟翻转一次
end
endmodule
2.三分频不要求50%占空比
奇数分频不能直接翻转,需要借助计数器和条件翻转。计数器记录周期,到特定值翻转时钟。
module div3_simple (
input clk,
input rst_n,
output reg clk_div3
);
reg [1:0] cnt;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt <= 2'd0;
clk_div3 <= 1'b0;
end else begin
cnt <= (cnt == 2'd2) ? 2'd0 : cnt + 1'd1;
clk_div3 <= (cnt < 2'd1) ? 1'b1 : 1'b0;
end
end
endmodule
3.标准三分频,占空比50%,ASIC/FPGA通用
三分频要做到 50% 占空比,必须用 双边沿采样(上升沿 + 下降沿)
module div3 (
input clk,
input rst_n,
output clk_div3
);
reg [1:0] cnt_p, cnt_n;
reg q_p, q_n;
// 上升沿计数
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt_p <= 2'd0;
else
cnt_p <= (cnt_p == 2'd2) ? 2'd0 : cnt_p + 1'd1;
end
// 下降沿计数
always @(negedge clk or negedge rst_n) begin
if(!rst_n)
cnt_n <= 2'd0;
else
cnt_n <= (cnt_n == 2'd2) ? 2'd0 : cnt_n + 1'd1;
end
// 上升沿产生脉冲
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
q_p <= 1'b0;
else
q_p <= (cnt_p == 2'd0);
end
// 下降沿产生脉冲
always @(negedge clk or negedge rst_n) begin
if(!rst_n)
q_n <= 1'b0;
else
q_n <= (cnt_n == 2'd1);
end
assign clk_div3 = q_p | q_n; // 合成50%占空比
endmodule
4.偶数分频
2、4、6、8、10... 都属于这类,计数器计数到 N/2-1 翻转,天然 50% 占空比;单边沿(仅 posedge)就能实现,典型:4 分频、6 分频、8 分频、16 分频。
// 4分频 50% 占空比
always @(posedge clk or negedge rst_n) begin
if(!rst_n) cnt <= 0;
else cnt <= cnt + 1;
end
assign clk_div4 = cnt[1];
5.奇数分频
3、5、7、9...,想做 50% 占空比,必须用 双边沿(上升沿 + 下降沿);不想做 50% ,单边沿计数器即可。常见:3/5/7 分频。
6.其他分频
PLL 倍频 + 分频高速高精度,很常用。
- 输入: clk → PLL → 倍频 N 倍 → 再分频 M
- 输出:f_out = f_in × N / M
- 可实现任意整数 / 小数分频
- 无抖动、相位干净、50% 占空比
几乎所有高速设计都用这个:DDR/PCIe/CPU 内核时钟等。