6. Hardware Conventions
6.1. VHDL Naming and Syntax Conventions
This document outlines the general naming and syntax conventions followed in VHDL coding, applicable across various modules.
6.2. General Conventions
Libraries and Packages: - Always include necessary libraries at the top of the file to enable specific data types and operations.
For example: .. code-block:: vhdl
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL;
Entity Declaration: - The entity defines the module’s interface, including generic parameters and port signals.
For example: .. code-block:: vhdl
- entity Module_Name is
- generic (
PARAM_NAME : integer := DEFAULT_VALUE; – additional parameters…
); port (
signal_name_1 : in std_logic; – Input signal signal_name_2 : out std_logic; – Output signal – additional signals…
);
end Module_Name;
Architecture Declaration: - The architecture specifies the internal behavior of the module, including signals, constants, and processes.
For example: .. code-block:: vhdl
- architecture RTL of Module_Name is
– Declare internal signals signal internal_signal : std_logic_vector(N downto 0); – additional signals…
- begin
– Architecture body
end RTL;
6.3. Naming Conventions
Entity and Architecture Names: - Use descriptive names for entities and architectures.
Example: Module_Name, Architecture_Name
For the architecture, use a name that reflects the implementation type, such as RTL.
Port Signals: - Inputs and outputs should have clear, meaningful names, typically in lower case.
Use prefixes to indicate signal direction or purpose: - in_ for input signals. - out_ for output signals. - c_ for control signals. - addr_ for address signals. - data_ for data signals.
Example: .. code-block:: vhdl
- port (
clk : in std_logic; – Clock signal rstn : in std_logic; – Active-low reset in_command : in std_logic; – Input command out_data : out std_logic_vector(DATA_WIDTH - 1 downto 0) – Output data
);
Constants: - Use descriptive names in uppercase for constants, separating words with underscores.
Example: MAX_DATA_WIDTH, DEFAULT_TIMEOUT
Signal Naming: - Signals should clearly reflect their functionality and follow a consistent naming scheme.
Use prefixes to indicate their roles: - state_ for state signals. - next_ for next-state signals. - _reg for register signals.
Example: .. code-block:: vhdl
signal state : t_state_types; – Current state signal next_state : t_state_types; – Next state signal data_reg : std_logic; – data register
Component Instantiations: - Components should be instantiated with clear names that reflect their functionality. - The following example shows how to connection signals are named. Every output signal of an - instantiation is connected to a signal with its prefix. In this case em1. The suffix is always _out - and inbetweenn is the name of the port port_name. This way every connection signal in top level file - points always to its output source.
Example:
EM1 : example_module1 instance_name: Example_module1 generic map ( PARAM => VALUE ) port map ( port_name_1 => em1_name_1_out, -- This is an output of example module1 port_name_2 => em1_name_2_out, -- This is an output of example module1 port_name_3 => em2_name_3_out, -- This is an input from example module2 );
6.4. State Machine and Processes
State Machine: - Use enumerated types to define states.
Example:
type t_state_types is (STATE_IDLE, STATE_PROCESS, STATE_DONE); signal current_state : t_state_types; signal next_state : t_state_types;
Implement state machines using 3 process blocks:
One clocked process for state switching and register:
process(clk) begin if rising_edge(clk) then if rstn = '0' then current_state <= STATE_IDLE; else current_state <= next_state; end if; end if; end process;
One state driven process handling state switches
process(current_state, input_signals) begin case current_state is when STATE_IDLE => if start_condition then next_state <= STATE_PROCESS; else next_state <= STATE_IDLE; end if; -- additional states... end case; end process;
One process setting the signals in each state
process(current_state, input_signals) begin -- Default signals out_signal1 <= '0'; out_signal2 <= '0'; case current_state is when STATE_IDLE => out_signal2 <= '1'; -- additional states... end case; end process;
Sequential Logic: - Use process blocks triggered by the clock signal for sequential logic.
Example:
process(clk) begin if rising_edge(clk) then if rstn = '0' then data_reg <= (others => '0'); else data_reg <= (others => '1'); end if; end if; end process;
Combinatorial Logic: - Use process blocks without clock triggers for combinatorial logic.
Example:
process(input_signals) begin -- Default outputs output_signal <= default_value; if condition then output_signal <= new_value; end if; end process;