Best Practices
Naming conventions, prefixes, and best practices for readable and maintainable VHDL code.
Why Coding Rules?
In a real VHDL project, a file may be read by dozens of people over years. Coding rules ensure:
- Readability: understand a signal's role at first glance
- Maintainability: quickly locate a bug
- Consistency: same style throughout the team
- Code review: facilitates error detection
Naming Prefixes
Ports (external interface)
| Prefix | VHDL Mode | Meaning | Example |
|---|
i_ | in | Input port | i_clk, i_data, i_rst |
o_ | out | Output port | o_valid, o_data |
io_ | inout | Bidirectional port | io_bus, io_sda |
Internal Signals
| Prefix | Meaning | Example |
|---|
w_ | Unregistered signal - wire, combinational | w_sum, w_mux_out |
r_ | Registered signal - flip-flop, D latch | r_counter, r_data |
Other Identifiers
| Prefix | Meaning | Example |
|---|
c_ | Constant | c_CLK_FREQ, c_MAX_COUNT |
g_ | Generic (entity parameter) | g_WIDTH, g_DEPTH |
t_ | User-defined type | t_state, t_data_array |
v_ | Variable (inside a process) | v_temp, v_index |
P_ | Process (label) | P_WRITE_FSM, P_READ_DATA |
|
Complete Examples
entity uart_tx is
generic (
g_CLK_FREQ : integer := 100_000_000; -- g_ for generic
g_BAUD_RATE : integer := 115_200
);
port (
i_clk : in std_logic; -- i_ input
i_rst : in std_logic; -- i_ input
i_data : in std_logic_vector(7 downto 0);
i_valid : in std_logic;
o_tx : out std_logic; -- o_ output
o_ready : out std_logic
);
end entity uart_tx;
architecture rtl of uart_tx is
constant c_BIT_PERIOD : integer
Additional Naming Conventions
Case
-- VHDL keywords: lowercase
entity, architecture, process, signal, begin, end, if, then, else
-- Constants and generics: UPPERCASE or mixed
constant c_MAX_VALUE : integer := 255;
generic (g_DATA_WIDTH : integer := 8);
-- Types: t_ + snake_case
type t_uart_state is (IDLE, START, DATA, STOP);
-- FSM states: UPPERCASE
type t_state is (IDLE, WAIT_START, SEND_DATA, DONE);
Files
- One file per entity
- Filename = entity name:
uart_tx.vhd
- Extension:
.vhd (VHDL) or .vhdl (less common)
Architecture
- Use
rtl for synthesizable code
- Use
tb for testbenches
architecture rtl of my_component is -- synthesizable code
architecture tb of tb_my_component is -- testbench
What to Avoid
-- BAD : non-descriptive names
signal a, b, c, x : std_logic;
signal temp1, temp2 : unsigned(7 downto 0);
-- BAD : mixed styles
signal DATA_OUT : std_logic; -- inconsistent
signal data_in : std_logic;
-- BAD : no prefix -> impossible to know if it's a register
signal counter : unsigned(7 downto 0); -- registered or combinational?
-- GOOD : clear prefixes
signal r_counter : unsigned(7 downto 0); -- clearly a register
signal w_carry : std_logic; -- clearly combinational
Prefix Reference Table
| Prefix | Type | Direction / Nature |
|---|
i_ | Port | Input (in) |
o_ | Port | Output (out) |
io_ | Port | Bidirectional (inout) |
w_ | Signal | Combinational (wire) |
r_ | Signal | Registered (flip-flop) |
c_ | Constant | Fixed value |
g_ | Generic | Entity parameter |
t_ | Type | User type |
v_ | Variable | Local process variable |
P_ | Process | Process label |
|
📝 Test your knowledge - Chapter quiz