Elecard's VHDL Design Rules & Coding Style

� 2006 Elecard - all rights reserved

 

Introduction

This document is only proposing a number of recommendations that, if followed, will

considerably reduce the design risks. If you do not agree with some rules, or want to suggest adding others, please fell free to contact: Denis Shekhalev [email protected].

 

Conventions

RTL: Register Transfer Level (almost equivalent to � synthesizable �).

BEH : Behavioral code almost equivalent to � synthesizable �).

SIM : Test benches, test code and resources for simulation and verification in general.

 

1.      Design Data Organization

 

1.1.      Source Files Naming Convention :

��������������� Use the following notation for file naming convention.

Design file

Pc name

Entity

EntityName_e.vhd

Architecture

EntityName_a.vhd

Entity/architecture pair

EntityName_ea.vhd

Package declaration

PackageName_p.vhd

Package body

PackageName_b.vhd

Package declaration and body

PackageName_pb.vhd

Configuration

EntityNameConfigName_c.vhd

Test bench

EntityName_tb.vhd

 

 

 

1.2.      Only one design unit entity per file (with the exception of configurations which may be grouped in one file).

1.3.      In general, avoid splitting Entity and Architecture in different files.

1.4.      If one entity has several architectures, there must exist only a unique entity section. Multiple architectures are possible in the same file, be sure to put the one used for synthesis in the last position (bottom of file), so the use of a configuration will not be compulsory for synthesis.

1.5.      RTL: A module (entity) should not contain several different and independent functionalities.

1.6.      Design units should be placed in design libraries other than work The library name should reflect the family of devices or of functions the library holds.

 

2.      Cosmetic Rules

2.1.      Every design file must be properly documented in a standardized header. �Each file should have a descriptive header which is a set of comments containing the following information (Note: The project should decide which header information is appropriate).

2.1.1.    Project name.

2.1.2.    File name.

2.1.3.    Title of the design unit.

2.1.4.    Description of the design unit including its purpose and model limitations.

2.1.5.    Design library where the code is intended to be compiled in.

2.1.6.    List of analysis dependencies, if any (e.g. packages, components (for simulation)).

2.1.7.    Initialization of model (e.g. hardware RESET, port and signal initialization).

2.1.8.    Notes or other items (e.g. synthesis aspect of design unit).

2.1.9.    Author(s) and full address (email, phone number, etc.).

2.1.10. Simulator(s), simulator version(s), and platform(s) used.

2.1.11. Revision list containing version number, authors), the dates, and a description of all changes performed.

2.2.      The comments and header information must be kept accurate and up-to-date throughout code changes and design iterations.

2.3.      The files must not include any � hard tab � (HT) but only soft spaces, and must be properly aligned and indented. All declarative regions and block statements should be indented by at least 2 spaces. A block statement can be the concurrent statement part of an architecture, the else clause of an if statement, the body of a subprogram, etc. If at all possible, indentation levels in sequential statements should not exceed 4. Use subprograms to break the code into manageable parts.

2.4.      Use blank lines to group logically related text of code.

2.5.      Elements in interface declarations should be vertically aligned. Vertical alignment of interface declarations allows quick identification of the various kind of interface declarations, their names, directions, and types.

2.6.      Total line length should be less than 132 characters.

2.7.      Only one single executable statement per line.

2.8.      The VHDL code must include significant and value-adding comments, in English. Every process or continuous assignment should be preceded by a comment summarizing its purpose.

2.9.      It should be easy to match the requirements and the HDL code, both ways.

2.10.   There should be no piece of code commented out. Inactive or wrong code should be deleted. If needed, an older version of the architecture can be kept as a reference, for comparison or non-regression purpose.

2.11.   Declare in the package declaration, only those items which will be used by users of the package. Hide items which are only used by the package body in the body of the package.

 

 

3.      Naming Rules

3.1.      Use the following requirements for identifier naming convention

IdentifierName ::= [prefix][partition]Identifier_Name[delayed][Polarity][_][Suffix]

������� PREFIXES are used in the naming of timing parameters in a manner compliant with the VITAL (VHDL Initiative Toward ASIC Libraries) specification which could allow back-annotation of timing parameters

PARTITION is one character representing the partition name, preferably in lower case (e.g. V for Receiver partition). The partition prefix is applicable only to ports or internal signals and variables which are synthesized to registers. It is not applicable to types, procedures, functions, process, block, entity or architecture names.

IDENTIFER_NAME represents the name of the object in mixed or upper case, with the first character in upper case.

DELAYED is one character "R" to indicate a register delay version of the original signal. This is applicable only to ports or internal signals and variables which are synthesized to registers.

POLARITY represents a logical polarity for signals of type standard logic or standard logic vectors, where "T" represents active TRUE, and "F" or "N" represents active FALSE. This is applicable only to ports or internal signals and variables which are synthesized to registers. If the identifier name ends with � "�" and the polarity is active TRUE, then the polarity is omitted. Conversely if the identifier name ends with an "F" and� the polarity is false, men the polarity is omitted

SUFFIX represents additional information about the identifiers. Summary of the recommended suffixes:

CATEGORY

SUFFIX

COMMENTS

EXAMPLE

Object

_s

signal from signal class, used in architectures and in subprograms.

 

Object

_inp,

_outp,

_inoutp

Input port.

Output port.

Inout_port.

Port. Port names and signals connecting to component ports may omit the suffix.

 

Object

_v

variable from variable class

 

Object

_i

index of loop

 

Object

_g

generic

 

Object

_c

constant from a constant class, used in packages, architectures, and subprograms

 

Object

_f

file from a file class

 

Library

_lib

Library which holds design units for a design.

 

Package

_pkg

Package which holds constant, type, and subprogram definitions.

 

Entity

_nty

Entity which defines the I/O Interfaces

 

Type

_t

Type and subtype definitions

 

Label

_gen,

_proc,

_loop

label for generate

label for process

label for loop

 

Configuration

_cfg

Configuration

 

 

3.2.      Use the following restrictions for identifier name naming convention

3.2.1.    Adopt HDL-friendly Identifiers, OS-friendly names for design units, always restrict yourself to using plain 7-bits Ascii (avoid accents) and adopt meaningful names (in English).

3.2.2.    Avoid too short names (like � i �, � n �...) except for very short scope since they tend to be difficult to locate with a text editor.

3.2.3.    Avoid the use of extended identifiers

3.2.4.    Use Short identifiers when the scope is local, and Longer more explicit (English) identifiers for greater scope or global items.

3.2.5.  Use Upper and Lower cases for improved readability e.g. LocalReadEnable.

3.2.6.    Avoid using 1 (one), l (lower case L), I (uppercase i) O (uppercase Oh) and 0 (zero) in situations which may be visually ambiguous.

3.2.7.    Do not use too long names for identifiers, especially for entities. Try a maximum of 8 characters, and at least no more than 16, identical with the file name.

 

3.3.      Use the following names for architecture naming convention: "rtl", "behavioral", "structural", "functional" and etc.

3.4.      Whenever possible, when installation components in architecture, use as the component name the entity associated with that component.

3.5.      Use the following restrictions for port naming convention

 

Port name

Port definition

clkXXXX

Use for clock signal�s

rstXXXX

Use for asynchronous reset

sclrXXXX

Use for synchronous reset

enaXXXX

Use for enable signal

loadXXX

Use for load signal

 

3.6.      Identifiers for subprograms (i.e. procedures and functions) should be verb phrases descriptive of their actions such that their functionality can be interpreted from the context of usage.

 

 

4.      Coding Rules

4.1.      Adopt VHDL 93 / 2001 standard (VHDL '87 was messy and is definitely obsolete).

4.2.      RTL: Use exclusively IEEE libraries : std_logic_1164, �numeric_std. Do NOT use Synopsys: std_logic_arith, std_logic_(un)signed, numeric_bit, and other horrendous and proprietary libraries. Math_real should be avoided if possible in RTL code.

4.3.      BEH & SIM: use also textio (ieee) and std_logic_textio (synopsys). Math_real is also possible and useful, recommended in test benches.

4.4.      Using specific non-standard packages and libraries should be limited to a strict minimum and with great care since this weakens the project's integrity, safety, portability and reusability.

4.5.      RTL + BEH: define only one single port per line + a comment for every port.

4.6.      Unconstrained arrays can be used in ports (very elegant style), but this can cause trouble for unitary synthesis (always), and synthesis (not all synthesizers, at the time of writing, do support unconstrained array in ports).

4.7.      Default values can be used for input and output ports.

4.8.      RTL: records are possible and sometimes recommended for inter-entity connectivity, but should be avoided in top level ports.

4.9.      Vectors directions:

4.9.1.    Use descending (downto) if the vector represents a number (or when in doubt...).

4.9.2.    Use ascending (to) for the first dimension of a memory array.

4.9.3.    Ascending is also okay for a numbered collection of items, like LED array etc...

4.10.   RTL: Avoid hard values use attributes on objects.

4.11.   Use constants to define data parameters and table lookups.

4.12.   Use attributes of objects instead of fixed values or constant unless the value is known and very unlikely to be modified

4.13.   RTL: Use "rising_edge" exclusively (it's time to give up clock'event and clk='1').

4.14.   RTL: When �rst� exist in process then every signal assigned inside "rising_edge" must be initialized.

4.15.   RTL: Inside "if rst", only constant values can be assigned (no asynchronous load). Furthermore, registers powering up at '0' are usually preferable.

4.16.   RTL: "wait" is forbidden.

4.17.   RTL: Avoid using attributes on types, prefer the attributes on objects (signals or variables).

4.18.   RTL: Do not use "BUFFER" mode in ports. Use � out � mode and internal signals with proper naming convention and suitable type. If different type, convert in the continuous assignment.

4.19.   RTL: Do not use "INOUT" mode except at the very top level. Define the tri-state drivers only at the top-level of the hierarchy, thus avoiding to rely on "tri-states bubble-up". Remember that internal tri-states are strictly forbidden (in most FPGA architectures) or non portable if allowed in the technology.

4.20.   RTL: the tri-state and bi-directional Input/Outputs must be coded in the top level as :

ExtBus <= BusOut when Oen='1' else (others=>'Z');

BusIn <= ExtBus;

4.21.   Input ports can be left unconnected (open) at instantiation provided they are assigned default values at declaration.

4.22.   �It is possible, maybe recommended to use direct instantiation which gets rid of the component declaration, but the instance can then no longer be configured.

4.23.   Instantiation must use named Port Maps. Ordered port maps should not be allowed.

4.24.   Do not leave ports unconnected by omission : use "open".

4.25.   �RTL: Avoid recursive code ! This can work with some tools, and it will likely improve over the years, but it's taking chances with tools and it may not be very easy to understand.

4.26.   �RTL: Global signals and shared variables are not allowed. If needed for simulation purpose, exclude them by synthesis pragmas (but see below).

4.27.   �RTL: beware of proprietary pragmas. If absolutely required, be sure to document their use and put a note in the header. �

4.28.   A graphical (schematics) top-level, automatically translated in structural VHDL can be a good idea. But always keep the VHDL the master document.

4.29.   �RTL: Use as few variables as possible in synthesizable code, and never when you may use signals instead. Use variables for their specific behavior (factoring, intermediate results, re-using the FlipFlops inputs etc..).

4.30.   BEH & SIM: Use as many variables as possible in Test Benches and Behavioral Models !

4.31.   �RTL: Never create latches, combinational feedback or asynchronous sequential logic, whether intended or unintended !

4.32.   �RTL: It is not allowed to initialize signals at their declaration. It is not allowed to initialize variables at their declaration in processes. It is acceptable to initialize variables at their declaration inside functions.

4.33.   �RTL: Definitely avoid using procedures in RTL code. Using functions in RTL is possible. Prefer functions declared in the architecture (local) rather than in packages (too far) or in the process (too local).

4.34.   �BEH & SIM: Definitely use procedures as much as possible.

4.35.   �RTL: Preferably code combinational logic inside sequential processes.

4.36.   �RTL: Avoid combinational processes if possible (see above). In case: Sensitivity Lists must be complete and accurate (no missing, no extra).

4.37.   Use concurrent signal assignment statements without a clock statement to describe the combinatorial logic. Alternatively, use processes with sensitivity clauses and with variables used to compute the values of complex terms

4.38.   �BEH & SIM: Do not use processes with sensitivity list.

4.39.   �BEH & SIM: Inside the processes make sure there is a wait or equivalent in every branch!

4.40.   �RTL: Resource sharing. Document (with appropriate comments) the intended operators that synthesis is expected to share. In case of doubt, remove the operator(s) and factor it (them) out � by hand � (like in continuous assignments).

4.41.   �RTL: Use as few proprietary (vendor-specific) macro-functions as possible and properly isolate / document them. When possible, inference may be preferable, but this depends on many design- vendors- and tools-specific factors.

4.42.   �RTL: One single clock domain per entity (except on top level and clock domain resynchronization-crossing entities indeed!).

4.43.   �RTL: All asynchronous input signals should be re-synchronized, preferably at the top-level. Do not insert logic between the I/O and the input Flip-Flop! Synchronous I/Os must be handled specifically (constraints etc...).

4.44.   �RTL: All the Entity's outputs should be registered. Combinational outputs can also create combinational feedbacks through the hierarchy.

4.45.   �RTL: At the top level, combinational outputs should not be allowed. In general, all the device's outputs should be direct Flip-Flop outputs. Avoid relying on � not gate push back �.

4.46.   RTL, BEH, SIM: Avoid active-low signals inside the design. The internal logic should be active-high.

4.47.   RTL: Finite State Machines Coding Style. (not describe yet)

4.48.   RTL: Isolate unavoidable technology-specific code (internal tri-states, memory inference / instantiation, primitive�s instantiations like PLLs, etc...

4.49.   RTL: Complex entities or technology-specific instances must have a behavioral model, for simulation (or faster simulation).

4.50.   RTL, SIM, BEH: Place documented assertions (VHDL, OVL, or PSL) where appropriate. Refer to ABV methodology.

4.51.   SIM: At the end of the simulation, the simulator should stop due to event starvation, to avoid useless simulation runs (beyond stimulus range). The clock must therefore be stopped (also).

4.52.   When designing synchronous logic, avoid VHDL structures that infer latches.

4.53.   To avoid unwanted latches in combinational designs, all conditional statements, conditional signal assignments, and selected signal assignments must be complete. Thus, all conditions must be considered, and values must be assigned under all conditions.

4.54.   Avoid the definition of impure functions.

 

5.      Design Flow

5.1.      Use Scripts (command line or Tcl preferably) for synthesis and simulation tasks. Use GUIs when investigating, or other early phases. A finalized design should never rely on any GUI.

5.2.      Test Benches must be self-checking and regressionable. They should not use not-portable run-time �simulator � commands (like force, unforce, etc...).

5.3.      If an external stimulus (e.g. memory data) is required, it shall be implemented by reading an ASCII file using STD.TextIO package to ensure portability.

5.4.      Test benches, auxiliary files (vectors, expected results, memory contents, behavioral models, etc...) should be versioned, properly documented and archived.

5.5.      Every step involved in producing the final object (usually the bitstream) must be automated through documented, versioned and archived scripts. The steps must be documented since the scripts are tool-specific and version-specific.

5.6.      Every entity must be white-box tested (unitary) with (at least) one Test bench.

5.7.      Every entity must be unitary synthesized (simple entities may violate this rule).

5.8.      The design must be simulatable at the post-layout timing level.

5.9.      The exact Type and Version (including Services Pack info) of all the Tools used must be properly documented. On some key projects, it may be desirable to maintain the availability of all the tools used throughout the life of the product.

 

 

 

 

6.      List of material:

  1. ALSE's VHDL Design Rules & Coding Style.
  2. Ben Cohen - VHDL Coding Guide and Methodologies.