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

打印 上一主题 下一主题

主题 877|帖子 877|积分 2631

目录

格雷码的先容

在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(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 [n-1:0] bin; logic [n-1:0] 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中,我们可以用下面的几行代码,得到二进制编码到格雷码的转化:
  1. logic [n-1:0] bin;
  2. logic [n-1:0] grey
  3. 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块内循环实现转换
  1. //从次高位到0,二进制的高位和次高位格雷码相异或
  2. genvar i;
  3. generate
  4.         for(i = 0; i <= DATA_WIDTH-2; i = i + 1)
  5.                 begin:
  6.                         assign bin[i] = bin[i + 1] ^ grey[i];
  7.                 end
  8. endgenerate
复制代码
在vscode中执行以下命令,编译code,打开波形文件:
  1. `timescale 1ns/1ps       
  2. module grey_tb;
  3.         logic clk=0;
  4.         always #5 clk = ~clk;
  5.         initial begin
  6.             $display("start a clock pulse");
  7.             $dumpfile("grey.vcd");
  8.             $dumpvars(0, grey_tb);
  9.                    #300 $finish;
  10.         end
  11.         logic [7:0] bin;
  12.         logic [7:0] grey;
  13.         logic [7:0] bin2;
  14.         logic [7:0] bin_1=0;
  15.         logic [7:0] grey_1;
  16.         logic [7:0] bin2_1;
  17.         initial begin
  18. // 重复执行10次随机数生成过程
  19.                 repeat(10) begin
  20.                         @(posedge clk) begin
  21.                         bin <= $random();
  22.                         end
  23.                 end
  24. // 重复执行32次的循环,用于对bin_1进行自增操作
  25.                 repeat(32) begin
  26.                         @(posedge clk) begin
  27.                         bin_1 <= bin_1+1;
  28.                         end
  29.                 end
  30.         end
  31.         bin2grey #(.DATA_WIDTH(8)) bin2grey_inst(.bin(bin),.grey(grey));
  32.         grey2bin #(.DATA_WIDTH(8)) grey2bin_inst(.grey(grey),.bin(bin2));
  33.         bin2grey #(.DATA_WIDTH(8)) bin2grey_inst1(.bin(bin_1),.grey(grey_1));
  34.         grey2bin #(.DATA_WIDTH(8)) grey2bin_inst1(.grey(grey_1),.bin(bin2_1));
  35. endmodule
  36. //二进制转格雷码
  37. module        bin2grey
  38. #(
  39.         parameter DATA_WIDTH=8
  40. )
  41. (
  42.         input wire [DATA_WIDTH-1:0] bin,
  43.         output logic [DATA_WIDTH-1:0] grey
  44. );                                                              
  45.         assign grey = bin ^(bin>>1);
  46. endmodule
  47. //格雷码转二进制码
  48. module grey2bin
  49. #(
  50.         parameter DATA_WIDTH=8
  51. )
  52. (
  53.         input wire [DATA_WIDTH-1:0] grey,
  54.         output logic [DATA_WIDTH-1:0] bin
  55. );                                                              
  56.         assign bin[DATA_WIDTH-1] = grey[DATA_WIDTH-1];
  57. genvar i;
  58. generate
  59.         for(i=DATA_WIDTH-2;i>=0;i=i-1) begin
  60.                 assign bin[i] = bin[i+1] ^ grey[i];
  61.         end
  62. endgenerate
  63. endmodule
复制代码

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表