FPGARelated.com
Forums

how to filter glitches and mutliple transitions?

Started by Frank Buss November 15, 2006
I have built a prototyp board with wires between the FPGA and an external
component. With the scope I can see glitches (looks like from crosstalk
when switching other signals) and multiple transitions are detected by the
FPGA when switching signals. Looks like the noise is < 200 ns. The period
of the wanted signal is > 3 us. I think with a PCB there would be less
problems, but there is lots of space left inside the FPGA, so it should be
possible enhance the signal with logic so that it works even with the noisy
wired prototype. What do you do normally to solve this kind of problems?

My idea is to use a low-pass filter: a n bit counter, which is incremented
with system clock, if the input signal is 1 and decremented otherwise. If
all n bits are 1, the counter is not incremented and if all bits are 0, it
is not decremented. If the highest bit is set, then the sampled signal is
considered as 1, otherwise as 0. I could encapsulate this function within a
VHDL entity, so it is easy to use it for multiple input signals and maybe a
generic for specifying n.

-- 
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Frank Buss wrote:
> I have built a prototyp board with wires between the FPGA and an external > component. With the scope I can see glitches (looks like from crosstalk > when switching other signals) and multiple transitions are detected by the > FPGA when switching signals. Looks like the noise is < 200 ns. The period > of the wanted signal is > 3 us. I think with a PCB there would be less > problems, but there is lots of space left inside the FPGA, so it should be > possible enhance the signal with logic so that it works even with the noisy > wired prototype. What do you do normally to solve this kind of problems? > > My idea is to use a low-pass filter: a n bit counter, which is incremented > with system clock, if the input signal is 1 and decremented otherwise. If > all n bits are 1, the counter is not incremented and if all bits are 0, it > is not decremented. If the highest bit is set, then the sampled signal is > considered as 1, otherwise as 0. I could encapsulate this function within a > VHDL entity, so it is easy to use it for multiple input signals and maybe a > generic for specifying n. >
Hi Frank You are describing a soft filter. I have a number of them in a current design (it's in a rather noisy environment) and I use a 5 bit counter as part of a state machine. I assume you have an appropriate clock, so simply qualify the signal as continuously present (or perhaps mostly present) for the 3us you state. With a 10MHz clock, for example, a 5 bit counter is almost perfect (and besides, we can always terminate at count = 30 ;) I like your approach, but this is simple and uses pretty limited resources. so, somewhere wire Sig; // the signal we are watching reg SigValid; // valid indicator reg [4:0] SigCount; always @(posedge clk) begin if (!Sig) begin SigCount <= 5'b00000; // signal disappeared, clear counter SigValid <= 1'b0; end else if(Sig & SigCount < 28) begin SigCount <= SigCount+1; end else if (SigCount == 28) begin SigValid <= 1'b1; // Signal has been true for 30 consecutive // clocks. end end Simple, as I said, and if you find bugs, I state in my defence I have had a couple of glasses of wine :) Cheers PeteS
A small fix :)

PeteS wrote:
> Frank Buss wrote: >> I have built a prototyp board with wires between the FPGA and an external >> component. With the scope I can see glitches (looks like from crosstalk >> when switching other signals) and multiple transitions are detected by >> the >> FPGA when switching signals. Looks like the noise is < 200 ns. The period >> of the wanted signal is > 3 us. I think with a PCB there would be less >> problems, but there is lots of space left inside the FPGA, so it >> should be >> possible enhance the signal with logic so that it works even with the >> noisy >> wired prototype. What do you do normally to solve this kind of problems? >> >> My idea is to use a low-pass filter: a n bit counter, which is >> incremented >> with system clock, if the input signal is 1 and decremented otherwise. If >> all n bits are 1, the counter is not incremented and if all bits are >> 0, it >> is not decremented. If the highest bit is set, then the sampled signal is >> considered as 1, otherwise as 0. I could encapsulate this function >> within a >> VHDL entity, so it is easy to use it for multiple input signals and >> maybe a >> generic for specifying n. >> > > Hi Frank > > You are describing a soft filter. > > I have a number of them in a current design (it's in a rather noisy > environment) and I use a 5 bit counter as part of a state machine. > > I assume you have an appropriate clock, so simply qualify the signal as > continuously present (or perhaps mostly present) for the 3us you state. > > With a 10MHz clock, for example, a 5 bit counter is almost perfect (and > besides, we can always terminate at count = 30 ;) > > I like your approach, but this is simple and uses pretty limited resources. > > so, somewhere > > wire Sig; // the signal we are watching > reg SigValid; // valid indicator > reg [4:0] SigCount; > > > always @(posedge clk) > begin > if (!Sig) > begin > SigCount <= 5'b00000; // signal disappeared, clear counter > SigValid <= 1'b0; > end > else if(Sig & SigCount < 28) > begin > SigCount <= SigCount+1; > > end
// fix the next line // was else if (SigCount == 28) else if (Sig & SigCount == 28) // qualify signal properly
> begin > SigValid <= 1'b1; // Signal has been true for 30 > consecutive // clocks. > end > end > > Simple, as I said, and if you find bugs, I state in my defence I have > had a couple of glasses of wine :) > > > Cheers > > PeteS
Frank Buss wrote:

> I have built a prototyp board with wires between the FPGA and an external > component. With the scope I can see glitches (looks like from crosstalk > when switching other signals) and multiple transitions are detected by the > FPGA when switching signals. Looks like the noise is < 200 ns. The period > of the wanted signal is > 3 us. I think with a PCB there would be less > problems, but there is lots of space left inside the FPGA, so it should be > possible enhance the signal with logic so that it works even with the noisy > wired prototype. What do you do normally to solve this kind of problems? > > My idea is to use a low-pass filter: a n bit counter, which is incremented > with system clock, if the input signal is 1 and decremented otherwise. If > all n bits are 1, the counter is not incremented and if all bits are 0, it > is not decremented. If the highest bit is set, then the sampled signal is > considered as 1, otherwise as 0. I could encapsulate this function within a > VHDL entity, so it is easy to use it for multiple input signals and maybe a > generic for specifying n.
Yes, that's a saturating counter. You have one minor blindspot in your topology, if you merely use the MSB as the output, it can spin quite quickly if the pattern makes your counter go 01111 / 10000 / 01111 / 10000 So, better is to take something like the saturating sense logic (which has to already be there), and feed a JK FF, or SyncSET/SyncRST -jg
I assume, because we are talking about glitches, that changes in Sig
are effectively asynch to the clk - so shouldn't it be synchronised
with a 2 flip-flop synchronizer first, or else the counter could count
incorrectly? (some flip-flops seeing the value as a 1, others seeing it
as a 0 ) perhaps the nature of the system means it can recover from
that, but I think it would make it safer.
(I've had a few glasses of wine too, so the same disclaimer for me!)
Cheers
John

PeteS wrote:
> A small fix :) > > PeteS wrote: > > Frank Buss wrote: > >> I have built a prototyp board with wires between the FPGA and an external > >> component. With the scope I can see glitches (looks like from crosstalk > >> when switching other signals) and multiple transitions are detected by > >> the > >> FPGA when switching signals. Looks like the noise is < 200 ns. The period > >> of the wanted signal is > 3 us. I think with a PCB there would be less > >> problems, but there is lots of space left inside the FPGA, so it > >> should be > >> possible enhance the signal with logic so that it works even with the > >> noisy > >> wired prototype. What do you do normally to solve this kind of problems? > >> > >> My idea is to use a low-pass filter: a n bit counter, which is > >> incremented > >> with system clock, if the input signal is 1 and decremented otherwise. If > >> all n bits are 1, the counter is not incremented and if all bits are > >> 0, it > >> is not decremented. If the highest bit is set, then the sampled signal is > >> considered as 1, otherwise as 0. I could encapsulate this function > >> within a > >> VHDL entity, so it is easy to use it for multiple input signals and > >> maybe a > >> generic for specifying n. > >> > > > > Hi Frank > > > > You are describing a soft filter. > > > > I have a number of them in a current design (it's in a rather noisy > > environment) and I use a 5 bit counter as part of a state machine. > > > > I assume you have an appropriate clock, so simply qualify the signal as > > continuously present (or perhaps mostly present) for the 3us you state. > > > > With a 10MHz clock, for example, a 5 bit counter is almost perfect (and > > besides, we can always terminate at count = 30 ;) > > > > I like your approach, but this is simple and uses pretty limited resources. > > > > so, somewhere > > > > wire Sig; // the signal we are watching > > reg SigValid; // valid indicator > > reg [4:0] SigCount; > > > > > > always @(posedge clk) > > begin > > if (!Sig) > > begin > > SigCount <= 5'b00000; // signal disappeared, clear counter > > SigValid <= 1'b0; > > end > > else if(Sig & SigCount < 28) > > begin > > SigCount <= SigCount+1; > > > > end > // fix the next line > // was else if (SigCount == 28) > else if (Sig & SigCount == 28) > > // qualify signal properly > > > begin > > SigValid <= 1'b1; // Signal has been true for 30 > > consecutive // clocks. > > end > > end > > > > Simple, as I said, and if you find bugs, I state in my defence I have > > had a couple of glasses of wine :) > > > > > > Cheers > > > > PeteS
PeteS wrote:

> I like your approach, but this is simple and uses pretty limited resources. > > so, somewhere
> if (!Sig) > begin > SigCount <= 5'b00000; // signal disappeared, clear counter > SigValid <= 1'b0; > end
maybe this is sufficient, but this solution won't filter negative glitches. See below for my try, with hysteresis (thanks Jim for the blindspot). I wonder if it is overkill :-) library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity low_pass_filter is generic( counter_max: positive := 30; hysteresis: positive := 5); port( clock: in std_logic; reset: in std_logic; input: in std_logic; output: out std_logic); end entity low_pass_filter; architecture rtl of low_pass_filter is constant low_limit: natural := (counter_max - hysteresis) / 2; constant high_limit: natural := low_limit + hysteresis; signal counter: natural range 0 to counter_max := 0; type state_type is (low, high); signal state: state_type := low; begin filter: process(clock) begin if reset = '1' then counter <= 0; state <= low; output <= '0'; elsif rising_edge(clock) then -- update output with hysteresis case state is when low => if counter > high_limit then output <= '1'; state <= high; else output <= '0'; end if; when high => if counter < low_limit then output <= '0'; state <= low; else output <= '1'; end if; end case; -- update counter if input = '1' then if counter < counter_max then counter <= counter + 1; end if; else if counter > 0 then counter <= counter - 1; end if; end if; end if; end process; end architecture rtl; Test bench: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity low_pass_filter_test is end entity low_pass_filter_test; architecture rtl of low_pass_filter_test is constant bits: positive := 2; signal input: std_logic := '0'; signal output: std_logic := '0'; signal clock: std_logic := '1'; begin low_pass_filter_test_inst: entity low_pass_filter generic map( counter_max => 30, hysteresis => 5) port map( clock => clock, reset => '0', input => input, output => output); test_it: process procedure do_clock(count: positive) is begin for i in 1 to count loop clock <= not clock; wait for 10 ns; clock <= not clock; wait for 10 ns; end loop; end do_clock; begin -- startup input <= '0'; do_clock(30); -- test high hysteresis input <= '1'; do_clock(1); assert output = '0' report "failed 1." severity failure; do_clock(17); assert output = '0' report "failed 2." severity failure; do_clock(1); assert output = '1' report "failed 3." severity failure; input <= '0'; do_clock(3); assert output = '1' report "failed 4." severity failure; input <= '1'; do_clock(3); assert output = '1' report "failed 5." severity failure; -- test low hysteresis input <= '0'; do_clock(7); assert output = '1' report "failed 6." severity failure; do_clock(1); assert output = '1' report "failed 7." severity failure; do_clock(1); assert output = '0' report "failed 8." severity failure; input <= '1'; do_clock(1); assert output = '0' report "failed 9." severity failure; do_clock(3); assert output = '0' report "failed 10." severity failure; -- test low saturation input <= '0'; do_clock(40); assert output = '0' report "failed 11." severity failure; -- test high saturation input <= '1'; do_clock(40); assert output = '1' report "failed 12." severity failure; assert false report "No failure, simulation was successful." severity failure; end process; end architecture rtl; -- Frank Buss, fb@frank-buss.de http://www.frank-buss.de, http://www.it4-systems.de
John McGrath wrote:
> I assume, because we are talking about glitches, that changes in Sig > are effectively asynch to the clk - so shouldn't it be synchronised > with a 2 flip-flop synchronizer first, or else the counter could count > incorrectly? (some flip-flops seeing the value as a 1, others seeing it > as a 0 ) perhaps the nature of the system means it can recover from > that, but I think it would make it safer. > (I've had a few glasses of wine too, so the same disclaimer for me!) > Cheers > John > > PeteS wrote: >> A small fix :) >> >> PeteS wrote: >>> Frank Buss wrote: >>>> I have built a prototyp board with wires between the FPGA and an external >>>> component. With the scope I can see glitches (looks like from crosstalk >>>> when switching other signals) and multiple transitions are detected by >>>> the >>>> FPGA when switching signals. Looks like the noise is < 200 ns. The period >>>> of the wanted signal is > 3 us. I think with a PCB there would be less >>>> problems, but there is lots of space left inside the FPGA, so it >>>> should be >>>> possible enhance the signal with logic so that it works even with the >>>> noisy >>>> wired prototype. What do you do normally to solve this kind of problems? >>>> >>>> My idea is to use a low-pass filter: a n bit counter, which is >>>> incremented >>>> with system clock, if the input signal is 1 and decremented otherwise. If >>>> all n bits are 1, the counter is not incremented and if all bits are >>>> 0, it >>>> is not decremented. If the highest bit is set, then the sampled signal is >>>> considered as 1, otherwise as 0. I could encapsulate this function >>>> within a >>>> VHDL entity, so it is easy to use it for multiple input signals and >>>> maybe a >>>> generic for specifying n. >>>> >>> Hi Frank >>> >>> You are describing a soft filter. >>> >>> I have a number of them in a current design (it's in a rather noisy >>> environment) and I use a 5 bit counter as part of a state machine. >>> >>> I assume you have an appropriate clock, so simply qualify the signal as >>> continuously present (or perhaps mostly present) for the 3us you state. >>> >>> With a 10MHz clock, for example, a 5 bit counter is almost perfect (and >>> besides, we can always terminate at count = 30 ;) >>> >>> I like your approach, but this is simple and uses pretty limited resources. >>> >>> so, somewhere >>> >>> wire Sig; // the signal we are watching >>> reg SigValid; // valid indicator >>> reg [4:0] SigCount; >>> >>> >>> always @(posedge clk) >>> begin >>> if (!Sig) >>> begin >>> SigCount <= 5'b00000; // signal disappeared, clear counter >>> SigValid <= 1'b0; >>> end >>> else if(Sig & SigCount < 28) >>> begin >>> SigCount <= SigCount+1; >>> >>> end >> // fix the next line >> // was else if (SigCount == 28) >> else if (Sig & SigCount == 28) >> >> // qualify signal properly >> >>> begin >>> SigValid <= 1'b1; // Signal has been true for 30 >>> consecutive // clocks. >>> end >>> end >>> >>> Simple, as I said, and if you find bugs, I state in my defence I have >>> had a couple of glasses of wine :) >>> >>> >>> Cheers >>> >>> PeteS >
Well, in this case, I have a 5 flipflop synchroniser :) Cheers PeteS
Frank Buss wrote:

> entity low_pass_filter is > generic( > counter_max: positive := 30; > hysteresis: positive := 5);
Some corrections: hysteresis doesn't make sense. I've deleted it and tested in low-state for counter=counter_max and in high-state for counter=0 and tested it today with real hardware and it works. -- Frank Buss, fb@frank-buss.de http://www.frank-buss.de, http://www.it4-systems.de
Frank Buss wrote:
> Frank Buss wrote: > >> entity low_pass_filter is >> generic( >> counter_max: positive := 30; >> hysteresis: positive := 5); > > Some corrections: hysteresis doesn't make sense. I've deleted it and tested > in low-state for counter=counter_max and in high-state for counter=0 and > tested it today with real hardware and it works. >
Well, good! If talking through a problem helps you solve it, only too glad to talk :) Cheers PeteS
Except the asynch control signal is going to all 5 flip-flops at the
same time, which means if it came at just the wrong time, some would
capture it, and others would not - causing unexpected behaviour. in a
real synchronizer, the asynch signal only goes to one flip-flop.

PeteS wrote:
> John McGrath wrote: > > I assume, because we are talking about glitches, that changes in Sig > > are effectively asynch to the clk - so shouldn't it be synchronised > > with a 2 flip-flop synchronizer first, or else the counter could count > > incorrectly? (some flip-flops seeing the value as a 1, others seeing it > > as a 0 ) perhaps the nature of the system means it can recover from > > that, but I think it would make it safer. > > (I've had a few glasses of wine too, so the same disclaimer for me!) > > Cheers > > John > > > > PeteS wrote: > >> A small fix :) > >> > >> PeteS wrote: > >>> Frank Buss wrote: > >>>> I have built a prototyp board with wires between the FPGA and an external > >>>> component. With the scope I can see glitches (looks like from crosstalk > >>>> when switching other signals) and multiple transitions are detected by > >>>> the > >>>> FPGA when switching signals. Looks like the noise is < 200 ns. The period > >>>> of the wanted signal is > 3 us. I think with a PCB there would be less > >>>> problems, but there is lots of space left inside the FPGA, so it > >>>> should be > >>>> possible enhance the signal with logic so that it works even with the > >>>> noisy > >>>> wired prototype. What do you do normally to solve this kind of problems? > >>>> > >>>> My idea is to use a low-pass filter: a n bit counter, which is > >>>> incremented > >>>> with system clock, if the input signal is 1 and decremented otherwise. If > >>>> all n bits are 1, the counter is not incremented and if all bits are > >>>> 0, it > >>>> is not decremented. If the highest bit is set, then the sampled signal is > >>>> considered as 1, otherwise as 0. I could encapsulate this function > >>>> within a > >>>> VHDL entity, so it is easy to use it for multiple input signals and > >>>> maybe a > >>>> generic for specifying n. > >>>> > >>> Hi Frank > >>> > >>> You are describing a soft filter. > >>> > >>> I have a number of them in a current design (it's in a rather noisy > >>> environment) and I use a 5 bit counter as part of a state machine. > >>> > >>> I assume you have an appropriate clock, so simply qualify the signal as > >>> continuously present (or perhaps mostly present) for the 3us you state. > >>> > >>> With a 10MHz clock, for example, a 5 bit counter is almost perfect (and > >>> besides, we can always terminate at count = 30 ;) > >>> > >>> I like your approach, but this is simple and uses pretty limited resources. > >>> > >>> so, somewhere > >>> > >>> wire Sig; // the signal we are watching > >>> reg SigValid; // valid indicator > >>> reg [4:0] SigCount; > >>> > >>> > >>> always @(posedge clk) > >>> begin > >>> if (!Sig) > >>> begin > >>> SigCount <= 5'b00000; // signal disappeared, clear counter > >>> SigValid <= 1'b0; > >>> end > >>> else if(Sig & SigCount < 28) > >>> begin > >>> SigCount <= SigCount+1; > >>> > >>> end > >> // fix the next line > >> // was else if (SigCount == 28) > >> else if (Sig & SigCount == 28) > >> > >> // qualify signal properly > >> > >>> begin > >>> SigValid <= 1'b1; // Signal has been true for 30 > >>> consecutive // clocks. > >>> end > >>> end > >>> > >>> Simple, as I said, and if you find bugs, I state in my defence I have > >>> had a couple of glasses of wine :) > >>> > >>> > >>> Cheers > >>> > >>> PeteS > > > > Well, in this case, I have a 5 flipflop synchroniser :) > > Cheers > > PeteS