格雷码和二进制的转换及典型例题(4bits格雷码计数器)

目录

一、格雷码简介:

二、格雷码与二进制的转换方法

1、(常用)异或转换

2、递归生成码表

3、其他

三、例题:格雷码计数器(Verilog)​​​​​​​


一、格雷码简介:

        典型的二进制格雷码(Binary Gray Code)简称格雷码,因1953年公开的弗兰克·格雷(Frank Gray,18870913-19690523)专利“Pulse Code Communication”而得名,当初是为了通信,现在则常用于模拟-数字转换和位置-数字转换中。

        而在数字电路中,格雷码每次的变换只会有一个二进制位的跳变,极大地减少了亚稳态的产生,保证电路的稳定性,受到了广泛的应用。

格雷码与十进制

        而在实际的应用中,常常需要进行二进制和格雷码的相互转换。比如在后文的例题中,是以格雷码的方式进行计数(对电路来说性能更好)但计算机进行计数都是简单的二进制,所以需要熟悉和了解两者的转换规则。

        格雷码的特征:

(1)格雷码属于可靠性编码,是一种错误最小化的编码方式

(2)典型格雷码是一种采用绝对编码方式的准权码,其权的绝对值为2^i-1(设最低位i=1)。

(3)格雷码的十进制数奇偶性与其码字中1的个数的奇偶性相同


二、格雷码与二进制的转换方法

1、(常用)异或转换

         (1)二进制到格雷码(编码) :

                        格雷码的第i位的值等于二进制第i位和i+1位的异或,当i=n-1时,i+1位取0。

                        公式为:         g(i) = b(i)^b(i+1), i=0,1,2,...,n-1 .

                        原理如图(以4bits格雷码为例):

           (2)格雷码到二进制(解码)

            从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变)。依次异或,直到最低位。依次异或转换后的值(二进制数)就是格雷码转换后二进制码的值。

        公式为:b(i) = g(i)^b(i+1), i = 0,1,2...n-2; b(n-1) = g(n-1).

        原理如图(以4bits格雷码为例):

 

2、递归生成码表

        这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造:

                1.1位格雷码有两个码字

                2.(n+1)位格雷码中的前2^n个码字等于n位格雷码的码字,按顺序书写,加前缀0

                3.(n+1)位格雷码中的后2^n个码字等于n位格雷码的码字,按逆序书写,加前缀1 

                4.n+1位格雷码的集合 = n位格雷码集合(顺序)加前缀0 + n位格雷码集合(逆序)加前缀1

        这个规则一眼看上去很复杂,我们来举几个例子了解一下:        

                例如:针对2位格雷码,我们知道变化规律是00,01,11,10。我们再以上述的规则来分析,此时n=1,前2个码字按顺序就是0,1,加前缀0就是00,01;后2个码字按逆序就是1,0,在前缀加1就是11,10。在比如三位的格雷码,000,001,011,010,110,111,101,100,前4个码字是00,01,11,10,加前缀0就是前四个格雷码,而后四位按逆序10,11,01,00,加前缀1就是三位格雷码的后四位。以此类推,4位格雷码就是  (前)  8位码字顺序加前缀0+(后)   8位码字逆序加前缀1,从而形成一级一级的递归。

3、其他

        另外还有卡诺图法等方法,不常用或是比较繁琐不做介绍。


三、例题:格雷码计数器(Verilog)

题目描述:        

        实现4bit位宽的格雷码计数器,两个周期计数一次。 

        电路的接口如下图所示。

思路: 我们以二进制来计数,再转换为格雷码就可以。

详解如下:

module gray_counter(
   input   clk,
   input   rst_n,

   output  reg [3:0] gray_out
);
    reg [3:0] b;
    reg c; //计时钟
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin b<=0; c<=0;end
        else
            begin
                c <= ~c; //c执行010101的周期性变化,用来记两个时钟周期
                b <=(c)? (b+1):b; //c=1时b才加1,两个上升沿记一次
            end      
    end
    
    //根据二进制码到格雷码的转换关系可得
    always @(*) begin
        gray_out[0] <= b[0]^b[1];
        gray_out[1] <= b[1]^b[2];
        gray_out[2] <= b[2]^b[3];
        gray_out[3] <= b[3]^0;
    end
    
endmodule

结束

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值