柴古香 发表于 2025-6-5 09:21:07

verilog实现格雷码和二进制码的相互转换

目录

[*]格雷码的介绍
[*]二进制码转化为格雷码
[*]格雷码转化为二进制码
[*]verilog实现代码

格雷码的介绍

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

二进制码转换成二进制格雷码,其法则是保留二进制码的最高位作为格雷码的最高位,而次高位格雷码为二进制码的高位与次高位相异或,而格雷码其余各位与次高位的求法相类似。
假设有n位二进制数:
n位二进制数Bn-1Bn-2Bn-3...B1B0其转化位相应n位格雷码的转化法则为:
n位格雷码Gn-1Gn-2Gn-3...G1G0转化规则Bn-1Bn-1^Bn-2Bn-2^Bn-3...B2^B1B1^B0在verilog中,假设有 logic bin; logic grey;
则有:
binBn-1Bn-2Bn-3...B1B0bin>>10Bn-1Bn-2Bn-3...B1greyBn-1^0Bn-1^Bn-2Bn-2^Bn-3...B2^B1B1^B0greyBn-1Bn-1^Bn-2Bn-2^Bn-3...B2^B1B1^B0因为Bn-1^0=Bn-1,所以在verilog中,我们可以用下面的几行代码,得到二进制编码到格雷码的转化:
logic bin;
logic grey
assign grey = bin ^ (bin>>1);格雷码转化为二进制码

从前面二进制码转化为格雷码法则,我们知道
Gn-i=Bn-i+1^Bn-i
则有
Bn-i+1^Gn-i = Bn-i+1 ^ Bn-i+1 ^ Bn-i
Bn-i+1 ^ Gn-i = 0 ^ Bn-i-1= Bn-i
所以格雷码转化为二进制码的规则为:
n位二进制Bn-1Bn-2Bn-3...B1B0转化规则Gn-1Gn-2^Bn-1Gn-3^Bn-2...G1^B2B0^B1在verilog中我们可以用一个generate块内循环实现转换
//从次高位到0,二进制的高位和次高位格雷码相异或
genvar i;
generate
        for(i = 0; i <= DATA_WIDTH-2; i = i + 1)
                begin:
                        assign bin = bin ^ grey;
                end
endgenerate在vscode中执行以下命令,编译code,打开波形文件:
`timescale 1ns/1ps       

module grey_tb;

        logic clk=0;

        always #5 clk = ~clk;

        initial begin

            $display("start a clock pulse");
            $dumpfile("grey.vcd");
            $dumpvars(0, grey_tb);
                   #300 $finish;
        end

        logic bin;
        logic grey;
        logic bin2;

        logic bin_1=0;
        logic grey_1;
        logic bin2_1;

        initial begin

// 重复执行10次随机数生成过程
                repeat(10) begin
                        @(posedge clk) begin

                        bin <= $random();

                        end
                end
// 重复执行32次的循环,用于对bin_1进行自增操作
                repeat(32) begin
                        @(posedge clk) begin

                        bin_1 <= bin_1+1;

                        end
                end

        end

        bin2grey #(.DATA_WIDTH(8)) bin2grey_inst(.bin(bin),.grey(grey));
        grey2bin #(.DATA_WIDTH(8)) grey2bin_inst(.grey(grey),.bin(bin2));

        bin2grey #(.DATA_WIDTH(8)) bin2grey_inst1(.bin(bin_1),.grey(grey_1));
        grey2bin #(.DATA_WIDTH(8)) grey2bin_inst1(.grey(grey_1),.bin(bin2_1));

endmodule


//二进制转格雷码
module        bin2grey
#(
        parameter DATA_WIDTH=8
)
(
        input wire bin,

        output logic grey

);                                                            

        assign grey = bin ^(bin>>1);

endmodule

//格雷码转二进制码
module grey2bin
#(
        parameter DATA_WIDTH=8
)
(
        input wire grey,

        output logic bin

);                                                            

        assign bin = grey;

genvar i;
generate
        for(i=DATA_WIDTH-2;i>=0;i=i-1) begin
                assign bin = bin ^ grey;
        end
endgenerate


endmodule
可以看到二进制码先转化为格雷码,再转回二进制码,得到期望的值。而且相邻数的格雷码确实是只差1位数。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

背竽 发表于 2025-12-19 00:28:33

感谢分享,学习下。

博咱 发表于 2025-12-21 07:58:29

很好很强大我过来先占个楼 待编辑

威割 发表于 2025-12-26 03:44:29

这个好,看起来很实用

马璞玉 发表于 2025-12-27 09:50:11

喜欢鼓捣这些软件,现在用得少,谢谢分享!

衣旱 发表于 2026-1-11 06:51:42

谢谢分享,试用一下

司马黛 发表于 2026-1-14 15:46:33

感谢分享,下载保存了,貌似很强大

汲佩杉 发表于 2026-1-15 01:36:27

感谢分享,下载保存了,貌似很强大

纪睐讦 发表于 2026-1-18 04:17:26

这个有用。

松菊 发表于 2026-1-18 15:26:25

谢谢分享,试用一下

申屠梓彤 发表于 2026-1-25 08:57:55

谢谢分享,辛苦了

豌笆 发表于 2026-1-26 22:04:03

热心回复!

粉押淫 发表于 2026-1-27 04:54:51

谢谢分享,试用一下

叟减 发表于 2026-1-30 07:56:45

这个好,看起来很实用

届表 发表于 2026-2-1 02:37:35

热心回复!

更成痒 发表于 2026-2-3 05:20:38

喜欢鼓捣这些软件,现在用得少,谢谢分享!

闵雇 发表于 2026-2-6 04:10:40

喜欢鼓捣这些软件,现在用得少,谢谢分享!

卒挪 发表于 2026-2-7 04:03:03

这个好,看起来很实用

都淑贞 发表于 2026-2-7 06:19:50

分享、互助 让互联网精神温暖你我

阮蓄 发表于 2026-2-8 14:22:41

yyds。多谢分享
页: [1] 2
查看完整版本: verilog实现格雷码和二进制码的相互转换