johnson ring counter and how to simulate it

A

Amit

Hello group,

I have a question and will appreciate it if you give me some insight
into it. Assume one of the entities of a circuit is key debouncer
which its output goes to a johnson ring counter as clock.

My question is that can I embed or include the Johnson Ring-Counter as
part of the debouncer enetity? I believe I must done using an IF
statement but still not quite sure how.

Thanks in advance.
Amit
 
A

Amit

Hello group,

I have a question and will appreciate it if you give me some insight
into it. Assume one of the entities of a circuit is key debouncer
which its output goes to a johnson ring counter as clock.

My question is that can I embed or include the Johnson Ring-Counter as
part of the debouncer enetity? I believe I must done using an IF
statement but still not quite sure how.

Thanks in advance.
Amit


It seems I had missed the most important part of it. What I was trying
to say is that can I implement it as a PROCESS in the architecture of
the debouncer?

Thanks,
Amit
 
J

Jonathan Bromley

Yuck! Why are you not using the key-debounce output as a
clock enable?

Of course. You can decompose your overall design into multiple
entities, or keep it all within one huge entity/architecture,
in any way you choose.

Meaningless question. IF is just a procedural statement that may
appear as part of a PROCESS. Maybe you'll use an IF statement,
maybe not.
It seems I had missed the most important part of it. What I was trying
to say is that can I implement it as a PROCESS in the architecture of
the debouncer?

See above: YES.

HOWEVER.....

A key debouncer is a very well defined, distinct piece of
functionality. It's not obvious that you want to mess it
around by including some other, application-specific
functionality in the same module. It's your choice, of
course, but it wants some thought.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
A

Amit

Yuck! Why are you not using the key-debounce output as a
clock enable?


Of course. You can decompose your overall design into multiple
entities, or keep it all within one huge entity/architecture,
in any way you choose.


Meaningless question. IF is just a procedural statement that may
appear as part of a PROCESS. Maybe you'll use an IF statement,
maybe not.


See above: YES.

HOWEVER.....

A key debouncer is a very well defined, distinct piece of
functionality. It's not obvious that you want to mess it
around by including some other, application-specific
functionality in the same module. It's your choice, of
course, but it wants some thought.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.


Hello Doulos,

This is a given problem I'm still learning VHDL so not sure why but
would you please tell me why you didn't like clocking a ring-counter
by debouncer? and what is the better approach to this?

As you know better, the debouncer will make sure that it is sending a
chaing of 0s or 1s which in this case it either sends "0000000000" or
"1111111111" otherwise there would be no output from it.

I'm new to this field and would love to know if there is a better
approach.

Thanks,
Amit
 
J

Jonathan Bromley

Hello Doulos,

Wrong - it's "hello Jonathan". I post on my own behalf.
Corporate disclaimer is partly so that there can be no
suggestion that I'm concealing anything, and partly because
(quite properly) my employers insist I include it.
This is a given problem I'm still learning VHDL so not sure why but
would you please tell me why you didn't like clocking a ring-counter
by debouncer? and what is the better approach to this?

In any normal modern FPGA or ASIC technology, you should always
try to use exactly one clock signal for all the flip-flops in a
design - or, at least, in any large block of a design. This
approach is known as "synchronous design" and it has many
important benefits, which you can easily find for yourself
by looking at a modern digital design text, or back through the
archives of this group or comp.arch.fpga.

There are some exceptions, of course.

For very low power designs, it is useful to be able to switch
off or slow the clock to blocks of the design. This is known
as "clock gating" and it needs special care.

For communications, multimedia and some other applications,
it is possible that part of the design is forced to use a
standardised clock speed that is different from other clocks
in your system. For example, you may have a 270MHz clock
derived from an incoming D1 digital video stream, but
perhaps you also need a locally generated 133MHz
clock for your CPU and memory subsystem. To get the data
from one zone of clocking ("clock domain") to another
requires special care and special techniques - Google for
"clock domain crossing" to find more.
As you know better, the debouncer will make sure that it is sending a
chaing of 0s or 1s which in this case it either sends "0000000000" or
"1111111111" otherwise there would be no output from it.

Yes. But if the debouncer has an output "keypress", which goes true
for exactly one clock period, you can then use that keypress signal
as a clock-enable for other logic that has THE SAME CLOCK as the
debouncer. Therefore, all flip-flops have just one clock.

This is extremely easy to implement in VHDL. The following is
only a sketch - you will need to fill in various declarations
of signals, ports, etc. to complete it - I don't want to do
all your homework for you.

-- Number of clocks for which the keypress must be stable
constant debounce_cycles: integer := 10;

debouncer: process (clock)
variable resynch: std_logic;
variable previous_key: std_logic;
variable debounce_count: integer range 0 to debounce_cycles;
begin
if rising_edge(clock) then
-- Has the key_input state changed?
if previous_key /= resynch then
-- Yes, it changed. Reset the timeout.
debounce_count := debounce_cycles;
else
-- Key is stable. Has it been stable for long enough?
if debounce_count /= 0 then
-- Not yet. Continue counting.
debounce_count := debounce_count - 1;
else
-- Yes, it is stable. Update the output signal.
debounced_key <= resynch;
end if;
end if;
-- update the state
previous_key := resynch;
resynch := key_input;
end if; -- rising_edge
end process;

OK, so now we have a signal "debounced_key" that is a
stabilized version of the bouncy "key_input". Now let's
find when it was pushed, by edge-detecting it SYNCHRONOUSLY:

edge_detector: process (clock)
variable old: std_logic;
begin
if rising_edge(clock) then
if debounced_key = '1' and old = '0' then
-- Stable form of key made a 0->1 transition
keypress <= '1';
else
keypress <= '0';
end if;
old := debounced_key;
end if; -- rising_edge
end process;

Finally we can use the "keypress" signal to enable other
clocked logic, so that it operates only once per keypress
even though the clock is ticking much faster:

some_counter: process(clock)
begin
if rising_edge(clock) then
if synch_reset = '1' then
-- Unconditionally reset the counter
johnson_counter <= (others => '0');
elsif keypress = '1' then
-- We detected a keypress on this cycle, so
-- we should do something interesting
johnson_counter <=
(not johnson_counter(0)) &
johnson_counter(N-1 downto 1);
else
-- No keypress, so do nothing
null;
end if;
end if; -- rising_edge
end process;

You'll note that this design is fully synchronous. EVERY
flip-flop is clocked by the SAME clock, which can be as fast
as you like - don't forget, of course, that if the clock is
very fast then your debounce_cycles value will need to be
correspondingly large.

Ho hum, looks like I did the homework after all.
But it sounds as though it's not the solution the prof
wanted, so that's OK then :)

For extra credit, find how to get the Johnson counter
to count out of illegal states automatically (mine
doesn't).

For more extra credit, discuss
(a) why do I need the "resynch_key" variable at all -
why can't I just use the key_input signal directly?
(b) is it sufficient to have just one "resynch_key"
variable, or do I need two or more?
(c) what the blazes are you doing with a Johnson counter
anyhow?
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
A

Amit

Wrong - it's "hello Jonathan". I post on my own behalf.
Corporate disclaimer is partly so that there can be no
suggestion that I'm concealing anything, and partly because
(quite properly) my employers insist I include it.


In any normal modern FPGA or ASIC technology, you should always
try to use exactly one clock signal for all the flip-flops in a
design - or, at least, in any large block of a design. This
approach is known as "synchronous design" and it has many
important benefits, which you can easily find for yourself
by looking at a modern digital design text, or back through the
archives of this group or comp.arch.fpga.

There are some exceptions, of course.

For very low power designs, it is useful to be able to switch
off or slow the clock to blocks of the design. This is known
as "clock gating" and it needs special care.

For communications, multimedia and some other applications,
it is possible that part of the design is forced to use a
standardised clock speed that is different from other clocks
in your system. For example, you may have a 270MHz clock
derived from an incoming D1 digital video stream, but
perhaps you also need a locally generated 133MHz
clock for your CPU and memory subsystem. To get the data
from one zone of clocking ("clock domain") to another
requires special care and special techniques - Google for
"clock domain crossing" to find more.


Yes. But if the debouncer has an output "keypress", which goes true
for exactly one clock period, you can then use that keypress signal
as a clock-enable for other logic that has THE SAME CLOCK as the
debouncer. Therefore, all flip-flops have just one clock.

This is extremely easy to implement in VHDL. The following is
only a sketch - you will need to fill in various declarations
of signals, ports, etc. to complete it - I don't want to do
all your homework for you.

-- Number of clocks for which the keypress must be stable
constant debounce_cycles: integer := 10;

debouncer: process (clock)
variable resynch: std_logic;
variable previous_key: std_logic;
variable debounce_count: integer range 0 to debounce_cycles;
begin
if rising_edge(clock) then
-- Has the key_input state changed?
if previous_key /= resynch then
-- Yes, it changed. Reset the timeout.
debounce_count := debounce_cycles;
else
-- Key is stable. Has it been stable for long enough?
if debounce_count /= 0 then
-- Not yet. Continue counting.
debounce_count := debounce_count - 1;
else
-- Yes, it is stable. Update the output signal.
debounced_key <= resynch;
end if;
end if;
-- update the state
previous_key := resynch;
resynch := key_input;
end if; -- rising_edge
end process;

OK, so now we have a signal "debounced_key" that is a
stabilized version of the bouncy "key_input". Now let's
find when it was pushed, by edge-detecting it SYNCHRONOUSLY:

edge_detector: process (clock)
variable old: std_logic;
begin
if rising_edge(clock) then
if debounced_key = '1' and old = '0' then
-- Stable form of key made a 0->1 transition
keypress <= '1';
else
keypress <= '0';
end if;
old := debounced_key;
end if; -- rising_edge
end process;

Finally we can use the "keypress" signal to enable other
clocked logic, so that it operates only once per keypress
even though the clock is ticking much faster:

some_counter: process(clock)
begin
if rising_edge(clock) then
if synch_reset = '1' then
-- Unconditionally reset the counter
johnson_counter <= (others => '0');
elsif keypress = '1' then
-- We detected a keypress on this cycle, so
-- we should do something interesting
johnson_counter <=
(not johnson_counter(0)) &
johnson_counter(N-1 downto 1);
else
-- No keypress, so do nothing
null;
end if;
end if; -- rising_edge
end process;

You'll note that this design is fully synchronous. EVERY
flip-flop is clocked by the SAME clock, which can be as fast
as you like - don't forget, of course, that if the clock is
very fast then your debounce_cycles value will need to be
correspondingly large.

Ho hum, looks like I did the homework after all.
But it sounds as though it's not the solution the prof
wanted, so that's OK then :)

For extra credit, find how to get the Johnson counter
to count out of illegal states automatically (mine
doesn't).

For more extra credit, discuss
(a) why do I need the "resynch_key" variable at all -
why can't I just use the key_input signal directly?
(b) is it sufficient to have just one "resynch_key"
variable, or do I need two or more?
(c) what the blazes are you doing with a Johnson counter
anyhow?
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.




Hello Jonathan,

Thank you so much for your response!!! I will write my own version.
First, it will give me a self-confedance and better for my future
since I don't want to pass it only but learn it. However, you gave me
a view of how I should the coding but meantime several questions
popuped in my head. After more study I will get back to you. Once
again thanks for sharing your knowledge and learning me this.

Regards,
Amit
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,241
Latest member
Lisa1997

Latest Threads

Top