【Verilog 常见设计】(0)二进制码和格雷码互转 Verilog 实现

2023-11-12

目录

格雷码介绍

转化原理

Verilog 实现

testbench 测试代码

仿真波形


格雷码介绍

在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。在数字系统中,常要求代码按一定顺序变化。例如,按自然数递增计数,若采用8421码,则数0111变到1000时四位均要变化,而在实际电路中,4位的变化不可能绝对同时发生,则计数中可能出现短暂的其它代码(1100、1111等)。在特定情况下可能导致电路状态错误或输入错误。使用格雷码可以避免这种错误。

在常见的 IP 设计中就会用到格雷码,比如异步 FIFO 的实现,在读时钟域同步到写时钟域或写时钟域同步到读时钟域时,就需要将数据由二进制码转化为格雷码,转化后的数据响相邻数据之间只有一位不同,这样就大大降低了数据同步时出错的概率。

以下为四位二进制码和格雷码之间的对应关系:

Decimal

Binary

Gray Code

0

0000

0000

1

0001

0001

2

0010

0011

3

0011

0010

4

0100

0110

5

0101

0111

6

0110

0101

7

0111

0100

8

1000

1100

9

1001

1101

10

1010

1111

11

1011

1110

12

1100

1010

13

1101

1011

14

1110

1001

15

1111

1000

可以很明显的看出,随着数值增大,格雷码相邻数之间的差别只有一位之差,下面介绍二进制码和格雷码之间是如何互相转化的。

转化原理

二进制码转格雷码

如下图所示,二进制码转格雷码,格雷码的最高位和二进制的最高位一致,次高位为二进制的最高位和次高位的异或结果,同理可得格雷码最低位为二进制码的第1位和第0位的异或结果。

格雷码转二进制码

如下图所示,格雷码转二进制码,二进制码的最高位和格雷码的最高位一致,次高位为格雷码的最高位和二进制码的次高位的异或结果,同理可得格雷码最低位为格雷码的第1位和二进制码的第0位的异或结果。

Verilog 实现

二进制码转格雷码

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Engineer    : Linest-5                                                         
/* File        : bin2gray.v                                                         
/* Create      : 2022-08-30 15:35:07
/* Revise      : 2022-08-30 15:35:07                                                  
/* Module Name : bin2gray                                                  
/* Description : 二进制码转格雷码                                                                         
/* Editor : sublime text3, tab size (4)                                                                                
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

module bin2gray#(	
	parameter  DATA_WIDTH  =  'd8
	)(
	input   [DATA_WIDTH-1:0]    bin_code,
	output  [DATA_WIDTH-1:0]    gray_code   
	);

generate
	genvar i;
	for (i=0;i<DATA_WIDTH-1;i=i+1) begin
		assign gray_code[i] = bin_code[i+1] ^ bin_code[i];
	end
endgenerate

assign gray_code[DATA_WIDTH-1] = bin_code[DATA_WIDTH-1];

endmodule

格雷码转二进制码

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Engineer    : Lqc                                                         
/* File        : gray2bin.v                                                         
/* Create      : 2022-08-30 15:09:27
/* Revise      : 2022-08-30 15:09:27                                                  
/* Module Name : gray2bin                                                  
/* Description : 格雷码转二进制码                                                                         
/* Editor : sublime text3, tab size (4)                                                                                
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

module gray2bin#(
	parameter  DATA_WIDTH  =  'd8
	)(
	input   [DATA_WIDTH-1:0]    gray_code,
	output  [DATA_WIDTH-1:0]    bin_code   
	);

generate
	genvar i;
	for (i=0;i<DATA_WIDTH-1;i=i+1) begin
		assign bin_code[i] = bin_code[i+1] ^ gray_code[i];
	end
endgenerate

assign bin_code[DATA_WIDTH-1] = gray_code[DATA_WIDTH-1];

endmodule

testbench 测试代码

将两个模块都例化到测试模块中,输入二进制码转化成格雷码,然后再转化回二进制码,以此来验证两个模块的设计正确性。

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Engineer    : Lqc                                                         
/* File        : tb_bin_gray.v                                                         
/* Create      : 2022-08-30 15:40:10
/* Revise      : 2022-08-30 15:40:10                                                  
/* Module Name : tb_bin_gray                                                  
/* Description : 二进制码和格雷码互转仿真模块                                                                         
/* Editor : sublime text3, tab size (4)                                                                                
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
`timescale 1ns/1ps
module tb_bin_gray();

reg   [7:0]     bin_code_in;
wire  [7:0]     gray_code_out;
wire  [7:0]     bin_code_out;

//每10个单位时间输入的数据加1
integer i;
initial begin
	for (i=0;i<256;i=i+1) begin
		bin_code_in = #20 i;
	end
end 

//例化二进制码转格雷码模块
bin2gray #(
	.DATA_WIDTH(8)
) inst_bin2gray 
(
	.bin_code(bin_code_in), 
	.gray_code(gray_code_out)
);

//例化格雷码转二进制码模块
gray2bin #(
	.DATA_WIDTH(8)
) inst_gray2bin 
(
	.gray_code(gray_code_out), 
	.bin_code(bin_code_out)
);

endmodule

仿真波形

依次输入8位二进制数据 0-255,可以看到格雷码相邻的数据都只变化一位,并且重新转化为二进制码的数据也和输入的数据一致,设计正确!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Verilog 常见设计】(0)二进制码和格雷码互转 Verilog 实现 的相关文章

  • 计算数组中的个数

    我试图在 Verilog 中计算 4 位二进制数中 1 的数量 但我的输出是意外的 我尝试了几种方法 这是我认为应该有效的方法 但事实并非如此 module ones one in input 3 0 in output 1 0 one a
  • 比较数字进行排序然后得到中值

    使用按位或比较运算符对五个整数进行排序可以通过以下方式实现 首先获取最大的数字 然后获取第二大的数字 然后获取第三大的数字 依此类推 这是我获取最高数字的代码 include
  • 带有always_comb结构的Systemverilog问题

    我对这个 SystemVerilog 代码有疑问 这是代码 module mult multiplicand multiplier Product clk clear Startm endm input 31 0 multiplicand
  • 如何在 Verilog 中定义带参数的模块?

    我想定义一个add有一个参数的模块 但我对新实例的声明进展不顺利 我想定义这个模块的一个实例 module add parameter wd 1 input wire wd 1 0 a b output wire wd 1 0 o assi
  • 如何使用触发器输出作为复位信号的输入

    我在柜台里放了 3D 触发器 一旦达到 5 101 我想将 FF 复位输入设置为高 使用或门 复位为低电平有效 这几乎可以工作 但是 当我最初运行程序时 触发器的 Q 输出都是未知的 因此 最初 或门的复位输入为低电平 但是 因为一开始 Q
  • 如何使用 Verilog 宏模拟 $display?

    我想创建一个具有多个参数的宏 就像 display 一样 我的代码看起来像这样 但它不起作用 define format macro A write s sformatf A 这就是我调用 format macro 的方式 format m
  • Verilog、FPGA、统一寄存器的使用

    我有一个问题 关于我正在开发的 AGC SPI 控制器在我看来奇怪的行为 它是用 Verilog 完成的 针对的是 Xilinx Spartan 3e FPGA 该控制器是一个依赖外部输入来启动的 FSM FSM的状态存储在状态寄存器它没有
  • 使用数据流模型的T触发器

    我正在尝试模拟 t flipflop 的工作 timescale 1ns 1ps module t flipflop input t input clk input clear output q output qbar wire sbar
  • Vivado 比特流消息:违反规​​则 (LUTLP-1) 组合循环

    我在串流时遇到问题 该项目旨在创建一个占空比为 1 2 的时钟 综合和实现过程中没有任何问题 我尝试了几种方法来解决它 但他们的表现并不好 module clock div clk clk out input clk output reg
  • [Verilog] Verilog 基本格式和语法

    主页 元存储博客 全文 3000 字 文章目录 1 声明格式 1 1 模块声明 1 2 输入输出声明 1 3 内部信号声明 1 4 内部逻辑声明
  • 「Verilog学习笔记」游戏机计费程序

    专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点 刷题网站用的是牛客网 timescale 1ns 1ns module game count input rst n 异位复位信号 低电平有效 input clk 时
  • 基于FPGA的简易BPSK和QPSK

    1 框图 2 顶层 3 m generator M序列的生成 输出速率为500Kbps 4 S2P是串并转换模块 将1bit的m序列转换到50M时钟下的2bit M序列数据 就有4个象限 5 my pll是生成256M的时钟作为载波 因为s
  • 修改后的 baugh-wooley 算法乘法 verilog 代码不能正确乘法

    以下 verilog 源代码和 或测试平台可以很好地工作商业模拟器 iverilog https www edaplayground com x 3TuQ也形式化验证工具 yosys smtbmc https gist github com
  • DSCA190V 57310001-PK

    DSCA190V 57310001 PK DSCA190V 57310001 PK 具有两个可编程继电器功能 并安装在坚固的 XP 外壳中 DSCA190V 57310001 PK 即可使用 只需最少的最终用户校准 DSCA190V 573
  • 在 Verilog 中判断总线是否包含单个 x 的最佳方法是什么?

    我有一个监控总线的测试台 总线内的一些信号 位 可以是 1 bx 由于多种原因 我需要知道总线内是否有任何信号是 1 bx 如果总线包含任何 x 测试 不用于综合 仅用于模拟目的 的最佳方法是什么 我曾希望我可以使用减少或然后使用 但这似乎
  • 在 Verilog 设计中产生时钟故障

    我正在使用 Verilog 设计芯片 我有一个 3 位计数器 我希望当计数器处于第 8 次循环时 应该有一个时钟故障 之后就可以正常工作了 在 Verilog 设计中产生时钟故障的可能方法是什么 在时钟信号上注入毛刺的一种方法是使用forc
  • 为什么 Verilog 不被视为编程语言? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 教授在课堂上说学生不应该说他们学会了用Verilog 编程 他说 Verilog 之类的东西不是用来编程的 而是用来设计的 那么 Verilog
  • 在 Verilog 程序中使用连续分配?

    在 Verilog 程序中使用连续赋值是否可能和 或有用 例如 是否有任何理由将assign里面一个always堵塞 例如这段代码 always begin assign data in Data end 此外 是否可以用这种方法生成顺序逻
  • reg 声明中的位顺序

    如果我需要使用 4 个 8 位数字 我会声明以下 reg reg 7 0 numbers 3 0 我对第一个和第二个声明 7 0 和 3 0 之间的区别感到很困惑 他们应该按什么顺序来 第一个是保留数字的大小 而第二个是保留数字的数量 还是
  • 具有内部赋值延迟的阻塞和非阻塞语句之间的区别

    以下 2 个 verilog 代码片段有什么区别 1 always in out 5 in AND 2 always in out lt 5 in 考虑到always块中不存在其他行 输出会有什么不同吗 问题参考幻灯片 16 参见 o5 和

随机推荐

  • C++中结构体、公用体在内存单元占用字节数计算

    一 数据类型所占存储空间对比 数据类型 64位机 32位机 char 1个字节 1个字节 short 2个字节 2个字节 int 4个字节 4个字节 long 8个字节 4个字节 float 4个字节 4字节 double 8个字节 8个字
  • 软件外包开发代码管理工具

    软件代码规范是为了提高代码质量 可读性和可维护性而制定的一系列编程规则和约定 代码管理工具则是用于协助团队成员共享 跟踪和合并代码的工具 今天和大家分享这方面的知识 希望对大家有所帮助 北京木奇移动技术有限公司 专业的软件外包开发公司 欢迎
  • 魅族大数据可视化平台建设之路

    本文是根据魅族科技大数据平台架构师赵天烁3月31日在msup携手魅族主办的第十二期魅族技术开放日 魅族大数据可视化平台建设之路 演讲中的分享内容整理而成 内容简介 本文主要从现状 问题 当前目标 实现方案三个方面介绍了可视化平台的建设之路
  • Python点云处理(二)点云数据可视化

    目录 0 简述 1 matplotlib 1 1 安装 1 2 点云可视化 2 Mayavi 3 Open3D 4 Vispy 5 VTK 6 结语 0 简述 点云可视化是数据分析 数据展示及程序集成的基础性功能 Python提供了许多强大
  • Error:Abnormal build process termination:

    Error Abnormal build process termination C Program Files Java jdk1 8 0 121 bin java Xmx700m Djava awt headless true Djav
  • 分布式计算框架Spark集群实战

    一 Spark整体架构 1 Spark集群架构 从集群部署的角度看 Spark集群由集群管理器 Cluster Manager 工作节点 Worker 执行器 Executor 驱动器 Driver 应用程序 Application 等部分
  • 1.8,strerror和perror

    这个例子主要是报错 其实 我不大注重报错的差异 只要知道大概在哪里出错就行了 先抄代码 运行 ok
  • clone()

    深复制 浅复制
  • css选择器

    css选择器 1 选择器的作用 找到特定的HTML标签元素 选择所需要的标签 2 基础选择器 2 1标签选择器 作用 可以把一类标签全部选择出来 比如div span标签 快速的为页面中同类型的标签统一化 但是不能设计差异化的样式 div
  • WIN10应用程序无法正常启动(0xc0000142)。请单击‘确认’关闭应用程序

    在网上找了好久解决方法 有说用命令行for 1 in windir system32 dll do regsvr32 exe s 1 来重新注册系统组件 有说删除 appdata microsoft templates 这个目录下的文件 还
  • 软件产品license的简单实现java

    目录 软件License简介 License控制内容 实现方案 代码示例讲解 注意事项 源码 软件License简介 我们在使用一些需要购买版权的软件产品时 或者我们做的商业软件需要进行售卖 为了收取费用 一般需要一个软件使用许可证 然后输
  • 基于Arduino开发板和20×4 I2C LCD显示屏制作一款实时时钟

    当我们在制作一个有趣的硬件项目时 可能会需要使用到一款显示屏 但选择显示屏的尺寸和控制它所需的引脚都令人困惑 在上一篇文章中 我们介绍了0 96寸I2C OLED显示屏 在本篇文章中 我们将介绍使用I2C 20 4字符显示屏 所需的零件 本
  • You are running the esm-bundler build of vue-i18n. It is recommended to configure your bundler to ex

    vue3项目启动之后 会提示如下警告 You are running the esm bundler build of vue i18n It is recommended to configure your bundler to expl
  • 网络编程之channel

    介绍 Channel 是一个对象 可以通过它读取和写入数据 拿 NIO 与原来的 I O 做个比较 通道就像是流 所有数据都通过 Buffer 对象来处理 您永远不会将字节直接写入通道中 相反 您是将数据写入包含一个或者多个字节的缓冲区 同
  • 官网下载Eclipse历史版本

    官网下载Eclipse历史版本 Eclipse官网 downloads路径 https www eclipse org downloads 点击 Download Packages 点击 Download Packages 选择你想要的版本
  • Idea 断点调试PHP

    老实说 我尝试过xdebug 但是说实话 没一次成功过 看来我还是 经验不足 简单的方法 前期工作需要装上xdebug 在php ini 末尾加上 XDebug 这是xdebug的dll 需要到官网上下载 需要注意区分自己的PHP是线程安全
  • Jordan Lecture Note-12: Kernel典型相关分析(Kernel Canonical Correlation Analysis, KCCA).

    Jordan Lecture Note 12 Kernel典型相关分析 Kernel Canonical Correlation Analysis KCCA Kernel典型相关分析 一 KCCA 同样 我们可以引入Kernel函数 通过非
  • 华为培训 05 PON EPON GPON

    学习目标 PON架构 EPON主要技术 GPON主要技术 EPON 基于以太网方式的无源光网络 GPON 千兆无源光网络 1 PON网络加架构
  • 2022电大国家开放大学网上形考任务-客户关系管理非免费(非答案)

    客户关系管理形考作业一答案 试题 1 1 不是常用的市场营销组合理论 A 4C 理论 B 4P 理论 C 4A 理论 D 4S 理论 试题 2 2 企业实施客户关系管理的作用主要体现在提升企业竞争优势 提高客户满意度 以及提升企业销售业绩
  • 【Verilog 常见设计】(0)二进制码和格雷码互转 Verilog 实现

    目录 格雷码介绍 转化原理 Verilog 实现 testbench 测试代码 仿真波形 格雷码介绍 在一组数的编码中 若任意两个相邻的代码只有一位二进制数不同 则称这种编码为格雷码 Gray Code 另外由于最大数与最小数之间也仅一位数