Hi everyone, I'm encountering an issue that I'm having trouble coding to eliminate, Im using a xilinx cpld, VHDL, and with a 4 bit optical parallel output encoder, at key points using a "when" switch case I have 2 different signal outputs being generated at specific points each, with multiple pulses each, everything is working perfect until at low speeds where the encoder can and does momentarily jiggle backwards turning a signal that was commanded on to off then back on creating havoc on my system. So far I've been able to get all this done without the use of a clock, I'm needing this to work as fast as possible, basically ignoring input from encoder if it's the same as last 2 or 3 inputs as if it's stopped at most recent input and then moving forward, essentially a anti reversal process or encoder one way check valve as my friend puts it lol any suggestions would be greatly appreciated. Thank you.
here is my basic code. ------------------------------------------------------------------------ ---------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_unsigned.all; use IEEE.NUMERIC_STD.ALL; entity decoder is port ( encoder: in bit_vector (3 downto 0); recieve: out bit_vector (3 downto 0); 2out: out bit_vector (1 downto 0); present: in bit := '0' ); end decoder; architecture Behavioral of decoder is signal who: bit_vector (3 downto 0) := "0000"; begin process (encoder, present) begin case encoder is when "1111"=> 2out<="10";who<="1000"; when "1110"=> 2out<="10";who<="1000"; when "1101"=> 2out<="11";who<="1000"; when "1100"=> 2out<="01";who<="1000"; when "1011"=> 2out<="00";who<="0100"; when "1010"=> 2out<="10";who<="0100"; when "1001"=> 2out<="11";who<="0100"; when "1000"=> 2out<="11";who<="0100"; when "0111"=> 2out<="00";who<="0010"; when "0110"=> 2out<="00";who<="0010"; when "0101"=> 2out<="11";who<="0010"; when "0100"=> 2out<="11";who<="0010"; when "0011"=> 2out<="10";who<="0001"; when "0010"=> 2out<="10";who<="0001"; when "0001"=> 2out<="01";who<="0001"; when "0000"=> 2out<="01";who<="0001"; when others => out<="000"; who<="0000"; end case; if present ='1' then case who is when "0001"=> recieve<="0001"; when "0010"=> recieve<="0010"; when "0100"=> recieve<="0100"; when "1000"=> recieve<="1000"; when others => recieve<="0000"; end case; else recieve <="0000"; end if; end process; end Behavioral;
Christopher wrote: > basically ignoring input from encoder if it's the same as last 2 or 3 > inputs Your design is completely combinatorial (it could easily be implemented in an EPROM). And due to the lack of any memory elements there's no "last" or "next". You only have a "now" and some glitches... So: say WHAT you want to achieve with that design. WHERE does the signal cone from? WHAT speed (range) has that signal? WHERE does the result go to? And finally WHAT do you expect and WHAT ELSE do you get?
Sorry for the little info, I'm not at liberty to disclose a lot of info, this is not actually my code but a similar example to what my code is doing, the encoder is actually 13bit parallel and is attached to a gearbox, at specific points during a single rotation there are 3 signals being produced, each very different, I need the cpld due to its speed, and this is vital. So I tried a if statement before the switch case to "prevent" backwards rotating jiggle from propagating unwanted signals, the code snippet is , if encoderin = (encoder-1 or encoder-2 or encoder-3 or encoder+15 or encoder+14 or encoder+13) then encoder<=encoder; Else encoder<= encoderin; end if;
Christopher wrote: > So I tried a if statement before the switch case to "prevent" backwards > rotating jiggle from propagating unwanted signals You didn't get what I meant! You cannot(!) solve your problem with additional whatsoever-statements before whateverelse! The actual problem here is, that you have a PURE combinatoric design and therefore you will always have glitches and spikes at the output. > the encoder is actually 13bit parallel Whats its output? Is it a Gray-code or is it binary?
1 | if encoderin = (encoder-1 or encoder-2 or encoder-3 or encoder+15 or encoder+14 or encoder+13) then |
2 | encoder<=encoder; |
3 | Else
|
4 | encoder<= encoderin; |
5 | end if; |
That latch will NOT work reliable due to glitches and spikes... It will for sure not work with a binary encoder, it will be only slightly better with an Gray encoder. > I need the cpld due to its speed If the design is that secrect, that you even can't supply a figure for that "speed", how should anyone be able to help you? > attached to a gearbox Supposed its a mechanical gearbox, the signals are fairly slow compared to the several 100MHz easily reachable for an CLPD. Just a hint: I would add a "high speed" clock signal (5..10 times the highest encoder data rate) to the design and implement a FSM. That way I would be finished tomorrow...
The gear box reaches speeds of 200rpm to 6000rpm, so far the only glitches I encounter is the shaft jiggle at low rpm, there is a key from the gear box that mates to the encoder that by manufactures design has slop, which I need to work around in code.
Christopher wrote: > so far the only glitches I encounter is the shaft jiggle at low rpm I'n fairly sure you aren't... I was talking about glitches in the nd range. Not that mechanical glitches in the ms range. BTW: there is a bunch of unanswered questions. How should anybody be able to help you, when you don't supply necessary information?
My system is fine, the only real question here is with the addition of a clock, how could I create a function to check the 13 bits of data coming in, store them, check if the bits are equal to the last few positions, if so make no change to the current position sent to the case, if the position bits are new and not equal to the last few, then pass that position to the case. I'll use close to the fastest clock possible without fully maxing it out. I use this system everyday, the only glitch is literally when there is shaft jiggle under 500 rpm.
Christopher wrote: > My system is fine ... > the only glitch is literally when there is shaft jiggle under 500 rpm. Sounds like: "The bomb is stable it explodes only Tuesdays 9:35..." To keep things short: your system is not fine. But due to good luck you see the problem only under 500rpm... > how could I create a function to check the 13 bits of data coming in, > store them, check if the bits are equal to the last few positions, if > so make no change to the current position sent to the case Thats fairly tricky because you have a CPLD with only very few flipflops. And to store each of the "last" positions you will need 13 of them. One idea is to use the LSB as a clock for latching the other 12 bits for further calculation... Up to now theres one BIG question remainig, I ask it a THIRD time: WHAT kind of encoding does your encoder use? The second: what CPLD and how much of it is used?
It is a binary encoder, the cpld is a Xilinx xc9572xl. there is 36/72macrocells in use,156/360 Pterms, 9/72 registers.
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.