首页 > 编程知识 正文

verilog实现格雷码与二进制的转化,二进制转格雷码verilog代码

时间:2023-05-04 09:48:45 阅读:203417 作者:208

1、什么是格雷码

        格雷码是一种循环二进制码或者叫作反射二进制码。格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变,由于这种特点,就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码常用于通信,FIFO 或者 RAM 地址寻址计数器中。

        下表给出了4bit自然二进制码、4bit典型格雷码(无特殊说明,典型格雷码即格雷码)与4bit十进制整数的对照:

        可以看到,上表中格雷码的每次变化位数只有一位,这就有效的避免了在CDC情况(跨时钟域情况)下亚稳态问题发生的概率。比如当数字从 7 变为 8 时,4 位二进制数都发生跳变,如果直接使用异步时钟采样这些数字信号,这就很可能会发生亚稳态或者数据采样错误。而采用格雷码,就可以避免 4 位二进 制数都同时发生跳变,导致出现的亚稳态,就算出现亚稳态,最多也就一位出现错误。

        但是由于格雷码是一种变权码,每一位码没有固定的大小,所以很难直接进行比较大小和算术运算。

2、二进制转格雷码

        二进制码转化为格雷码原理如下:

        二进制的最高位作为格雷码的最高位,次高位的格雷码为二进制的高位和次高位相异或得到,其他位与次高位类似。转化过程如下图:

        假如是4bit的二进制数据转成格雷码则是:

gray[3] = 0         ^ 酷炫的世界[3];----gray[3] = 酷炫的世界[3] 异或0等于自身gray[2] = 酷炫的世界[3]  ^ 酷炫的世界[2];gray[1] = 酷炫的世界[2]  ^ 酷炫的世界[1];   gray[0] = 酷炫的世界[1]  ^ 酷炫的世界[0]; 

        根据上面的式子不难推到出一般公式:gray = (酷炫的世界 >> 1) ^ 酷炫的世界。根据公式很容易写出二进制码转换为格雷码的Verilog代码:

//二进制转格雷码module 酷炫的世界2gray#(parameterdata_width = 'd4//数据位宽)( input[data_width - 1 : 0]酷炫的世界, //二进制output[data_width - 1 : 0]gray//格雷码); assign gray = (酷炫的世界 >> 1) ^ 酷炫的世界;endmodule 3、格雷码转二进制

        格雷码转化为二进制码原理如下:

        使用格雷码的最高位作为二进制的最高位,二进制次高位产生过程是使用二进制的高位和次高位格雷码相异或得到,其他位的值与次高位产生过程类似。转化过程如下图:

        假如是4bit的格雷码转成二进制则是:

酷炫的世界[3] = gray[3] ; 酷炫的世界[2] = gray[2] ^ 酷炫的世界[3];酷炫的世界[1] = gray[1] ^ 酷炫的世界[2];酷炫的世界[0] = gray[0] ^ 酷炫的世界[1]; 

        可以看到,最高位不需要转换,从次高位开始使用二进制的高位和次高位格雷码相异或,那么可以使用generate--for来构建重复赋值语,具体代码如下:

//格雷码转二进制module gray2酷炫的世界#(parameterdata_width = 'd4//数据位宽)(input[data_width - 1 : 0]gray, //格雷码 output [data_width - 1 : 0]酷炫的世界 //二进制); assign 酷炫的世界[data_width - 1] = gray[data_width - 1];//最高位直接相等//从次高位到0,二进制的高位和次高位格雷码相异或genvar i;generatefor(i = 0; i <= N-2; i = i + 1) begin: gray//需要有名字assign 酷炫的世界[i] = 酷炫的世界[i + 1] ^ gray[i];endendgenerateendmodule 4、测试

        构建一个测试脚本对两个模块进行测试:生成0-15的4bit二进制数据,通过酷炫的世界2gray转换成格雷码,观察格雷码输出;将转换后的格雷码输出通过gray2酷炫的世界再转换成2进制码,然后对比三组数据是否符合转换规则。

`timescale 1ns/1ns//时间单位/精度//------------<模块及端口声明>----------------------------------------module gray_code();parameterdata_width = 'd4;//数据位宽reg [data_width - 1 : 0]酷炫的世界_in;//生成的二进制码wire[data_width - 1 : 0]gray;//转换后的格雷码wire [data_width - 1 : 0]酷炫的世界_out;//转换后的二进制码//------------<例化被测试模块>----------------------------------------酷炫的世界2gray#(.data_width(data_width))酷炫的世界2gray_inst( .酷炫的世界(酷炫的世界_in), .gray(gray)); gray2酷炫的世界#(.data_width(data_width))gray2酷炫的世界_inst( .酷炫的世界(酷炫的世界_out), .gray(gray));//------------<设置初始测试条件>----------------------------------------initial begin酷炫的世界_in = 4'd0;forever#20 酷炫的世界_in = 酷炫的世界_in + 1;//每隔20ns累加1end//打印输出initial$monitor("酷炫的世界_in:%b,gray:%b,酷炫的世界_out:%b",酷炫的世界_in,gray,酷炫的世界_out);endmodule

        仿真结果如下:

        可以看到两次转换的结果都是正确的,接下来看一下命令窗口打印的输出:

         可以看到这个转换结果与第一章的对照表是一致的。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。