原创 Gray与Binary

2011-10-4 23:30 2079 7 7 分类: FPGA/CPLD

在现在的设计中,为了减少亚稳态的发生,通常需要使用可靠编码,比较常用的是Gray码,比如:跨时钟域的数据同步中,对于双端FIFO就可使用Gray码计数器来进行寻址等。

 

Gray码与Binary码的相互转换原理如下:
Gray->Binary:
1、Gray[n-1] = Bin[n-1]
2、Gray = Bin[i+1] ^ Bin, i=n-2,..0
即:Gray码与Binary码最高位相同,Gray码其余位等于Binary码的相应位与其相邻高位异或。
Binary->Gray:

1、Bin[n-1] = Gray[n-1]
2、Bin = Gray[n-1] ^ Gray[n-2] ^...Gray, i=n-2,..0
即:Binary码与Gray码最高位相同,Binary码其余位等于Gray码相应位与所有高位异或。

 

下面以Binary->Gray为例进行说明。
基本框图如下:

20111004232952481.jpg


相关代码如下:

module gray_cnt(clk,rst_n,gray);

 

parameter WIDTH = 2;

 

input clk;
input rst_n;
output [WIDTH-1:0] gray;

 

reg [WIDTH-1:0] gray;
reg [WIDTH-1:0] binary;
reg [WIDTH-1:0] next_binary;
wire [WIDTH-1:0] next_gray;


always @(negedge clk or negedge rst_n) &n 

 

assign next_gray = next_binary ^ (next_binary>>1);

 

always @(posedge clk or negedge rst_n)    //利用clk上升沿数据同步输出
if(!rst_n)
   begin
       gray <= {WIDTH{1'b0}};
       binary <= {WIDTH{1'b0}};
   end
else         //同步输出
   begin
       gray <= next_gray;
       binary <= next_binary;
   end
 
endmodule

 

测试代码如下:

`timescale 1ns/1ns
`include "./gray_cnt.v"

 

module gray_cnt_tb;


parameter PTR_WIDTH = 3;
parameter CYCLE = 10;

 

reg clk;
reg rst_n;
wire [PTR_WIDTH-1:0] gray;

 

initial
begin
   clk = 0;
   forever
      #(CYCLE/2) clk = ~clk;
end 

 

initial
begin
    rst_n = 0;
    #(CYCLE) rst_n =1;
end


gray_cnt u_gray_cnt(.clk(clk),
                    .rst_n(rst_n),
                    .gray(gray));
defparam u_gray_cnt.WIDTH = PTR_WIDTH;
   
endmodule


注:

模块调用/例化时参数的修改:

1、使用带有参数值的模块例化语句

2、使用参量重定义语句(defparam)

例如:

1、gray_cnt #(PTR_WIDTH) u_gray_cnt(...);

当有多个参数时要注意顺序,有不需要改变的参数也要全部列出

2、gray_cnt u_gray_cnt(...);

     defparam u_gray_cnt.WIDTH = PTR_WIDTH;

defparam语句的位置前后都可以,不重要

因此,用第二种方法更加灵活,推荐使用。

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /3 下一条