- 格雷码(Gray code):
第一次接触格雷码是在本科的数电课本上,其在可靠性编码占据重要位置。后来所学的卡诺图与格雷码关系密切。
格雷码特点在于相邻性和单位距离性。在代码传输过程中,彼此相邻位置仅有一位数码不同,故有着较好的可靠性。
4位格雷码:
十进制 | 二进制 | 格雷码 |
---|---|---|
0 | 0000 | 0000 |
1 | 0001 | 0001 |
2 | 0010 | 0011 |
3 | 0011 | 0010 |
4 | 0100 | 0110 |
5 | 0101 | 0111 |
6 | 0110 | 0101 |
7 | 0111 | 0100 |
8 | 1000 | 1100 |
9 | 1001 | 1101 |
10 | 1010 | 1111 |
11 | 1011 | 1110 |
12 | 1100 | 1010 |
13 | 1101 | 1011 |
14 | 1110 | 1001 |
15 | 1111 | 1000 |
- Verilog的实现:
格雷码计数器的Verilog实现,即用格雷码计数的方式,完成数据的累加。
实现方式有多种,参考J.Bhasker的书,此处贴上第一种。
代码的基本流程为:首先将初始化的格雷码转变为二级制码,二进制完成累加,最后再讲二级制码转化为格雷码。
- 格雷码转二进制码的基本思路:
最高位不变,次高位往下依次完成自异或运算,得到对应二进制码的各位数据,运算次数为位宽-1 - 二进制码转格雷码的基本思路:
最高位不变,最低位依次往前完成自异或运算,得到对应二进制码的各位数据,运算次数为位宽-1 - 注:这样的自异或运算与其他人给出的格雷码+二进制共同运算的方式不同,前一种可能存在局限性,待发现后说明
异步复位的N位格雷码计数器
`timescale 1ns/1ns
module gray_counter1(ck,preclear,q);
parameter NBITS = 4; //决定格雷码计数的带宽
input ck,preclear;
output [0:NBITS-1] q;
reg [0:NBITS-1] q;
reg [0:NBITS-1] gray_cnt;
integer k;
always @(posedge ck or negedge preclear)
begin
if(!preclear) //异步清零信号,信号为低时,计数清零
q <= 0;
else
begin
gray_cnt = q;
//将数据存在在临时变量中
for(k=1;k<NBITS;k=k+1)
if(gray_cnt[k-1])
gray_cnt[k] = !gray_cnt[k];//高位为高,低位取反,本质上是异或操作
//完成格雷码到二进制的转换,二进制计数
gray_cnt = gray_cnt + 1;
for(k=NBITS-1;k>0;k=k-1)
if(gray_cnt[k-1])
gray_cnt[k] = !gray_cnt[k];
//二进制转回格雷码
q <= gray_cnt;
end
end
endmodule
module gray_counter1_tb; //测试文件
parameter NBITS = 4;
reg ck,preclear;
wire [0:NBITS-1] q;
gray_counter1 U1(ck,preclear,q);
always #50 ck = !ck; //计数时钟,周期100ns
initial
begin
ck = 0;
preclear = 1;
#70 preclear = 0;
#70 preclear = 1;
end
endmodule
网友评论