one signal set ffrom two processes .....

G

Gerhard

Hi,

newbe needs help.

My problem:
I have a Moor state machine sitting around and waiting.
After a falling edge on a port the state machine needs to start out
working, which take about 96 clock cycles. the work mainly is clocking
data in from a spi interface.
After that the state machine wents sleeping again.

I try to create a signal (later a variable) and set it in a process
which monitors the start signal.
The state machine consists of three processes (synced Moor state
machine) and monitors my start signal (which is like a reset if not
active) and starts out working on the next clock transition.
After finishing the work, I try to reset my start signal, after
entering the neutral state (sleeping), but ..

I always get compiler errors, telling me that the net 'start' is
constantely driven from different places ....

Please tell me, how i should solve such an scenario in VHDL ....

Thinking in 'plain hardware'. I need a FF, which is set by a port
signal and some edge of the clock and is reset by some condition ....

Sounds quite easy in hardware, but seems not so easy to implement in
VHDL for a rouky...

Thanks for helping.

With best regards

gerhard

Here some snippets:

nDRdy_sync:
process
begin
wait until falling_edge(nDRDY);
transfer := '1';
end process;

some other:
process (mySCLK)
begin
...
...
transfer := '0';
end process;
 
B

Brian Drummond

Hi,

newbe needs help.

My problem:
I always get compiler errors, telling me that the net 'start' is
constantely driven from different places ....

That is a very bad design pattern. There are ways to make it work, but
it's unnecessary here.
Please tell me, how i should solve such an scenario in VHDL ....

Drive "start" from one single process.

The state machine can feed a second signal ("started", or "finished")
back to that process to let it know when it is safe to return "start" to
zero.
Thinking in 'plain hardware'. I need a FF, which is set by a port signal
and some edge of the clock and is reset by some condition ....
Here some snippets:

nDRdy_sync:
process
begin
wait until falling_edge(nDRDY);
--transfer := '1';
-- "transfer" should be a signal.
-- A variable local to the process is OK but invisible outside the process
-- A "shared variable" is likely to cause problems and best avoided.
transfer <= '1';
wait until active; -- a signal of type boolean
transfer <= '0';
end process;

some other:
process (mySCLK)
begin
...
...
-- transfer := '0';
active <= true;
...
-- now the state machine has returned to idle
active <= false;
end process;

Incidentally the first of these processes will probably not synthesise
into an FPGA. You would be better off adopting synchronous design using
one internal clock, for example:

nDRdy_sync: process(clk)
variable idle: boolean := true;
begin
if rising_edge(clk) then
if idle then
if nDRDY = '0' then
idle := false;
transfer <= '1';
end if;
else
if active then
transfer <= '0';
idle := true;
end if;
end if;
end if;
end process;

You will also simplify your state machine if you transform the obsolete
three-process style into the equivalent single-process state machine. The
archives of this group cover state machines on a regular basis.

See also
http://www.xilinx.com/itp/xilinx4/data/docs/xst/hdlcode15.html
and some of Mike Treseler's examples on
http://mysite.ncnetwork.net/reszotzl/

- Brian
 
G

Gerhard

That is a very bad design pattern. There are ways to make it work, but
it's unnecessary here.


Drive "start" from one single process.

The state machine can feed a second signal ("started", or "finished")
back to that process to let it know when it is safe to return "start" to
zero.



-- "transfer" should be a signal.
-- A variable local to the process is OK but invisible outside the process
-- A "shared variable" is likely to cause problems and best avoided.
              transfer <= '1';
              wait until active;        -- a signalof type boolean


              active <= true;
              ...
              -- now the state machine has returned to idle
              active <= false;


Incidentally the first of these processes will probably not synthesise
into an FPGA. You would be better off adopting synchronous design using
one internal clock, for example:

nDRdy_sync: process(clk)
variable idle: boolean := true;
begin
   if rising_edge(clk) then
      if idle then
         if nDRDY = '0' then
            idle := false;
            transfer <= '1';
         end if;
      else
         if active then
            transfer <= '0';
            idle := true;
         end if;
      end if;
   end if;
end process;

You will also simplify your state machine if you transform the obsolete
three-process style into the equivalent single-process state machine. The
archives of this group cover state machines on a regular basis.

See alsohttp://www.xilinx.com/itp/xilinx4/data/docs/xst/hdlcode15.html
and some of Mike Treseler's examples onhttp://mysite.ncnetwork.net/reszotzl/

- Brian



???
I get the book VHDL-synthese by Jürgen Reichardt and Bernd Schwarz,
which discuss a three process, two process and one process approach,
so I try the first one, because its more clear for the beginning and
fully synchronized. Speed isn't an issue here.

Ah, I should implement some kind of hand-shaking, one process rise
start and waiting for some reply. The other process generate 'stopped'
after the work is done and the first process clears the start signal.

But, when the state machine enters the idle state and the start signal
is still present .....
ok, my state machine runs through some sequential states so I can drop
the 'stopped' info earlier, but code will be not very clear ...

Strange idea, but syntactically there is a chance of working.

Problem is, that the start signal is async (came from another chip,
running on another clock, no chance to change that) and is only held
active as long as I start reading data via SPI.
So I have to sync and I have to stretch this puls until the state
machine is done or I have to make changes so the state machine doesnt
need a permanent signal for running.

Thanks a lot

With best regards

Gerhard
 
B

Brian Drummond

???
I get the book VHDL-synthese by Jürgen Reichardt and Bernd Schwarz,
which discuss a three process, two process and one process approach, so
I try the first one, because its more clear for the beginning and fully
synchronized. Speed isn't an issue here.

All three will work, and should generate identical hardware. But the
single-process variant is generally easier to get right, and easier to
maintain.
Ah, I should implement some kind of hand-shaking, one process rise start
and waiting for some reply. The other process generate 'stopped' after
the work is done and the first process clears the start signal.

YES, exactly.
But, when the state machine enters the idle state and the start signal
is still present .....

then it would re-trigger. If the start signal is of indeterminate length,
the SM should be designed to wait for start to be retracted before
entering idle. (the "transfer" signal in my example should be maintained
until n_RDY -> '1')
Problem is, that the start signal is async (came from another chip,
running on another clock, no chance to change that) and is only held
active as long as I start reading data via SPI. So I have to sync and I
have to stretch this puls until the state machine is done or I have to
make changes so the state machine doesnt need a permanent signal for
running.

I think you have an understanding of the remaining issues.

- Brian
 
R

rickman

???
I get the book VHDL-synthese by Jürgen Reichardt and Bernd Schwarz,
which discuss a three process, two process and one process approach,
so I try the first one, because its more clear for the beginning and
fully synchronized. Speed isn't an issue here.

Ah, I should implement some kind of hand-shaking, one process rise
start and waiting for some reply. The other process generate 'stopped'
after the work is done and the first process clears the start signal.

But, when the state machine enters the idle state and the start signal
is still present .....
ok, my state machine runs through some sequential states so I can drop
the 'stopped' info earlier, but code will be not very clear ...

Strange idea, but syntactically there is a chance of working.

Problem is, that the start signal is async (came from another chip,
running on another clock, no chance to change that) and is only held
active as long as I start reading data via SPI.
So I have to sync and I have to stretch this puls until the state
machine is done or I have to make changes so the state machine doesnt
need a permanent signal for running.


Can you explain what makes the start signal go away? You mkae it
sound like accessing the SPI port makes it go away which would be
perfect if I understand your problem. But you say that your Finite
State Machine (FSM) reads the SPI port, finishes and the start signal
is still active. So something is not right with my understanding.

If the start signal is asserted and cleared independently of your FSM
then you need to design your machine to detect the assertion, not the
fact that it is asserted. When the FSM gets to the end of its work,
the start signal needs to be cleared before the FSM will trigger
again, in other words, enter a state where you wait for Start to be
false before you enter the state where it waits for Start to be
true.

If the Start signal can be cleared by the FSM, then do that before
entering the state where it waits for the Start signal to be true.

That is pretty simple, no?

I can't say I understand your last part about stretching the Start
signal. It only needs to be true long enough for the FSM to see that
it is asserted. As long as that is two clock cycles, it is guaranteed
to be seen. Then you only need to see it cleared before you return to
the starting state waiting for Start to be true. Have you somehow
written your code so that if Start goes away the FSM resets? That
would be very bad and should be changed.

One other thought, the code you give that seems to be waiting for
nDRDY it treating nDRDY as a clock. Probably not a good idea unless
nDRDY is not guaranteed to be at least two clock cycles long.

Rick
 
L

logic_guy

I looks to me like you need something like this.

Here is a basic single-process state machine with a synchronized start
pulse. Input signal nDRDY is first synchronized to the state machine
clock. When nDRDY makes a 1 -> 0 transition, you will get a 1-clock
cycle pulse on start. This starts the state machine going through its
steps. When done, it goes back to the IDLE state to wait for another
start pulse.

TYPE states is (IDLE, S1, S2, S3, S4);
SIGNAL state : _states;
SIGNAL nDRDY_1, nDRDY_2, start : std_logic;

start <= NOT nDRDY_1 and nDRDY_2;

clk_proc: PROCESS
BEGIN
WAIT until rising_edge(clk);
nDRDY_1 <= nDRDY;
nDRDY_2 <= nDRDY_1;
CASE state is
WHEN IDLE => If start='1'
state <= S1;
end if;
WHEN S1 => -- Do state 1 processing here
-- when done:
state <= S2;
WHEN S2 => -- Do state 2 processing here
-- when done:
state <= S3;
WHEN S3 => -- Do state 3 processing here
-- when done:
state <= S4;
WHEN S4 => -- Do state 4 processing here
-- when done:
state <= IDLE;
-- Add or subtract states as needed
END CASE;
END PROCESS;


Charles Bailey
 
A

Alessandro Basili

TYPE states is (IDLE, S1, S2, S3, S4);
SIGNAL state : _states;
SIGNAL nDRDY_1, nDRDY_2, start : std_logic;

start <= NOT nDRDY_1 and nDRDY_2;

clk_proc: PROCESS
BEGIN
WAIT until rising_edge(clk);
nDRDY_1 <= nDRDY;
nDRDY_2 <= nDRDY_1;
CASE state is
WHEN IDLE => If start='1'
state <= S1;
end if;
WHEN S1 => -- Do state 1 processing here
-- when done:
state <= S2;
WHEN S2 => -- Do state 2 processing here
-- when done:
state <= S3;
WHEN S3 => -- Do state 3 processing here
-- when done:
state <= S4;
WHEN S4 => -- Do state 4 processing here
-- when done:
state <= IDLE;
-- Add or subtract states as needed
END CASE;
END PROCESS;

I would put start in the process to have it clocked. This would avoid
any racing problems between nDRDY_1 and nDRDY_2.
The clause "when others =>" should also be added, to land always on a
"safe" state.
I would also honor the OP choice of naming, being the start the input
signal to this component.

Last comment is on the choice of the structure "WAIT until" which I'm
not very accustomed to and seems to me lacking of the "block" view which
you would get with an "if then end if" syntax.

I extremely appreciated the simplicity of the example and how well it
describes what the hardware should do.

Al
 
A

Alessandro Basili

If the start signal is asserted and cleared independently of your FSM
then you need to design your machine to detect the assertion, not the
fact that it is asserted. When the FSM gets to the end of its work,
the start signal needs to be cleared before the FSM will trigger
again, in other words, enter a state where you wait for Start to be
false before you enter the state where it waits for Start to be
true.

If you "detect the assertion" there's no need to wait anywhere, since
you will need another "assertion".
If the Start signal can be cleared by the FSM, then do that before
entering the state where it waits for the Start signal to be true.

Again if the FSM is designed to "detect the assertion" as you (and I
also would) suggest, there's no need to do anything with it.
I can't say I understand your last part about stretching the Start
signal. It only needs to be true long enough for the FSM to see that
it is asserted. As long as that is two clock cycles, it is guaranteed
to be seen. Then you only need to see it cleared before you return to
the starting state waiting for Start to be true. Have you somehow
written your code so that if Start goes away the FSM resets? That
would be very bad and should be changed.

If the start signal is asynchronous it should be first synchronized.
Once it's synchronized, why the length should be two clock cycles to be
seen?

Why would it be bad if the start signal is used to start and reset the
FSM? I agree the name would be absolutely wrong, since it should be
called "enable".
Certainly the reset should be synchronous.
One other thought, the code you give that seems to be waiting for
nDRDY it treating nDRDY as a clock. Probably not a good idea unless
nDRDY is not guaranteed to be at least two clock cycles long.

I agree is a bad choice to use nDRDY as a clock, but I don't quite
understand the argument of two clock cycles long, since there's no other
clock in the process being nDRDY the only one.
 
L

logic_guy

Alessandro Basili said:
I would put start in the process to have it clocked. This would avoid
any racing problems between nDRDY_1 and nDRDY_2.
It is not necessary to put "start" in the process because it is the AND
of nDRDY_1 and nDRDY_2, which are clocked by "clk", so "start" is
already synchronized with "clk". Also, "start" should not have any
glitches on it the way it is generated in the example. Even if it did,
glitches are no problem in a synchronous system as long as the longest
latch-to-latch path delay is less than the clock period.
The clause "when others =>" should also be added, to land always on a
"safe" state.
An "others" clause is not needed here since "state" is defined with
exactly 5 states, so there are no other states. If you did put an
"others" clause there some tools would give you a warning that the
"others" clause is unreachable.
I would also honor the OP choice of naming, being the start the input
signal to this component.

Last comment is on the choice of the structure "WAIT until" which I'm
not very accustomed to and seems to me lacking of the "block" view
which
you would get with an "if then end if" syntax.
"WAIT until rising_edge(clk);" is a perfectly legitimate way of
specifying the clock of a clocked process and is simpler to code than
the "if then end if" syntax. I work on a team that has been designing
large, multi-million gate ASICs for years and we have 100,000's of lines
of VHDL coded like that.

Charles
 
A

Alessandro Basili

It is not necessary to put "start" in the process because it is the AND
of nDRDY_1 and nDRDY_2, which are clocked by "clk", so "start" is
already synchronized with "clk". Also, "start" should not have any
glitches on it the way it is generated in the example. Even if it did,
glitches are no problem in a synchronous system as long as the longest
latch-to-latch path delay is less than the clock period.

Indeed, my bad!
An "others" clause is not needed here since "state" is defined with
exactly 5 states, so there are no other states. If you did put an
"others" clause there some tools would give you a warning that the
"others" clause is unreachable.

Depending on the encoding (onehot, gray, etc.) the number of FF you are
going to use certainly gives you more than 5 states (32 for onehot, 8
for gray). How the synthesizer is going to know what to do in case your
FF are presenting a state that is not among the 5?
But maybe you care if a bit flip will put your FSM in a state out of
which it cannot get out.
"WAIT until rising_edge(clk);" is a perfectly legitimate way of
specifying the clock of a clocked process and is simpler to code than
the "if then end if" syntax.

I'm not blaming the illegitimacy of the statement, I simply dislike it
as to me it lacks of readability and as well the possibility to include
an asynch reset to the process. If you can post a snippet of a code
including an asynch reset I would appreciate.
 
P

Paul Uiterlinden

Alessandro said:
I'm not blaming the illegitimacy of the statement, I simply dislike it
as to me it lacks of readability

For me readability is the main reason for using and promoting to use "WAIT
UNTIL clk='1'" (or "WAIT UNTIL rising_edge(clk)").

As soon as I see "WAIT UNTIL clk='1'", I know that I need not look further
to see what kind of process it is. It is a pure clocked process without any
asynchronicities.

Another (visual/layout) advantage is the lack of a long stretched if-end-if
statement, which eats up indentation as well.
and as well the possibility to include
an asynch reset to the process. If you can post a snippet of a code
including an asynch reset I would appreciate.

That is not possible with the WAIT statement.
 
L

logic_guy

Paul Uiterlinden said:
For me readability is the main reason for using and promoting to use
"WAIT
UNTIL clk='1'" (or "WAIT UNTIL rising_edge(clk)").

As soon as I see "WAIT UNTIL clk='1'", I know that I need not look
further
to see what kind of process it is. It is a pure clocked process
without any
asynchronicities.

Another (visual/layout) advantage is the lack of a long stretched
if-end-if
statement, which eats up indentation as well.
My sentiments exactly.

Also, regarding asynchronous resets, those should be avoided wherever
possible. The logic team I work with is just finishing an ASIC with
over 900,000 latches. Only a very small handful of those have
asynchronous resets. That was for a case where some logic needed to be
reset when the clock wasn't running.

Charles Bailey
 
K

KJ

Depending on the encoding (onehot, gray, etc.) the number of FF you are
going to use certainly gives you more than 5 states (32 for onehot, 8
for gray). How the synthesizer is going to know what to do in case your
FF are presenting a state that is not among the 5?
But maybe you care if a bit flip will put your FSM in a state out of
which it cannot get out.

The synthesis tool default is not to implement safe state machines
(i.e. ones that return to a particular state if it ever gets into an
'illegal' state).

Unless you play with that synthesis tool setting you will not get
'safe state machines'. In particular, you will not get 'safe state
machines' regardless of how the FSM states are encoded. But don't
take my word for it, try your own state machine with and without an
otherwise unreachable 'when others' clause, and you should see that
you get the same implementation regardless of state bit encoding...or
likely regardless of any other settings other than the tool control
specifically for implementing safe state machines.

As a parting note, the causes for getting into an illegal state are:
- Timing problem
- SEU

In neither of these situations would it be likely that the correct
course of action would be to simply go to some arbitrary reset state.

Kevin Jennings
 
A

Alessandro Basili

The synthesis tool default is not to implement safe state machines
(i.e. ones that return to a particular state if it ever gets into an
'illegal' state).

Indeed I used to turn on the "safe" mode in Synplify to have what I
"wanted".
Unless you play with that synthesis tool setting you will not get
'safe state machines'. In particular, you will not get 'safe state
machines' regardless of how the FSM states are encoded. But don't
take my word for it, try your own state machine with and without an
otherwise unreachable 'when others' clause, and you should see that
you get the same implementation regardless of state bit encoding...or
likely regardless of any other settings other than the tool control
specifically for implementing safe state machines.

And indeed the tool tends to optimize away all the "unnecessary" FF
regardless of the encoding. What I did not know is that in the "safe"
mode the 'when others' clause is not really followed the way it is
written and Synplify will resolve the illegal state to the reset state,
whether it is asynchronous or synchronous:

To force the tool to follow the 'when others' clause it is suggested to
turn off the the FSM compiler. At this point the 'when others' clause
will be exactly followed (provided the "enumerated type" is changed with
constants [why???]).
As a parting note, the causes for getting into an illegal state are:
- Timing problem
- SEU

In neither of these situations would it be likely that the correct
course of action would be to simply go to some arbitrary reset state.

Assuming the design has gone through timing analysis, the SEU is really
a concern that in some applications may get you in troubles. That is why
some communication protocols for space applications (ex. spacewire) can
recover if the FSM fail over the reset state, causing the link on both
sides to an "exchange of silence" procedure that will restore communication.

I do agree that some time a "safe" state maybe safe from the FSM point
of view but system wise doesn't help that much, unless every part of the
design is designed to tolerate it.

Al
 
M

Martin Thompson

Paul Uiterlinden said:
That is not possible with the WAIT statement.

It sort of is... but it's unpleasant in various ways:

process is
begin
-- do_reset things here
wait until reset = '0'; -- wait until reset goes away
main : loop
wait until rising_edge(clk) or falling_edge(reset); exit main when reset = '1';
-- do one set of things
wait until rising_edge(clk) or falling_edge(reset); exit main when reset = '1';
-- do another set of things
-- etc.. repeat long wait until line as many times as necessary
end loop;
end process;

Also on "inferred state machines":

http://parallelpoints.com/node/69

(apologies to Chrome users, the code wraps rather than providing scroll-bars
like in Firefox. I haven't figured out why yet)

Cheers,
Martin
 
A

Alessandro Basili

On 7/11/2011 12:07 PM, Martin Thompson wrote:
[...]
process is
begin
-- do_reset things here
wait until reset = '0'; -- wait until reset goes away
main : loop
wait until rising_edge(clk) or falling_edge(reset); exit main when reset = '1';
-- do one set of things
wait until rising_edge(clk) or falling_edge(reset); exit main when reset = '1';
-- do another set of things
-- etc.. repeat long wait until line as many times as necessary
end loop;
end process;

Isn't the "exit main when reset = '1'" a synchronous reset? The way I
read is the following:

- wait until rising_edge(clk) and then
- if reset = '1' exit the main loop.

Am I wrong (*)?
Also on "inferred state machines":

http://parallelpoints.com/node/69

very interesting approach. And I do share the same view when you say:
it saves you having to think of names for your states

since IMHO what is more critical is the condition under which an FSM
moves from one state to the other, rather than the state itself.
The suggestion to move at a higher level of description and leave the
synthesizer infer whatever is needed to perform the functionality
described is the right way of exploiting the language. Too many times we
loose ourselves amongst gates and flops forgetting the big picture.

Two comments though:

- giving the impression that "less code is usually good" is a
misconception (as Nemo's father would say about clownfish). Being on the
defense line "the smaller the better" usually drives designers to write
unreadable and therefore unmaintainable code.

- comparing vhdl with C# in terms of lines of code is risky. Hardware
acceleration is nothing related to the lines of code and its main goal
is to search for tasks in the sequential (and/or multi-threaded)
computing that can be performed in parallel by an external device (or
additional dedicated CPU) in the hope of being more efficient (number of
computations/cycle). Nothing related to lines of code.
(apologies to Chrome users, the code wraps rather than providing scroll-bars
like in Firefox. I haven't figured out why yet)

Didn't work for me as well, but found the following:

http://code.google.com/p/chromium/issues/detail?id=10533

even though they claim they fixed this problem...

(*) my apologies I cannot try it out myself...reinstalling my pc! :-(
 
M

Martin Thompson

Alessandro Basili said:
On 7/11/2011 12:07 PM, Martin Thompson wrote:
[...]
process is
begin
-- do_reset things here
wait until reset = '0'; -- wait until reset goes away
main : loop
wait until rising_edge(clk) or falling_edge(reset); exit main when reset = '1';
-- do one set of things
wait until rising_edge(clk) or falling_edge(reset); exit main when reset = '1';
-- do another set of things
-- etc.. repeat long wait until line as many times as necessary
end loop;
end process;

Isn't the "exit main when reset = '1'" a synchronous reset? The way I
read is the following:

- wait until rising_edge(clk) and then

wait until rising_edge(clk) or falling_edge(reset)
^^^^^^^^^^^^^^^^^^^^^^
- if reset = '1' exit the main loop.

Am I wrong (*)?

reset is also "in the sensitivity list" of the wait statement.
very interesting approach. And I do share the same view when you say:


since IMHO what is more critical is the condition under which an FSM
moves from one state to the other, rather than the state itself.
The suggestion to move at a higher level of description and leave the
synthesizer infer whatever is needed to perform the functionality
described is the right way of exploiting the language. Too many times we
loose ourselves amongst gates and flops forgetting the big picture.

Two comments though:

- giving the impression that "less code is usually good" is a
misconception (as Nemo's father would say about clownfish). Being on the
defense line "the smaller the better" usually drives designers to write
unreadable and therefore unmaintainable code.

Yes, it always needs some common-sense applying. But note that I didn't
say "smaller is better".

"Less code is *usually* good". A much weaker assertion :)
- comparing vhdl with C# in terms of lines of code is risky.

Oh, yes of course - it's not meant to be much more than a
pseudo-academic "playing with possibilities". My original motivation
was simply in response to the originally presented HDL solution to show
that the VHDL *could* look much like the C# approach. (Bar the
horrible-ness of the clocking construct).

But I also feel that "lines of code" is not a metric to be completely
discarded.
Hardware acceleration is nothing related to the lines of code and its
main goal is to search for tasks in the sequential (and/or
multi-threaded) computing that can be performed in parallel by an
external device (or additional dedicated CPU) in the hope of being
more efficient (number of computations/cycle). Nothing related to
lines of code.

No, but if you can (readably!) do the same thing in many less lines of
code, that's a win, surely? LOC matters not to the machine, but it is
still a significant metric to the programmer/designer, and even more so
to the reviewers of said code.

Cheers,
Martin
(all his own opinions)
 
A

Alessandro Basili

Alessandro Basili said:
On 7/11/2011 12:07 PM, Martin Thompson wrote:
[...]
process is
begin
-- do_reset things here
wait until reset = '0'; -- wait until reset goes away
main : loop
wait until rising_edge(clk) or falling_edge(reset); exit main when reset = '1';
-- do one set of things
wait until rising_edge(clk) or falling_edge(reset); exit main when reset = '1';
-- do another set of things
-- etc.. repeat long wait until line as many times as necessary
end loop;
end process;

Isn't the "exit main when reset = '1'" a synchronous reset? The way I
read is the following:

- wait until rising_edge(clk) and then

wait until rising_edge(clk) or falling_edge(reset)
^^^^^^^^^^^^^^^^^^^^^^

I was much too distracted by the "exit main when reset = '1';" that I
totally miss that! Uhm, talking about readability I do admit the reader
sometimes has his/her own responsability :)
My apologies.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top