使用时序逻辑对一个单bit信号进行毛刺滤除操作,高电平或者低电平宽度小于4个时钟周期的为毛刺。
一、分析
边沿检测+计数的方法,检测到上升沿或下降沿说明可能是信号变化或毛刺,检测到边沿变化后计数器清零并开始计数,计数到3说明单bit信号不是毛刺,可以赋值并停止计数;未计数到3说明单bit信号是毛刺信号,不赋值。
二、时序分析
三、代码
module glitch_filter(
input wire Clk_50M,
input wire Rst_n,
input wire data_in,
output wire pose_data,
output wire nege_data,
output wire pose_nege_data,
output reg data_out
);
//边沿检测
reg data_in_r;
always@(posedge Clk_50M or negedge Rst_n)
begin
if(!Rst_n)
data_in_r <= 1'b0;
else
data_in_r <= data_in;
end
assign pose_data = data_in && (~data_in_r);
assign nege_data = ~data_in && data_in_r;
assign pose_nege_data = data_in ^ data_in_r;
//计数
reg [1:0]cnt;
always@(posedge Clk_50M or negedge Rst_n)
begin
if(!Rst_n)
cnt <= 2'd0;
else if(pose_nege_data)
cnt <= 2'd0;
else
cnt <= cnt + 1'd1;
end
//根据计数器判断输出
always@(posedge Clk_50M or negedge Rst_n)
begin
if(!Rst_n)
data_out <= 1'b0;
else if(&cnt) //cnt == 2'b11
data_out <= data_in_r;
end
endmodule
四、仿真代码及结果
`timescale 1ns/1ns
`define clk_period 20 //50M
module glitch_filter_tb();
reg Clk_50M;
reg Rst_n;
reg data_in;
wire pose_data;
wire nege_data;
wire pose_nege_data;
wire data_out;
glitch_filter glitch_filter_U(
.Clk_50M(Clk_50M),
.Rst_n(Rst_n),
.data_in(data_in),
.pose_data(pose_data),
.nege_data(nege_data),
.pose_nege_data(pose_nege_data),
.data_out(data_out)
);
always #(`clk_period/2) Clk_50M = ~Clk_50M;
initial begin
Clk_50M = 1;
Rst_n = 0;
#(`clk_period*5+1);
Rst_n = 1;
end
//计数
reg [6:0]cnt_tb;
always@(posedge Clk_50M or negedge Rst_n)
begin
if(!Rst_n)
cnt_tb <= 7'd0;
else
cnt_tb <= cnt_tb + 7'd1;
end
//输入:0001110111100100001111111+随机数
always@(posedge Clk_50M or negedge Rst_n)
begin
if(!Rst_n)
data_in <= 1'b0;
else if((cnt_tb<7'd3)||(cnt_tb==7'd6) ||(cnt_tb>7'd10&&cnt_tb<7'd13)||(cnt_tb>7'd13&&cnt_tb<7'd18))
data_in <= 1'b0;
else if((cnt_tb>7'd2&&cnt_tb<7'd6)||(cnt_tb>7'd6&&cnt_tb<7'd11)||(cnt_tb==7'd13) ||(cnt_tb>7'd17&&cnt_tb<7'd25))
data_in <= 1'b1;
else
data_in <= {$random}%2;
end
endmodule