4.去除毛刺的一种方法

FPGA去除毛刺技巧

                                            去除毛刺的一种方法

在学习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

这里简单说明下代码实现,分三种情形。

  1. 检测到4个全0时,输出为0;
  2. 检测到4个全1时,输出为1;

其他情形输出保持不变。

以毛刺2进行简单的分析。

在有毛刺前,检测到为0,输出为0。这时检测的毛刺宽度小于4个时钟周期,即所有的数据都不可能是全0或者全1,只能是0、1的组合,这样的话,就保持前一时刻的输出为0。这样,毛刺就去除了。


需要注意的是,输出结果与实际的输出存在一定的置后,但这不会影响结果的正确输出。

在Verilog中过滤北斗秒脉冲毛刺可以采用以下几种常见方法: ### 延时滤波法 延时滤波法的基本原理是通过延迟信号一段时间,然后比较原始信号和延迟后的信号。如果两者相同,则认为信号稳定;如果不同,则说明存在毛刺。 ```verilog module glitch_filter_delay ( input wire clk, input wire rst_n, input wire pps_in, // 北斗秒脉冲输入 output reg pps_out // 滤波后的秒脉冲输出 ); reg [2:0] delay_reg; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin delay_reg <= 3'b000; pps_out <= 1'b0; end else begin delay_reg[0] <= pps_in; delay_reg[1] <= delay_reg[0]; delay_reg[2] <= delay_reg[1]; if (delay_reg[0] == delay_reg[2]) begin pps_out <= delay_reg[0]; end end end endmodule ``` ### 计数器滤波法 计数器滤波法是在检测到信号变化时启动一个计数器,只有当计数器达到一定值且信号保持稳定时,才认为信号有效。 ```verilog module glitch_filter_counter ( input wire clk, input wire rst_n, input wire pps_in, // 北斗秒脉冲输入 output reg pps_out // 滤波后的秒脉冲输出 ); reg [7:0] counter; reg pps_temp; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin counter <= 8'b0; pps_temp <= 1'b0; pps_out <= 1'b0; end else begin if (pps_in != pps_temp) begin counter <= counter + 1; if (counter == 8'd255) begin pps_temp <= pps_in; pps_out <= pps_in; counter <= 8'b0; end end else begin counter <= 8'b0; end end end endmodule ``` ### 状态机滤波法 状态机滤波法通过定义不同的状态来处理信号的变化,只有当信号在某个状态下保持一定时间后,才进行状态转换。 ```verilog module glitch_filter_fsm ( input wire clk, input wire rst_n, input wire pps_in, // 北斗秒脉冲输入 output reg pps_out // 滤波后的秒脉冲输出 ); parameter IDLE = 2'b00; parameter WAIT_LOW = 2'b01; parameter WAIT_HIGH = 2'b10; reg [1:0] state; reg [7:0] counter; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= IDLE; counter <= 8'b0; pps_out <= 1'b0; end else begin case (state) IDLE: begin if (pps_in) begin state <= WAIT_HIGH; counter <= 8'b0; end else begin state <= WAIT_LOW; counter <= 8'b0; end end WAIT_LOW: begin if (pps_in) begin counter <= counter + 1; if (counter == 8'd255) begin state <= WAIT_HIGH; pps_out <= 1'b1; counter <= 8'b0; end end else begin counter <= 8'b0; end end WAIT_HIGH: begin if (!pps_in) begin counter <= counter + 1; if (counter == 8'd255) begin state <= WAIT_LOW; pps_out <= 1'b0; counter <= 8'b0; end end else begin counter <= 8'b0; end end default: state <= IDLE; endcase end end endmodule ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值