分频器
(1)偶数分频
常见偶数分频:2、4、8分频。可通过设置一个计数器
cnt
来计数输入的时钟,以N=4
为例,cnt
的计数范围是0-3
,在cnt==0
和cnt==2 (cnt==N>>1)
时进行翻转便可得到4分频的时钟。
- verilog代码
module clk_div_even # ( parameter N = 4)(
input clk_in,
input rst_n,
output reg clk_out
);
reg[N-1:0] cnt;
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
cnt <= 'b0;
end
else begin
cnt <= cnt==N-1? 0:cnt+1'b1;
end
end
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
clk_out <= 'b0;
end
else if(cnt=='b0 || cnt==N>>1)begin
clk_out <= ~clk_out;
end
end
endmodule
- 仿真结果
(2)奇数分频(非50%占空比)
以
N=3
分频为例,当计数器cnt==0
和cnt==1
(N>>1
)时发生翻转,该种情况下占空比为1/3。
- verilog代码
module clk_div_odd0 #(parameter N=3)(
input clk_in,
input rst_n,
output reg clk_out
);
reg[N-1:0] cnt;
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
cnt <= 'b0;
end
else begin
cnt <= cnt==N-1? 0:cnt+1'b1;
end
end
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
clk_out <= 1'b0;
end
else if(cnt=='b0 || cnt==N>>1)begin
clk_out <= ~clk_out;
end
end
endmodule
- 仿真结果
(3)奇数分频(50%占空比)
需要对两个非50%占空比的奇数分频再进行组合逻辑才能得出:
module clk_div_odd1 #(parameter N=3)(
input clk_in,
input rst_n,
output reg clk_out
);
reg[N-1:0] cnt0;
reg[N-1:0] cnt1;
reg clk_out0;
reg clk_out1;
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
cnt0 <= 'b0;
end
else begin
cnt0 <= cnt0==N-1? 0:cnt0+1'b1;
end
end
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
clk_out0 <= 'b0;
end
else if(cnt0==0 || cnt0==N>>1)begin
clk_out0 <= ~clk_out0;
end
end
always@(negedge clk_in, negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 'b1;
end
else begin
cnt1 <= cnt1==N-1? 0:cnt1+1'b1;
end
always@(negedge clk_in, negedge rst_n)begin
if(!rst_n)begin
clk_out1 <= 'b0;
end
else if(cnt1==0 || cnt1==N>>1)begin
clk_out1 <= ~clk_out1;
end
end
// clk_out0和clk_out1都是1/3占空比,故采用 `|`运算
assign clk_out = clk_out0 | clk_out1;
endmodule
- 仿真结果
(4)半整数分频
N.5倍分频称为半整数分频,以1.5倍分频举例,可以使用两个3分频来组合实现,占空比无法达到50%。使用clk的上升沿和下降沿分别产生3分频,两个分频相差1.5周期。
- verilog代码
- 仿真结果
(5)小数分频
以6.7倍的小数分频为例。小数分频与奇偶分频不同,小数分频无法用一种分频得到,6.7倍分频可以理解我67:10,也就是当输入时钟个数为67个,输出时钟个数应为10个。可将其转化为6分频和7分频的组合。
6x+7y=67;x+y=10;
可得x=3
,y=7
,即,3个6分频和7个7分频可组合成6.7倍分频。
- verilog代码
module clk_div_6_7(
input clk_in,
input rst_n,
output reg clk_out
);
reg[7:0] clk_cnt; // 对输入的时钟进行计数
reg[2:0] cyc_cnt; // 对6分频和7分频进行计数
reg div_flag; // 6分频和7分频标识
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
clk_cnt <= 8'd0;
end
else begin
clk_cnt <= clk_cnt==8'd66? 0:clk_cnt+1'b1;
end
end
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
div_flag <= 'b0;
end
else if(clk_cnt==8'd17 || clk_cnt==8'd66)begin
div_flag <= ~div_flag; // 'b0为6分频;'b1为7分频
end
end
always@(posedge clk_in ,negedge rst_n)begin
if(!rst_n)begin
cyc_cnt <= 3'd0;
end
else begin
if(div_flag)
cyc_cnt <= cyc_cnt==3'd6? 0:cyc_cnt+1'b1;
else
cyc_cnt <= cyc_cnt==3'd5? 0:cyc_cnt+1'b1;
end
end
always@(posedge clk_in, negedge rst_n)begin
if(!rst_n)begin
clk_out <= 'b0;
end
else begin
clk_out <= (cyc_cnt=='b0||cyc_cnt==3'd3)? ~clk_out:clk_out;
end
end
endmodule
- 仿真结果