Altera_Forum
Honored Contributor
11 years agoDeglitch Logic Metastability
I'm trying to determine if the way this deglitching filter was written will incur a metastability issue:
sig_filt : process (i_clk)
variable abc : std_logic_vector(2 downto 0) := "000";
variable abc_last : std_logic_vector(2 downto 0) := "000";
variable abc_count : integer := 0;
begin
if rising_edge(i_clk) then
-- filter 'a', 'b', 'c' signals as a group
-- all signals need to be in a stable state
-- for FILT_COUNTS clk periods before transitions
-- are passed up to the state decoder
abc(2) := a;
abc(1) := b;
abc(0) := c;
if abc /= abc_last then
abc_count := 0;
abc_last := abc;
elsif abc_count < FILT_COUNTS then
abc_count := abc_count + 1;
else
filt_a <= a;
filt_b <= b;
filt_c <= c;
end if;
end if;
end process; The way I think this should be written: sig_filt : process (i_clk)
variable abc : std_logic_vector(2 downto 0) := "000";
variable abc_last : std_logic_vector(2 downto 0) := "000";
variable abc_count : integer := 0;
begin
if rising_edge(i_clk) then
-- filter 'a', 'b', 'c' signals as a group
-- all signals need to be in a stable state
-- for FILT_COUNTS clk periods before transitions
-- are passed up to the state decoder
abc(2) := a;
abc(1) := b;
abc(0) := c;
if abc /= abc_last then
abc_count := 0;
elsif abc_count < FILT_COUNTS then
abc_count := abc_count + 1;
else
filt_a <= abc_last(2);
filt_b <= abc_last(1);
filt_c <= abc_last(0);
end if;
abc_last := abc;
end if;
end process; or at least: sig_filt : process (i_clk)
variable abc : std_logic_vector(2 downto 0) := "000";
variable abc_last : std_logic_vector(2 downto 0) := "000";
variable abc_count : integer := 0;
begin
if rising_edge(i_clk) then
-- filter 'a', 'b', 'c' signals as a group
-- all signals need to be in a stable state
-- for FILT_COUNTS clk periods before transitions
-- are passed up to the state decoder
abc(2) := a;
abc(1) := b;
abc(0) := c;
if abc /= abc_last then
abc_count := 0;
abc_last := abc;
elsif abc_count < FILT_COUNTS then
abc_count := abc_count + 1;
else
filt_a <= abc(2);
filt_b <= abc(1);
filt_c <= abc(0);
end if;
end if;
end process; What I'm thinking could happen in the first snippet is while the abc and abc_last match for the edge, the input signals a, b, and c, could glitch right before they are latched into filt_a, filt_b, or filt_c signals. By using the abc_last values, this is mitigated. Any thoughts? Am I over thinking this? Trying to resolve a once in rare occurence issue, which in my mind could be attributed to this filtering logic which seems a bit off.