Search code examples
vhdlfpgastate-machine

Proper way to change state on a state machine in VHDL


I'm working on a FPGA project where I need to read data from an image sensor. This sensor has different image modes (like test pattern, frame, binning, etc.) and in order to change image mode I need to look for specific signals before writing into the registers.

I have inherited some code that I need to fix since the image sensor sometimes gets stuck when we change image mode.

Concerning the change of image mode, a state machine is used.

The following piece of code shows how the registers for changing mode are currently written. Essentially, when we want to change mode, we need to wait that the signal MODE_SIG_HIGH becomes high before writing into the registers. Then, when this condition happens, we check what mode we want to set. For example, to set set test pattern, we check if bit S2 is set. Then we performs all the operations to actually change mode (line 10).

01. ...
02. WHEN MODE_SIG_HIGH =>
03.   NEXT_ST <= MODE_SIG_HIGH;
04.   ...
05.   IF S2 = '1' THEN 
06.     -- configure the sensor to            
07.     NEXT_ST <= CONFIGURE_TEST_PATTERN;
08.   END IF; 
09.   ...
10.   WHEN CONFIGURE_TEST_PATTERN =>
11.   ...

I'm having a debate with a friend of mine concerning what is the best way to change state when a new event happens. The above solution doesn't seem right to me. As far as I understood, when we enter a sate, all the instructions contained in that state are performed in parallel. Therefore, concerning the above piece of code, when we enter the state MODE_SIG_HIGH the instruction at line 03 is executed in parallel to the IF condition. My point is that if the bit S2 is set to 1, the IF condition is true and we end up assigning the value CONFIGURE_TEST_PATTERN to the NEXT_ST. An this ends up in assigning two different values to the same variable (in parallel), in line 03 and in line 07. Am I right or am I missing some basic behavior? The reason for having the instruction at line 3 is because after we enter MODE_SIG_HIGH, it could take some clock cycles before we see on of the mode bits set.


Solution

  • As far as I understood, when we enter a sate, all the instructions contained in that state are performed in parallel.

    Not quite. The only things in VHDL which are concurrent ('performed in parallel') are:

    1. processes
    2. concurrent signal assignments
    3. component instantiations
    4. concurrent procedure calls
    5. concurrent assertions (inc.PSL)
    6. generates
    7. blocks

    The code inside a process or subprogram (function/prodedure) executes sequentially. This is where you do your conventional programming, using sequential statements (ie. nothing in the list above). These are your standard control constructs (if, case, loop, etc), sequential signal assignments, and so on. If you carry out signal (or variable) assignments in a sequential region, the last one wins, just like a conventional programming language. There are scheduling rules that make this happen, but you don't need to know about those (yet!)