Coding Style Guidelines

Дата канвертавання24.04.2016
Памер116.6 Kb.
1   2   3   4


The rules for using signals are not complex. The most common problem is that signals can be various data types. The problem in VHDL is "casting" from one data type to another. Unfortunately, no single function can automatically cast one signal type to another. Therefore, the use of a standard set of casting functions is important to maintain consistency between designers.


Rules for Casting

  • Use std_logic_arith, std_logic_unsigned/std_logic_signed packages.

This provides the essential conversion functions:

  • conv_integer(): converts std_logic_vector, unsigned, and signed data types into an integer data type.

  • conv_unsigned(, ): converts a std_logic_vector, integer, unsigned (change size), or signed data types into an unsigned data type.

  • conv_signed(, ): converts a std_logic_vector, integer, signed (change size), or unsigned data types into a signed data type.

  • conv_std_logic_vector(, ): converts an integer, signed, or unsigned data type into a std_logic_vector data type.

  • ext(, ): zero extends a std_logic_vector to size .

  • sxt(, ): sign extends a std_logic_vector to size .

All conversion functions can take for the data-type a std_logic_vector, unsigned, signed, std_ulogic_vector, or integer. is specified as an integer value.

Inverted Signals

To reduce complication and to make the code easier to debug and test, it is generally recommended that you use active-high signals in hardware description languages. Generally, active-low signals make the code more complicated than necessary. If active-low signals are required at the boundaries of an FPGA, invert incoming signals at the FPGA top structural level. Also, for outbound signals, invert them at the FPGA top structural level. Consider this a rule of thumb.
However, for FPGAs in general and Xilinx FPGAs specifically, inverters are free throughout the device. There are inverters in the IOB, and a LUT can draw in an inverter as part of its functionality, without a loss in performance.
Often, ASIC designers will use active-low signals in their code to use less power in the part. The synthesis tool will map the logic based on a vendor’s libraries. Therefore, the synthesis tool will infer active-low signals internally when it sees fit. For that matter, writing code that uses active-low signals does not necessarily infer active-low signals in the ASIC. Again, the synthesis tool makes these decisions based on the vendor's libraries. Let the synthesis tool do its job!
Rule of thumb

  • Use only active-high signals in HDL. One exception is a signal with a dual purpose, such as a read or a write signal. In this case, a naming convention should be used to reduce complication – rw_l is an easily recognizable signal name that clearly defines that signal’s role.

  • Where active-low signals are required, use of a _l as a suffix generally makes the intent clear. E.g., _l. Use of _n is generally confusing.

Rule for Signals

  • There are a few basic rules to follow when you use signals. Remember that ports are just signals with special rules that apply to them.

Entity Port Rules within the Bound Architecture:

  • You can read from inputs, but you cannot assign to inputs.

  • You can assign to outputs, but you cannot read from outputs.

  • See section 1, Signal Naming Conventions , rule number four, for help in skirting this limitation.

  • You can both assign to and read from inouts.

Internal Signal Rules

  • Never assign to a signal in more than one process, with the exception of a three-state signal.

  • For a combinatorial process (no registers inferred), never assign to a signal and read from the same signal in the same process. This will eliminate infinite loops when performing behavioral simulation.

  • This is not true for a "clocked" process; i.e., a process that is used to register signals. A clocked process would only need to have an asynchronous set or reset signal and a clock in its sensitivity list. Therefore, this process would not execute again until there was a change on one of those signals.

  • In a clocked process, never assign to a signal outside of the control of the if rising_edge(clk) statement (or reset statement if an asynchronous reset exists). This is a common coding mistake. In synthesis, it will infer a combinatorial signal. In a behavioral simulation, it will have the behavior of a signal clocked on the falling edge.

Filling out a Process Sensitivity List

  • Within a combinatorial process, all signals that are read (which can change) must be in the sensitivity list.

  • This will insure the correct behavioral simulation. This includes any signals that are compared in if-then-else statements and case statements. It also includes any signal on the right-hand side of an assignment operator. Remember that this is only for signals that can change. A constant cannot change; thus, it does not need to be in the sensitivity list.

  • Within a clocked process, only an asynchronous set or reset and the clock should be in the sensitivity list.

  • If others are added, the functionality of a behavioral simulation will still be correct. However, the simulation will be slower because that process will need to be evaluated or simulated whenever a signal in its sensitivity list changes.

Rules for Variables and Variable Use

Variables are commonly not understood and are therefore not used. Variables are also commonly used and not understood. Variables can be very powerful when used correctly. This warrants an explanation of how to properly use variables.
Variables are used to carry combinatorial signals within a process. Variables are updated differently than signals in simulation and synthesis.
In simulation, variables are updated immediately, as soon as an assignment is made. This differs from signals. Signals are not updated until all processes that are scheduled to run in the current delta cycle have executed (generally referred to as suspending). Thus, a variable can be used to carry a combinatorial signal within both a clocked process and a combinatorial process. This is how synthesis tools treat variables – as intended combinatorial signals.
Figure 13-10 shows how to use a variable correctly. In this case, the variable correct_v maintains its combinatorial intent of a simple two-input and-gate that drives an input to an or-gate for both the a and b registers.

Figure 13-10 Correct Use of Variables

In Figure 13-11, you read from the variable incorrect_v before you assign to it. Thus, incorrect_v uses its previous value, therefore inferring a register. Had this been a combinatorial process, a latch would have been inferred.

Figure 13-11 Incorrect Use of Variables

Rule for Variables

  • Always make an assignment to a variable before it is read. Otherwise, variables will infer either latches (in combinatorial processes) or registers (in clocked processes) to maintain their previous value. The primary intent of a variable is for a combinatorial signal.

    Packages Section 3

Packages are useful for creating modular and reusable code. There should be one or more packages used by a design team. These packages should include commonly used functions, procedures, types, subtypes, aliases, and constants. All team designers should familiarize themselves with the contents of these packages. If each designer were to create his or her own functions, procedures, types, subtypes, aliases, and constants, it could result in code that is difficult for other team members to use and read. Thus, when your team uses packages, it results in code that is more modular and more readable.
Package use can generally be broken down into the three types:

  • The global package. This package is used on a company-wide basis, on each design. This package should include functions and procedures, such as reduction functions, for instance functions, and procedures that -- and, or, and xor (etc.) -- reduce individual buses. It should also include commonly used types and subtypes. This package should be created in a group setting by VHDL experts (or the most experienced in VHDL) who decide the best elements to have present in the package. This package should be used extensively and should have periodic reviews to determine what should be added to or taken away from the package. Because most divisions within a company work on the same type of projects, primarily, this package should contain the most widely and extensively used material that is common to all design teams.

  • The project package. This package is used and created for a specific design project. The functions, procedures, types, subtypes, constants, and aliases are all specifically defined and created for the design at hand.

  • The designer’s packages. These packages are specific to a designer. Packages of this type should not be used extensively. If there is a need for something to be extensively used within the designer’s package, it should be moved into the project package and possibly even the global package. Code readability and modularity is limited by the use of designer packages, as the type of function calls and types, etc. will not be readily understandable to all other designers in the group.

1   2   3   4

База данных защищена авторским правом © 2016
звярнуцца да адміністрацыі

    Галоўная старонка