使用D触发器设计2/4/8分频的占空比为百分之50的时钟分频器。
基于计数器的原理,通过计数实现时钟的分频。 要实现2/4/8分频,可以使用三位的计数器来实现。2分频一个时钟周期反转,4分频两个时钟周期反转,8分频4个时钟周期实现反转。
三位计数器 三位对应三个分频信号的。
module even_div
(
input wire rst ,
input wire clk_in,
output wire clk_out2,
output wire clk_out4,
output wire clk_out8
);
reg [2:0]cnt;
always@(posedge clk_in or negedge rst)
if(!rst)
cnt <= 3'b011;
else
cnt <= cnt + 1'b1;
assign clk_out2 = ~cnt[0];
assign clk_out4 = ~cnt[1];
assign clk_out8 = cnt[2];
endmodule
输出7分频的时钟分频器,占空比要求50%。
实现7分频是两个6分频的输出的或,两个6分频一个上升沿计数,上升沿分频,一个下降沿计数,下降沿分频。
计数器+信号反转
module odo_div_or
(
input wire rst ,
input wire clk_in,
output wire clk_out7
);
reg [2:0] count_p;
reg [2:0] count_n;
reg clk_p;
reg clk_n;
//上升沿计数
always@(posedge clk_in or negedge rst)
if(!rst)
count_p <= 3'b0;
else if(count_p == 3'd6)
count_p <= 3'b0;
else
count_p <= count_p + 1'b1;
always@(posedge clk_in or negedge rst)
if(!rst)
clk_p <= 1'b0;
else if(count_p == 3'd3 || count_p == 3'd6)
clk_p <= ~clk_p;
else
clk_p <= clk_p;
//下降沿计数
always@(negedge clk_in or negedge rst)
if(!rst)
count_n <= 3'b0;
else if(count_n == 3'd6)
count_n <= 3'b0;
else
count_n <= count_n + 1'b1;
always@(negedge clk_in or negedge rst)
if(!rst)
clk_n <= 1'b0;
else if(count_n == 3'd3 || count_n == 3'd6)
clk_n <= ~clk_n;
else
clk_n <= clk_n;
assign clk_out7 = clk_n | clk_p;
endmodule
小数分频
双模小数分频原理是取该频次两边的两个分频器拼接组成小数分频器,以5.3分频为例,即使用5分频和6分频道分频器拼接可以组成5.3分频分频器。 即a+b = 10 5a+6b = 53. 即可求出需要五分频7个6分频3个。
计数满
module div_M_N(
input wire clk_in,
input wire rst,
output wire clk_out
);
parameter M_N = 8'd87;
parameter c89 = 8'd24; // 8/9时钟切换点
parameter div_e = 5'd8; //偶数周期
parameter div_o = 5'd9; //奇数周期
//先输出8分频三个周期,24个周期后输出9分频7个。 分频点为C89。
//完成偶数和奇数的计数
reg [3:0]clk_cnt;
//对clk_in计数,计满清零
reg [6:0]cyc_cnt;
//8/9分频的分频标志
reg div_flag;
reg clk_out_r;
//切换8分频 9分频。通过div_flag信号进行切换. 切换偶数或者奇数计数器
always@(posedge clk_in or negedge rst)
if(!rst)
clk_cnt <= 0;
else if(~div_flag)
clk_cnt <= clk_cnt == (div_e-1) ? 0: clk_cnt + 1;
else
clk_cnt <= clk_cnt == (div_o-1) ? 0: clk_cnt + 1;
// 计数整个周期 统计87个周期
always@(posedge clk_in or negedge rst)
if(!rst)
cyc_cnt <= 1'b0;
else
cyc_cnt <= cyc_cnt == (M_N-1)?0:cyc_cnt+1;
//切换8分频和9分频,标志信号div_flag 使得偶数分频时候div_flag一直为0,奇数分频时为1。
always@(posedge clk_in or negedge rst)
if(!rst)
div_flag <= 1'b0;
else
div_flag <= cyc_cnt == (M_N-1)|| cyc_cnt == (c89-1) ? ~div_flag:div_flag;
//确定输出 右移两位为2. 小于等于3 0123 对于偶数分频为百分之50占空比,对于奇数分频不是百分之50占空比
always@(posedge clk_in or negedge rst)
if(!rst)
clk_out_r<=1'b0;
else if(~div_flag)
clk_out_r <= clk_cnt <= ((div_e>>2)+1);
else
clk_out_r <= clk_cnt <= ((div_o>>2)+1);
assign clk_out = clk_out_r;
endmodule