简析
使用自然二进制码计数时,相邻数据之间可能会产生多bit的变化。比如,从0111→1111,四个bit全部发生了变化。这会产生较大的尖峰电流以及其他问题。格雷码是一种相邻数据只有1bit变化的码制。
十进制 |
自然二进制 |
格雷码 |
0 |
000 |
000 |
1 |
001 |
001 |
2 |
010 |
011 |
3 |
011 |
010 |
4 |
100 |
110 |
5 |
101 |
111 |
6 |
110 |
101 |
7 |
111 |
100 |
自然二进制码binary_code转换为格雷码gray_code如下:
gray_code=binary_code⊕(binary_code>>1)
格雷码gray_code转换为自然二进制码binary_code要复杂一些,以4bit码为例:
⎩⎪⎪⎨⎪⎪⎧binary_code3=gray_code3,binary_code2=gray_code2⊕binary_code3=gray_code2⊕gray_code3,binary_code1=gray_code1⊕binary_code1=gray_code1⊕gray_code2⊕gray_code3,binary_code0=gray_code0⊕binary_code0=gray_code0⊕gray_code1⊕gray_code2⊕gray_code3
最后一点,根据波形图,计数器两个周期变化一次。(2022.06.03更:题目已经修改,这个条件已经删除)
代码
`timescale 1ns/1ns
module gray_counter(
input clk,
input rst_n,
output reg [3:0] gray_out
);
reg [3:0] binary_cnt;
reg flag;
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
flag <= 0;
else
flag <= ~flag;
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
binary_cnt <= 0;
else
binary_cnt <= flag? binary_cnt + 1: binary_cnt;
end
always@(*) begin
gray_out = binary_cnt^(binary_cnt>>1);
end
endmodule