The major differences among coding styles relate to how the design engineer decides to handle VHDL keywords and any user-defined items (the names of signals, variables, functions, procedures, etc.). Although there are many different possibilities, in practice there are only three commonly used approaches. The first technique is to use a standard text editor and simply enter everything in lowercase (and black-and-white) as shown in the following example of a simple synchronizer:
The second method is to follow the VHDL Language Reference Manual (LRM), which says that keywords (if, case, when, select, etc.) should be presented in lowercase. Strangely, the LRM doesn’t have anything to say about how user-defined items should be presented, but the common practice (when the keywords are in lowercase) is to present user-defined items in uppercase as shown below:
The third approach — and my personal preference — is to turn the LRM on its head; to capitalize keywords (IF, CASE, WHEN, SELECT, etc.) and to present any user-defined items in lowercase as shown below:
The main argument for using uppercase for keywords and lowercase for user-defined items, or vice versa, is that this helps design engineers and reviewers to quickly locate and identify the various syntactical elements in the design. However, this line of reasoning has been somewhat negated by the use of today’s context-sensitive editors, which are language-aware and therefore able to automatically assign different colors to different items in the design.
Let’s look at our original examples through the “eyes” of a context-sensitive editor as illustrated in the following three images:
Although context-sensitive editors are extremely efficacious, it’s important to remember that some users may be color-blind. Also, even if the code is captured using a context-sensitive editor, it may be that some members of the team end up viewing it using a non-context-aware (black-and-white) editor. Furthermore, the code may well be printed out using a black-and-white printer. For all these reasons, my personal preference is to capitalize keywords and for everything else to be in lowercase.
Aside from how we handle the keywords, most companies will have their own sets of coding guidelines, which will also address other aspects of coding, such as:
- Naming conventions for clock signals; possibly requiring each clock name to include the frequency, e.g., clk_40MHz, clk_100MHz.
- Naming and handling of reset signals to the device (active-high, active-low), along with the synchronization of the signal and its assertion and de-assertion within the FPGA. The de-assertion of a reset is key, as removing this signal at the wrong time (too close to an active clock edge) could lead to metastability issues in flip-flops.
- Naming conventions for signals that are active-low (this is common with external enables). Such signals often have a “_z” or “_n” attached to the end, thereby indicating their status as active-low (“ram_cs_n” or “ram_cs_z,” for example).
- The permissible and/or preferred libraries that will ensure the standard types that can be used. Commonly used libraries for any implementable code are “std_logic_1164” (this is the base library that everyone uses) and the “numeric_std” for mathematical operations (as opposed to “std_logic_arith”). Meanwhile, other libraries such as “textio” and the “math_real” and “math_complex” libraries will be used when creating test benches.
- The use of “std_logic” or the unresolved “std_ulogic” types on entities and signals (“std_ulogic” is the unresolved type of “std_logic” and is used to indicate concurrent assignments on a signal).
- Permissible port styles. Many companies prefer to use only “in,” “out,” and “inout” (for buses only) as opposed to “buffer,” as the need to read back an output can be handled internally with a signal. Also, many companies may limit the types permissible in entities to just “std_logic” or “std_logic_vector” to ease interfacing between large design teams.
- It is also common for companies in some specialist safety-critical designs to have rules regarding the use of variables.
These coding styles can be very detailed, depending upon the end application the FPGA is being developed for.