waljj

时钟分频-偶数分频和奇数分频

0
阅读(2552)

分频电路在项目中经常要用到,这里介绍两种分频电路。偶数分频和奇数分频。

偶数分频:

偶数分频相对来说简单点。只要做一个计数器,计数值为需要分频的偶数值,输出时钟在计数值的前半部分和后半部分进行取反就可得到。如对时钟进行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个步骤:

  1. 建立一个计数器cnt。计数值为分频值减一,如进行N次分频,那么计数值为N-1。N为奇数。
  2. 设定两个寄存器,如rt1,rt2。当cnt = 0时,rt1为1,否则rt1为0,。当cnt 等于2(对于3分频为2,对应5分频为3,对应7分频为4,以此类推)时,rt2为1,否则rt2为0。
  3. 设定两个寄存器div1,div2。当rt1为1时,在时钟的上升沿对div1进行取反。当rt2为1时,在时钟的下降沿对div2进行取反。
  4. 时钟的输出为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中,是为了进行仿真时,看到输出波形,便于调试。其仿真结果如下图:

Baidu
map