两忘而化其道

整数奇偶分频(占空比50%)

0
阅读(3688)

整数奇偶分频(占空比50%

一、名词解释

1.分频:是指将一单一频率信号的频率降低为原来的1/N,就叫N分频。实现分频的电路或装置称为分频器。关于分频还有另外一种解释:对信号中不同频率成分的各种信号分开,分成几个频率段。本次介绍的分频是指前一种。

2.占空比:如下图1所示,在一串理想的脉冲周期序列中(如方波),正脉冲的持续时间与脉冲总周期的比值。








1.占空比示意图


二、设计方案

总的来说就是用计数器实现信号的分频。

1.偶数分频(2N

a.一个模为2N的计数器,其计数范围为02N-1

b.一个信号发生模块,当检测到计数器的值小于N时,输出信号为高电平,其余情况信号输出为低电平;

如此便可以实现2N分频。

注:在偶数分频中,还有一种比较特殊的分频——2^N分频,实现这个分频效果只需要一个相应的N位的计数器,将其最高位作为输出即可。

2.计数分频(2N+1

a.两个模为2N+1的计数器,其计数范围为02N,一个为时钟上升沿触发,另一个为时钟下降沿触发;

b.两个信号发生模块,这两个模块对应相应的计数器模块,由于信号发生模块控制信号输出的方式都是相同的,所以这里只介绍一个,另一个与其相同。当信号发生模块测到计数器的值小于N时,信号输出为高电平,其余输出都是低电平;

由于有两个模相同的计数器,其区别只是在于触发方式不同,所以两个计数器输出的信号相位相差0.5个周期,且占空比都为N/(2N+1),将这两个信号相或,即可得到占空比为50%2N+1分频信号。


三、设计代码

1.偶数分频

module fp_even

(

input wire clk,

input wire rst_n,

output wire clk_fp_even,

output wire clk_fp_2_even,

output wire clk_fp_4_even,

output wire clk_fp_8_even

);

reg [2:0] counter_fp_2_power; // 2's power counter

// module 1: 2's power fp

always @ (posedge clk) begin

if(!rst_n)

counter_fp_2_power <= 3'b0;

else

counter_fp_2_power <= counter_fp_2_power + 1'b1;

end

// 2's power fp out

assign clk_fp_2_even = counter_fp_2_power[0];

assign clk_fp_4_even = counter_fp_2_power[1];

assign clk_fp_8_even = counter_fp_2_power[2];

///////////////////////////////////////////////////////////////////////////////

parameter FP_EVEN_NUM = 3'b110; // 6 fp

reg [2:0] cnt; // fp counter

reg clk_fp_even_q;

// module 1: fp counter

always @ (posedge clk) begin

if(!rst_n)

cnt <= 3'b0;

else if(cnt < FP_EVEN_NUM - 1'b1)

cnt <= cnt + 1'b1;

else

cnt <= 3'b0;

end

// module 2: fp

always @ (posedge clk) begin

if(!rst_n)

clk_fp_even_q <= 1'b0;

else if(cnt < (FP_EVEN_NUM >> 1)) // FP_EVEN_NUM / 2 - 1, but '-' is higher priority

clk_fp_even_q <= 1'b1;

else// if(cnt == (FP_EVEN_NUM - 1))

clk_fp_even_q <= 1'b0;

end

assign clk_fp_even = clk_fp_even_q;

endmodule

2.偶数分频testbench

`include "fp_even.v"

module fp_even_tb;

reg clk, rst_n;

wire clk_fp_even;

wire clk_fp_2_even, clk_fp_4_even, clk_fp_8_even;

fp_even fp_unit

(

.clk(clk),

.rst_n(rst_n),

.clk_fp_even(clk_fp_even),

.clk_fp_2_even(clk_fp_2_even),

.clk_fp_4_even(clk_fp_4_even),

.clk_fp_8_even(clk_fp_8_even)

);

initial begin

clk = 0;

rst_n = 0;

#10;

rst_n = 1;

#1000;

$finish;

end

always #2 clk = ~clk;

initial begin

$dumpfile("fp_even_tb.vcd");

$dumpvars;

end

endmodule

3.奇数分频

module fp_odd

(

input wire clk,

input wire rst_n,

output wire clk_fp_odd

);

parameter FP_ODD_NUM = 2'b11; // 3 fp

reg [1:0] cnt_p, cnt_n; // fp counter(posedge & negedge)

reg clk_fp_odd_p_q, clk_fp_odd_n_q;

// module 1: fp posedge counter

always @ (posedge clk) begin

if(!rst_n)

cnt_p <= 2'b0;

else if(cnt_p == FP_ODD_NUM - 1)

cnt_p <= 2'b0;

else

cnt_p <= cnt_p + 1'b1;

end

// module 2: odd fp posedge sign

always @ (posedge clk) begin

if(!rst_n)

clk_fp_odd_p_q <= 1'b0;

else if(cnt_p < (FP_ODD_NUM - 1) >> 1)

clk_fp_odd_p_q <= 1'b1;

else

clk_fp_odd_p_q <= 1'b0;

end

// module 3: fp negedge counter

always @ (negedge clk) begin

if(!rst_n)

cnt_n <= 2'b0;

else if(cnt_n == FP_ODD_NUM - 1)

cnt_n <= 1'b0;

else

cnt_n <= cnt_n + 1'b1;

end

// module 4: odd fp negedge sign

always @ (negedge clk) begin

if(!rst_n)

clk_fp_odd_n_q <= 1'b0;

else if(cnt_n < (FP_ODD_NUM - 1) >> 1)

clk_fp_odd_n_q <= 1'b1;

else

clk_fp_odd_n_q <= 1'b0;

end

// clk out

assign clk_fp_odd = clk_fp_odd_p_q | clk_fp_odd_n_q;

endmodule

4.计数分频testbench

`include "fp_odd.v"

module fp_odd_tb;

reg clk, rst_n;

wire clk_fp_odd;

fp_odd fp_odd_unit

(

.clk(clk),

.rst_n(rst_n),

.clk_fp_odd(clk_fp_odd)

);

initial begin

clk = 0;

rst_n = 0;

#10;

rst_n = 1;

#1000;

$finish;

end

always #2 clk = ~clk;

initial begin

$dumpfile("fp_odd_tb.vcd");

$dumpvars;

end

endmodule


四、测试波形及解释

注:verilog使用iverilog进行,波形图查看使用gtkwave

2.偶数分频测试波形

3.奇数分频测试波形

从测试波形可以看到,两个Verilog HDL描述电路分别实现了时钟的偶数分频和奇数分频,并且占空比都为50%


五、Quartus II 13.0下的RTL视图

1.偶数分频的RTL视图

4.偶数分频的RTL视图


2.奇数分频的RTL视图

5.奇数分频的RTL视图


六、总结

本次设计虽然简单,但是还是废了一些事情,都是一些细节,例如减号运算的优先级高于移位运算;vcd文件的输出不是用iverilog编译后就可以产生,而是要运行一下编译生成的默认a.out文件才可以生成vcd文件,从而用于gtkwave仿真。

本次设计的不足之处在于只实现了整数分频,而未实现小数分频,虽然这个用的不多。设计之中只是使用了计数器的思路,其实还有其他的实现方法,以后再写吧。

以前一直用ISE,现在一用Quartus II,感觉真的不错,就拿RTL图来说,ISE中看不懂,Quautus II就能看清楚了。不过这个开源的iverilog+gtkwave也是不错的,在Linux5分钟下载好就能使用了,非常方便,当然我也只是用到了其一部分功能,还需继续努力。

Baidu
map