Verilog实现的格雷码与二进制码的互相转换
1、什么是格雷码
格雷码是一种循环二进制码或者叫作反射二进制码。格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变,由于这种特点,就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码常用于通信,FIFO 或者 RAM 地址寻址计数器中。
下表给出了4bit自然二进制码、4bit典型格雷码(无特殊说明,典型格雷码即格雷码)与4bit十进制整数的对照:
可以看到,上表中格雷码的每次变化位数只有一位,这就有效的避免了在CDC情况(跨时钟域情况)下亚稳态问题发生的概率。比如当数字从 7 变为 8 时,4 位二进制数都发生跳变,如果直接使用异步时钟采样这些数字信号,这就很可能会发生亚稳态或者数据采样错误。而采用格雷码,就可以避免 4 位二进 制数都同时发生跳变,导致出现的亚稳态,就算出现亚稳态,最多也就一位出现错误。
但是由于格雷码是一种变权码,每一位码没有固定的大小,所以很难直接进行比较大小和算术运算。
2、二进制转格雷码
二进制码转化为格雷码原理如下:
二进制的最高位作为格雷码的最高位,次高位的格雷码为二进制的高位和次高位相异或得到,其他位与次高位类似。转化过程如下图:
假如是4bit的二进制数据转成格雷码则是:
- gray[3] = 0 ^ bin[3];----gray[3] = bin[3] 异或0等于自身
- gray[2] = bin[3] ^ bin[2];
- gray[1] = bin[2] ^ bin[1];
- gray[0] = bin[1] ^ bin[0];
根据上面的式子不难推到出一般公式:gray = (bin >> 1) ^ bin。根据公式很容易写出二进制码转换为格雷码的Verilog代码:
//二进制转格雷码
module bin2gray
#(parameter data_width = 'd4 //数据位宽
)
(input [data_width - 1 : 0] bin , //二进制output [data_width - 1 : 0] gray //格雷码
); assign gray = (bin >> 1) ^ bin;endmodule
3、格雷码转二进制
格雷码转化为二进制码原理如下:
使用格雷码的最高位作为二进制的最高位,二进制次高位产生过程是使用二进制的高位和次高位格雷码相异或得到,其他位的值与次高位产生过程类似。转化过程如下图:
假如是4bit的格雷码转成二进制则是:
- bin[3] = gray[3] ;
- bin[2] = gray[2] ^ bin[3];
- bin[1] = gray[1] ^ bin[2];
- bin[0] = gray[0] ^ bin[1];
可以看到,最高位不需要转换,从次高位开始使用二进制的高位和次高位格雷码相异或,那么可以使用generate--for来构建重复赋值语,具体代码如下:
//格雷码转二进制
module gray2bin
#(parameter data_width = 'd4 //数据位宽
)
( input [data_width - 1 : 0] gray, //格雷码output [data_width - 1 : 0] bin //二进制
); assign bin[data_width - 1] = gray[data_width - 1]; //最高位直接相等
//从次高位到0,二进制的高位和次高位格雷码相异或
genvar i;
generatefor(i = 0; i <= data_width-2; i = i + 1) begin: gray //需要有名字assign bin[i] = bin[i + 1] ^ gray[i];end
endgenerateendmodule
4、测试
构建一个测试脚本对两个模块进行测试:生成0-15的4bit二进制数据,通过bin2gray转换成格雷码,观察格雷码输出;将转换后的格雷码输出通过gray2bin再转换成2进制码,然后对比三组数据是否符合转换规则。
`timescale 1ns/1ns //时间单位/精度//------------<模块及端口声明>----------------------------------------
module gray_code();
parameter data_width = 'd4; //数据位宽reg [data_width - 1 : 0] bin_in; //生成的二进制码
wire [data_width - 1 : 0] gray; //转换后的格雷码
wire [data_width - 1 : 0] bin_out; //转换后的二进制码//------------<例化被测试模块>----------------------------------------
bin2gray
#(.data_width (data_width)
)
bin2gray_inst(.bin (bin_in ), .gray (gray )
); gray2bin
#(.data_width (data_width)
)
gray2bin_inst(.bin (bin_out ), .gray (gray )
);//------------<设置初始测试条件>----------------------------------------
initial beginbin_in = 4'd0;forever #20 bin_in = bin_in + 1; //每隔20ns累加1
end
//打印输出
initial $monitor("bin_in:%b, gray:%b, bin_out:%b",bin_in,gray,bin_out);endmodule
仿真结果如下:
可以看到两次转换的结果都是正确的,接下来看一下命令窗口打印的输出:
可以看到这个转换结果与第一章的对照表是一致的。
Verilog实现的格雷码与二进制码的互相转换相关推荐
- 数字电路基础知识——格雷码和二进制码的转换的算法和Verilog实现
数字电路基础知识--格雷码和二进制码的转换的算法和Verilog实现 关于数字电路中的码制问题在这篇博客中已经做了详细分析, 数字电路基础知识--数字IC中的进制问题(原码,反码,补码以及各进制的转换 ...
- [Verilog]格雷码与二进制码的相互转换
格雷码与二进制码的相互转换 摘要:在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即"首尾相 ...
- 格雷码与二进制码的相互转换 (python代码实现)
⭐ What? 格雷码 在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即"首尾相连&quo ...
- 格雷码与二进制码转换
格雷码转二进制码 二进制码转格雷码 代码如下 //gray to bin module gray2bin #(parameter ADDR_WIDTH=8)(input [ADDR_WIDTH-1:0 ...
- 【数字电路基础】格雷码、二进制码与格雷码的转换、独热码
文章目录 一. 格雷码 二.二进制码与格雷码的转换 2.1.二进制码转格雷码(编码) 2.2.格雷码转二进制码(解码) 三.代码实现 3.1.`b2g.v`(**二进制码转格雷码**) 3.2.`g2 ...
- 格雷码、二进制码、BCD编码
格雷码 格雷码(12页).pdf 格雷码(12页).pdf-其它文档类资源-CSDN下载 奇偶校验码(25页).pdf 奇偶校验码(25页).pdf-其它文档类资源-CSDN下载 经验:如何快速地写出 ...
- 状态机与独热码、格雷码、二进制码
状态机 简称FSM,也叫同步有限状态机 同步:同步的意思就是在系统时钟的作用下 有限:有限代表状态机中的状态是有限的 根据影响输出分为两大类,一为Moore.二为Mealy Moore:若最后的输出只 ...
- 二进制与格雷码之间的转换的Verilog实现(更多一点的讨论)
目录 前言 二进制码转换为格雷码的方法 格雷码转换为二进制码的过程 更多一点讨论之generate for 更多一点讨论之for 最后对格雷码的介绍 前言 以前的博客也有写这方面的内容,只是没有显式的 ...
- 七种计数器总结(格雷码计数器、环形计数器、约翰逊计数器、FLSR、简易时分秒数字秒表|verilog代码|Testbench|仿真结果)
七种计数器总结 一.可复位/置数计数器 1.1 可复位/置数计数器 1.2 Verilog代码 1.3 Testbench 1.4 仿真结果 二.双向(可加可减)计数器 2.1 双向(可加可减)计数器 ...
- C语言学习:二进制码与格雷码的转换
格雷码,又叫循环二进制码或反射二进制码,格雷码是我们在工程中常会遇到的一种编码方式,它的基本的特点就是任意两个相邻的代码只有一位二进制数不同. 格雷码的基本特点就是任意两个相邻的代码只有一位二进制数不 ...
最新文章
- 安装了ubuntu14.04+windows7双系统的笔记本启动后出现grub rescue提示符
- 织梦dedecms dede plus文件作用介绍及安全设置
- quartus怎么仿真波形_单相半波可控整流电路电阻负载的Matlab Simulink仿真
- apple mach-o linker (id) error
- Python_套接字、IPv4和简单的客户端/服务器编程
- 让服务程序进入demon模式的代码
- mysql固定某列获取不连续的值_SQL-怎么把一列不规律的值,取出其中连续段的首尾数字?...
- 自动驾驶 9-5: EKF 的局限性 Limitations of the EKF
- vivo发布OriginOS Ocean,国产定制系统越来越好了
- python爬虫做灰产_python爬虫
- vsto 批量删除列
- 常见经典音频运放(一般作前级用)
- DHTMLET-Cascading Style Sheet 2.0 中文手册
- 关于码距、检错、纠错
- [c#]图书ISBN信息批量查询工具开发手记
- K8S 数据卷volumes之ConfigMap
- 【软件项目管理】项目建议书是项目立项阶段开发的文档
- Mysql项目 github_GitHub开源项目2018-09-11更新精选
- 【工控安全产品】工业控制系统信息安全检查工具箱
- 【待更新】北京大学肖臻老师《区块链技术与应用》公开课笔记【04-BTC-协议】