在vivado中,可直接调用PLL实现奇数分频,这里介绍的是50%占空比的奇数分频器的代码实现。
如果要实现一个2N+1的奇数分频器,首先,先设置两个计数器cnt_n和cnt_p,分别用于上升沿触发和下降沿触发的计数器,两个计数器都是计数到N,然后进行翻转。以下是一个5分频的计数器例子。
module clk_div5(
input clk_in,
input reset,
output clk_out
);
reg[2:0] cnt_n , cnt_p;
reg clk_1to5p,clk_1to5n;
always @( posedge clk_in) begin
if (!reset) begin
cnt_p <= 0 ;
clk_1to5p <= 0;
end
else begin
if (cnt_p == 5) begin
cnt_p <= 0;
clk_1to5p <= 0;
end
else begin
case (cnt_p)
3'b0: clk_1to5p <=1;
3'b1: clk_1to5p <=1;
default:clk_1to5p <= 0 ;
endcase
if (cnt_p == 4) begin
cnt_p <= 0;
end
else
cnt_p <= cnt_p + 1;
end
end
end
always @( negedge clk_in) begin
if (!reset) begin
cnt_n <= 0 ;
clk_1to5n <= 0;
end
else begin
case (cnt_n)
3'b0: clk_1to5n <=1;
3'b1: clk_1to5n <=1;
default:clk_1to5n <= 0 ;
endcase
if (cnt_n == 4) begin
cnt_n <= 0;
end
else
cnt_n <= cnt_n + 1;
end
end
assign clk_out = clk_1to5p | clk_1to5n;
endmodule
在5分频中,一个用于上升沿触发,一个用于下降沿触发,这里N为2,然后在进行相或操作就能得到占空比为50%的3分频输出。
测试文件如下:
`timescale 1ns / 1ps
module div5sim(
);
reg clk_in ;
reg reset;
wire clk_out;
initial begin
#0 clk_in =0;
#0 reset = 0;
#100 reset = 1;
end
always begin
#20 clk_in <= !clk_in;
end
clk_div5 clk_div5_instance(.clk_in(clk_in),.reset(reset),.clk_out(clk_out));
endmodule
仿真图如下: