我是靠谱客的博主 难过中心,最近开发中收集的这篇文章主要介绍用verilog实现偶数,奇数,半整数,分数(小数)分频用verilog实现偶数,奇数,半整数,分数(小数)分频4. 分数(小数分频),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

用verilog实现偶数,奇数,半整数,分数(小数)分频

声明:本文参考了king阿金的博客
一般来说,N倍分频是指时钟频率变为原来的1/N,而时钟周期变为原来的N倍。

1. 偶数分频

N为偶数,设计一个计数器,循环从0-(N-1)计数,在在N/2-1与N-1分别将输出取反,即完成偶数N分频。用verilog代码实现如下:

//div2
always@(posedge clk or negedge rstn) begin
    if(!rstn)
     div2_clk <= 1'b0;
 else
  div2_clk <= ~div2_clk;
end
//div6
always@(posedge clk or negedge rstn) begin
    if(!rstn)
      cnt2 <= 2'b0;
    else if(cnt2 == 2'b10)
     cnt2 <= 2'b0;
 else
     cnt2 <= cnt2 + 1;
end
always@(posedge clk or negedge rstn) begin
    if(!rstn)
     div6_clk <= 1'b0;
 else if(cnt2 == 2'b10)
  div6_clk <= ~div6_clk;
end

如果采用D触发器画出分频器,单个D触发器的反向输出到输入就构成了一个简单的2分频器,以此为基础,其分频输出作为下一级D触发器的时钟,如此串联起来,x个串联就是2^x分频,属于偶数分频。
在这里插入图片描述

2. 奇数分频

Verilog:N为奇数,使用一个计数器循环0-(N-1)进行计数,控制(N-1)/2个高电平,(N+1)/2个低电平,称为A;然后将此A电平信号延迟半个时钟周期称为B,最后输出C = A|B,即为占空比为50%的奇数分频器。另一种方案是(N+1)/2个高电平,(N-1)/2个低电平,那么最后输出C=A&B。

以C = A|B为例,将A延时半个时钟周期的方法有2种,方法1是直接使用下降沿的锁存器对A锁存得到B,方法2得到B的原理与A相同,不过是在下降沿检测(假设A是上升沿检测)。
在这里插入图片描述
用verilog代码实现如下:

`timescale 1ns/1ps
module  odd_division(
input rstn,
input clk,
output clk_out );
parameter    DIV_N;
reg [4:0] cnt_p;
reg [4:0] cnt_n;
reg clk_p;
reg clk_n;
always@(posedge clk or negedge rstn) begin
    if(!rstn)
     cnt_p <= 5'b0;
 else if(cnt_p == DIV_N-1)
     cnt_p <= 5'b0;
 else
     cnt_p <= cnt_p + 1'b1;
end
always@(negedge clk or negedge rstn) begin
    if(!rstn)
     cnt_n <= 5'b0;
 else if(cnt_n == DIV_N-1)
     cnt_n <= 5'b0;
 else
     cnt_n <= cnt_n + 1'b1;
end
always@(posedge clk or negedge rstn) begin
    if(!rstn)
     clk_p <= 1'b0;
 else if((cnt_p == (DIV_N-1'b1)/2 -1) || (cnt_p == (DIV_N-1)))
     clk_p <= ~clk_p;
end
always@(negedge clk or negedge rstn) begin
    if(!rstn)
     clk_n <= 1'b0;
 else if(cnt_n==(DIV_N-1'b1)/2 -1 || cnt_n == (DIV_N-1))
     clk_n <= ~clk_n;
end
assign clk_out = clk_n & clk_p;
endmodule

3. 半整数分频

说明:占空比非50%
网上广为流传的一种分频结果是,半分频多出来那半个周期为高电平,其余为低电平。例如N=5.5,以原时钟的一半为单位,可以分频输出1高10低。原理是用计数器循环计数0-10即11个周期,控制输出X前6周期高电平,后5周期低电平,然后再使用计数器得到一个下降沿触发的5低6高的输出Y,最后输出Z = X&Y。
在这里插入图片描述
代码如下:

`timescale 1ns/1ps
module for_practice(
input clk,
input arst,
output  clk_div         
    );
parameter N = 5;//5.5分频
reg[31:0]cnt1;
reg clkx;
reg clky;
always@(posedge clk or posedge arst)
begin
    if(arst)
        cnt1 <= 0;
    else if(cnt1 == 2*N)
        cnt1 <= 0;
    else
        cnt1 <= cnt1+ 1;          
end
always@(posedge clk or posedge arst)
begin
    if(arst)
        clkx <= 0;
    else if(cnt1 == 2*N)//
        clkx <= 1;
    else if(cnt1 == N)///
        clkx <= 0;          
end
always@(negedge clk or posedge arst)
begin
    if(arst)
        clky <= 0;
    else if(cnt1 == 0)///
        clky <= 0;
    else if(cnt1 == N)//
        clky <= 1;          
end
assign clk_div =  clkx & clky;
endmodule 

另外一种做法是想得到接近50%的占空比,例如5分频得到3个高电平,2.5个低电平,其思路是控制clk,使得计数器值等于某一值只保持半个周期。

4. 分数(小数分频)

说明:占空比非50%

比如8.7分频。因为没办法用计数器表示0.7这种数字,所以就用一个等效的概念来进行8.7分频,原时钟87个周期的总时间等于分频后的时钟10个周期的总时间;
先做3次8分频得到时钟周期数是24,再做7次9(8加1)分频得到时钟周期数63,总共就87个时钟周期;在这87个时钟周期里面分频时钟跳变20次总共10个周期。分数分频器的原理可以用下图来概括。
图5分数分频的原理
用整数部分zn(=8)作为一个分频系数,zn加1(=9)作为另外一个分频系数组成一个小数分频器。
根据上面的原理可以列出下面的二元一次方程组
zn*N+(zn+1)*M=87 ……(1)
N+M=10 ……(2)
可以解出N和M的值分别是3和7。
ACC计数器设计,在这里ZN=8:
ACC计数器就是控制做N次ZN分频和M次ZN+1次分频,具体控制过程可以分为以下几种情况:
第1种情况 :先做N次ZN分频,再做M次ZN+1次分频;
第2种情况: 先做M次ZN+1次分频,再做N次ZN分频;
第3种情况 :把N次ZN分频平均插入到M次ZN+1分频中;
第4种情况 :把M次ZN+1次分频平均插入到N次ZN分频中。
组合N次ZN分频和M次ZN+1次分频的情况很多。第1、2种情况前后时钟频率不太均匀,因此相位抖动比较大;
第3、4种情况前后时钟频率均匀性稍好,因此相位抖动会减小,因此最终采用3或4。下图
分数分频的几种控制过程
在这里插入图片描述

最后

以上就是难过中心为你收集整理的用verilog实现偶数,奇数,半整数,分数(小数)分频用verilog实现偶数,奇数,半整数,分数(小数)分频4. 分数(小数分频)的全部内容,希望文章能够帮你解决用verilog实现偶数,奇数,半整数,分数(小数)分频用verilog实现偶数,奇数,半整数,分数(小数)分频4. 分数(小数分频)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部