EmbDev.net

Forum: FPGA, VHDL & Verilog Index Input for Encoder Interface


von SparkyT (Guest)


Rate this post
useful
not useful
Hi,

based on the example bellow

http://www.lothar-miller.de/s9y/categories/46-Encoder

i need to use the INDEX input of the encoder, sometimes.
From what i understand, when needed, the INDEX pulse should clear the 
position counter. Is it as simple as this?

double register INDEX input
1
dr_INDEX <= dr_INDEX(0) & INDEX    when rising_edge(CLK);

Have an Enable input, and
1
        -- index allow to clear count
2
        if ENA then
3
            if dr_INDEX = "01" then
4
                p <= 0;
5
            end if;
6
        end if;

T

von Lothar M. (lkmiller) (Moderator)


Rate this post
useful
not useful
SparkyT wrote:
> Is it as simple as this?
You're on the right way...

I would also check wether the counter value is (nearby) 0 at that point. 
Because when not, then you have lost counts in the previous round. That 
may be a reason to raise an ERROR flag.

: Edited by Moderator
von SparkyT (Guest)


Rate this post
useful
not useful
Thanks for reply.

A bit more education required. :)

Nearby zero(0) means what exactly? I am getting confused with the signed 
integer.
1
-- 32-bit signed integer range: -2147483647 to +2147483647
2
ENC_POS <= std_logic_vector(to_signed(p,32));

check when p is nearby 0? (p > X or p < -X, where X is 10? 100? 1000?)
check at the edges? (-2147483647 to +2147483647)

i was thinking like
1
        -- index allow to clear count
2
        -- 32-bit signed integer range: -2147483647 to +2147483647
3
        if ENA then
4
            if dr_INDEX = "01" then
5
                if p > 1000 or p < -1000 then
6
                    EQEP_ERR <= '1';
7
                    p <= 0;
8
                else
9
                    EQEP_ERR <= '0';
10
                    p <= 0;     
11
                end if;
12
            end if;
13
        end if;

T

von Lothar M. (lkmiller) (Moderator)


Rate this post
useful
not useful
SparkyT wrote:
> Nearby zero(0) means what exactly?
That depends on what you would allow for an deviation. Usually it must 
be 0.

> check at the edges? (-2147483647 to +2147483647)
You will not be able to buy an encoder with somewhat 500000000 lines per 
revolution. So you will never ever reach the limit of an integer number.

> check when p is nearby 0? (p > X or p < -X, where X is 10? 100? 1000?)
Because my code does a quadruple evaluation all of the 4 edges in one 
"step" are counted. Usually the index pulse is 1 step wide, so at either 
"end" of the index pulse the counters value is up to 3 or down to -3.
So I would raise the error flag when the counter >3 or <-3 at the 
"begin" (=rising edge) of the index pulse.


1
        if ENA then
2
            if dr_INDEX = "01" then
3
                p <= 0;
4
                EQEP_ERR <= '0';
5
                if p>3 or p<-3 then
6
                    EQEP_ERR <= '1';
7
                end if;
8
            end if;
9
        end if;

: Edited by Moderator
von SparkyT (Guest)


Rate this post
useful
not useful
Thanks for the explanation. I ll just use a counter to catch the error 
ticks.

T

von SparkyT (Guest)


Attached files:

Rate this post
useful
not useful
FYI

von SparkyT (Guest)


Attached files:

Rate this post
useful
not useful
Hi,
i come close to to use the encoder description, along with the error 
detection.
Am running some simulations for building confidence and noticed that,
I get eqer_err active when evaluating everything on the risedge of 
Index. see eqep_err image attached.

But if i clear the position count on the risedge of Index, and do the 
checks on the falledge of Index, then it looks ok. see attached image 
epeq_no_err
1
if ENA_I then
2
   if dr_I = "01" then
3
      pos_cnt <= 0;
4
   end if;
5
   if dr_I = "10" then
6
      if pos_cnt>3 or pos_cnt<-3 then
7
         err <= '1';
8
      else
9
         err <= '0';
10
      end if;
11
   end if;
12
end if;


What do you think?

von Lothar M. (lkmiller) (Moderator)


Rate this post
useful
not useful
SparkyT wrote:
> But if i clear the position count on the risedge of Index, and do the
> checks on the falledge of Index, then it looks ok.
Sounds very like the traditional latency error. Just dig inside your 
module and have a look for the pos_cnt that causes the error. Look at 
the dr_I at the same time...

> What do you think?
The problem is located outside the posted piece of code.

von SparkyT (Guest)


Attached files:

Rate this post
useful
not useful
Thanks for the reply.

Am attaching the file in use. It should look very, very familiar.. 
except the async reset.

Am also attaching a more detailed simulation (pre-synth). I guess the 
err is triggered because value 37(in this specific sim) is used for the 
check(?)

On another note, i fail to understand how clearing the pos_cnt and 
checking it on the same edge of the index will produce an error (even 
though the attached sim actually does..). the value of the pos_cnt while 
checking it, should be zero, right?

von Lothar M. (lkmiller) (Moderator)


Rate this post
useful
not useful
SparkyT wrote:
> I guess the err is triggered because value 37(in this specific sim) is
> used for the check(?)
No, its triggered because 25 in pos_cnt is more than 3 in this line:
1
if pos_cnt>3 or pos_cnt<-3 then
2
    err <= '1';


> i fail to understand how clearing the pos_cnt and checking it on the
> same edge of the index
As I said: latency.
You must dig in much deeper in the behaviour of signals in processes!
To say it simple: they do not change their value throughout the process. 
They keep their "start values" from the beginning of the process to the 
end of the process.
When you assign a new value to a signal them the signal does not change 
its value! The new value is just "memorized" until the end of the 
process. Then it is assigned to the signal.

So in your specific "problem" it looks like that:
1
if ENA_I then          -- Sim: ENA_I is 1
2
  if dr_I = "01" then  -- Sim: dr_I is 01
3
    pos_cnt <= 0;      -- kind of magic here: pos_cnt does not change its value as it is a signal!
4
                       -- the assinged value is not updated till the end of the process!  
5
      err <= '0';
6
      if pos_cnt>3 or pos_cnt<-3 then -- Sim: pos_cnt is still 25 here and throughout the whole process!
7
         err <= '1';  -- obviously we will end up here... :-(

This kind of behaviour is really nice, when you are used to it. But 
first you must "get the trick" somehow...  ;-)

: Edited by Moderator
von SparkyT (Guest)


Rate this post
useful
not useful
Hi,

thanks for the explanation. Just love fpga magic.

And in the sim above, 37 dec = 25 hex.

Thanks

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig