预分频之二

整数分频

整数分频都可以使用计数器简单实现,但奇数分频不作处理不能达到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的奇数偶数小数分频器设计

posted @ 2016-11-11 19:39  乔_木  阅读(591)  评论(0编辑  收藏  举报