数字设计---格雷码与二进制码
格雷码与二进制码
格雷码
格雷码是一种循环二进制码或者叫作反射二进制码。
格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变(或者说相邻的两个格雷码之间只有一位不同)。
从图上可以看出,相邻的二进制数会出现多位的变化(比如从15变到0就会有4位的变化),但对于格雷码来说,相邻的格雷码只有一位存在不同。
对于二进制数计数器来说,如果在跨时钟域的时候将计数器传到不同的时钟域,如果仅采用“打两拍的方法”,因为有多位数的变化,就可能会导致电路出现亚稳态或者出现毛刺。
由于格雷码的这种特点,采用格雷码就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码常用于通信,FIFO 或者 RAM 地址寻址计数器中。
格雷码与BCD码的转换
BCD码转格雷码
对于位的二进制数,可以通过下面的式子转换为格雷码
即格雷码的最高位与二进制数的最高位相同,后面格雷码的各位等于相应的二进制码的对应位与上一位的异或。
从上图可以看出二进制码转换为格雷码的具体流程
拿5位二进制数10110举例
对于verilog来说,我们可以将二进制数与他右移一位的数按位相异或来求得gray码。
module bin_to_gray #(parameter WIDTH = 4) ( input [WIDTH-1:0] bin_in, output [WIDTH-1:0] gray_out ); //================================================================ // ------------------------- MAIN CODE -------------------------- //================================================================ assign gray_out = (bin_in >> 1) ^ bin_in; //右移一位再按位相异或 // gray_out[0] = (bin_in[1]) ^ bin_in[0]; //当然可以分着来,就是没上面那么简洁 // gray_out[1] = (bin_in[2]) ^ bin_in[1]; // gray_out[2] = (bin_in[3]) ^ bin_in[2]; // gray_out[3] = (bin_in[3]) ^ 0 ; endmodule
格雷码转BCD码
对于位的格雷码,可以采用下面的式子转换为二进制码
即二进制码的最高位与格雷码的最高位相同,剩余位可以通过将对应位的格雷码与上一位的二进制码相异或求得
还是拿上图的5位格雷码10110举例
从上面的分析可以看出格雷码转换为二进制,对应位的二进制可以通过求对应位格雷码及以上所有位的异或求得。
对于verilog实现来说,可以通过将格雷码右移相应位数,再求所有位的异或来实现上面的效果(求对应位格雷码及以上所有位的异或)。
module gray_to_bin #(parameter WIDTH = 4) ( input [WIDTH-1:0] gray_in, output reg [WIDTH-1:0] bin_out ); //=================================================== // ------------------- MAIN CODE ------------------- //=================================================== integer i; always @(*) begin for(i=0;i<WIDTH;i=i+1) bin_out[i] = ^(gray_in >> i); end endmodule
参考
(9条消息) 二进制与格雷码互相转换_耐心的小黑的博客-CSDN博客_二进制转格雷码
《硬件架构的艺术》
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期