hello all, I'm sure their are different ways to do this, and I would like to explore them at a later date, but as I'm still novice at VHDL coding I'd like to know what is wrong with this particular code. Its a simple debounce process and the synthesize reports an error on line 44: ---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 08:06:38 12/31/2008 -- Design Name: -- Module Name: VhdlModule1 - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; --line 20 use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity VhdlModule1 is --line 30 port( CLK : in std_logic; SIGNAL_IN : in std_logic; SIGNAL_OUT : out std_logic); end VhdlModule1; architecture Behavioral of VhdlModule1 is constant DEBOUNCE_COUNT : integer := 5; signal SIGNAL_OUT_TEMP : std_logic := '0'; begin P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP) -- line 44 variable mycount : integer := 0; begin if (CLK = '1' and CLK'event and SIGNAL_OUT_TEMP /= SIGNAL_IN) then mycount := mycount + 1; -- line 48 if (mycount >= DEBOUNCE_COUNT) then SIGNAL_OUT_TEMP <= SIGNAL_IN; mycount := 0; end if; else mycount := 0; -- line 54 end if; SIGNAL_OUT <= SIGNAL_OUT_TEMP; end process P1; end Behavioral; ----------------------------------------------------------------------------------------------------------------------------- the error message is this: ******************************************* Analyzing Entity <VhdlModule1> in library <work> (Architecture <Behavioral>). ERROR:Xst:827 - "//dhpc-1/shared/jon/MyVhdl/VhdlModule1.vhd" line 44: Signal mycount cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release. ****************************************** I've tried this code with both 9.2 and the 10.1 ISE with no change. I've also tried declaring mycount as a SIGNAL and that didn't change anything either (another question is why I would want mycount to be a SIGNAL or a VARIABLE, pros and cons but lets stick to the main issue first) In my trial and terror attempt to fix this synth, I can report that if I comment out either line 48 or 54 the synth works, but I don't understand why I can't have both lines in and the code be valid. I'm guessing my problem is me trying to program with my single cpu, sequential processing C background in the very non-linear non- sequential environment that is VHDL, so any insight into this would be helpful. Sincerely, Jon
beginner synthesize question - my debounce process won't synthesize.
Started by ●January 5, 2009
Reply by ●January 5, 20092009-01-05
> P1: process (CLK, SIGNAL_IN, > SIGNAL_OUT_TEMP) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ==A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- line 44> variable mycount : integer :=3D 0; > begin > =A0 =A0 =A0 =A0 if (CLK =3D '1' and CLK'event and SIGNAL_OUT_TEMP /=3D SI=GNAL_IN) then> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mycount :=3D mycount + > 1; > -- line 48 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (mycount >=3D DEBOUNCE_COUNT) then > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 SIGNAL_OUT_TEMP <=3D SIGN=AL_IN;> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mycount :=3D 0; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end if; > =A0 =A0 =A0 =A0 else > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mycount :=3D > 0; > -- line 54 > =A0 =A0 =A0 =A0 end if; > =A0 =A0 =A0 =A0 SIGNAL_OUT <=3D SIGNAL_OUT_TEMP; > end process P1; > > end Behavioral;First, consider what it is you're trying to synthesize in terms of discrete logic parts (think 74xx series logic components). Then, you will probably find that your problem is that there are no logic elements that can support how you're describing mycount. mycount as described can change on both the rising and falling edges of CLK. Most likely, the FPGA you are designing for does not have dual-edge triggered internal flipflops (although interestingly, CoolRunner CPLDs do). I also think that's not what you want. In addition, I suspect you'll have a problem with SIGNAL_OUT for similar reasons, but I'll leave that as an exercise to you.
Reply by ●January 5, 20092009-01-05
What Nathan said is correct. Specifically what you are doing wrong is including the comparison "SIGNAL_OUT_TEMP /= SIGNAL_IN" in the IF that detects the rising edge of the clock. You also have an else condition that covers the case when the comparison fails, as well as any time the clock is ***NOT*** at a rising edge. You need to separate the if for the clock edge from the if for the enabling condition. You will do much better as a beginner if you don't treat an HDL as a programming language, but rather use it to describe hardware. When you try to "program" in an HDL you often end up with code that is not even synthesizable as you have done. Don't "program" hardware, "describe" hardware! So first think of the hardware you want to implement and then look up the HDL constructs that will produce this hardware. Logic is pretty much logic, but registers take a little practice to get right. You have to specify the clock correctly and consistently as well as understanding when a clock enable will be used and when all of the logic will be rolled into the D input of the D-FF. A couple of points about how you are generating SIGNAL_OUT. The debounce circuit must prevent SIGNAL_OUT from glitching, but it does not *have* to introduce a delay. Also, your design is retriggerable so that each time the input changes earlier than the timeout the counter resets and starts over. Another way to do this is to use a longer timeout that is assured of being longer than the debounce time and updating SIGNAL_OUT as soon as the input changes the *first* time. So the input change is detected and the output follows while the counter starts. Until the counter reaches the timeout, SIGNAL_OUT is inhibited from changing again. This prevents the output from bouncing, but does not introduce the delay that the circuit below will have. Rick On Jan 5, 11:20 am, jleslie48 <j...@jonathanleslie.com> wrote:> hello all, > > I'm sure their are different ways to do this, and I would like to > explore them at a later date, but as I'm still novice at VHDL coding > I'd like to know what is wrong with this particular code. Its a > simple debounce process and the synthesize reports an error on line > 44: > > ---------------------------------------------------------------------------------- > -- Company: > -- Engineer: > -- > -- Create Date: 08:06:38 12/31/2008 > -- Design Name: > -- Module Name: VhdlModule1 - Behavioral > -- Project Name: > -- Target Devices: > -- Tool versions: > -- Description: > -- > -- Dependencies: > -- > -- Revision: > -- Revision 0.01 - File Created > -- Additional Comments: > -- > ---------------------------------------------------------------------------------- > library > IEEE; > --line 20 > use IEEE.STD_LOGIC_1164.ALL; > use IEEE.STD_LOGIC_ARITH.ALL; > use IEEE.STD_LOGIC_UNSIGNED.ALL; > > ---- Uncomment the following library declaration if instantiating > ---- any Xilinx primitives in this code. > --library UNISIM; > --use UNISIM.VComponents.all; > > entity VhdlModule1 > is > --line 30 > port( CLK : in std_logic; > SIGNAL_IN : in std_logic; > SIGNAL_OUT : out std_logic); > end VhdlModule1; > > architecture Behavioral of VhdlModule1 is > > constant DEBOUNCE_COUNT : integer := 5; > signal SIGNAL_OUT_TEMP : std_logic := '0'; > > begin > > P1: process (CLK, SIGNAL_IN, > SIGNAL_OUT_TEMP) -- line 44 > variable mycount : integer := 0; > begin > if (CLK = '1' and CLK'event and SIGNAL_OUT_TEMP /= SIGNAL_IN) then > mycount := mycount + > 1; > -- line 48 > if (mycount >= DEBOUNCE_COUNT) then > SIGNAL_OUT_TEMP <= SIGNAL_IN; > mycount := 0; > end if; > else > mycount := > 0; > -- line 54 > end if; > SIGNAL_OUT <= SIGNAL_OUT_TEMP; > end process P1; > > end Behavioral; > > ----------------------------------------------------------------------------------------------------------------------------- > > the error message is this: > ******************************************* > Analyzing Entity <VhdlModule1> in library <work> (Architecture > <Behavioral>). > > ERROR:Xst:827 - "//dhpc-1/shared/jon/MyVhdl/VhdlModule1.vhd" line 44: > Signal mycount cannot be synthesized, bad synchronous description. The > description style you are using to describe a synchronous element > (register, memory, etc.) is not supported in the current software > release. > > ****************************************** > I've tried this code with both 9.2 and the 10.1 ISE with no change. > I've also tried declaring mycount as a SIGNAL and that didn't change > anything either (another question is why I would want mycount to be a > SIGNAL or a VARIABLE, pros and cons but lets stick to the main issue > first) > > In my trial and terror attempt to fix this synth, I can report that if > I comment out either line 48 or 54 the synth works, but I don't > understand why I can't have both lines in and the code be valid. > > I'm guessing my problem is me trying to program with my single cpu, > sequential processing C background in the very non-linear non- > sequential environment that is VHDL, so any insight into this would be > helpful. > > Sincerely, > > Jon
Reply by ●January 5, 20092009-01-05
On Jan 5, 1:26 pm, rickman <gnu...@gmail.com> wrote:> What Nathan said is correct. Specifically what you are doing wrong is > including the comparison "SIGNAL_OUT_TEMP /= SIGNAL_IN" in the IF that > detects the rising edge of the clock. You also have an else condition > that covers the case when the comparison fails, as well as any time > the clock is ***NOT*** at a rising edge. You need to separate the if > for the clock edge from the if for the enabling condition. > > You will do much better as a beginner if you don't treat an HDL as a > programming language, but rather use it to describe hardware. When > you try to "program" in an HDL you often end up with code that is not > even synthesizable as you have done. Don't "program" hardware, > "describe" hardware! > > So first think of the hardware you want to implement and then look up > the HDL constructs that will produce this hardware. Logic is pretty > much logic, but registers take a little practice to get right. You > have to specify the clock correctly and consistently as well as > understanding when a clock enable will be used and when all of the > logic will be rolled into the D input of the D-FF. > > A couple of points about how you are generating SIGNAL_OUT. The > debounce circuit must prevent SIGNAL_OUT from glitching, but it does > not *have* to introduce a delay. Also, your design is retriggerable > so that each time the input changes earlier than the timeout the > counter resets and starts over. Another way to do this is to use a > longer timeout that is assured of being longer than the debounce time > and updating SIGNAL_OUT as soon as the input changes the *first* > time. So the input change is detected and the output follows while > the counter starts. Until the counter reaches the timeout, SIGNAL_OUT > is inhibited from changing again. This prevents the output from > bouncing, but does not introduce the delay that the circuit below will > have. > > Rick > > On Jan 5, 11:20 am, jleslie48 <j...@jonathanleslie.com> wrote: > > > hello all, > > > I'm sure their are different ways to do this, and I would like to > > explore them at a later date, but as I'm still novice at VHDL coding > > I'd like to know what is wrong with this particular code. Its a > > simple debounce process and the synthesize reports an error on line > > 44: > > > ---------------------------------------------------------------------------------- > > -- Company: > > -- Engineer: > > -- > > -- Create Date: 08:06:38 12/31/2008 > > -- Design Name: > > -- Module Name: VhdlModule1 - Behavioral > > -- Project Name: > > -- Target Devices: > > -- Tool versions: > > -- Description: > > -- > > -- Dependencies: > > -- > > -- Revision: > > -- Revision 0.01 - File Created > > -- Additional Comments: > > -- > > ---------------------------------------------------------------------------------- > > library > > IEEE; > > --line 20 > > use IEEE.STD_LOGIC_1164.ALL; > > use IEEE.STD_LOGIC_ARITH.ALL; > > use IEEE.STD_LOGIC_UNSIGNED.ALL; > > > ---- Uncomment the following library declaration if instantiating > > ---- any Xilinx primitives in this code. > > --library UNISIM; > > --use UNISIM.VComponents.all; > > > entity VhdlModule1 > > is > > --line 30 > > port( CLK : in std_logic; > > SIGNAL_IN : in std_logic; > > SIGNAL_OUT : out std_logic); > > end VhdlModule1; > > > architecture Behavioral of VhdlModule1 is > > > constant DEBOUNCE_COUNT : integer := 5; > > signal SIGNAL_OUT_TEMP : std_logic := '0'; > > > begin > > > P1: process (CLK, SIGNAL_IN, > > SIGNAL_OUT_TEMP) -- line 44 > > variable mycount : integer := 0; > > begin > > if (CLK = '1' and CLK'event and SIGNAL_OUT_TEMP /= SIGNAL_IN) then > > mycount := mycount + > > 1; > > -- line 48 > > if (mycount >= DEBOUNCE_COUNT) then > > SIGNAL_OUT_TEMP <= SIGNAL_IN; > > mycount := 0; > > end if; > > else > > mycount := > > 0; > > -- line 54 > > end if; > > SIGNAL_OUT <= SIGNAL_OUT_TEMP; > > end process P1; > > > end Behavioral; > > > ----------------------------------------------------------------------------------------------------------------------------- > > > the error message is this: > > ******************************************* > > Analyzing Entity <VhdlModule1> in library <work> (Architecture > > <Behavioral>). > > > ERROR:Xst:827 - "//dhpc-1/shared/jon/MyVhdl/VhdlModule1.vhd" line 44: > > Signal mycount cannot be synthesized, bad synchronous description. The > > description style you are using to describe a synchronous element > > (register, memory, etc.) is not supported in the current software > > release. > > > ****************************************** > > I've tried this code with both 9.2 and the 10.1 ISE with no change. > > I've also tried declaring mycount as a SIGNAL and that didn't change > > anything either (another question is why I would want mycount to be a > > SIGNAL or a VARIABLE, pros and cons but lets stick to the main issue > > first) > > > In my trial and terror attempt to fix this synth, I can report that if > > I comment out either line 48 or 54 the synth works, but I don't > > understand why I can't have both lines in and the code be valid. > > > I'm guessing my problem is me trying to program with my single cpu, > > sequential processing C background in the very non-linear non- > > sequential environment that is VHDL, so any insight into this would be > > helpful. > > > Sincerely, > > > JonNathan and Rick, Wonderful insight, thank you both. You both hit the nail on the head, by stating: "First, consider what it is you're trying to synthesize in terms of discrete logic parts " "You will do much better as a beginner if you don't treat an HDL as a programming language, but rather use it to describe hardware." I have never dealt with hardware in my entire 25 year career. I have strictly done software programming, and I realize that my interpretations of this very hardware one-to-one mapped environment is wrong. Quite frankly, I don't even know what a D-FF (a "D" flip-flop??) is. My boss just stuck me in the front of the plane because all of the real pilots were sucked out of the cockpit during the explosion. I'm flying blind here. But I want to learn how to do this right, so I'm trying to re-train my brain. Anyway, so here of course is the simple fix to my synth problem (at least I'm not calling it a compile anymore!): P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP) variable mycount : integer := 0; begin if (CLK = '1' and CLK'event ) then --{1 if (SIGNAL_OUT_TEMP /= SIGNAL_IN) then --{2 mycount := mycount + 1; if (mycount >= DEBOUNCE_COUNT) then --{3 SIGNAL_OUT_TEMP <= SIGNAL_IN; mycount := 0; end if; --3} else mycount := 0; end if; --2} end if; --1} SIGNAL_OUT <= SIGNAL_OUT_TEMP; end process P1; Now my process only does something on a RISING edge of the clock pulse, as a clocked process should do. However I cannot "see" my hardware situation in my head. I think that my issue with the bad program is that line 54 would be wrongly firing on every FALLING edge of CLK as well and thus not have me achieve the desired results, but I don't see how the compiler, err, synthesize function, was able to discern my intention. From what you two have said is I must of made a situation where the wiring of the "hardware" was impossible, but I don't see that. I also see that my debounce, will also put a delay of 5 clock pulses after SIGNAL_IN stops bouncing before effecting a change in SIGNAL_OUT_TEMP and then one more clock pulse for the change to effect SIGNAL_OUT. I'm not sure what you are getting out Nathan, other than my original [wrong] code as shown would of never allowed MYCOUNT to get above 1, so SIGNAL_OUT would be forever stuck at SIGNAL_OUT_TEMP's initial state. Rick though, you intrigue me on improving the debounce design. I believe you have pointed out that my debounce functionality will not raise the state of SIGNAL_OUT_TEMP until after 5 CLK rising edges after all bounces. What I think you are getting at is that I should raise the state of SIGNAL_OUT_TEMP immediately on SIGNAL_IN, but then not do anything to SIGNAL_OUT_TEMP until an appropriate amount of Clock pulses after the input stops bouncing, aka assume the state change, but don't bother looking again until the dust settles.
Reply by ●January 5, 20092009-01-05
On Jan 5, 5:53 pm, jleslie48 <j...@jonathanleslie.com> wrote:> On Jan 5, 1:26 pm, rickman <gnu...@gmail.com> wrote: > > > > > What Nathan said is correct. Specifically what you are doing wrong is > > including the comparison "SIGNAL_OUT_TEMP /= SIGNAL_IN" in the IF that > > detects the rising edge of the clock. You also have an else condition > > that covers the case when the comparison fails, as well as any time > > the clock is ***NOT*** at a rising edge. You need to separate the if > > for the clock edge from the if for the enabling condition. > > > You will do much better as a beginner if you don't treat an HDL as a > > programming language, but rather use it to describe hardware. When > > you try to "program" in an HDL you often end up with code that is not > > even synthesizable as you have done. Don't "program" hardware, > > "describe" hardware! > > > So first think of the hardware you want to implement and then look up > > the HDL constructs that will produce this hardware. Logic is pretty > > much logic, but registers take a little practice to get right. You > > have to specify the clock correctly and consistently as well as > > understanding when a clock enable will be used and when all of the > > logic will be rolled into the D input of the D-FF. > > > A couple of points about how you are generating SIGNAL_OUT. The > > debounce circuit must prevent SIGNAL_OUT from glitching, but it does > > not *have* to introduce a delay. Also, your design is retriggerable > > so that each time the input changes earlier than the timeout the > > counter resets and starts over. Another way to do this is to use a > > longer timeout that is assured of being longer than the debounce time > > and updating SIGNAL_OUT as soon as the input changes the *first* > > time. So the input change is detected and the output follows while > > the counter starts. Until the counter reaches the timeout, SIGNAL_OUT > > is inhibited from changing again. This prevents the output from > > bouncing, but does not introduce the delay that the circuit below will > > have. > > > Rick > > > On Jan 5, 11:20 am, jleslie48 <j...@jonathanleslie.com> wrote: > > > > hello all, > > > > I'm sure their are different ways to do this, and I would like to > > > explore them at a later date, but as I'm still novice at VHDL coding > > > I'd like to know what is wrong with this particular code. Its a > > > simple debounce process and the synthesize reports an error on line > > > 44: > > > > ---------------------------------------------------------------------------------- > > > -- Company: > > > -- Engineer: > > > -- > > > -- Create Date: 08:06:38 12/31/2008 > > > -- Design Name: > > > -- Module Name: VhdlModule1 - Behavioral > > > -- Project Name: > > > -- Target Devices: > > > -- Tool versions: > > > -- Description: > > > -- > > > -- Dependencies: > > > -- > > > -- Revision: > > > -- Revision 0.01 - File Created > > > -- Additional Comments: > > > -- > > > ---------------------------------------------------------------------------------- > > > library > > > IEEE; > > > --line 20 > > > use IEEE.STD_LOGIC_1164.ALL; > > > use IEEE.STD_LOGIC_ARITH.ALL; > > > use IEEE.STD_LOGIC_UNSIGNED.ALL; > > > > ---- Uncomment the following library declaration if instantiating > > > ---- any Xilinx primitives in this code. > > > --library UNISIM; > > > --use UNISIM.VComponents.all; > > > > entity VhdlModule1 > > > is > > > --line 30 > > > port( CLK : in std_logic; > > > SIGNAL_IN : in std_logic; > > > SIGNAL_OUT : out std_logic); > > > end VhdlModule1; > > > > architecture Behavioral of VhdlModule1 is > > > > constant DEBOUNCE_COUNT : integer := 5; > > > signal SIGNAL_OUT_TEMP : std_logic := '0'; > > > > begin > > > > P1: process (CLK, SIGNAL_IN, > > > SIGNAL_OUT_TEMP) -- line 44 > > > variable mycount : integer := 0; > > > begin > > > if (CLK = '1' and CLK'event and SIGNAL_OUT_TEMP /= SIGNAL_IN) then > > > mycount := mycount + > > > 1; > > > -- line 48 > > > if (mycount >= DEBOUNCE_COUNT) then > > > SIGNAL_OUT_TEMP <= SIGNAL_IN; > > > mycount := 0; > > > end if; > > > else > > > mycount := > > > 0; > > > -- line 54 > > > end if; > > > SIGNAL_OUT <= SIGNAL_OUT_TEMP; > > > end process P1; > > > > end Behavioral; > > > > ----------------------------------------------------------------------------------------------------------------------------- > > > > the error message is this: > > > ******************************************* > > > Analyzing Entity <VhdlModule1> in library <work> (Architecture > > > <Behavioral>). > > > > ERROR:Xst:827 - "//dhpc-1/shared/jon/MyVhdl/VhdlModule1.vhd" line 44: > > > Signal mycount cannot be synthesized, bad synchronous description. The > > > description style you are using to describe a synchronous element > > > (register, memory, etc.) is not supported in the current software > > > release. > > > > ****************************************** > > > I've tried this code with both 9.2 and the 10.1 ISE with no change. > > > I've also tried declaring mycount as a SIGNAL and that didn't change > > > anything either (another question is why I would want mycount to be a > > > SIGNAL or a VARIABLE, pros and cons but lets stick to the main issue > > > first) > > > > In my trial and terror attempt to fix this synth, I can report that if > > > I comment out either line 48 or 54 the synth works, but I don't > > > understand why I can't have both lines in and the code be valid. > > > > I'm guessing my problem is me trying to program with my single cpu, > > > sequential processing C background in the very non-linear non- > > > sequential environment that is VHDL, so any insight into this would be > > > helpful. > > > > Sincerely, > > > > Jon > > Nathan and Rick, > > Wonderful insight, thank you both. > > You both hit the nail on the head, by stating: > > "First, consider what it is you're trying to synthesize in terms of > discrete logic parts " > > "You will do much better as a beginner if you don't treat an HDL as a > programming language, but rather use it to describe hardware." > > I have never dealt with hardware in my entire 25 year career. I have > strictly done software programming, > and I realize that my interpretations of this very hardware one-to-one > mapped environment is wrong. Quite frankly, > I don't even know what a D-FF (a "D" flip-flop??) is. My boss just > stuck me in the front of the plane because all of the > real pilots were sucked out of the cockpit during the explosion. I'm > flying blind here. > > But I want to learn how to do this right, so I'm trying to re-train my > brain. > > Anyway, so here of course is the simple fix to my synth problem (at > least I'm not calling it a compile anymore!): > > P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP) > variable mycount : integer := 0; > begin > if (CLK = '1' and CLK'event ) then --{1 > if (SIGNAL_OUT_TEMP /= SIGNAL_IN) then --{2 > mycount := mycount + 1; > if (mycount >= DEBOUNCE_COUNT) then --{3 > SIGNAL_OUT_TEMP <= SIGNAL_IN; > mycount := 0; > end if; --3} > else > mycount := 0; > end if; --2} > > end if; --1} > SIGNAL_OUT <= SIGNAL_OUT_TEMP; > end process P1; > > Now my process only does something on a RISING edge of the clock > pulse, as a clocked process should do. > However I cannot "see" my hardware situation in my head. I think that > my issue with the bad program is that > line 54 would be wrongly firing on every FALLING edge of CLK as well > and thus not have me achieve the desired > results, but I don't see how the compiler, err, synthesize function, > was able to discern my intention. From what you > two have said is I must of made a situation where the wiring of the > "hardware" was impossible, but I don't see that. > > I also see that my debounce, will also put a delay of 5 clock pulses > after SIGNAL_IN stops bouncing before effecting > a change in SIGNAL_OUT_TEMP and then one more clock pulse for the > change to effect SIGNAL_OUT. > > I'm not sure what you are getting out Nathan, other than my original > [wrong] code as shown would of never allowed MYCOUNT > to get above 1, so SIGNAL_OUT would be forever stuck at > SIGNAL_OUT_TEMP's initial state. > > Rick though, you intrigue me on improving the debounce design. I > believe you have pointed out that my debounce functionality will not > raise the state of SIGNAL_OUT_TEMP until after 5 CLK rising edges > after all bounces. What I think you are getting at is that I should > raise the state of SIGNAL_OUT_TEMP immediately on SIGNAL_IN, but then > not do anything to SIGNAL_OUT_TEMP until an appropriate amount > of Clock pulses after the input stops bouncing, aka assume the state > change, but don't bother looking again until the dust settles.ok a D flip flop means that whatever its input is its output is delayed to the next rising edge :)))
Reply by ●January 5, 20092009-01-05
On Jan 5, 1:26=A0pm, rickman <gnu...@gmail.com> wrote: [SNIP]> A couple of points about how you are generating SIGNAL_OUT. =A0The > debounce circuit must prevent SIGNAL_OUT from glitching, but it does > not *have* to introduce a delay. =A0Also, your design is retriggerable > so that each time the input changes earlier than the timeout the > counter resets and starts over. =A0Another way to do this is to use a > longer timeout that is assured of being longer than the debounce time > and updating SIGNAL_OUT as soon as the input changes the *first* > time. =A0So the input change is detected and the output follows while > the counter starts. =A0Until the counter reaches the timeout, SIGNAL_OUT > is inhibited from changing again. =A0This prevents the output from > bouncing, but does not introduce the delay that the circuit below will > have. > > RickStrictly speaking to de-glitch the input you do need to add a delay. If you only want to de-bounce the signal you don't. The circuit as described will filter out glitches shorter than DEBOUNCE_COUNT.
Reply by ●January 5, 20092009-01-05
On Jan 5, 5:53=A0pm, jleslie48 <j...@jonathanleslie.com> wrote:> On Jan 5, 1:26 pm, rickman <gnu...@gmail.com> wrote: > > Anyway, so here of course is the simple fix to my synth problem (at > least I'm not calling it a compile anymore!):Heck, I call it compiling. I get tired of saying those big words like synthesize and instantiate, etc. I AM compiling my description of a design into something that the machine understands. At that level, it *is* just like software... some software anyway. I use Forth where I can and that is a whole different thing...> P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP) > variable mycount : integer :=3D 0; > begin > =A0 =A0 =A0 =A0 if (CLK =3D '1' and CLK'event ) then --{1 > =A0 =A0 =A0 =A0 =A0 =A0 =A0if (SIGNAL_OUT_TEMP /=3D SIGNAL_IN) then --{2 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mycount :=3D mycount + 1; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (mycount >=3D DEBOUNCE_COUNT) =then =A0--{3> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0SIGNAL_OUT_TEM=P <=3D SIGNAL_IN;> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mycount :=3D 0=;> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end if; --3} > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mycount :=3D 0; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end if; --2} > > =A0 =A0 =A0 =A0 end if; --1} > =A0 =A0 =A0 =A0 SIGNAL_OUT <=3D SIGNAL_OUT_TEMP; > end process P1;You are using a variable for mycount. I may be showing my ignorance of variables, but it is not clear to me exactly what the comparison will do since it follows the increment.> mycount :=3D mycount + 1; > if (mycount >=3D DEBOUNCE_COUNT) then --{3The difference between a variable and a signal has to do with *when* you look at the value in other statements. In this case mycount will synthesize to a register. It will use an incrementer to do the +1 and will use a comparitor to test for >=3D DEBOUNCE_COUNT. It will also have a reset signal to clear it depending on the count. The signal comparison will be also be part of the logic for the clear. But how exactly will the value of mycount be used in the test with DEBOUNCE_TEMP? You are doing the test after you have incremented it, but by the rules of synthesis, this is not the value that will be latched into the register on the clock edge. That value will depend on the result of the comparison. I am not saying this is a bad design because I am not sure. As much as anything I am showing that I seldom work with variables and I just plain don't know what this will synthesize. If you make mycount a signal, then the input to everything within the process will be the direct output of the register and the resulting circuit will be very clear. The rules of signal synthesis is that the value latched in the register is the last value assigned during the process. All other values are in essence "over written" before the clock edge is done. For a variable, each value assigned is in use until the next value assigned.> Now my process only does something on a RISING edge of the clock > pulse, as a clocked process should do. > However I cannot "see" my hardware situation in my head. =A0I think that > my issue with the bad program is that > line 54 would be wrongly firing on every FALLING edge of CLK as well > and thus not have me achieve the desired > results, but I don't see how the compiler, err, synthesize function, > was able to discern my intention. =A0From what you > two have said is I must of made a situation where the wiring of the > "hardware" was impossible, but I don't see that.The synthesis could not "see" your intent and so it threw up its hands and cried "foul"! BTW, not only was the use of the else clause wrong, but as long as I am criticizing... opps, "giving advice", I'll point out that your sensitivity list is overly populated. P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP) You are using a clock, but no reset so the only thing in the sensitivity list should be the clock. Otherwise in the original post, not only are you telling it to reset the counter on the falling edge of the clock, but on *any* transition of the other signals, one of which is assigned in the process. The sensitivity list of a process is *not* like the parameter list of a subroutine. It tells the tools when the process should be run, not what data is going in and out of it. Think of this as a trigger list for a concurrent process (because that is what it is). Remember that all statements outside of a process (or function) are parallel processes (including the processes themselves). If you are familiar with programming multiple processes this may make a bit more sense.> I also see that my debounce, will also put a delay of 5 clock pulses > after SIGNAL_IN stops bouncing before effecting > a change in SIGNAL_OUT_TEMP and then one more clock pulse for the > change to effect SIGNAL_OUT. > > I'm not sure what you are getting out Nathan, other than my original > [wrong] code as shown would of never allowed MYCOUNT > to get above 1, so SIGNAL_OUT would be forever stuck at > SIGNAL_OUT_TEMP's initial state. > > Rick though, you intrigue me on improving the debounce design. I > believe you have pointed out that my debounce functionality will not > raise the state of SIGNAL_OUT_TEMP until after 5 CLK rising edges > after all bounces. =A0What I think you are getting at is that I should > raise the state of SIGNAL_OUT_TEMP immediately on SIGNAL_IN, but then > not do anything to SIGNAL_OUT_TEMP until an appropriate amount > of Clock pulses after the input stops bouncing, aka assume the state > change, but don't bother looking again until the dust settles.Actually, you stated it better than I did. Yes, that is exactly what I meant. If this were being built out of hardware (in the old style where the hardware is scarce) a double throw switch would be used with a single FF. This circuit would make the FF change state as soon as the leading edge of the signal arrived without delay. There is no reason that your circuit can't do the same thing. As to the D FF, I think the D refers to a DATA input which the output follows when clocked. This is compared to a T FF which toggles each time it is clocked and the T input is high. If the T input is low it does not change state. Others are the RS (typically not clocked) with one set input and one reset input, and the JK which has two inputs along with a clock and can either remember the last state, go low, go high or toggle. You will likely never see any of these monsters. Rick
Reply by ●January 5, 20092009-01-05
On Jan 5, 7:14 pm, rickman <gnu...@gmail.com> wrote:> On Jan 5, 5:53 pm, jleslie48 <j...@jonathanleslie.com> wrote: > > > On Jan 5, 1:26 pm, rickman <gnu...@gmail.com> wrote: > > > Anyway, so here of course is the simple fix to my synth problem (at > > least I'm not calling it a compile anymore!): > > Heck, I call it compiling. I get tired of saying those big words like > synthesize and instantiate, etc. I AM compiling my description of a > design into something that the machine understands. At that level, it > *is* just like software... some software anyway. I use Forth where I > can and that is a whole different thing... > > > > > P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP) > > variable mycount : integer := 0; > > begin > > if (CLK = '1' and CLK'event ) then --{1 > > if (SIGNAL_OUT_TEMP /= SIGNAL_IN) then --{2 > > mycount := mycount + 1; > > if (mycount >= DEBOUNCE_COUNT) then --{3 > > SIGNAL_OUT_TEMP <= SIGNAL_IN; > > mycount := 0; > > end if; --3} > > else > > mycount := 0; > > end if; --2} > > > end if; --1} > > SIGNAL_OUT <= SIGNAL_OUT_TEMP; > > end process P1; > > You are using a variable for mycount. I may be showing my ignorance > of variables, but it is not clear to me exactly what the comparison > will do since it follows the increment.> mycount := mycount + 1; > > if (mycount >= DEBOUNCE_COUNT) then --{3 > > The difference between a variable and a signal has to do with *when* > you look at the value in other statements. In this case mycount will > synthesize to a register. It will use an incrementer to do the +1 and > will use a comparitor to test for >= DEBOUNCE_COUNT. It will also > have a reset signal to clear it depending on the count. The signal > comparison will be also be part of the logic for the clear. But how > exactly will the value of mycount be used in the test with > DEBOUNCE_TEMP? You are doing the test after you have incremented it, > but by the rules of synthesis, this is not the value that will be > latched into the register on the clock edge. That value will depend > on the result of the comparison. > > I am not saying this is a bad design because I am not sure. As much > as anything I am showing that I seldom work with variables and I just > plain don't know what this will synthesize. If you make mycount a > signal, then the input to everything within the process will be the > direct output of the register and the resulting circuit will be very > clear. The rules of signal synthesis is that the value latched in the > register is the last value assigned during the process. All other > values are in essence "over written" before the clock edge is done. > For a variable, each value assigned is in use until the next value > assigned. > > > Now my process only does something on a RISING edge of the clock > > pulse, as a clocked process should do. > > However I cannot "see" my hardware situation in my head. I think that > > my issue with the bad program is that > > line 54 would be wrongly firing on every FALLING edge of CLK as well > > and thus not have me achieve the desired > > results, but I don't see how the compiler, err, synthesize function, > > was able to discern my intention. From what you > > two have said is I must of made a situation where the wiring of the > > "hardware" was impossible, but I don't see that. > > The synthesis could not "see" your intent and so it threw up its hands > and cried "foul"! BTW, not only was the use of the else clause wrong, > but as long as I am criticizing... opps, "giving advice", I'll point > out that your sensitivity list is overly populated. > > P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP) > > You are using a clock, but no reset so the only thing in the > sensitivity list should be the clock. Otherwise in the original post, > not only are you telling it to reset the counter on the falling edge > of the clock, but on *any* transition of the other signals, one of > which is assigned in the process. The sensitivity list of a process > is *not* like the parameter list of a subroutine. It tells the tools > when the process should be run, not what data is going in and out of > it. Think of this as a trigger list for a concurrent process (because > that is what it is). Remember that all statements outside of a > process (or function) are parallel processes (including the processes > themselves). If you are familiar with programming multiple processes > this may make a bit more sense. > > > > > I also see that my debounce, will also put a delay of 5 clock pulses > > after SIGNAL_IN stops bouncing before effecting > > a change in SIGNAL_OUT_TEMP and then one more clock pulse for the > > change to effect SIGNAL_OUT. > > > I'm not sure what you are getting out Nathan, other than my original > > [wrong] code as shown would of never allowed MYCOUNT > > to get above 1, so SIGNAL_OUT would be forever stuck at > > SIGNAL_OUT_TEMP's initial state. > > > Rick though, you intrigue me on improving the debounce design. I > > believe you have pointed out that my debounce functionality will not > > raise the state of SIGNAL_OUT_TEMP until after 5 CLK rising edges > > after all bounces. What I think you are getting at is that I should > > raise the state of SIGNAL_OUT_TEMP immediately on SIGNAL_IN, but then > > not do anything to SIGNAL_OUT_TEMP until an appropriate amount > > of Clock pulses after the input stops bouncing, aka assume the state > > change, but don't bother looking again until the dust settles. > > Actually, you stated it better than I did. Yes, that is exactly what > I meant. If this were being built out of hardware (in the old style > where the hardware is scarce) a double throw switch would be used with > a single FF. This circuit would make the FF change state as soon as > the leading edge of the signal arrived without delay. There is no > reason that your circuit can't do the same thing. > > As to the D FF, I think the D refers to a DATA input which the output > follows when clocked. This is compared to a T FF which toggles each > time it is clocked and the T input is high. If the T input is low it > does not change state. Others are the RS (typically not clocked) with > one set input and one reset input, and the JK which has two inputs > along with a clock and can either remember the last state, go low, go > high or toggle. You will likely never see any of these monsters. > > Rick"as I am criticizing... opps, "giving advice", by all means criticize away. I came here for constructive criticism and all I've heard so far has been great. I'm just stabbing in the dark on my code, so I hardly expect I'm picking the right/best way of doing things. The reason I used 'variable' was simply because that was what I found first in the glossary when I was looking for a place to store an integer value and in C we call them variables. That's the section of the book I read. I didn't know that the more commonly used contruct was a SIGNAL. Now I realize that I've introduced a timing issue where my variable 'mycount' will increment at the same time that I do the DEBOUNCE_COUNT check, and as a result I may (depending on when things within the clock pulse occur) not recognize that I've debounced until an additional clock pulse, viz, mycount might actually reach 6 before it changes SIGNAL_OUT_TEMP (but then it instantly gets reset to 0.)>"The synthesis could not "see" your intent and so it threw up its hands >and cried "foul"!"- here's my issue. I don't see what my foul was. I agree that functionally what I wrote would never work; every falling edge of the clock pulse would reset 'mycount' to 0. but I don't understand why just because it was stupid it wouldn't synthesize. I'm guessing I ended up with two plugs instead of a plug and a socket( like when I wired up my christmas tree), somewhere, but its not obvious to me that my SYNTAX yields to a non-resolvable state. I think this has to do with me not being able to visualize the discrete logic parts. for example in c: x = 0; While (x < 10) { x++; // do something 10 times }//while loop 1 x = 0; While ((x < 10) && (x>20)) { x++; // this will never happen; x can never be <10 and > 20 at the same time }//while loop 2 x = 0; While (x < 10) { x++; // this will happen forever because the line below forces x to always be 5 for the while test. x = 5; }//while loop 3 all thee WHILE loops are syntacticaly correct, the second one just doesn't make any sense, and the third will do a real nice job of sending my program into an infinite loop, I can compile and link the while loops and generate prefectly executable code, it will be an executable time debugging issue for me to recognize my errors in loops 2 and 3. In the case that started this thread, ISE recognized that I did something stupid, well, it recognized I did something that was impossible to resolve even though my syntax was fine. I don't know how it did that.>"I'll point > out that your sensitivity list is overly populated. > > P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP)"ahh, so the sensitivity list should only include elements that define when my "rising edges" of activity should occur, in my case CLK, and in many other cases a RESET event. SIGNAL_IN is an untimed event that needs to be checked WHEN the CLK pulse rises but since by itself it cannot be synched up, it is not necessary in the sensitivity list. Is that it? And continuing, by forcing values to change based on SIGNAL_IN at a rising edge time of CLK, I have made those logic element into a D-FF, eg, the event of mycount incrementing occurs on the rising edge of the clock and not just whenever Signal_in goes high.
Reply by ●January 5, 20092009-01-05
<.... snip>>There are library elements for some devices that support clocking on both edges; for example, DDR I/O. Some tools may not be able to infer such elements, while others may. Typiclly, they would be instantiated. In general, however, most devices won't support the structure; a standard template [if (rising_edge) then ..., or if (signal'event and signal=value)] clues the synthesizer in so it can choose an appropriate library element. Simulation, of course, has no such restrictions. In principal, the synthesizer should be able to build up such a complex structure out of basic gates, but would it be worth the trouble?>>"The synthesis could not "see" your intent and so it threw up its hands >>and cried "foul"!" > > - here's my issue. I don't see what my foul was. I agree that > functionally what I wrote would never work; every > falling edge of the clock pulse would reset 'mycount' to 0. but I > don't understand why just because it was stupid > it wouldn't synthesize. I'm guessing I ended up with two plugs instead > of a plug and a socket( like when I wired up my > christmas tree), somewhere, but its > not obvious to me that my SYNTAX yields to a non-resolvable state. I > think this has to do with me not being able > to visualize the discrete logic parts.> > for example in c: > x = 0; > While (x < 10) { > x++; > // do something 10 times > }//while loop 1 > > x = 0; > While ((x < 10) && (x>20)) { > x++; > // this will never happen; x can never be <10 and > 20 at the same > time > }//while loop 2 > > x = 0; > While (x < 10) { > x++; > // this will happen forever because the line below forces x to > always be 5 for the while test. > x = 5; > }//while loop 3 > > > all thee WHILE loops are syntacticaly correct, the second one just > doesn't make any sense, and the > third will do a real nice job of sending my program into an infinite > loop, I can > compile and link the while loops and generate prefectly executable > code, it will be an executable time debugging > issue for me to recognize my errors in loops 2 and 3. > > In the case that started this thread, ISE recognized that I did > something stupid, well, it recognized I did > something that was impossible to resolve even though my syntax was > fine. I don't know how it did that. > > > >>"I'll point >> out that your sensitivity list is overly populated. >> >> P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP)" > > ahh, so the sensitivity list should only include elements that define > when my "rising edges" of > activity should occur, in my case CLK, and in many other cases a RESET > event. > SIGNAL_IN is an untimed event that needs to be checked WHEN the CLK > pulse rises but since by > itself it cannot be synched up, it is not necessary in the sensitivity > list. Is that it? > > And continuing, by forcing values to change based on SIGNAL_IN at a > rising edge time of CLK, I have made those > logic element into a D-FF, eg, the event of mycount incrementing > occurs on the rising edge of the clock and not > just whenever Signal_in goes high. >JTW
Reply by ●January 5, 20092009-01-05
On Jan 5, 9:12 pm, jleslie48 <j...@jonathanleslie.com> wrote:> On Jan 5, 7:14 pm, rickman <gnu...@gmail.com> wrote: > > "as I am criticizing... opps, "giving advice", > > by all means criticize away. I came here for constructive criticism > and all I've heard > so far has been great. I'm just stabbing in the dark on my code, so I > hardly expect I'm picking > the right/best way of doing things.I was just kidding. It is easy to give advice, harder to give good advice.> The reason I used 'variable' was simply because that was what I found > first in the glossary when > I was looking for a place to store an integer value and in C we call > them variables. That's the section > of the book I read. I didn't know that the more commonly used > contruct was a SIGNAL.That is understandable and there is nothing wrong with variables. You just have to understand how they work and how they will synthesize. The best way to learn to code in an HDL is to look at the template code that the synthesis vendors provide. If you stick with that type of code, you will have a synthesizable design at least.> Now I realize that I've introduced a timing issue where my variable > 'mycount' will increment at the same > time that I do the DEBOUNCE_COUNT check, and as a result I may > (depending on when things within the > clock pulse occur) not recognize that I've debounced until an > additional clock pulse, viz, mycount might actually > reach 6 before it changes SIGNAL_OUT_TEMP (but then it instantly gets > reset to 0.)It's not so much a timing issue as what logic will be generated. The logic will likely work, it will just be a bit more complex than needed.> >"The synthesis could not "see" your intent and so it threw up its hands > >and cried "foul"!" > > - here's my issue. I don't see what my foul was. I agree that > functionally what I wrote would never work; every > falling edge of the clock pulse would reset 'mycount' to 0. but I > don't understand why just because it was stupid > it wouldn't synthesize.It wouldn't synthesize because there is no hardware that will update both on the rising edge and the falling edge. At least there is none that I know of. If there is some circuit that will work that way, it would be so "unique" that the synthesis vendors would not design their programs to support it.> In the case that started this thread, ISE recognized that I did > something stupid, well, it recognized I did > something that was impossible to resolve even though my syntax was > fine. I don't know how it did that.The synthesis recognized that it did not know how to construct logic to implement your design. The simulator would likely have worked just fine. But the code would have done some weird things compared to hardware. In fact, you could say that when running the simulator, and HDL *is* software and when running synthesis, it is *hardware*, or had better be hardware. Your code would run in the simulator (I think) but will update the mycount variable on the rising edge, as well as the falling edge and also any time either of the other two signals change.> >"I'll point > > out that your sensitivity list is overly populated. > > > P1: process (CLK, SIGNAL_IN, SIGNAL_OUT_TEMP)" > > ahh, so the sensitivity list should only include elements that define > when my "rising edges" of > activity should occur, in my case CLK, and in many other cases a RESET > event. > SIGNAL_IN is an untimed event that needs to be checked WHEN the CLK > pulse rises but since by > itself it cannot be synched up, it is not necessary in the sensitivity > list. Is that it?Yes, exactly. If you look at a template for a register you will see exactly this. If it is a combinatorial process, all signals on the right side of any assignments or in condtional part of an if or case needs to be in the list.> And continuing, by forcing values to change based on SIGNAL_IN at a > rising edge time of CLK, I have made those > logic element into a D-FF, eg, the event of mycount incrementing > occurs on the rising edge of the clock and not > just whenever Signal_in goes high.That sounds right. In hardware there is combinatorial logic which is just made up of gates. There is no clock and any time any input changes, the output can change. Sequential logic is the term for registers and latches (slightly different use of the clock) and constitute memory. A register only changes the output when the clock has the appropriate edge (some are rising edge and others falling edge triggered). A latch uses an enable. The input passes through to the output any time the enable is high. When the enable goes low, the current output is remembered. Mostly latches should be avoided. They happen by accident when combinatorial logic is does not specify the output for all possible input combinations. In that case the assumption is that the last output should be held which is exactly what a latch does. This is all well described in pretty much any HDL design book. Rick






