Programmable Logic/VHDL Processes

Concurrent vs. Sequential evaluation
There are two ways to make signal assignments in VHDL. Signal assignments can be made through a concurrent statement or a sequential statement. Assignments in concurrent statements take effect immediately. In the following example code, it can be thought that sQ will always have the value of sD when sFlag = '1'. Otherwise it will be zero. This will take effect one simulation "tick" after sD or sFlag changes.

Using a process allows us to write functionally equivalent code, only using more natural sequential statements. In a process, the statements are executed in order and only the end result of all the assignments in the process actually take effect. It is convenient to think of processes as mini "programs" that are executed and then apply the result of their signal assignments when done. Functionally equivalent sequential code is shown below:

When tracing through this code, sQ is first assigned the value of zero. Then, IF sFlag = '1', sQ is assigned the value of sD. sQ is not updated until the entire process is executed. Since the whole process is executed in a single simulation "tick" the end result is identical to the code with a concurrent assignment.

Processes using "wait"
One way processes can be constructed is using wait statements. A wait statement is a VHDL construct that tells the simulator how long do delay execution or under what condition to continue execution. The following are examples of wait statements:

By using wait statements the simulator knows when to stop execution of a process and let time advance in the simulation. Wait statements are used in a process as in the example below:

In this example the signal sClk is assigned the opposite of its current value. The process will then wait for half the time specified by the constant cClkPeriod, after which execution will continue. When the end of a process is reached, evaluation continues immediately back at the beginning of a process.

Processes using wait statements are usually not synthesizable and are typically used in test benches. However, they are usually intuitive to use and allow the rapid construction of test bench modules and the generation of other test signals used for checking the functionality of a VHDL module.

Processes using a sensitivity list
Another way to use processes is to use a sensitivity list:

The sensitivity list (another_flag) is a comma separated list of signals that the simulator watches for changes. When these signals change, the simulator will evaluate the process and update the assigned signals. With the above example, the process will be executed any time the signal "another_flag" changes.

Concurrent Statements as Processes
Concurrent statements in an architecture can be interpreted as a process with a single statement.

This code can be abbreviated as:

Concurrent statements in an architecture simplify the syntax of a module and allow simple assignments to be made with fewer VHDL constructs.

Synthesis of processes
Since the concept of scheduling evaluation of processes does not translate directly to physical logic, processes are interpreted to represent blocks of combinatorial logic or registers. A synthesis utility will usually interpret a block of combinatorial logic from a process with a sensitivity list.

This example from earlier will be synthesized into the mux below:

Aside from combinatorial logic, in order to create useful digital logic circuits, we need a way to create a register in hardware. A register (flip-flop) can be created using a process template similar to the following:

When synthesized, this code will create a register that has an asynchronous active high reset with a "D" input of sQ_next and an output of sQ.

Processes with sensitivity lists used to describe combinatorial logic and "register template" processes can be used together to describe a RTL digital circuit:

Again, the combinatorial parts of the RTL circuit are expressed using processes with sensitivity lists. Registers are then created using a standard register template as above.

Process coding tips

 * When describing combinatorial logic using a process, always "initialize" all the assigned signals to a default value at the top of the process.


 * Although shorter, one author's experience has shown that separating RTL logic into two processes (one for combinatorial logic and one for registers) is less error prone. The uses of signals such as "sQ" for the current output of a register and "sQ_next" for the output of the combinatorial logic and the next clock output of the register facilitates this.