预分频之二
整数分频
整数分频都可以使用计数器简单实现,但奇数分频不作处理不能达到50%的占空比,下面具体讨论整数的分频。
偶数分频
偶数分频的翻转都在相同的沿(上升沿)发生,且都为50%占空比。
波形分析
偶数分频代码实例
verilog code
module evenprescaler(
output reg prescaler,
input clk,
input rstn
);
parameter N = 6;
reg [7:0] cnt; //定义8位宽,以便能实现更都的分频,实际中够用即可
reg [7:0] cnt_next;
//计数器
always@(posedge clk,negedge rstn)
begin
if(!rstn)
cnt <= 8'b0;
else
cnt <= cnt_next;
end
always@(*)
begin
if(cnt == (N - 1'b1)) //周期设定( 0 - N-1 ) N分频
cnt_next = 8'b0;
else
cnt_next = cnt + 1'b1;
end
//分频翻转
always@(posedge clk,negedge rstn)
begin
if(cnt == (N - 1'b1)/2)
prescaler <= 1'b1;
else if(cnt == (N - 1'b1)) //翻转
prescaler <= 1'b0;
end
endmodule
testbench
module evenprescaler_tb;
reg clk;
reg rstn;
wire prescaler;
initial
begin
clk = 0;
rstn = 0;
@(posedge clk) rstn = 1;
repeat(100) @(posedge clk);
@(posedge clk) $finish;
end
always #5 clk = ~clk;
initial begin
$fsdbDumpfile("test.fsdb"); //dump波形
$fsdbDumpvars();
end
evenprescaler u_evenprescaler(
.prescaler(prescaler),
.clk(clk),
.rstn(rstn)
);
endmodule
仿真结果
奇数分频
非50%占空比
与偶数分频方法类似,在适当的时钟上升沿置位或复位即可实现。
50%占空比
7分频波形分析
上图可见, 7 = 3 + 4 = 3.5 + 3.5,我们需要在下降沿得到一个边沿,以得到半拍,这样错位的两个信号运算即可得到50%的占空比分频,具体请看代码。
代码实例(以7分频为例)
verilog code
module oddprescaler(
output prescaler,
input clk,
input rstn
);
parameter N = 7;
reg [7:0] cnt; //定义8位宽,以便能实现更都的分频,实际中够用即可
reg [7:0] cnt_next;
reg preodd0;
reg preodd1;
//计数器
always@(posedge clk,negedge rstn)
begin
if(!rstn)
cnt <= 8'b0;
else
cnt <= cnt_next;
end
always@(*)
begin
if(cnt == (N - 1'b1)) //周期设定( 0 - N-1 ) N分频
cnt_next = 8'b0;
else
cnt_next = cnt + 1'b1;
end
always@(posedge clk,negedge rstn)
begin
if(!rstn)
preodd0 <= 1'b0;
else if(cnt == N - 1'b1)
preodd0 <= 1'b0;
else if(cnt == (N - 1'b1)/2) //翻转
preodd0 <= 1'b1;
end
always@(negedge clk,negedge rstn) //注意使用时钟的下降沿
begin
if(!rstn)
preodd1 <= 1'b0;
else if(cnt == N - 1'b1)
preodd1 <= 1'b0;
else if(cnt == (N - 1'b1)/2) //翻转
preodd1 <= 1'b1;
end
//错位信号进行运算
assign prescaler = preodd0 | preodd1;
endmodule
testbench
module oddprescaler_tb;
reg clk;
reg rstn;
wire prescaler;
initial
begin
clk = 0;
rstn = 0;
@(posedge clk) rstn = 1;
repeat(100) @(posedge clk);
@(posedge clk) $finish;
end
always #5 clk = ~clk;
initial begin
$fsdbDumpfile("test.fsdb");
$fsdbDumpvars();
end
oddprescaler u_oddprescaler(
.prescaler(prescaler),
.clk(clk),
.rstn(rstn)
);
endmodule
仿真结果
最后
说了这么多,试一试,思考5分频怎样写呢?
波形已给出,使用两种方法实现,其他奇数分频50占空比都可以使用这种方法实现。
参考资料
[1]. 用Verilog语言实现奇数倍分频电路3分频、5分频、7分频
[2]. 基于Verilog的奇数偶数小数分频器设计
形而上者谓之道 形而下者谓之器。