VHDL CODING GUIDELINES


Coding for Simulation:

1. General Naming Conventions

Rule: Develop a naming convention for the design. Document it and use it consistently throughout the design.

Guidelines:

  • Use lowercase letter for all signals names, variables names and port names.

Example

Clk, rst

  • Use uppercase letters for names of constant and user-defined types.

Example

`define IDLE 3’b000

  • Use meaningful names for signals, ports, functions and parameter.

Example

Do not use ra for RAM address bus .Instead use ram_addr

  • Use the name clk for the clock signal. If there is more than one clock in the design, use clk as the prefix for all clock signals.

Example

clk1, clk2 or clk_interface

  • Use the same name for all clock signals that are driven from the same source.
  • Use _n to indicate for active low signals. However any lowercase character is acceptable as long as it is used consistently.

Example

rst_n

  • When possible use the same name or similar name for ports and signals that are connected.

Example

a=>a; or a=>a_int;

When possible use the signal naming conventions listed in table.

Convention Use Example

*_r Output of a register count_r

*_a Asynchronous signal addr_strobe_a

*_pn Signal used in the nth phase enable _p2

*_nxt Data before being registered into a register with the same name

*_z Tristate internal signal

2. Naming Conventions for VITAL Support

Rule: (hard macro, top-level ports): Do not use underscore characters (_) in the entity port declaration for the top level entity of a hard macro. The reason for the rule is that VITAL uses of underscores as separators to construct names for SDF back-annotation from the SDF entries.

Rule: A port that is declared in entity port declaration shall not be of mode LINKAGE.

Rule: The type mark in the entity port declaration shall denote a type or subtype that is declared in package strd_logic_1164.The type mark in the declaration of an array port shall denote the type std_logic_vector.

Rule: The port in an entity declaration can not be a guarded port. Furthermore the declaration cannot impose a range constraint on the port nor can it alter the resolution of the port from that defined in the standard logic package.

2.1 Architecture Naming Conventions

Guideline: Use the VHDL architecture types listed in the table.

Architecture Naming Convention

Synthesis ARCHITECTURE rtl OF my_Syn_model IS

Model or

ARCHITECTURE str OF my_Structural_design IS

Simulation ARCHITECTURE sim OF my_behave_model IS

Model or


ARCHITECTURE tb OF my_test_bench IS

2.2 Include Headers in Source Files

Rule: Include a header at the top of every source file, including scripts. The header must contain

  • Filename
  • Author
  • Description of function and list of key features of the module
  • Date the file was Created
  • Modification history including date ,name of modifier and description of the change

Example:

-------------------------------------------------------------(c) Copyright 2007 company name. All rights reserved

--

-- File:

-- Project:

-- Purpose:

-- Author:

--

-- $Id: index.html,v 1.1 1999/03/09 01:55:57 george Exp $

--

-- Detailed description of the module included in the file. --Include relavant part of the spec

-- Logical hierarchy tree

-- Block diagrams

-- Timing diagrams etc.

--

-----------------------------------------------------------

2.3 Use Comments

Rule: Use comments appropriately to explain all process, functions and declarations of types and subtypes.

Example:

Comment for subtype declaration:

--Create subtype INTEGER-256 for built-in error

--checking of legal values.

Subtype INTEGER_256 is type integer range 0 t0 256

Guideline: Use comment to explain ports, signal and variables or groups of signals or variables.

2.4 .Keep Commands on Separate Lines

Rule: Use a separate line for each HDL statement. Although VHDL allow more than one statement per line, the code is more readable and maintainable if each statement or command is on a separate line.

3. Line Length

Guideline: Keep the line length to 72 characters or less.

Lines that exceed 80 characters are difficult to read in print and on standard terminal width computer screens. The 72 character limit provides a margin that enhances the readability of the code.

For HDL code, use carriage returns to divide lines that exceed 72 characters and indent the next line to show that it is a continuation of the previous line.

Example:

Hp_reg<= (count or data or temp_reg or ready_reg

Count_data_reg or enable_reg );

4. Indentation

Rule: Use indentation to improve the readability of continued code lines and nested loops.

Guideline: Use indentation of 2 spaces. Larger indentation (for examples, 8 spaces restricts line when there are several levels of nesting.

Guideline: Avoid using tabs. Differences in editors and user setup make the positioning of tabs unpredictable and can corrupt the indentation. There are programs available, including language – specific versions of emacs , that will replace tabs with spaces.

Example:

-------------------------------------------------

always @(posedge RClk)

begin

if(Rst_rclk)

RPtrBinRd <= 0;

else begin

if(WClr_sync)

--Clear the Read Pointer On Fifo Clear

RPtrBinRd <= 0;

else if(Read & ~Empty)

-- Increment the read pointer on every read and FIFO not empty

RPtrBinRd <= RPtrBinPls1Rd;

end

end

---------------------------------------------------------------------------

5. Do not Use HDL Reserved Words

Rule: Do not Sue VHDL or Verilog reserved words names of any element in your RTL source files. Because macro design must be translatable from VHDL to Verilog and from Verilog to VHDL, it is important not to use VHDL reserved words in Verilog and not to use Verilog reserved words in VHDL.


6. Port Ordering

Rule: Declare ports in a logical order, and keep this order consistent throughout the design.

Guideline: Declare one port per line, with a comment following it (preferably on the same line).

Guideline: Declare the ports in the following order.

Inputs:

  • Clocks
  • Resets
  • Enables
  • Other control signals
  • Data and address lines

Outputs:

  • Clocks
  • Resets
  • Enables
  • Other control signals
  • Data

Guideline: Use comment to describe groups of ports.

Examples:

entity mt_fir is

generic (

DATA_WIDTH : positive;

COEF_WIDTH : positive;

ACC_WIDTH : positive;

ORDER : positive;

);

port (

--control Inputs

clk : in std_logic;

rst_n : in std_logic;

run :in std_logic;

load :in std_logic;

tc :in std_logic;

--Data Inputs

data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);

coef_in : in std_logic_vector(COEF_WIDTH-1 downto 0);

sum_in : in std_logic_vector(ACC_WIDTH-1 downto 0);

-- control inputs

start : out std_logic;

hold : out std_logic;

--Data ouputs

sum_out : out std_logic_vector (ACC_WIDTH-1 downto 0);

end my_fir;

7. Port Maps and Generic Maps

Rule: Always use explicit mapping for ports and generics, using named association rather that positional association.

Guideline: Leave a blank line between the input and output ports to improve readability.

Example:

-- instantiate my_add

U_ADD: my_add

Generic map (width=> WORDLENGTH)

Port map (

a=> in1;

b=> in2;

ci=> carry_in;

sum => sum;

co=> carry_out;

);

8. VHDL Entity, Architecture, and Configuration Sections

Guideline: Place entity, architecture and configuration section of your VHDL design in the same file. Putting all the information about a particular in one file makes the design easier to understand and to maintain.

If you include sub design configuration in a source file with entity and architecture declarations, you must comment them out for synthesis. you can do this with the pragma translate_off and pragma translate_on

Pseudo-comments in the VHDL source file

Example:

--pragma translate_off

configuration ofg_example_struc of example is

for struc

use example_gate;

end for;

end cfg_example_struc;

--pragma translate_on

9. Use Function

Guideline: Use function when possible, instead of repeating the same section of code. If possible generalize the function to make it reusable. Also use comments to explain the function.

Example:

function convert_address

(input _address , offset : integer)

return integer is

begin

--function body here….

end;--convert _address

10. Use Loops and Arrays

Guideline: Use loops and arrays for improved readability of source code.

Example:

type reg_array is array (natural range<>) of

std_logic_vector (REG _WIDTH-1 downto 0);

signal reg: reg_array (WORD_COUNT-1 downto ));

begin

REG_PROC: process (clk)

begin

if clk=’1’ and clk ‘event then

if we=’1’ then

reg (addr) <= data;

end if;

end process REg_PROC;

data_out<=reg(addr);

11. Use Meaning Labels

Rule: Label each process block with a meaning name. This is very helpful for debug.

Guideline: Label each process block _PROC.

Example:

--synchronize requests (hold for one clock)

SYNC_PROC: process (req1, req2, rst, clk)

… Process body here…

end process SYNC_PROC;

Rule: Label each instance with a meaningful name.

Guideline: Label each instance U_

Rule: Do not duplicate any signal, variable or entity names.

Example:

If you have a signal named incr, do not use incr as process label.

12. Coding for Portability

Rule: Use only IEEE Standard types.

Example:

Creating a subtype from std_logic_vector

--create new 16 –bit subtype

subtype WORD_TYPE is std_logic_vector (15 downto 0);

Guideline: Use std_logic rather than std_ulogic. Likewise, use std_logic_vector rather than std_ulogic_vector. The std_logic and std_logic_vector types provide the resolution functions required for tristate buses. The std_ulogic and std_ulogic_vector types do not provide resolutions functions.

Guideline: Be conservative in the number of subtypes you create. Using too many subtypes makes the code difficult to understand.

Guideline: Do not use the types bit or bit_vector . Many simulators do not provide built-in arithmetic functions for these types.

Example:

Use ieee.std_logic_arith.all;

Signal a,b,c,d:std_logic_vector (y downto x);

C<=a+b;

13. Do Not Use Hard Coded Numeric Values

Guideline: Do not use hard coded numeric values in the design. As an exception use the values 0 and 1 ( but not in combination, as in 1001).

Example:

Poor coding Style:

wire [7:0] my_in_bus;

reg [7:0] my_out_bus;

Recommended coding Style:

`define MY_BUS_SIZE 8

wire [`MY_BUS_SIZE-1:0] my_in_bus;

reg [`MY_BUS_SIZE-1:0] my_out_bus;

14. Packages

Guideline: Collect all parameter values and function definitions for a design into a single separate file and name the file DesignName_package.vhd

15. Coding for Translation (VHDL to Verilog)

Guideline: Do not use generate statement. There is no equivalent construct in Verilog.

Guideline: Do not use block constructs. There is no equivalent construct in Verilog.

Guideline: Do not use code to modify constructs declarations. There is no equivalent construct in Verilog.

Coding for Synthesis:

1. Infer Register

Guideline: Registers (flip flops) are the preferred mechanism for sequential logic. To maintain consistency and to ensure correct synthesis, use the following templates to infer technology independent registers.

Example:

--process with synchronous reset

EX19A_PROC: process (clk)

begin

IF (clk’ event and clk=’1’) then

if rst=’1’ then

. . .

else

. . .

end if;

end if;

end process EX19A_PROC;



--Process with asynchronous reset.

EX19B_PROC: process (clk , rst_a)

begin

IF (clk’ event and clk=’1’) then

if rst=’1’ then

. . .

else

. . .

end if;

end if;

end process EX19B_PROC;


2. Avoid Latches

Rule: Avoid using latches in your design.

Example: Poor coding style: Infer Latch because of missing else condition.

EX21_PROC: process (a, b)

begin

if(a= ‘1’) then

Q<=b;

end if;

end process EX21_PROC;

Recommended Coding Style:

EX21A_PROC: process (a, b)

begin

if(a= ‘1’) then

Q<=b;

else

Q<=a;

end if;

end process EX21A_PROC;

Example: Poor coding style: Infer Latch because of missing z output assignment.

EX22_PROC: process (c)

begin

case c is

when ‘0’ => q <= ‘1’ ; z<=’0’;

when others => q<= ‘0’;

end case;

end process EX22_PROC;

3. Specify Complete Sensitivity Lists

Rule: Include a complete sensitivity list in each of your process in VHDL.

Example:

Process (a)

begin

C<=a or b;

end process

Pre-Synthesis Simulation Waveform

Synthesized Net list



Post –Synthesis Simulation Waveform

Simulation Mismatches Because of incomplete Sensitivity list

4. Combinational Block

For combinational block the sensitivity list must include every signal that is read by the process. In general this means every signal that appears on the right side of an assign (<=) statement or in a conditional expression.

Example:

COMBINATIONAL_PROC: process (a,inc_dec)

begin

if inc_dec =’0’ then

sum <= a+1;

else

sum <=a-1;

end if;

end process COMBINATIONAL_PROC;

5. Sequential Blocks

For sequential blocks, the sensitivity list must include the clock signal that is read by the process. If the sequential process block also uses a reset signal, include the reset in the sensitivity list.

Example:

SEQUENTIAL_PROC: process (clk)

begin

if (clk ‘event and clk=’1’) then

q<= d;

end if;

end process SEQUENTIAL_PROC;

6. Sensitivity List and Simulation Performance

Guideline: Make sure that process sensitivity lists contain only necessary signals. Adding unnecessary signals to the sensitivity list slow down simulation.

7. Signal Vs Variable Assignments

Signal assignments are scheduled for execution in the next simulation cycle.

Variable assignments take effect immediately and they take place in the order in which they appear in the code.

Example:

Poor Coding Style:

EX31_PROC: process (a, b)

variable c: std_logic;

begin

c: = a and b;

end process EX#31_PRCO;

Recommended Coding Style:

Signal c: std-logic;

EX31_PROC: process (a, b)

begin

c <= a and b;

end process EX31_PRCO;

8. Case Statement Versus if – then – else statements

A case statement infers a single level multiplexer, while an if-then-else statement infers a priority encoded, cascaded combination of multiplexers.

Example: if –then-else statement

EX32_PROC: process (sel, a, b, c, d)

begin

if (sel==”00”) then

outi <= a;

elsif (sel=”01”) then

outi<=b;

elsif (sel”10”) then

outi< = c;

else

outi<=d;

end if;

end process EX32_PRCO;

Example: Case Statement

EX33_PROC: process (sel, a, b, c, d)

begin

case sel is

when “00” => outc <=a;

when “01” => outc <=b;

when “10” => outc <=c;

when others => outc <=d;

end case;

end process EX33_PROC;

9. Coding State Machines

Guideline: Separate the state machine HDL description into two process, one for the combinational logic and one for sequential logic.

Guideline: Create an enumerated type for the state vector.

Guideline: Keep FSM logic and Non FSM logic in separate modules.

Guideline: Assign default state for the state machine. This is useful to implement graceful entry into the ideal state if no other state is initiated.

Example:

-----------------------------------------------------
 
library ieee ;
use ieee.std_logic_1164.all;
 
-----------------------------------------------------
 
entity seq_design is
port(    a:                  in std_logic;
          clock:            in std_logic;
          reset:            in std_logic;
          x:                  out std_logic
);
end seq_design;
 
-----------------------------------------------------
 
architecture FSM of seq_design is
 
    -- define the states of FSM model
 
    type state_type is (S0, S1, S2, S3);
    signal next_state, current_state: state_type;
 
begin
    
    -- cocurrent process#1: state registers
    state_reg: process(clock, reset)
    begin
 
          if (reset='1') then
            current_state <= S0;
          elsif (clock'event and clock='1') then
              current_state <= next_state;
          end if;
 
    end process;                                                              
 
    -- cocurrent process#2: combinational logic
    comb_logic: process(current_state, a)
    begin
 
          -- use case statement to show the 
          -- state transistion
 
          case current_state is
 
              when S0 =>          x <= '0';
                               if a='0' then
                                   next_state <= S0;
                               elsif a ='1' then
                                   next_state <= S1;
                               end if;
 
              when S1 =>          x <= '0';
                               if a='0' then 
                                   next_state <= S1;
                               elsif a='1' then 
                                   next_state <= S2;
                               end if;
 
              when S2 =>          x <= '0';
                               if a='0' then
                                   next_state <= S2;
                               elsif a='1' then
                                   next_state <= S3;
                               end if;
 
              when S3 =>          x <= '1';
                               if a='0' then 
                                   next_state <= S3;
                               elsif a='1' then 
                                   next_state <= S0;
                               end if;
 
              when others =>
                               x <= '0';
                               next_state <= S0;
 
          end case;
 
    end process;
 
end FSM;
 
-----------------------------------------------------