- •About This Manual
- •Additional Resources
- •Manual Contents
- •Conventions
- •Typographical
- •Online Document
- •Using Foundation Express with VHDL
- •Hardware Description Languages
- •Typical Uses for HDLs
- •Advantages of HDLs
- •About VHDL
- •Foundation Express Design Process
- •Using Foundation Express to Compile a VHDL Design
- •Design Methodology
- •Design Descriptions
- •Entities
- •Entity Generic Specifications
- •Entity Port Specifications
- •Architecture
- •Declarations
- •Components
- •Concurrent Statements
- •Constant Declarations
- •Processes
- •Signal Declarations
- •Subprograms
- •Type Declarations
- •Examples of Architectures for NAND2 Entity
- •Configurations
- •Packages
- •Using a Package
- •Package Structure
- •Package Declarations
- •Package Body
- •Resolution Functions
- •Data Types
- •Type Overview
- •Enumeration Types
- •Enumeration Overloading
- •Enumeration Encoding
- •Enumeration Encoding Values
- •Integer Types
- •Array Types
- •Constrained Array
- •Unconstrained Array
- •Array Attributes
- •Record Types
- •Record Aggregates
- •Predefined VHDL Data Types
- •Data Type BOOLEAN
- •Data Type BIT
- •Data Type CHARACTER
- •Data Type INTEGER
- •Data Type NATURAL
- •Data Type POSITIVE
- •Data Type STRING
- •Data Type BIT_VECTOR
- •Unsupported Data Types
- •Physical Types
- •Floating-Point Types
- •Access Types
- •File Types
- •Express Data Types
- •Subtypes
- •Expressions
- •Overview
- •Operators
- •Logical Operators
- •Relational Operators
- •Adding Operators
- •Unary (Signed) Operators
- •Multiplying Operators
- •Miscellaneous Arithmetic Operators
- •Operands
- •Operand Bit-Width
- •Computable Operands
- •Aggregates
- •Attributes
- •Expressions
- •Function Calls
- •Identifiers
- •Indexed Names
- •Literals
- •Numeric Literals
- •Character Literals
- •Enumeration Literals
- •String Literals
- •Qualified Expressions
- •Records and Fields
- •Slice Names
- •Limitations on Null Slices
- •Limitations on Noncomputable Slices
- •Type Conversions
- •Sequential Statements
- •Assignment Statements and Targets
- •Simple Name Targets
- •Indexed Name Targets
- •Slice Targets
- •Field Targets
- •Aggregate Targets
- •Variable Assignment Statements
- •Signal Assignment Statements
- •Variable Assignment
- •Signal Assignment
- •if Statements
- •Evaluating Conditions
- •Using the if Statement to Infer Registers and Latches
- •case Statements
- •Using Different Expression Types
- •Invalid case Statements
- •loop Statements
- •Basic loop Statement
- •while...loop Statements
- •for...loop Statements
- •Steps in the Execution of a for...loop Statement
- •for...loop Statements and Arrays
- •next Statements
- •exit Statements
- •Subprograms
- •Subprogram Always a Combinatorial Circuit
- •Subprogram Declaration and Body
- •Subprogram Calls
- •Procedure Calls
- •Function Calls
- •return Statements
- •Procedures and Functions as Design Components
- •Example with Component Implication Directives
- •Example without Component Implication Directives
- •wait Statements
- •Inferring Synchronous Logic
- •Combinatorial Versus Sequential Processes
- •null Statements
- •Concurrent Statements
- •Overview
- •process Statements
- •Combinatorial Process Example
- •Sequential Process Example
- •Driving Signals
- •block Statements
- •Nested Blocks
- •Guarded Blocks
- •Concurrent Versions of Sequential Statements
- •Concurrent Procedure Calls
- •Concurrent Signal Assignments
- •Simple Concurrent Signal Assignments
- •Conditional Signal Assignments
- •Selected Signal Assignments
- •Component Instantiation Statements
- •Direct Instantiation
- •generate Statements
- •for...generate Statements
- •Steps in the Execution of a for...generate Statement
- •Common Usage of a for...generate Statement
- •if...generate Statements
- •Register and Three-State Inference
- •Register Inference
- •The Inference Report
- •Latch Inference Warnings
- •Controlling Register Inference
- •Inferring Latches
- •Inferring Set/Reset (SR) Latches
- •Inferring D Latches
- •Inferring Master-Slave Latches
- •Inferring Flip-Flops
- •Inferring D Flip-Flops
- •Inferring JK Flip-Flops
- •Inferring Toggle Flip-Flops
- •Getting the Best Results
- •Understanding Limitations of Register Inference
- •Three-State Inference
- •Reporting Three-State Inference
- •Controlling Three-State Inference
- •Inferring Three-State Drivers
- •Inferring a Simple Three-State Driver
- •Three-State Driver with Registered Enable
- •Three-State Driver Without Registered Enable
- •Writing Circuit Descriptions
- •How Statements Are Mapped to Logic
- •Design Structure
- •Adding Structure
- •Using Variables and Signals
- •Using Parentheses
- •Using Design Knowledge
- •Optimizing Arithmetic Expressions
- •Arranging Expression Trees for Minimum Delay
- •Sharing Common Subexpressions
- •Changing an Operator Bit-Width
- •Using State Information
- •Propagating Constants
- •Sharing Complex Operators
- •Asynchronous Designs
- •Don’t Care Inference
- •Using Don’t Care Default Values
- •Differences Between Simulation and Synthesis
- •Synthesis Issues
- •Feedback Paths and Latches
- •Fully Specified Variables
- •Asynchronous Behavior
- •Understanding Superset Issues and Error Checking
- •Foundation Express Directives
- •Notation for Foundation Express Directives
- •Foundation Express Directives
- •Translation Stop and Start Pragma Directives
- •synthesis_off and synthesis_on Directives
- •Resolution Function Directives
- •Component Implication Directives
- •Foundation Express Packages
- •std_logic_1164 Package
- •std_logic_arith Package
- •Using the Package
- •Modifying the Package
- •Data Types
- •UNSIGNED
- •SIGNED
- •Conversion Functions
- •Arithmetic Functions
- •Example 10-1: Binary Arithmetic Functions
- •Example 10-2: Unary Arithmetic Functions
- •Comparison Functions
- •Example 10-3: Ordering Functions
- •Example 10-4: Equality Functions
- •Shift Functions
- •ENUM_ENCODING Attribute
- •pragma built_in
- •Type Conversion
- •numeric_std Package
- •Understanding the Limitations of numeric_std package
- •Using the Package
- •Data Types
- •Conversion Functions
- •Resize Function
- •Arithmetic Functions
- •Comparison Functions
- •Defining Logical Operators Functions
- •Shift Functions
- •Rotate Functions
- •Shift and Rotate Operators
- •std_logic_misc Package
- •ATTRIBUTES Package
- •VHDL Constructs
- •VHDL Construct Support
- •Design Units
- •Data Types
- •Declarations
- •Specifications
- •Names
- •Identifiers and Extended Identifiers
- •Specifics of Identifiers
- •Specifics of Extended Identifiers
- •Operators
- •Shift and Rotate Operators
- •xnor Operator
- •Operands and Expressions
- •Sequential Statements
- •Concurrent Statements
- •Predefined Language Environment
- •VHDL Reserved Words
- •Examples
- •Moore Machine
- •Mealy Machine
- •Read-Only Memory
- •Waveform Generator
- •Smart Waveform Generator
- •Definable-Width Adder-Subtracter
- •Count Zeros—Combinatorial Version
- •Count Zeros—Sequential Version
- •Soft Drink Machine—State Machine Version
- •Soft Drink Machine—Count Nickels Version
- •Carry-Lookahead Adder
- •Carry Value Computations
- •Implementation
- •Serial-to-Parallel Converter—Counting Bits
- •Input Format
- •Implementation Details
- •Serial-to-Parallel Converter—Shifting Bits
- •Programmable Logic Arrays
VHDL Reference Guide
Operands
Operands specify the data that the operator uses to compute its value. An operand returns its value to the operator.
There are many categories of operands. The simplest operand is a literal, such as the number 7, or an identifier, such as a variable or signal name. An operand itself can be an expression. You create expression operands by surrounding an expression with parentheses.
The operand categories follow.
•Aggregates: my_array_type’(others => 1)
•Attributes: my_array’range
•Expressions: (A nand B)
•Function calls: LOOKUP_VAL(my_var_1, my_var_2)
•Identifiers: my_var, my_sig
•Indexed names: my_array(7
•Literals: ’0’, "101", 435, 16#FF3E#
•Qualified expressions: BIT_VECTOR’(’1’ & ’0’)
•Records and fields: my_record.a_field
•Slice names: my_array(7 to 11)
•Type conversions: THREE_STATE(’0’)
The next two sections discuss operand bit-widths and explain computable operands. The sections following them describe the operand types listed above.
Operand Bit-Width
Foundation Express uses the bit-width of the largest operand to determine the bit-width needed to implement an operator in a circuit. For example, an INTEGER operand is 32 bits wide by default. An addition of two INTEGER operands causes Foundation Express to build a 32-bit adder.
To use hardware resources efficiently, always indicate the bit-width of numeric operands. For example, use a subrange of INTEGER when declaring types, variables, or signals.
4-14 |
Xilinx Development System |
|
|
|
|
|
|
Expressions |
|
|
|
|
|
||
type |
ENOUGH: |
INTEGER range 0 |
to |
255; |
||
variable |
WIDE: |
INTEGER |
range |
-1024 to 1023; |
||
signal |
NARROW: |
INTEGER |
range |
0 |
to |
7; |
Note: During optimization, Foundation Express removes hardware for unused bits.
Computable Operands
Some operators, such as the division operator, restrict their operands to be computable. A computable operand is one whose value can be determined by Foundation Express. Computability is important because noncomputable expressions can require logic gates to determine their value.
Examples of computable operands follow.
•Literal values
•for...loop parameters, when the loop’s range is computable
•Variables assigned a computable expression
•Aggregates that contain only computable expressions
•Function calls with a computable return value
•Expressions with computable operand
•Qualified expressions when the expression is computable
•Type conversions when the expression is computable
•Value of the AND or NAND operators when one of the operands is a computable ‘0’
•Value of the OR or NOR operators when one of the operands is a computable ‘1’
Additionally, a variable is given a computable value if it is an OUT or INOUT parameter of a procedure that assigns it a computable value.
Examples of noncomputable operands follow.
•Signals
•Ports
•Variables assigned different computable values that depend on a noncomputable condition
VHDL Reference Guide |
4-15 |
VHDL Reference Guide
•Variables assigned noncomputable values
The following example shows some definitions and declarations, followed by several computable and noncomputable expressions.
signal S: BIT;
. . .
function MUX(A, B, C: BIT) return BIT is begin
if (C = ’1’) then return(A);
else return(B);
end if; end;
procedure COMP(A: BIT; B: out BIT) is begin
B := not A;
end; |
|
|
|
|
process(S) |
|
|
||
variable V0, V1, V2: BIT; |
|
|||
variable V_INT: |
INTEGER; |
|||
subtype |
MY_ARRAY is BIT_VECTOR(0 to 3); |
|||
variable V_ARRAY: |
MY_ARRAY; |
|||
begin |
|
|
|
|
V0 |
:= |
’1’; |
-- Computable (value is ’1’) |
|
V1 |
:= |
V0; |
-- Computable (value is ’1’) |
|
V2 |
:= |
not V1; |
-- Computable (value is ’0’) |
|
for I |
in 0 to 3 loop |
|
|
|
|
V_INT := I; |
-- Computable (value depends |
||
|
|
|
-- |
on iteration) |
|
end |
loop; |
|
|
V_ARRAY := MY_ARRAY’(V1, V2, ’0’, ’0’); |
||||
|
|
|
-- Computable ("1000") |
|
V1 |
:= |
MUX(V0, V1, V2); -- Computable (value is ’1’) |
||
COMP(V1, V2); |
|
|
||
V1 |
:= |
V2; |
-- Computable (value is ’0’) |
|
V0 |
:= |
S and ’0’; |
-- Computable (value is ’0’) |
|
V1 |
:= |
MUX(S, ’1’, ’0’);-- Computable (value is ’1’) |
||
V1 |
:= |
MUX(’1’, ’1’, S);-- Computable (value is ’1’) |
||
if (S |
= ’1’) then |
|
|
|
|
V2 := ’0’; |
-- Computable (value is ’0’) |
||
else |
|
|
|
|
4-16 |
Xilinx Development System |
|
|
|
Expressions |
|
|
|
|
|
V2 := ’1’; |
|
-- Computable (value is ’1’) |
end if; |
|
|
|
V0 |
:= V2; |
-- Noncomputable; V2 depends |
|
|
|
-- |
on S |
V1 |
:= S; |
-- Noncomputable; S is signal |
|
V2 |
:= V1; |
-- Noncomputable; V1 is no |
|
|
|
-- |
longer computable |
end process;
Aggregates
Aggregates create array literals by giving a value to each element of an instance of an array type. Aggregates can also be considered array literals, because they specify an array type and the value of each array element. The syntax follows.
type_name’ ([choice=>] expression {, [choice =>] expression})
type_name must be a constrained array type (as required by Foundation Express in the previous example), an element index, a sequence of indexes, or the others expression. Each expression provides a value for the chosen elements and must evaluate to a value of the element’s type.
The following example shows an array type definition and an aggregate representing a literal of that array type. The two sets of assignments have the same result.
subtype |
MY_VECTOR is BIT_VECTOR(1 to 4); |
|
||
signal X: |
MY_VECTOR; |
|
||
variable A, B: BIT; |
|
|||
X <= MY_VECTOR’(’1’, A nand B, ’1’, A or B) |
-- Aggregate |
|||
|
|
|
|
-- assignment |
X(1) |
<= |
’1’; |
|
-- Element assignment |
X(2) |
<= |
A nand B; |
|
|
X(3) |
<= |
’1’; |
|
|
X(4) |
<= |
A or B; |
|
|
You can specify an element’s index by using either positional or named notation. With positional notation, each element receives the value of its expression in order, as shown in the example above.
By using named notation, the choice => construct specifies one or more elements of the array. The choice can contain an expression (such as (I mod 2) =>) to indicate a single element index or a range
VHDL Reference Guide |
4-17 |
