2841|0

12

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

gray 计数器 [复制链接]

格雷码(Gray code)是由贝尔实验室的Frank Gray在1940年提出,用于在PCM(Pusle Code Modulation)方法传送讯号时防止出错,并于1953年三月十七日取得美国专利。格雷码是一个数列集合,相邻两数间只有一个位元改变,为无权数码,且格雷码的顺序不是唯一的。

直接排列

以二进制为0值的格雷码为第零项,第一项改变最右边的位元,第二项改变右起第一个为1的位元的左边位元,第三、四项方法同第一、二项,如此反覆,即可排列出n个位元的格雷码。

 二进制码->格雷码(编码):从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变(相当于左边是0);

格雷码-〉二进制码(解码):从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变).

  数学(计算机)描述:

  原码:p[n:0];格雷码:c[n:0](n∈N);编码:c=G(p);解码:p=F(c);

  书写时按从左向右标号依次减小,即MSB->LSB,编解码也按此顺序进行

  编码:

  ...................c[n]=p[n],

  ...................c=p XOR p[i+1] (iN,n-1i0)

  解码:

  ...................p[n]=c[n],

  ...................P=c XOR p[i+1] (iN, n-1i0)。   //注意

二进制数转格雷码

(假设以二进制为0的值做为格雷码的0)

格雷码第n位 = 二进制码第(n+1)位+二进制码第n位。不必理会进制。

Verilog 代码:gray=(binary>>1)^binary;

格雷码转二进制数

二进制码第n位 = 二进制码第(n+1)位+格雷码第n位。因为二进制码和格雷码皆有相同位数,所以二进制码可从最高位的左边位元取0,以进行计算。

verilog 代码://------假设 reg [n-1] gray,binary;

integer i;

for(i=0;i<=n-1;i=i+1)

binary=

^(gray>>i)//gray移位后,自身按位异或

^(gray>>i)//第一次看到这样的用法,特意查了下verilog语法

 
 
方法一
代码:
module gray
#(parameter N=5)
(
input clk,
input rst_n,
output reg [N-1:0] gray_cnt_out
);
reg [N-1:0] cnt;
reg [N-1:0] temp;
integer i;
always @ (posedge clk ,negedge rst_n)
begin
if(!rst_n)
cnt <= 5'd0;
else
cnt <= cnt +1'b1;
end
always @(cnt)
begin
temp[N-1] = cnt[N-1];
for(i=1; i<=N-1;i=i+1)
temp[i-1] = cnt[i-1]^cnt;
end
//   此处for循环综合会展开  不推荐这种写法
 
always @ (posedge clk ,negedge rst_n)
begin
if(!rst_n)
gray_cnt_out<=1'b0;
else
gray_cnt_out<=temp;
end
endmodule
备注:在实际工程中,Gray码计数器广泛应用于跨时钟域设计,他用于将计数器的计数值从A时钟域传递给B时钟域。由于信号的传播延时,而且CLKA和CLKB没有固定的相位关系,CLKA_cnt的输出不能同时到达CLKB,如果用二进制计数器,则可能出现毛刺,从而导致设计错误;而如果采样Gray码计数器,根据Gray的特性,则可以有效地避免这个问题。
 
方法2:(只有一个寄存器的gray计数器)
代码:
module gray_counter
(
    input iclk,
    input irst_n,
    input ivalid,
    output reg [3:0] gray
);
  
wire [3:0] bin_counter;
wire [3:0] gray_counter;
   
reg  [3:0] G2B_counter;
  
// convert gray to  bin;
always@(*)
begin
    G2B_counter[3] = gray[3];
    G2B_counter[2] = gray[2] ^ G2B_counter[3];
    G2B_counter[1] = gray[1] ^ G2B_counter[2];
    G2B_counter[0] = gray[0] ^ G2B_counter[1];
end
  
//binary counter increased by one
assign bin_counter = bin_counter +ivalid;
  
//convert bin to gray 
assign gray_counter = (bin_counter >>1) ^ bin_counter;
//理解该处的电路结构
  
always@(posedge iclk or negedge irst_n)
begin
    if(!irst_n)
    begin
        gray <= 4'b0;
    end
    else
    begin
        gray <= gray_counter;
    end
end
  
endmodule
 
//  为码
always @(gray) begin
  for (i=0; i<`WIDTH; i=i+1)
   bin = ^(gray>>i);   // Gray码到二进制码转换
  bnext = bin + 1;
  gnext = (bnext>>1) ^ bnext;   // 二进制码到Gray码转换
 end
 
方法3(提高频率,增加寄存器,减少组合逻辑)
module graycounter
(
    input iclk,
    input irst_n,
    input ivalid,
    output     [ADDSIZE-1 : 0]  bin,
    output reg [ADDSIZE : 0]  gray
);
  
parameter ADDSIZE = 4;
  
wire[ADDSIZE : 0] binnext;
wire[ADDSIZE : 0] graynext;
reg[ADDSIZE : 0] bin_o;
  
assign binnext = bin_o + ivalid;
  
assign graynext = (binnext >>1) ^ binnext;
  
assign bin = bin_o[ADDSIZE-1 : 0];
  
always@(posedge iclk or negedge irst_n )
if(!irst_n)
    {bin_o, gray} <= 0;
else
    {bin_o, gray} <= {binnext, graynext};
  
endmodule
此帖出自FPGA/CPLD论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表