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

  1. 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;

  2. 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;

  3. 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

  1. 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.

  2. 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

    );

  3. Constants: - Use descriptive names in uppercase for constants, separating words with underscores.

    • Example: MAX_DATA_WIDTH, DEFAULT_TIMEOUT

  4. 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

  5. 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

  1. 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;
    
  2. 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;
    
  3. 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;