EmbDev.net

Forum: FPGA, VHDL & Verilog vhdl decoder, preventing previous position output duplication


von Christopher (Guest)


Rate this post
useful
not useful
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.

von Christopher (Guest)


Rate this post
useful
not useful
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;

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
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?

von Christopher (Guest)


Rate this post
useful
not useful
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;

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
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...

von Christopher (Guest)


Rate this post
useful
not useful
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.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
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?

von Christopher (Guest)


Rate this post
useful
not useful
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.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
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?

von Christopher (Guest)


Rate this post
useful
not useful
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
No account? Register here.