整数奇偶分频(占空比50%)
0赞整数奇偶分频(占空比50%)
一、名词解释
1.分频:是指将一单一频率信号的频率降低为原来的1/N,就叫N分频。实现分频的电路或装置称为”分频器“。关于分频还有另外一种解释:对信号中不同频率成分的各种信号分开,分成几个频率段。本次介绍的分频是指前一种。
2.占空比:如下图1所示,在一串理想的脉冲周期序列中(如方波),正脉冲的持续时间与脉冲总周期的比值。
图1.占空比示意图
二、设计方案
总的来说就是用计数器实现信号的分频。
1.偶数分频(2N)
a.一个模为2N的计数器,其计数范围为0~2N-1;
b.一个信号发生模块,当检测到计数器的值小于N时,输出信号为高电平,其余情况信号输出为低电平;
如此便可以实现2N分频。
注:在偶数分频中,还有一种比较特殊的分频——2^N分频,实现这个分频效果只需要一个相应的N位的计数器,将其最高位作为输出即可。
2.计数分频(2N+1)
a.两个模为2N+1的计数器,其计数范围为0~2N,一个为时钟上升沿触发,另一个为时钟下降沿触发;
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.偶数分频测试波形
从测试波形可以看到,两个Verilog HDL描述电路分别实现了时钟的偶数分频和奇数分频,并且占空比都为50%。
五、Quartus II 13.0下的RTL视图
1.偶数分频的RTL视图
2.奇数分频的RTL视图
六、总结
本次设计虽然简单,但是还是废了一些事情,都是一些细节,例如减号运算的优先级高于移位运算;vcd文件的输出不是用iverilog编译后就可以产生,而是要运行一下编译生成的默认a.out文件才可以生成vcd文件,从而用于gtkwave仿真。
本次设计的不足之处在于只实现了整数分频,而未实现小数分频,虽然这个用的不多。设计之中只是使用了计数器的思路,其实还有其他的实现方法,以后再写吧。
以前一直用ISE,现在一用Quartus II,感觉真的不错,就拿RTL图来说,ISE中看不懂,Quautus II就能看清楚了。不过这个开源的iverilog+gtkwave也是不错的,在Linux下5分钟下载好就能使用了,非常方便,当然我也只是用到了其一部分功能,还需继续努力。