EmbDev.net

Forum: FPGA, VHDL & Verilog VHDL : signal goes to zero when looping on a state


von Ed H. (hachhac)


Attached files:

Rate this post
useful
not useful
First of all, sorry for my bad English!

I am new to vhdl (and embdev) , so I will try to clearly explain my 
problem (which must come from a problem of comprehension of how a state 
machine )

Context : I need to read a ROM, i read data, and after a certain number 
of data read ( I know that number) i'll get a data wich is a delay. At 
this moment , I want to stay at this state as many clocks as the delay, 
before reading on. (And this will loop again ).

You can find quick drawing to explain the process in file joined.


So my problem is about a (intern) signal, the delay !

It takes the good value a the first time, and then goes to zero, but 
rom_out is still good so i really do not understand what i'm doing wrong 
!

I do not have the code on my computer today so i will try to quickly 
rewrite you some code :
1
signal delay                  : unsigned (7 downto 0);
2
3
begin
4
process(clk, rst)
5
begin
6
7
if(rst = '1') then
8
    curr_state <= start;
9
    rom_counter <= (others => '0');
10
    delay <= (others => '0');
11
    flag <= (others => '0');
12
13
elsif(clk'event and clk = '1') then
14
    rom_counter<=next_rom_counter;
15
    flag<=next_flag;
16
end if;
17
end process;

and i have my other process wich is only my state machine
1
|
2
|
3
|
4
when S8=>
5
next_rom_counter<=rom_counter+1;
6
flag<="0....0";
7
rom_address<=std_logic_vector(rom_counter);
8
delay<=Rom_out;
9
next_state<=S9;
10
11
12
when S9=>
13
if flag=delay then
14
next_state<=S10;
15
else next_state<=S9;
16
end if;

The problem:

In my simulation, everything is fine, i enter S9 with the good delay 
value, flag at 0, so, the next_state is S9 a second time but delay goes 
from the good value to 0 !

And i don't understand why ? Could you help me please.

What i have tried :

-put everything in the same state (the same problem happened)

-don't use a signal intern and directly compared flag to rom_out : not 
working

Thank you for the help !

HacHac.

von Achim S. (Guest)


Rate this post
useful
not useful
in one process you have the assignment

> flag<="0....0";

in another process you have the assignement

> flag<=next_flag;

I cannot believe that this works without complaints from your synthesis 
tool. Please show your real code, not just code-fragments which "look 
similar" to your real code.

Ed H. wrote:
> the next_state is S9 a second time but delay goes
> from the good value to 0 !

Your second process is not using a Clock, correct? Then you store delay 
in a latch, not in a flipflop. That is typically a bad idea. Use a 
flipflop if you want to keep information in an FPGA.

von Ed H. (hachhac)


Rate this post
useful
not useful
Hello !

First of all, thank you for your answer ! I'll post the entire code with 
my simulation by monday (when i will have access to my code).

So if i understand well, it's not possible to make two assigment of the 
same signal in two different process !
So in my second process, to re-initialize the flag value, i need to 
write
1
next_flag<="0..0"

instead of
1
flag<="0..0"


I'll post the code as soon as possible, but i think i have made lots of 
mistakes with latches .... because all my previous states are in the 
same kind :
1
when Si=>
2
  next_rom_counter<=rom_counter+1;
3
  rom_adress<=rom_counter;
4
  data_wanted<=rom_out;
5
  next_state<=s(i+1);

where data_wanted is a signal unsigned. So i can't do this kind of 
assigment for data_wanted because my value will be stored in a latch ? 
But why when i simulate, it keep the value i want, so i thought it was 
good but i'm wrong ?

And why it keep the value for those signal and not the delay (it will be 
difficult to answer whitout the code, i guess)


Thank you for the help !

: Edited by User
von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Ed H. wrote:
> So if i understand well, it's not possible to make two assigment of the
> same signal in two different process !
You will get a error about "multiple drivers" when you try that in real 
hardware...


> but i think i have made lots of mistakes with latches ....
My assumption is: your major problem is the 2-process FSM (one 
combinatorial process and one clocked process).
Why not trying the 1-process FSM?

Try this with Google translator:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html

: Edited by Moderator
von Achim S. (Guest)


Rate this post
useful
not useful
Ed H. wrote:
> So if i understand well, it's not possible to make two assigment of the
> same signal in two different process !

Correct: how should the hardware know, which of both is the valid 
assignment at any given point in time? Maybe in simulation the problem 
does not show up, as in simulation the processes are only executed, 
which may avoid the conflict of different drivers. But in hardware both 
drivers for the same signal would be conflicting permanently with each 
other. So if you try to implement in hardware you must get error 
messages.

Ed H. wrote:
> So i can't do this kind of
> assigment for data_wanted because my value will be stored in a latch ?

You can do: it is not impossible to store data in latches. But it is bad 
style, if gives (serious) warnings and can make severe problems, which 
are sometimes hard to identify and to understand in detail. So just 
don't do it. Store the signals in flip-flops: that's the right place.

If you still have problems with the value of "delay" in a flip-flop, 
then one can look deeper in your code and try to understand, where the 
zero is coming from.

As Lothar wrote: the two-process coding style can very quickly lead to 
latches (and to combinatorial loops). This two process style may be good 
for teaching and to understand, that the FSM has a combinatorial logic 
(described in one process) and a storage flip-flop (described in the 
other process). But once you understood this anyhow and you start to 
generate real code for real world problems, the one process coding style 
of the FSM is much more compact (no need to define every signal twice 
like "flag" and "new_flag") and you avoid all the problems of unintended 
latches and combinatorial loops.

von Achim S. (Guest)


Rate this post
useful
not useful
Ups, sorry: this sentence makes no sense.

Achim S. wrote:
> Maybe in simulation the problem
> does not show up, as in simulation the processes are only executed,
> which may avoid the conflict of different drivers.

It should mean:

Maybe in Simulation the problem does nicht show up, as in simulation the 
processes are only executed according to their sensitivity list.....

von Ed H. (hachhac)


Rate this post
useful
not useful
Thank you both of you for your answers  ! It really helps me to 
understand how vhdl really works ! (Unfortunately i can't say i 
understood everything since i have not yet tried it by myself).

@lkmiller
Why not try a 1-process fsm ? Just because my teachers taught me like 
that (with 2 process ) , so I'm a little scared to do it differently. 
because, if ever what I do does not work with one process ... I risk of 
being slapped on the wrist ! But i have read your entire link, it's 
really well done, it helped me understand certain things and I keep in 
mind the 1-process FSM method. I 'll try to fix it.

So, when i do my 2-process FSM, when i'm creating new_delay an delay, or 
new_counter and counter, i making flipflop, which is much better than 
latch (i already know that i have to avoid them) ?

For example if i writing something like that :
1
signal data_wanted: unsigned (31 downto 0);
2
signal next_data_wanted: unsigned (31 downto 0);
3
4
--My sequentiel process
5
begin
6
process(clk, rst)
7
begin
8
9
if(rst = '1') then
10
    curr_state <= start;
11
    data_wanted <= (others => '0');
12
    maybe_something_else;
13
14
elsif(clk'event and clk = '1') then
15
    curr_state<=next_state;
16
    data_wanted<=next_data_wanted;
17
end if;
18
end process;

and in a state of my second process (combinatorial)
1
when Si=>
2
  next_rom_counter<=rom_counter+1;
3
  rom_adress<=rom_counter;
4
  next_data_wanted<=rom_out; -- this line
5
  next_state<=S(i+1);

I'm storing correctly (in a flip-flop) my data_wanted ? Something like 
this (even if it's not very professional and efficient) could be 
correct, i mean synthesizable ? And i could re-use data_wanted in an 
other state to make conditions ?

Thank you very much for your time !

: Edited by User
von Achim S. (Guest)


Rate this post
useful
not useful
Ed H. wrote:
> So, when i do my 2-process FSM, when i'm creating new_delay an delay, or
> new_counter and counter, i making flipflop,

In principle this works: data_wanted is stored in a flipflop, 
next_data_wanted "calculates" the input value for that flipflop.

But: you have to describe an assignment to next_data_wanted for every 
state Si in your combinatorial process. If you only assign 
next_data_wanted in some states  but make no assignment to it in others, 
then for the other states the value of next_data_wanted still has to be 
stored in a latch.

A default-assignment to next_data_wanted at the beginning of the 
combinatorial process will solve this problem. Put a
next_data_wanted <= data_wanted there. If you make an assignment to 
next_data_wanted in the actual state, then this is overwritten (e.g. by 
rom_out). If you are in another state and make no assignemt to it, the 
old value of data_wanted (stored in the flipflop) is reassigned.

Ed H. wrote:
> Just because my teachers taught me like
> that (with 2 process ) , so I'm a little scared to do it differently.

Ok, understood. As long as you write code for your teachers this may be 
ok. Once you write code for real life, you may change to the one process 
style ;-)

von Ed H. (hachhac)


Rate this post
useful
not useful
Fast answer and really clear in my head now i think !

So, if i want to avoid latch for next_data_wanted, and to avoid to 
assign next_data_wanted in every state to avoid latch, i can do things 
like that ?
1
P_FSM: process(.....)
2
begin
3
--HERE I SOLVE THE PROBLEM
4
next_data_wanted <= data_wanted;
5
Case current_state is
6
    when S1 => ...
7
    when S2 => ...
8
9
...

If i understood correctly, every time, next_data_wanted take the value 
stored in the flip_flop of data_wanted, and , when i'm in a state using 
next_data_wanted, i'm overwriting next_data_wanted, and so data_wanted 
too (with my other process).

and in my first example, i need to do the same thing for rom_counter and 
next_rom_counter if i don't want to assign next_rom_counter at every 
state !
Is that correct ?

Thank you very much, i'll try this tomorrow and come back here to tell 
you the result !

: Edited by User
von Achim S. (Guest)


Rate this post
useful
not useful
Ed H. wrote:
> If i understood correctly, every time, next_data_wanted take the value
> stored in the flip_flop of data_wanted, and , when i'm in a state using
> next_data_wanted, i'm overwriting next_data_wanted, and so data_wanted
> too (with my other process).

in that specific state you're overwriting next_data_wanted, i.e. the 
input of your flip-flop. And with the next rising clock-edge, the output 
of the flip-flop (data_wanted) takes the input value.

Ed H. wrote:
> and in my first example, i need to do the same thing for rom_counter and
> next_rom_counter if i don't want to assign next_rom_counter at every
> state !
> Is that correct ?

Sounds correct. And you need to do this for pretty much every signal. 
And this writing-overhead is one strong reason for using the one process 
style.

von Ed H. (hachhac)


Rate this post
useful
not useful
Thank you very much !

I know understand the power of 1-process fsm ... i really want to ty it, 
seems much more efficent and "code-lines saver" !

von Ed H. (hachhac)


Rate this post
useful
not useful
Hello !

Thank you for all your advices, it's now working and i was able to 
synthetize my work ! I mean no error about the problem and no latch.

( Even if after the synthesis it's absolutely not working (everything is 
freeze at the first state) but it's another problem !)

Thank you very much !

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.