数字IC前端学习笔记:格雷码(含Verilog实现的二进制格雷码转换器)

相关文章

数字IC前端专栏icon-default.png?t=N6B9https://blog.csdn.net/weixin_45791458/category_12173698.html?spm=1001.2014.3001.5482


目录

1.格雷码编码/解码

2.二进制码转格雷码Verilog实现

3.格雷码转二进制码Verilog实现


1.格雷码编码/解码

        格雷编码在弗兰克·格雷在1953年公布的专利中出现,主要特点是相邻编码值只有一位比特发生改变,下表中给出了三比特和四比特二进制码和对应的格雷码,从图中可以清晰地看到这一特点,而这一特点也使格雷码有十分广泛的应用。

三比特格雷码

十进制编码二进制编码格雷编码
0000000
1001001
2010011
3011010
4100110
5101111
6110101
7111100

四比特格雷码

十进制编码二进制编码格雷编码十进制编码二进制编码格雷编码
000000000810001100
100010001910011101
2001000111010101111
3001100101110111110
4010001101211001010
5010101111311011011
6011001011411101001
7011101001511111000

        格雷编码被广泛应用于使用两个不同时钟的异步FIFO(First In First Out,先入先出存储器)中。一般来说,当多位数据穿越时钟域边界时,不能直接使用传统的同步器分别同步各位数据,因为无法保证这些数据会被同时同步,可能会出现较高的错误率。但如果多位数据是使用格雷编码,每次只可能有一比特数据改变,则可以直接同步。

        在异步FIFO中,写地址和读地址指针分别保存在不同的时钟域中,而为了表示FIFO状态,我们需要分别在写时钟域中产生FIFO_full信号,在读时钟域中产生FIFO_rmpty信号,而判断FIFO状态时,需要对比读写指针的值,两个不同时钟域中的值不能直接比较。所以,我们需要先把二进制编码的指针先转换成格雷码,并使格雷编码从一个时钟域穿越到另一个时钟域,然后使用转换公式再把格雷编码转换回二进制码,并与目标时钟域的指针比较。整个同步的过程如下图所示。

       

         我们通过一些真实的案例来深入分析这一过程,然后再看不使用这一转换方法时存在的问题。下面的例子中CLKA时钟域内,一个值从十进制值5变为6,我们来分析一下多位数据的传递过程。 

十进制数值二进制数值格雷码值同步后的二进制值同步后的十进制值
51011111115
6110101111或1015或6

         在CLKA中,当十进制数从5变成6时,经过同步器后,在目标时钟域变为101或暂时为原来的111(一至两个时钟周期后,依旧会变为101)。可以看出,无论是101还是111,最终的结果都是按先后顺序出现的合法值。

        如果不使用上面的二进制-格雷码相互转换的电路,直接在CLKB时钟域使用同步器,会发生什么呢?下表给出了可能的结果。

十进制数值二进制数值同步后的二进制值同步后的十进制值
51011015
6110101或110或100或1115或6或4或7

        可以看出,同步后的值可能是旧值101、新值,但也可能变为100或111。因为多位数据是分别进行同步的,无法保证多位信号在同一个时钟沿被采样到,这些独立同步的信号有效值可能出现在不同的时钟沿。

        虽然最终能得到正确值,即最终输出变为。但是在此期间可能会出现违反规则的值。在该例中,出现了两种非法值,如果同时有更多位数据跳变,则可能会产生大量不合法的值,输出端会保留这些值一至两个周期。

        对于FIFO来说,空\满信号是根据指针对比得到的,当出现这些非法值时,FIFO可能会出现错误的空\满信号,导致系统工作错误甚至崩溃。

2.二进制码转格雷码Verilog实现

module binary_to_gray #(parameter PTR = 8)
                       (input [PTR:0]binary_value,
                        output [PTR:0]gray_value);
genvar i;
generate
    for(i = 0;i < PTR;i = i+1) begin
        assign gray_value[i] = binary_value[i] ^ binary_value[i+1];
    end
endgenerate

assign gray_value[PTR] = binary_value[PTR];

endmodule

3.格雷码转二进制码Verilog实现

module gray_to_binary #(parameter PTR = 8)
                       (output [PTR:0]binary_value,
                        input [PTR:0]gray_value);
genvar i;
generate
    for(i = 0;i < PTR;i = i+1) begin
        assign binary_value[i] = binary_value[i+1] ^ gray_value[i];
    end
endgenerate

assign binary_value[PTR] = gray_value[PTR];

endmodule

 以上内容来源于《Verilog高级数字系统设计技术和实例分析》

  • 15
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
二进制码转二进制 十进制转二进制 二进制转十进制等,在Delphi xe2下通过测试。码(英文:Gray Code, Grey Code,又称作葛莱码,二进制循环码)是1880年由法国工程师Jean-Maurice-Emlle Baudot发明的一种编码[,因Frank Gray于1953年申请专利“Pulse Code Communication”得名。当初是为了机械应用,后来在电报上取得了巨大发展.压缩包里该源代码. 二进制码转换: 最佳答案: 十进制 586 = 二进制 1001001010 = 码 1101101111。 二进制码 ----> 码(编码): 从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应码该位的值,最左边一位不变(相当于左边是0)。 码的特点是: 相邻两数的码,仅仅有一位二进制发生变化。 而且在其范围内的最小值和最大值,也仅仅有一位二进制发生变化。 例如下面两数: 最小:二进制0000=码0000 最大:二进制1111=码1000 看到了吧,0000 和 1000,仅仅有一位数发生变化。 ------- 如果在变换的过程中,先把十进制转换成BCD码,这就失去了码的特点。 因为在BCD码中: 最小:二进制0000=码0000 最大:二进制1001=码1101 可以看出,它们之间有三位发生变化。 通过BCD码来变换码,思路不对。变换出来的,并不是原数的码。 自然二进制数与码的互换公式与电路: 自然二进制数转换到码 ------------ 设有 N 位二进制数 B(i),其中 0 <= i <= N - 1;它可以变换成为同样位数的码 G(i)。 二进制数与码的转换公式如下:   G(i) = B(i 1) XOR B(i) ; 0 <= i < N - 1   G(i) = B(i) ; i = N - 1 如果是通过编程计算进行变换,就需要使用这个公式逐位的计算; 如果是使用硬件电路进行变换,就可以使用做而论道前面在回答问题时给出的电路。 码转换到自然二进制数 ------------ 设有 N 位码 G(i),把它转换成自然二进制数的算法如下。 自然二进制码的最高位等于码的最高位; 自然二进制码的次高位为最高位自然二进制码与次高位码相异或; 自然二进制码的其余各位与次高位自然二进制码的求法相类似。 转换公式如下:   B(i) = G(i) ; i = N - 1   B(i) = B(i 1) XOR G(i) ; 0 <= i < N - 1 二进制转换器截图:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日晨难再

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值