分频电路在项目中经常要用到,这里介绍两种分频电路。偶数分频和奇数分频。
偶数分频:
偶数分频相对来说简单点。只要做一个计数器,计数值为需要分频的偶数值,输出时钟在计数值的前半部分和后半部分进行取反就可得到。如对时钟进行4分频的代码如下:
`timescale 1ns/100ps
module even_div_fre
(
input clk_i,reset_i,
output reg clk_o
);
reg [2:0]cnt;
always @ (posedge clk_i or negedge reset_i) begin
if (!reset_i)begin
clk_o <= 1'b0;
cnt <= 3'd0;
end
else if (cnt < 3'd1 ) begin
cnt <= cnt + 1'b1;
end
else begin
cnt <= 3'd0;
clk_o <= ~clk_o;
end
end
endmodule
其中cnt < 3'd1中的3'd1值是4分频的一半减一得到的。其仿真结果如下图:
奇数分频:
奇数分频则比较繁琐点。方式应该有很多种,这里介绍项目中经常用到的一种。分4个步骤:
建立一个计数器cnt。计数值为分频值减一,如进行N次分频,那么计数值为N-1。N为奇数。设定两个寄存器,如rt1,rt2。当cnt = 0时,rt1为1,否则rt1为0,。当cnt 等于2(对于3分频为2,对应5分频为3,对应7分频为4,以此类推)时,rt2为1,否则rt2为0。设定两个寄存器div1,div2。当rt1为1时,在时钟的上升沿对div1进行取反。当rt2为1时,在时钟的下降沿对div2进行取反。时钟的输出为div1和div2的异或。
如对时钟进行3分频的代码如下:
module odd_div_fre
(
input clk_i,reset_i,
output reg rt1,rt2,div1,div2,
output clk_o
);
reg [1:0]cnt;
always @ (posedge clk_i or negedge reset_i) begin
if (!reset_i)begin
cnt <= 2'd0 ;
end
else if (cnt < 2'd2)begin
cnt <= cnt + 1'b1 ;
end
else cnt <= 2'd0 ;
end
always @ (posedge clk_i or negedge reset_i) begin
if (!reset_i)begin
rt1 <= 1'b0 ;
end
else if (cnt == 2'd0) begin
rt1 <= 1'b1 ;
end
else rt1 <= 1'b0 ;
end
always @ (posedge clk_i or negedge reset_i) begin
if (!reset_i)begin
rt2 <= 1'b0 ;
end
else if (cnt == 2'd2) begin
rt2 <= 1'b1 ;
end
else rt2 <= 1'b0 ;
end
always @ (posedge clk_i or negedge reset_i) begin
if (!reset_i)begin
div1 <= 1'b0 ;
end
else if (rt1 == 1'b1) begin
div1 <= ~div1 ;
end
end
always @ (negedge clk_i or negedge reset_i) begin
if (!reset_i)begin
div2 <= 1'b0 ;
end
else if (rt2 == 1'b1) begin
div2 <= ~div2 ;
end
end
assign clk_o = div1 ^ div2;
endmodule
把rt1,rt2,div1,div2放在output中,是为了进行仿真时,看到输出波形,便于调试。其仿真结果如下图: