General VHDL Coding TipsEdit
- Use spaces and indentation that reflects the purpose of the code. The formatting of the code should emphasize its functionality and help the reader follow its flow.
- Indent with spaces, tabs are not uniform across all text editors.
- Use a consistent style when naming signals. One of the authors uses the following
- Prefix signals with a lower case "s" and capitalize the first letter of the name, ie sFlag
- Prefix variables with "v", constants with "c", arrays and other general types with "t", processes with "p", and record types with "r" in a similar fashon
- Capitalize each new word of a signal name. (sStatusFlag)
- Designate the input of registers with a _next suffix. If sQ is the output of a register, the signal containing its value on the next rising edge of the clock sQ_next.
- Avoid repeated code whenever possible. Check the capabilities of your synthesis tool. If the tool supports multidimensional arrays, record types, loops , and/or generate statements, USE them.
- Use record types (if possible) to pass a large number of status bits or control bits around modules. If the number or type of status bits changes, the entity and port maps of the effected entities do not also have to change. Also, this saves one from having to remember which bit slices of a vector are for which flag or control signal.
- When using record types or arrays in a design, define these in a package instead of in the architecture. This allows them to be shared between modules.
- Use an enumeration to specify states for a state machine. This improves readability of the code and helps one follow things when debugging in a simulator. If control of the state machine encoding is needed, check with the synthesis tool and use an "attribute" statement if needed.
- Don't assign directly to output ports in processes. Assign the outputs to an internal signal and then later use a concurrent statement to assign the values to the output. This gives the ability to inspect the output value if needed (by debugging code or an ILA block if later needed).
- A text editor that supports column editing is very useful when writing VHDL. (UltraEdit is a Paid one of these...)(NotePad++ is a free one of these...)
The architecture name should be descriptive of the "type" of design it describes. Some general guidelines are below:
- Use "behave" for test bench and most behaviorally written code (generally not synthesizable)
- Use "rtl" for most synthesizable code.
- Use "struct" for modules that mainly glue other modules together with port maps (top level, etc...)
File naming and organizationEdit
- Create one VHDL entity per file
- Name the file after the VHDL entity or package it contains ie. address_decoder.vhd contains the entity address_decoder.
- For all except the largest of designs, it is recommended that all the files that implement a design be kept in the same directory. This saves time when trying to trace signals through files. It is useful to separate test bench files elsewhere. This keeps the directory from getting too cluttered.
- A useful directory structure for VHDL projects is as follows:
- /doc - design documentation is kept here
- /loads - programming files go here
- /sim - simulation scripts, projects, and testbench files go here
- /syn - synthesis project and files go here (optional if synthesis done as part of the place and route process, ie using XST with a Xilinx design)
- /par - place and route/implementation project and files go here.
- /src - source VHDL/Verilog files go here
- Use version/source control (subversion, cvs) with your FPGA project. The software programming world has learned a lot of lessons about managing source code. Many of these can be applied to HDL code as well.
- When possible, a way to poll the "version" of the FPGA/CPLD project should be implemented. This allows the ability to determine what code is being tested on the hardware. This "version" should be coordinated with the version/source control system.