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
how to filter glitches and mutliple transitions?
Started by ●November 15, 2006
Reply by ●November 15, 20062006-11-15
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
Reply by ●November 15, 20062006-11-15
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
Reply by ●November 15, 20062006-11-15
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
Reply by ●November 15, 20062006-11-15
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
Reply by ●November 15, 20062006-11-15
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; > endmaybe 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
Reply by ●November 16, 20062006-11-16
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
Reply by ●November 16, 20062006-11-16
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
Reply by ●November 16, 20062006-11-16
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
Reply by ●November 16, 20062006-11-16
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






