Showing posts with label VHDL. Show all posts
Showing posts with label VHDL. Show all posts

Non-Synthesizable VHDL Code


RTL Synthesis is done by matching high level code against templates or patterns. It is important to use idioms that your synthesis tool recognizes. If you aren’t careful, you could write code that has the same behavior as one of the idioms, but which results in inefficient or incorrect hardware.





Most synthesis tools agree on a large set of idioms, and will reliably generate hardware for these idioms. This post is based on the idioms that Synopsys, Xilinx, Altera, and Mentor Graphics are all able to synthesize. We consider combinational loops to be unsynthesizable. Although it is obviously possible to build a circuit with a combinational loop, in most cases the behaviour of such a circuit is undefined.

Initial Values
Initial values on signals (UNSYNTHESIZABLE)
signal bad_signal : std_logic := ’0’;
Reason: In most implementation technologies, when a circuit powers up, the values on signals are completely random. Some FPGAs are an exception to this. For some FPGAs, when a chip is powered up, all flip flops will be ’0’. For other FPGAs, the initial values can be programmed.

Wait For
Wait for length of time (UNSYNTHESIZABLE)
wait for 10 ns;
Reason: Delays through circuits are dependent upon both the circuit and its operating environment, particularly supply voltage and temperature.

Different Wait Conditions
wait statements with different conditions in a process (UNSYNTHESIZABLE)
-- different clock signals
process
begin
wait until rising_edge(clk1);
x <= a;
wait until rising_edge(clk2);
x <= a;
end process; 

-- different clock edges
process
begin
wait until rising_edge(clk);
x <= a;
wait until falling_edge(clk);
x <= a;
end process; 

Reason: Processes with multiple wait statements are turned into finite state machines. The wait statements denote transitions between states. The target signals in the process are outputs of flip flops. Using different wait conditions would require the flip flops to use different clock signals at different times. Multiple clock signals for a single flip flop would be difficult to synthesize, inefficient to build, and fragile to operate.

Multiple “if rising edge”s in Same Process
Multiple if rising edge statements in a process (UNSYNTHESIZABLE)
process (clk)
begin
if rising_edge(clk) then
q0 <= d0;
end if;
if rising_edge(clk) then
q1 <= d1;
end if;
end process;
Reason: The idioms for synthesis tools generally expect just a single if rising edge statement in each process. The simpler the VHDL code is, the easier it is to synthesize hardware. Programmers of synthesis tools make idiomatic restrictions to make their jobs simpler.

“if rising edge” and “wait” in Same Process
An if rising edge statement and a wait statement in the same process (UNSYNTHESIZABLE)
process (clk)
begin
if rising_edge(clk) then
q0 <= d0;
end if;
wait until rising_edge(clk);
q0 <= d1;
end process;
Reason: The idioms for synthesis tools generally expect just a single type of flop-generating statement
in each process.

“if rising edge” with “else” Clause
The if statement has a rising edge condition and an else clause (UNSYNTHESIZABLE).
process (clk)
begin
if rising_edge(clk) then
q0 <= d0;
else
q0 <= d1;
end if;
end process;
Reason: Generally, an if-then-else statement synthesizes to a multiplexer. The condition that is tested in the if-then-else becomes the select signal for the multiplexer. In an if rising edge with else, the select signal would need to detect a rising edge on clk, which isn’t feasible to synthesize.

“if rising edge” Inside a “for” Loop
An if rising edge statement in a for-loop (UNSYNTHESIZABLE-Synopsys)
process (clk) begin
for i in 0 to 7 loop
if rising_edge(clk) then
q(i) <= d;
end if;
end loop;
end process;
Reason: just an idiom of the synthesis tool.
Some loop statements are synthesizable. For-loops in general are described in the VHDL cookbook by Ashenden. For the curious reader, the above code is an 8-bit serial-to-parallel converter. The signal d is the serial data and q is the parallel data. On each clock cycle, d is copied into one of the bits of q.

For the synthesizable alternatives, please discuss/leave comments below.

A Step-By-Step Methodical Approach for Efficient Mixed-Language IP Integration


This article provides a comprehensive methodology that highlights the best practices for mixed-language design integration and automatically comes up with an option for designers to select the optimal method for integration.
There are broadly five ways of making mixed-language connections. Pros and cons of each of these approaches and their comparison is described in terms of the usage scenarios, performance implications of using one versus the other, delta cycle value update concerns, and more. A step-by-step guideline based on decision-making trees that designers can follow to help them decide which approach best suits their particular mixed-language integration scenario is also discussed.

Words of wisdom


Delta cycles are used by the simulator to order events within a simulation cycle. A delta cycle has an infinitesimally small delay and it does not appear on the trace waveform produced for analysis.

Words of wisdom


Inertial Delay – Default delay type in VHDL. Used to model gates that do not propagate short pulses. Any signal with a pulse-width shorter than the specified delay time is rejected.

Words of wisdom


Transport Delay – Intended to model wiring delay. Simply delays the signal by specified delay time.

Words of wisdom


If a signal is updated with the same value it had in the previous simulation cycle, then it does not change, and therefore does not trigger processes to resume.

Words of wisdom


Combinational for-loops are usually synthesizable. They are often used to build a combinatorial circuit for each element of an array.

Words of wisdom


Clocked for-loops are not synthesizable, but are very useful in simulation, particularly to generate test vectors for test benches.

Words of wisdom


The phrases "behavioural model" and "structural model" are commonly used for "high-level models" and "synthesizable models". In most cases, what people call structural code contains both structural and behavioural code. The technically correct definition of a structural model is an HDL program that contains only component instantiations and generate statements.

Words of wisdom


Postponed in VHDL terminology is a synonym for some operating systems usage of ready, to describe a process that is ready to execute.

Words of wisdom


Clocked processes are sometimes called sequential processes. they should not be confused with sequential statements.

VITAL and its Origins!


Verilog started out as a proprietary simulator in 1984 and enjoyed considerable success due to its C like syntax. In 1990, Cadence Design Systems made the language public. It became an IEEE standard in 1995. VHDL was developed under contract to the U.S. Department of Defense. It became an IEEE standard in 1987. VHDL has its roots in Ada.

For many years there was intense competition between Verilog and VHDL for mind share and market share. Both languages have their strong points. In the end, most EDA companies came out with simulators that work with both. Early in the language wars it was noted that Verilog had a number of built-in, gate-level primitives. Over the years these had been optimized for performance by Cadence and later by other Verilog vendors. Verilog also had a single defined method of reading timing into a simulation from an external file. VHDL, on the other hand, was designed for a higher level of abstraction. Although it could model almost anything Verilog could, and without primitives, it allowed things to be modeled in a multitude of ways. This made performance optimization or acceleration impractical. VHDL was not successfully competing with Verilog as a sign-off ASIC language. The EDA companies backing VHDL saw they had to do something. The something was named VITAL, the VHDL Initiative toward ASIC Libraries.

The intent of VITAL was to provide a set of standard practices for modeling ASIC primitives, or macrocells, in VHDL and in the process make acceleration possible. Two VHDL packages were written: a primitives package and a timing package. The primitives package modeled all the gate-level primitives found in Verilog.

Because these primitives were now in a standard package known to the simulator writers, they could be optimized by the VHDL compilers for faster simulation. The timing package provided a standard, acceleratable set of procedures for checking timing constraints, such as setup and hold, as well as pin-to-pin propagation delays. The committee writing the VITAL packages had the wisdom to avoid reinventing the wheel. They chose the same SDF file format as Verilog for storing and annotating timing values.

SDF is the Standard Delay Format, IEEE Standard 1497. It is a textual file format for timing and delay information for digital electronic designs. It is used to convey timing and delay values into both VHDL and Verilog simulations. Another stated goal of VITAL is model maintainability. It restricts the writer to a subset of the VHDL language and demands consistent use of provided libraries. This encourages uniformity among models, making them easily readable by anyone familiar with VITAL. Readability and having the difficult code placed in a provided library greatly facilitate the maintenance of models by engineers who are not the original authors.

VITAL became IEEE Standard 1076.4 in 1995. It was reballoted in 2000. The 2000 revision offers several enhancements. These include support for multisource interconnect timing, fast path delay disable, and skew constraint timing checks. However, the most important new feature is the addition of a new package to support the modeling of static RAMs and ROMs.

Author: Keshav K, MindTree, Bangalore, India

HDL Coding Guidelines - Part 7


Hints
  1. Avoid more package references than needed
  2. Keep all objects and subprograms in the nearest possible scope
  3. Keep local objects invisible outside a package
  4. Transfer stable component declarations into components packages
  5. Re-use functionality of standard packages as much as possible
  6. Size of VHDL Units should be reasonable for synthesis
  7. A VHDL unit should not exceed 500 lines of code
  8. A process or subprogram should not exceed 100 lines of code
  9. Component instantiations should not exceed 4 levels of hierarchy
  10. An architecture should not contain more than 10 processes
  11. Structural and behavioral code should not be mixed
  12. Define project packages early in the project
  13. Hide old VHDL files
  14. Follow Naming conventions for VHDL units
  15. Follow Naming conventions for VHDL files
  16. Follow Naming conventions for VHDL objects
  17. Choose short instance names
  18. Keyword casing should be uniform in all VHDL code
  19. Use an intermediate signal for reading from an output port
  20. Self-defined conversion functions must assert un-mappable input values
  21. Use complex data types inside architectures
  22. Use a small number of self-defined global data types
  23. Insert test-enable for scan-test
  24. Use vector operations instead of loops
  25. Avoid unnecessary repetition of function calls
  26. Use efficient description for the wrap around of counters
  27. Build interface consistency checks into the model
  28. For soft-core development use generics, do not use constants
  29. A testbench has neither ports nor generics
  30. Variables of access types should be modified only in procedures defined in packages
  31. Use abstract, compact coding style in testbench and simulation models
  32. In case of accelerated simulation or emulation, the testbench must be synthesizable
  33. Stop the simulation from within the testbench
  34. Use assertion messages extensively
  35. Check the success of a read operation
  36. Use std.textio only, where really necessary
  37. Store file data to a VHDL variable, if read multiple times
  38. In association lists of subprogram calls use named association
  39. Indentation should be consistent in all VHDL code
  40. Align comments vertically
  41. Align declaration lists vertically
  42. Align association lists vertically
  43. Use closing labels for entity, architecture, process, loop, generate, etc.
  44. Indicate condition at remote ends of control structures (if ... then, case)
  45. Use one statement per line
  46. Group related constructs
  47. Group related port or signal declarations
  48. Switch constructs should not be nested to more than 4 levels
  49. Remove unnecessary code fragments
  50. Order of items should be the same in package header and body
  51. Use predefined attributes to make code generic and more re-usable
  52. Do not have code that have been commented out in checked-in versions
  53. Carefully use real values with PN-generators
  54. Be aware of operating-system-specific features
  55. Take care of array widths for std_logic_arith operators
  56. Use conversion functions around arithmetic operators
  57. Requirements for resource sharing
  58. EMC and transmission line effects need not be modeled
  59. Minimize the number of processes, signals, and signal assignments
  60. Replace signals by variables whenever possible
  61. Inhibit execution of statements where not necessary
  62. Divide large memories into blocks
  63. Avoid declaring constants within subprograms
  64. Always use deallocate(access_obj) to dereference allocated memory
  65. Use only well tested functions for object-initialization purposes
  66. Be aware of the use of the attributes DELAYED, STABLE, QUIET, and TRANSACTION

HDL Coding Guidelines - Part 6


To Avoid common Warnings
  1. Store each VHDL unit into a separate file except package header and body
  2. Signal assignments for renaming purposes should be avoided
  3. The names of clocks and resets should be unique in the whole design
  4. Soft macros: Data types at ports: std_(u)logic(_vector)
  5. Avoid custom data types (e.g., multidimensional arrays, records, enumeration types)
  6. Avoid gated clocks unless absolutely necessary
  7. Avoid latches unless absolutely necessary
  8. All outputs of synchronous modules should be registered
  9. Process only one clock in RTL-units
  10. Do not use the value of type’left for initializing of a signal or variable during reset
  11. Avoid unused ports, busses must be split accordingly
  12. Avoid homographs
  13. Do not define a subprogram for a subtype only
  14. Comment each process, each subprogram and global aspects
  15. Processes should be labeled
  16. Aliases are not recommended
  17. Bussed ports of width one are forbidden
  18. Use case-statements instead of if-statements when the conditions are mutually exclusive
  19. All signals and variables should be read at least once
  20. Static ports should not exist
  21. Use a separate library clause for each declared resource library
  22. Use a separate use clause for each declared package
  23. Maximum line-length is 100 characters
  24. Order of ports in entity, component and instance should be the same
  25. Do not have unused signals
  26. Minimize the number of signals of your sensitivity list
  27. Avoid unnecessary computations within loops
  28. Use sensitivity lists instead of wait statements
  29. Subprograms may not have any side effects

HDL Coding Guidelines - Part 5


Critical Policies to Keep note!
  1. Balance clock to delta accuracy
  2. Pull-ups and pull-downs have to be modeled on chip level
  3. Communication between modules using text-IO is forbidden
  4. No characters with a lower rank than space may occur in text-IO
  5. Testbench and DUT should be compiled into the same library
  6. Asynchronous parts should be placed into separate entities
  7. VHDL units should take into account later floorplanning
  8. A FSM must be described in a separate entity/architecture pair
  9. Only verified VHDL code allowed for check-in
  10. Identifier naming must be based on English language
  11. Use meaningful identifier names
  12. Separate identifier components using underscores
  13. Instantiate the power pads for each power domain
  14. Gate instantiation must be encapsulated by separate unit
  15. Spend extensive efforts for documentation of interfaces
  16. Request external VHDL code suppliers to deliver used arithmetic packages
  17. Spacer cells needed between pads
  18. Signals that cross clock domains must be synchronized by synchronization cells
  19. Language for comments and code documentation is English
  20. Comments should be related to the lines of code below

HDL Coding Guidelines - Part 4


To Avoid common Errors
  1. A configuration declaration is needed for each architecture in the design
  2. Design-internal references must use library work
  3. Use selected names in binding indications and ’use’ clauses only
  4. Configuration must be in a separated file except the latest level of hierarchy
  5. All primary unit names must be unique in the project library
  6. Identifier casing should be uniform in all VHDL code
  7. Length of entity names should not exceed 32 characters
  8. An instance name must not contain the substring ’pfiller’
  9. Use unresolved data types if possible
  10. Hard/firm macros: Data types at ports: std_(u)logic(_vector)
  11. Generics must have type integer for synthesis
  12. Avoid feedthroughs
  13. Strength stripping should be performed on chip level
  14. Do not assign the value 'X'
  15. Asynchronous reset is mandatory for sequential processes
  16. Do not use internal three-state busses
  17. Use the predefined templates for component instantiation
  18. Refer to one edge of clock, only
  19. Do not use combinational feedback loops
  20. Global signals may be used for testing purposes only
  21. Use relative path names for files accessed through text-IO
  22. Binary file-IO may not be used
  23. In association lists of generic maps and port maps use named association
  24. VHDL-93 keywords should not be used
  25. Verilog keywords should not be used
  26. SDF keywords should not be used
  27. IKOS keywords should not be used
  28. Allowable replacement characters are forbidden
  29. Tool specific types may not be used
  30. Configuration declarations must have the configuration name and the entity name in one line for vimport
  31. Never redefine standard operators, subprograms, attributes, and packages
  32. Language for modeling is VHDL-87
  33. Comparison of arrays must be based on arrays of the same width
  34. Bussed arithmetic objects use "downto" as their index orientation
  35. Store package header and body into same file
  36. Default values for ports, signals, and variables may not be used
  37. Data types must be synthesizable
  38. Array ranges must be of type integer
  39. Integer type objects must be constrained with respect to to their range
  40. Use standard templates for clocked processes
  41. Generics must have type integer
  42. Order of generics in entity, component and instance must be the same
  43. Place port and generic maps at the component instantiation
  44. Instantiated component and entity name must be equal, incl. casing
  45. The sensitivity list for combinational processes must be complete
  46. Write variables before read in combinational logic
  47. Bit-wise association of arrays in port maps is not possible in presence of generics
  48. Embedding scripts as meta comments is not acceptable
  49. Use only standard meta comments
  50. Code for synthesis must match the synthesis subset
  51. Do not use disconnect, register, and bus
  52. Do not use port modes buffer and linkage
  53. Do not use configuration specification (“hard binding”)
  54. Do not use blocks
  55. Avoid identifier hiding caused by loop index
  56. Recursive use of subprograms is forbidden
  57. Do not use guarded signals, guarded assignments, and guarded expressions
  58. Trailing comments are only allowed for declarative lists

HDL Coding Guidelines - Part 3


Portability
  1. Language for modeling should be VHDL-87
  2. VHDL-93 keywords should not be used
  3. Verilog keywords should not be used
  4. SDF keywords should not be used
  5. IKOS keywords should not be used
  6. Allowable replacement characters are forbidden
  7. Tool specific types may not be used
  8. Configuration declarations must have the configuration name and the entity name in one line
  9. Never redefine standard operators, subprograms, attributes, and packages
  10. Design-internal references must use library work
  11. Bussed ports of width one are forbidden
  12. Carefully use real values with PN-generators
  13. Be aware of operating-system-specific features
Arithmetic
  1. Bussed arithmetic objects use "downto" as their index orientation
  2. Comparison of arrays must be based on arrays of the same width
  3. Request external VHDL code suppliers to deliver used arithmetic packages
  4. Avoid homographs
  5. Where to use ieee.std_logic_arith and std_developerskit.synth_regpak
  6. Where to use std_logic_signed and std_logic_unsigned
  7. Take care of array widths for std_logic_arith operators
  8. Use conversion functions around arithmetic operators
Synthesizability
Note that the restrictions listed below do not apply to pure simulation models and not to testbench models.
  1. Code for synthesis must match the synthesis subset
  2. Store package header and body into same file
  3. Default values for ports, signals, and variables may not be used
  4. Data types must be synthesizable
  5. Array ranges must be of type integer
  6. Integer type objects must be constrained with respect to to their range
  7. Use standard templates for clocked processes
  8. Generics must have type integer
  9. Order of generics in entity, component and instance must be the same
  10. Place port and generic maps at the component instantiation
  11. Instantiated component and entity name must be equal, incl. casing
  12. The sensitivity list for combinational processes must be complete
  13. Write variables before read in combinational logic
  14. Bit-wise association of arrays in port maps is not possible in presence of generics
  15. Embedding scripts as meta comments is not acceptable
  16. Use only standard meta comments
  17. Gate instantiation must be encapsulated by separate unit
  18. Requirements for resource sharing
Simulation Performance
  1. Use sensitivity lists instead of wait statements
  2. Minimize the number of signals of your sensitivity list
  3. Avoid unnecessary computations within loops
  4. Remove unnecessary code fragments
  5. EMC and transmission line effects need not be modeled
  6. Use abstract, compact coding style in testbench and simulation models
  7. Minimize the number of processes, signals, and signal assignments
  8. Replace signals by variables whenever possible
  9. Inhibit execution of statements where not necessary
  10. Divide large memories into blocks
  11. Avoid unnecessary repetition of function calls
  12. Avoid declaring constants within subprograms
  13. Always use deallocate(access_obj) to dereference allocated memory
Critical Constructs
  1. Do not use guarded signals, guarded assignments, and guarded expressions
  2. Do not use disconnect, register, and bus
  3. Do not use configuration specification (“hard binding”)
  4. Do not use port modes buffer and linkage
  5. Do not use blocks
  6. Avoid identifier hiding caused by loop index
  7. Global signals may be used for testing purposes only
  8. Recursive use of subprograms is forbidden
  9. Subprograms may not have any side effects
  10. Use only well tested functions for object-initialization purposes
  11. Be aware of the use of the attributes DELAYED, STABLE, QUIET, and TRANSACTION

HDL Coding Guidelines - Part 2


When Compiling (VHDL):
  1. A configuration declaration is needed for each architecture in the design
  2. Design-internal references must use library work
  3. Use selected names in binding indications and ’use’ clauses only
  4. Testbench and DUT should be compiled into the same library
  5. Avoid more package references than needed
Partitioning VHDL Code
  1. VHDL units should take into account later floorplanning
  2. Asynchronous parts should be placed into separate entities
  3. Keep all objects and subprograms in the nearest possible scope
  4. Keep local objects invisible outside a package
  5. Transfer stable component declarations into components packages
  6. Re-use functionality of standard packages as much as possible
  7. Size of VHDL Units should be reasonable for synthesis
  8. A VHDL unit should not exceed 500 lines of code
  9. A process or subprogram should not exceed 100 lines of code
  10. Component instantiations should not exceed 4 levels of hierarchy
  11. An architecture should not contain more than 10 processes
  12. Structural and behavioral code should not be mixed
  13. Define project packages early in the project
Storing VHDL Code
  1. Configuration must be in a separated file except the latest level of hierarchy
  2. Only verified VHDL code allowed for check-in
  3. Store each VHDL unit into a separate file except package header and body
  4. Hide old VHDL files
Naming Conventions
  1. All primary unit names must be unique in the project library
  2. Identifier casing should be uniform in all VHDL code
  3. Length of entity names should not exceed 32 characters
  4. An instance name must not contain the substring ’pfiller’
  5. An instance name must not start with bondpad
  6. Identifier naming must be based on English language
  7. Use meaningful identifier names
  8. Separate identifier components using underscores
  9. Signal assignments for renaming purposes should be avoided
  10. The names of clocks and resets should be unique in the whole design
  11. Naming conventions for VHDL units
  12. Naming conventions for VHDL files
  13. Naming conventions for VHDL objects
  14. Choose short instance names
  15. Keyword casing should be uniform in all VHDL code
  16. Use standard top-levels xmpl, xmpl_top, and xmpl_chip
  17. Use an intermediate signal for reading from an output port
  18. Example for unit and file naming conventions
  19. Abbreviations for naming conventions
Data-Types
  1. Use unresolved data types if possible
  2. Hard/firm macros: Data types at ports: std_(u)logic(_vector)
  3. Generics must have type integer for synthesis
  4. Soft macros: Data types at ports: std_(u)logic(_vector)
  5. Avoid custom data types (e.g., multidimensional arrays, records, enumeration types)
  6. Self-defined conversion functions must assert un-mappable input values
  7. Use complex data types inside architectures
  8. Use a small number of self-defined global data types
Design Rules
  1. Asynchronous reset is mandatory for sequential processes
  2. Do not use internal three-state busses
  3. Use the predefined templates for component instantiation
  4. Refer to one edge of clock, only
  5. Do not use combinational feedback loops
  6. Avoid feedthroughs
  7. Strength stripping should be performed on chip level
  8. Do not assign the value 'X'
  9. Balance clock to delta accuracy
  10. Pull-ups and pull-downs have to be modeled on chip level
  11. Gate instantiation must be encapsulated by separate unit
  12. A FSM must be described in a separate entity/architecture pair
  13. Instantiate the power pads for each power domain
  14. Spend extensive efforts for documentation of interfaces
  15. Spacer cells needed between pads
  16. Signals that cross clock domains must be synchronized by synchronization cells
  17. Avoid gated clocks unless absolutely necessary
  18. Avoid latches unless absolutely necessary
  19. All outputs of synchronous modules should be registered
  20. Process only one clock in RTL-units
  21. Do not use the value of type’left for initializing of a signal or variable during reset
  22. Avoid unused ports, busses must be split accordingly
  23. Use case-statements instead of if-statements when the conditions are mutually exclusive
  24. All signals and variables should be read at least once
  25. Static ports should not exist
  26. Avoid unnecessary computations within loops
  27. Insert test-enable for scan-test
  28. Use vector operations instead of loops
  29. Avoid unnecessary repetition of function calls
  30. Use efficient description for the wrap around of counters
  31. Build interface consistency checks into the model
  32. For soft-core development use generics, do not use constants
Testbenches
  1. Global signals may be used for testing purposes only
  2. Variables of access types should be modified only in procedures defined in packages
  3. A testbench has neither ports nor generics
  4. Use abstract, compact coding style in testbench and simulation models
  5. In case of accelerated simulation or emulation, the testbench must be synthesizable
  6. Stop the simulation from within the testbench
  7. Use assertion messages extensively
Text-IO
  1. Binary file-IO may not be used
  2. Use relative path names for files accessed through text-IO
  3. Communication between modules using text-IO is forbidden
  4. No characters with a lower rank than space may occur in text-IO
  5. Check the success of a read operation
  6. Use std.textio only, where really necessary
  7. Store file data to a VHDL variable, if read multiple times
Readability
  1. In association lists of generic maps and port maps use named association
  2. Language for comments and code documentation is English
  3. Comments should be related to the lines of code below
  4. Trailing comments are only allowed for declarative lists
  5. Comment each process, each subprogram and global aspects
  6. Processes should be labeled
  7. Aliases are not recommended
  8. Do not define a subprogram for a subtype only
  9. The names of clocks and resets should be unique in the whole design
  10. Use a separate library clause for each declared resource library
  11. Use a separate use clause for each declared package
  12. Maximum line-length is 100 characters
  13. Order of ports in entity, component and instance should be the same
  14. Do not have unused signals
  15. In association lists of subprogram calls use named association
  16. Indentation should be consistent in all VHDL code
  17. Align comments vertically
  18. Align declaration lists vertically
  19. Align association lists vertically
  20. Use closing labels for entity, architecture, process, loop, generate, etc.
  21. Indicate condition at remote ends of control structures (if ... then, case)
  22. Use one statement per line
  23. Group related constructs
  24. Group related port or signal declarations
  25. Switch constructs should not be nested to more than 4 levels
  26. Remove unnecessary code fragments
  27. Order of items should be the same in package header and body
  28. Use predefined attributes to make code generic and more re-usable
  29. Do not have code that have been commented out in checked-in versions

HDL Coding Guidelines - Part 1


Coding of circuit behavior and architecture is one of the most critical steps in the whole chip development project. It has a major impact on logic synthesis, routing results, timing robustness, verifiability and testability.

The HDL Coding Guidelines help chip and macro developers/teams to rapidly understand each other's code. Macro based designs integrate easier if these common coding styles are followed. This also applies to externally developed softcores. Codes will not need modification if simulator, synthesis tool, or technology is exchanged. Code invariants with respect to Synthesis tool is given in case of a similar HDL synthesis subset. Code invariants with respect to technology is given in case of similar performance and cell set. In addition, the given guidelines enable high synthesis quality and simulation performance.

The HDL Coding Guidelines need continuous adaptation according to new tool properties and new upcoming methodologies. Please participate in this process with your design know-how. Contribute rules for HDL coding that turned out to prevent errors in the downstream flow, or recommendations that alleviate further design, re-use or maintenance.

The HDL Coding Guidelines may be passed to sub-contractors or cooperation partners. Ideally their coding works should comply to these guidelines, enabling rapid and safe integration with internally developed modules.

Reading of the HDL Coding Guidelines is most efficient at the beginning of a chip-design-project. Furthermore a code review should be considered in a very early phase of HDL coding.

VHDL Interview Question(s)


  1. What are the two key concepts in the simulation semantics of VHDL and how does each concept help VHDL simulation produce waveforms that match the behaviour that we expect?
  2. What is the advantage of RTL simulation in comparison to simulation as defined by the VHDL standard?
  3. What is the disadvantage of RTL simulation in comparison to simulation as defined by the VHDL standard?
  4. For each of the architectures muruku 1. . . muruku 4, answer the following questions.
    • INSTRUCTIONS:
      1. Is the code legal VHDL?
      2. If the code is legal VHDL:
        • Answer whether the behaviour of the signal z has the same behaviour as in the main architecture of sumit.
        • Answer whether the code is synthesizable.
        • If the code is synthesizable, answer whether it adheres to good coding practices.
If the the code is not legal, not synthesizable, or does not follow good coding practices, explain why.

entity sumit is
port (
a, b, clk : in std_logic;
z : out std_logic
);
end sumit;

architecture main of sumit is
signal m : std_logic;
begin
process ( clk )
begin
if rising_edge( clk ) then
m <= a or b; end if; end process; process ( clk ) begin if rising_edge( clk ) then z <= not m; end if; end process; end main;
  1. Muruku 1
    • architecture muruku_1 of sumit is
      signal m : std_logic;
      begin
      process ( clk )
      begin
      if rising_edge( clk ) then
      m <= a or b; z <= not m; end if; end process; end muruku_1;
  2. Muruku_X
    • architecture muruku_X of sumit is
      signal m, p : std_logic;
      begin
      process ( clk )
      begin
      if rising_edge( clk ) then
      m <= a or b; end if; end process; process ( clk ) begin if rising_edge( clk ) then z <= p; end if; end process; p <= not m; end muruku_X;
  3. Muruku_2
    • architecture muruku_2 of sumit is
      signal m, p : std_logic;
      begin
      if (a or b) = ’1’ generate
      m <= ’1’; end generate; if (a or b) = ’0’ generate m <= ’0’; end generate; process ( clk ) begin if rising_edge( clk ) then p <= m; end if; end process; process ( clk ) begin if rising_edge( clk ) then z <= not p; end if; end process; end muruku_2;
  4. Muruku_3
    • architecture muruku_3 of sumit is
      begin
      process
      begin
      wait until rising_edge(clk);
      wait until rising_edge(clk);
      z <= not (a or b); end process; end muruku_3;
  5. Muruku_4
    • architecture muruku_4 of sumit is
      signal m, p : std_logic;
      begin
      process ( clk )
      begin
      if rising_edge( clk ) then
      m <= a or b; end if; end process; process ( clk ) begin if rising_edge( clk ) then p <= m; end if; end process; z <= not p; end muruku_4;
Difficulty: Medium