0
votes

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.

1
Signals only take the last value assigned to it, as the second assignment overrides the first. It is only processes and single line assignements that run "in parallel". Code within a process is sequential (within the same delta cycle). So if s2 = '0', then it will stay in the same state. If s2 = '1', then it will move into the configure_test_pattern state. This is a pretty standard coding technique.Tricky
The same simulation cycle, not delta cycle. IEEE Std 1076-2008 10.5.2.2 Executing a simple assignment statement para 7 "a) All old transactions that are projected to occur at or after the time at which the earliest new transaction is projected to occur are deleted from the projected output waveform." There's only one projected output waveform queue location for any simulation time, including the current time. The first NEXT_ST assignment can be viewed as a default and prevents inferred latches.user1155120
10.5.2.2 Executing a simple assignment statement para graph 4 in part "... If the after clause of a waveform element is not present, then an implicit “after 0 ns” is assumed. ..." Assignment times are relative to the current simulation time. A signal value is not updated in the same simulation cycle it updates the projected output waveform (14.7.5 Model execution, 14.7.5.3 Simulation cycle para 1 steps c), d), f) 2)). Drivers are updated before process execution is resumed. It allows the projected output waveform to be overwritten before driver update.user1155120
This question doesn't appear on-topic here. Not a specific programming problem, or a software algorithm, or software tools commonly used by programmers; and is a practical, answerable problem that is unique to software development. It could be modified to be a specific programming question, see How to Ask.user1155120

1 Answers

2
votes

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!)