FPGA时钟分频器设计

小蛇玩FPGA / 2025-01-25 / 原文

时钟奇偶分频设计

产生特定奇、偶分频的时钟分频设计

计数器设计

计数器使用时序电路的时钟进行计数,在到达计数值后清零。

wire    add_pose_flag    ;
wire    end_pose_flag    ;
reg     clk_out_pose     ;
reg     [$clog2(DIV_NUM)-1:0]    cnt_pose    ;
always @(posedge clk or negedge rst_n) begin
    if( !rst_n )
        cnt_pose <= 0   ;
    else if( add_pose_flag )
        if(end_pose_flag)   
            cnt_pose <= 0   ;
        else
            cnt_pose <= cnt_pose + 1 ;
end
assign add_pose_flag = 1 ;		//随时进行计数
assign end_pose_flag = add_pose_flag && cnt_pose == DIV_NUM - 1 ;	//分频系数

在cnt_pose达到DIV_NUM - 1处,就开始下一次计数。结果如下 。

计数器仿真图

偶分频设计

偶分频只需要对时钟的一个边沿计数,在达到计数值一半的位置让输出时钟偏转即可。那么现在主要的设计思路就是利用计数器对时钟边沿进行计数(时钟上升沿下降沿皆可,但多数使用的时钟上升沿)在达到计数指定计数值时输出翻转即可,那么输出时钟是使用时序电路还是组合电路呢,接下来我们分别设计来看看。

输出信号的设计:

always @(posedge clk or negedge rst_n) begin
    if( !rst_n )
        clk_out_pose <= 0 ;
    else if( cnt_pose < pose_cnt / 2 )
        clk_out_pose <= 0 ;
    else
        clk_out_pose <= 1 ;
end

在上升沿时计数,然后在到达计数值一半的位置电平翻转仿真如下

电平翻转时序电路设计

红线是我的输出时钟信号,在两黄线之间是一个周期的8分频信号,从中可以看到:信号的翻转总是在结束计数的后一个时钟生效,虽然效果相同但是仍然优点别扭,所以对次进行了修改,将时序电路改成了组合电路,效果如下:

组合逻辑仿真

现在的效果就看着很正常了。

奇分频设计

在设计奇分频时仅仅使用一个计数器进行分频时比较困难的,因此用两个奇数器分别对时钟的上升沿和下降沿进行计数,然后分别对两个计数器的计数值进行偶分频一样的操作,最后将两个输出信号进行处理得到奇分频信号。

assign clk_out = clk_out_nege & clk_out_pose ;	//奇分频,将两个信号相与得到

奇分频仿真

综合设计

我的clk_out就是分频输出信号,然后用一个vld信号选择输出的信号类型(奇/偶),之后设计了一个分频系数切换的电路。

总结

本节就是一个简单的计数器的设计和使用,其中略微涉及了时序电路与组合电路的区别:

时序电路语句生效总是在always块都执行完后才会生效,而组合电路则 是立刻生效,所以在计数值达到边界后的下一个时钟有效沿才发生跳变。