用verilog写一段代码,实现消除一个glitch
最近在准备FPGA方面的求职面试,遇到这样一题目“用verilog写一段代码,实现消除一个glitch”,于是在网上找了些资料,根据一篇博客作者提供的资料,现把消除glitch方法做了如下整理,望批评指正:
滤掉小于1个周期glitch的原理图如下:

verilog代码实现如下:
module digital_filter_(clk_in,rst,host_rst,host_rst_filter);
input clk_in;
input rst;
input host_rst;
output host_rst_filter;
reg host_rst_d1;
reg host_rst_d2;
always@(posedge clk_in or negedge rst)
begin
if(~rst)
begin
host_rst_d1 <= 1'b1;
host_rst_d2 <= 1'b1;
end
else
begin
host_rst_d1 <= host_rst;
host_rst_d2 <= host_rst_d1;
end
end
assign host_rst_filter = host_rst_d1 | host_rst_d2;
endmodule
滤掉大于1个周期且小于2个周期glitch的原理图如下:

verilog代码如下:
module digital_filter_(clk_in,rst,host_rst,host_rst_filter);
input clk_in;
input rst;
input host_rst;
output host_rst_filter;
reg host_rst_d1;
reg host_rst_d2;
reg host_rst_d3;
always@(posedge clk_in or negedge rst)
begin
if(~rst)
begin
host_rst_d1 <= 1'b1;
host_rst_d2 <= 1'b1;
host_rst_d3 <= 1'b1;
end
else
begin
host_rst_d1 <= host_rst;
host_rst_d2 <= host_rst_d1;
host_rst_d3 <= host_rst_d2;
end
end
assign host_rst_filter = host_rst_d1 | host_rst_d2 | host_rst_d3;
endmodule
`timescale 1ns/1ps
module glitch_filter_TB;
/********************************************************\
parameter
\********************************************************/
parameter U_DLY = 1;
parameter CLK_P = 10;
/********************************************************\
signals
\********************************************************/
reg clk;
reg rst_n;
reg glitch1;
reg [1:0] glitch_shifter1;
wire filter1;
reg glitch2;
reg [1:0] glitch_shifter2;
wire filter2;
/********************************************************\
Generat clok and reset
\********************************************************/
initial
begin
clk = 1'b0;
rst_n = 1'b0;
#(CLK_P*10);
@(negedge clk);
rst_n = 1'b1;
end
always #(CLK_P/2) clk = ~clk;
/********************************************************\
main code
\********************************************************/
assign filter1 = &glitch_shifter1;
assign filter2 = &glitch_shifter2;
initial
begin
glitch1 = 1'b0;
glitch2 = 1'b0;
wait(rst_n==1'b1);
#(CLK_P*10);
@(negedge clk)
begin
glitch1 <= 1'b1;
glitch2 <= 1'b1;
end
@(posedge clk);
glitch1 <= #1 1'b0;
@(negedge clk);
glitch2 <= #1 1'b0;
#(CLK_P*10);
$stop;
end
always@(posedge clk,negedge rst_n)
begin
if(rst_n==1'b0)
begin
glitch_shifter1 <= 'h0;
glitch_shifter2 <= 'h0;
end
else
begin
glitch_shifter1 <= #1 {glitch_shifter1[0],glitch1};
glitch_shifter2 <= #1 {glitch_shifter2[0],glitch2};
end
end
endmodule
仿真结果如下:

看电路图只是消除单边glitch,一般使用都会用双边。
有两个问题:
1.glitch的位置如果是随机的,那么通过第1个触发器之后的信号是亚稳态的,不能用于后面的与门,会导致与门的结果出错。
2.功能上,连续两个周期为1,才输出1,否则输出0.实际中的glitch有可能是反过来的。当然根据需要来调整就好了。
输出应该是与的关系而不是或的关系吧?
并且第一个触发器输出亚问题的时候怎么办?
异步信号输入起码要用两个触发器打一下,第一用于同步,第二个用于消除亚稳态。
所以第一个图中应该再加一个触发器,第二个要三个或,也需要再加一个。
用寄存器打两拍也不能完全消除亚稳态的出现,不让亚稳态出现的唯一办法是不用异步信号。当然打两拍能够大大减少亚稳态出现的概率。
ghefjwefqwerjwerj
学习了。
为什么要消除?
什么是glitch?你怎么知道两个周期,或者三个周期的信号不是正常信号,而是glitch?
能持续一个周期的绝对不叫Glitch...
這些無法消除短於脈波寬度的 glitch.
信号,还是同步的好。
总是在理论上听到两拍不能完全消除亚稳态,不知道你遇到过两拍消除亚稳态失败的案例没?
I thought your code is the signal de-bouncing circuit. That can't filter the glitch by the combination circuit. For example, How can used your circuit to filter the glitch of 1ns pulse width and so on.
好!
谢谢小编!
评论说的都不知道是啥,就没一个靠谱的
4楼说的对!
只用或门只能消除‘0’ glitch,只用与门只能消除'1' glitch。
另外,楼上其他人的回复老是针对片内信号,即组合逻辑的,实际上既然消除glitch,那肯定是片外的信号,所以可以大于几个周期。
小编很牛啊
你可以去找一篇老外写的关于两拍消除亚稳态的文章看看,记不得了,里面详细分析了两拍消除亚稳态的原理,并计算了两拍之后出现亚稳态的概率,确实不会完全消除,只是说概率上可以认为亚稳态不会在出现,没有办法完全消除的。
很好 学习了 谢谢
学习。
