DO-254 Users Group
DO-254 Users Group
Position Paper
Position Paper
DO254-UG-001
DO254-UG-001
Best Practice VHDL Coding Standards for
Best Practice VHDL Coding Standards for DO-254
DO-254
Programs
Programs
COMPLETED 2/26/10
COMPLETED 2/26/10
(MODIFIED 9/13/10)
(MODIFIED 9/13/10)
(Rev 1a)
(Rev 1a)
Team
Team Primary
Primary Author:
Author: Michelle
Michelle Lange
Lange
NOTE:
NOTE: This position paper has been coordinatedThis position paper has been coordinated among representatives from the Europe and US among representatives from the Europe and US DO-254
254 users users groups. groups. This This document document is is provided forprovided for educational and informational purposes only and educational and informational purposes only and should be discussed with the appropriate certification should be discussed with the appropriate certification authority when
authority when considering actual considering actual projects. projects. ThisThis
position paper does not represent an official position of position paper does not represent an official position of the EASA, FAA or Eurocae/RTCA related committees. the EASA, FAA or Eurocae/RTCA related committees.
Contents
Contents
1.0
1.0 PURPOSE PURPOSE ... 2222
2.0
2.0 BACKGROBACKGROUND UND ... 2222
3.0
3.0 REFEREREFERENCES NCES ... 3333
4.0
4.0 TERMINOLTERMINOLOGY OGY ... 3333
5.0
5.0 INTRODUINTRODUCTION CTION ... 3333
6.0
6.0 SUGGESTESUGGESTED D CODING CODING STANDARSTANDARDS DS (RULES) ...(RULES) ... 4444
Category
Category: Coding : Coding Practices (CP) Practices (CP) ...4444
Category
Category: Clock Domain : Clock Domain Crossing (CDC) ...Crossing (CDC) ... 14141414
Category
Category: Safe S: Safe Syntheynthesis (SS) ...sis (SS) ... ...15151515
Category
Category: Design Reviews (DR) ...: Design Reviews (DR) ... ...28282828
7.0 BEST PRACTICE USA
7.0 BEST PRACTICE USAGE OF AUTOMATED HDL STANDARDS CHGE OF AUTOMATED HDL STANDARDS CHECKING ECKING ... 33333333
Benefits of
Benefits of Automated Checking Automated Checking ...33333333
Use Model for Automated HDL Code Checking ... Use Model for Automated HDL Code Checking ... 34343434
Considera
Considerations for Tool Assessment ...tions for Tool Assessment ... ... 35353535
8.0 THE “DO-254” RULESET IN MENTOR GRAPHICS HDL DESIGNER TOOL ... 8.0 THE “DO-254” RULESET IN MENTOR GRAPHICS HDL DESIGNER TOOL ... 36363636
9.0
Contents
Contents
1.0
1.0 PURPOSE PURPOSE ... 2222
2.0
2.0 BACKGROBACKGROUND UND ... 2222
3.0
3.0 REFEREREFERENCES NCES ... 3333
4.0
4.0 TERMINOLTERMINOLOGY OGY ... 3333
5.0
5.0 INTRODUINTRODUCTION CTION ... 3333
6.0
6.0 SUGGESTESUGGESTED D CODING CODING STANDARSTANDARDS DS (RULES) ...(RULES) ... 4444
Category
Category: Coding : Coding Practices (CP) Practices (CP) ...4444
Category
Category: Clock Domain : Clock Domain Crossing (CDC) ...Crossing (CDC) ... 14141414
Category
Category: Safe S: Safe Syntheynthesis (SS) ...sis (SS) ... ...15151515
Category
Category: Design Reviews (DR) ...: Design Reviews (DR) ... ...28282828
7.0 BEST PRACTICE USA
7.0 BEST PRACTICE USAGE OF AUTOMATED HDL STANDARDS CHGE OF AUTOMATED HDL STANDARDS CHECKING ECKING ... 33333333
Benefits of
Benefits of Automated Checking Automated Checking ...33333333
Use Model for Automated HDL Code Checking ... Use Model for Automated HDL Code Checking ... 34343434
Considera
Considerations for Tool Assessment ...tions for Tool Assessment ... ... 35353535
8.0 THE “DO-254” RULESET IN MENTOR GRAPHICS HDL DESIGNER TOOL ... 8.0 THE “DO-254” RULESET IN MENTOR GRAPHICS HDL DESIGNER TOOL ... 36363636
9.0
Best Practice VHDL Coding
Best Practice VHDL Coding
Standards for DO-254 Programs
Standards for DO-254 Programs
1.0 Purpose 1.0 Purpose
DO-254 discusses the need for “Design Standards” and FAA Order 8110.105 takes this a DO-254 discusses the need for “Design Standards” and FAA Order 8110.105 takes this a step further, discussing the specific need for HDL coding standards. Many companies step further, discussing the specific need for HDL coding standards. Many companies having to comply with DO-254 are either looking for examples of good standards, or having to comply with DO-254 are either looking for examples of good standards, or have insufficient or inconsistent standards. This paper provides a list of generally have insufficient or inconsistent standards. This paper provides a list of generally
accepted HDL (specifically VHDL) design best practice coding guidelines that should be accepted HDL (specifically VHDL) design best practice coding guidelines that should be considered for a fail-safe design, including DO-254 programs.
considered for a fail-safe design, including DO-254 programs.
These coding guidelines should not be viewed as what must be done in a DO-254 These coding guidelines should not be viewed as what must be done in a DO-254 program.
program. What must be done What must be done is always the decision of is always the decision of the applicant in conjunction withthe applicant in conjunction with the certification authority. However, if a project team is looking for a good foundational the certification authority. However, if a project team is looking for a good foundational set of checks to assess the HDL design quality for their DO-254 program, this document set of checks to assess the HDL design quality for their DO-254 program, this document provides that foundation. The standards or checks presented in this document serve one provides that foundation. The standards or checks presented in this document serve one of three purposes, specifically: 1) Catching potential design problems in HDL code that of three purposes, specifically: 1) Catching potential design problems in HDL code that may not normally surface until later in the process and may not be caught by other may not normally surface until later in the process and may not be caught by other verification activities, 2) Supporting error detection, containment and recovery verification activities, 2) Supporting error detection, containment and recovery mechanisms, and 3) Enforcing style and readability practices to improve code mechanisms, and 3) Enforcing style and readability practices to improve code comprehension, portability, and reviews.
comprehension, portability, and reviews.
In DO-254 programs, HDL coding standards must be documented, and any project code In DO-254 programs, HDL coding standards must be documented, and any project code must be reviewed to ensure it follows these standards. While reviews can be done
must be reviewed to ensure it follows these standards. While reviews can be done manually, an automated approach (when possible) guarantees a more consistent HDL manually, an automated approach (when possible) guarantees a more consistent HDL code quality assessment. Automating the HDL code assessment process, often called code quality assessment. Automating the HDL code assessment process, often called
linting
linting, has the added benefit of promoting regular HDL design checking steps, has the added benefit of promoting regular HDL design checking steps throughout the design development process, as opposed to waiting for gating design throughout the design development process, as opposed to waiting for gating design reviews where issues can be overwhelming and more costly to address. This paper also reviews where issues can be overwhelming and more costly to address. This paper also discusses automation when appropriate, and states that a combination of automation and discusses automation when appropriate, and states that a combination of automation and manual reviews can lead to best results.
manual reviews can lead to best results.
2.0 Background 2.0 Background
FAA Order 8110.105 section 6-2a clarified that HDL coding standards should be defined FAA Order 8110.105 section 6-2a clarified that HDL coding standards should be defined and checked when it stated:
and checked when it stated:
“To prevent potentially unsafe attributes of HDLs from leading to unsafe features of the “To prevent potentially unsafe attributes of HDLs from leading to unsafe features of the components, we must expect that, if they
components, we must expect that, if they use an HDL, applicants define the codinguse an HDL, applicants define the coding standards for this language consistent with the
standards for this language consistent with the system safety objectives, and establishsystem safety objectives, and establish conformance to those standards by HDL code reviews.”
conformance to those standards by HDL code reviews.”
In the EASA context, guidance for the use of HDL is also required, and conformance to those In the EASA context, guidance for the use of HDL is also required, and conformance to those standards should be established.
This has led many applicants to ask for a good set of HDL coding standards. This paper presents a foundational set of checks that an applicant may use if they do not already have a good set of standards in-house.
3.0 References
a. RTCA/DO-254 (EUROCAE ED-80), Design Assurance Guidance For Airborne Electronic Hardware;
b. FAA AC 20-152, RTCA, Inc., Document RTCA/DO-254
c. FAA Order 8110.105
d. EASA Certification Memos and CRIs on recent programs (non public material)
4.0 Terminology
For this paper, the following terminology applies:
HDL – Hardware Description Language. An HDL is any language from a class of computer languages and/or programming languages for formal description of electronic circuits, and more specifically, digital logic. It can describe the circuit's operation, its design and organization, and tests to verify its operation by means of simulation. Note that the coding standards shown in this document apply to HDL for use as a design language, not necessarily for verification testbenches. RTL – Register Transfer Level. In integrated circuit design, register transfer level (RTL) description is a way of describing the operation of a synchronous digital circuit. In RTL design, a circuit's behavior is defined in terms of the flow of signals (or transfer of data) between hardware registers, and the logical operations performed on those signals. Register transfer level abstraction is the level of design representation in which hardware description languages (HDLs) like
Verilog and VHDL are used to define the circuit, from which technology specific implementations can be derived.
VHDL – VHSIC Hardware Description Language; where VHSIC stands for “very-high-speed integrated circuit.” VHDL is a hardware description language used in electronic design automation to describe digital and mixed-signal systems such as Field-Programmable Gate Arrays (FPGAs) and Application Specific Integrated Circuits (ASICs).
5.0 Introduction
HDL languages, such as VHDL, are very flexible. They allow extensive flexibility and creativity in coding. The flexibility of the language can lead to downstream problems and in-hardware design errors that cannot only be very hard to debug but also pose potential threats to safety. By developing and following a good set of HDL coding standards,
many potential problems can be caught early and addressed before they turn into bugs in a physical implementation.
This paper presents a set of standards that have been developed from the input of many companies doing safety-critical design and also the input of 20 individuals participating in both the US and EU DO-254 User Groups. From this collective experience and input, this paper provides a foundational set of standards that could be considered best practice coding guidelines for the VHDL language.
6.0 Suggested Coding Standards (Rules)
The following coding standards are suggested for VHDL synthesizable code for DO-254 projects. While the guidance of FAA Order 8110.105 states that HDL coding standards are required for DAL A/B devices, following these standards in general for all designs would be considered a best practice.
Each coding standard listed hereafter falls under one of four categories. These categories are arbitrarily named, but each category serves a distinct purpose as described. The
categories are 1) Coding Practices, 2) Clock Domain Crossings, 3) Safe Synthesis, and 4) Code Reviews.
Each coding standard has a default severity level of Error, Warning, or Note, which provides a measure of the worst case impact a standard violation can have on safety. In general, errors should always be corrected, warnings should usually be corrected but may have documented and justified exceptions, and notes should simply be examined to
ensure there is no impact on safe design operation.
The standards and severity levels are potentially editable by the project team, depending on the design assurance level assigned to the design as well as the project team’s own coding style and preferences.
Note that in some cases, ensuring good HDL coding practice is only half of the solution. The other half lies with setting up the synthesis tool properly to ensure the intent of the HDL is properly synthesized. For example, both case statements and finite state machines are prone to undesired synthesis optimizations, even if properly
coded in HDL. These concerns are explained, where appropriate, in the coding rules descriptions that follow.
Category: Coding Practices (CP)
This category of standards ensures that a coding style supporting safety-critical and good digital design practices are used. Each rule that follows is given a coding practice (CP) number for ease of reference.
1. Avoid Incorrect VHDL Type Usage (CP1)
Check for the incorrect use of types, incompatible bounds, and/or constraints.
While these types of issues are usually caught during compilation, it is beneficial to correct the problem as early as possible.
Default severity: Error Example:
ENTITY top IS port (rf2fe_vec: IN dword); ARCHITECTURE rtl OF top IS
signal tx_index: std_logic_vector (14 DOWNTO 0); ….
tx_index <= rf2fe_vec (f_txindex_hi DOWNTO f_txindex_lo); -- Type error at ‘rf2fe_vec’. Needed type ‘std_logic_vector’ END rtl;
2. Avoid Duplicate Signal Assignments (CP2)
The same signal should not be assigned a value more than once within the same statement region.
A violation leads to a potential conflict on the signal assignment, and this may or may not be flagged by the synthesis tool. An assignment is considered duplicated if its left hand side exists more than once in the same statement region in the same process that is being checked. Default assignments (one occurrence) should be acceptable as indicated in the example below. This check ensures the designer will be warned consistently during HDL design development, as opposed to waiting until synthesis, which could have different results across different synthesis tools. It will also ensure implementation of a more portable design IP review process.
Default severity: Warning Example:
same_signal <= '0'; -- Default assignment IF (reset = '1') THEN
same_signal <= '1'; -- This is NOT a duplicate assignment. END IF;
IF (reset = '1') THEN -- Default Reset Values beep <= '0';
-- more lines
beep <= '1'; -- Duplicate assignment maybe a mistake ELSIF (falling_edge(clk)) THEN
3. Avoid Hard-Coded Numeric Values (CP3)
used.
Constants or generics should be used and documented within the design. This will greatly reduce the probability of a design error from creeping into the design code as it is being ported to a new application.
Default severity: Warning Example:
PACKAGE dcc_pkg is
--- constant declarations
---CONSTANT CPU_ADR_WIDTH : INTEGER := 16; -- cpu address bus width CONSTANT CPU_DATA_WIDTH : INTEGER := 32; -- cpu data bus width . . .
ENTITY dual_clock_cache_struct is PORT(
cpu_addr : IN std_logic_vector( 15 DOWNTO 0 ); -- violation
cpu_di : IN std_logic_vector(CPU_DATA_WI DTH-1 DOWNTO 0); --32-bit cpu_clk : IN std_logic;
4. Avoid Hard-Coded Vector Assignment (CP4)
For vector reset assignments; do not use hard-coded values.
The reset assignment should be done in a way that is independent of the size of the vector. This limits the impact of changing vector sizes and enhances design
portability ease.
Default severity: Note Example:
WHEN OTHERS =>
clk_div_en <= '0'; xmitdt_en <= '0';
ser_if_select <= "00000000"; -- Violation
ser_in_select <= (OTHERS => ‘0’); -- This is preferred
5. Ensure Consistent FSM State Encoding Style (CP5)
a. A design should employ a consistent state encoding style for Finite State Machines (FSM).
Inconsistent FSM encoding style may interfere with the design’s FSM error detection and recovery scheme for the operating environment. Enumerated state types make HDL code more readable generally. Enumerated types facilitate more flexibility in the synthesis implementation as users can select the encoding style used (one-hot, gray, binary etc.) without modifying the HDL code. These aspects support greater design portability and insure FSM error detection and recovery.
Note that in general, care must be taken in designing state machines and each project must determine the FSM coding styles allowed. Considerations may include whether one-hot encoding is allowed, whether TMR (Triple Modular Redundancy) is required, how to minimize the number of bit-flips at state transitions, the error detection, error isolation and recovery mechanisms to be employed, etc. When these decisions are made, this rule ensures that the appropriate FSM style is consistently used throughout the design. As an exception to this rule, some organizations’ coding guidelines may enforce a hard coded FSM state definition to avoid unexpected synthesis results.
Note that while this check of the HDL code is important, the synthesis tool must also be set up properly to implement the FSM state encoding consistently in the targeted hardware. The synthesis tool control can be achieved through a pragma in the code or via an external control file. Consult your synthesis tool vendor for more information.
Default severity: Error Example:
TYPE cpu_sm_state_type IS (
IDLE, -- reset & default state START_OP,
WRITE_DATA, DO_READ, WAITMEM, STALL_WAIT,
DO_RD -- Note, FSM states are encoded as enumerated type ); P_CPU_SM_NEXT_STATE : PROCESS( . . . ) BEGIN CASE current_state_r is WHEN IDLE => . . . WHEN START_OP => . . .
WHEN “0011” => -- Violation, inconsistent state encoding . . .
END CASE;
6. Ensure Safe FSM Transitions (CP6)
a. An FSM should have a defined reset state.
b. All unused (illegal or undefined) states should transition to a defined state, whereupon this error condition can be processed accordingly.
c. There should be no unreachable states (i.e., those without any incoming
transitions) and dead-end states (i.e., those without any outgoing transitions) in an FSM.
Checking for these issues is central in determining if the FSM design will be able to handle adverse operating conditions that could induce invalid FSM state transitions.
In general, memory logic, including FSM state registers, can change state
unpredictably due to supply-rail transients, ground bounces and SEUs (Single Event Upsets). If the FSM design contains a fault condition detection and default error recovery transition, then the transient event(s) inducing the invalid state will be recoverable by way of a defined transition to a safe recovery state. Thus, it is
possible to check for improperly written HDL code that does not implement a fault-tolerant FSM design at the RTL level.
Note that while this check of the HDL code is important, the synthesis tool must also be set up properly to implement the safe FSM design consistently in the targeted hardware. The synthesis tool control can be achieved via an external control file. If the synthesis tool’s control options have not been properly configured for safe FSM implementation, then it will remove the fault condition detection and recovery logic during synthesis optimization. This will result in a incorrect in-hardware logic implementation of the RTL code. Check with your synthesis tool vendor for more information.
It should be noted that some designs may have other well-defined schemes for fault condition mitigation and recovery, and in those cases, this standard would be
modified or unnecessary. Default severity: Error Example:
TYPE fsm_state_type IS (
IDLE, -- reset & default state START_OP,
WRITE_DATA, DO_READ,
WAITMEM, -- wait for memory response STALL_WAIT, -- cpu stall
DO_RD
-- AIS -- Commented out AIS state will cause violation );
. . .
CASE current_state IS WHEN IDLE =>
IF (rd_req=’1’ AND pre=’0’) THEN next_state <= DO_RD;
. . .
WHEN DO_READ => -- Violation, no incoming transition next_state <= DO_RD;
. . .
WHEN DO_RD => IF (pre=’1’) THEN
status <= WAITMEM; -- Violation, no outgoing transition WHEN OTHERS => -- Others, including error states
next_state <= AIS; -- transition to the AIS state
-- Violation, AIS is not a defined state END CASE;
7. Avoid Mismatching Ranges (CP7)
Bit widths on both sides of an assignment, comparison, or association should match.
Mismatching range in an assignment, comparison, or association might result in logic overflow errors.
Default severity: Warning Example
ENTITY nonStatRange IS PORT (
in1 : IN std_logic_vector(31 DOWNTO 0); in2 : IN std_logic_vector(31 DOWNTO 0); sel1 : IN integer range 0 TO 15;
sel2 : IN integer range 0 TO 15;
out1 : OUT std_logic_vector(31 DOWNTO 0)); END;
ARCHITECTURE arch_nonStatRange OF nonStatRange is BEGIN
sm_proc: PROCESS(in1, in2)
variable local_var1 : std_logic_vector (1 DOWNTO 0); variable local_var2 : std_logic_vector (1 DOWNTO 0); BEGIN
local_var1 := in1 (sel1 + 1 DOWNTO sel1); --This is not --a violation, since the range is actually static although --the left and right indices are not.
local_var2 := in2 (sel1 + sel2 DOWNTO sel1); -- Violation END PROCESS;
END;
8. Ensure Complete Sensitivity List (CP8)
The sensitivity list should only contain the signals needed by the process.
does not include any unnecessary signals. The unused signals will slow down simulation. Missing signals potentially lead to mismatching simulation versus synthesized hardware function. Existence of unused signals should be justified. Default severity: Warning
Example:
RCV_CLOCKED_PROC : PROCESS ( clk,
-- rst, --Violation, signal needed in sensitivity list rcv_bit_cnt_cld --Violation, signal unnecessary
--will cause process to be trigger more than needed. )
BEGIN
IF (rst = '0') THEN
rcv_current_state <= waiting; ELSIF (falling_edge(clk)) THEN
rcv_current_state <= rcv_next_state; CASE rcv_current_state IS WHEN waiting => rcv_bit_cnt_cld <= "000"; IF (sin='0') THEN rcv_bit_cnt_cld <= "001"; END IF; WHEN incr_count2 =>
IF (sample='1' AND rcv_bit_cnt_cld /= "111") THEN rcv_bit_cnt_cld <= unsigned(rcv_bit_cnt_cld) + 1; END IF; WHEN OTHERS => NULL; END CASE; END IF;
END PROCESS RCV_CLOCKED_PROC;
9. Ensure Proper Sub-Program Body (CP9) Each sub-program must:
a. have only one exit point b. have no recursion
c. access only local variables/signals
Check for all these conditions in procedures, functions, and tasks. In some cases, if the code is intentionally designed this way (such as a recursive sub-program), its justification should be documented.
Default severity: Warning Example:
FUNCTION logicop (in1, in2 : IN bit_vector; c1, c2 : IN bit) RETURN bit_vector IS
BEGIN
IF(c1 = '1') THEN
RETURN (in1 OR in2); -- Violation, multiple exit points ELSIF(c2 = '1') AND (adr_mode = ‘1’) THEN
RETURN (in1 AND in2); -- Violation END IF;
END FUNCTION;
10.Assign Value Before Using (CP10)
Every object (e.g., signal, variable, port) should be assigned a value before using it.
When objects are used before being defined, a latch may be inferred during synthesis, which is most likely unintentional functional behavior for the design.
Default severity: Warning Example:
ENTITY fifo_bk_pressure IS PORT(
-- Port Declarations
clk_ck2 : IN std_logic; -- GLOBAL: downstream clock rst_ck2_n : IN std_logic; -- GLOBAL: downstream reset(N) cntr_ck1_i : IN std_logic_vector(FIFO_CNT R-1 DOWNTO 0); -- 9-bit -- Cut-and-paste error, should be cntr_ck2_i, results in violation . . . ); ARCHITECTURE rtl OF fifo_bk_pressure is --- register definitions
---signal full_threshold_r : fifo_cntr_type; -- 9-bit data type . . .
threshold_proc: PROCESS(cntr_ck2_i, full_threshold_r) BEGIN
assert_bk_pressure_s <= ‘0’; . . .
ELSIF (cntr_ck2_i = full_threshold_r – CDC_DELAY) THEN
--VIOLATION “cntr_ck2_i” should be assigned before being read assert_bk_pressure_s <= ‘1’;
END IF;
END PROCESS threshold_proc;
11.Avoid Unconnected Input Ports (CP11)
Input ports and bidirectional ports should be connected and not left floating. Unconnected input ports can cause the associated circuit blocks to exhibit non-deterministic functional behavior in hardware, varying with changes in voltage-rails and operating conditions.
Default severity: Error Example:
component usable_vhd PORT (
in1 : IN std_logic ;
in2 : IN std_logic_vector(MEM_ADR_ WIDTH-1 DOWNTO 0); out1 : OUT std_logic_vector(MEM_ADR_WIDTH-1 DOWNTO 0); out2 : OUT std_logic_vector(MEM_ADR_WIDTH-1 DOWNTO 0) );
. . .
U_bad: usable_vhd PORT MAP( in1 => d,
out1 => q, out2 => q );
-- VIOLATION. Unit bound to instance “U_bad” has an -- unused input port “in2”, that should be
-- actively driven by another signal or fixed to ‘0’ or ‘1’
12.Avoid Unconnected Output Ports (CP12) Design output ports should be connected.
Output ports should usually be connected to an internal signal. However, in some cases, such as with built-in self test (BIST) output signals used for debug, a floating output is acceptable. In these cases, the violation should be justified and documented. Default severity: Note
Example:
component usable_vhd PORT (
in1 : IN std_logic ;
in2 : IN std_logic_vector(MEM_ADR_ WIDTH-1 DOWNTO 0); out1 : OUT std_logic_vector(MEM_ADR_WIDTH-1 DOWNTO 0); out2 : OUT std_logic_vector(MEM_ADR_WIDTH-1 DOWNTO 0) );
...
U_bad: usable_vhd PORT MAP ( in1 => d,
out1 => FLOAT, out2 => q
-- VIOLATION. Unit bound to instance “U_bad” has a -- unconnected output port “out1”
-- unused output port “out1”, that should be
-- actively driven by another signal or by fixed ‘0’ or ‘1’
13.Declare Objects Before Use (CP13) Objects should be declared before use.
All objects used must be declared. Note: While this sort of error will be caught downstream in compilation, it is useful to check for it as early as possible as it is a very common mistake that results in misinterpreted code.
Default severity: Error Example:
ENTITY top IS GENERIC (Speed: SpeedType := typical;….); -- ‘SpeedType’ is an unknown type PORT(
. . . );
14.Avoid Unused Declarations (CP14) All declared objects should be used.
Check for objects that have been declared, but are never used (i.e., read from or assigned to). Unused declared objects are considered dead code. Dead code can be detrimental when a design is reused. The dead code could be inadvertently activated during the code base port.
Default severity: Warning Example:
LIBRARY ieee;
USE ieee.std_logic_1164.all; ENTITY unuseddecl IS
PORT (
in1 : IN std_logic_vector (3 DOWNTO 0);-- Violation
-- in1(3 DOWNTO 1)not used in RTL code
out1, -- Violation out1 not used in RTL code below, out2 : OUT std_logic_vector(3 DOWNTO 0) -- Violation
-- out2(2 DOWNTO 0) not used in RTL code );
END;
ARCHITECTURE unuseddecl_rtl OF unuseddecl IS SIGNAL temp1, temp2 : std_logic;
temp1 <= in1(0); -- Violation Signal 'temp1' is never used out2(3) <= temp2; -- Violation Signal 'temp2' is never assigned END;
Category: Clock Domain Crossing (CDC)
This set of standards addresses potential hazards with designs containing multiple clock zones and asynchronous clock zone transitions.
1. Analyze Multiple Asynchronous Clocks (CDC1)
Any time a design has multiple asynchronous clocks, or if internally-generated clocks are allowed, a thorough clock domain crossing (CDC) analysis should be done.
Improper clock domain crossings result in metastability or indeterminate circuit
operation, which can have serious adverse affects on a device’s operation. This design guidance needs to be mentioned, even though clock domain crossing issues and
analysis is beyond the scope of typical HDL linting tools and beyond the scope of this document.
As part of the design review process, all digital designs should be reviewed for
potential clock domain crossing boundaries, and, when found, analyzed to verify that they are properly addressed by a synchronizer circuit. This challenging design
methodology should be identified due to the extreme difficulties associated with isolating and debugging the intermittent CDC-error-induced functional behavior at the hardware level. It is often impossible to consistently duplicate these CDC-error-induced behaviors in hardware for design debug. Making this situation worse, circuit elements are affected by the operating conditions, such as loading, transistor junction temperature, voltage rails and ground bounce. In a worst case scenario, a CDC error might not exhibit itself during normal testing conditions, but it will occur during in-field (i.e., in-flight) operating conditions given the right set of environmental factors for the targeted system application.
For those interested in learning more about clock domain crossing issues and analysis techniques, refer to:
• 2008 FAA SW and AEH presentation “Mitigating the Dangers of Multi-Clock
Designs” (available here: http://www.mentor.com/products/fpga/do-254/upload/multi-clock-designs.pdf )
• “Automating Clock-Domain Crossing Verification for DO-254 (and other
Safety-Critical) Designs” a whitepaper developed by Mentor Graphics (available here: http://www.mentor.com/products/fpga/do-254/techpubs )
Category: Safe Synthesis (SS)
The following standards are checked to ensure a proper netlist is created by the synthesis tool.
1. Avoid Implied Logic (SS1)
Do not allow coding that implies feed-throughs, delay chains, and internal tri-state drivers.
Certain coding styles that are dependent on implied synthesis constructs can be dangerous. This implied logic might prevent the design code base from being
synthesized in a consistent manner across different device technologies. This sort of implied logic includes feed-throughs, delay chains, and internal tri-state drivers. Delay chains are two or more consecutive components with a single fan-in and single fan-out, such as inverters. In some cases, such as tri-state assignments and small width counters, this could be allowed and the applicant should document and justify the warning in these cases.
Default severity: Warning Example:
SIGNAL mode : std_logic; -- Internal Tri-state Control
SIGNAL tri_bus : std_logic_vector (1 DOWNTO 0); -- Internal signal -- (not top level port) …
Tristate_Control: PROCESS (mode) BEGIN
IF (mode = '0') THEN
tri_bus <= "0Z"; -- Do not allow internal tristates ELSE
tri_bus <= "Z0"; -- Do not allow internal tristates END IF;
END PROCESS Tristate_Control;
Example:
ENTITY feed_through_ea IS PORT(
a_i : IN std_logic;
av_i : IN std_logic_vector (10 DOWNTO 0); x_o : OUT std_logic
);
END feed_through_ea;
ARCHITECTURE rtl OF feed_through_ea IS BEGIN
x_o <= a_i; -- Violation, feed-through from input port “a_i” to output port “x_o”
Example:
ENTITY delay_ea IS
PORT(
adr_i : IN std_logic_vector(ADR_WID TH-1 DOWNTO 0); av_i : IN std_logic_vector(10 DOWNTO 0);
adrx_o : OUT std_logic_vector(ADR_WIDTH-1 DOWNTO 0) );
END delay_ea;
ARCHITECTURE rtl OF delay_ea is
signal adr_inv1_s : std_logic_vector(ADR_WIDTH-1 DOWNTO 0); signal adr_inv2_s : std_logic_vector(ADR_WIDTH-1 DOWNTO 0); BEGIN
adr_inv1_s <= NOT(adr_i);
adr_inv2_s <= NOT(adr_inv1_s);
adrx_o <= adr_int2_s; -- Violation, delay chain from input port “adr_i” to output port “adrx_o”
2. Ensure Proper Case Statement Specification (SS2) Case statements should:
a. Be complete
b. Never have duplicate/overlapping statements c. Never have unreachable case items
d. Always include the “when others” clause
Case statements need to define operations for all enumerations of the case variable. Incomplete case statements will not synthesize in a predictable manner. Thus, when this logic is driven by a non-predefined input pattern (e.g., during ground bounce condition or SEU), its functional behavior will be dependent on the synthesis and place-and-route tools’ optimization algorithm settings, the release version, and even the computing environment used to execute the downstream tool runs.
Note that while this check of the HDL code is important, the synthesis tool must also be set up properly to implement fault-tolerant design consistently in the
targeted hardware. The synthesis tool control can be achieved through a pragma in the code or via an external control file.
Default severity: Error Example: CASE addr IS WHEN "000" => clk_div_en <= '1'; WHEN "001" => clk_div_en <= '1';
WHEN "000" => -- Duplicate/overlapping case specification clk_div_en <= '1';
-- Incomplete case specification WHEN "10X" => -- Not reachable case specification
xmitdt_en <= '1';
ser_if_select <= addr(1 DOWNTO 0); WHEN "110" =>
ser_if_select <= addr(1 DOWNTO 0); WHEN "111" =>
clr_int_en <= '1';
-- Missing WHEN OTHERS clause END CASE;
3. Avoid Combinational Feedback (SS3)
Do not allow reading and assigning to the same signal in the sa me combinational process.
Such combinational feedback paths cause race conditions, making the design’s functional behavior unpredictable. This design check could also be referred to as “asynchronous feedback loops.”
Default severity: Error Example:
fred_s <= gated_in_s OR pulse_r; -- Violation combinational feedback -- loop, at fred_s P_GATED_IN : PROCESS( en_i, fred_s, pulse_r) BEGIN
gated_in_s <= fred_s AND en_i; -- Violation, async. feedback loop IF (en_i = '0') THEN
gated_in_s <= NOT(fred_s); -- Violation, async. feedback loop ELSIF (pulse_r <= '1') THEN
gated_in_s <= '0'; END IF;
END PROCESS P_GATED_IN;
4. Avoid Latch Inference (SS4)
The HDL coding style should avoid inference of latches.
Careful consideration should be given to the creation of latches in a design. In many cases latches may be introduced unintentionally, due to coding errors. The HDL coding style should avoid inference of latches. While latches might simulate properly, the synthesized hardware behavior may not match functional simulation. To avoid this problem, a good HDL coding practice is to write every IF-statement ending with an ELSE to avoid unnecessary latches in the design, as a result of
synthesis inference of the IF-statement functional behavior. This does not apply to the IF-statement for the clock. A non-used ELSE-statement should be declared with a NULL.
If a project decides not to allow any asynchronous design, this should be considered an Error. However, if it is acceptable in certain cases, the severity should be
considered Warning, and the applicant should document and justify each case. Default severity: Warning
Example:
library ieee;
use ieee.std_logic_1164.all; ENTITY vhdlatch IS
PORT (
in1, in2, in3, in4 : IN std_logic; out1 : OUT std_logic;
out2 : OUT std_logic_vector(3 DOWNTO 0)); END;
ARCHITECTURE arch OF vhdlatch IS BEGIN
PROCESS (in1, in2, in3, in4) -- Violation BEGIN
IF( in4 = '0') THEN out2(3) <= in1; out2(0) <= in2; ELSE
out2 <= (others => in3); END IF;
END PROCESS; END;
5. Avoid Multiple Waveforms (SS5)
Only one waveform should exist on the right-hand side of a signal assignment.
A waveform consists of an assignment value expression and an optional assignment delay expression. Multiple waveforms are non-synthesizable. With multiple
waveforms, synthesized hardware behavior will not match simulation. Default severity: Error
Example:
nRW <= '1' AFTER clk_prd, '0' AFTER 8 * clk_prd;
-- Violation, Only first waveform element used for synthesis
6. Avoid Multiple Drivers (SS6)
A signal/shared variable should not have multiple, simultaneously active drivers. Multiply-driven signals can synthesize as “bucking drivers” in the hardware implementation and exhibit latent in-field failures of these circuits, which may become permanent.
Default severity: Error Example:
library ieee;
use ieee.std_logic_1164.all; ENTITY top IS
PORT(
a1, a2 : IN std_logic_vector(7 DOWNTO 0); a3 : OUT std_logic_vector(7 DOWNTO 0)); END; ARCHITECTURE rtl OF top IS BEGIN operate_proc: PROCESS(a1) BEGIN a3 <= a1 and "10101000"; -- Violation END PROCESS; test_proc: PROCESS(a2) BEGIN
a3 <= a2; -- Associated Violation END PROCESS;
END rtl;
7. Avoid Uninitialized VHDL Deferred Constants (SS7) Ensure all VHDL deferred constants are initialized.
A constant can be declared in a package without an initialization. The corresponding package body should contain the initialization. Constants defined using this style are called deferred constants. It is important to ensure that VHDL deferred constants do actually get initialized. When VHDL deferred constants are not initialized, they may not be synthesizable.
Default severity: Warning Example:
PACKAGE trafficPackage IS
CONSTANT MaxTimerVal: integer
–- Violation. Deferred constant ‘MaxTimerVal’ without initial -- value may not be synthesizable
8. Avoid Clock Used as Data (SS8)
Clock signals should not be used in a logic path that drives the data input of a register.
Clock signals used as data can result in potential race conditions. This standard would also be violated in the case where a clock signal happens to be a primary output of the design (that is, output of the top design unit), since it can potentially be used as data outside the design.
While synthesis engines should catch this issue, it may only be shown as a “warning” in the synthesis environment, and therefore could easily be overlooked. Thus, the recommended severity is error. This ensures the issue is caught and addressed. Default severity: Error
Example:
P_GATED_IN : PROCESS(in1, mclk) BEGIN
gated_in_s <= '0';
IF (in1 = TRANSITION) and (mclk = '0') THEN -- Associated Violation gated_in_s <= '1'; -- See below
END IF;
END PROCESS P_GATED_IN;
P_PULSE_FF : PROCESS(mclk, rst_n) -- Violation clock used as data BEGIN -- Race condition can occur here
IF (rst_n = '0') THEN pulse_r <= '0';
ELSIF rising_edge(mclk) THEN pulse_r <= gated_in_s; END IF;
END PROCESS P_PULSE_FF;
9. Avoid Shared Clock and Reset Signal (SS9)
The same signal should not be used as both a clock and reset signal.
Shared clock and reset functions for the same signal will cause race conditions in the design. In general, clock signals should be coded in HDL in a manner to help the downstream tools synthesize and map them onto the dedicated clock routing
resources. Similarly, the reset signals should be coded in HDL in a clear manner to insure that they are mapped onto dedicated reset routing resources. This will mitigate potential timing violations due to different routing implementations and design code base ports targeting a different device.
Example:
reset_n <= mclk AND en_i; -- reset_n signal has embedded clock P_FRED_R : PROCESS(mclk, reset_n)
BEGIN
IF (reset_n = '0') THEN -- Violation shared clock & reset signal fred_r <= '0';
ELSIF rising_edge(mclk) THEN fred_r <= in1(DIR_BIT); END IF;
END PROCESS P_FRED_R;
10.Avoid Gated Clocks (SS10)
Data signals should not be used in a logic path that drives the clock input of a register.
Gated clocks can cause clock skews and are sensitive to glitches, due to propagation delay and SET (Single Event Transient) effects, which can lead to incorrect data being registered. Coding should be checked for the usage of gated clocks throughout the design. Disallowing clock gating is good safety-critical design best practice for synchronous digital designs. A design based on synchronous enabled registers should be used instead of gated clocks.
If the project’s standards determine it is never OK to use clock gating, then the
severity should be set to Error. However, the suggested severity is generally Warning because in some cases (e.g., battery-power devices), clock gating is intentionally designed in to save power. When allowed, each implementation and justification must be documented thoroughly. Careful consideration of potential adverse effects when halting and starting up the associated circuit block(s) must be reviewed.
Additionally, special consideration for the targeted FPGA device technology must be taken into account. Clock gating designs for FPGA should not be allowed if the targeted FPGA device does not contain special purpose-built clock gating circuitry in silicon.
Default severity: Warning Example:
clk_s <= mclk AND en_i; -- Gating mclk as clk_s P_PULSE_FF : PROCESS(clk_s, rst_n) -- Violation gated clock BEGIN
IF (rst_n = '0') THEN pulse_r <= '0';
ELSIF rising_edge(clk_s) THEN pulse_r <= in1(DIR_BIT); END IF;
11.Avoid Internally Generated Clocks (SS11) Internally generated clocks should be avoided.
Clocks, clock-trees, and signals crossing clock-domains need careful consideration and handling. If internally generated clocks are allowed in a design, clock-domain crossing (CDC) analysis should be run to detect metastable design errors. See “Category: Clock Domain Crossings” for more information.
If allowed, each implementation must be justified and thoroughly documented. In FPGA targeted designs, the potential for CDC and propagation delay variance
induced errors can be mitigated by requiring these clock signals to be generated with the FPGA’s special purpose-built clock management circuitry, global clock drivers and routing.
Default severity: Warning Example:
ARCHITECTURE rtl OF top IS BEGIN
U_and: gate port map (a => clk_master, b => enable, c => clk_c); --Isolated Clock Generator instance synch_PROC: PROCESS (clk_c, rst_master)
BEGIN
IF (rst_master = '0') THEN …
ELSIF (rising_edge(clk_c)) THEN
-– VIOLATION: Internally generated clock signal “clk_c” used to drive synchronous block “synch_PROC”, due to default rule configuration is Disallowed. Should the project team (or company) wish to allow
isolation at top-level, they could change the setting or severity of this rule and it would not violate the example above.
12.Avoid Internally Generated Resets (SS12)
Unless they are properly isolated, internally-generated resets should be avoided.
Internally generated resets should only be allowed throughout the design if they are at the top-level of the design hierarchy and properly isolated. For synchronous digital designs, it is considered best practice to use asynchronous reset signals, which are synchronously released. This avoids race condition problems when the reset signal is de-asserted too close to the active edge of the clock, violating set-up or hold time. See the coding standard to flag “Avoid Asynchronous Reset Release” for additional information.
When allowed, each implementation must be justified and thoroughly documented. In FPGA targeted designs, internally generated reset propagation delay variance, due
to routing differences, can induce timing violations. This can be mitigated by
generating the reset signals with the FPGA’s special purpose-built reset management circuitry, global reset drivers and routing.
Default severity: Warning Example: ENTITY reset_module IS PORT( clk: IN std_logic; rst: IN std_logic; in1: IN std_logic; out1:OUT std_logic); END reset_module; ARCHITECTURE rtl OF reset_module IS SIGNAL rst_int: std_logic;
BEGIN
PROCESS(clk) -- Violation, rst_int
BEGIN -- is internally generated IF rising_edge(clk) THEN IF (rst = '1') THEN rst_int <= '0'; ELSE rst_int <= in1; END IF; END IF; END PROCESS; PROCESS(clk) BEGIN IF rising_edge(clk) THEN
IF (rst_int = '1') THEN -- Associated Violation out1 <= '0'; ELSE out1 <= in1; END IF; END IF; END PROCESS; END rtl;
13.Avoid Mixed Polarity Reset (SS13)
The same reset signal should not be used with mixed styles or polarities.
Reset signals should be used consistently throughout the entire design. This is important for a safety-critical program from a design IP reuse and comprehension aspect. Applying a reset signal inconsistently can cause unintended circuit behaviors during the reset signal’s assertion and de-assertion when the designer does not fully comprehend the interactions between active circuit blocks and the reset blocks. If this is intentionally implemented in the design, its justification should be documented.
Unintended design behavior can occur due to potential race conditions. Default severity: Warning
Example:
ARCHITECTURE rtl OF top IS BEGIN
proc1: PROCESS(clk_master, clk_n, rst_master) BEGIN
IF rising_edge(clk_master) THEN
IF (rst_master = '1') THEN -- Violation, inconsistent q <= '0'; -- reset polarities & style ELSE
q <= d1; END IF; END IF;
IF (rst_master = '0') THEN -- Violation, inconsistent q <= '0'; -- reset polarities & style ELSIF (falling_edge(clk_n)) THEN
q <= d2; END IF; END PROCESS; END rtl;
14.Avoid Unresettable Registers (SS14) All registers should have a reset control.
All registers in the design should have an explicit reset of a specified type. A reset signal is used to help initialize a device into a predetermined condition. This system initiated error recovery command is used as the last resort recovery mechanism for a non-responsive device.
There are occasional situations where the registers are not implemented with a reset control intentionally (e.g., synchronizer flops and scan-chains). In these cases, the applicant should document and justify each exception. Note that multi-dimensional signals/register declarations modeled as memories should be exempt from this check. Default severity: Warning
Example:
PROCESS (clk, reset) –- Violation for out3, missing reset control BEGIN IF(reset = '1') THEN out2 <= (others => '0'); ELSIF(rising_edge(clk)) THEN out2 <= in2; out3 <= in1; END IF;
END PROCESS;
15.Avoid Asynchronous Reset Release (SS15) Reset signals should have a synchronous release.
For synchronous digital designs, it is considered best practice to generate reset control as asynchronous assertion and synchronous de-assertion signal to avoid problems when the reset signal is de-asserted during the active edge of the clock..
Default severity: Error Example:
Note that the following figure demonstrates a correct on-chip reset scheme as described in the preceding text.
16.Avoid Initialization Assignments (SS16) Do not use register initialization assignments.
It is best practice to use an explicit reset to set a register to a value as opposed to using an initialization assignment in the port/signal declaration. It is desirable to allow uninitialized signals to simulate as unknown, to detect and evaluate the X-propagation through the design. This may reflect actual design issues in-hardware. Default severity: Error
Example:
library ieee;
use ieee.std_logic_1164.all;
PROCESS (clk, reset) –- Violation for out3, missing reset control BEGIN
out2 <= (others => '0'); ELSIF(rising_edge(clk)) THEN out2 <= in2; out3 <= in1; END IF; END PROCESS;
17.Avoid Undriven and Unused Logic (SS17)
a. Every register and latch must be used and driven in the design. b. Registers and latches affecting only unused logic must be examined.
Unused registers, latches, and other logic are simply dead code. Dead code can be detrimental when a design is reused and the dead code is inadvertently activated
during the code base port. Dead code effects on safety-critical design assurance is not predictable nor insured to be consistent across different synthesis tools, release
versions, and even computing environments. Default severity: Error
Example:
As seen from this figure, n1 and n2 are not used in the design and hence constitute unused logic violations. Moreover, the registers in red are only feeding nets that are unused, and consequently those registers are unused as well. However, the other (blue) registers are used since they drive output Z and hence they should be allowed, even though they also drive unused logic n1 and n2.
18.Ensure Register Controllability (SS18)
Each register should be controllable from its inputs.
suffer from a dead-end value, which means that the bit drives a constant unless an asynchronous reset is applied. A state bit might also suffer from a stuck-at-fault, which means that the register always drives a constant value, irrespective of any changes to the inputs, including resets. These situations can lead to inconsistent synthesis results.
Default severity: Warning Example: flag_s <= (OTHERS => ’0’); . . . P_CMD_R : PROCESS(rst_n, mclk) BEGIN IF (rst_n = ’0’) THEN cmd_r <= (OTHERS => ’0’); ELSIF RISING_EDGE(mclk) THEN
cmd_r <= request_in AND flag_s; -- violation, stuck-at-0 fault END IF;
END PROCESS P_CMD_R;
19.Avoid Snake Paths (SS19)
Combinational paths should not exceed a maximum allowable logic depth.
It is difficult for timing optimizers to optimize the critical path of a design, if it spans multiple levels of hierarchy. Long combinational paths, also called snake paths, can pose synthesis problems. The project team should determine the maximum levels of permissible user hierarchy level that a path can span. Any path longer than this should be reported as a violation, and should be broken at an appropriate point by inserting registers.
Default severity: Warning 20.Ensure Nesting Limits (SS20)
Conditional branching constructs should have a maximum nesting depth.
Deeply nested conditional branching logic will tend to synthesize with longer
propagation delay depths, in addition to being more complex to debug and fix when an error has been found. The project teams should specify, and then check for, a maximum limit for nesting depth for conditional branching constructs. Controlling the nesting depth and format improves readability and reduces complexity, which is desirable to insure that the code base will more likely implement a fully verifiable design that can also be modified quickly for design reuse and debugging. All of these aspects are important in a fail-safe design. The nesting limit can be set at the
discretion of the project team, taking into account logic propagation delays’ negative effect on the design’s timing requirements. Violations should be examined to see if
they are acceptable or require re-design.
If the design requires the use of a logic implementation exceeding the maximum allowable nesting limit, then this violation and its impact study should be
documented.
Default severity: Warning Example: FLIP_FLOP: PROCESS(rst,clk) BEGIN IF rst = '1' THEN qout <= '0'; out_one <= '0'; out_two <= '0'; out_three <= '0';
ELSIF RISING_EDGE(clk) THEN IF in_one = '1' THEN
out_one <= in_one; IF in_two = '1'THEN
out_two <= in_two;
IF in_three = '1' THEN -- Violation if set to 3, as 4th level
out_three <= in_three; ...
21.Ensure Consistent Vector Order (SS21)
Use the same multi-bit vector order consistently throughout the design.
In order to promote code comprehension and reduce potential interconnection errors, the multi-bit vector order should be consistent throughout the design. The vector range should consistently use either an ascending or descending order. Note that violations often occur when a design uses reused code or IP. But each of these violations should be examined and justification/assurance should be given that the issue is appropriately addressed in the design.
Default severity: Warning Example:
Bus_ascending : IN std_logic_vector (7 DOWNTO 0);
Bus_decending : IN std_logic_vector (0 T0 7); -- Violation if Descending order enabled
Category: Design Reviews (DR)
The following standards are checked to make design reviews and code comprehension easier.
1. Use Statement Labels (DR1) Statements should have labels.
Case Statements, Processes, Always Blocks, and Initial Blocks should have labels to improve clarity for design code reviews and tracing during simulation. Labels should be added to the End constructs to assist with following the scope of the code.
Default severity: Note Example:
ARCHITECTURE flow OF top IS BEGIN
-- Architecture concurrent statements
data_out <= div_data WHEN clk_div_en = '1' ELSE ser_if_data; -- Violation. Concurrent statements should be labeled
END flow;
2. Avoid Mixed Case Naming for Differentiation (DR2) Names should not be differentiated by case alone.
Note that this is different than mixed case naming for a single object. Mixed case naming is sometimes preferred for clarity/readability. However, when design code uses the same name for two different objects, with the only difference being character case, this should not be allowed. Violating this coding standard will cause confusion regarding the design’s intention. It is a bad coding practice with respect to design comprehension for a safety-critical application.
Default severity: Warning Example:
ENTITY top IS
PORT (nrw: OUT std_logic ); END top;
ARCHITECTURE flow OF top BEGIN
Nrw <= ‘0’;
-- Violation. Do not allow mixing of case identifier “nrw” -- Identifiers “nrw” and “Nrw” are differentiated by case only END
3. Ensure Unique Name Spaces (DR3)
The same name should not be used for different types of identifiers.
The same name is not used in different name spaces. For example, the same name should not be used to identify a signal in one part of the design but also used as a process label elsewhere. Port names having the same names as connected signals can
be excluded.
At best, violating this standard will cause confusion regarding the design’s intention. At worst, the design could pass synthesis without any violation but its in-hardware functionally will not follow the HDL code’s intention.
Default severity: Error Example:
ARCHITECTURE rtl OF top IS SIGNAL i : std_logic;
-- Violation. Do not use identifier “i” since it exists in -- another namespace within the same design
PROCEDURE my_and (in1 : std_logic; in2 : std_logic; out1 : OUT std_logic) is
VARIABLE i : std_logic;
-- Identifier name “i” already used in another namespace BEGIN
i := '1';
out1 <= in1 AND in2; END PROCEDURE;
4. Use Separate Declaration Style (DR4)
Each declaration should be placed on a separate line.
Having declarations on separate lines dramatically improves code reviews and
readability. Thus declarations should be formatted with each on a separate line or, in the case of ports, with each group of ports of the same mode (input, output etc) on a separate line.
Default severity: Note Example:
ARCHITECTURE spec OF status_registers IS
SIGNAL xmitting_r, done_xmitting_r : std_logic; -- declaration -- Violation. Multiple signals declared in one line,
-- declarations should be on separate lines. END spec;
5. Use Separate Statement Style (DR5)
Each statement should be placed on a separate line.
Having statements on separate lines ensures readability of the code. Declarations are excluded unless there is a declaration on the same line as another statement. Note that the “begin” keyword can be removed from this check.
Default severity: Note Example:
IF (en_i = '1') THEN
x1_s <= NOT(a1_i); x2_s <= a1_i; -- Violation, multiple statements ELSE
x1s <= '0'; x2_s <= '0'; -- Violation, multiple statements END IF;
6. Ensure Consistent Indentation (DR6) Code should be consistently indented.
In order to promote readability of code between different editors, code should be consistently indented in terms of spaces and the number of indentation steps. Default severity: Note
Example:
FLOP_FLIP: PROCESS(rst,clk) –- Consistently formatted BEGIN
IF rst = '1' THEN tout_one <= '0'; tout_two <= '0'; tout_three <= '0';
ELSIF rising_edge(clk) THEN IF in_one = '1' THEN tout_one <= in_one; IF in_two = '1' THEN tout_two <= in_two; IF in_three = '1' THEN tout_three <= in_three; ENDIF; ENDIF; ENDIF; ENDIF;
7. Avoid Using Tabs (DR7) Tabs should not be used.
Tabs should not be used, as they can result in problems when moving source code from one editing environment to another.
8. Avoid Large Design Files (DR8)
Designs should be partitioned and files should be of limited size.
In order to promote code comprehension, a design file should be of a limited size to promote better design partitioning. This will help force the design structure into a more hierarchical partition away from a large flat code structure. The acceptable size should be at the discretion of the project team.
Default severity: Warning
9. Ensure Consistent Signal Names Across Hierarchy (DR9)
Signals and busses should have consistent names when they span the design hierarchy.
In order to promote code comprehension and reduce potential interconnection errors, a signal/bus should have a constant name when it spans across hierarchical levels. Default severity: Warning
10.Ensure Consistent File Header (DR10) Ensure a consistent file header.
In order to promote code comprehension, a consistent file header comment style should be enforced through out the design project. Important information such as the code’s author, organization, creation and modification dates, legal briefing, statement of proprietary information, etc should be included if deemed appropriate. A brief summary of the code’s intention should be placed in the file header as well.
Default severity: Warning
11.Ensure Sufficient Comment Density (DR11)
Code should be sufficiently documented via inline comments.
In order to promote code comprehension, a minimum design code in-line
documentation (i.e., commenting) should be enforced. The amount of design code in-line commenting should allow a different designer to be able to understand the design well enough to be able to modify it for a different project in a reasonable amount of time.
Default severity: Warning
12.Ensure Proper Placement of Comments (DR12)
Comments should be placed in appropriate places to aid understanding.
Enforce the placement of comments near (preferably above) code statements and code blocks to aid design code functionality understanding. This design check helps
to enforce stricter degrees of design code documentation/commenting for more complex language constructs usage.
Default severity: Note
13.Ensure Company Specific Naming Standards (DR13)
Each company or project should establish and enforce its own naming standards.
These standards will vary from company to company, or even project to project, and therefore cannot be explicitly included in a generic set of DO-254 coding standards. However, they should be considered and included in each company’s HDL coding standards. The sorts of things to consider include:
• Having the component have the same name as the associated entity • Ensuring name association between formal and actual generics, ports or
parameters
• Enforcing specific filename matching with associated entity
• Enforcing specific object type naming convention, with a prefix or postfix
appended to the object name. Choose only one of these two methods (prefix vs. postfix labels) and consistently apply it through out the entire design. Consideration should be give to naming conventions for clocks, resets, signals, constants, variables, registers, FSM State Variables, generics, labels etc. For example:
a. signals use “_s” b. registers use “_r” c. constants use “_c” d. processes use “_p” e. off-chip inputs use “_I” f. on-chip inputs use “_i” g. off-chip outputs use “_O” h. on-chip outputs use “_o” i. etc.
Default severity: Note
7.0 Best Practice Usage of Automated HDL Standards Checking
Tools can automate nearly all of the HDL standards presented in this paper. This section discusses the benefits, processes, and issues (such at Tool Qualification) involved when using an automated means to check HDL coding standards.
Benefits of Automated Checking
First, automation brings to the design checking process a standard metric for finding coding violations and weighing violation severities, based on an organization’s digital
design coding guidelines. If a team does not have a set of coding guidelines, a pre-packaged rule set provides a quick and easy way to get started.
Second, by leveraging tool automation capability, this can dramatically reduce the large man-hour labor cost from manual design code reviews. Additionally, the more senior design engineers who typically oversee these design code reviews are now freed to
concentrate on the more difficult tasks of correcting the design functionality and refining the design architecture. Thus, a design teams’ most valuable resources are used more effectively, while reducing design review cost and schedule impact as they are aligned to the organization’s standard HDL design coding guidelines. While this may not tie
directly to design assurance, high cost is an issue in DO-254 programs, and leveraging automation (when appropriate) is a way to bring down these costs.
Third, a well written set of digital design coding guidelines keeps HDL based design mistakes from propagating in an organization and within a design flow. That is, one of the coding guideline documents’ primary goal is to pass on best practice digital design knowledge to less experienced design engineers. Becoming proficient with a HDL language for digital design requires using it in practice and learning from design as well as coding mistakes. An automated design checking tool can also help as a digital design guidelines teaching tool when it is used in an interactive fashion during the initial design coding phase. With each design, lessons are learned and improved practices are
identified. These refinements can be added back into the rule set and checking tool to constantly improve the design checking process over time.
Finally, automating HDL coding checks can assist in managing growing design
complexity and size. For large, complex designs, it is nearly impossible to guarantee a consistent and error free design checking process based on manual code reviews.
Machine based checking guided by an organization’s design standards ensures a consistent result, even as designs grow in size.
Use Model for Automated HDL Code Checking
In order to get maximum use out of automated standards checking, it should be used as early and often as possible.
Building the rule set. Most standards can be automated with linting tools. A company should first define the standards they want to use, and then map them into the capabilities of a tool. Alternately, if a company does not have a set of standard checks, choose a well-constructed, pre-defined set and then modify the parameters and severity to meet the project style preferences and design assurance requirements. Select appropriate built-in rules based on the defined standard requirements. Add and delete additional standards from other packaged rule sets as well as from all available base rules. Each company or project team may also have their own “style” standards as well, such as naming,
indentations, comments, and so on. Some of these can be automatically checked and enforced, while others might not easily lend themselves to be machine checked. In this
regard, supplement a packaged rule set with customizations and even some manual checks that must be examined during code reviews.
Check during design.With today’s level of automation, a designer can literally code a block of logic, and press a button to check for any violations against the automatable coding standards. This allows him to clean up his code prior to integrating that code into the larger design.
Check at integration. Each time the design code is integrated with other code into a larger design, run the checks again as well.
Check reused code.Any time code is reused, check the quality of the previously-written code against the organization’s design coding standards. Oftentimes reused code was developed prior to an organization’s current set of coding standards, as coding standards tend to evolve and become more mature over time. Thus, reused code may often have violations of some of the newer standards. However, reused code is often taken from other projects where it may have proven usage. The key is simply ensuring reused code does not violate any of the most critical/serious checks, and/or that any violations are examined to ensure they will not have any safety impact. For these cases, a subset of the full coding standards can be used to verify the quality of the reused code. If reused code passes the safety-critical checks, and has a proven track record, it should be fine to use. On the other hand, if reused code has numerous violations against safety-critical
standards, the reuse potential may have to be reconsidered.
Downstream checks.Many of the coding violations in HDL development would be caught later on in the process where they are tedious, and costly to fix. For example, some violations may be caught at compile time. Others may be caught in simulation or other verification activities. Some violations may later be flagged as uncovered by code coverage metrics. While others may be caught as bugs very late in the design process (or even in silicon).
Considerations for Tool Assessment
Checking of HDL code against a set of standards via a review would be considered a verification activity in DO-254. Therefore, if credit was taken for this activity via an automated tool, the tool used would have to go through tool assessment.
It could be possible to use an “independent output assessment” argument for tool assessment, as the automation does not replace the need for other aspects of code reviews. Manual code reviews to understand code intent can never be replaced, and during this process, many of these standards could be caught. Likewise, some of these checks would be caught in downstream processes, such as simulation and synthesis. In the absence of a tool to automate the process, a manual code review process would be followed.
However, a preferred method would be to conduct a basic tool qualification, as defined by DO254 § 11.4. This could consist of a document identifying the standards to be checked, along with a set of test cases, including both good and bad code for each standard. This could be run by the applicant to demonstrate that the tool is indeed
performing the standards checking correctly. If the set of standards the tool is checking is modified in any way, the set of tests run to demonstrate correct results would have to change accordingly. Using this approach, credit taken for the automated code review activity should be assured.
Note that because this is not a “functional” verification activity (in other words, the tool checking HDL coding standards is not verifying that the design implementation meets its intended function as per requirements), this approach should be sufficient.
8.0 The “DO-254” Ruleset in Mentor Graphics HDL Designer Tool
Mentor Graphics, a member of the DO-254 user group, and an electronic design
automation (EDA) company committed to aerospace and DO-254, provides a tool called HDL Designer which is used to create, explore, analyze, and run various tasks on an HDL project. One key feature of HDL Designer is the DesignChecker. DesignChecker is a configurable design rule checker that can apply checks to HDL code, report resulting violations, and enable debugging.
As a result of their effort to lead the initiative to create this foundational set of DO-254 coding rules in the user group, Mentor has implemented this set of checks as a pre-defined ruleset called “DO-254” which runs in the DesignChecker available in HDL Designer. This ruleset can be run “as is” or modified as per a project’s specific needs. For more information on using HDL Designer to run DO-254 rules checking, visit www.mentor.com/go/do-254 and locate the paper entitled “Understanding and Running DO-254 Coding Checks in HDL Designer.”
9.0 Summary
Defining and checking HDL coding standards is a best practice that is generally accepted and employed by many companies today. It is also a recent requirement imposed by DO-254.
In order to assist with this compliance objective, a “best practice” set of foundational standards was presented in this paper. These standards (or rules) can be used as-is by companies who don’t have their own standards and are seeking guidance. Likewise this rule set can also be modified and augmented by companies wanting to do more or
different types of checks.
Using a tool to automate the checking of these coding standards is common practice. While automated checking cannot fully replace manual code reviews, it can improve the