分频:单个时钟周期变长,频率变小,若50Mhz(20ns一个周期)实现2分频,则分频后为25Mhz(40ns)
50Mhz(20ns)实现5分频,分频后为10Mhz(100ns)
1、正常分频,比如5分频,即计5个数(0-4),当计到4时拉高,(0-3拉低)
,使最后一个数(4)为高电平,其余为低电平。
module divider_five
(
input wire sys_clk,
input wire sys_rst_n,
output reg clk_divider //频率输出管脚
);
reg [2:0] cnt;
//cnt计数
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt <= 3'd0;
else if (cnt == 3'd4)
cnt <= 3'd0;
else
cnt <= cnt + 1'd1;
//cnt_flag 输出
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
clk_divider <= 1'b0;
else if(cnt == 3'd3)
clk_divider <= 1'b1;
else
clk_divider <= 1'b0;
endmodule
2,实现奇数占空比50%的5分频需要在第2.5时拉低(计数5个数),因此需要借助下降沿的计数来实现
//5分频占空比50%
module mux2_1
(
input wire sys_clk,
input wire sys_rst_n,
output wire clk_divider
);
reg [2:0] cnt;
reg clk_1;
reg clk_2;
assign clk_divider = clk_1 | clk_2;
//cnt计数
always@ (posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt <= 3'b0;
else if(cnt == 3'd4)
cnt <= 3'd0;
else
cnt <= cnt + 1'b1;
//clk_1 赋值
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
clk_1 <= 1'b0;
else if(cnt == 3'd2)
clk_1 <= 1'b1;
else if(cnt == 3'd4)
clk_1 <= 1'b0;
else
clk_1 <= clk_1;
//clk_2 赋值
always @(negedge sys_clk or negedge sys_rst_n)
if(syss_rst_n == 1'b0)
clk_2 <= 1'b0;
else if(cnt == 3'd2)
clk_2 <= 1'b1;
else if(cnt == 3'd4)
clk_2 <= 1'b0;
else
clk_2 <= clk_2;
endmodule

若设计其他占空比的分频修改clk_1和clk_2的数值
//通用的奇数N分频占空比50
// 奇数N分频占空比50
//比如5 分频
module divider(
input wire sys_clk,
input wire sys_rst_n,
output wire div_clk
);
parameter N = 5;
reg [2:0] cnt;
reg [2:0] cnt_f;
reg clk1;
reg clk2;
assign div_clk = clk1 || clk2;
always@(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt <= 3'd0;
else if(cnt == N - 1)
cnt <= 3'd0;
else
cnt <= cnt + 1'd1;
always@(negedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt_f <= 3'd0;
else if(cnt_f == N - 1)
cnt_f <= 3'd0;
else
cnt_f <= cnt_f + 1'd1;
always@(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
clk1 <= 1'b0;
else if(cnt >= (N+1)/2)
clk1 <= 1;
else
clk1 <= 0;
always@(negedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
clk2 <= 1'b0;
else if(cnt_f >= (N+1)/2)
clk2 <= 1;
else
clk2 <= 0;
endmodule