最近在做项目中遇到了一个问题,首先我们知道信号的边缘不会像我们想要的那么陡峭,而且不会像我们想的一样准时到达。
作者:Trustintruth
来源: https://zhuanlan.zhihu.com/p/130732799
那如果是在多位翻转时,各个信号到来时间也可能不同,所以我们的多位变化时会发生误码的概率大大增加,例如位宽为5的信号由11111到00000变化时有可能会是是这样
11111——11011——11010——10010——00010——00000
出于对稳定性的考虑,我们采用格雷码,尤其是在FSM的状态我们经常使用格雷码表示。
格雷码在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。
相对于二进制,格雷码转二进制可以使用公式来变换
根据公式设计出格雷码转二进制的译码器
module gray_to_bin (gray,bin);
parameter WIDTH = 8;
input [WIDTH-1:0] gray;
output [WIDTH-1:0] bin;
wire [WIDTH-1:0] bin;
assign bin[WIDTH-1] = gray[WIDTH-1];
genvar i;
generate
for (i=WIDTH-2; i>=0; i=i-1)
begin: gry_to_bin
assign bin[i] = bin[i+1] ^ gray[i];
end
endgenerate
endmodule
同样二进制转格雷码也可以使用公式
二进制转化为格雷码的编码器设计
module bin_to_gray (bin,gray);
parameter WIDTH = 8;
input [WIDTH-1:0] bin;
output [WIDTH-1:0] gray;
wire [WIDTH-1:0] gray;
assign gray = bin ^ (bin >> 1);
endmodule
右上边的可以得到最终的设计——格雷码计数器
module gray_counter(clk, rst_n, gray_dout);
parameter WIDTH = 8;
input clk;
input rst_n;
output [WIDTH-1:0] gray_dout;
reg [WIDTH-1:0] gray_dout;
wire [WIDTH-1:0] gray_temp;
wire [WIDTH-1:0] bin_dout;
wire [WIDTH-1:0] bin_add;
assign bin_add = bin_out + 1'b1;
assign gray_temp = bin_add ^ (bin_add >> 1);
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
gray_dout <= {WIDTH{1'b0}};
else
gray_dout <= gray_temp;
end
gray_to_bin gtb(.gray(gray_dout), .bin(bin_dout));
defparam gtb .WIDTH = WIDTH;
endmodule
获取更多代码与资料,欢迎关注我啊!
推荐阅读
关注此系列,请关注专栏FPGA的逻辑