Foreword

距离上一篇CSDN又有两个月了,这两个月学了好多,感觉这半年我还是有很大进步了的,没有一开始那么心力憔悴了。但是水管依旧到处漏……

最近和老虞还有刘同学吃饭,两个不同领域下的大佬,一个做考古,一个做AI,虽然聊的内容差异巨大,但两个人给我的感触都是,他们好厉害,小汤要好好努力!同时也让我想到了,世界可以分为哲学和数学,但最后都会归结于美学。我身边几个特别厉害的程序员,往往审美也是很好的,可能不是那么艺术,但做出来的东西一定是让人看着舒服的。

分频原理

首先推荐一个画波形原理图的在线网站WaveDrom Online Editor,他们家也有软件可以下载WaveDrom Download Github,使用方法在他家官网上也有介绍Tutorial,可以保存多种格式: json/png/svg,很好用。

在时序电路里,一般系统时钟都是高频的,不同外设对时钟频率的要求不同,所以需要通过分频来获得相应的时钟频率,一般都是将高频的时钟转换为低频的时钟。最简单的分频就是2分频,也就是把时钟频率减半,输出时钟和输入时钟上升沿对齐,波形图是这样的:


当然也会有遇到需要奇数分频的时候,这时候上升沿和下降沿都需要用到,3分频波形图是这样的:

上面两张图都是50%占空比的,有的时候我们只需要用输出时钟的上升沿,不需要考虑下降沿,这样的话我们的输出时钟只需要是单脉冲的就可以了,设计的时候会简单很多,单脉冲的3分频波形图是这样的:

50%占空比的偶数分频方法

偶数分频又可以分成两种,一种是2的倍数,一种是2的次方。当分频系数是2的次方时,分频的方法会简单很多。这里还是要吐槽一下,CSDN为什么不支持verilog语法!!!

  • 2的倍数分频

    原理:

    1. 计数器在时钟上升沿+1,加到对应分频系数后,清零
    2. clkOut在计数器记到(N-1)/2和N-1的地方翻转
    3. 当分频系数为0或1时,clkOut = clkIn
    `define __DIVEVEN_V__module DivEven #(
    parameter PRRWIDTH = 4
    )(
    input  wire                 clk,
    input  wire                 rst,    // negetive valid
    input  wire                 en,
    input  wire [PRRWIDTH-1:0]  prr,output reg                  clkOut
    );reg  [PRRWIDTH-1:0]           cnt;
    wire [PRRWIDTH-1:0]         cntValue;
    wire                        direct;// when prr is 0 or 1, clkOut = clk directly
    assign  direct = (prr == {PRRWIDTH{1'b0}}) | (prr == {{(PRRWIDTH-1){1'b0}}, 1'b1});
    assign  cntValue = direct ? {PRRWIDTH{1'b0}} : (prr - 1'b1);// positive edge count
    always @(posedge clk or negedge rst) beginif (!rst) begincnt <= {PRRWIDTH{1'b0}};endelse if (!en) begincnt <= {PRRWIDTH{1'b0}};endelse if (cnt == cntValue) begincnt <= {PRRWIDTH{1'b0}};endelse begincnt <= cnt + 1'b1;end
    end// overturn clkOut when cnt = (cntValue - 1) / 2 or cntValue
    always @(posedge clk or negedge rst) beginif (!rst) beginclkOut <= 1'b0;endelse if (!en) beginclkOut <= 1'b0;endelse if (direct) beginclkOut <= clk;endelse if ((cnt == (cntValue >> 1)) || (cnt == cntValue)) beginclkOut <= !clkOut;end
    endendmodule
    
  • 2的次方分频

    原理:

    1. 计数器在时钟上升沿+1,加到全1后,清零
    2. cnt[0]的值是2分频,cnt[1]的值是4分频,cnt[2]的值是8分频
    3. 例如4分频,每两个clkIn上升沿,cnt[1]翻转一次,所以得到4分频后的clkOut
    `define __DIVEVEN_V__module DivEven (
    input  wire                 clk,
    input  wire                 rst,    // negetive valid
    input  wire                 en,
    input  wire [1:0]           div,// div = 0 means prr = 0;// div = 1 means prr = 2;// div = 2 means prr = 4;// div = 3 means prr = 8;output wire                 clkOut
    );reg  [2:0]    cnt;assign clkOut = (!rst | !en)   ? 1'b0     :div == 2'b00    ? clk       :div == 2'b01    ? cnt[0]    : // prr = 2div == 2'b10    ? cnt[1]    : // prr = 4div == 2'b11    ? cnt[2]    : // prr = 81'b0;// positive edge count
    always @(posedge clk or negedge rst) beginif (!rst) begincnt <= 3'b000;endelse if (!en) begincnt <= 3'b000;endelse if (cnt == 3'b111) begincnt <= 3'b000;endelse begincnt <= cnt + 1'b1;end
    endendmodule
    

50%占空比的任意整数分频方法

原理:

  1. 偶数的时候只用上升沿得到的时钟,奇数的时候将上升沿得到的时钟和下降沿得到的时钟并起来
  2. 上升沿得到的时钟和下降沿得到的时钟都是在计数器记到(N-1)/2和N-1的地方翻转
  3. 当分频系数为0或1时,clkOut = clkIn

`define __DIV50PCT_V__module Div50Pct #(parameter PRRWIDTH = 4
)(input  wire                   clk,input  wire                 rst,    // negetive validinput  wire                    en,input  wire  [PRRWIDTH-1:0]  prr,output wire                 clkOut
);reg  [PRRWIDTH-1:0]           cntP;reg  [PRRWIDTH-1:0]            cntN;reg                            clkP;reg                            clkN;wire [PRRWIDTH-1:0]            cntValue;wire                       direct;// when prr is 0 or 1, clkOut = clk directlyassign  direct = (prr == {PRRWIDTH{1'b0}}) | (prr == {{(PRRWIDTH-1){1'b0}}, 1'b1});assign   cntValue = direct ? {PRRWIDTH{1'b0}} : (prr - 1'b1);// when prr is odd, clkOut = clkP || clkN// when prr is even, clkOut = clkPassign  clkOut = direct ? clk : (prr[0] ? (clkP | clkN) : clkP);// positive edge countalways @(posedge clk or negedge rst) beginif (!rst) begincntP <= {PRRWIDTH{1'b0}};endelse if (!en) begincntP <= {PRRWIDTH{1'b0}};endelse if (cntP == cntValue) begincntP <= {PRRWIDTH{1'b0}};endelse begincntP <= cntP + 1'b1;endend// positive edge clock// overturn clkP when cntP = (cntValue - 1) / 2 or cntValuealways @(posedge clk or negedge rst) beginif (!rst) beginclkP <= 1'b0;endelse if (!en) beginclkP <= 1'b0;endelse if (direct) beginclkP <= 1'b0;endelse if ((cntP == (cntValue >> 1)) || (cntP == cntValue)) beginclkP <= !clkP;endend// negetive edge count for odd prralways @(negedge clk or negedge rst) beginif (!rst) begincntN <= {PRRWIDTH{1'b0}};endelse if (!en) begincntN <= {PRRWIDTH{1'b0}};endelse if (prr[0]) beginif (cntN == cntValue) begincntN <= {PRRWIDTH{1'b0}};endelse if (cntP != {PRRWIDTH{1'b0}})begincntN <= cntN + 1'b1;endendelse begincntN <= {PRRWIDTH{1'b0}};endend// negetive edge clock for odd prr// overturn clkN when cntN = (cntValue - 1) / 2 or cntValuealways @(negedge clk or negedge rst) beginif (!rst) beginclkN <= 1'b0;endelse if (!en) beginclkN <= 1'b0;endelse if (direct) beginclkN <= 1'b0;endelse if (prr[0]) beginclkN <= ((cntN == (cntValue >> 1)) || (cntN == cntValue)) ? !clkN : clkN;endelse beginclkN <= 1'b0;endendendmodule

单脉冲的任意整数分频方法

思路:

  1. 计数器在时钟上升沿+1,加到对应分频值后,clkOutReg拉高,计数器清零
  2. 计数器清零后,clkOutReg拉低
  3. 当clkOutReg和clk都为高时,clkOut为高
  4. 当分频系数为0或1时,clkOut = clkIn
`define __DIVSINGLEPULSE_V__module DivSinglePulse #(parameter PRRWIDTH = 4
)(input  wire                   clk,input  wire                 rst,    // negetive validinput  wire                    en,input  wire  [PRRWIDTH-1:0]  prr,output wire                 clkOut
);reg                           clkOutReg;reg  [PRRWIDTH-1:0]           cnt;wire [PRRWIDTH-1:0]         cntValue;wire                       direct;// when prr is 0 or 1, clkOut = clk directlyassign  direct = (prr == {PRRWIDTH{1'b0}}) | (prr == {{(PRRWIDTH-1){1'b0}}, 1'b1});assign   cntValue = direct ? {PRRWIDTH{1'b0}} : (prr - 1'b1);assign   clkOut = direct ? clk : clkOutReg & clk;// positive edge countalways @(posedge clk or negedge rst) beginif (!rst) begincnt <= {PRRWIDTH{1'b0}};endelse if (!en) begincnt <= {PRRWIDTH{1'b0}};endelse if (cnt == cntValue) begincnt <= {PRRWIDTH{1'b0}};endelse begincnt <= cnt + 1'b1;endend// clkOut is high when cnt == cntValuealways @(posedge clk or negedge rst) beginif (!rst) beginclkOutReg <= 1'b0;endelse if (!en) beginclkOutReg <= 1'b0;endelse if (direct) beginclkOutReg <= 1'b0;endelse if (cnt == cntValue) beginclkOutReg <= 1'b1;endelse beginclkOutReg <= 1'b0;endendendmodule

代码下载

以上代码及testbench都可以在verilog任意整数分频及测试.zip中下载噢!

Conclusion

12月到处都是节日的氛围,相信圣诞老人,相信爱、童话和魔法。

昨晚听了Westlife线上演唱会,感觉回到了初中的时候,Seasons in the Sun可能是我最早接触的英文歌。十多年过去了,我工作了,西城男孩也有了岁月的痕迹。They have raised me up and hope to see them once again.

Verilog 任意整数分频器相关推荐

  1. Verilog任意整数分频器

    Verilog任意整数分频器 Verilog任意整数分频器 偶数分频 奇数分频 两种情况结合一下 在实际设计中有的时候需要简单的任意整数分频器,整数分频器主要解决两种情况下的分频,一个是偶数分频,另一 ...

  2. Verilog实现---1/x任意整数分频器通用代码

    目录 1.偶数分频 2.奇数分频 3.代码文件说明 4.端口说明 5.测试&波形 6.代码 7.Reference 1.偶数分频 对于占空比为50%,分频系数为N的偶数分频,其核心思想是使用计 ...

  3. <Verilog实现数字分频器> 偶数分频器

    一,内容介绍 分频器是数字电路的常见IP,将高频时钟分为低频时钟信号以供外设使用. 下面我们用verilog实现一个偶数分频器 进一步结合奇数分频器组合为整数分频器 再一步升级为小数分频器 二,数字分 ...

  4. 任意整数分频(图文并茂)

    上一篇文章讲解了如何进行任意的奇分频和任意的偶分频,这篇文章主要讲解占空比为50%的任意整数分频(奇分频和偶分频),下面首先以6分频和5分频来回顾一下奇偶分频. 偶分频 偶分频时最简单的,通过下图就可 ...

  5. matlab x为整数,关于matlab中用什么字符表示任意整数

    matlab做除法,怎么取整数? 方法一: floor(a/b);就是舍去小数点. ceil(a/b)就是舍去小数点+1的数. 方法二: fix(x)截尾取整 fix(x)不超过x的最大整数 ceil ...

  6. java 五个数字_关于java:五个任意整数找出其中第二大的数字

    package comxaqf.w02_objectoriented.a_saturday1030; import java.util.Scanner; /** [题6] 6.五个任意整数,找出其中第 ...

  7. 20210916:Verilog的整数类型易错点

    Verilog的整数类型表示易错点 对比类型 仿真结果 易错点分析 总结 对比类型 分析以下四个值的结果: wire [31:0] A; wire [31:0] B; wire [31:0] C; w ...

  8. C语言随笔小算法:取出一个任意整数的每一位数值

    C语言随笔小算法:取出一个任意整数的每一位数值 代码: #include "stdlib.h" #include "stdio.h"//将val的各位取出来 i ...

  9. mysql编写1到n的奇数和_编写程序。输入任意整数n,计算1到n的奇数和

    编写程序.输入任意整数n,计算1到n的奇数和以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 编写程序.输入任意整数n,计 ...

  10. python求1到n的奇数和_编写程序。输入任意整数n,计算1到n的奇数和。C语言编写程序 输入整数N 显...

    编写程序.输入任意整数n,计算1到n的奇数和. C语言编写程序 输入整数N 显 www.zhiqu.org 时间: 2020-11-23 解题思路:循环判断1到N的每一个数: 若除以2是结果为整数,也 ...

最新文章

  1. WiresShark 使用方法
  2. axios请求接口http_Vue使用Axios实现http请求以及解决跨域问题
  3. 网络营销——营销型网站如何在网络营销大环境中展开宣传与推广
  4. 创建springboot出现error:connection timed out创建springboot报错显示连接超时解决方案
  5. Linux下查看文件内容
  6. 用VC++修改注册表----让我们踏出第一步(适合初学者)
  7. LeakCanary上传 leak trace 到服务器
  8. jQuery.Validate 验证,以及 remote验证, 多参数传递
  9. rabbitmq的通配符模式(Topic Exchange)的*和#区别
  10. Postgres 数据库字符集更改 ERROR: new encoding (UTF8) is incompatible
  11. 大漠综合工具取点阵显示不全_利用pyfolio工具评价回测资金曲线
  12. CLOSE_WAIT状态的原因与解决方法
  13. 电商的运营模式流程(最全解析电商运营模式)
  14. html网页加线条,「网站特效」html5 canvas粒子线条特效制作方法
  15. 倪光南院士:网络安全和信息化要同步推进
  16. The error occurred while setting parameters
  17. 美区苹果id绑定QQ邮箱教程
  18. html飞机大战游戏实验报告,飞机大战实验报告.docx
  19. SEO怎么做?SEO的具体流程是什么?
  20. Latex中BibTex编辑参考文献

热门文章

  1. scrapy_redis分布式爬虫遇到的问题DEBUG: Filtered offsite request to
  2. php判断是否连续出现数字,php通过gbk编码判断 含有连续数字 可用于判断QQ号,手机号等。...
  3. C#实现右下角弹窗效果
  4. 小程序通过background-image设置背景图片
  5. 魔兽TBC常用WA字符串收集
  6. python之Scrapy 的Xpath常用定位相关
  7. 直播问答的后博弈时代:社交化或许才是未来
  8. 卷积神经网络(CNN)详解
  9. 虚拟机搭建Harbor安装和简单使用
  10. html - <thead>标签