去除毛刺的一种方法
在学习FPGA的过程中,我们一直在进步,也一直在同一个问题上有所突破。对于去除毛刺这个问题,我们一直在寻求更好、更简便的方式。最近,得一良方,现写出来进行分享。
-
说明
首先,需要说明的是,对于脉冲小于一个时钟周期的毛刺,只要不在数据的采集时刻(一般是在时钟的上升沿)进行干扰,可以忽略不计。
而对于较宽的毛刺,则需要仔细地去除毛刺。
-
实现
话不多说,直接上代码。
module SpurRemove
#(parameter SPURWIDTH = 4, //去,毛刺最长长度
parameter INITVALUE = 0 //初始化状态
)
(
//输入
input clk,
input rst, //复位信号,高有效
input sig_in, //带去毛刺信号
//输出
output sig_out //已去毛刺信号
);
wire initialvalue = INITVALUE;
reg sig = INITVALUE;
reg[SPURWIDTH:0] sig_in_reg = {(SPURWIDTH+1){INITVALUE}};
always @(posedge clk)
begin
if(rst)
begin
sig_in_reg <= {(SPURWIDTH+1){initialvalue}};
end
else
begin
sig_in_reg[0] <= sig_in;
sig_in_reg[SPURWIDTH:1] <= sig_in_reg[(SPURWIDTH-1):0];
end
end
always @(posedge clk)
begin
if(rst)
sig <= initialvalue;
else if(~(|sig_in_reg)) //所有位都为0则输出0
sig <= 1'b0;
else if(&sig_in_reg) //所有位都为1则输出1
sig <= 1'b1;
else
sig <= sig; //否则保持不变
end
assign sig_out = sig;
endmodule
这里简单说明下代码实现,分三种情形。
- 检测到4个全0时,输出为0;
- 检测到4个全1时,输出为1;
其他情形输出保持不变。
以毛刺2进行简单的分析。
在有毛刺前,检测到为0,输出为0。这时检测的毛刺宽度小于4个时钟周期,即所有的数据都不可能是全0或者全1,只能是0、1的组合,这样的话,就保持前一时刻的输出为0。这样,毛刺就去除了。
需要注意的是,输出结果与实际的输出存在一定的置后,但这不会影响结果的正确输出。