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?
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?