格雷码(gray code)的使用

在产生FIFO满信号时,要将写指针和读指针进行比较,由于两个指针分别在各自的时钟域,彼此之间是异步的,在使用二进制进行计数器实现指针时,就会导致用于比较的指针取样错误。

使用自然二进制码计数时,相邻数据之间可能会产生多bit的变化。这会产生较大的尖峰电流以及其他问题。

比如,二进制计数器的值会从FFF变为000。这时所有位会同时改变。虽然能通过同步计数器避免亚稳态,但是仍然能得到极不相关的取样值,所以同步计数器不是最终的解决方案。

从FFF 到000可能的转换:

  • FFF→000
  • FFF→001
  • FFF→010
  • FFF→011
  • FFF→100
  • FFF→101
  • FFF→110
  • FFF→111

如果同步时钟边沿在FFF向000转换的中间位置到来,就可能将三位二进制数的任何值取样并同步到新的时钟域中。鉴于以上情况,强烈建议避免使用二进制计数器实现读、写指针。

格雷码是一种相邻数据只有1bit变化的码制。因此可以使用格雷码去取代二进制计数器,并且用打拍的方式去同步(跨时钟域问题(二)(单bit信号跨时钟域 1. 电平同步器 2. 边沿同步器 3. 脉冲检测器))(只有深度为2的n次方才能用格雷码的方式去同步,这样才能保证最大值和最小值只有一位的变化)。我们可以将指针转为格雷码同步到另一个时钟域再进行比较。如果同步时钟在计数值转换期间到来,这种编码能够消除绝大部分的错误。

图2 格雷码编码计数器

格雷码编码的verilog的实现

自然二进制编码转换为格雷码如下:

图3 二进制转化为格雷码

gray_code=binary_code⊕(binary_code>>1)gray\_code = binary\_code \oplus (binary\_code > > 1)gray_code=binary_code⊕(binary_code>>1)

格雷码转化为自然二进制

图4 格雷码转化为自然二进制


我们以牛客网VL47 格雷码计数器为例!


代码

`timescale 1ns/1nsmodule gray_counter(input                               clk                        ,input                               rst_n                      ,output reg         [   3:0]         gray_out
);reg                    [   3:0]         binary_cnt                 ;
reg                                     flag                       ;always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag <= 1'd0;endelse beginflag <= ~flag;end
end
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginbinary_cnt <= 1'd0;end else beginif (flag == 1'd1) beginbinary_cnt <= binary_cnt + 1'd1;end else beginbinary_cnt <= binary_cnt;endend
endalways @(*) begingray_out <= binary_cnt ^ (binary_cnt >> 1);
endendmodule

牛客网verilog刷题_VL47 格雷码计数器相关推荐

  1. IC笔试牛客网verilog刷题总结四

    47.格雷码计数器 reg [3:0] bin_out;wire [3:0] gray_wire;//格雷码转二进制always@(posedge clk or negedge rst_n)begin ...

  2. IC笔试牛客网verilog刷题总结三

    30.数据串转并电路 reg [2:0]count;always@(posedge clk or negedge rst_n)beginif(~rst_n)begincount <= 3'd0; ...

  3. 牛客网Java刷题知识点之关键字static、static成员变量、static成员方法、static代码块和static内部类...

    不多说,直接上干货! 牛客网Java刷题知识点之关键字static static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个"伪全局"的概 ...

  4. 牛客网Java刷题知识点之构造函数可以调用一般函数,但是一般函数不可以直接调用构造函数...

    不多说,直接上干货! 通过 牛客网Java刷题知识点之构造函数是什么.一般函数和构造函数什么区别呢.构造函数的重载.构造函数的内存图解 我们对构造函数有了一个比较清楚的认识,当我们在创建对象时,我们会 ...

  5. 牛客网Java刷题知识点之Java 集合框架的构成、集合框架中的迭代器Iterator、集合框架中的集合接口Collection(List和Set)、集合框架中的Map集合...

    不多说,直接上干货! 集合框架中包含了大量集合接口.这些接口的实现类和操作它们的算法. 集合容器因为内部的数据结构不同,有多种具体容器. 不断的向上抽取,就形成了集合框架. Map是一次添加一对元素. ...

  6. 牛客网Java刷题知识点之ArrayList 、LinkedList 、Vector 的底层实现和区别

    不多说,直接上干货! 这篇我是从整体出发去写的. 牛客网Java刷题知识点之Java 集合框架的构成.集合框架中的迭代器Iterator.集合框架中的集合接口Collection(List和Set). ...

  7. 牛客网Veirlog刷题答案目录(持续更新)

    牛客网Veirlog刷题答案目录(持续更新) 基础篇 进阶篇 基础篇 1.VL1--四选一多路选择器 2.VL2--异步复位的串联T触发器 3.VL3--奇偶校验 4.VL4--移位运算与乘法 5.V ...

  8. 牛客网java刷题笔记2019-1-4

    牛客网java刷题笔记 2019-1-4 1.java中可以用类中构造器调用其他类构造器(这个和C++中构造函数很类似)用于初始化程序变量值, 构造器和方法的区别: 功能和作用的不同 构造器是为了创建 ...

  9. 牛客网SQL刷题笔记(MySQL)

    牛客网SQL刷题笔记(MySQL) 此博客集合LeetCode.牛客网常见的题型及其解法,侵删 目录 牛客网SQL刷题笔记(MySQL) 类型1:查找排名第几的数据 SQL2 查找入职员工时间排名倒数 ...

最新文章

  1. Java排序算法——希尔排序
  2. AI芯片的过去、现在与未来
  3. rest-framework 解析器
  4. Python自动化运维——系统性能信息模块
  5. The Basics
  6. 背景透明文字不透明的最佳方法兼容IE(以背景黑色透明度0.5为例)
  7. mysql范式与反范式_MySQL 三种范式以及反范式 | 剑花烟雨江南
  8. Java 设置文件只读
  9. 02 掌握实现数据导入导出的方法 1214
  10. vue、cnpm不是内部文件_UBoot链接文件 搞懂程序内部长什么样
  11. 4、HTML 超链接
  12. 没有任何一个行业是没有竞争的
  13. POJ3251 Big Square【水题】
  14. c语言名著摘抄——语法及实例
  15. ASP入门教程 1小时ASP入门,非常简单
  16. java8 利用reduce实现将列表中的多个元素的属性求和并返回
  17. 能考上重本的学生成绩处于什么水平?看完这篇就懂了
  18. linux下Nerdtree安装方法
  19. C语言再学习25——常用字符串函数归纳
  20. Flutter弹起键盘页面布局超限问题以及布局上移问题

热门文章

  1. S3C6410(OK6410开发板介绍)
  2. 获取实时汇率代码片段
  3. request.getParameter() request.getAttribute()区别
  4. python symbols函数_有限元平面四边形等差单元python编程
  5. 论文解读:基于共享混合深度学习架构的DNA形状特征预测转录因子结合位点
  6. ios 自定义拍照页面_iOS开发笔记:自定义相机拍照
  7. uniapp微信小程序老预览失败,或者上传失败(已解决)
  8. 教你快速爬取哔哩哔哩整部番剧的视频弹幕
  9. opencv normalize blur medianBlur
  10. 最流行的Python编辑器/IDEs你认识吗?