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

发布于:2022-12-07 ⋅ 阅读:(943) ⋅ 点赞:(0)

目录

格雷码介绍

转化原理

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,可以看到格雷码相邻的数据都只变化一位,并且重新转化为二进制码的数据也和输入的数据一致,设计正确!

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到