Fpga Express VHDL Reference Manual
Fpga Express VHDL Reference Manual
Copyright 1999 Synopsys, Inc. All rights reserved. This software and documentation are owned by Synopsys, Inc., and furnished under a license agreement. The software and documentation may be used or copied only in accordance with the terms of the license agreement. No part of the software and documentation may be reproduced, transmitted, or translated, in any form or by any means, electronic, mechanical, manual, optical, or otherwise, without prior written permission of Synopsys, Inc., or as expressly provided by the license agreement.
Disclaimer
SYNOPSYS, INC., AND ITS LICENSORS MAKE NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Registered Trademarks
Synopsys, the Synopsys logo, BiNMOS-CBA, CMOS-CBA, COSSAP, DESIGN (ARROWS), DesignPower, DesignWare, dont_use, Eagle Design Automation, ExpressModel, in-Sync, LM-1000, LM-1200, Logic Modeling, Logic Modeling (logo), Memory Architect, ModelAccess, ModelTools, PathMill, PLdebug, Powerview, Retargeter, SmartLicense, SmartLogic, SmartModel, SmartModels, SNUG, SOLV-IT!, SourceModel Library, Stream Driven Simulator_, Synopsys, Synopsys (logo), Synopsys VHDL Compiler, Synthetic Designs, Synthetic Libraries, TestBench Manager, TimeMill, ViewBase, ViewData, ViewDoc, ViewDraw, ViewFault, ViewFlow, VIEWFPGA, ViewGen, Viewlogic, ViewPlace, ViewPLD, ViewScript, ViewSim, ViewState, ViewSynthesis, ViewText, Workview, Workview Office, and Workview Plus are registered trademarks of Synopsys, Inc.
Trademarks
3-D Debugging, AC/Grade, AMPS, Arcadia, Arkos, Aurora, BCView, BOA, BRT, CBA Design System, CBA-Frame, characterize, Chip Architect, Chronologic, Compiler Designs, Core Network, Core Store, Cyclone, Data Path Express, DataPath Architect, DC Expert, DC Expert Plus, DC Professional, Delay Mill, Design Advisor, Design Analyzer_proposed, Design Exchange, Design Source, DesignTime, DesignWare Developer, Direct RTL, Direct Silicon Access, dont_touch, dont_touch_network, DW 8051, DWPCI, DxDataBook, DxDataManager, Eagle, Eaglei, Eagle V, Embedded System Prototype, Floorplan Manager, Formality, FoundryModel, FPGA Compiler II, FPGA Express, Fusion, FusionHDL, General Purpose Post-Processor, GPP, HDL Advisor, HTX, Integrator, IntelliFlow, Interactive Waveform Viewer, ISIS, ISIS PreVUE, LM-1400, LM-700, LM-family, Logic Model, ModelSource, ModelWare, MOTIVE, MS-3200, MS-3400, PathBlazer, PDQ, POET, PowerArc, PowerCODE, PowerGate, PowerMill, PreVUE, PrimeTime, Protocol Compiler, QUIET, QUIET Expert, RailMill, RTL Analyzer, Shadow Debugger, Silicon Architects, SimuBus, SmartCircuit, SmartModel Windows, Source-Level Design, SourceModel, SpeedWave, SWIFT, SWIFT interface, Synopsys Behavioral Compiler, Synopsys Design Compiler, Synopsys ECL Compiler, Synopsys ECO Compiler, Synopsys FPGA Compiler, Synopsys Frame Compiler, Synopsys Graphical Environment, Synopsys HDL Compiler, Synopsys Library Compiler, Synopsys ModelFactory, Synopsys Module Compiler, Synopsys Power Compiler, Synopsys Test Compiler, Synopsys Test Compiler Plus, TAP-in, Test Manager, TestGen, TestGen Expert Plus, TestSim, Timing Annotator, TLC, Trace-On-Demand, VCS, DCS Express, VCSi, VHDL System Simulator, ViewAnalog, ViewDatabook, ViewDRC, ViewLibrarian, ViewLibrary, ViewProject, ViewSymbol, ViewTrace, Visualyze, Vivace, VMD, VSS Expert, VSS Professional VWaves, XFX, XNS, and XTK are trademarks of Synopsys, Inc.
Service Marks
SolvNET is a service mark of Synopsys, Inc. All other product or company names may be trademarks of their respective owners. Printed in the U.S.A.
ii
Audience
This manual is written for logic designers and electronic engineers who are familiar with Synopsys synthesis products. A basic knowledge of VHDL or other high-level programming language is also necessary.
iii
Related Publications
These Synopsys documents supply additional information:
FPGA Compiler II / FPGA Express Getting Started Manual Design Compiler Command-Line Interface Guide Design Compiler Reference Manual: Constraints and Timing Design Compiler Reference Manual: Optimization and Timing Analysis Design Compiler Tutorial Design Compiler User Guide DesignWare Developer Guide VSS User Guide
iv
For more information about VHDL and its use, see the following publications:
IEEE Standard VHDL Language Reference Manual, IEEE Std 1076-1987. Introduction to HDL-Based Design Using VHDL. Steve Carlson. Synopsys, Inc., 1990. VHDL. Douglas L. Perry. McGraw-Hill, Inc., 1991.
Man Pages
You can view man pages from fc2_shell / fe_shell environment. From the shell prompt, enter:
fc2_shell> help command_name
or
fe_shell> help command_name
Customer Support
If you have problems, questions, or suggestions, contact the Synopsys Technical Support Center in one of the following ways: Send e-mail to
support_center@synopsys.com
Call (650) 584-4200 outside the continental United States, or call (800) 245-8005 inside the continental United States, from 7 a.m. to 5:30 p.m. Pacific Time, Monday through Friday. Send a fax to (650) 594-2539.
vi
Conventions
The following conventions are used in Synopsys documentation.
Convention courier Description Indicates command syntax. In command syntax and examples, shows system prompts, text from files, error messages, and reports printed by the system. Indicates a user specification, such as object_name In command syntax and examples, indicates user input (text the user types verbatim). Denotes optional parameters, such as pin1 [pin2, . . , pinN] Indicates a choice among alternatives, such as low | medium | high This example indicates that you can enter one of three possible values for an option: low, medium, or high. Connects two terms that are read as a single term by the system. For example, design_space. Indicates a keyboard combination, such as holding down the Control key and pressing c. Indicates a continuation of a command line. Indicates levels of directory structure. Shows a menu selection. Edit is the menu name, and Copy is the item on the menu.
courier italic
courier bold [ ] |
vii
viii
Table of Contents
About This Manual 1. Using FPGA Compiler II / FPGA Express with VHDL Hardware Description Languages . . . . . . . . . . . . . . . . . . . . . . . . . . Typical uses for HDLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Advantages of HDLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About VHDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . FPGA Compiler II / FPGA Express Design Process . . . . . . . . . . . . 1-2 1-3 1-3 1-4 1-7
Using FPGA Compiler II / FPGA Express to Compile a VHDL Design 1-8 Design Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2. Design Descriptions Entities. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Entity Generic Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . Entity Port Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 2-3 2-4 2-5 1-9
Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-10
ix
Examples of Architectures for NAND2 Entity. . . . . . . . . . . . . . . 2-33 Configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-34 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-35 Package Uses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-35 Package Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-36 Package Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-37 Package Body . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-39 Resolution Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-40 3. Data Types Enumeration Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enumeration Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enumeration Encoding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enumeration Encoding Values. . . . . . . . . . . . . . . . . . . . . . . . . . Integer Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Array Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3 3-4 3-4 3-7 3-8 3-9
Record Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-13 Record Aggregates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-14 Predefined VHDL Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-16 Data Type BOOLEAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-18 Data Type BIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-18 Data Type CHARACTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-18 Data Type INTEGER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-19 Data Type NATURAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-19 Data Type POSITIVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-19 Data Type STRING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-19 Data Type BIT_VECTOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-19 Unsupported Data Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-20 Physical Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-20 Floating-Point Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-20 Access Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-20 File Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-20 Synopsys Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-21 Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-21 4. Expressions Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Logical Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2 4-3 4-5 4-8
xi
Multiplying Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-11 Miscellaneous Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . 4-12 Operands. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-14 Operand Bit-Width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-15 Computable Operands. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-16 Aggregates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-18 Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-20 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-21 Function Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-22 Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-23 Indexed Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-24 Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Numeric Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Character Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enumeration Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . String Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-26 4-26 4-26 4-27 4-27
Qualified Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-29 Records and Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-30 Slice Names. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-32 Limitations on Null Slices . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-33 Limitations on Noncomputable Slices . . . . . . . . . . . . . . . . . 4-34 Type Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-34 5. Sequential Statements Assignment Statements and Targets. . . . . . . . . . . . . . . . . . . . . . . . Simple Name Targets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Indexed Name Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-2 5-3 5-4
xii
Variable Assignment Statements. . . . . . . . . . . . . . . . . . . . . . . . . . . 5-11 Signal Assignment Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-12 if Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-15 Evaluating Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-15 Using the if Statement to Infer Registers and Latches. . . . . . . . 5-16 case Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-17 Using Different Expression Types . . . . . . . . . . . . . . . . . . . . . . . 5-18 Invalid case Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-21 loop Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-22 Basic loop Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-23 while...loop Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-24 for...loop Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-25 Steps in the Execution of a for...loop Statement. . . . . . . . . . 5-27 for...loop Statements and Arrays . . . . . . . . . . . . . . . . . . . . . 5-28 next Statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-30 exit Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-33 Subprograms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-35 Subprogram Always a Combinational Circuit. . . . . . . . . . . . . . . 5-35 Subprogram Declaration and Body . . . . . . . . . . . . . . . . . . . . . . 5-35 Subprogram Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-37 Procedure Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-39 Function Calls. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-41
xiii
return Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-43 Procedures and Functions as Design Components. . . . . . . . . . 5-45 Example With Component Implication Directives . . . . . . . . . . . 5-47 Example Without Component Implication Directives . . . . . . . . . 5-49 wait Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-50 Inferring Synchronous Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-51 Combinational Versus Sequential Processes . . . . . . . . . . . . . . 5-55 null Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-58 6. Concurrent Statements process Statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Combinational Process Example . . . . . . . . . . . . . . . . . . . . . . . . Sequential Process Example . . . . . . . . . . . . . . . . . . . . . . . . . . . Driving Signals. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2 6-5 6-6 6-8
block Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10 Nested Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-11 Guarded Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12 Concurrent Versions of Sequential Statements. . . . . . . . . . . . . . . . 6-13 Concurrent Procedure Calls. . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-14 Concurrent Signal Assignments. . . . . . . . . . . . . . . . . . . . . . . . . Simple Concurrent Signal Assignments . . . . . . . . . . . . . . . . Conditional Signal Assignment. . . . . . . . . . . . . . . . . . . . . . . Selected Signal Assignments. . . . . . . . . . . . . . . . . . . . . . . . 6-17 6-17 6-18 6-20
xiv
generate Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-26 for...generate Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-26 Steps in the Execution of a for...generate Statement . . . . . . 6-27 Common Usage of a for...generate Statement . . . . . . . . . . . 6-29 if...generate Statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-31 7. Register and Three-State Inference Register Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The inference Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Latch Inference Warnings. . . . . . . . . . . . . . . . . . . . . . . . . . . Controlling Register Inference . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes That Control Register Inference . . . . . . . . . . . . . . 7-1 7-3 7-4 7-4 7-5
Inferring Latches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-8 Inferring Set/Reset (SR) Latches . . . . . . . . . . . . . . . . . . . . . 7-8 Inferring D Latches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10 Inferring Master-Slave Latches. . . . . . . . . . . . . . . . . . . . . . . 7-20 Inferring Flip-Flops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inferring D Flip-Flops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inferring JK Flip-Flops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inferring Toggle Flip-Flops . . . . . . . . . . . . . . . . . . . . . . . . . . Getting the Best Results. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-21 7-22 7-41 7-45 7-51
Understanding Limitations of Register Inference . . . . . . . . . . . . 7-57 Three-State Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-59 Reporting Three-State Inference . . . . . . . . . . . . . . . . . . . . . . . . 7-59 Controlling Three-State Inference . . . . . . . . . . . . . . . . . . . . . . . 7-60 Inferring Three-State Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-60 Inferring a Simple Three-State Driver. . . . . . . . . . . . . . . . . . 7-60
xv
Three-State Driver With Registered Enable . . . . . . . . . . . . . 7-65 Three-State Driver Without Registered Enable . . . . . . . . . . 7-67 Understanding the Limitations of Three-State Inference . . . . . . 7-69 8. Writing Circuit Descriptions How Statements Are Mapped to Logic . . . . . . . . . . . . . . . . . . . . . . Design Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Variables and Signals. . . . . . . . . . . . . . . . . . . . . . . . . Using Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Design Knowledge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2 8-3 8-3 8-4 8-5 8-6
Optimizing Arithmetic Expressions . . . . . . . . . . . . . . . . . . . . . . 8-6 Arranging Expression Trees for Minimum Delay . . . . . . . . . 8-7 Sharing Common Subexpressions. . . . . . . . . . . . . . . . . . . . 8-12 Changing an Operator Bit-Width . . . . . . . . . . . . . . . . . . . . . . . . 8-14 Using State Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-17 Propagating Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-21 Sharing Complex Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-22 Asynchronous Designs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-23 Dont Care Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-29 Using dont care Default Values . . . . . . . . . . . . . . . . . . . . . . . . . 8-32 Differences Between Simulation and Synthesis . . . . . . . . . . . . 8-33 Synthesis Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-34 Feedback Paths and Latches. . . . . . . . . . . . . . . . . . . . . . . . . . . 8-34 Fully Specified Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-35 Asynchronous Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-37
xvi
Understanding Superset Issues and Error Checking. . . . . . . . . 8-38 9. FPGA Compiler II / FPGA Express Directives Notation for FPGA Compiler II / FPGA Express Directives . . . . . . . FPGA Compiler II / FPGA Express Directives. . . . . . . . . . . . . . . . . Translation Stop and Start Pragma Directives . . . . . . . . . . . . . . synthesis_off and synthesis_on Directives . . . . . . . . . . . . . . . . Resolution Function Directives . . . . . . . . . . . . . . . . . . . . . . . . . Component Implication Directives . . . . . . . . . . . . . . . . . . . . . . . A. Examples Moore Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mealy Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Read-Only Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-2 A-5 A-7 9-2 9-2 9-3 9-3 9-5 9-5
Waveform Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-10 Smart Waveform Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-13 Definable-Width Adder-Subtracter. . . . . . . . . . . . . . . . . . . . . . . . . . A-16 Count ZerosCombinational Version . . . . . . . . . . . . . . . . . . . . . . . A-19 Count ZerosSequential Version . . . . . . . . . . . . . . . . . . . . . . . . . . A-22 Soft Drink MachineState Machine Version. . . . . . . . . . . . . . . . . . A-24 Soft Drink MachineCount Nickels Version . . . . . . . . . . . . . . . . . . A-29 Carry-Lookahead Adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-32 Carry Value Computations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-32 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-39
xvii
Serial-to-Parallel ConverterCounting Bits . . . . . . . . . . . . . . . . . . A-40 Input Format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-41 Implementation Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-42 Serial-to-Parallel ConverterShifting Bits. . . . . . . . . . . . . . . . . . . . A-47 Programmable Logic Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-51 B. Synopsys Packages std_logic_1164 Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . std_logic_arith Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modifying the Package. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . UNSIGNED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SIGNED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conversion Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-2 B-3 B-4 B-5 B-6 B-6 B-7 B-8
Arithmetic Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-10 Comparison Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-13 Shift Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-15 ENUM_ENCODING Attribute. . . . . . . . . . . . . . . . . . . . . . . . . . . B-17 pragma built_in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Two-Argument Logic Functions . . . . . . . . . . . . . . . . . . . . . . One-Argument Logic Functions . . . . . . . . . . . . . . . . . . . . . . Type Conversion. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-17 B-18 B-19 B-19
numeric_std Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-20 Understanding the Limitations of numeric_std package . . . . . . B-21 Using the Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-21
xviii
Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-22 Conversion Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-22 Resize Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-23 Arithmetic Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-23 Comparison Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-24 Defining Logical Operators Functions . . . . . . . . . . . . . . . . . . . . B-26 Shift Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-27 Rotate Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-28 Shift and Rotate Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-28 std_logic_misc Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-30 ATTRIBUTES Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-31 C. VHDL Constructs VHDL Construct Support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Design Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Specifications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Identifiers and Extended Identifiers . . . . . . . . . . . . . . . . . . . . . . Specifics of Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Specifics of Extended Identifiers . . . . . . . . . . . . . . . . . . . . . C-2 C-3 C-4 C-5 C-6 C-7 C-8 C-8 C-8
Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-9 Shift and Rotate Operators. . . . . . . . . . . . . . . . . . . . . . . . . . C-10 xnor Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-11 Operands and Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-12
xix
Sequential Statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-13 Concurrent Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-15 Predefined Language Environment . . . . . . . . . . . . . . . . . . . . . . C-16 VHDL Reserved Words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-17
xx
List of Figures
Figure 1-1 Figure 1-2 Figure 2-1 Figure 2-2 Figure 4-1 Figure 4-2 Figure 4-3 Figure 4-4 Figure 4-5 Figure 4-6 Figure 4-7 Figure 4-8 Figure 5-1 Figure 5-2 VHDL Hardware Model. . . . . . . . . . . . . . . . . . . . . . . . . . Design Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-Bit Counter Synthesized Circuit . . . . . . . . . . . . . . . . . . 1-5 1-9 2-8
Design Using Resolved Signal . . . . . . . . . . . . . . . . . . . . 2-43 Design Schematic for Logical Operators . . . . . . . . . . . . Relational Operators Design Illustrating Example 4-4 . . Design Array Illustrating Example 4-5. . . . . . . . . . . . . . . 4-4 4-8 4-9
Design Illustrating Unary Negation From Example 4-6. . 4-10 Design Illustrating Multiplying Operators From Example 4-7 412 Design With Arithmetic Operators From Example 4-8 . . 4-13 Design Illustrating Use of Indexed Names From Example 4-16 4-25 Design Illustrating Use of Slices From Example 4-24. . . 4-33 Design Illustrating Indexed Name Targets From Example 5-3 5-6 Schematic Design From Example 5-8 . . . . . . . . . . . . . . 5-16
xxi
Figure 5-3 Figure 5-4 Figure 5-5 Figure 5-6 Figure 5-7 Figure 5-8 Figure 5-9 Figure 5-10 Figure 5-11 Figure 5-12 Figure 5-13 Figure 5-14 Figure 6-1 Figure 6-2 Figure 6-3 Figure 6-4 Figure 6-5 Figure 6-6 Figure 6-7 Figure 6-8 Figure 6-9 Figure 6-10
Schematic Design From Example 5-9 . . . . . . . . . . . . . . 5-19 Schematic Design From Example 5-10 . . . . . . . . . . . . . 5-20 Schematic Design From Example 5-12 . . . . . . . . . . . . . 5-28 Schematic Design of Array From Example 5-13 . . . . . . . 5-29 Schematic Design From Example 5-14 . . . . . . . . . . . . . 5-31 Schematic Design From Example 5-16 . . . . . . . . . . . . . 5-34 Schematic Design From Example 5-18 . . . . . . . . . . . . . 5-41 Schematic Design From Example 5-20 . . . . . . . . . . . . . 5-45 Schematic Design With Component Implication Directives 548 Schematic Design Without Component Implication Directives 5-50 Schematic Design From Example 5-30 . . . . . . . . . . . . . 5-57 Schematic Design From Example 5-31 . . . . . . . . . . . . . 5-59 Modulo-10 Counter Process Design . . . . . . . . . . . . . . . 6-6
Modulo-10 Counter Process With wait Statement Design 6-8 Two Three-State Buffers Driving the Same Signal . . . . . 6-9
Schematic of Nested Blocks . . . . . . . . . . . . . . . . . . . . . . 6-12 Concurrent CHECK Procedure Design. . . . . . . . . . . . . . 6-16 Conditional Signal Assignment Design. . . . . . . . . . . . . . 6-19 Selected Signal Assignment Design. . . . . . . . . . . . . . . . 6-21 A Simple Netlist Design . . . . . . . . . . . . . . . . . . . . . . . . . 6-24 An 8-Bit Array Design . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-29 Design of COMP Components Connecting Bit Vectors A and B 6-30
xxii
Figure 6-11 Figure 7-1 Figure 7-2 Figure 7-3 Figure 7-4 Figure 7-5 Figure 7-6 Figure 7-7 Figure 7-8 Figure 7-9 Figure 7-10 Figure 7-11 Figure 7-12 Figure 7-13 Figure 7-14 Figure 7-15 Figure 7-16 Figure 7-17 Figure 7-18 Figure 7-19 Figure 7-20 Figure 7-21 Figure 7-22
Design of N-Bit Serial-to-Parallel Converter . . . . . . . . . . 6-33 SR Latch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10 D Latch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-13 D Latch With Asynchronous Set . . . . . . . . . . . . . . . . . . . 7-15 D Latch With Asynchronous Reset . . . . . . . . . . . . . . . . . 7-17 D Latch With Asynchronous Set and Reset . . . . . . . . . . 7-19 Two-Phase Clocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-21 Positive Edge-Triggered D Flip-Flop . . . . . . . . . . . . . . . . 7-25 Positive Edge-Triggered D Flip-Flop Using rising_edge . 7-27 Negative Edge-Triggered D Flip-Flop . . . . . . . . . . . . . . . 7-28 Negative Edge-Triggered D Flip-Flop Using falling_edge 7-29 D Flip-Flop With Asynchronous Set . . . . . . . . . . . . . . . . 7-30 D Flip-Flop With Asynchronous Reset . . . . . . . . . . . . . . 7-32 D Flip-Flop With Asynchronous Set and Reset . . . . . . . 7-34 D Flip-Flop With Synchronous Set . . . . . . . . . . . . . . . . . 7-35 D Flip-Flop With Synchronous Reset . . . . . . . . . . . . . . . 7-37 D Flip-Flop With Synchronous and Asynchronous Load 7-38 MultipleFlip-FlopswithAsynchronousandSynchronousControls 7-40 JK Flip-Flop. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-43 JK Flip-Flop With Asynchronous Set and Reset. . . . . . . 7-45 Toggle Flip-Flop With Asynchronous Set . . . . . . . . . . . . 7-47 Toggle Flip-Flop With Asynchronous Reset . . . . . . . . . . 7-49 Toggle Flip-Flop With Enable and Asynchronous Reset. 7-51
xxiii
Figure 7-23 Figure 7-24 Figure 7-25 Figure 7-26 Figure 7-27 Figure 7-28 Figure 7-29 Figure 8-1 Figure 8-2 Figure 8-3 Figure 8-4 Figure 8-5 Figure 8-6 Figure 8-7 Figure 8-8 Figure 8-9 Figure 8-10 Figure 8-11 Figure 8-12 Figure 8-13 Figure 8-14
Circuit With Six Inferred Flip-Flops . . . . . . . . . . . . . . . . . 7-54 Circuit With Three Inferred Flip-Flops . . . . . . . . . . . . . . . 7-56 Schematic of Simple Three-State Driver . . . . . . . . . . . . 7-61 One Three-State Driver Inferred From a Single Process 7-63 Two Three-State Drivers Inferred From Separate Processes 765 Three-State Driver With Registered Enable . . . . . . . . . . 7-67 Three-State Driver Without Registered Enable. . . . . . . . 7-69 Ripple Carry and Carry-Lookahead Chain Design . . . . . Diagram of 4-Input Adder . . . . . . . . . . . . . . . . . . . . . . . . Diagram of 4-Input Adder With Parentheses . . . . . . . . . Default Expression Tree . . . . . . . . . . . . . . . . . . . . . . . . . 8-5 8-5 8-6 8-7
Balanced Adder Tree (Same Arrival Times for All Signals) 8-8 Expression Tree With Minimum Delay (Signal A Arrives Last) 8-9 Expression Tree With Subexpressions Dictated by Parentheses 8-10 Default Expression Tree With 4-Bit Temporary Variable . 8-11 Expression Tree With 5-Bit Intermediate Result . . . . . . . 8-12 Function With One Adder Schematic . . . . . . . . . . . . . . . 8-15 Using TEMP Declaration to Save Circuit Area . . . . . . . . 8-16 Schematic of Simple State Machine With Two Processes 8-19 Schematic of an Improved State Machine . . . . . . . . . . . 8-21 Schematic of Synchronous Counter With Reset and Enable 824
xxiv
Figure 8-15 Figure 8-16 Figure 8-17 Figure 8-18 Figure 8-19 Figure A-1 Figure A-2 Figure A-3 Figure A-4 Figure A-5 Figure A-6 Figure A-7 Figure A-8 Figure A-9
Design With AND Gate on Clock and Enable Signals . . 8-26 Design With Asynchronous Reset . . . . . . . . . . . . . . . . . 8-26 Schematic of Incorrect Asynchronous Design With Gated Clock 8-28 Seven-Segment LED Decoder With Dont Care Type. . . 8-30 Seven-Segment LED Decoder With 0 LED Default . . . . 8-32 Moore Machine Specification . . . . . . . . . . . . . . . . . . . . . Moore Machine Schematic . . . . . . . . . . . . . . . . . . . . . . . Mealy Machine Specification . . . . . . . . . . . . . . . . . . . . . Mealy Machine Schematic . . . . . . . . . . . . . . . . . . . . . . . ROM Schematic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-2 A-4 A-5 A-7 A-9
Waveform Example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-10 Waveform Generator Schematic. . . . . . . . . . . . . . . . . . . A-12 Waveform for Smart Waveform Generator Example. . . . A-13 Smart Waveform Generator Schematic . . . . . . . . . . . . . A-16
Figure A-10 6-Bit Adder-Subtracter Schematic . . . . . . . . . . . . . . . . . A-19 Figure A-11 Count ZerosCombinational Schematic . . . . . . . . . . . . A-21 Figure A-12 Count ZerosSequential Schematic . . . . . . . . . . . . . . . A-24 Figure A-13 Soft Drink MachineState Machine Schematic . . . . . . . A-28 Figure A-14 Soft Drink MachineCount Nickels Version Schematic . A-31 Figure A-15 Carry-Lookahead Adder Block Diagram . . . . . . . . . . . . . A-34 Figure A-16 Sample Waveform Through the Converter . . . . . . . . . . . A-42 Figure A-17 Serial-to-Parallel ConverterCounting Bits Schematic . A-47 Figure A-18 Serial-to-Parallel ConverterShifting Bits Schematic . . A-50
xxv
xxvi
List of Tables
Table 3-1 Table 4-1 Table 7-1 Table 7-2 Table B-1 Table B-2 Table C-1 Array Index Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-12 Predefined VHDL Operators. . . . . . . . . . . . . . . . . . . . . . SR Latch Truth Table (NAND Type) . . . . . . . . . . . . . . . . 4-3 7-9
Truth Table for JK Flip-Flop . . . . . . . . . . . . . . . . . . . . . . . 7-42 UNSIGNED,SIGNED,andBIT_VECTORComparisonFunctions B-4 Number of Bits Returned by + and . . . . . . . . . . . . . . . B-13 VHDL Reserved Words . . . . . . . . . . . . . . . . . . . . . . . . . C-17
xxvii
xxviii
List of Examples
Example 2-1 Example 2-2 Example 2-3 Example 2-4 Example 2-5 Example 2-6 Example 2-7 Example 2-8 Example 2-9 Example 2-10 Example 2-11 Example 2-12 Example 2-13 Example 2-14 Example 2-15 Example 2-16 VHDL Entity Specification . . . . . . . . . . . . . . . . . . . . . . Interface for an N-Bit Counter . . . . . . . . . . . . . . . . . . . An Implementation of a 3-Bit Counter . . . . . . . . . . . . . 2-3 2-5 2-7
Incorrect Use of a Port Name in Declaring Signals or Constants 2-9 Component Declaration of a 2-Input AND Gate . . . . . 2-11 Component Declaration of an N-Bit Adder . . . . . . . . . 2-11 Equivalent Named and Positional Association . . . . . . 2-15 Structural Description of a 3-Bit Counter . . . . . . . . . . 2-15 Constant Declarations. . . . . . . . . . . . . . . . . . . . . . . . . 2-18 Variable Declarations . . . . . . . . . . . . . . . . . . . . . . . . . 2-20 Signal Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-21 Two Subprogram Declarations . . . . . . . . . . . . . . . . . . 2-25 Two Subprogram Calls . . . . . . . . . . . . . . . . . . . . . . . . 2-26 Two Subprogram Bodies . . . . . . . . . . . . . . . . . . . . . . . 2-29 Subprogram Overloading . . . . . . . . . . . . . . . . . . . . . . 2-29 Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . 2-30
xxix
Example 2-17 Example 2-18 Example 2-19 Example 2-20 Example 2-21 Example 2-22 Example 3-1 Example 3-2 Example 3-3 Example 3-4 Example 3-5 Example 3-6 Example 3-7 Example 3-8 Example 3-9 Example 3-10 Example 3-11 Example 3-12 Example 3-13 Example 3-14 Example 3-15 Example 3-16 Example 3-17
Variable Declarations . . . . . . . . . . . . . . . . . . . . . . . . . 2-31 Structural Architecture for Entity NAND2 . . . . . . . . . . 2-33 Data Flow Architecture for Entity NAND2 . . . . . . . . . . 2-34 RTL Architecture for Entity NAND2 . . . . . . . . . . . . . . . 2-34 Sample Package Declarations . . . . . . . . . . . . . . . . . . 2-38 Resolved Signal and Its Resolution Function . . . . . . . 2-42 Enumeration Type Definitions . . . . . . . . . . . . . . . . . . . Enumeration Literal Overloading. . . . . . . . . . . . . . . . . Automatic Enumeration Encoding . . . . . . . . . . . . . . . . Using the ENUM_ENCODING Attribute . . . . . . . . . . . Integer Type Definitions. . . . . . . . . . . . . . . . . . . . . . . . Declaration of Array of Arrays . . . . . . . . . . . . . . . . . . . 3-4 3-4 3-5 3-6 3-8 3-9
Constrained Array Type Definition. . . . . . . . . . . . . . . . 3-10 Unconstrained Array Type Definition . . . . . . . . . . . . . . 3-11 Use of Array Attributes . . . . . . . . . . . . . . . . . . . . . . . . 3-13 Record Type Declaration and Use . . . . . . . . . . . . . . . 3-13 Simple Record Type . . . . . . . . . . . . . . . . . . . . . . . . . . 3-15 Named Aggregate for Example 3-11. . . . . . . . . . . . . . 3-15 Use of others in an Aggregate . . . . . . . . . . . . . . . . . . 3-16 Positional Aggregate . . . . . . . . . . . . . . . . . . . . . . . . . . 3-16 Record Aggregate Equivalent to Example 3-16 . . . . . 3-16 Record Aggregate With Set of Choices . . . . . . . . . . . 3-16 FPGA Compiler II / FPGA Express STANDARD Package 317
xxx
Example 3-18 Example 3-19 Example 4-1 Example 4-2 Example 4-3 Example 4-4 Example 4-5 Example 4-6 Example 4-7 Example 4-8 Example 4-9 Example 4-10 Example 4-11 Example 4-12 Example 4-13 Example 4-14 Example 4-15 Example 4-16 Example 4-17 Example 4-18 Example 4-19 Example 4-20 Example 4-21
Valid and Invalid Assignments Between INTEGER Subtypes 3-22 Attributes and Functions Operating on a Subtype . . . 3-23 Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . True Relational Expressions . . . . . . . . . . . . . . . . . . . . Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . Adding Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3 4-4 4-7 4-7 4-9
Unary (Signed) Operators. . . . . . . . . . . . . . . . . . . . . . 4-10 Multiplying Operators With Powers of 2 . . . . . . . . . . . 4-11 Miscellaneous Arithmetic Operators . . . . . . . . . . . . . . 4-13 Computable and Noncomputable Expressions . . . . . . 4-17 Simple Aggregate . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-19 Equivalent Aggregates . . . . . . . . . . . . . . . . . . . . . . . . 4-20 Equivalent Aggregates Using the others Expression . 4-20 Function Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-23 Sample Extended Identifiers . . . . . . . . . . . . . . . . . . . . 4-23 Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-24 Indexed Name Operands . . . . . . . . . . . . . . . . . . . . . . 4-25 Numeric Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-26 Enumeration Literals . . . . . . . . . . . . . . . . . . . . . . . . . . 4-27 Character String Literals . . . . . . . . . . . . . . . . . . . . . . . 4-28 Bit String Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-29 A Qualified Decimal Literal . . . . . . . . . . . . . . . . . . . . . 4-30
xxxi
Example 4-22 Example 4-23 Example 4-24 Example 4-25 Example 4-26 Example 5-1 Example 5-2 Example 5-3 Example 5-4 Example 5-5 Example 5-6 Example 5-7 Example 5-8 Example 5-9 Example 5-10 Example 5-11 Example 5-12 Example 5-13 Example 5-14 Example 5-15 Example 5-16 Example 5-17 Example 5-18
Qualified Aggregates and Enumeration Literals . . . . . 4-30 Record and Field Access . . . . . . . . . . . . . . . . . . . . . . 4-31 Slice Name Operands . . . . . . . . . . . . . . . . . . . . . . . . . 4-32 Null and Noncomputable Slices . . . . . . . . . . . . . . . . . 4-34 Valid and Invalid Type Conversions. . . . . . . . . . . . . . . 4-35 Simple Name Targets . . . . . . . . . . . . . . . . . . . . . . . . . Indexed Name Targets . . . . . . . . . . . . . . . . . . . . . . . . 5-4 5-5
Computable and Noncomputable Indexed Name Targets 55 Slice Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-7 5-8
Aggregate Targets. . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-10 Variable and Signal Assignments . . . . . . . . . . . . . . . . 5-14 if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-16 case Statement With Enumerated Type . . . . . . . . . . . 5-18 case Statement With Integers . . . . . . . . . . . . . . . . . . . 5-20 Invalid case Statements . . . . . . . . . . . . . . . . . . . . . . . 5-21 for...loop Statement With Equivalent Code Fragments 5-27 for...loop Statement Operating on an Entire Array . . . 5-28 next Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-30 Named next Statement . . . . . . . . . . . . . . . . . . . . . . . . 5-32 Comparator That Uses the exit Statement . . . . . . . . . 5-34 Subprogram Declarations and Bodies . . . . . . . . . . . . 5-37 Procedure Call to Sort an Array . . . . . . . . . . . . . . . . . 5-40
xxxii
Example 5-19 Example 5-20 Example 5-21 Example 5-22 Example 5-23 Example 5-24 Example 5-25 Example 5-26 Example 5-27 Example 5-28 Example 5-29 Example 5-30 Example 5-31 Example 6-1 Example 6-2 Example 6-3 Example 6-4 Example 6-5 Example 6-6 Example 6-7 Example 6-8 Example 6-9 Example 6-10 Example 6-11
Function Definition With Two Calls . . . . . . . . . . . . . . . 5-42 Use of Multiple return Statements. . . . . . . . . . . . . . . . 5-44 Using Component Implication Directives on a Function 5-47 Using Gates to Implement a Function. . . . . . . . . . . . . 5-49 Equivalent wait Statements . . . . . . . . . . . . . . . . . . . . . 5-51 wait for a Positive Edge . . . . . . . . . . . . . . . . . . . . . . . . 5-51 Loop That Uses a wait Statement . . . . . . . . . . . . . . . . 5-52 Multiple wait Statements . . . . . . . . . . . . . . . . . . . . . . . 5-52 wait Statements and State Logic. . . . . . . . . . . . . . . . . 5-53 Synchronous Reset That Uses wait Statements. . . . . 5-54 Invalid Uses of wait Statements . . . . . . . . . . . . . . . . . 5-54 Parity Tester That Uses the wait Statement . . . . . . . . 5-56 null Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-58 Modulo-10 Counter Process . . . . . . . . . . . . . . . . . . . . Modulo-10 Counter Process With wait Statement . . . Multiple Drivers of a Signal . . . . . . . . . . . . . . . . . . . . . 6-5 6-7 6-9
Nested Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-11 Guarded Blocks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12 Level-Sensitive Latch Using Guarded Blocks . . . . . . . 6-13 Concurrent Procedure Call and Equivalent Process. . 6-14 Procedure Definition for Example 6-9 . . . . . . . . . . . . . 6-15 Concurrent Procedure Calls . . . . . . . . . . . . . . . . . . . . 6-16 Concurrent Signal Assignment . . . . . . . . . . . . . . . . . . 6-17 Conditional Signal Assignment . . . . . . . . . . . . . . . . . . 6-19
xxxiii
Example 6-12 Example 6-13 Example 6-14 Example 6-15 Example 6-16 Example 6-17 Example 6-18 Example 6-19 Example 6-20 Example 6-21 Example 7-1 Example 7-2 Example 7-3 Example 7-4 Example 7-5 Example 7-6 Example 7-7 Example 7-8 Example 7-9 Example 7-10 Example 7-11 Example 7-12 Example 7-13
Process Equivalent to Conditional Signal Assignment 6-19 Selected Signal Assignment . . . . . . . . . . . . . . . . . . . . 6-21 Process Equivalent to Selected Signal Assignment . . 6-22 Component Declaration and Instantiations . . . . . . . . . 6-24 A Simple Netlist. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-24 Component Instantiation Statement . . . . . . . . . . . . . . 6-25 Direct Component Instantiation Statement . . . . . . . . . 6-26 for...generate Statement . . . . . . . . . . . . . . . . . . . . . . . 6-28 for...generate Statement Operating on an Entire Array 6-30 Typical Use of if...generate Statements. . . . . . . . . . . . 6-32 Inference Report for a JK Flip-Flop . . . . . . . . . . . . . . . SR Latch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-3 7-9
Inference Report for an SR Latch . . . . . . . . . . . . . . . . 7-10 Latch Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-11 Fully Specified Signal: No Latch Inference . . . . . . . . . 7-11 Function: No Latch Inference . . . . . . . . . . . . . . . . . . . 7-11 D Latch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-13 Inference Report for a D Latch . . . . . . . . . . . . . . . . . . 7-13 D Latch With Asynchronous Set . . . . . . . . . . . . . . . . . 7-14 Inference Report for D Latch With Asynchronous Set 7-15 D Latch With Asynchronous Reset . . . . . . . . . . . . . . . 7-16 Inference Report for D Latch With Asynchronous Reset 716 D Latch With Asynchronous Set and Reset . . . . . . . . 7-18
xxxiv
Example 7-14 Example 7-15 Example 7-16 Example 7-17 Example 7-18 Example 7-19 Example 7-20 Example 7-21 Example 7-22 Example 7-23 Example 7-24 Example 7-25 Example 7-26 Example 7-27 Example 7-28 Example 7-29 Example 7-30 Example 7-31
Inference Report for D Latch With Asynchronous Set and Reset 7-18 Invalid Use of a Conditionally Assigned Variable . . . . 7-19 Two-Phase Clocks. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-20 Inference Reports for Two-Phase Clocks . . . . . . . . . . 7-21 Using a wait Statement to Infer a Flip-Flop . . . . . . . . . 7-23 Using an if Statement to Infer a Flip-Flop . . . . . . . . . . 7-23 Positive Edge-Triggered D Flip-Flop . . . . . . . . . . . . . . 7-25 Inference Report for Positive Edge-Triggered D Flip-Flop 725 Positive Edge-Triggered D Flip-Flop Using rising_edge 7-26 Inference Report for a Positive Edge-Triggered D Flip-Flop Using rising_edge . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-26 Negative Edge-Triggered D Flip-Flop . . . . . . . . . . . . . 7-27 Inference Report for Negative Edge-Triggered D Flip-Flop 7-28 Negative Edge-Triggered D Flip-Flop Using falling_edge 728 Inference Report for a Negative Edge-Triggered D Flip-Flop Using falling_edge. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-29 D Flip-Flop With Asynchronous Set . . . . . . . . . . . . . . 7-30 Inference Report for a D Flip-Flop With Asynchronous Set 7-30 D Flip-Flop With Asynchronous Reset . . . . . . . . . . . . 7-31 Inference Report for a D Flip-Flop With Asynchronous Reset 7-31
xxxv
Example 7-32 Example 7-33 Example 7-34 Example 7-35 Example 7-36 Example 7-37 Example 7-38 Example 7-39 Example 7-40 Example 7-41 Example 7-42 Example 7-43 Example 7-44 Example 7-45 Example 7-46 Example 7-47 Example 7-48 Example 7-49
D Flip-Flop With Asynchronous Set and Reset. . . . . . 7-33 Inference Report for a D Flip-Flop With Asynchronous Set and Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-33 D Flip-Flop With Synchronous Set . . . . . . . . . . . . . . . 7-35 Inference Report for a D Flip-Flop With Synchronous Set 735 D Flip-Flop With Synchronous Reset . . . . . . . . . . . . . 7-36 Inference Report for a D Flip-Flop With Synchronous Reset 7-36 D Flip-Flop With Synchronous and Asynchronous Load 37 7-
Inference Report for a D Flip-Flop With Synchronous and Asynchronous Load . . . . . . . . . . . . . . . . . . . . . . . . . . 7-38 Multiple Flip-Flops: Asynchronous and Synchronous Controls 7-39 Inference Reports for Example 7-40 . . . . . . . . . . . . . . 7-40 JK Flip-Flop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-42 Inference Report for JK Flip-Flop . . . . . . . . . . . . . . . . 7-43 JK Flip-Flop With Asynchronous Set and Reset . . . . . 7-44 Inference Report for JK Flip-Flop With Asynchronous Set and Reset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-45 Toggle Flip-Flop With Asynchronous Set . . . . . . . . . . 7-46 Inference Report for Toggle Flip-Flop With Asynchronous Set 7-47 Toggle Flip-Flop With Asynchronous Reset . . . . . . . . 7-48 InferenceReportforaToggleFlip-FlopWithAsynchronousReset 7-48
xxxvi
Example 7-50 Example 7-51 Example 7-52 Example 7-53 Example 7-54 Example 7-55 Example 7-56 Example 7-57 Example 7-58 Example 7-59 Example 7-60 Example 7-61 Example 7-62 Example 7-63 Example 7-64 Example 7-65 Example 7-66 Example 7-67
Toggle Flip-Flop With Enable and Asynchronous Reset7-50 Inference Report for Toggle Flip-Flop With Enable and Asynchronous Reset . . . . . . . . . . . . . . . . . . . . . . . . . . 7-50 Circuit With Six Inferred Flip-Flops . . . . . . . . . . . . . . . 7-52 Inference Report for Circuit With Six Inferred Flip-Flops 53 7-
Circuit With Three Inferred Flip-Flops . . . . . . . . . . . . . 7-55 Inference Report for Circuit With Three Inferred Flip-Flops 7-55 Delays in Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-57 Three-State Inference Report . . . . . . . . . . . . . . . . . . . 7-59 Simple Three-State Driver. . . . . . . . . . . . . . . . . . . . . . 7-61 Inference Report for Simple Three-State Driver . . . . . 7-61 Inferring One Three-State Driver From a Single Process 762 Single Process Inference Report . . . . . . . . . . . . . . . . 7-62 Inferring Two Three-State Drivers From Separate Processes 7-64 Inference Report Two for Three-State Drivers Separate From Processes 7-64 Inferring a Three-State Driver With Registered Enable 7-66 InferenceReportforThree-StateDriverWithRegisteredEnable 7-66 Three-State Driver Without Registered Enable. . . . . . 7-68 InferenceReportforThree-StateDriverWithoutRegisteredEnable 7-68
xxxvii
Example 7-68 Example 7-69 Example 8-1 Example 8-2 Example 8-3 Example 8-4 Example 8-5 Example 8-6 Example 8-7 Example 8-8 Example 8-9 Example 8-10 Example 8-11 Example 8-12 Example 8-13 Example 8-14 Example 8-15 Example 8-16 Example 8-17 Example 8-18 Example 8-19 Example 8-20 Example 8-21
Incorrect Use of the Z Value in an Expression . . . . . . 7-70 Correct Use of the Z Value in an Expression . . . . . . . 7-70 Four Logic Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ripple Carry Chain . . . . . . . . . . . . . . . . . . . . . . . . . . . Carry-Lookahead Chain . . . . . . . . . . . . . . . . . . . . . . . 4-Input Adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-Input Adder Structured With Parentheses . . . . . . . . Simple Arithmetic Expression . . . . . . . . . . . . . . . . . . . Parentheses in an Arithmetic Expression . . . . . . . . . . 8-2 8-4 8-4 8-5 8-6 8-7 8-9
Adding Numbers of Different Bit-Widths . . . . . . . . . . . 8-11 Simple Additions With a Common Subexpression . . . 8-12 Sharing Common SubexpressionsIncreases Area . 8-13 Common Subexpressions . . . . . . . . . . . . . . . . . . . . . . 8-14 Function With One Adder . . . . . . . . . . . . . . . . . . . . . . 8-15 Using Design Knowledge to Simplify an Adder. . . . . . 8-16 A Simple State Machine . . . . . . . . . . . . . . . . . . . . . . . 8-17 A Better Implementation of a State Machine . . . . . . . 8-20 Equivalent Statements . . . . . . . . . . . . . . . . . . . . . . . . 8-22 Fully Synchronous Counter With Reset and Enable . . 8-24 Design With Gated Clock and Asynchronous Reset. . 8-25 Incorrect Design (Counter With Asynchronous Load). 8-27 Incorrect Asynchronous Design With Gated Clock . . . 8-28 Using dont care Type for Seven-Segment LED Decoder 829
xxxviii
Example 8-22 Example 8-23 Example 9-1 Example A-1 Example A-2 Example A-3 Example A-4 Example A-5 Example A-6 Example A-7 Example A-8 Example A-9
Seven-Segment Decoder Without Dont Care Type . . 8-31 Fully Specified Variables . . . . . . . . . . . . . . . . . . . . . . . 8-35 Using synthesis_on and synthesis_off Directives . . . . Implementation of a Moore Machine. . . . . . . . . . . . . . Implementation of a Mealy Machine . . . . . . . . . . . . . . Implementation of a ROM in Random Logic . . . . . . . . 9-4 A-3 A-5 A-8
Implementation of a Waveform Generator . . . . . . . . . A-11 Implementation of a Smart Waveform Generator . . . . A-14 MATH Package for Example A-7 . . . . . . . . . . . . . . . . . A-17 Implementation of a 6-Bit Adder-Subtracter . . . . . . . . A-18 Count ZerosCombinational . . . . . . . . . . . . . . . . . . . A-20 Count ZerosSequential . . . . . . . . . . . . . . . . . . . . . . A-22
Example A-10 Soft Drink MachineState Machine . . . . . . . . . . . . . . A-25 Example A-11 Soft Drink MachineCount Nickels . . . . . . . . . . . . . . A-29 Example A-12 Carry-Lookahead Adder . . . . . . . . . . . . . . . . . . . . . . . A-35 Example A-13 Serial-to-Parallel ConverterCounting Bits . . . . . . . . A-45 Example A-14 Serial-to-Parallel ConverterShifting Bits . . . . . . . . . A-48 Example A-15 Programmable Logic Array . . . . . . . . . . . . . . . . . . . . . A-53 Example B-1 Example B-2 Example B-3 Example B-4 Example B-5 New Function Based on a std_logic_arith Package Function B-5 UNSIGNED Declarations . . . . . . . . . . . . . . . . . . . . . . SIGNED Declarations . . . . . . . . . . . . . . . . . . . . . . . . . Conversion Functions . . . . . . . . . . . . . . . . . . . . . . . . . B-7 B-8 B-8
xxxix
Unary Arithmetic Functions. . . . . . . . . . . . . . . . . . . . . B-12 Using the Carry-Out Bit. . . . . . . . . . . . . . . . . . . . . . . . B-13 Ordering Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . B-14 Equality Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . B-14
Example B-10 Shift Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-15 Example B-11 Shift Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-16 Example B-12 Using a built_in pragma . . . . . . . . . . . . . . . . . . . . . . . B-17 Example B-13 Built-In AND for Arrays . . . . . . . . . . . . . . . . . . . . . . . . B-18 Example B-14 Built-In NOT for Arrays . . . . . . . . . . . . . . . . . . . . . . . . B-19 Example B-15 Use of SYN_FEED_THRU . . . . . . . . . . . . . . . . . . . . . B-20 Example B-16 numeric_std Conversion Functions . . . . . . . . . . . . . . . B-22 Example B-17 numeric_std Resize Function . . . . . . . . . . . . . . . . . . . B-23 Example B-18 numeric_std Binary Arithmetic Functions . . . . . . . . . . B-24 Example B-19 numeric_std Unary Arithmetic Functions . . . . . . . . . . B-24 Example B-20 numeric_std Ordering Functions. . . . . . . . . . . . . . . . . B-25 Example B-21 numeric_std Equality Functions . . . . . . . . . . . . . . . . . B-26 Example B-22 numeric_std Logical Operators Functions. . . . . . . . . . B-26 Example B-23 numeric_std Shift Functions . . . . . . . . . . . . . . . . . . . . B-27 Example B-24 numeric_std Rotate Functions . . . . . . . . . . . . . . . . . . B-28 Example B-25 numeric_std Shift Operators . . . . . . . . . . . . . . . . . . . . B-28 Example B-26 Some numeric_std Shift Functions and Shift Operators 29 B-
Example B-27 Boolean Reduction Functions . . . . . . . . . . . . . . . . . . . B-30 Example B-28 Boolean Reduction Operations . . . . . . . . . . . . . . . . . . B-31
xl
C-9
Sample Showing Use of Shift and Rotate Operators . C-11 Sample Showing Use of xnor Operator. . . . . . . . . . . . C-11
xli
xlii
1
Using FPGA Compiler II / FPGA Express with VHDL 1
FPGA Compiler II / FPGA Express translates a VHDL description to an internal gate-level equivalent format. This format is then optimized for a given FPGA technology. This chapter contains the following sections: Hardware Description Languages About VHDL FPGA Compiler II / FPGA Express Design Process Using FPGA Compiler II / FPGA Express to Compile a VHDL Design Design Methodology
The United States Department of Defense, as part of its Very High Speed Integrated Circuit (VHSIC) program, developed VHSIC HDL (VHDL) in 1982. VHDL describes the behavior, function, inputs, and outputs of a digital circuit design. VHDL is similar in style and syntax to modern programing languages, but includes many hardwarespecific constructs. FPGA Compiler II / FPGA Express reads and parses the supported VHDL syntax. Appendix C, "VHDL Constructs, lists all VHDL constructs and includes the level of Synopsys support provided for each construct.
Advantages of HDLs
A design methodology that uses HDLs has several fundamental advantages over a traditional gate-level design methodology. Among the advantages are the following: You can verify design functionality early in the design process and immediately simulate a design written as an HDL description. Design simulation at this higher level, before implementation at the gate level, allows you to test architectural and design decisions. FPGA Compiler II / FPGA Express provides logic synthesis and optimization, so you can automatically convert a VHDL description to a gate-level implementation in a given technology. This methodology eliminates the former gate-level design bottleneck and reduces circuit design time and errors introduced when handtranslating a VHDL specification to gates.
With FPGA Compiler II / FPGA Express logic optimization, you can automatically transform a synthesized design to a smaller and faster circuit. You can apply information gained from the synthesized and optimized circuits back to the VHDL description, perhaps to fine-tune architectural decisions. HDL descriptions provide technology-independent documentation of a design and its functionality. An HDL description is more easily read and understood than a netlist or schematic description. Because the initial HDL design description is technology-independent, you can later reuse it to generate the design in a different technology, without having to translate from the original technology. VHDL, like most high-level software languages, provides strong type checking. A component that expects a four-bit-wide signal type cannot be connected to a three- or five-bit-wide signal; this mismatch causes an error when the HDL description is compiled. If a variables range is defined as 1 to 15, an error results from assigning it a value of 0. Incorrect use of types has been shown to be a major source of errors in descriptions. Type checking catches this kind of error in the HDL description even before a design is generated.
About VHDL
VHDL is one of a few HDLs in widespread use today. VHDL is recognized as a standard HDL by the Institute of Electrical and Electronics Engineers (IEEE Standard 1076, ratified in 1987) and by the United States Department of Defense (MIL-STD-454L).
VHDL divides entities (components, circuits, or systems) into an external or visible part (entity name and connections) and an internal or hidden part (entity algorithm and implementation). After you define the external interface to an entity, other entities can use that entity when they all are being developed. This concept of internal and external views is central to a VHDL view of system design. An entity is defined, relative to other entities, by its connections and behavior. You can explore alternate implementations (architectures) of an entity without changing the rest of the design. After you define an entity for one design, you can reuse it in other designs as needed. You can develop libraries of entities for use by many designs or for a family of designs. The VHDL hardware model is shown in Figure 1-1.
Process
Sequential Process wait ... ; if A then X else Y end if;
Process
Combinational Process
red, blue
Ports
(Signals)
0 to 15
Component
A VHDL entity (design) has one or more input, output, or inout ports that are connected (wired) to neighboring systems. An entity is composed of interconnected entities, processes, and components, all of which operate concurrently. Each entity is defined by a particular architecture, which is composed of VHDL constructs such as arithmetic, signal assignment, or component instantiation statements. In VHDL independent processes model sequential (clocked) circuits, using flip-flops and latches, and combinational (unclocked) circuits, using only logic gates. Processes can define and call (instantiate) subprograms (subdesigns). Processes communicate with each other by signals (wires). A signal has a source (driver), one or more destinations (receivers), and a user-defined type, such as color or number between 0 and 15. VHDL provides a broad set of constructs. With VHDL, you can describe discrete electronic systems of varying complexity (systems, boards, chips, or modules) with varying levels of abstraction. VHDL language constructs are divided into three categories by their level of abstraction: behavioral, dataflow, and structural. These categories are described as follows:
behavioral The functional or algorithmic aspects of a design, expressed in a sequential VHDL process. dataflow The view of data as flowing through a design, from input to output. An operation is defined in terms of a collection of data transformations, expressed as concurrent statements.
structural The view closest to hardware; a model where the components of a design are interconnected. This view is expressed by component instantiations.
FPGA Compiler II / FPGA Express synthesizes VHDL descriptions according to the VHDL synthesis policy defined in Chapter 2, "Design Descriptions. The Synopsys VHDL synthesis policy has three parts: design methodology, design style, and language constructs. You use the VHDL synthesis policy to produce high quality VHDL-based designs.
The following section describes the design process that uses FPGA Compiler II / FPGA Express with a VHDL simulator.
Design Methodology
Figure 1-2 shows a typical design process that uses FPGA Compiler II / FPGA Express and a VHDL simulator.
1.
VHDL Description
2.
4.
5.
3.
VHDL Simulator
6.
VHDL Simulator
Simulation Output
7.
Compare Output
Simulation Output
Figure 1-2 illustrates the following steps: 1. Write a design description in VHDL. This description can be a combination of structural and functional elements (as shown in Chapter 2, "Design Descriptions). This description is used with both FPGA Compiler II / FPGA Express and the VHDL simulator. 2. Provide VHDL test drivers for the simulator. For information on writing these drivers, see the appropriate simulator manual. The drivers supply test vectors for simulation and other output data. 3. Simulate the design by using a VHDL simulator. Verify that the description is correct. 4. Use FPGA Compiler II / FPGA Express to synthesize and optimize the VHDL design description into a gate-level netlist. FPGA Compiler II / FPGA Express generates optimized netlists to satisfy timing constraints for a targeted FPGA architecture. 5. Use your FPGA development system to link the FPGA technologyspecific version of the design to the VHDL simulator. The development system includes simulation models and interfaces required for the design flow. 6. Simulate the technology-specific version of the design with the VHDL simulator. You can use the original VHDL simulation drivers from step 3because module and port definitions are preserved through the translation and optimization processes. 7. Compare the output of the gate-level simulation (step 6) against the original VHDL description simulation (step 3) to verify that the implementation is correct.
2
Design Descriptions 2
Each VHDL structural design can have four parts, which this chapter discusses in the following major sections: Entities Architecture Configurations Packages
This chapter also contains the section Resolution Functions on page 2-40.
Entities
An entity defines the input and output ports of a design. A design can contain more than one entity. Each entity has its own architecture statement. The syntax is
entity entity_name is [ generic ( generic_declarations );] [ port ( port_declarations ) ;] end [ entity_name ] ;
entity_name The name of the entity. - generic_declarations determine local constants used for sizing or timing the entity. - port_declarations determine the number and type of input and output ports. You cannot use the declaration of other in the entity specification. An entity serves as an interface to other designs, by defining entity characteristics that must be known to FPGA Compiler II / FPGA Express before it can connect the entity to other entities and components. For example, before you can connect a counter to other entities, you must specify the number and types of its input and output ports, as shown in Example 2-1.
constant_name The name of a generic constant. - type is a previously defined data type. - Optional value is the default value of constant_name.
port_name The name of the port. mode Any of these four values: in Can only be read. out Can only be assigned a value. inout Can be read and assigned a value. The value read is that of the ports incoming value, not the assigned value (if any). buffer Similar to out but can be read. The value read is the assigned value. It can have only one driver. For more information about drivers, see Driving Signals on page 6-8. port_type A previously defined data type.
Example 2-2 shows an entity specification for a 2-input N-bit comparator with a default bit-width of 8.
-- default is 8 bits
Architecture
Architecture, which determines the implementation of an entity, can range in abstraction from an algorithm (a set of sequential statements within a process) to a structural netlist (a set of component instantiations). The syntax is
architecture architecture_name of entity_name is { block_declarative_item } begin { concurrent_statement } end [ architecture_name ] ;
architecture_name The name of the architecture. entity_name The name of the entity being implemented.
block_declarative_item Any of the following statements: - use statement (see Package Uses on page 2-35) - subprogram declaration (Subprogram Declarations on page 2-23) - subprogram body (Subprogram Body on page 2-26) - type declaration (see Types on page 2-31) - subtype declaration (see Subtypes on page 2-32) - constant declaration (see Constants on page 2-18) - signal declaration (see Signals on page 2-21) - component declaration (see Subtypes on page 2-32) - concurrent statement Defines a unit of computation that reads signals, performs computations, and assigns values to signals (see Concurrent Statements on page 2-17). Example 2-3 shows a description for a 3-bit counter that contains an entity specification and an architecture statement: Entity specification for COUNTER3 Architecture statement, MY_ARCH
Note: In an architecture, you must not give constants or signals the same name as any of the entitys ports in the entity specification. If you declare a constant or signal with a ports name, the new declaration hides that port name. If the new declaration lies directly in the architecture declaration (as shown in Example 2-4) and not in an inner block, FPGA Compiler II / FPGA Express reports an error.
Declarations
An architecture consists of a declaration section where you declare Components Concurrent statements Constants Processes Signals Subprograms Types
Components
If your design consists only of VHDL entity statements, every component declaration in the architecture or package statement has to correspond to an entity. Components declared in an architecture are local to that architecture. The syntax is
component identifier [ generic( generic_declarations ); ] [ port( port_declarations ); ] end component ;
identifier The name of the component. You cannot use names preceded by GTECH_ for components other than ones provided by Synopsys. However, you can use GTECH to precede a name if it is used without an underscore, as in GTECHBUSTBUF. generic_declaration Determines local constants used for sizing or timing the component. port_declaration Determines the number and type of input and output ports. Example 2-5 shows a simple component declaration statement.
Example 2-6 shows a component declaration statement that uses a generic parameter.
The component declaration makes a design entity (AND2 in Example 2-5, ADD in Example 2-6) usable within an architecture. You must declare a component in an architecture or package before you can instantiate it. Sources of Components A declared component can come from The same VHDL source file A different VHDL source file Another format, such as EDIF or XNF A component from a technology library
Consistency of Component Ports FPGA Compiler II / FPGA Express checks for consistency among its VHDL entities. For other entities, the port names are taken from the original design description, as follows: For components in a technology library, the port names are the input and output pin names. For EDIF designs, the port names are the EDIF port names.
The bit-widths of each port must match. For VHDL components, FPGA Compiler II / FPGA Express verifies matching. For components from other sources, FPGA Compiler II / FPGA Express checks when linking the component to the VHDL description.
Component Instantiation Statements You use a component instantiation statement to define a design hierarchy or build a netlist in VHDL. A netlist is a structural description of a design. To form a netlist, use component instantiation statements to instantiate and connect components. A component instantiation statement create a new level of design hierarchy. The syntax of the component instantiation statement is
instance_name : component_name [ generic map ( generic_name => expression { , generic_name => expression } ) ] port map ( [ port_name => ] expression { , [ port_name => ] expression } );
generic map (optional) Maps nondefault values onto generics. Each generic_name is the name of a generic exactly as declared in the corresponding component declaration statement. Each expression evaluates to an appropriate value.
U1 : ADD generic map (N => 4)
port map Maps the components ports onto connections. Each port_name is the name of a port, exactly as declared in the corresponding component declaration statement. Each expression evaluates to a signal value.
U1 : ADD generic map (N => 4) port map (X, Y, Z, CARRY) ;
FPGA Compiler II / FPGA Express uses the following two rules to select which entity and architecture to associate with a component instantiation: 1. Each component declaration must have an entitya VHDL entity, a design entity from another source or format, or a library componentwith the same name. This entity is used for each component instantiation associated with the component declaration. 2. A VHDL entity may have only one architecture associated with it. If multiple architectures are available, add only one of these files to the Design Sources window. Mapping Generic Values When you instantiate a component with generics, you can map generics to values. A generic without a default value must be instantiated with a generic map value. For example, a 4-bit instantiation of the component ADD from Example 2-6 on page 2-11 might use the following generic map:
U1: ADD generic map (N => 4) port map (X, Y, Z, CARRY);
Mapping Port Connections The port map maps component ports to actual signals. Use named or positional association to specify port connections in component instantiation statements, as follows: To identify the specific ports of the component, use named association. The port_name => construction identifies the ports. To list the component port expressions in the declared port order, use positional association.
Example 2-7 shows named and positional association for the U5 component instantiation statement in Example 2-8.
Note: When you use positional association, the instantiated port expressions (signals) must be in the same order as the ports in the component declaration statement. Example 2-8 shows a structural netlist description for the COUNTER3 design entity from Example 2-3 on page 2-7.
component AND2 port(I1, I2: in BIT; O: out BIT); end component; component OR2 port(I1, I2: in BIT; O: out BIT); end component; component NAND2 port(I1, I2: in BIT; O: out BIT); end component; component XNOR2 port(I1, I2: in BIT; O: out BIT); end component; component INV port(I: in BIT; O: out BIT); end component; signal N1, N2, N3, N4, N5, N6, N7, N8, N9: BIT; begin u1: DFF port map(CLK, N1, N2); u2: DFF port map(CLK, N5, N3); u3: DFF port map(CLK, N9, N4); u4: INV port map(N2, N1); u5: OR2 port map(N3, N1, N6); u6: NAND2 port map(N1, N3, N7); u7: NAND2 port map(N6, N7, N5); u8: XNOR2 port map(N8, N4, N9); u9: NAND2 port map(N2, N3, N8); COUNT(0) <= N2; COUNT(1) <= N3; COUNT(2) <= N4; end STRUCTURE;
Concurrent Statements
Each concurrent statement in an architecture defines a unit of computation that Reads signals Performs a computation that is based on the values of the signals Assigns the computed values to the signals
Concurrent statements all compute their values at the same time. Although the order of concurrent statements has no effect on the order in which FPGA Compiler II / FPGA Express executes them, concurrent statements coordinate their processing by communicating with each other through signals. The five kinds of concurrent statements are Block Groups a set of concurrent statements. Component instantiation Creates an instance of an entity, connecting its interface ports to signals or interface ports of the entity being defined. See Component Instantiation Statements on page 2-13. Procedure call Calls algorithms that compute and assign values to signals. Process Defines sequential algorithms that read the values of signals and compute new values to assign to other signals. For a discussion of processes, see Processes on page 2-19.
Signal assignments Assign computed values to signals or interface ports. Concurrent statements are described further in Chapter 6, "Concurrent Statements.
Constants
Constant declarations create named values of a given type. The value of a constant can be read but not changed. Constant declarations are allowed in architectures, packages, entities, blocks, processes, and subprograms. Constants declared in an architecture are local to that architecture. Example 2-9 shows some constant declarations.
You can use constants in expressions, as described in Identifiers on page 4-23 and Literals on page 4-26, and as source values in assignment statements, as described in Assignment Statements and Targets on page 5-2.
Processes
A process, which is declared within an architecture, is a concurrent statement. But it is made up of sequentially executed statements that define algorithms. The sequential statements can be any of the following, all of which are discussed in Chapter 5, "Sequential Statements: case statement exit statement if statement loop statement next statement null statement Procedure call Signal assignment Variable assignment wait statement
Processes, like all other concurrent statements, read and write signals and the values of interface ports to communicate with the rest of the architecture and with the enclosing system. Processes are unique in that they behave like concurrent statements to the rest of the design, but they are internally sequential. In addition, only processes can define variables to hold intermediate values in a sequence of computations.
Because the statements in a process are sequentially executed, several constructs, such as if and loop statements, are provided to control the order of execution. Variable Declarations Variable declarations define a named value of a given type. Example 2-10 shows some variable declarations.
You can use variables in expressions, as described in Chapter 4, "Expressions. You assign values to variables by using variable assignment statements, as described in Variable Assignment Statements on page 5-11. FPGA Compiler II / FPGA Express does not support variable initialization. If you try to initialize a variable, FPGA Compiler II / FPGA Express generates the following message:
Warning: Initial values for signals are not supported for synthesis. They are ignored on line %n (VHDL-2022)
Note: Variables are declared and used only in processes and subprograms, because processes and subprograms cannot declare signals for internal use.
Signals
Signals connect the separate concurrent statements of an architecture to each other, and to other parts of a design, through interface ports. Signal declarations create new named signals (wires) of a given type. Signals can be given default (initial) values, but these initial values are ignored for synthesis. Signals with multiple drivers (signals driven by wired logic) can have associated resolution functions, as described in Resolution Functions on page 2-40. Example 2-11 shows two signal declarations.
Note: Ports are also signals, with the restriction that out ports cannot be read and in ports cannot be assigned a value. You create signals either with port declarations or with signal declarations. You create ports only with port declarations. You can declare signals in architectures, entities, and blocks and can use them in processes and subprograms. Processes and subprograms cannot declare signals for internal use. You can use signals in expressions, as described in Chapter 5, "Sequential Statements. Signals are assigned values by signal assignment statements, as described in Signal Assignment Statements on page 5-12.
Subprograms
Subprograms use sequential statements to define algorithms and are useful for performing repeated calculations, often in different parts of an architecture (see Subprograms on page 5-35). Subprograms declared in an architecture are local to that architecture. Subprograms differ from processes, in that subprograms cannot directly read or write signals from the rest of the architecture. All communication is through the subprograms interface. Each subprogram call has its own set of interface signals. Signal declarations create new named signals (wires) of a given type. Signals can be given default (initial) values, but these initial values are ignored for synthesis. Signals with multiple drivers (signals driven by wired logic) can have associated resolution functions, as described in Resolution Functions on page 2-40. Subprograms also differ from component instantiation statements, in that the use of a subprogram by an entity or another subprogram does not create a new level of design hierarchy. There are two types of subprograms, which can have zero or more parameters: Procedure Subprogram A procedure returns zero or more values through its interface. Function Subprogram A function returns a single value directly.
Note: When you declare a subprogram in a package, the subprogram declaration must be in the package declaration and the subprogram body must be in the package body. When you declare a subprogram in an architecture, the program body must be in the architecture body but there is no corresponding subprogram declaration. Subprogram Declarations A declaration lists the names and types of the subprograms parameters and, for functions, the type of the subprograms return value. Procedure Declaration Syntax The syntax of a procedure declaration is
procedure proc_name [ ( parameter_declarations ) ] ;
proc_name The name of the procedure. parameter_declarations Specify the number and type of input and output ports. The syntax is
[ parameter_name : { ; parameter_name :
parameter_name The name of a parameter. mode Procedure parameters can be any of these four modes: in Can only be read. out Can only be assigned a value. inout Can be read and assigned a value. The value read is that of the ports incoming value, not the assigned value (if any). buffer Similar to out but can be read. The value read is the assigned value. A buffer can have only one driver. For more information about drivers, see Driving Signals on page 6-8. parameter_type A previously defined data type. Function Declaration Syntax The syntax of a function declaration is
function func_name [ ( parameter_declarations ) return type_name ;
func_name The name of the function. type_name The type of the functions returned value. Signal parameters of type range cannot be passed to a subprogram.
parameter_declarations Specify the number and type of input and output ports. The syntax is
[ parameter_name : { ; parameter_name :
parameter_name The name of a parameter. mode Function parameters can only use the in mode: in Can only be read. parameter_type A previously defined data type. Declaration Examples Example 2-12 shows sample subprogram declarations for a function and a procedure.
When FPGA Compiler II / FPGA Express calls a subprogram, it substitutes actual parameters for the declared formal parameters.
Actual parameters are Constant values Names of signals, variables, constants, or ports
An actual parameter must support the type and mode of the formal parameter. For example, FPGA Compiler II / FPGA Express does not accept an input port as an out actual parameter and uses a constant only as an in actual parameter. Example 2-13 shows some calls to the subprogram declarations from Example 2-12.
procedure_name Name of the procedure subprogram_declarative_item A subprogram_declarative_item can be any of the following statements: - use clause - type declaration - subtype declaration - constant declaration - variable declaration - attribute declaration - attribute specification - subprogram declaration (for local or nested subprograms) - subprogram body (for locally declared subprograms)
function_name Name of the function subprogram_declarative_item A subprogram_declarative_item can be any of the following statements: - use clause - type declaration - subtype declaration - constant declaration - variable declaration - attribute declaration - attribute specification - subprogram declaration (for local or nested subprograms) - subprogram body (for locally declared subprograms) Example 2-14 shows subprogram bodies for the sample subprogram declarations in Example 2-12 on page 2-25.
Subprogram Overloading You can overload subprograms, which means that one or more subprograms can have the same name. Each subprogram that uses a given name must have a different parameter profile. A parameter profile specifies a subprograms number and type of parameters. This information determines which subprogram is called when more than one subprogram has the same name. Overloaded functions are also distinguished by the type of their return values. Example 2-15 shows two subprograms with the same name (IS_ODD) but different parameter profiles.
Operator Overloading You can overload predefined operators such as +, and, and mod. By using overloading, you can adapt predefined operators to work with your own data types. For example, you can declare new logic types rather than use the predefined types BIT and INTEGER. However, you cannot use predefined operators with these new types unless you overload the operators for the types. Example 2-16 shows how some predefined operators are overloaded for a new logic type.
VHDL requires that overloaded operator declarations enclose the operator name or symbol in double quotation marks, because operator name and symbol are infix operators (they are used between operands). If you declare the overloaded operators without quotation marks, a VHDL tool considers them functions rather than operators.
Variable Declarations Variable declarations define a named value of a given type. You can use variables in expressions, as described in Identifiers on page 4-23 and Literals on page 4-26. You assign values to variables by using variable assignment statements, as described in Variable Assignment Statements on page 5-11. FPGA Compiler II / FPGA Express does not support variable initialization. If you try to initialize a variable, FPGA Compiler II / FPGA Express generates the following message:
Warning: Initial values for signals are not supported for synthesis. They are ignored on line %n (VHDL-2022)
Note: Variables are declared and used only in processes and subprograms, because processes and subprograms cannot declare signals for internal use. To use these declarations in more than one entity or architecture, place them in a package, as described in Packages on page 2-35.
Types
You declare each signal with a type that determines the kind of data it carries. Types declared in an architecture are local to that architecture.
You can use type declarations in architectures, packages, entities, blocks, processes, and subprograms. Type declarations define the name and characteristics of a type. Types and type declarations are fully described in Chapter 3, "Data Types. A type is a named set of values, such as the set of integers or the set of colors (red, green, and blue). An object of a given type, such as a signal, can have any value of that type. You can see an example of a type declaration for type NEW_BIT in Example 2-16 on page 2-30. Subtypes Use subtype declarations to define the name and characteristics of a constrained subset of another type or subtype. A subtype is fully compatible with its parent type, but only over the subtypes range. The following subtype declaration (NEW_LOGIC) is a subrange of the type declaration in Example 2-16 on page 2-30.
subtype NEW_LOGIC is NEW_BIT range 0 to 1;
You can use subtype declarations wherever you use type declarations: in architectures, packages, entities, blocks, processes, and subprograms.
begin U0: AND_2 port map (I1 => A, I2 => B, O1 => I); U1: INVERT port map (I1 => I, O1 => Z); end STRUCTURAL;
Example 2-19 shows how you can define the entity NAND2 by its logical function.
Configurations
Configurations are not currently supported by FPGA Compiler II / FPGA Express.
Packages
A package is a collection of declarations that more than one design can use. You can collect constants, data types, component declarations, and subprograms into a VHDL package that can then be used by more than one design or entity. A package must contain at least one of the following constructs: Constant Declares systemwide parameters, such as data-path widths. VHDL data type declaration Defines data types used throughout a design. All entities in a design must use common interface types, such as common address bus types. Component declaration Specifies the interfaces to entities that can be instantiated in the design. Subprogram Defines algorithms that can be called anywhere in a design. Packages are often sufficiently general that they are usable in many different designs. For example, the std_logic_1164 package defines data types std_logic and std_logic_vector.
Package Uses
The use statement allow an entity to use the declarations in a package.
The syntax is
use LIBRARY_NAME.PACKAGE_NAME.ALL;
LIBRARY_NAME The name of a VHDL library. PACKAGE_NAME The name of the included package. A use statement is usually the first statement in a package or entity specification source file. Note: Synopsys does not support different packages with the same name when they exist in different libraries. No two packages can have the same name.
Package Structure
Packages have two parts: the declaration and the body. Package declaration Holds public information, including constant, type, and subprogram declarations. Package body Holds private information, including local types and subprogram implementations (bodies). Note: When a package declaration contains subprogram declarations, a corresponding package body must define the subprogram bodies.
Package Declarations
Package declarations collect information that are needed by one or more entities in a design. This information includes data type declarations, signal declarations, subprogram declarations, and component declarations. Note: Signals declared in packages cannot be shared across entities. If two entities both use a signal from a given package, each entity has its own copy of that signal. Although you can declare all this information explicitly in each design entity or architecture in a system, it is often easier to declare system information in a separate package. Each design entity in the system can then use the systems package. The syntax of a package declaration is
package package_name is { package_declarative_item } end [ package_name ] ;
package_name The name of this package. package_declarative_item Any of the following statements: - use clause (to include other packages) - type declaration - subtype declaration - constant declaration
- signal declaration - subprogram declaration - component declaration Example 2-21 shows some package declarations.
To use the previous example declarations, add a use statement at the beginning of your design description as follows:
use WORK.EXAMPLE.ALL; entity . . . architecture . . .
Appendix B, "Synopsys Packages, contains more examples of packages and their declarations.
Package Body
A package body includes The implementations (bodies) of subprograms declared in the package declaration Internal support subprograms
But designs or entities that use the package never see this information. The syntax of a package body is
package body package_name is { { package_body_declarative_item } end [ package_name ] ;
package_name The name of the associated package. package_body_declarative_item Any of the following statements: - use clause - subprogram declaration - subprogram body - type declaration - subtype declaration - constant declaration Appendix B, "Synopsys Packages, shows a package declaration and body example that comes with FPGA Compiler II / FPGA Express.
Design Descriptions 2-39
Resolution Functions
Resolution functions are used with signals that can be connected (wired together). For example, if two drivers directly connect to a signal, the resolution function determines whether the signal value is the AND, OR, or three-state function of the driving values. Use resolution functions to assign the driving values when there are multiple drivers. For simulation, you can write an arbitrary function to resolve bus conflicts. Note: A resolution function might change the value of a resolved signal even if all drivers have the same value. The resolution function for a signal is part of that signals subtype declaration. You create a resolved signal in four steps: 1. Declare the signals base type.
type SIGNAL_TYPE is ... -- signals base type is SIGNAL_TYPE
3. Declare the resolved signals subtype as a subtype of the base type, which includes the name of the resolution function.
subtype res_type is res_function SIGNAL_TYPE; -- name of the subtype is res_type -- name of function is res_function -- signal type is res_type (a subtype of SIGNAL_TYPE)
FPGA Compiler II / FPGA Express does not support arbitrary resolution functions. Only wired AND, wired OR, and three-state functions are allowed. FPGA Compiler II / FPGA Express requires that you mark all resolution functions with a special directive indicating the kind of resolution being performed. FPGA Compiler II / FPGA Express considers the directive only when creating hardware. The body of the resolution function is parsed but ignored; using unsupported VHDL constructs generates errors (see Appendix C, "VHDL Constructs). Do not connect signals that use different resolution functions. FPGA Compiler II / FPGA Express supports only one resolution function per network. The three resolution function directives are synopsys resolution_method wired_and synopsys resolution_method wired_or synopsys resolution_method three_state
Pre-synthesis and post-synthesis simulation results might not match if the body of the resolution function the simulator uses does not match the directive the synthesizer uses. Example 2-22 shows how to create and use a resolved signal and how to use compiler directives for resolution functions. The signals base type is the predefined type BIT. Figure 2-2 shows the design.
X Y
AN2
3
Data Types 3
VHDL is a strongly typed language. Every constant, signal, variable, function, and parameter is declared with a type, such as BOOLEAN or INTEGER, and can hold or return only a value of that type. VHDL predefines abstract data types such as BOOLEAN, which are part of most programming languages, and hardware-related types, such as BIT, which are found in most hardware languages. VHDL predefined types are declared in the STANDARD package supplied with all VHDL implementations (see Example 3-17 on page 3-17). This chapter includes information about Enumeration Types Integer Types Array Types Record Types
Predefined VHDL Data Types Unsupported Data Types Synopsys Data Types Subtypes
The advantage of strong typing is that VHDL tools can detect many common design errors, such as assigning an 8-bit value to a 4-bit-wide signal, or detect incrementing of an array index out of its range. The following code shows the definition of a new type, BYTE, as an array of 8 bits and a variable declaration, ADDEND, which uses this type.
type BYTE is array(7 downto 0) of BIT; variable ADDEND: BYTE;
The predefined VHDL data types are built from the basic VHDL data types. Some VHDL types, such as REAL and FILE, are not supported for synthesis. The examples in this chapter show type definitions and associated object declarations. Although each constant, signal, variable, function, and parameter is declared with a type, only variable and signal declarations are shown in the examples. For more information about constant, function, and parameter declarations, see Declarations on page 2-10.
VHDL also provides subtypes, which are defined as subsets of other types. Anywhere a type definition can appear, a subtype definition can also appear. The difference between a type and a subtype is that a subtype is a subset of a previously defined parent (or base) type or subtype. Overlapping subtypes of a given base type can be compared against and assigned to each other. All integer types, for example, are technically subtypes of the built-in integer base type (see Integer Types on page 3-8 and Subtypes on page 3-21).
Enumeration Types
You define an enumeration type by listing (enumerating) all possible values of that type. The syntax of an enumeration type definition is
type type_name is ( enumeration_literal {, enumeration_literal} );
type_name An identifier. Each enumeration_literal is either an identifier (enum_6) or a character literal (A). An identifier is a sequence of letters, underscores, and numbers. It must start with a letter and cannot be a VHDL reserved word, such as TYPE. All VHDL reserved words are listed in VHDL Reserved Words on page C-17. A character literal is any value of type CHARACTER, in single quotation marks. Example 3-1 shows two enumeration type definitions and corresponding variable and signal declarations.
Enumeration Overloading
You can overload an enumeration literal by including it in the definition of two or more enumeration types. When you use such an overloaded enumeration literal, FPGA Compiler II / FPGA Express is usually able to determine the literals type. However, under certain circumstances determination might be impossible. In these cases, you must qualify the literal by explicitly stating its type. (See Enumeration Literals on page 4-27.) Example 3-2 shows how you can qualify an overloaded enumeration literal.
Enumeration Encoding
Enumeration types are ordered by enumeration value. By default, the first enumeration literal is assigned the value 0, the next enumeration literal is assigned the value 1, and so forth.
FPGA Compiler II / FPGA Express automatically encodes enumeration values into bit vectors that are based on each values position. The length of the encoding bit vector is the minimum number of bits required to encode the number of enumerated values. For example, an enumeration type with five values would have a 3-bit encoding vector. Example 3-3 shows the default encoding of an enumeration type with five values.
The result is RED < GREEN < YELLOW < BLUE < VIOLET. You can override the automatic enumeration encodings and specify your own enumeration encodings with the ENUM_ENCODING attribute. This interpretation is specific to FPGA Compiler II / FPGA Express. A VHDL attribute is defined by its name and type and is then declared with a value for the attributed type, as shown in Example 3-4. Several VHDL synthesis-related attributes are declared in the ATTRIBUTES package supplied with FPGA Compiler II / FPGA Express. For more information about this package, see ATTRIBUTES Package on page B-31.
The ENUM_ENCODING attribute must be a string containing a series of vectors, one for each enumeration literal in the associated type. The encoding vector is specified by 0s, 1s, Ds, Us, and Zs, separated by blank spaces. The meaning of these encoding vectors is described in the next section. The first vector in the attribute string specifies the encoding for the first enumeration literal, the second vector specifies the encoding for the second enumeration literal, and so on. The ENUM_ENCODING attribute must immediately follow the type declaration. Example 3-4 illustrates how the default encodings from Example 3-3 can be changed with the ENUM_ENCODING attribute.
The result is GREEN < VIOLET < RED < YELLOW < BLUE. Note: The interpretation of the ENUM_ENCODING attribute is specific to FPGA Compiler II / FPGA Express. Other VHDL tools, such as simulators, use the standard encoding (ordering).
Data Types 3-6
Integer Types
The maximum range of a VHDL integer type is (2311) to 2311 (2_147_483_647 ... 2_147_483_647). Integer types are defined as subranges of this anonymous built-in type. Multidigit numbers in VHDL can include underscores (_) to make them easier to read. FPGA Compiler II / FPGA Express encodes an integer value as a bit vector whose length is the minimum necessary to hold the defined range. FPGA Compiler II / FPGA Express encodes integer ranges that include negative numbers as 2s-complement bit vectors. The syntax of an integer type definition is
type type_name is range integer_range ;
type_name is the name of the new integer type, and integer_range is a subrange of the anonymous integer type. Example 3-5 shows some integer type definitions.
You cannot directly access the bits of an INTEGER or explicitly state the bit-width of the type. For these reasons, Synopsys provides overloaded functions for arithmetic. These functions are defined in the std_logic_signed and std_logic_unsigned packages, described in std_logic_arith Package on page B-3.
Array Types
An array is an object that is a collection of elements of the same type. VHDL supports N-dimensional arrays, but FPGA Compiler II / FPGA Express supports only one-dimensional arrays. Array elements can be of any type. An array has an index whose value selects each element. The index range determines how many elements are in the array and their ordering (low to high or high downto low). An index can be of any integer type. You can declare multidimensional arrays by building one-dimensional arrays where the element type is another one-dimensional array, as shown in Example 3-6.
VHDL provides constrained as well as unconstrained arrays. The difference between the two comes from the index range in the array type definition.
Constrained Arrays
A constrained arrays index range is explicitly defined; an example is the integer range (1 to 4). When you declare a variable or signal of the type constrained array, the variable or signal has the same index range as the constrained array. The syntax of a constrained array type definition is
type array_type_name is array ( integer_range ) of type_name;
array_type_name The name of the new constrained array type. integer_range A subrange of another integer type. type_name The type of each array element. Example 3-7 shows a constrained array type definition.
Unconstrained Arrays
You define an unconstrained arrays index range as a type; for example, INTEGER. This definition implies that the index range can be any contiguous subset of that types values. When you declare an array variable or signal of this type, you also define its actual index range. Different declarations can have different index ranges.
Data Types 3-10
array_type_name The name of the new unconstrained array type. range_type_name The name of a range type or subtype. element_type_name The type of each array element. Example 3-8 shows an unconstrained array type definition and a declaration that uses it.
The advantage of using unconstrained arrays is that a VHDL tool can recall the index range of each declaration. You can use array attributes to determine the range (bounds) of a signal or variable of an unconstrained array type. With this information, you can write routines that use variables or signals of an unconstrained array type, independent of any one array variables or signals bounds. The next section describes array attributes and how they are used.
Array Attributes
FPGA Compiler II / FPGA Express supports the following predefined VHDL attributes for use with arrays: left right high low length range reverse_range
These attributes all return a value corresponding to part of an arrays range. Table 3-1 shows the values of the array attributes for the variable MY_VECTOR in Example 3-8.
Example 3-9 shows the use of array attributes in a function that ORs together all elements of a given bit vector (declared in Example 3-8) and returns that value.
Record Types
A record is a set of named fields of various types, unlike an array, which is composed of identical anonymous entries. A records field can be of any previously defined type, including another record type. Example 3-10 shows a record type declaration (BYTE_AND_IX), three signals of that type, and some assignments.
signal DATA: BYTE_VEC; signal NUM: INTEGER; . . . X.BYTE <= "11110000"; X.IX <= 2; DATA <= Y.BYTE; NUM <= Y.IX; Z <= X;
As shown in Example 3-10, you can read values from or assign values to records in two ways: By individual field name
X.BYTE <= DATA; X.IX <= LEN;
A record type objects individual fields are accessed by the object name, a period, and a field name: X.BYTE or X.IX. To access an element of the BYTE fields array, use array notation: X.BYTE(2).
Record Aggregates
Record aggregates (constants) have the same syntax as array aggregates (see Aggregates on page 4-18). They can appear anywhere records appear.
You can use the others construct in a named or positional record aggregate, just as you can in an array aggregate (see Aggregates on page 4-18). You can mix named and positional aggregates in a description, with the positional items listed first. You cannot have a named item that refers to a field covered in the positional aggregate. The following four examples illustrate this caveat.
You can supply a set of choices in a description of a record aggregate, but a choice cannot be a range. See Example 3-15 and Example 3-16.
The FPGA Compiler II / FPGA Express implementation of the STANDARD package is listed in Example 3-17. This STANDARD package is a subset of the IEEE VHDL STANDARD package. Differences are described in Unsupported Data Types on page 3-20.
type INTEGER is range -2147483647 to 2147483647; subtype NATURAL is INTEGER range 0 to 2147483647; subtype POSITIVE is INTEGER range 1 to 2147483647; type STRING is array (POSITIVE range <>) of CHARACTER; type BIT_VECTOR is array (NATURAL range <>) of BIT; end STANDARD;
Physical Types
FPGA Compiler II / FPGA Express does not support physical types, such as units of measure (for example, ns).
Floating-Point Types
FPGA Compiler II / FPGA Express does not support floating-point types, such as REAL.
Access Types
FPGA Compiler II / FPGA Express does not support access (pointer) types because no equivalent hardware construct exists.
File Types
FPGA Compiler II / FPGA Express does not support file (disk file) types, such as a hardware file type RAM or ROM.
Subtypes
A subtype is defined as a subset of a previously defined type or subtype. A subtype definition can appear anywhere a type definition is allowed. Using subtypes is a powerful way to use VHDL type checking to ensure valid assignments and meaningful data handling. Subtypes inherit all operators and subprograms defined for their parent (base) types. Subtypes are also used for resolved signals to associate a resolution function with the signal type (see Subtypes on page 2-32, for more information). For example, note in Example 3-17 that NATURAL and POSITIVE are subtypes of INTEGER and that they can be used with any INTEGER function. They can be added, multiplied, compared, and assigned to each other if the values are within the appropriate subtypes range. All INTEGER types and subtypes are actually subtypes of an anonymous predefined numeric type.
Example 3-18 shows some valid and invalid assignments between NATURAL and POSITIVE values.
If your design uses only 16-bit vectors, you can define a subtype MY_VECTOR as
subtype MY_VECTOR is BIT_VECTOR(0 to 15);
Example 3-19 shows that all functions and attributes that operate on BIT_VECTOR also operate on MY_VECTOR.
4
Expressions 4
In VHDL, expressions perform arithmetic or logical computations by applying an operator to one or more operands. Operators specify the computation to perform. Operands are the data for the computation. In the following VHDL fragment, A and B are operands, + is an operator, and A + B is an expression.
C := A + B; -- Computes the sum of two values
You can use expressions in many places in a design description. You can Assign them to variables or signals or use them as the initial values of constants Use them as operands to other operators Use them for the return value of functions
Expressions 4-1
Use them for the IN parameters in a subprogram call Assign them to the OUT parameters in a procedure body Use them to control the actions of statements such as if, loop, and case
This chapter discusses the use of expressions in a design description, in the following major sections: Operators Operands
Operators
A VHDL operator is characterized by Name Computation (function) Number of operands Type of operands (such as Boolean or character) Type of result value
You can define new operators, like functions, for any type of operand and result value. The predefined VHDL operators are listed in Table 4-1.
Expressions 4-2
rem Highest
Each line in the table lists operators with the same precedence. Each lines operators have greater precedence than those on the previous line. An operators precedence determines whether it is applied before or after adjoining operators. Example 4-1 shows some expressions and how they are interpreted.
VHDL allows existing operators to be overloadedthat is, applied to new types of operands. The logical operator called and, for example, can be overloaded to work with a new logic type. For more information, see Operator Overloading on page 2-30.
Logical Operators
Operands of a logical operator must be of the same type. The logical operatorsand, or, nand, nor, xor, xnor, notaccept operands of type BIT or type BOOLEAN and one-dimensional arrays of BIT or BOOLEAN. Array operands must be the same size. A logical operator applied to two array operands is applied to pairs of the two arrays elements.
Expressions 4-3
Example 4-2 shows some logical signal declarations and logical operations on them. Figure 4-1 illustrates the resulting design.
Expressions 4-4
Normally, to use more than two operands in an expression, you must use parentheses to group the operands. An exception is that you can combine, without parentheses, a sequence that uses only one of the following operators: - and - or - xor - xnor The following expression uses the same operatorandin the sequence:
A and B and C and D
However, a sequence that contains more than one of these operators requires parentheses to indicate which two operands are to be paired. In the following sequence, and is the first operator, or is the second.
A and B or C
or
A and (B or C)
Relational Operators
Relational operators, such as = or >, compare two operands of the same base type and return a Boolean value.
Expressions 4-5
IEEE VHDL defines the equality (=) and inequality (/=) operators for all types. Two operands are equal if they represent the same value. For array and record types, IEEE VHDL compares corresponding elements of the operands. IEEE VHDL defines the ordering operators (<, <=, >, and >=) for all enumerated types, integer types, and one-dimensional arrays of enumeration or integer types. The internal order of a types values determines the result of the ordering operators. Integer values are ordered from negative infinity to positive infinity. Enumerated values are in the same order as they were declared, unless you have changed the encoding. Note: If you set the encoding of your enumerated types (see Enumeration Encoding on page 3-4), the ordering operators compare your encoded value ordering, not the declaration ordering. Because this interpretation is specific to FPGA Compiler II / FPGA Express, a VHDL simulator still uses the declarations order of enumerated types. Arrays are ordered alphabetically. FPGA Compiler II / FPGA Express determines the relative order of two array values by comparing each pair of elements in turn, beginning from the left bound of each arrays index range. If a pair of array elements is not equal, the order of the different elements determines the order of the arrays. For example, bit vector 101011 is less than 1011, because the fourth bit of each vector is different, and 0 is less than 1. If the two arrays have different lengths and the shorter one matches the first part of the longer one, the shorter comes before the longer. Thus, the bit vector 101 is less than 101000. Arrays are compared from left to right, regardless of their index ranges (to or downto).
Expressions 4-6
-- Array comparison
To interpret bit vectors such as 011 as signed or unsigned binary numbers, use the relational operators defined in the std_logic_arith package (listed in Appendix B, "Synopsys Packages). The third line in Example 4-3 evaluates false if the operands are of type UNSIGNED.
UNSIGNED1 < UNSIGNED011 -- Numeric comparison
Example 4-4 shows some relational expressions. Figure 4-2 illustrates the resulting synthesized circuits.
Expressions 4-7
Adding Operators
Adding operators include arithmetic and concatenation operators. The arithmetic operators + and are predefined for all integer operands. These addition and subtraction operators perform conventional arithmetic. Example 4-5 uses the + operator. The concatenation operator & is predefined for all one-dimensional array operands. The concatenation operator builds arrays by combining the operands. Each operand of & can be an array or an
Expressions 4-8
element of an array. Use & to add a single element to the beginning or end of an array, to combine two arrays, or to build an array out of elements, as shown in Example 4-5 and Figure 4-3.
signal J, K, L: INTEGER range 0 to 3; A D G J <= <= <= <= not not not K + B & not C; E & not F; H & not I; L; ----Array & array Array & element Element & element Simple addition
Expressions 4-9
Example 4-6 shows how unary negation is synthesized, and Figure 4-4 illustrates the resulting design.
Expressions 4-10
Multiplying Operators
FPGA Compiler II / FPGA Express predefines the multiplying operators (*, /, mod, and rem) for all integer types. FPGA Compiler II / FPGA Express places some restrictions on the supported values for the right-hand operands of the multiplying operators, as follows: * Integer multiplication: no restrictions. / Integer division: The right-hand operand must be a computable power of 2 and cannot be negative (seeComputable Operands on page 4-16). This operator is implemented as a bit shift. mod Modulus: same as /. rem Remainder: same as /. Example 4-7 shows some uses of the multiplying operators whose right-hand operands are all powers of 2. Figure 4-5 illustrates the resulting synthesized circuit design.
Expressions 4-11
Expressions 4-12
Example 4-8 shows how these operators are used. Figure 4-6 illustrates the synthesized design.
Expressions 4-13
Operands
The operands specify the data used by the operator 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. Operands can themselves be expressions. You create expression operands by surrounding an expression with parentheses. The operand categories are Aggregates my_array_type(others => 1) Attributes my_arrayrange 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)
Expressions 4-14
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 categories listed here.
Operand Bit-Width
FPGA Compiler II / FPGA 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 FPGA Compiler II / FPGA 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.
type ENOUGH: variable WIDE: signal NARROW: INTEGER range 0 to 255; INTEGER range -1024 to 1023; INTEGER range 0 to 7;
Note: During optimization, FPGA Compiler II / FPGA Express removes hardware for unused bits.
Expressions 4-15
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 FPGA Compiler II / FPGA Express. Computability is important because noncomputable expressions can require logic gates to determine their value. Following are examples of computable operands: Literal values for...loop parameters, when the loops range is computable Variables assigned a computable expression Aggregates that contain only computable expressions Function calls whose return value is computable Expressions with computable operands Qualified expressions when the expression is computable Type conversions when the expression is computable The value of the and or nand operators when one of the operands is a computable 0 The value of the or operator or the nor operator 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. Following are examples of noncomputable operands:
Expressions 4-16
Signals
Ports Variables assigned different computable values that depend on a noncomputable condition Variables assigned noncomputable values
Example 4-9 shows some definitions and declarations, followed by several computable and noncomputable expressions.
Expressions 4-17
V_ARRAY := MY_ARRAY(V1, V2, 0, 0); -- Computable (1000) V1 := MUX(V0, V1, V2); -- Computable (value is COMP(V1, V2); V1 := V2; -- Computable (value is V0 := S and 0; -- Computable (value is V1 := MUX(S, 1, 0);-- Computable (value is V1 := MUX(1, 1, S);-- Computable (value is if (S = 1) then V2 := 0; else V2 := 1; end if; V0 := V2; V1 := S; V2 := V1; computable end process;
1) 0) 0) 1) 1)
-- Computable (value is 0) -- Computable (value is 1) -- Non-computable; V2 depends on S -- Non-computable; S is signal -- Non-computable; V1 is no longer
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 is
type_name([choice =>] expression{, [choice =>] expression})
type_name A constrained array type (as required by FPGA Compiler II / FPGA 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 elements type.
Expressions 4-18
Example 4-10 shows an array type definition and an aggregate representing a literal of that array type. The two sets of assignments have the same result.
You can specify an elements index by using either positional or named notation. With positional notation, each element receives the value of its expression in order, as shown in Example 4-10. 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, such as 3 to 5 => or 7 downto 0 =>, to indicate a sequence of element indexes. An aggregate can use both positional and named notation. It is not necessary to specify all element indexes in an aggregate. All unassigned values are given a value by inclusion of the others => expression as the last element of the list. Example 4-11 shows several aggregates representing the same value.
Expressions 4-19
The others expression can be the only expression in the aggregate. Example 4-12 shows two equivalent aggregates.
For information on using an aggregate as the target of an assignment statement, see Assignment Statements and Targets on page 5-2.
Attributes
VHDL defines attributes for various types. A VHDL attribute takes a variable or signal of a given type and returns a value. The syntax of an attribute is
objectattribute
FPGA Compiler II / FPGA Express supports the following predefined VHDL attributes for use with arrays, as described in Array Types on page 3-9.
Expressions 4-20
left right
FPGA Compiler II / FPGA Express also supports the following predefined VHDL attributes for use with wait and if statements, as described in Chapter 7, "Register and Three-State Inference". event stable
In addition to supporting the previous predefined VHDL attributes, FPGA Compiler II / FPGA Express has a defined set of synthesisrelated attributes. You can include these FPGA Compiler II / FPGA Express-specific attributes in your VHDL design description to direct FPGA Compiler II / FPGA Express during optimization.
Expressions
Operands can themselves be expressions. You create expression operands by surrounding an expression with parentheses, such as (A nand B).
Expressions 4-21
Function Calls
A function call executes a named function with the given parameter values. The value returned to an operator is the functions return value. The syntax of a function call is
function_name ( [parameter_name =>] expression {, [parameter_name =>] expression }) ;
function_name Name of a defined function. The optional parameter_names are the names of formal parameters as defined by the function. Each expression provides a value for its parameter and must evaluate to a type appropriate for that parameter. You can specify parameters in positional or named notation, as you can with aggregate values. In positional notation, the parameter_name => construct is omitted. The first expression provides a value for the functions first parameter, the second expression is for the second parameter, and so on. In named notation, parameter_name => is specified before an expression; the named parameter gets the value of that expression. You can mix positional and named expressions in the same function call if you put all positional expressions before named parameter expressions. Example 4-13 shows a function declaration and several equivalent function calls.
Expressions 4-22
Identifiers
Identifiers are probably the most common operand. An identifier is the name of a constant, variable, function, signal, entity, port, subprogram, or parameter and returns that objects value to an operand. Identifiers that contain special characters, begin with numbers, or have the same name as a keyword can be specified as an extended identifier. An extended identifier starts with a backslash character (\), followed by a sequence of characters, followed by another backslash character (\). Example 4-14 shows some extended identifiers.
Example 4-15 shows several kinds of identifiers and their usages. All identifiers appear in bold type.
Expressions 4-23
Indexed Names
An indexed name identifies one element of an array variable or signal. The syntax of an indexed name is
identifier (expression)
identifier Name of a signal or variable of an array type. The expression must return a value within the arrays index range. The value returned to an operator is the specified array element. If the expression is computable (see Computable Operands on page 4-16), the operand is synthesized directly. If the expression
Expressions 4-24
is noncomputable, a circuit is synthesized that extracts the specified element from the array. Example 4-16 shows two indexed names, one computable and one not. Figure 4-7 illustrates the resulting synthesized circuit design.
Figure 4-7 Design Illustrating Use of Indexed Names From Example 4-16
You can also use indexed names as assignment targets; see Assignment Statements and Targets on page 5-2.
Expressions 4-25
Literals
A literal (constant) operand can be a numeric literal, a character literal, an enumeration literal, or a string literal. The following sections describe these four kinds of literals.
Numeric Literals
Numeric literals are constant integer values. The two kinds of numeric literals are decimal and based. A decimal literal is written in base 10. A based literal can be written in a base from 2 to 16 and is composed of the base number, an octothorpe (#), the value in the given base, and another octothorpe (#). For example, 2#101# is decimal 5. The digits in either kind of numeric literal can be separated by underscores. Example 4-17 shows several different numeric literals, all representing the same value, which is 170.
Character Literals
Character literals are single characters enclosed in single quotation marksfor example, A. Character literals are used both as values for operators and in defining enumerated types, such as CHARACTER and BIT. See Enumeration Types on page 3-3 for the valid character types.
Expressions 4-26
Enumeration Literals
Enumeration literals are values of enumerated types. The two kinds of enumeration literals are character literals and identifiers. Character literals are described earlier. Enumeration identifiers are those listed in an enumeration type definition. For example,
type SOME_ENUM is (ENUM_ID_1, ENUM_ID_2, ENUM_ID_3);
If two enumerated types use the same literals, those literals are overloaded. You must qualify overloaded enumeration literals when you use them in an expression, unless their type can be determined from context (see Qualified Expressions on page 4-29). For more information, see Enumeration Types on page 3-3. Example 4-18 defines two enumerated types and shows some enumeration literal values.
String Literals
String literals are one-dimensional arrays of characters enclosed in double quotation marks ( ). The two kinds are Character strings, which are sequences of characters in double quotation marks, for example, ABCD.
Expressions 4-27
Bit strings, which are similar to character strings but represent binary, octal, or hexadecimal values. For example, B1101, O15, and XD all represent the decimal value 13.
A string literals type is a one-dimensional array of an enumerated type. Each of the characters in the string represents one element of the array. Example 4-19 shows some character string literals.
Note: Null string literals () are not supported. Bit strings, like based numeric literals, are composed of a base specifier character, a double quotation mark, a sequence of numbers in the given base, and another double quotation mark. For example, B0101 represents the bit vector 0101. A bit string literal consists of the base specifier B, O, or X, followed by a string literal. It is interpreted as a bit vector, a one-dimensional array of the predefined type BIT. The base specifier determines the interpretation of the bit string as follows: B (binary) The value is in binary digits (bits 0 or 1). Each bit in the string represents one BIT in the generated bit vector (array). O (octal) The value is in octal digits (0 to 7). Each octal digit in the string represents three BITs in the generated bit vector (array).
Expressions 4-28
X (hexadecimal) The value is in hexadecimal digits (0 to 9 and A to F). Each hexadecimal digit in the string represents four BITs in the generated bit vector (array). You can separate the digits in a bit string literal value with underscores (_) for readability. Example 4-20 shows three bit string literals representing the value AAA.
Qualified Expressions
Qualified expressions state the type of an ambiguous operand. You cannot use qualified expressions for type conversion (see Type Conversions on page 4-34). The syntax of a qualified expression is
type_name(expression)
type_name The name of a defined type. The expression must evaluate to a value of an appropriate type. Note: FPGA Compiler II / FPGA Express requires a single quotation mark (tick) between type_name and (expression). If the single quotation mark is not there, the construction is intepreted as a type conversion (described in the next section).
Expressions 4-29
Example 4-21 shows a qualified expression that resolves an overloaded function by qualifying the type of a decimal literal parameter.
function FUNC(A: R_1) return BIT; function FUNC(A: R_2) return BIT; FUNC(5) -- Ambiguous; could be of type R_1, R_2, or INTEGER FUNC(R_1(5)) -- Unambiguous
Example 4-22 shows how qualified expressions resolve ambiguities in aggregates and enumeration literals.
Expressions 4-30
In an expression, you can refer to a whole record or to a single field. The syntax of field names is
record_name.field_name
record_name Name of the record variable or signal. A record_name is different for each variable or signal of that record type. field_name Name of a field in that record type. A field_name is separated from the record_name by a period (.). A field_name is the field name defined for that record type. Example 4-23 shows a record type definition and record and field access.
A field can be of any type, including an array, record, or aggregate type. Refer to an element of a field by using that types notation; for example,
X.BYTE(2) X.BYTE(3 downto 0)
-- one element from array field BYTE
Expressions 4-31
Slice Names
Slice names identify a sequence of elements of an array variable or signal. The syntax is
identifier (expression direction expression)
identifier Name of a signal or variable of an array type. Each expression must return a value within the arrays index range and must be computable (see Computable Operands on page 4-16). The direction must be either to or downto. The direction of a slice must be the same as the direction of an identifiers array type. If the left and right expressions are equal, they define a single element. The value returned to an operator is a subarray containing the specified array elements. Example 4-24 uses slices to assign an 8-bit input to an 8-bit output, exchanging the lower and upper 4 bits. Figure 4-8 illustrates the resulting synthesized circuit design. Slices are also used as assignment targets. This usage is described in Assignment Statements and Targets on page 5-2.
Expressions 4-32
Example 4-25 shows three null slices and one noncomputable slice.
Expressions 4-33
Type Conversions
Type conversions change an expressions type. The syntax of a type conversion is
type_name(expression)
type_name The name of a defined type. The expression must evaluate to a value of a type that is convertible into type type_name. - Type conversions can convert between integer types or between similar array types. - Two array types are similar if they have the same length and have convertible or identical element types.
Expressions 4-34
- Enumerated types are not convertible. Example 4-26 shows some type definitions and associated signal declarations, followed by valid and invalid type conversions.
Expressions 4-35
Expressions 4-36
5
Sequential Statements 5
FPGA Compiler II / FPGA Express interprets sequential statements, such as A := 3, in the order in which they appear in the code. VHDL sequential statements can appear only in processes and subprograms. This chapter discusses the different types of sequential statements, in the following sections: Assignment Statements and Targets Variable Assignment Statements Signal Assignment Statements if Statements case Statements loop Statements next Statements
target The target can be a variable or a signal (or part of a variable or a signal, such as a subarray) that receives the value of the expression. The expression must evaluate to the same type as the target. See Chapter 4, "Expressions for more information. There are five kinds of targets: - Simple names, such as my_var - Indexed names, such as my_array_var(3) - Slices, such as my_array_var(3 to 6) - Field names, such as my_record.a_field - Aggregates, such as (my_var1, my_var2)
The difference in syntax between variable assignments and signal assignments is that Variables use the := operator Variables are local to a process or subprogram, and their assignments take effect immediately. Signals use the <= operator Signals need to be global in a process or subprogram, and their assignments take effect at the end of a process. Signals are the only means of communication between processes. For more information on semantic differences, see Signal Assignment Statements on page 5-12. The following descriptions refer to variable as well as signal targets.
identifier The name of a signal or variable. The assigned expression must have the same type as the signal or variable. For array types, all elements of the array are assigned values. Example 5-1 shows some assignments to simple name targets.
identifier The name of an array type signal or variable. The index_expression must evaluate to an index value for the identifier arrays index type and bounds. It does not have to be computable (see Chapter 4, "Expressions), but more hardware is synthesized if it is not. The assigned expression must have the arrays element type. In Example 5-2, the array variable A elements are assigned values as indexed names. Example 5-3 shows two indexed name targets. One is computable, the other is not. Figure 5-1 illustrates the corresponding design.
:= := := :=
1 1 0 0
to to to to
first element of array A. second element of array A third element of array A fourth element of array A
Figure 5-1 Design Illustrating Indexed Name Targets From Example 5-3
Slice Targets
The syntax for an assignment to a slice target is
identifier(index_expr_1 direction index_expr_2)
identifier The name of an array type signal or variable. Each index_expr expression must evaluate to an index value for the identifier arrays index type and bounds. Both index_expr expressions must be computable (see Chapter 4, "Expressions") and must lie within the bounds of the array. The direction must match the identifier array types direction, either to or downto. The assigned expression must have the arrays element type. In Example 5-4, array variables A and B are assigned the same value.
Field Targets
The syntax for an assignment to a field target is
identifier.field_name
identifier The name of a record type signal or variable. field_name is the name of a field in that record type, preceded by a period (.). The assigned expression must have the identified fields type. A field can be of any type, including an array, record, or aggregate type. Example 5-5 assigns values to the fields of record variables A and B.
Aggregate Targets
The syntax for an assignment to an aggregate target is
([choice =>] identifier {,[choice =>] identifier}) := array_expression; -- Variable assignment ([choice =>] identifier {,[choice =>] identifier}) <= array_expression; -- Signal assignment
aggregate assignment Assigns the array_expression element values to one or more variable or signal identifiers. Each (optional) choice is an index expression selecting an element or a slice of the assigned array_expression. Each identifier must have the array_expression element type. An identifier can be an array type. You can assign array element values to the identifiers by position or by name. In positional notation, the choice => construct is not used. Identifiers are assigned array element values in order, from the left array bound to the right array bound. In named notation, the choice => construct identifies specific elements of the assigned array. A choice index expression indicates a single element (such as 3). The identifiers type must match the assigned expressions element type. Positional and named notation can be mixed, but positional associations must come before named associations, as in Example 5-6.
to to to to
G(2) G(1) E F
target Names the variables that receive the value of expression. See Assignment Statements and Targets on page 5-2 for a description of variable assignment targets. expression Determines the assigned value; its type must be compatible with the target. For more information about expressions, see Chapter 4, "Expressions. When a variable is assigned a value, the assignment takes place immediately. A variable keeps its assigned value until another assignment takes place. Example 5-7 on page 5-14 shows the different effects of variable and signal assignments.
target Names the signals that receive the value of expression. See Assignment Statements and Targets on page 5-2 for a description of variable assignment targets. expression Determines the assigned value; its type must be compatible with target. For more information about expressions, see Chapter 4, "Expressions. Signals and variables act in different ways when they receive assigned values. The differences lie in the way the two kinds of assignments take effect and how that influences the value FPGA Compiler II / FPGA Express reads from either variables or signals. variable assignment When a variable receives an assigned value, the assignment changes the value of the variable from that point on. That value is kept until the variable is assigned a different value.
signal assignment When a signal receives an assigned value, the assignment does not necessarily take effect, because the value of a signal is determined by the processes (or other concurrent statements) that drive the signal. - If several values are assigned to a given signal in one process, only the last assignment is effective. Even if a signal in a process is assigned, then read, and then assigned again, the value read (either inside or outside the process) is the last assignment value. - If several processes (or other concurrent statements) assign values to one signal, the drivers are wired together. The resulting circuit depends on the expressions and the target technology. It might be invalid, wired AND, wired OR, or a threestate bus. For more information on this topic, see Chapter 6, "Concurrent Statements. Example 5-7 shows the different effects of variable and signal assignments.
V1 := 0; V2 := 0; S2 <= 0;
This sets the new value of V1 This sets the new value of V2 This assignment overrides the previous one since it is the last assignment to this signal in this process ----Assigns Assigns Assigns Assigns 0, 0, 1, 0, the the the the value value value value assigned assigned assigned assigned above above above above
S_OUT(5) <= S_OUT(6) <= S_OUT(7) <= S_OUT(8) <= end process;
if Statements
The if statement executes a sequence of statements. The sequence depends on the value of one or more conditions. The syntax is
if condition then [ { sequential_statement } elsif condition then ] { sequential_statement } [ else { sequential_statement } ] end if;
Each condition must be a Boolean expression. Each branch of an if statement can have one or more sequential_statements.
Evaluating Conditions
An if statement evaluates each condition in order. Only the first true condition causes the execution of the if statements branch statements. The remainder of the if statement is skipped. If none of the conditions is true and the else clause is present, those statements are executed. If none of the conditions is true and no else clause is present, none of the statements is executed. Example 5-8 shows an if statement. Figure 5-2 illustrates the corresponding circuit.
case Statements
The case statement executes one of several sequences of statements, depending on the value of a single expression. The syntax is
case expression is when choices => { sequential_statement } { when choices => { sequential_statement } } end case;
expression Must evaluate to an INTEGER, an enumerated type, or an array of enumerated types such as BIT_VECTOR. Each of the choices must be of the form
choice { | choice }
choice Each choice can be either a static expression (such as 3) or a static range (such as 1 to 3). The type of choice_expression determines the type of each choice. Each value in the range of choice_expressions type must be covered by one choice. The final choice can be others, as in Example 5-10 on page 5-20, which matches all remaining (unchosen) values in the range of expressions type. The others choice, if present, matches expression only if no other choices match. The case statement evaluates expression and compares that value with each choice value. The when clause with the matching choice value has its statements executed.
The following restrictions are placed on choices: No two choices can overlap. If an others choice is not present, all possible values of expression must be covered by the set of choices.
library work; use work.case_enum.all; entity example5_9 is port ( signal A, B, C, D: in BIT; signal VALUE: ENUM; signal Z: out BIT ); end example5_9; architecture behave of example5_9 is begin process (VALUE)
begin case VALUE is when PICK_A Z <= A; when PICK_B Z <= B; when PICK_C Z <= C; when PICK_D Z <= D; end case; end process; end behave;
Example 5-10 shows a case statement again used to select one of four signal assignment statements, this time by using an integer expression type with multiple choices. Figure 5-4 illustrates the corresponding design.
case VALUE is -- Must have at least one when clause end case; case VALUE is -- Values 2 to 15 are not covered by choices when 0 => OUT_1 <= 1; when 1 => OUT_1 <= 0; end case; case VALUE is -- Choices 5 to 10 overlap when 0 to 10 => OUT_1 <= 1; when 5 to 15 => OUT_1 <= 0; end case;
loop Statements
A loop statement repeatedly executes a sequence of statements. The syntax is
[label :] [iteration_scheme] loop { sequential_statement } { next [ label ] [ when condition ] ; } { exit [ label ] [ when condition ] ; } end loop [label];
label The label, which is optional, names the loop and is useful for building nested loops. iteration_scheme There are three types of iteration_scheme: loop, while...loop, and for...loop. They are described in the next three sections. next and exit statements Sequential statements used only within loops. next statement Skips the remainder of the current loop and continues with the next loop iteration. exit statement Skips the remainder of the current loop and continues with the next statement after the exited loop. See next Statements on page 5-30 and exit Statements on page 5-33.
loop The label, which is optional, names this loop. sequential_statement Any statement described in this chapter. Two sequential statements are used only with loops: next statement Skips the remainder of the current loop and continues with the next loop iteration. exit statement Skips the remainder of the current loop and continues with the next statement after the exited loop. See next Statements on page 5-30 and exit Statements on page 5-33. Note: Noncomputable loops (loop and while...loop statements) must have at least one wait statement in each enclosed logic branch. Otherwise, a combinational feedback loop is created. See wait Statements on page 5-50 for more information. Conversely, computable loops (for...loop statements) must not contain wait statements. Otherwise, a race condition may result.
Sequential Statements 5-23
while...loop Statements
The while...loop statement has a Boolean iteration scheme. If the iteration condition evaluates true, FPGA Compiler II / FPGA Express executes the enclosed statements once. The iteration condition is then reevaluated. As long as the iteration condition remains true, the loop is repeatedly executed. When the iteration condition evaluates false, the loop is skipped and execution continues with the next loop iteration. The syntax for a while...loop statement is
[label :] while condition loop { sequential_statement } end loop [label];
label The label, which is optional, names this loop. condition Any Boolean expression, such as ((A = 1) or (X < Y)). sequential_statement Any statement described in this chapter. Two sequential statements are used only with loops: next statement Skips the remainder of the current loop and continues with the next loop iteration. exit statement Skips the remainder of the current loop and continues with the next statement after the exited loop. See next Statements on page 5-30 and exit Statements on page 5-33.
Note: Noncomputable loops (loop and while...loop statements) must have at least one wait statement in each enclosed logic branch. Otherwise, a combinational feedback loop is created. See wait Statements on page 5-50 for more information.
for...loop Statements
The for...loop statement has an integer iteration scheme. The integer range determines the number of repetitions. The syntax for a for...loop statement is
[label :] for identifier in range loop { sequential_statement } end loop [label];
label The label, which is optional, names this loop. identifier Specific to the for...loop statement: - Identifier is not declared elsewhere. It is automatically declared by the loop itself and is local to the loop. A loop identifier overrides any other identifier with the same name, but only within the loop. - The identifier value can be read only inside its loop (identifier does not exist outside the loop). You cannot assign a value to a loop identifier.
Each integer_expression evaluates to an integer. For more information, see Chapter 4, "Expressions sequential_statement Any statement described in this chapter. Two sequential statements are used only with loops: next statement Skips the remainder of the current loop and continues with the next loop iteration. exit statement Skips the remainder of the current loop and continues with the next statement after the exited loop. See next Statements on page 5-30 and exit Statements on page 5-33. Note: Computable loops (for...loop statements) must not contain wait statements. Otherwise, a race condition may result.
next Statements
The next statement skips execution to the next iteration of an enclosing loop statement, called label in the syntax, as follows:
next [ label ] [ when condition ] ;
label A next statement with no label terminates the current iteration of the innermost enclosing loop. When you specify a loop label, the current iteration of that named loop is terminated. when An optional clause that executes its next statement when its condition (a Boolean expression) evaluates true. Example 5-14 uses the next statement to copy bits conditionally from bit vector B to bit vector A only when the next condition evaluates true. Figure 5-7 illustrates the corresponding design.
for I in 1 to 8 loop next when COPY_ENABLE(I) = 0; A(I) <= B(I); end loop; end process; end behave;
Example 5-15 shows the use of nested next statements in named loops. This example processes The first element of vector X against the first element of vector Y The second element of X against each of the first two elements of Y The third element of X against each of the first three elements of Y
exit Statements
The exit statement completes execution of an enclosing loop statement, called label in the syntax. The completion is conditional if the statement includes a condition, such as the when condition in the following syntax:
exit [ label ] [ when condition ] ;
label An exit statement with no label terminates the current iteration of the innermost enclosing loop. When you specify a loop label, the current iteration of that named loop is terminated, as shown previously in Example 5-15. when An optional clause that executes its next statement when its condition (a Boolean expression) evaluates true. Note: The exit statement and the next statement have identical syntax, and they both skip the remainder of the enclosing (or named) loop. The difference between them is that exit terminates its loop and next continues with the next loop iteration (if any). Example 5-16 compares two bit vectors. An exit statement exits the comparison loop when a difference is found. Figure 5-8 illustrates the corresponding design.
Subprograms
Subprograms are independent, named algorithms. A subprogram is either a procedure (zero or more in, inout, or out parameters) or a function (zero or more in parameters and one return value). Subprograms are called by name from anywhere within a VHDL architecture or a package body. Subprograms can be called sequentially (as described later in this chapter in Combinational Versus Sequential Processes on page 5-55) or concurrently (as described in Chapter 6, "Concurrent Statements).
The advantage of the separation between declarations and bodies is that subprogram interfaces can be declared in public packages during system development. One group of developers can use the public subprograms as another group develops the corresponding bodies. You can modify package bodies, including subprogram bodies, without affecting existing users of that packages declarations. You can also define subprograms locally inside an entity, block, or process. FPGA Compiler II / FPGA Express implements procedure and function calls with combinational logic, unless you use the map_to_entity compiler directive (see Procedures and Functions as Design Components on page 5-45.) FPGA Compiler II / FPGA Express does not allow inference of sequential devices, such as latches or flip-flops, in subprograms. Example 5-17 shows a package containing some procedure and function declarations and bodies. The example itself is not synthesizable; it just creates a template. Designs that instantiate procedure P, however, compile normally. For more information about subprograms, see Subprograms on page 2-22.
Subprogram Calls
Subprograms can have zero or more parameters. A subprogram declaration defines each parameters name, mode, and type. These are a subprograms formal parameters. When the subprogram is called, each formal parameter receives a value, termed the actual parameter. Each actual parameters value (of an appropriate type) might come from an expression, a variable, or a signal.
The mode of a parameter specifies whether the actual parameter can be read from (mode in) written to (mode out) both read from and written to (mode inout)
Actual parameters that use mode out and mode inout must be variables or signals and include indexed names (A(1)) and slices (A(1 to 3)). They cannot be constants or expressions. The two kinds of subprograms are procedures and functions: Procedures A procedure can have multiple parameters that use modes in, inout, and out, but a procedure does not itself return a value. Procedures are used when you want to update some parameters (modes out and inout) or when you do not need a return value. An example could be a procedure with one inout bit vector parameter that inverted each bit in place. Functions A function can have multiple parameters but only parameters that use mode in. A function returns its own function value. Part of a function definition specifies its return value type (also called the function type). Use functions when you do not need to update the parameters and you want a single return value. For example, the arithmetic function ABS returns the absolute value of its parameter.
Procedure Calls
A procedure call executes the named procedure with the given parameter values. The syntax is
procedure_name [ ( [ name => ] expression { , [ name => ] expression } ) ] ;
expression Each expression is called an actual parameter; expression is often just an identifier. If a name is present (positional notation), it is a formal parameter name associated with the actual parameters expression. Formal parameters are matched to actual parameters by a positional or named notation. A notation can mix positional and named notation, but positional parameters must precede named parameters. A procedure call occurs in three steps: 1. FPGA Compiler II / FPGA Express assigns the values of the in and inout actual parameters to their associated formal parameters. 2. The procedure executes. 3. FPGA Compiler II / FPGA Express assigns the values of the inout and out formal parameters to the actual parameters. In the synthesized circuit, the procedures actual inputs and outputs are wired to the procedures internal logic. Example 5-18 shows a local procedure named SWAP that compares two elements of an array and exchanges them if they are out of order.
SWAP is called repeatedly to sort an array of three numbers. Figure 5-8 illustrates the corresponding design.
-- Read input to variable ----Swap first and second Swap second and third Swap 1st and 2nd again Write result to output
Function Calls
A function call executes a named function with the given parameter values. The value returned to an operator is the functions return value. The syntax is
function_name ( [parameter_name =>] expression {, [parameter_name =>] expression }) ;
function_name Name of a defined function. The parameter_name, which is optional, is the name of a formal parameter as defined by the function. Each expression provides a value for its parameter and must evaluate to a type appropriate for that parameter. You can specify parameter values in positional or named notation, as you can aggregate values. In positional notation, the parameter_name => construct is omitted. The first expression provides a value for the functions first parameter, the second expression is for the second parameter, and so on.
In named notation, parameter_name => is specified before an expression; the named parameter gets the value of that expression. You can mix positional and named expressions in the same function call if you put all positional expressions before named parameter expressions. Example 5-19 shows a simple function definition and two calls to that function.
return Statement
The return statement terminates a subprogram. A function definition requires a return statement. In a procedure definition, a return statement is optional. The syntax is
return expression ; return ; -- Functions -- Procedures
expression Provides the return value of a function. Every function must have at least one return statement and can have more than one. The expression type must match the declared function type. Only one return statement is reached by a given function call. procedure Can have one or more return statements but no expression. A return statement, if present, is the last statement executed in a procedure. In Example 5-20, the function OPERATE returns either the and logical operator or the or logical operator of its parameters A and B. The return depends on the value of the parameter OPERATION. Figure 5-10 illustrates the corresponding design.
Insert these directives after the function or procedure definition, as in the following example:
function MUX_FUNC(A,B: in TWO_BIT; C: in BIT) return TWO_BIT is -- pragma map_to_entity MUX_ENTITY -- pragma return_port_name Z ...
When FPGA Compiler II / FPGA Express encounters the map_to_entity directive, it parses but ignores the contents of the subprogram definition. Use --pragma synthesis_off and --pragma synthesis_on to hide simulation-specific constructs in a map_to_entity subprogram (see Translation Stop and Start Pragma Directives on page 9-3 for more information about synthesis_off and synthesis_on). The matching entity (entity_name) does not need to be written in VHDL. It can be in any format that FPGA Compiler II / FPGA Express supports. Note: Be aware that the behavioral description of the subprogram is not checked against the functionality of the entity overloading it. Presynthesis and post-synthesis simulation results might not match if differences in functionality exist between the VHDL subprogram and the overloaded entity.
-- the following entity overloads the function MUX_FUNC above entity MUX_ENTITY is port(A, B: in TWO_BIT; C: in BIT; Z: out TWO_BIT); end; architecture ARCH of MUX_ENTITY is begin process begin case C is when 1 => Z <= A; when 0 => Z <= B; end case; end process; end ARCH;
wait Statements
A wait statement suspends a process until FPGA Compiler II / FPGA Express detects a positive-going or negative-going edge on a signal. The syntax is
wait until signal = value ; wait until signalevent and signal = value ; wait until not signalstable and signal = value ;
signal The name of a single-bit signala signal of an enumerated type encoded with 1 bit (see Chapter 3, "Data Types). The value must be one of the literals of the enumerated type. If the signal type is BIT, the awaited value is either 1, for a positive-going edge, or 0, for a negative-going edge.
Note: Three forms of the wait statement (a subset of IEEE VHDL), shown in the syntax above and in Example 5-23, are specific to the current implementation of FPGA Compiler II / FPGA Express.
When a circuit is synthesized, the hardware in the three forms of wait statements does not differ. Example 5-24 shows a wait statement that suspends a process until the next positive edge (a 0-to-1 transition) on signal CLK.
Note: IEEE VHDL specifies that a process containing a wait statement must not have a sensitivity list. For more information, see process Statements on page 6-2. Example 5-25 shows the use of a wait statement to describe a circuit where a value is incremented on each positive clock edge. Example 5-26 shows the use of multiple wait statements to describe a multicycle circuit. The circuit provides an average value of its input A over four clock cycles. Example 5-27 shows two equivalent descriptions, the first with implicit state logic and the second with explicit state logic.
Note: You can use wait statements anywhere in a process except in for...loop statements and subprograms. However, if any path through the logic has one or more wait statements, all the paths must have at least one wait statement. Example 5-28 shows how to describe a circuit with synchronous reset, using wait statements in an infinite loop. FPGA Compiler II / FPGA Express checks the reset signal immediately after each wait statement. The assignment statements in Example 5-28 (X <= A; and Y <= B;) represent the sequential statements that implement the circuit.
Example 5-29 shows two invalid uses of wait statements. These limitations are specific to FPGA Compiler II / FPGA Express.
Note: As with the wait statement, some uses of the if statement can imply synchronous logic, causing FPGA Compiler II / FPGA Express to infer registers or latches. These methods are described in Chapter 7, "Register and Three-State Inference. Example 5-30 uses a wait statement to store values across clock cycles. The example code compares the parity of a data value with a stored value. The stored value (called CORRECT_PARITY) is set from the NEW_CORRECT_PARITY signal if the SET_PARITY signal is true. Figure 5-13 illustrates the corresponding design.
Figure 5-13 shows two flip-flops in the synthesized schematic for Example 5-30. The first (input) flip-flop holds the value of CORRECT_PARITY. A flip-flop is needed here because CORRECT_PARITY is read (when it is compared to TEMP) before it is set (if SET_PARITY is false). The second (output) flip-flop holds the value of PARITY_OK between clock cycles. The variable TEMP is not given a flip-flop because it is always set before it is read.
null Statements
The null statement explicitly states that no action is required. It is often used in case statements because all choices must be covered, even if some of the choices are ignored. The syntax is
null;
Example 5-31 shows a typical usage. Figure 5-14 illustrates the corresponding design.
-- If 0 or 7, then invert A
6
Concurrent Statements 6
A VHDL architecture construct comprises a set of interconnected concurrent statements, such as processes and blocks, that describe an overall design in terms of behavior or structure. Concurrent statements in a design execute simultaneously, unlike sequential statements, which execute one after another. This chapter describes concurrent statements, in the following order: The two main concurrent statements - process Statements - block Statements Concurrent Versions of Sequential Statements - Concurrent Procedure Calls - Concurrent Signal Assignments
process Statements
A process statement (which is concurrent) contains a set of sequential statements. Although all processes in a design execute concurrently, FPGA Compiler II / FPGA Express interprets the sequential statements within each process one at a time. A process communicates with the rest of the design by reading values from or writing them to signals or ports outside the process. The syntax of a process statement is
[ label: ] process [ ( sensitivity_list ) ] { process_declarative_item } begin { sequential_statement } end process [ label ] ;
sensitivity_list A list of all signals (including ports) read by the process. The syntax is
signal_name {, signal_name}
The circuit FPGA Compiler II / FPGA Express synthesizes is sensitive to all signals the process reads. To guarantee the same results from a VHDL simulator and the synthesized circuit, a process sensitivity list has to contain all signals whose changes require resimulation of that process. Follow these guidelines when developing the sensitivity list: - Synchronous processes (processes that compute values only on clock edges) must be sensitive to the clock signal. - Asynchronous processes (processes that compute values on clock edges and when asynchronous conditions are true) must be sensitive to the clock signal (if any) and to inputs that affect asynchronous behavior. FPGA Compiler II / FPGA Express checks sensitivity lists for completeness and issues warning messages for any signals that are read inside a process but are not in the sensitivity list. An error message is issued if a clock signal is read as data in a process. Note: IEEE VHDL does not allow a sensitivity list if the process has a wait statement. process_declarative_item Declares subprograms, types, constants, and variables local to the process. These items can be any of the following, all of which are discussed in Chapter 2, "Design Descriptions: - use clause - Subprogram declaration
Concurrent Statements 6-3
- Subprogram body - Type declaration - Subtype declaration - Constant declaration - Variable declaration The sequence of statements in a process defines the behavior of the process. After executing all the statements in a process, FPGA Compiler II / FPGA Express executes them all again. The only exception is during simulation: If a process has a sensitivity list, the process is suspended (after its last statement) until a change occurs in one of the signals in the sensitivity list. If a process has one or more wait statements (and, therefore, no sensitivity list), the process is suspended at the first wait statement whose wait condition is false. The circuit synthesized for a process is either combinational (not clocked) or sequential (clocked). If a process includes a wait or if signalevent statement, its circuit contains sequential components. The wait and if statements are described in Chapter 5, "Sequential Statements. Process statements provide a natural means of describing sequential algorithms. If the values computed in a process are inherently parallel, consider using concurrent signal assignment statements (see Concurrent Signal Assignments on page 6-17).
If CLEAR is 1 or IN_COUNT is 9, OUT_COUNT is set to 0 (zero). Otherwise, OUT_COUNT is set to the value of IN_COUNT plus 1 (one). Figure 6-1 illustrates the resulting circuit design.
The value of the variable COUNT is stored in four flip-flops, which FPGA Compiler II / FPGA Express generates because COUNT can be read before it is set. Thus, the value of COUNT has to be maintained from the previous clock cycle. For more information on using wait statements and count values, see wait Statements on page 5-50.
Driving Signals
If a process assigns a value to a signal, the process is a driver of that signal. If more than one process or other concurrent statement drives a signal, that signal has multiple drivers. In the code fragment in Example 6-3, two three-state buffers drive the same signal (SIG). To learn to infer three-state devices in VHDL, see Three-State Inference on page 7-59. Figure 6-3 shows the schematic design.
Bus resolution functions assign the value for a signal with multiple drivers. For more information, see Resolution Functions on page 2-40.
block Statements
A block statement (which is concurrent) contains a set of concurrent statements. The order of the concurrent statements does not matter, because all statements are always executing. Note: FPGA Compiler II / FPGA Express does not create a new level of design hierarchy from a block statement. The syntax of a block statement is
label: block [ (expression) ] { block_declarative_item } begin { concurrent_statement } end block [ label ];
label The label, which is required, names the block. expression The guard condition for the block. When this optional expression is present, FPGA Compiler II / FPGA Express evaluates the expression and creates a Boolean signal called GUARD. block_declarative_item Declares objects local to the block, which can be any of the following items: - use clause - subprogram declaration - subprogram body - type declaration
Concurrent Statements 6-10
- subtype declaration - constant declaration - signal declaration - component declaration Objects declared in a block are visible to that block and to all blocks nested within it. When a child block (nested inside a parent block) declares an object with the same name as an object in the parent block, the child blocks declaration overrides that of the parent.
Nested Blocks
The description in Example 6-4 uses nested blocks. Figure 6-4 shows the schematic.
B2: block signal S: BIT; -- Declaration of S, block B2 begin S <= C and D; -- S from B2 B3: block begin Z <= S; end block B3; end block B2; Y <= S; end block B1;
-- S from B2
-- S from B1
Guarded Blocks
The description in Example 6-5 uses guarded blocks. In the example, z has the same value as a.
A concurrent assignment within a block statement can use the guarded keyword. In such a case, the guard expression conditions the signal assignment. The description in Example 6-6 produces a level-sensitive latch.
Note: Do not use the event or stable attributes with the guard expression if you want to produce an edge-triggered latch using a guarded block. The presence of either attribute prevents it.
The equivalent process reads all the in and inout parameters of the procedure. Example 6-7 shows a procedure declaration and a concurrent procedure call and its equivalent process.
FPGA Compiler II / FPGA Express implements procedure calls (and function calls) with logic unless you use the map_to_entity compiler directive (see Procedures and Functions as Design Components on page 5-45.)
A common use for concurrent procedure calls is to obtain many copies of a procedure. For example, assume that a class of BIT_VECTOR signals must have just 1 bit with value 1 and the rest of the bits with value 0 (as in Example 6-8). Suppose you have several signals of varying widths that you want monitored at the same time (as in Example 6-9). One approach is to write a procedure to detect the error in a bit vector signal and then make a concurrent call to that procedure for each signal. Example 6-8 shows a procedure, CHECK, that determines whether a given bit vector has exactly one element with value 1. If this is not the case, CHECK sets its out parameter ERROR to true, as the example shows.
Example 6-9 shows the CHECK procedure called concurrently for four bit vector signals that are different sizes. Figure 6-5 illustrates the resulting circuit design.
signal E1, E2, E3, E4: BOOLEAN; begin CHECK(S1, E1); CHECK(S2, E2); CHECK(S3, E3); CHECK(S4, E4); end block BLK;
target A signal that receives the value of an expression. Example 6-10 shows the value of expressions A and B concurrently assigned to signal Z.
target A signal that receives the value of an expression. The expression used is the first one whose Boolean condition is true. When FPGA Compiler II / FPGA Express executes a conditional signal assignment statement, it tests each condition in the order written. FPGA Compiler II / FPGA Express assigns to the target the expression of the first condition that evaluates to true. If no condition evaluates to true, FPGA Compiler II / FPGA Express assigns the final expression to the target. If two or more conditions are true, FPGA Compiler II / FPGA Express assigns only the first one to the target.
Example 6-11 shows a conditional signal assignment. The target is the signal Z, which is assigned from one of the signals A, B, or C. The signal depends on the value of the expressions ASSIGN_A and ASSIGN_B. Figure 6-6 illustrates the resulting design. Note: The A assignment takes precedence over B, and B takes precedence over C, because the first true condition controls the assignment.
The process in Example 6-12 is equivalent to the conditional signal assignment in Example 6-11.
target A signal that receives the value of an expression. The expression selected is the first one whose choices include the value of choice_expression. Each choice can be either - A static expression (such as 3) - A static range (such as 1 to 3) The value of each choice the target signal receives has to match the value or values of choice_expression. If the value of choice_expression is a static range, each value in the range must be covered by one choice in the expression. The final choice can be others, which matches all remaining (unchosen) values in the range of the choice_expression type. The others choice, if present, matches choice_expression only if none of the other choices match.You can use others as the final choice only if the value of choice_expression is a range. The with...select statement evaluates choice_expression and compares that value with each choice value. The when clause with the matching choice value has its expression assigned to target.
The use of choices has the following restrictions: No two choices can overlap. If no others choice is present, all possible values of choice_expression must be covered by the set of choices.
Example 6-13 shows target Z assigned from A, B, C, or D. The assignment depends on the current value of CONTROL. Figure 6-7 illustrates the resulting design.
Example 6-14 shows the process equivalent to the selected signal assignment statement in Example 6-13.
The syntax is
instance_name : component_name port map ( [ port_name => ] expression {, [ port_name => ] expression } );
instance_name Name of this instance of the component. component_name Name of the component port map, which connects each port of this instance of component_name to a signal-valued expression in the current entity. port_name Name of port. expression Name of a signal, indexed name, slice name, or aggregate, to indicate the connection method for the components ports. If expression is the VHDL reserved word open, the corresponding port is left unconnected. You can map ports to signals by named or positional notation. You can include named as well as positional connections in the port map, but you must put all positional connections before any named connections. Note: For named association, the component port names must match exactly the declared components port names. For positional association, the actual port expressions must be in the same order as the declared components port order. Example 6-15 shows a component declaration (a 2-input NAND gate) followed by three equivalent component instantiation statements.
Example 6-16 shows the component instantiation statement defining a simple netlist. The three instancesU1, U2, and U3are instantiations of the 2-input NAND gate component declared in Example 6-15. Figure 6-8 illustrates the resulting design.
Direct Instantiation
A component instantiation statement Defines a subcomponent of the design entity in which it appears Associates signals or values with the ports of that subcomponent Associates values with generics of that subcomponent
Example 6-17 and Example 6-18 show the difference between a component instantiation statement and the more concise direct component instantiation statement.
Example 6-18 shows how you can express the information in Example 6-17 in a direct component instantiation statement.
generate Statements
A generate statement creates zero or more copies of an enclosed set of concurrent statements. The two kinds of generate statements are
for...generate
for...generate Statement
The syntax is
label: for identifier in range generate { concurrent_statement } end generate [ label ] ;
label The label, which is required, names this statement and is useful for building nested generate statements.
identifier Specific to the for...generate statement: - Identifier is not declared elsewhere. It is automatically declared by the generate statement itself and is local to the statement. A for ... generate identifier overrides any other identifier with the same name, but only within the for...generate statement. - The value of identifier can be read only inside its for...generate statement (identifier does not exist outside the statement). You cannot assign a value to a for...generate identifier. - The value of identifier cannot be assigned to any parameter whose mode is out or inout. range Must be a computable integer range, in either of two forms:
integer_expression to integer_expression integer_expression downto integer_expression
integer_expression Each integer_expression evaluates to an integer. Each concurrent_statement can be any of the statements described in this chapter, including other generate statements.
3. The identifier receives the next value of range, and each concurrent statement executes once more. 4. Step 3 repeats until the identifier receives the last value in the range and each concurrent statement executes for the last time. Execution continues with the statement following end generate. The loop identifier is deleted. Example 6-19 shows a code fragment that combines and interleaves two 4-bit arrays, A and B, into an 8-bit array, C. Figure 6-9 illustrates the resulting design.
For more information about arrays, see Array Types on page 3-9.
if...generate Statements
The syntax is
label: if expression generate { concurrent_statement } end generate [ label ] ;
label The label identifies (names) this statement. expression Any expression that evaluates to a Boolean value. concurrent_statement Any of the statements described in this chapter, including other generate statements. Note: Unlike the if statement described in if Statements on page 5-15, the if...generate statement has no else or elsif branches. You can use the if...generate statement to generate a regular structure that has different circuitry at its ends. Use a for...generate statement to iterate over the desired width of a design, and use a set of if...generate statements to define the beginning, middle, and ending sets of connections. Example 6-21 shows a technology-independent description of an N-bit serial-to-parallel converter. Data is clocked into an N-bit buffer from right to left. On each clock cycle, each bit in an N-bit buffer is shifted up 1 bit and the incoming DATA bit is moved into the low-order bit. Figure 6-11 illustrates the resulting design.
7
Register and Three-State Inference 7
FPGA Compiler II / FPGA Express can infer registers (latches and flip-flops) and three-state cells. This chapter explains inference behavior and results, in the following sections: Register Inference Three-State Inference
Register Inference
Register inference allows you to use sequential logic in your designs and keep your designs technology-independent. A register is a simple, 1-bit memory device, either a latch or a flip-flop. A latch is a level-sensitive memory device. A flip-flop is an edge-triggered memory device.
The register inference capability can support coding styles other than those described in this chapter. However, for best results,
Restrict each always block to a single type of memory-element inferencing: latch, latch with asynchronous set or reset, flip-flop, flip-flop with asynchronous reset, or flip-flop with synchronous reset. Use the templates provided in Inferring Latches on page 7-8 and Inferring Flip-Flops on page 7-21.
In the inference reports in Example 7-1, Y indicates that the flip-flop has a synchronous reset (SR) and a synchronous set (SS) N indicates that the flip-flop does not have an asynchronous reset (AR), an asynchronous set (AS), or a synchronous toggle (ST)
In the inference report (Example 7-1), the last part of the report lists the objects that control the synchronous reset and set conditions. In this example, a synchronous reset occurs when J is low (logic 0) and K is high (logic 1). The last line of the report indicates the register output when both set and reset are active: zero (0) Indicates that the reset has priority and that the output goes to logic 0. one (1) Indicates that the set has priority and that the output goes to logic 1. X Indicates that there is no priority and the output is unstable. Inferring Latches on page 7-8and Inferring Flip-Flops on page 7-21 provide inference reports for each register template. After you read a description in FPGA Compiler II / FPGA Express, check the inference report.
async_set_reset_local FPGA Compiler II / FPGA Express treats listed signals in the specified process as if they have the async_set_reset attribute set to true. Attach this attribute to a process label by using the following syntax:
attribute async_set_reset_local of process_label : label is signal_name_list;
async_set_reset_local_all FPGA Compiler II / FPGA Express treats all signals in the specified processes as if they have the async_set_reset attribute set to true.
sync_set_reset When this is set to true on a signal, FPGA Compiler II / FPGA Express checks the signal to determine whether it synchronously sets or resets a register in the design. Attach this attribute to 1-bit signals by using the following syntax:
attribute sync_set_reset of signal_name_list : is true; signal
sync_set_reset_local FPGA Compiler II / FPGA Express treats listed signals in the specified process as if they have the sync_set_reset attribute set to true. Attach this attribute to a process label by using the following syntax:
attribute sync_set_reset_local of process_label : label is signal_name_list;
sync_set_reset_local_all FPGA Compiler II / FPGA Express treats all signals in the specified processes as if they have the sync_set_reset attribute set to true.
one_cold A one_cold implementation means that all signals in a group are active low and that only one signal can be active at a given time. The one_cold attribute prevents FPGA Compiler II / FPGA Express from implementing priority encoding logic for the set and reset signals. Add an assertion to the VHDL code to ensure that the group of signals has a one_cold implementation. FPGA Compiler II / FPGA Express does not produce any logic to check this assertion. Attach this attribute to set or reset signals on sequential devices by using the following syntax:
attribute one_cold signal_name_list : signal is true;
one_hot A one_hot implementation means that all signals in a group are active high and that only one signal can be active at a given time. The one_hot attribute prevents FPGA Compiler II / FPGA Express from implementing priority encoding logic for the set and reset signals. Add an assertion to the VHDL code to ensure that the group of signals has a one_hot implementation. FPGA Compiler II / FPGA Express does not produce any logic to check this assertion.
Attach this attribute to set or reset signals on sequential devices by using the following syntax:
attribute one_hot signal_name_list : signal is true;
Inferring Latches
In simulation, a signal or variable holds its value until that output is reassigned. In a circuit, a latch implements this holding-of-state capability. FPGA Compiler II / FPGA Express supports inference of the following types of latches: SR latch D latch Master-slave latch
The following sections provide details about each of these latch types.
Inferring D Latches
When you do not specify the resulting value for an output under all conditions, as in an incompletely specified if statement, FPGA Compiler II / FPGA Express infers a D latch. For example, the if statement in Example 7-4 infers a D latch, because there is no else clause. The resulting value for output Q is specified only when input enable has a logic 1 value. As a result, output Q becomes a latched value.
To avoid latch inference, assign a value to the signal under all conditions, as shown in Example 7-5.
Variables declared locally within a subprogram do not hold their value over time, because each time a subprogram is called, its variables are reinitialized. Therefore, FPGA Compiler II / FPGA Express does not infer latches for variables declared in subprograms. In Example 7-6, FPGA Compiler II / FPGA Express does not infer a latch for output Q.
The following sections provide code examples, inference reports, and figures for these types of D latches: Simple D latch D latch with asynchronous set D latch with asynchronous reset D latch with asynchronous set and reset
Simple D Latch When you infer a D latch, make sure that you can control the gate and data signals from the top-level design ports or through combinational logic. Controllable gate and data signals ensure that simulation can initialize the design. Example 7-7 provides the VHDL template for a D latch. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-8. Figure 7-2 shows the inferred latch.
Type Latch
Width 1
Bus -
MB -
AR N
AS N
SR -
SS -
ST -
D Latch With Asynchronous Set The template in this section uses the async_set_reset attribute to direct FPGA Compiler II / FPGA Express to the asynchronous set (AS) pins of the inferred latch. Example 7-9 provides the VHDL template for a D latch with an asynchronous set. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-10. Figure 7-3 shows the inferred latch.
Type Latch
Width 1
Bus -
MB -
AR N
AS Y
SR -
SS -
ST -
Note: Because the target technology library does not contain a latch with an asynchronous set, FPGA Compiler II / FPGA Express synthesizes the set logic by using combinational logic. D Latch With Asynchronous Reset The template in this section uses the async_set_reset attribute to direct FPGA Compiler II / FPGA Express to the asynchronous reset (AR) pins of the inferred latch. Example 7-11 provides the VHDL template for a D latch with an asynchronous reset. FPGA Compiler II / FPGA Express generates
the inference report shown in Example 7-12. Figure 7-4 shows the inferred latch.
D Latch With Asynchronous Set and Reset Example 7-13 provides the VHDL template for a D latch with an active low asynchronous set and reset. This template uses the async_set_reset_local attribute to direct FPGA Compiler II / FPGA Express to the asynchronous signals in the infer process. The template in Example 7-13 uses the one_cold attribute to prevent priority encoding of the set and reset signals. If you do not specify the one_cold attribute, the set signal has priority, because it is used as the condition for the if clause. Example 7-14 shows the inference report. Figure 7-5 shows the inferred latch.
architecture rtl of d_latch_async is attribute async_set_reset_local of infer : label is SET, RESET; begin infer : process (GATE, DATA, SET, RESET) begin if (SET = 0) then Q <= 1; elsif (RESET = 0) then Q <= 0; elsif (GATE = 1) then Q <= DATA; end if; end process infer; end rtl;
Example 7-14 Inference Report for D Latch With Asynchronous Set and Reset
Register Name Q_reg Type Latch Width 1 Bus MB AR Y AS Y SR SS ST -
Understanding the Limitations of D Latch Inference A variable must always have a value before it is read. As a result, you cannot read a conditionally assigned variable after the if statement in which it is assigned. A conditionally assigned variable is assigned a new value under some, but not all, conditions. Example 7-15 shows an invalid use of the conditionally assigned variable VALUE.
Type Latch
Width 1
Bus -
MB -
AR N
AS N
SR -
SS -
ST -
Type Latch
Width 1
Bus -
MB -
AR N
AS N
SR -
SS -
ST -
Inferring Flip-Flops
FPGA Compiler II / FPGA Express can infer D flip-flops, JK flip-flops, and toggle flip-flops. The following sections give details about each. Many FPGA devices have a dedicated global set/reset hardware resource that may be used. For this reason, you should infer asynchronous set/reset signals for all flip-flops in the design. FPGA Compiler II / FPGA Express will then use the global set/reset lines.
Register and Three-State Inference 7-21
Inferring D Flip-Flops
FPGA Compiler II / FPGA Express infers a D flip-flop whenever the condition of a wait or if statement uses an edge expression (a test for the rising or falling edge of a signal). Use the following syntax to describe a rising edge:
SIGNALevent and SIGNAL = 1
If you are using the IEEE std_logic_1164 package, you can use the following syntax to describe a rising edge and a falling edge:
if (rising_edge (CLK)) then if (falling_edge (CLK)) then
If you are using the IEEE std_logic_1164 package, you can use the following syntax for a bused clock. You can also use a member of a bus as a signal.
sig(3)event and sig(3) = 1 rising_edge (sig(3))
A wait statement containing an edge expression causes FPGA Compiler II / FPGA Express to create flip-flops for all signals, and some variables are assigned values in the process. Example 7-18 shows the most common usage of the wait statement to infer a flipflop.
An if statement implies flip-flops for signals and variables in the branches of the if statement. Example 7-19 shows the most-common usages of the if statement to infer a flip-flop.
You can sometimes use wait and if statements interchangeably. If possible, use the if statement, because it provides greater control over the inferred registers.
The following sections provide code examples, inference reports, and figures for these types of D flip-flops: Positive edge-triggered D flip-flop Positive edge-triggered D flip-flop using rising_edge Negative edge-triggered D flip-flop Negative edge-triggered D flip-flop using falling_edge D flip-flop with asynchronous set D flip-flop with asynchronous reset D flip-flop with asynchronous set and reset D flip-flop with synchronous set D flip-flop with synchronous reset D flip-flop with synchronous and asynchronous load Multiple flip-flops with asynchronous and synchronous controls
Positive Edge-Triggered D Flip-Flop When you infer a D flip-flop, make sure that you can control the clock and data signals from the top-level design ports or through combinational logic. Controllable clock and data signals ensure that simulation can initialize the design. If you cannot control the clock and data signals, infer a D flip-flop with asynchronous reset or set, or with synchronous reset or set. Example 7-20 provides the VHDL template for a positive edgetriggered D flip-flop. Example 7-21 shows the inference report. Figure 7-7 shows the inferred flip-flop.
Positive Edge-Triggered D Flip-Flop Using rising_edge Example 7-22 provides the VHDL template for a positive edgetriggered D flip-flop using the IEEE_std_logic_1164 package and rising_edge. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-23. Figure 7-8 shows the inferred flip-flop.
Example 7-23 Inference Report for a Positive Edge-Triggered D Flip-Flop Using rising_edge
Register Name Q_reg Type Flip-flop Width 1 Bus MB AR N AS N SR N SS N ST N
Negative Edge-Triggered D Flip-Flop Example 7-24 provides the VHDL template for a negative edgetriggered D flip-flop. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-25. Figure 7-9 shows the inferred flip-flop.
Negative Edge-Triggered D Flip-Flop Using falling_edge Example 7-26 provides the VHDL template for a negative edgetriggered D flip-flop using the IEEE_std_logic_1164 package and falling_edge. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-27. Figure 7-10 shows the inferred flip-flop.
infer : process (CLK) begin if (falling_edge (CLK)) then Q <= DATA; end if; end process infer; end rtl;
Example 7-27 Inference Report for a Negative Edge-Triggered D Flip-Flop Using falling_edge
Register Name Q_reg Type Flip-flop Width 1 Bus MB AR N AS N SR N SS N ST N
D Flip-Flop With Asynchronous Set Example 7-28 provides the VHDL template for a D flip-flop with an asynchronous set. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-29. Figure 7-11 shows the inferred flip-flop.
Type Flip-flop
Width 1
Bus -
MB -
AR N
AS Y
SR N
SS N
ST N
D Flip-Flop With Asynchronous Reset Example 7-30 provides the VHDL template for a D flip-flop with an asynchronous reset. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-31. Figure 7-12 shows the inferred flip-flop.
D Flip-Flop With Asynchronous Set and Reset Example 7-32 provides the VHDL template for a D flip-flop with active high asynchronous set and reset pins. The template in Example 7-32 uses the one_hot attribute to prevent priority encoding of the set and reset signals. If you do not specify the one_hot attribute, the reset signal has priority, because it is used as the condition for the if clause. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-33. Figure 7-13 shows the inferred flip-flop. Note: Most FPGA architectures do not have a register with an asynchronous set AND asynchronous reset cell available. For this reason you should avoid this construct.
Example 7-33 Inference Report for a D Flip-Flop With Asynchronous Set and Reset
Register Name Q_reg Type Flip-flop Width 1 Bus MB AR Y AS Y SR N SS N ST N
D Flip-Flop With Synchronous Set or Reset The previous examples illustrate how to infer a D flip-flop with asynchronous controlsone way to initialize or control the state of a sequential device. You can also synchronously reset or set the flipflop (see Example 7-34 and Example 7-36). The sync_set_reset attribute directs FPGA Compiler II / FPGA Express to the synchronous controls of the sequential device. When the target technology library does not have a D flip-flop with synchronous reset, FPGA Compiler II / FPGA Express infers a D flipflop with synchronous reset logic as the input to the D pin of the flipflop. If the reset (or set) logic is not directly in front of the D pin of the flip-flop, initialization problems can occur during gate-level simulation of the design. D Flip-Flop With Synchronous Set Example 7-34 provides the VHDL template for a D flip-flop with synchronous set. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-35. Figure 7-14 shows the inferred flip-flop.
Register and Three-State Inference 7-34
Type Flip-flop
Width 1
Bus -
MB -
AR N
AS N
SR N
SS Y
ST N
D Flip-Flop With Synchronous Reset Example 7-36 provides the VHDL template for a D flip-flop with synchronous reset. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-37. Figure 7-15 shows the inferred flip-flop.
D Flip-Flop With Synchronous and Asynchronous Load D flip-flops can have asynchronous or synchronous controls. To infer a component with both synchronous and asynchronous controls, you must check the asynchronous conditions before you check the synchronous conditions. Example 7-38 provides the VHDL template for a D flip-flop with a synchronous load (called SLOAD) and an asynchronous load (called ALOAD). FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-39. Figure 7-16 shows the inferred flipflop.
architecture rtl of dff_a_s_load is begin infer: process (CLK, ALOAD) begin if (ALOAD = 1) then Q <= ADATA; elsif (CLKevent and CLK = 1) then if (SLOAD = 1) then Q <= SDATA; end if; end if; end process infer; end rtl;
Example 7-39 Inference Report for a D Flip-Flop With Synchronous and Asynchronous Load
Register Name Q_reg Type Flip-flop Width 1 Bus MB AR N AS N SR N SS N ST N
Multiple Flip-Flops: Asynchronous and Synchronous Controls If a signal is synchronous in one process but asynchronous in another, use the sync_set_reset_local and async_set_reset_local attributes to direct FPGA Compiler II / FPGA Express to the correct implementation. In Example 7-40, the process infer_sync uses the reset signal as a synchronous reset, and the process infer_async uses the reset signal as an asynchronous reset. Example 7-41 shows the inference report. Figure 7-17 shows the resulting design.
infer_async: process (CLK, RESET) begin if (RESET = 0) then Q2 <= 0; elsif (CLKevent and CLK = 1) then if (SLOAD = 1) then Q2 <= DATA2; end if; end if; end process infer_async; end rtl;
Type Flip-flop
Width 1
Bus -
MB -
AR N
AS N
SR Y
SS N
ST N
Type Flip-flop
Width 1
Bus -
MB -
AR Y
AS N
SR N
SS N
ST N
A flip-flop inference has specific limitations. See Understanding Limitations of Register Inference on page 7-57.
Inferring JK Flip-Flops
When you infer a JK flip-flop, make sure you can control the J, K, and clock signals from the top-level design ports to ensure that simulation can initialize the design. The following sections provide code examples, inference reports, and figures for these types of JK flip-flops: JK flip-flop JK flip-flop with asynchronous set and reset
JK Flip-Flop When you infer a JK flip-flop, make sure you can control the J, K, and clock signals from the top-level design ports to ensure that simulation can initialize the design. Example 7-42 provides the VHDL code that implements the JK flip-flop described in the truth table in Table 7-2. In the JK flip-flop, the J and K signals act as active high synchronous set and reset. Use the sync_set_reset attribute to indicate that the J and K signals are the synchronous set and reset for the design. Example 7-43 shows the inference report generated by FPGA Compiler II / FPGA Express. Figure 7-18 shows the inferred flip-flop.
JK Flip-Flop With Asynchronous Set and Reset Example 7-44 provides the VHDL template for a JK flip-flop with asynchronous set and reset. Use the sync_set_reset attribute to indicate the JK function. Use the one_hot attribute to prevent priority encoding of the J and K signals. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-45. Figure 7-19 shows the inferred flip-flop.
Example 7-45 Inference Report for JK Flip-Flop With Asynchronous Set and Reset
Register Name Q_reg
Q_reg Async-reset: RESET Async-set: SET Sync-reset: J K Sync-set: J K Sync-toggle: J K Async-set and Async-reset ==> Q: X Sync-set and Sync-reset ==> Q: X
Type Flip-flop
Width 1
Bus -
MB -
AR Y
AS Y
SR Y
SS Y
ST N
The following sections provide code examples, inference reports, and figures for these types of toggle flip-flops: Toggle flip-flop with asynchronous set Toggle flip-flop with asynchronous reset Toggle flip-flop with enable and asynchronous reset
Toggle Flip-Flop With Asynchronous Set Example 7-46 provides the VHDL template for a toggle flip-flop with asynchronous set. Example 7-47 shows the inference report. Figure 7-20 shows the inferred flip-flop.
Example 7-47 Inference Report for Toggle Flip-Flop With Asynchronous Set
Register Name TMP_Q_reg Type Flip-flop Width 1 Bus MB AR N AS Y SR N SS N ST Y
Toggle Flip-Flop With Asynchronous Reset Example 7-48 provides the VHDL template for a toggle flip-flop with asynchronous reset. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-49. Figure 7-21 shows the inferred flip-flop.
Example 7-49 Inference Report for a Toggle Flip-Flop With Asynchronous Reset
Register Name TMP_Q_reg Type Flip-flop Width 1 Bus MB AR Y AS N SR N SS N ST Y
Toggle Flip-Flop With Enable and Asynchronous Reset Example 7-50 provides the VHDL template for a toggle flip-flop with an enable and an asynchronous reset. The flip-flop toggles only when the enable (TOGGLE signal) has a logic 1 value. FPGA Compiler II / FPGA Express generates the inference report shown in Example 7-51. Figure 7-22 shows the inferred flip-flop.
Example 7-51 Inference Report for Toggle Flip-Flop With Enable and Asynchronous Reset
Register Name TMP_Q_reg Type Flip-flop Width 1 Bus MB AR Y AS N SR N SS N ST Y
Minimizing Flip-Flop Count HDL descriptions should build only as many flip-flops as a design requires.
Circuit Description Inferring Too Many Flip-Flops Example 7-52 shows a description that infers too many flip-flops. The inference report is shown in Example 7-53. Figure 7-23 shows the inferred flip-flops.
Example 7-52 has only one process, which contains a wait statement and six output signals. FPGA Compiler II / FPGA Express infers six flip-flops, one for each output signal in the process: COUNT(2:0) (three inferred flip-flops) AND_BITS (one inferred flip-flop) OR_BITS (one inferred flip-flop) XOR_BITS (one inferred flip-flop)
However, because the outputs AND_BITS, OR_BITS, and XOR_BITS depend solely on the value of variable COUNT, and variable COUNT is registered, these three outputs do not need to be registered. Therefore, assign AND_BITS, OR_BITS, and XOR_BITS within a process that does not have a wait statement (see the next section, Circuit Description Inferring Correct Number of Flip-Flops on page 7-54).
Example 7-53 Inference Report for Circuit With Six Inferred Flip-Flops
Register Name AND_BITS_reg COUNT_reg OR_BITS_reg XOR_BITS_reg Type Flip-flop Flip-flop Flip-flop Flip-flop Width 1 3 1 1 Bus Y MB N AR N N N N AS N N N N SR N N N N SS N N N N ST N N N N
RESET
CLK
Circuit Description Inferring Correct Number of Flip-Flops To avoid inferring extra flip-flops, assign the output signals from within a process that does not have a wait statement. Example 7-54 shows a description with two processes, one with a wait statement and one without. The registered (synchronous) assignments are in the first process, which contains the wait statement. The other (asynchronous) assignments are in the second process. Signals communicate between the two processes. This description style lets you choose the signals that are registered and those that are not. The inference report is shown in Example 7-55. Figure 7-24 shows the resulting circuit.
Example 7-55 Inference Report for Circuit With Three Inferred Flip-Flops
Register Name COUNT_reg Type Flip-flop Width 3 Bus Y MB N AR N AS N SR N SS N ST N
AND_BITS
OR_BITS
CLK
XOR_BITS
RESET
This technique of separating combinational logic from registered or sequential logic in your design is useful when describing finite state machines. See these in Appendix A, "Examples: Moore Machine on page A-2 Mealy Machine on page A-5 Count ZerosSequential Version on page A-22 Soft Drink MachineState Machine Version on page A-24
Correlating Synthesis Results With Simulation Results Using delay specifications with registered values can cause the simulation to behave differently from the logic synthesized by FPGA Compiler II / FPGA Express. For example, the description in Example 7-56 contains delay information that causes FPGA Compiler II / FPGA Express to synthesize a circuit that behaves unexpectedly (the postsynthesis simulation results do not match pre-synthesis simulation results).
Register and Three-State Inference 7-56
In Example 7-56, B changes 100 nanoseconds after A changes. If the clock period is less than 100 nanoseconds, output D is one or more clock cycles behind output C during simulation of the design. However, because FPGA Compiler II / FPGA Express ignores the delay information, A and B change values at the same time and so do C and D. This behavior is not the same as in the post-synthesis simulation. When using delay information in your designs, make sure that the delays do not affect registered values. In general, you can safely include delay information in your description if it does not change the value that gets clocked into a flip-flop.
Flip-flops with bidirectional pins Flip-flips with multiple clock inputs Multiport latches Register banks
Note: Although you can instantiate flip-flops with bidirectional pins, FPGA Compiler II / FPGA Express interprets these cells as black boxes. If you use an if statement to infer D flip-flops, your design must meet the following requirements: An edge expression must be the only condition of an if or an elsif clause. The following if statement is invalid because it has multiple conditions in the if clause:
if (edge and RST = 1)
You can have only one edge expression in an if clause, and the if clause must not have an else clause. The following if statement is invalid, because you cannot include an else clause when using an edge expression as the if or elsif condition:
if X > 5 then sequential_statement; elsif edge then sequential_statement; else sequential_statement; end if;
An edge expression cannot be part of another logical expression or be used as an argument. The following function call is invalid, because you cannot use the edge expression as an argument:
any_function(edge);
Three-State Inference
FPGA Compiler II / FPGA Express infers a three-state driver when you assign the value of Z to a signal or variable. The Z value represents the high-impedance state. FPGA Compiler II / FPGA Express infers one three-state driver per process. You can assign high-impedance values to single-bit or bused signals (or variables).
The first column of the report indicates the name of the inferred threestate device. The second column indicates the type of three-state device FPGA Compiler II / FPGA Express inferred. The third column indicates whether the three-state device has multiple bits.
Inferring One Three-State Driver From a Single Process Example 7-60 provides an example of placing all high-impedance assignments in a single process. In this case, the data is gated and FPGA Compiler II / FPGA Express infers a single three-state driver. Example 7-61 shows the inference report. Figure 7-26 shows the three-state driver.
TRI
Inferring Three-State Drivers From Separate Processes Example 7-62 provides an example of placing each high-impedance assignment in a separate process. In this case, FPGA Compiler II / FPGA Express infers multiple three-state drivers. Example 7-63 shows the inference report. Figure 7-27 shows the design.
Example 7-63 Inference Report for Two Three-State Drivers From Separate Processes
Three-State Device Name T_tri Three-State Device Name T_tri2 Type Three-State Buffer Type Three-State Buffer MB N MB N
Example 7-65 Inference Report for Three-State Driver With Registered Enable
Register Name OUT1_reg Type Flip-flop Width 1 Bus MB AR N AS N SR N SS N MB N N ST N
Example 7-67 Inference Report for Three-State Driver Without Registered Enable
Register Name TEMP_reg Type Flip-flop Width 1 Bus MB AR N AS N SR N SS N ST N MB N
You cannot use the Z value in an expression, except for comparison with Z. Be careful when using expressions that compare with the Z value. FPGA Compiler II / FPGA Express always evaluates such expressions to false, and the pre- and post-synthesis simulation results might differ. For this reason, FPGA Compiler II / FPGA Express issues a warning when it synthesizes such comparisons.
Example 7-68 shows an incorrect use of the Z value. Example 7-69 shows a correct use of the Z value.
8
Writing Circuit Descriptions 8
To understand FPGA Compiler II / FPGA Express and to write VHDL descriptions that produce efficient synthesized circuits, study the information presented in the following sections of this chapter: How Statements Are Mapped to Logic Design Structure Asynchronous Designs Dont Care Inference Synthesis Issues
Some general guidelines for writing efficient circuit descriptions are Restructure a design that makes repeated use of several large components to minimize the number of instantiations.
In a design that needs some, but not all, of its variables or signals stored during operation, minimize the number of latches or flipflops required. Consider collapsing hierarchy for more-efficient synthesis.
The logic blocks created by FPGA Compiler II / FPGA Express are custom-built for their environment. If A and B are 4-bit quantities, a
4-bit adder is built. If A and B are 9-bit quantities, a 9-bit adder is built. Because FPGA Compiler II / FPGA Express incorporates a large set of these customized logic blocks, it can translate most VHDL statements and operators.
Design Structure
A designs structure influences the size and complexity of the resulting synthesized circuit. These sections help you understand the concepts: Adding Structure Using Design Knowledge Optimizing Arithmetic Expressions Changing an Operator Bit-Width Using State Information Propagating Constants Sharing Complex Operators
Adding Structure
FPGA Compiler II / FPGA Express gives you significant control over the preoptimization structure, or organization of components, in your design. Whether or not your design structure is preserved after optimization depends on the options you select.
c0
c1
Using Parentheses
Another way to control the structure of a design is to use parentheses to define logic groupings. Example 8-4 describes a 4-input adder grouping. Figure 8-2 illustrates the resulting design.
Example 8-5 describes a 4-input adder grouping that is structured with parentheses. Figure 8-3 illustrates the design.
choice of implementation for an expression. Two forms of arithmetic optimization are discussed in this section: Arranging Expression Trees for Minimum Delay Sharing Common Subexpressions
The parser performs each addition in order, as though parentheses were placed within the expression as follows:
Z <= ((A + B) + C) + D;
Considering Signal Arrival Times To figure out the delay through an expression tree, FPGA Compiler II / FPGA Express considers the arrival times of each signal in the expression. If the arrival times of all the signals are the same, the length of the critical path of the expression in Example 8-6 equals three adder delays. The critical path delay can be reduced to two adder delays if you insert parentheses as follows:
Z <= (A + B) + (C + D);
Figure 8-5 Balanced Adder Tree (Same Arrival Times for All Signals)
A B C D
Suppose signals B, C, and D arrive at the same time and signal A arrives last. The expression tree that produces the minimum delay is: shown in Figure 8-6.
Figure 8-6 Expression Tree With Minimum Delay (Signal A Arrives Last)
B C D A
Using Parentheses You can use parentheses in expressions to exercise more control over the way expression trees are constructed. Parentheses are regarded as user directives that force an expression tree to use the groupings inside the parentheses. The expression tree cannot be rearranged in a way that violates these groupings. To see the effect of parentheses on the construction of an expression tree, consider Example 8-7.
The parentheses in the expression in Example 8-7 define the following subexpressions:
1 (B + C) 2 (A + (B + C)) 3 ((A + (B + C)) + D + E)
These subexpressions must be preserved in the expression tree. The default expression tree for Example 8-7 is shown in Figure 8-7.
C A D E F
Considering Overflow Characteristics When FPGA Compiler II / FPGA Express performs arithmetic optimization, it determines how to handle the overflow from carry bits during addition. The optimized structure of an expression tree is affected by the bitwidths you declare for storing intermediate results. For example, suppose you write an expression that adds two 4-bit numbers and stores the result in a 4-bit register. If the result of the addition overflows the 4-bit output, the most-significant bits are truncated. Example 8-8 shows how FPGA Compiler II / FPGA Express handles overflow characteristics.
In Example 8-8, three variables (a + b + c) are added. A temporary variable, t, holds the intermediate result of a + b. If t is declared as a 4-bit variable, the overflow bits from the addition of a + b are truncated. The parser determines the default structure of the expression tree, which is shown in Figure 8-8.
Now suppose the addition is performed without a temporary variable (z = a + b + c). FPGA Compiler II / FPGA Express determines that 5 bits are needed to store the intermediate result of the addition, so no overflow condition exists. The results of the final addition can be different from those of the first case, where a 4-bit temporary variable is declared that truncates the result of the intermediate addition. Therefore, these two expression trees do not always yield the same result. The expression tree for the second case is shown in Figure 8-9.
Instead of manually forcing common subexpressions to be shared, you can let FPGA Compiler II / FPGA Express automatically determine whether sharing common subexpressions improves your circuit. You do not need to declare a temporary variable to hold the common subexpression in this case.
In some cases, sharing common subexpressions results in the building of more adders. Consider Example 8-10, where A + B is a common subexpression.
E + F; A + B;
If the common subexpression A + B is shared, three adders are necessary to implement this section of code.
(A + B) (C + D) (E + F)
If the common subexpression is not shared, only two adders are necessary: one to implement the additions A + B and C + D, and one to implement the additions E + F and A + B. FPGA Compiler II / FPGA Express analyzes common subexpressions during the resource sharing phase of the compile process and considers area costs and timing characteristics. To turn off the sharing of common subexpressions for the current design, use the constraint manager. The default is true.
The parser does not recognize A + B as a common subexpression, because it parses the second equation as (D + A) + B. You can force the parser to recognize the common subexpression by rewriting the second assignment statement as
Z <= A + B + D;
or
Z <= D + (A + B);
Note: You do not have to rewrite the assignment statement, because FPGA Compiler II / FPGA Express recognizes common subexpressions automatically.
Example 8-13 shows how this change in TEMPs declaration can yield a significant savings in circuit area, which Figure 8-11 illustrates.
-- Hold value of Z
NEXT_STATE <= HOLD0; else NEXT_STATE <= SET1; end if; when SET1 => Z <= 1; NEXT_STATE <= SET0; end case; end process COMBIN; -- Set Z to 1
-- Process to hold synchronous elements (flip-flops). SYNCH: process begin wait until CLOCKevent and CLOCK = 1; CURRENT_STATE <= NEXT_STATE; PREVIOUS_Z <= Z; end process SYNCH; end BEHAVIOR;
In the state HOLD0, output Z retains its value from the previous state. To accomplish this, you insert a flip-flop to hold PREVIOUS_Z. However, you can make some assertions about the value of Z. In state HOLD0, the value of Z is always 0. You can deduce this from the fact that state HOLD0 is entered only from state SET0, where Z is always assigned 0. Example 8-15 shows how you can change the VHDL description to use this assertion, resulting in a simpler circuit. Figure 8-13 illustrates the circuit.
Propagating Constants
Constant propagation is the compile-time evaluation of expressions containing constants. FPGA Compiler II / FPGA Express uses constant propagation to reduce the amount of hardware required to implement operators. For example, a + operator with a constant 1 as one of its arguments causes an incrementer to be built, rather than a general adder. If both arguments of + or any other operator are constants, no hardware is constructed, because the expressions value is calculated by FPGA Compiler II / FPGA Express and inserted directly in the circuit. Other operators that benefit from constant propagation include comparators and shifters. Shifting a vector by a constant amount requires no logic to implement; it requires only a reshuffling (rewiring) of bits.
Asynchronous Designs
In a synchronous design, all flip-flops use a single clock that is a primary input to the design and there are no combinational feedback paths. Synchronous designs perform the same function regardless of the clock rate if all signals can propagate through the designs combinational logic during the clocks cycle time. FPGA Compiler II / FPGA Express treats all designs as synchronous. It can therefore change the timing behavior of the combinational logic if the maximum and minimum delay requirements are met. FPGA Compiler II / FPGA Express always preserves the Boolean function computed by logic, assuming that the clock arrives after all signals have propagated. FPGA Compiler II / FPGA Expresss builtin timing verifier helps determine the slowest path (critical path) through the logic, which determines how fast the clock can run. FPGA Compiler II / FPGA Express provides some support for asynchronous designs, but you must assume a greater responsibility for the accuracy of your circuits. Although fully synchronous circuits usually agree with their simulation models, asynchronous circuits might not. FPGA Compiler II / FPGA Express might not warn you when a design is not fully synchronous. Be aware of the possibility of asynchronous timing problems. The most common way to produce asynchronous logic in VHDL is to use gated clocks on latches or flip-flops. Example 8-17 shows a fully synchronous design, a counter with synchronous ENABLE and RESET inputs. Because it is synchronous, this counter works if the clock speed is slower than the critical path. Figure 8-14 illustrates the design.
Example 8-18 shows an asynchronous version of the design in Example 8-17. The version in Example 8-18 uses two common asynchronous design techniques: The first technique, shown in Example 8-15, enables the counter by using an AND gate on the clock and enable signals. The second technique, shown in Figure 8-16, uses an asynchronous reset.
These techniques work only when the proper timing relationships exist between the reset signal (RESET) and the clock signal (CLK) and there are no glitches in these signals.
Figure 8-15 Design With AND Gate on Clock and Enable Signals
Example 8-19 shows an asynchronous design that might not work, because FPGA Compiler II / FPGA Express does not guarantee that the combinational logic it builds has no hazards (glitches).
The design in Example 8-19 works only when the logic driving the preset and clear pins of the flip-flops that hold Z is faster than the clock speed. If you use this design style, you must simulate the synthesized circuit thoroughly. You also need to inspect the synthesized logic, because potential glitches might not appear in simulation. For a safer design, use a synchronous LOAD_ENABLE. A design synthesized with complex logic driving the gate of a latch rarely works. Example 8-20 describes an asynchronous design that never works. Figure 8-17 shows the resulting schematic.
Writing Circuit Descriptions 8-27
In Example 8-20 and Figure 8-17, the comparators output latches the value A onto the value Z. This design might work under behavioral simulation where the comparison happens instantly. However, the hardware comparator generates glitches that cause the latches to store new data when they should not.
Example 8-21 Using dont care Type for Seven-Segment LED Decoder
package P is type MULTI is (0, 1, D, Z); attribute ENUM_ENCODING: STRING; attribute ENUM_ENCODING of MULTI : type is 0 1 D Z; type MULTI_VECTOR is array (INTEGER range <>) of MULTI; end P; use work.P.all; entity CONVERTER is port(BCD: in MULTI_VECTOR(3 downto 0); LED: out MULTI_VECTOR(6 downto 0)); -- pragma dc_script_begin -- set_flatten true -- pragma dc_script_end end CONVERTER;
architecture BEHAVIORAL of CONVERTER is begin CONV: process(BCD) begin case BCD is when 0000 => LED <= 1111110; when 0001 => LED <= 1100000; when 0010 => LED <= 1011011; when 0011 => LED <= 1110011; when 0100 => LED <= 1100101; when 0101 => LED <= 0110111; when 0110 => LED <= 0111111; when 0111 => LED <= 1100010; when 1000 => LED <= 1111111; when 1001 => LED <= 1110111; when others => LED <= DDDDDDD; end case; end process CONV; end BEHAVIORAL;
Example 8-22 shows the seven-segment decoder used in Example 8-21, but the default assignment to LED is 0 instead of dont care. Note the larger gate count in the circuit without dont care values. Figure 8-19 illustrates the design.
For example, if you assign a default dont care value to VAR and later assign a value to VAR, expecting VAR to be a dont care, you might have overlooked an intervening condition under which VAR is assigned. Therefore, when you assign a value to a variable (or signal) containing a dont care value, make sure that the variable (or signal) is really a dont care type under those conditions.
These guidelines guarantee that when you simulate in the scope of the design itself, the only difference between simulation and synthesis occurs when the simulator defines an output as a dont care. Note: If you use dont care values internally to a design, expressions compared with dont care (D) are synthesized as though their values are not equal to D.
For example,
if X = D then ...
is synthesized as
if FALSE then
If you use expressions comparing values with D, there might be a difference between pre- and post-synthesis simulation results. For this reason, FPGA Compiler II / FPGA Express issues a warning when it synthesizes such comparisons.
Warning: A partial dont-care value was read in routine test line 24 in file test.vhdl This may cause simulation to disagree with synthesis. (HDL-171)
Synthesis Issues
Feedback paths and latches result from ambiguities in signal or variable assignments and language supersets, or the differences between a VHDL simulator view and the Synopsys use of VHDL.
specified when a condition exists under which the variable is not assigned.
The conditions of each if and else statement are considered independent in Example 8-23. A is considered not fully specified in the following fragment:
if (COND1) then A <= 1; end if; if (not COND1) then A <= 0; end if;
A variable or signal that is not fully specified in a combinational process is considered conditionally specified. In this case a flowthrough latch is implied. You can conditionally assign a variable, but you cannot read a conditionally specified variable. You can, however, both conditionally assign and read a signal. If a fully specified variable is read before its assignment statements, combinational feedback might exist. For example, the following fragment synthesizes combinational feedback for VAL.
process(NEW, LOAD) variable VAL: BIT; begin if (LOAD) then VAL <= NEW; else VAL <= VAL; end if; VAL_OUT <= VAL; end process;
In a combinational process, you can ensure that a variable or signal is fully specified by providing an initial (default) assignment to the variable at the beginning of the process. This default assignment assures that the variable is always assigned a value, regardless of conditions. Subsequent assignment statements can override the default. A default assignment is made to variables A and C in Example 8-23. Another way to ensure that you do not imply combinational feedback is to use a sequential process (one with a wait or if signalevent statement). In such a case, variables and signals are registered. The registers break the combinational feedback loop. See Chapter 7, "Register and Three-State Inference, for more information about sequential processes and the conditions under which FPGA Compiler II / FPGA Express infers registers and latches.
Asynchronous Behavior
Some forms of asynchronous behavior are not supported. An example is a circuit description of a one-shot signal generator of the form
X <= A nand (not(not(not A)));
You might expect this circuit description to generate three inverters (an inverting delay line) and a NAND gate, but it is optimized to
X <= A nand (not A);
then
X <= 1;
9
FPGA Compiler II / FPGA Express Directives
Synopsys has defined several methods of providing circuit design information directly in your VHDL source code. Using FPGA Compiler II / FPGA Express directives, you can direct translation from VHDL to components with special VHDL comments. These synthetic comments turn translation on or off, specify one of several hard-wired resolution methods, and provide a means to map subprograms to hardware components. To familiarize yourself with FPGA Compiler II / FPGA Express directives, consider the following topics presented in this chapter: Notation for FPGA Compiler II / FPGA Express Directives FPGA Compiler II / FPGA Express Directives
The use of these directives in FPGA Compiler II / FPGA Express can lead to errors in your design.
entity DRIVER is end DRIVER; architecture VHDL of DRIVER is signal A, B : INTEGER range 0 to 255; signal SUM : INTEGER range 0 to 511; component EXAMPLE port (A, B: in INTEGER range 0 to 255; SUM: out INTEGER range 0 to 511); end component; begin U1: EXAMPLE port map(A, B, SUM); process begin for I in 0 to 255 loop for J in 0 to 255 loop A <= I; B <= J; wait for 10 ns; assert SUM = A + B; end loop; end loop; end process; end VHDL; -- pragma synthesis_on -- Code from here on is translated entity EXAMPLE is port (A, B: in INTEGER range 0 to 255; SUM: out INTEGER range 0 to 511); end EXAMPLE; architecture VHDL of EXAMPLE is begin SUM <= A + B; end VHDL;
Note: Do not connect signals that use different resolution functions. FPGA Compiler II / FPGA Express supports only one resolution function per network.
A
Examples A
This appendix presents examples that demonstrate basic concepts of Synopsys FPGA Compiler II / FPGA Express: Moore Machine Mealy Machine Read-Only Memory Waveform Generator Smart Waveform Generator Definable-Width Adder-Subtracter Count ZerosCombinational Version Count ZerosSequential Version Soft Drink MachineState Machine Version
Examples A-1
Soft Drink MachineCount Nickels Version Carry-Lookahead Adder Serial-to-Parallel ConverterCounting Bits Serial-to-Parallel ConverterShifting Bits Programmable Logic Arrays
Moore Machine
Figure A-1 is a diagram of a simple Moore finite state machine. It has one input (X), four internal states (S0 to S3), and one output (Z).
0 1 S3 0 1
The VHDL code implementing this finite state machine is shown in Example A-1, which includes a schematic of the synthesized circuit.
Examples A-2
The machine description includes two processes. One process defines the synchronous elements of the design (state registers); the other process defines the combinational part of the design (state assignment case statement). For more details on using the two processes, see Combinational Versus Sequential Processes on page 5-55.
architecture BEHAVIOR of MOORE is type STATE_TYPE is (S0, S1, S2, S3); signal CURRENT_STATE, NEXT_STATE: STATE_TYPE; begin -- Process to hold combinational logic COMBIN: process(CURRENT_STATE, X) begin case CURRENT_STATE is when S0 => Z <= 0; if X = 0 then NEXT_STATE <= S0; else NEXT_STATE <= S2; end if; when S1 => Z <= 1; if X = 0 then NEXT_STATE <= S0; else NEXT_STATE <= S2; end if; when S2 => Z <= 1; if X = 0 then
Examples A-3
NEXT_STATE <= else NEXT_STATE <= end if; when S3 => Z <= 0; if X = 0 then NEXT_STATE <= else NEXT_STATE <= end if; end case; end process COMBIN;
S2; S3;
S3; S1;
-- Process to hold synchronous elements (flip-flops) SYNCH: process begin wait until CLOCKevent and CLOCK = 1; CURRENT_STATE <= NEXT_STATE; end process SYNCH; end BEHAVIOR;
Examples A-4
Mealy Machine
Figure A-3 is a diagram of a simple Mealy finite state machine. The VHDL code for implementing this finite state machine is shown in Example A-2. The machine description includes two processes, as in the previous Moore machine example.
0/0 S0
0/0
S3
architecture BEHAVIOR of MEALY is type STATE_TYPE is (S0, S1, S2, S3); signal CURRENT_STATE, NEXT_STATE: STATE_TYPE;
Examples A-5
begin -- Process to hold combinational logic. COMBIN: process(CURRENT_STATE, X) begin case CURRENT_STATE is when S0 => if X = 0 then Z <= 0; NEXT_STATE <= S0; else Z <= 1; NEXT_STATE <= S2; end if; when S1 => if X = 0 then Z <= 0; NEXT_STATE <= S0; else Z <= 0; NEXT_STATE <= S2; end if; when S2 => if X = 0 then Z <= 1; NEXT_STATE <= S2; else Z <= 0; NEXT_STATE <= S3; end if; when S3 => if X = 0 then Z <= 0; NEXT_STATE <= S3; else Z <= 1; NEXT_STATE <= S1; end if; end case; end process COMBIN; -- Process to hold synchronous elements (flip-flops) SYNCH: process
Examples A-6
begin wait until CLOCKevent and CLOCK = 1; CURRENT_STATE <= NEXT_STATE; end process SYNCH; end BEHAVIOR;
Read-Only Memory
Example A-3 shows how you can define a read-only memory in VHDL. The ROM is defined as an array constant, ROM. Each line of the constant array specification defines the contents of one ROM address. To read from the ROM, index into the array. The number of ROM storage locations and bit-width is easy to change. The subtype ROM_RANGE specifies that the ROM contains storage locations 0 to 7. The constant ROM_WIDTH specifies that the ROM is 5 bits wide.
Examples A-7
After you define a ROM constant, you can index into that constant many times to read many values from the ROM. If the ROM address is computable (see Computable Operands on page 4-16), no logic is built and the appropriate data value is inserted. If the ROM address is not computable, logic is built for each index into the value. In Example A-3, ADDR is not computable, so logic is synthesized to compute the value. FPGA Compiler II / FPGA Express does not actually instantiate a typical array-logic ROM, such as those available from ASIC vendors. Instead, it creates the ROM from random logic gates (AND, OR, NOT, and so on). This type of implementation is preferable for small ROMs and for ROMs that are regular. For very large ROMs, consider using an array-logic implementation supplied by your ASIC vendor. Example A-3 shows the VHDL source code and the synthesized circuit schematic.
Examples A-8
port(ADDR: in ROM_RANGE; DATA: out ROM_WORD); end ROM_5x8; architecture BEHAVIOR of ROM_5x8 is begin DATA <= ROM(ADDR); -- Read from the ROM end BEHAVIOR;
Examples A-9
Waveform Generator
The waveform generator example shows how to use the previous ROM example to implement a waveform generator. Assume that you want to produce the waveform output shown in Figure A-6. 1. First, declare a ROM wide enough to hold the output signals (4 bits) and deep enough to hold all time steps (0 to 12, for a total of 13). 2. Next, define the ROM so that each time step is represented by an entry in the ROM. 3. Finally, create a counter that cycles through the time steps (ROM addresses), generating the waveform at each time step.
Examples A-10
Example A-4 shows an implementation for the waveform generator. It consists of a ROM, a counter, and some simple reset logic.
-- Waveform generator
Examples A-11
architecture BEHAVIOR of WAVEFORM is signal STEP: ROM_RANGE; begin TIMESTEP_COUNTER: process -- Time stepping process begin wait until CLOCKevent and CLOCK = 1; if RESET then -- Detect reset STEP <= ROM_RANGElow; -- Restart elsif STEP = ROM_RANGEhigh then -- Finished? STEP <= ROM_RANGEhigh; -- Hold at last value -- STEP <= ROM_RANGElow; -- Continuous wave else STEP <= STEP + 1; -- Continue stepping end if; end process TIMESTEP_COUNTER; WAVES <= ROM(STEP); end BEHAVIOR;
Examples A-12
When the counter STEP reaches the end of the ROM, STEP stops, generates the last value, then waits until a reset. To make the sequence automatically repeat, remove the following statement:
STEP <= ROM_RANGEhigh; -- Hold at last value
0 1
10
11
12
4 80 5 20 5
Examples A-13
The implementation of the smart waveform generator is shown in Example A-5. It is similar to the waveform generator in Example A-4 on page A-11, but has two additions. A new ROM, D_ROM, has been added to hold the length of each time step. A value of 1 specifies that the corresponding time step should be one clock cycle long; a value of 80 specifies that the time step should be 80 clock cycles long. The second addition to the previous waveform generator is a delay counter that counts the clock cycles between time steps. In the architecture of this example, a selected signal assignment determines the value of the NEXT_STEP counter.
Examples A-14
type D_ROM_TABLE is array (0 to 12) of D_ROM_WORD; constant D_ROM: D_ROM_TABLE := D_ROM_TABLE( 1,80,5,1,1,1,1,20,5,1,1,1,1); end ROMS; use work.ROMS.all; entity WAVEFORM is -- Smart Waveform Generator port(CLOCK: in BIT; RESET: in BOOLEAN; WAVES: out W_ROM_WORD); end WAVEFORM; architecture BEHAVIOR of WAVEFORM is signal STEP, NEXT_STEP: W_ROM_RANGE; signal DELAY: D_ROM_WORD; begin -- Determine the value of the next time step NEXT_STEP <= W_ROM_RANGEhigh when STEP = W_ROM_RANGEhigh else STEP + 1; -- Keep track of which time step we are in TIMESTEP_COUNTER: process begin wait until CLOCKevent and CLOCK = 1; if RESET then -- Detect reset STEP <= 0; -- Restart waveform elsif DELAY = 1 then STEP <= NEXT_STEP; -- Continue stepping else null; -- Wait for DELAY to count down; end if; -- do nothing here end process TIMESTEP_COUNTER; -- Count the delay between time steps DELAY_COUNTER: process begin wait until CLOCKevent and CLOCK = 1; if RESET then -- Detect reset DELAY <= D_ROM(0); -- Restart elsif DELAY = 1 then -- Have we counted down?
Examples A-15
DELAY <= D_ROM(NEXT_STEP); -- Next delay value else DELAY <= DELAY - 1; -- decrement DELAY counter end if; end process DELAY_COUNTER; WAVES <= W_ROM(STEP); end BEHAVIOR; -- Output waveform value
Definable-Width Adder-Subtracter
VHDL lets you create functions for use with array operands of any size. This example shows an adder-subtracter circuit that, when called, is adjusted to fit the size of its operands.
Examples A-16
Example A-6 shows an adder-subtracter defined for two unconstrained arrays of bits (type BIT_VECTOR) in a package named MATH. When an unconstrained array type is used for an argument to a subprogram, the actual constraints of the array are taken from the actual parameter values in a subprogram call.
Examples A-17
-- Result
Within the function ADD_SUB, two temporary variables, A and B, are declared. These variables are declared to be the same length as L (and necessarily, R) but have their index constraints normalized to Llength-1 downto 0. After the arguments are normalized, you can create a ripple carry adder by using a for loop. No explicit references to a fixed array length are in the function ADD_SUB. Instead, the VHDL array attributes left and length are used. These attributes allow the function to work on arrays of any length. Example A-7 shows how to use the adder-subtracter defined in the MATH package. In this example, the vector arguments to functions ARG1 and ARG2 are declared as BIT_VECTOR(1 to 6). This declaration causes ADD_SUB to work with 6-bit arrays. A schematic of the synthesized circuit follows Example A-7.
Examples A-18
The circuit produces two outputs: the number of zeros found and an error indication. A valid input value can have at most one consecutive series of zeros. A value consisting entirely of ones is defined as a valid value. If a value is invalid, the zero counter resets to 0. For example, the value 00000000 is valid and has eight zeros; value 11000111 is valid and has three zeros; value 00111100 is invalid.
Examples A-19
Example A-8 shows the VHDL description for the circuit. It consists of a single process with a for loop that iterates across each bit in the given value. At each iteration, a temporary INTEGER variable (TEMP_COUNT) counts the number of zeros encountered. Two temporary Boolean variables (SEEN_ZERO and SEEN_TRAILING), initially false, are set to true when the beginning and end of the first sequence of zeros is detected. If a zero is detected after the end of the first sequence of zeros (after SEEN_TRAILING is true), the zero count is reset (to 0), ERROR is set to true, and the for loop is exited. Example A-8 shows a combinational (parallel) approach to counting the zeros. The next example shows a sequential (serial) approach.
Examples A-20
SEEN_TRAILING <= TRUE; elsif (DATA(I) = 0) then SEEN_ZERO <= TRUE; TEMP_COUNT <= TEMP_COUNT + 1; end if; end loop; COUNT <= TEMP_COUNT; end process; end BEHAVIOR;
Examples A-21
The circuits three outputs are IS_LEGAL, which is true if the data was a valid value COUNT_READY, which is true at the first invalid bit or when all 8 bits have been processed COUNT, the number of zeros (if IS_LEGAL is true)
Note: The output port COUNT is declared with mode BUFFER so that it can be read inside the process. OUT ports can only be written to, not read in.
Examples A-22
begin process variable SEEN_ZERO, SEEN_TRAILING: BOOLEAN; variable BITS_SEEN: INTEGER range 0 to 7; begin wait until CLKevent and CLK = 1; if(RESET) then COUNT_READY <= FALSE; IS_LEGAL <= TRUE; -- signal assignment SEEN_ZERO <= FALSE; -- variable assignment SEEN_TRAILING <= FALSE; COUNT <= 0; BITS_SEEN <= 0; else if (READ) then if (SEEN_TRAILING and DATA = 0) then IS_LEGAL <= FALSE; COUNT <= 0; COUNT_READY <= TRUE; elsif (SEEN_ZERO and DATA = 1) then SEEN_TRAILING := TRUE; elsif (DATA = 0) then SEEN_ZERO <= TRUE; COUNT <= COUNT + 1; end if; if (BITS_SEEN = 7) then COUNT_READY <= TRUE; else BITS_SEEN <= BITS_SEEN + 1; end if; end if; end if; end process; end BEHAVIOR; -- if (READ) -- if (RESET)
Examples A-23
Examples A-24
The output signals to the change dispensing unit are NICKEL_OUT and DIME_OUT. The output signal to the drink dispensing unit is DISPENSE (dispense drink). The first VHDL description for this design uses a state machine description style. The second VHDL description is in Example A-11.
Examples A-25
if(RESET) then NEXT_STATE <= IDLE; else -- State transitions and output logic case CURRENT_STATE is when IDLE => if(NICKEL_IN) then NEXT_STATE <= FIVE; elsif(DIME_IN) then NEXT_STATE <= TEN; elsif(QUARTER_IN) then NEXT_STATE <= TWENTY_FIVE; end if; when FIVE => if(NICKEL_IN) then NEXT_STATE <= TEN; elsif(DIME_IN) then NEXT_STATE <= FIFTEEN; elsif(QUARTER_IN) then NEXT_STATE <= THIRTY; end if; when TEN => if(NICKEL_IN) then NEXT_STATE <= FIFTEEN; elsif(DIME_IN) then NEXT_STATE <= TWENTY; elsif(QUARTER_IN) then NEXT_STATE <= IDLE; DISPENSE <= TRUE; end if; when FIFTEEN => if(NICKEL_IN) then NEXT_STATE <= TWENTY; elsif(DIME_IN) then NEXT_STATE <= TWENTY_FIVE; elsif(QUARTER_IN) then NEXT_STATE <= IDLE; DISPENSE <= TRUE; NICKEL_OUT <= TRUE; end if;
Examples A-26
when TWENTY => if(NICKEL_IN) then NEXT_STATE <= TWENTY_FIVE; elsif(DIME_IN) then NEXT_STATE <= THIRTY; elsif(QUARTER_IN) then NEXT_STATE <= IDLE; DISPENSE <= TRUE; DIME_OUT <= TRUE; end if; when TWENTY_FIVE => if(NICKEL_IN) then NEXT_STATE <= THIRTY; elsif(DIME_IN) then NEXT_STATE <= IDLE; DISPENSE <= TRUE; elsif(QUARTER_IN) then NEXT_STATE <= IDLE; DISPENSE <= TRUE; DIME_OUT <= TRUE; NICKEL_OUT <= TRUE; end if; when THIRTY => if(NICKEL_IN) then NEXT_STATE <= IDLE; DISPENSE <= TRUE; elsif(DIME_IN) then NEXT_STATE <= IDLE; DISPENSE <= TRUE; NICKEL_OUT <= TRUE; elsif(QUARTER_IN) then NEXT_STATE <= OWE_DIME; DISPENSE <= TRUE; DIME_OUT <= TRUE; end if; when OWE_DIME => NEXT_STATE <= IDLE; DIME_OUT <= TRUE;
Examples A-27
end case; end if; end process; -- Synchronize state value with clock -- This causes it to be stored in flip-flops process begin wait until CLKevent and CLK = 1; CURRENT_STATE <= NEXT_STATE; end process; end BEHAVIOR;
Examples A-28
Examples A-29
elsif(DIME_IN) then TEMP_NICKEL_COUNT <= TEMP_NICKEL_COUNT + 2; elsif(QUARTER_IN) then TEMP_NICKEL_COUNT <= TEMP_NICKEL_COUNT + 5; end if; -- Enough deposited so far? if(TEMP_NICKEL_COUNT >= 7) then TEMP_NICKEL_COUNT <= TEMP_NICKEL_COUNT - 7; DISPENSE <= TRUE; end if; -- Return change if(TEMP_NICKEL_COUNT >= 1 or CURRENT_RETURN_CHANGE) then if(TEMP_NICKEL_COUNT >= 2) then DIME_OUT <= TRUE; TEMP_NICKEL_COUNT <= TEMP_NICKEL_COUNT - 2; NEXT_RETURN_CHANGE <= TRUE; end if; if(TEMP_NICKEL_COUNT = 1) then NICKEL_OUT <= TRUE; TEMP_NICKEL_COUNT <= TEMP_NICKEL_COUNT - 1; end if; end if; NEXT_NICKEL_COUNT <= TEMP_NICKEL_COUNT; end if; end process; -- Remember the return-change flag and -- the nickel count for the next cycle process begin wait until CLKevent and CLK = 1; CURRENT_RETURN_CHANGE <= NEXT_RETURN_CHANGE; CURRENT_NICKEL_COUNT <= NEXT_NICKEL_COUNT; end process; end BEHAVIOR;
Examples A-30
Examples A-31
Carry-Lookahead Adder
This example uses concurrent procedure calls to build a 32-bit carrylookahead adder. The adder is built by partitioning of the 32-bit input into eight slices of 4 bits each. Each of the eight slices computes propagate and generate values by using the PG procedure. Propagate (output P from PG) is 1 for a bit position if that position propagates a carry from the next-lower position to the next-higher position. Generate (output G) is 1 for a bit position if that position generates a carry to the next-higher position, regardless of the carryin from the next lower position. The carry-lookahead logic reads the carry-in, propagate, and generate information computed from the inputs. The logic computes the carry value for each bit position and makes the addition operation an XOR of the inputs and the carry values.
Examples A-32
The second-level lookahead blocks read the group-propagate and generate information from the four first-level blocks and then compute their own group-propagate and generate information. The second-level lookahead blocks also read group carry information computed at the third level to compute the carries for each of the third-level blocks. The third-level block reads the propagate and generate information of the second level to compute a propagate and generate value for the entire adder. It also reads the external carry to compute each second-level carry. The carry-out for the adder is 1 if the third-level generate is 1 or if the third-level propagate is 1 and the external carry is 1. The third-level carry-lookahead block is capable of processing four second-level blocks. But because there are only two secondlevel blocks, the high-order 2 bits of the computed carry are ignored; the high-order two bits of the generate input to the thirdlevel are set to zero, 00; and the propagate high-order bits are set to 11. These settings cause the unused portion to propagate carries but not to generate them. Figure A-15 shows the overall structure for the carry-lookahead adder.
Examples A-33
CIN
P G
6
PG
A 27:24 B 27:24
P CLA GP G GG
CIN COUT 27:24
7 7
P G
5
P CLA GP G GG
CIN COUT 23:20
6 6 1
GP 7:4
"00"
CIN COUT
PG
A 23:20 B 23:20
P G
4
P CLA GP G GG
CIN COUT 19:16
5 5
GG 7:4
P CLA GP G GG
1 1
PG
A 19:16 B 19:16
Third-Level Block
4 4 GC 7:4 GC 3:0 GGC
P G
P CLA GP G GG
PG
CIN COUT
GGGP P CLA GP G GG
3 A 15:12 B 15:12
P G
2
PG
A 11:8 B 11:8
P CLA GP G GG
CIN COUT 11:8
3 3
GGGG
P G
1
P CLA GP G GG
CIN COUT 7:4
2 2 0
GP 3:0
PG
A 7:4 B 7:4
P G
0
P CLA GP G GG
CIN COUT 3:0
1 1
GG 3:0
PG
A 3:0 B 3:0
P G
P CLA GP G GG
0 0
PG
GGGG or (GGGP and CIN)
XOR S COUT
Examples A-34
The VHDL implementation of the design in Figure A-15 is accomplished with four procedures: CLA Names a 4-bit carry-lookahead block. PG Computes first-level propagate and generate information. SUM Computes the sum by adding the XOR values to the inputs with the carry values computed by CLA. BITSLICE Collects the first-level CLA blocks, the PG computations, and the SUM. This procedure performs all the work for a 4-bit value except for the second- and third-level lookaheads. Example A-12 shows a VHDL description of the adder.
Examples A-35
package body LOCAL is ------------------------------------------------ Compute sum and group outputs from a, b, cin ----------------------------------------------procedure BITSLICE( A, B: in BIT_VECTOR(3 downto 0); CIN: in BIT; signal S: out BIT_VECTOR(3 downto 0); signal GP, GG: out BIT) is variable P, G, C: BIT_VECTOR(3 downto 0); begin PG(A, B, P, G); CLA(P, G, CIN, C, GP, GG); S <= SUM(A, B, C); end; -------------------------------------------------- Compute propagate and generate from input bits ------------------------------------------------procedure PG(A, B: in BIT_VECTOR(3 downto 0); P, G: out BIT_VECTOR(3 downto 0)) is begin P <= A or B; G <= A and B; end; --------------------------------------------------- Compute sum from the input bits and the carries -------------------------------------------------function SUM(A, B, C: BIT_VECTOR(3 downto 0)) return BIT_VECTOR is begin return(A xor B xor C); end; ------------------------------- 4-bit carry-lookahead block -----------------------------procedure CLA( P, G: in BIT_VECTOR(3 downto 0); CIN: in BIT; C: out BIT_VECTOR(3 downto 0);
Examples A-36
signal GP, GG: out BIT) is variable TEMP_GP, TEMP_GG, LAST_C: BIT; begin TEMP_GP <= P(0); TEMP_GG <= G(0); LAST_C <= CIN; C(0) <= CIN; for I in 1 to N-1 loop TEMP_GP <= TEMP_GP and P(I); TEMP_GG <= (TEMP_GG and P(I)) or G(I); LAST_C <= (LAST_C and P(I-1)) or G(I-1); C(I) <= LAST_C; end loop; GP <= TEMP_GP; GG <= TEMP_GG; end; end LOCAL; use WORK.LOCAL.ALL; ---------------------------------- A 32-bit carry-lookahead adder --------------------------------entity ADDER is port(A, B: in BIT_VECTOR(31 downto 0); CIN: in BIT; S: out BIT_VECTOR(31 downto 0); COUT: out BIT); end ADDER; architecture BEHAVIOR of ADDER is signal GG,GP,GC: BIT_VECTOR(7 downto 0); -- First-level generate, propagate, carry signal GGG, GGP, GGC: BIT_VECTOR(3 downto 0); -- Second-level gen, prop, carry signal GGGG, GGGP: BIT; -- Third-level gen, prop begin -- Compute Sum and 1st-level Generate and Propagate -- Use input data and the 1st-level Carries computed -- later. BITSLICE(A( 3 downto 0),B( 3 downto 0),GC(0), S( 3 downto 0),GP(0), GG(0)); BITSLICE(A( 7 downto 4),B( 7 downto 4),GC(1), S( 7 downto 4),GP(1), GG(1));
Examples A-37
BITSLICE(A(11 S(11 BITSLICE(A(15 S(15 BITSLICE(A(19 S(19 BITSLICE(A(23 S(23 BITSLICE(A(27 S(27 BITSLICE(A(31 S(31
downto downto downto downto downto downto downto downto downto downto downto downto
8),B(11 downto 8),GC(2), 8),GP(2), GG(2)); 12),B(15 downto 12),GC(3), 12),GP(3), GG(3)); 16),B(19 downto 16),GC(4), 16),GP(4), GG(4)); 20),B(23 downto 20),GC(5), 20),GP(5), GG(5)); 24),B(27 downto 24),GC(6), 24),GP(6), GG(6)); 28),B(31 downto 28),GC(7), 28),GP(7), GG(7));
-- Compute first-level Carries and second-level -- generate and propagate. -- Use first-level Generate, Propagate, and -- second-level carry. process(GP, GG, GGC) variable TEMP: BIT_VECTOR(3 downto 0); begin CLA(GP(3 downto 0), GG(3 downto 0), GGC(0), TEMP, GGP(0), GGG(0)); GC(3 downto 0) <= TEMP; end process; process(GP, GG, GGC) variable TEMP: BIT_VECTOR(3 downto 0); begin CLA(GP(7 downto 4), GG(7 downto 4), GGC(1), TEMP, GGP(1), GGG(1)); GC(7 downto 4) <= TEMP; end process; -- Compute second-level Carry and third-level -Generate and Propagate -- Use second-level Generate, Propagate and Carry-in -(CIN) process(GGP, GGG, CIN) variable TEMP: BIT_VECTOR(3 downto 0); begin CLA(GGP, GGG, CIN, TEMP, GGGP, GGGG); GGC <= TEMP; end process; -- Assign unused bits of second-level Generate and -Propagate GGP(3 downto 2) <= 11; GGG(3 downto 2) <= 00;
Examples A-38
-- Compute Carry-out (COUT) -- Use third-level Generate and Propagate and -Carry-in (CIN). COUT <= GGGG or (GGGP and CIN); end BEHAVIOR;
Implementation
In the carry-lookahead adder implementation, procedures perform the computation of the design. The procedures can also be in the form of separate entities and used by component instantiation, producing a hierarchical design. FPGA Compiler II / FPGA Express does not collapse a hierarchy of entities, but it does collapse the procedure call hierarchy into one design. The keyword signal is included before some of the interface parameter declarations. This keyword is required for the out formal parameters when the actual parameters must be signals. The output parameter C from the CLA procedure is not declared as a signal; thus, it is not allowed in a concurrent procedure call. Only signals can be used in such calls. To overcome this problem, subprocesses are used, declaring a temporary variable TEMP. TEMP receives the value of the C parameter and assigns it to the appropriate signal (a generally useful technique).
Examples A-39
Examples A-40
Input Format
When no data is being transmitted to the serial port, keep it at a value of 0. Each 8-bit value requires ten clock cycles to read it. On the eleventh clock cycle, the parallel output value can be read. In the first cycle, a 1 is placed on the serial input. This assignment indicates that an 8-bit value follows. The next eight cycles transmit each bit of the value. The most significant bit is transmitted first. The tenth cycle transmits the parity of the 8-bit value. It must be 0 if an even number of 1 values are in the 8-bit data, and 1 otherwise. If the converter detects a parity error, it sets the PARITY_ERROR output to 1 and waits until the value is reset. On the eleventh cycle, the READ_ENABLE output is set to 1 and the 8-bit value can be read from the PARALLEL_OUT port. If the SERIAL_IN port has a 1 on the eleventh cycle, another 8-bit value is read immediately; otherwise, the converter waits until SERIAL_IN goes to 1. Figure A-16 shows the timing of this design.
Examples A-41
CLO CK
SERIAL_IN
RESET
PARALLEL_O UT
XX
2D
XX
READ_ENABLE
PARITY_ERRO R
Implementation Details
The implementation of the converter is as a four-state finite-state machine with synchronous reset. When a reset is detected, the converter enters a WAIT_FOR_START state. The description of each state follows WAIT_FOR_START Stay in this state until a 1 is detected on the serial input. When a 1 is detected, clear the PARALLEL_OUT registers and go to the READ_BITS state. READ_BITS If the value of the current_bit_position counter is 8, all 8 bits have been read. Check the computed parity with the transmitted parity. If it is correct, go to the ALLOW_READ state; otherwise, go to the PARITY_ERROR state.
Examples A-42
If all 8 bits have not yet been read, set the appropriate bit in the PARALLEL_OUT buffer to the SERIAL_IN value, compute the parity of the bits read so far, and increment the current_bit_position. ALLOW_READ This is the state where the outside world reads the PARALLEL_OUT value. When that value is read, the design returns to the WAIT_FOR_START state. PARITY_ERROR_DETECTED In this state, the PARITY_ERROR output is set to 1 and nothing else is done. This design has four values stored in registers: CURRENT_STATE Remembers the state as of the last clock edge. CURRENT_BIT_POSITION Remembers how many bits have been read so far. CURRENT_PARITY Keeps a running XOR of the bits read. CURRENT_PARALLEL_OUT Stores each parallel bit as it is found. The design has two processes: the combinational NEXT_ST containing the combinational logic and the sequential SYNCH that is clocked.
Examples A-43
NEXT_ST performs all the computations and state assignments. The NEXT_ST process starts by assigning default values to all the signals it drives. This assignment guarantees that all signals are driven under all conditions. Next, the RESET input is processed. If RESET is not active, a case statement determines the current state and its computations. State transitions are performed by assigning the next states value you want to the NEXT_STATE signal. The serial-to-parallel conversion itself is performed by these two statements in the NEXT_ST process:
NEXT_PARALLEL_OUT(CURRENT_BIT_POSITION) <= SERIAL_IN; NEXT_BIT_POSITION <= CURRENT_BIT_POSITION + 1;
The first statement assigns the current serial input bit to a particular bit of the parallel output. The second statement increments the next bit position to be assigned. SYNCH registers and updates the stored values previously described. Each registered signal has two parts, NEXT_... and CURRENT_... : NEXT_... Signals hold values computed by the NEXT_ST process. CURRENT_... Signals hold the values driven by the SYNCH process. The CURRENT_... signals hold the values of the NEXT_... signals as of the last clock edge. Example A-13 shows a VHDL description of the converter.
Examples A-44
entity SER_PAR is -- Declare the interface port(SERIAL_IN, CLOCK, RESET: in BIT; PARALLEL_OUT: out PARALLEL_TYPE; PARITY_ERROR, READ_ENABLE: out BIT); end SER_PAR; architecture BEHAVIOR of SER_PAR is -- Signals for stored values signal CURRENT_STATE, NEXT_STATE: STATE_TYPE; signal CURRENT_PARITY, NEXT_PARITY: BIT; signal CURRENT_BIT_POSITION, NEXT_BIT_POSITION: INTEGER range PARALLEL_BIT_COUNT downto 0; signal CURRENT_PARALLEL_OUT, NEXT_PARALLEL_OUT: PARALLEL_TYPE; begin NEXT_ST: process(SERIAL_IN, CURRENT_STATE, RESET, CURRENT_BIT_POSITION, CURRENT_PARITY, CURRENT_PARALLEL_OUT) -- This process computes all outputs, the next -state, and the next value of all stored values begin PARITY_ERROR <= 0; -- Default values for all READ_ENABLE <= 0; -- outputs and stored values NEXT_STATE <= CURRENT_STATE; NEXT_BIT_POSITION <= 0; NEXT_PARITY <= 0; NEXT_PARALLEL_OUT <= CURRENT_PARALLEL_OUT; if (RESET = 1) then -- Synchronous reset NEXT_STATE <= WAIT_FOR_START; else
Examples A-45
case CURRENT_STATE is -- State processing when WAIT_FOR_START => if (SERIAL_IN = 1) then NEXT_STATE <= READ_BITS; NEXT_PARALLEL_OUT <= PARALLEL_TYPE(others=>0); end if; when READ_BITS => if (CURRENT_BIT_POSITION = PARALLEL_BIT_COUNT) then if (CURRENT_PARITY = SERIAL_IN) then NEXT_STATE <= ALLOW_READ; READ_ENABLE <= 1; else NEXT_STATE <= PARITY_ERROR_DETECTED; end if; else NEXT_PARALLEL_OUT(CURRENT_BIT_POSITION) <= SERIAL_IN; NEXT_BIT_POSITION <= CURRENT_BIT_POSITION + 1; NEXT_PARITY <= CURRENT_PARITY xor SERIAL_IN; end if; when PARITY_ERROR_DETECTED => PARITY_ERROR <= 1; when ALLOW_READ => NEXT_STATE <= WAIT_FOR_START; end case; end if; end process NEXT_ST; SYNCH: process -- This process remembers the stored values -across clock cycles begin wait until CLOCKevent and CLOCK = 1; CURRENT_STATE <= NEXT_STATE; CURRENT_BIT_POSITION <= NEXT_BIT_POSITION; CURRENT_PARITY <= NEXT_PARITY; CURRENT_PARALLEL_OUT <= NEXT_PARALLEL_OUT; end process SYNCH; PARALLEL_OUT <= CURRENT_PARALLEL_OUT; end BEHAVIOR;
Examples A-46
0), the signal NEXT_HIGH_BIT is set to 1 and the conversion is complete. Example A-14 shows the listing of the second implementation. The differences are highlighted in bold. The differences relate to the removal of the ..._BIT_POSITION signals, the addition of ..._HIGH_BIT signals, and the change in the way NEXT_PARALLEL_OUT is computed.
entity SER_PAR is -- Declare the interface port(SERIAL_IN, CLOCK, RESET: in BIT; PARALLEL_OUT: out PARALLEL_TYPE; PARITY_ERROR, READ_ENABLE: out BIT); end SER_PAR; architecture BEHAVIOR of SER_PAR is -- Signals for stored values signal CURRENT_STATE, NEXT_STATE: STATE_TYPE; signal CURRENT_PARITY, NEXT_PARITY: BIT; signal CURRENT_HIGH_BIT, NEXT_HIGH_BIT: BIT; signal CURRENT_PARALLEL_OUT, NEXT_PARALLEL_OUT: PARALLEL_TYPE; begin NEXT_ST: process(SERIAL_IN, CURRENT_STATE, RESET, CURRENT_HIGH_BIT, CURRENT_PARITY, CURRENT_PARALLEL_OUT) -- This process computes all outputs, the next
Examples A-48
-state, and the next value of all stored values begin PARITY_ERROR <= 0; -- Default values for all READ_ENABLE <= 0; -- outputs and stored values NEXT_STATE <= CURRENT_STATE; NEXT_HIGH_BIT <= 0; NEXT_PARITY <= 0; NEXT_PARALLEL_OUT <= PARALLEL_TYPE(others=>0); if(RESET = 1) then -- Synchronous reset NEXT_STATE <= WAIT_FOR_START; else case CURRENT_STATE is -- State processing when WAIT_FOR_START => if (SERIAL_IN = 1) then NEXT_STATE <= READ_BITS; NEXT_PARALLEL_OUT <= PARALLEL_TYPE(others=>0); end if; when READ_BITS => if (CURRENT_HIGH_BIT = 1) then if (CURRENT_PARITY = SERIAL_IN) then NEXT_STATE <= ALLOW_READ; READ_ENABLE <= 1; else NEXT_STATE <= PARITY_ERROR_DETECTED; end if; else NEXT_HIGH_BIT <= CURRENT_PARALLEL_OUT(0); NEXT_PARALLEL_OUT <= CURRENT_PARALLEL_OUT( 1 to PARALLEL_BIT_COUNT-1) & SERIAL_IN; NEXT_PARITY <= CURRENT_PARITY xor SERIAL_IN; end if; when PARITY_ERROR_DETECTED => PARITY_ERROR <= 1; when ALLOW_READ => NEXT_STATE <= WAIT_FOR_START; end case; end if; end process NEXT_ST; SYNCH: process -- This process remembers the stored values -across clock cycles begin wait until CLOCKevent and CLOCK = 1;
Examples A-49
CURRENT_STATE <= NEXT_STATE; CURRENT_HIGH_BIT <= NEXT_HIGH_BIT; CURRENT_PARITY <= NEXT_PARITY; CURRENT_PARALLEL_OUT <= NEXT_PARALLEL_OUT; end process SYNCH; PARALLEL_OUT <= CURRENT_PARALLEL_OUT; end BEHAVIOR;
Note: The synthesized schematic for the shifter implementation is much simpler than that of the previous count implementation in Example A-13. It is simpler because the shifter algorithm is inherently easier to implement.
Examples A-50
With the count algorithm, each of the flip-flops holding the PARALLEL_OUT bits needed logic that decoded the value stored in the BIT_POSITION flip-flops to see when to route in the value of SERIAL_IN. Also, the BIT_POSITION flip-flops needed an incrementer to compute their next value. In contrast, the shifter algorithm requires neither an incrementer nor flip-flops to hold BIT_POSITION. Additionally, the logic in front of most PARALLEL_OUT bits needs to read only the value of the previous flip-flop or 0. The value depends on whether bits are currently being read. In the shifter algorithm, the SERIAL_IN port needs to be connected only to the least significant bit (number 7) of the PARALLEL_OUT flip-flops. These two implementations illustrate the importance of designing efficient algorithms. Both work properly, but the shifter algorithm produces a faster, more area-efficient design.
Examples A-51
In the PLA function, the output vector is first initialized to be all zeros. When the input vector matches an input plane in a row of the PLA table, the ones in the output plane are assigned to the corresponding bits in the output vector. A match is determined as follows: If a zero or one is in the input plane, the input vector must have the same value in the same position. If a minus is in the input plane, it matches any input vector value at that position.
The generic PLA table types and the PLA function are defined in a package named LOCAL. An entity PLA_VHDL that uses LOCAL needs only to specify its PLA table as a constant, then call the PLA function. The PLA function does not explicitly depend on the size of the PLA. To change the size of the PLA, change the initialization of the TABLE constant and the initialization of the constants INPUT_COUNT, OUTPUT_COUNT, and ROW_COUNT. In Example A-15, these constants are initialized to a PLA equivalent to the ROM shown previously (Example A-3). Accordingly, the synthesized schematic is the same as that of the ROM, with one difference: in Example A-3, the DATA output port range is 1 to 5; in Example A-15, the OUT_VECTOR output port range is 4 down to 0.
Examples A-52
Examples A-53
-- Check for match in input plane for J in ROW_SIZE - 1 downto OUTPUT_COUNT loop if(ROW(J) = PLA_ELEMENT( 1 )) then MATCH <= MATCH and (IN_VECTOR(IN_POS) = BIT( 1 )); elsif(ROW(J) = PLA_ELEMENT( 0 )) then MATCH <= MATCH and (IN_VECTOR(IN_POS) = BIT( 0 )); else null; -- Must be minus (dont care) end if; IN_POS <= IN_POS - 1; end loop; -- Set output plane if(MATCH) then for J in RESULTrange loop if(ROW(J) = PLA_ELEMENT( 1 )) then RESULT(J) <= BIT( 1 ); end if; end loop; end if; end loop; return(RESULT); end; end LOCAL; use WORK.LOCAL.all; entity PLA_VHDL is port(IN_VECTOR: BIT_VECTOR(2 downto 0); OUT_VECTOR: out BIT_VECTOR(4 downto 0)); end PLA_VHDL; architecture BEHAVIOR of PLA_VHDL is constant TABLE: PLA_TABLE := PLA_TABLE( PLA_ROW(--- 10000), PLA_ROW(-1- 01000), PLA_ROW(0-0 00101), PLA_ROW(-1- 00101), PLA_ROW(1-1 00101), PLA_ROW(-1- 00010));
Examples A-54
Examples A-55
Examples A-56
B
Synopsys Packages
The following Synopsys packages are included with this release: std_logic_1164 Package Defines a standard for designers to use in describing the interconnection data types used in VHDL modeling. std_logic_arith Package Provides a set of arithmetic, conversion, and comparison functions for SIGNED, UNSIGNED, INTEGER, STD_ULOGIC, STD_LOGIC, and STD_LOGIC_VECTOR types. numeric_std Package The numeric_std package is an alternative to the std_logic_arith package. It is the IEEE standard 1076.3-1997, and documentation about it is available from IEEE. For more information, see numeric_std Package on page B-20.
std_logic_misc Package Defines supplemental types, subtypes, constants, and functions for the std_logic_1164 package.
ATTRIBUTES Package Declares synthesis attributes and the resource sharing subtype and its attributes.
std_logic_1164 Package
The std_logic_1164 package defines the IEEE standard for designers to use in describing the interconnection data types used in VHDL modeling. The logic system defined in this package might be insufficient for modeling switched transistors, because such a requirement is out of the scope of this package. Furthermore, mathematics, primitives, and timing standards are considered orthogonal issues as they relate to this package and are, therefore, beyond its scope. The std_logic_1164 package file has been updated with Synopsys synthesis directives. To use this package in a VHDL source file, include the following lines at the beginning of the source file:
library IEEE; use IEEE.std_logic_1164.all;
When you analyze your VHDL source, FPGA Compiler II / FPGA Express automatically finds the IEEE library and the std_logic_1164 package. However, you must analyze those use packages that are not in the IEEE and Synopsys libraries before processing a source file that uses them.
std_logic_arith Package
Functions defined in the std_logic_arith package provide conversion to and from the predefined VHDL data type INTEGER, arithmetic, comparison, and BOOLEAN operations. This package lets you perform arithmetic operations and numeric comparisons on array data types. The package defines some arithmetic operators (+, -, *, ABS) and the relational operators (<, >, <=, >=, =, /=). (IEEE VHDL does not define arithmetic operators for arrays and defines the comparison operators in a manner inconsistent with an arithmetic interpretation of array values.) The package also defines two major data types of its own: UNSIGNED and SIGNED (see Data Types on page B-6 for details). The std_logic_arith package is legal VHDL; you can use it for both synthesis and simulation. You can configure the std_logic_arith package to work on any array of single-bit types. You encode single-bit types in 1 bit with the ENUM_ENCODING attribute.
You can make the vector type (for example, std_logic_vector) synonymous with either SIGNED or UNSIGNED. This way, if you plan to use mostly UNSIGNED numbers, you do not need to convert your vector type to call UNSIGNED functions. The disadvantage of making your vector type synonymous with either UNSIGNED or SIGNED is that it causes redefinition of the standard VHDL comparison functions (=, /=, <, >, <=, >=). Table B-1 shows that the standard comparison functions for BIT_VECTOR do not match the SIGNED and UNSIGNED functions.
Note the use of the CONV_INTEGER function in Example B-1. FPGA Compiler II / FPGA Express performs almost all synthesis directly from the VHDL descriptions. However, several functions are hard-wired for efficiency. They can be identified by the following comment in their declarations:
-- pragma built_in
This statement marks functions as special, causing the body of the function to be ignored. Modifying the body does not change the synthesized logic unless you remove the built_in comment. If you want new functionality, write it by using the built_in functions; this is more efficient than removing the built_in function and modifying the body of the function.
Data Types
The std_logic_arith package defines two data types: UNSIGNED and SIGNED.
type UNSIGNED is array (natural range <>) of std_logic; type SIGNED is array (natural range <>) of std_logic;
These data types are similar to the predefined VHDL type BIT_VECTOR, but the std_logic_arith package defines the interpretation of variables and signals of these types as numeric values.
UNSIGNED
The UNSIGNED data type represents an unsigned numeric value. FPGA Compiler II / FPGA Express interprets the number as a binary representation, with the farthest-left bit being most significant. For example, the decimal number 8 can be represented as
UNSIGNED(1000)
When you declare variables or signals of type UNSIGNED, a larger vector holds a larger number. A 4-bit variable holds values up to decimal 15, an 8-bit variable holds values up to 255, and so on. By definition, negative numbers cannot be represented in an UNSIGNED variable. Zero is the smallest value that can be represented. Example B-2 illustrates some UNSIGNED declarations. The most significant bit is the farthest-left array bound, rather than the high or low range value.
Example B-2
UNSIGNED Declarations
variable VAR: UNSIGNED (1 to 10); -- 11-bit number -- VAR(VARleft) = VAR(1) is the most significant bit signal SIG: UNSIGNED (5 downto 0); -- 6-bit number -- SIG(SIGleft) = SIG(5) is the most significant bit
SIGNED
The SIGNED data type represents a signed numeric value. FPGA Compiler II / FPGA Express interprets the number as a 2scomplement binary representation, with the farthest-left bit as the sign bit. For example, you can represent decimal 5 and 5 as
SIGNED(0101) SIGNED(1011) -- represents +5 -- represents -5
When you declare SIGNED variables or signals, a larger vector holds a larger number. A 4-bit variable holds values from 8 to 7; an 8-bit variable holds values from 128 to 127. A SIGNED value cannot hold as large a value as an UNSIGNED value with the same bit-width.
Example B-3 shows some SIGNED declarations. The sign bit is the farthest-left bit, rather than the highest or lowest.
Conversion Functions
The std_logic_arith package provides three sets of functions to convert values between its UNSIGNED and SIGNED types and the predefined type INTEGER. This package also provides the std_logic_vector. Example B-4 shows the declarations of these conversion functions, with BIT and BIT_VECTOR types.
function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER) function CONV_SIGNED(ARG: UNSIGNED; SIZE: INTEGER) function CONV_SIGNED(ARG: SIGNED; SIZE: INTEGER) function CONV_SIGNED(ARG: STD_ULOGIC; SIZE: INTEGER)
function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR; function CONV_STD_LOGIC_VECTOR(ARG: UNSIGNED; SIZE: INTEGER) return STD_LOGIC_VECTOR; function CONV_STD_LOGIC_VECTOR(ARG: SIGNED; SIZE: INTEGER) return STD_LOGIC_VECTOR; function CONV_STD_LOGIC_VECTOR(ARG: STD_ULOGIC; SIZE: INTEGER) return STD_LOGIC_VECTOR;
There are four versions of each conversion function. The VHDL operator overloading mechanism determines the correct version from the function calls argument types. The CONV_INTEGER functions convert an argument of type INTEGER, UNSIGNED, SIGNED, or STD_ULOGIC to an INTEGER return value. The CONV_UNSIGNED and CONV_SIGNED functions convert an argument of type INTEGER, UNSIGNED, SIGNED, or STD_ULOGIC to an UNSIGNED or SIGNED return value whose bit width is SIZE. The CONV_INTEGER functions have a limitation on the size of operands. VHDL defines INTEGER values as being between 2147483647 and 2147483647. This range corresponds to a 31-bit UNSIGNED value or a 32-bit SIGNED value. You cannot convert an argument outside this range to an INTEGER.
The CONV_UNSIGNED and CONV_SIGNED functions each require two operands. The first operand is the value converted. The second operand is an INTEGER that specifies the expected size of the converted result. For example, the following function call returns a 10-bit UNSIGNED value representing the value in sig.
ten_unsigned_bits := CONV_UNSIGNED(sig, 10);
If the value passed to CONV_UNSIGNED or CONV_SIGNED is smaller than the expected bit-width (such as representing the value 2 in a 24-bit number), the value is bit-extended appropriately. FPGA Compiler II / FPGA Express places zeros in the more significant (left) bits for an UNSIGNED return value, and it uses sign extension for a SIGNED return value. You can use the conversion functions to extend a numbers bit-width even if conversion is not required. For example,
CONV_SIGNED(SIGNED(110), 8) 11111110
An UNSIGNED or SIGNED return value is truncated when its bitwidth is too small to hold the ARG value. For example,
CONV_SIGNED(UNSIGNED(1101010), 3) 010
Arithmetic Functions
The std_logic_arith package provides arithmetic functions for use with combinations of the Synopsys UNSIGNED and SIGNED data types and the predefined types STD_ULOGIC and INTEGER. These functions produce adders and subtracters.
There are two sets of arithmetic functions: binary functions having two arguments, such as A+B or A*B, and unary functions having one argument, such as A. Example B-5 and Example B-6 show the declarations for these functions.
function function function function function function function function function function function function function function function
-(L: -(L: -(L: -(L: -(L: -(L: -(L: -(L: -(L: -(L: -(L: *(L: *(L: *(L: *(L:
SIGNED; R: SIGNED) return STD_LOGIC_VECTOR; UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR; SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR; UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR; INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR; SIGNED; R: INTEGER) return STD_LOGIC_VECTOR; INTEGER; R: SIGNED) return STD_LOGIC_VECTOR; UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR; STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR; SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR; STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR; UNSIGNED; SIGNED; SIGNED; UNSIGNED; R: R: R: R: UNSIGNED) SIGNED) UNSIGNED) SIGNED) return return return return UNSIGNED; SIGNED; SIGNED; SIGNED;
The unary arithmetic functions in Example B-5 and Example B-6 determine the width of their return values, as follows: 1. When only one UNSIGNED or SIGNED argument is present, the width of the return value is the same as that arguments. 2. When both arguments are either UNSIGNED or SIGNED, the width of the return value is the larger of the two argument widths. An exception is that when an UNSIGNED number is added to or subtracted from a SIGNED number that is the same size or smaller, the return value is a SIGNED number 1 bit wider than the UNSIGNED argument. This size guarantees that the return value is large enough to hold any (positive) value of the UNSIGNED argument. The number of bits returned by + and is illustrated in Table B-2.
UNSIGNED (3 downto 0); UNSIGNED (7 downto 0); SIGNED (3 downto 0); SIGNED (7 downto 0);
In some circumstances, you might need to obtain a carry-out bit from the + or operation. To do this, extend the larger operand by 1 bit. The high bit of the return value is the carry, as shown in Example B-7.
Comparison Functions
The std_logic_arith package provides functions for comparing UNSIGNED and SIGNED data types with each other and with the predefined type INTEGER. FPGA Compiler II / FPGA Express compares the numeric values of the arguments, returning a BOOLEAN value. For example, the following evaluates true:
The std_logic_arith comparison functions are similar to the built-in VHDL comparison functions. The only difference is that the std_logic_arith functions accommodate signed numbers and varying bit-widths. The predefined VHDL comparison functions perform bitwise comparisons and do not have the correct semantics for comparing numeric values (see Relational Operators on page 4-5). These functions produce comparators. The function declarations are listed in two groups: ordering functions (<, <=, >, >=), shown in Example B-8, and equality functions (=, /=), shown in Example B-9.
Shift Functions
The std_logic_arith package provides functions for shifting the bits in SIGNED and UNSIGNED numbers. These functions produce shifters. Example B-10 shows the shift function declarations. For a list of shift and rotate operators, see Operators on page C-9.
The SHL function shifts the bits of its argument ARG left by COUNT bits. SHR shifts the bits of its argument ARG right by COUNT bits. The SHL functions work the same for both UNSIGNED and SIGNED values of ARG, shifting in zero bits as necessary. The SHR functions treat UNSIGNED and SIGNED values differently. If ARG is an UNSIGNED number, vacated bits are filled with zeros; if ARG is a SIGNED number, the vacated bits are copied from the ARG sign bit. Example B-11 shows some shift function calls and their return values.
Multiplication Using Shifts You can use shift operations for simple multiplication and division of UNSIGNED numbers if you are multiplying or dividing by a power of 2. For example, to divide the following UNSIGNED variable U by 4, use this syntax:
variable U: UNSIGNED (7 downto 0) := 11010101; variable quarter_U: UNSIGNED (5 downto 0); quarter_U <= SHR(U, 01);
ENUM_ENCODING Attribute
Place the synthesis attribute ENUM_ENCODING on your primary logic type (see Enumeration Encoding on page 3-4). This attribute allows FPGA Compiler II / FPGA Express to interpret your logic correctly.
pragma built_in
Label your primary logic functions with built_in pragmas. Pragmas allow FPGA Compiler II / FPGA Express to interpret your logic functions easily. When you use a built_in pragma, FPGA Compiler II / FPGA Express parses but ignores the body of the function. Instead, FPGA Compiler II / FPGA Express directly substitutes the appropriate logic for the function. You need not use built_in pragmas, but they can result in runtimes that are 10 times as fast. Use a built_in pragma by placing a comment in the declaration part of a function. FPGA Compiler II / FPGA Express interprets a comment as a directive if the first word of the comment is pragma. Example B-12 shows the use of a built_in pragma.
You can use these functions on single-bit arguments or equal-length arrays of single bits. Example B-13 shows a function that takes the logical AND of two equal-size arrays.
You can use these functions on single-bit arguments or equal-length arrays of single bits. Example B-14 shows a function that takes the logical NOT of an array.
Type Conversion
The built-in function SYN_FEED_THRU performs fast type conversion between unrelated types. The synthesized logic from SYN_FEED_THRU wires the single input of a function to the return value. This connection can save CPU time required to process a complicated conversion function, as shown in Example B-15.
Synopsys Packages B-19
numeric_std Package
FPGA Compiler II / FPGA Express supports nearly all of numeric_std, the IEEE Standard VHDL Synthesis Package, which defines numeric types and arithmetic functions.
Caution! The numeric_std package and the std_logic_arith package have overlapping operations. Use of these two packages simultaneously during analysis could cause type mismatches.
Synopsys packages are pre-analyzed and do not require further analyzing. To list the packages currently in memory, use the following command:
report_design_lib
Data Types
The numeric_std package defines the following two data types in the same way that the std_logic_arith package does: USIGNED
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
Conversion Functions
The numeric_std package provides functions to convert values between its USIGNED and SIGNED types. Example B-16 shows the declarations of these conversion functions.
TO_INTEGER, TO_SIGNED, and TO_UNSIGNED are similar to CONV_INTEGER, CONV_SIGNED, and CONV_UNSIGNED in std_logic_arith (see Conversion Functions on page B-8).
Resize Function
The resize function numeric_std supports is shown in the declarations in Example B-17.
Arithmetic Functions
The numeric_std package provides arithmetic functions for use with combinations of Synopsys UNSIGNED and SIGNED data types and the predefined types STD_ULOGIC and INTEGER. These functions produce adders and subtracters. There are two sets of arithmetic functions, which the numeric_std package defines in the same way that the std_logic_arith package does (see Arithmetic Functions on page B-10 for more information): Binary functions having two arguments, such as A+B A*B Example B-18 shows the declarations for these functions. Unary functions having one argument, such as A abs A Example B-19 on page B-24 shows the declarations for these functions.
function function function function function function function function function function function function
"-" "-" "-" "-" "-" "-" "*" "*" "*" "*" "*" "*"
(L, (L, (L: (L: (L: (L: (L, (L, (L: (L: (L: (L:
R: UNSIGNED) return UNSIGNED; R: SIGNED) return SIGNED; UNSIGNED;R: NATURAL) return UNSIGNED; NATURAL; R: UNSIGNED) return UNSIGNED; SIGNED; R: INTEGER) return SIGNED; INTEGER; R: SIGNED) return SIGNED; R: UNSIGNED) return UNSIGNED; R: SIGNED) return SIGNED; UNSIGNED; R: NATURAL) return UNSIGNED; NATURAL; R: UNSIGNED) return UNSIGNED; SIGNED; R: INTEGER) return SIGNED; INTEGER; R: SIGNED) return SIGNED;
Comparison Functions
The numeric_std package provides functions to compare UNSIGNED and SIGNED data types to each other and to the predefined type INTEGER. FPGA Compiler II / FPGA Express compares the numeric values of the arguments and returns a BOOLEAN value. These functions produce comparators. The function declarations are listed in two groups: Ordering functions ("<", "<=", ">", ">="), shown in Example B-20 Equality functions ("=", "/="), shown in Example B-21 on page B-25
function "/=" (L, R: UNSIGNED) return BOOLEAN; function "/=" (L, R: SIGNED) return BOOLEAN; function "/=" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
function "/=" (L: INTEGER; R: SIGNED) return BOOLEAN; function "/=" (L: UNSIGNED; R: NATURAL) return BOOLEAN; function "/=" (L: SIGNED; R: INTEGER) return BOOLEAN;
Shift Functions
The numeric_std package provides functions for shifting the bits in UNSIGNED and SIGNED numbers. These functions produce shifters. Example B-23 shows the shift function declarations.
The SHIFT_LEFT function shifts the bits of its argument ARG left by COUNT bits. SHIFT_RIGHT shifts the bits of its argument ARG right by COUNT bits. The SHIFT_LEFT functions work the same for both UNSIGNED and SIGNED values of ARG, shifting in zero bits as necessary. The SHIFT_RIGHT functions treat UNSIGNED and SIGNED values differently: If ARG is an UNSIGNED number, vacated bits are filled with zeros If ARG is a SIGNED number, the vacated bits are copied from the ARG sign bit
Example B-26 on page B-29 shows some shift functions calls and their return values.
Rotate Functions
ROTATE_LEFT and ROTATE_RIGHT are similar to the shift functions. Example B-24 shows rotate function declarations.
"01011000" "01011000" "01011000" "01011000" "00001101" "00001101" "00011101" "11111101" "01011011" "01011011" "01011111" "01011111" "01101101" "01101101" "01111101" "01111101"
std_logic_misc Package
The std_logic_misc package resides in the lib/packages/IEEE/src/ std_logic_misc.vhd subdirectory of the FPGA Compiler II / FPGA Express directory. It declares the primary data types the Synopsys VSS tools support. Boolean reduction functions take one argument (an array of bits) and return a single bit. For example, the AND reduction of 101 is 0, the logical AND of all three bits. Several functions in the std_logic_misc package provide Boolean reduction operations for the predefined type STD_LOGIC_VECTOR. Example B-27 shows the declarations of these functions.
These functions combine the bits of the STD_LOGIC_VECTOR, as the name of the function indicates. For example, XOR_REDUCE returns the XOR of all bits in ARG. Example B-28 shows some reduction function calls and their return values.
ATTRIBUTES Package
The ATTRIBUTES package declares all the supported synthesis (and simulation) attributes. These include: FPGA Compiler II / FPGA Express constraints and attributes State vector attributes Resource sharing attributes General attributes for interpreting VHDL (described in Chapter 3, "Data Types) Attributes for use with the Synopsys VSS tools
C
VHDL Constructs C
Many VHDL language constructs, although useful for simulation and other stages in the design process, are not relevant to synthesis. Because these constructs cannot be synthesized, FPGA Compiler II / FPGA Express does not support them. This appendix provides a list of all VHDL language constructs, with the level of support for each, followed by a list of VHDL reserved words. This appendix describes VHDL Construct Support VHDL Reserved Words
Constructs are listed in the following order: Design units Data types Declarations Specifications Names Operators Operands and expressions Sequential statements Concurrent statements Predefined language environment
Design Units
entity The entity statement part is ignored. Generics are supported, but only of type INTEGER. Default values for ports are ignored. architecture Multiple architectures are allowed. Global signal interaction between architectures is unsupported. configuration Configuration declarations and block configurations are supported, but only to specify the top-level architecture for a toplevel entity. The use clauses, attribute specifications, component configurations, and nested block configurations are unsupported. package Packages are fully supported. library Libraries and separate compilation are supported. subprogram Default values for parameters are unsupported. Assigning to indexes and slices of unconstrained out parameters is unsupported, unless the actual parameter is an identifier. Subprogram recursion is unsupported if the recursion is not bounded by a static value. Resolution functions are supported for wired-logic and three-state functions only. Subprograms can be declared only in packages and in the declaration part of an architecture.
Data Types
enumeration Enumeration is fully supported. integer Infinite-precision arithmetic is unsupported. Integer types are automatically converted to bit vectors whose width is as small as possible to accommodate all possible values of the types range. The types range can be either in unsigned binary for nonnegative ranges or in 2s-complement form for ranges that include negative numbers. physical Physical type declarations are ignored. The use of physical types is ignored in delay specifications. floating Floating-point type declarations are ignored. The use of floatingpoint types is unsupported except for floating-point constants used with Synopsys-defined attributes. array Array ranges and indexes other than integers are unsupported. Multidimensional arrays are unsupported, but arrays of arrays are supported. record Record data types are fully supported. access Access type declarations are ignored, and the use of access types is unsupported.
file File type declarations are ignored, and the use of file types is unsupported. incomplete type declarations Incomplete type declarations are unsupported.
Declarations
constant Constant declarations are supported except for deferred constant declarations. signal Register and bus declarations are unsupported. Resolution functions are supported for wired and three-state functions only. Declarations other than from a globally static type are unsupported. Initial values are unsupported. variable Declarations other than from a globally static type are unsupported. Initial values are unsupported. shared variable Variable shared by different processes. Shared variables are fully supported. file File declarations are unsupported. interface Buffer and linkage are translated to out and inout, respectively.
alias Alias declarations are supported, with the following exceptions: - An alias declaration that lacks a subtype indication - A nonobject aliassuch as an alias that refers to a type. component Component declarations that list a name other than a valid entity name are unsupported. attribute Attribute declarations are fully supported, but the use of userdefined attributes is unsupported.
Specifications
attribute Others and all are unsupported in attribute specifications. Userdefined attributes can be specified, but the use of user-defined attributes is unsupported. configuration Configuration specifications are unsupported. disconnection Disconnection specifications are unsupported. Attribute declarations are fully supported, but the use of user-defined attributes is unsupported.
Names
simple Simple names are fully supported. selected Selected (qualified) names outside a use clause are unsupported. Overriding the scopes of identifiers is unsupported. operator symbol Operator symbols are fully supported. indexed Indexed names are fully supported, with one exception: Indexing an unconstrained out parameter in a procedure is unsupported. slice Slice names are fully supported, with one exception: Using a slice of an unconstrained out parameter in a procedure is unsupported unless the actual parameter is an identifier. attribute Only the following predefined attributes are supported: base, left, right, high, low, range, reverse_range, and length. The event and stable attributes are supported only as described with the wait and if statements (see wait Statements on page 5-50). Userdefined attribute names are unsupported. The use of attributes with selected names (name.nameattribute) is unsupported.
Specifics of Identifiers
The characteristics of identifiers are: They can be composed of letters, digits, and the underscore character ( _ ). Their first character cannot be a number, unless it is an extended identifier (see Example C-1). They can be of any length. They are case-insensitive. All of their characters are significant.
They start with a backslash character (\), followed by a sequence of characters, followed by another backslash (\). They are case-sensitive.
For more information about identifiers and extended identifiers, see Identifiers on page 4-23.
Operators
logical Logical operators are fully supported. relational Relational operators are fully supported. addition Concatenation and arithmetic operators are fully supported. signing Signing operators are fully supported. multiplying The * (multiply) operator is fully supported. The / (division), mod, and rem operators are supported only when both operands are constant or when the right operand is a constant power of 2.
miscellaneous The ** operator is supported only when both operands are constant or when the left operand is 2. The abs operator is fully supported. operator overloading Operator overloading is fully supported. short-circuit operation The short-circuit behavior of operators is not supported.
The rotate operators are rol Rotate left logical ror Rotate right logical Example C-2 illustrates the use of shift and rotate operators.
= = = = = =
xnor Operator
You can define the binary logical operator xnor for predefined types BIT and Boolean, as well as for any one-dimensional array type whose element type is BIT or Boolean. The operands must be the same type and length. The result also has the same type and length. The xnor operator is included in the list of VHDL reserved words in Table C-1 on page C-17.
-- c = "10110"
universal expression Floating-point expressions are unsupported, except in a Synopsys-recognized attribute definition. Infinite-precision expressions are not supported. Precision is limited to 32 bits; all intermediate results are converted to integer.
Sequential Statements
wait The wait statement is unsupported unless it is in one of the following forms:
wait until clock = VALUE; clockevent and clock = VALUE; wait until wait until not clockstable and clock = VALUE;
VALUE is 0, 1, or an enumeration literal whose encoding is 0 or 1. A wait statement in this form is interpreted to mean wait until the falling (VALUE is 0) or rising (VALUE is 1) edge of the signal named clock. You cannot use wait statements in subprograms. assert Assert statements are ignored. report Report statements are ignored. statement label Statement labels are ignored. signal Guarded signal assignment is unsupported. The transport and after signals are ignored. Multiple waveform elements in signal assignment statements are unsupported. variable Variable statements are fully supported.
VHDL Constructs C-13
procedure call Type conversion on formal parameters is unsupported. Assignment to single bits of vectored ports is unsupported. if The if statements are fully supported. case The case statements are fully supported. loop The for loops are supported, with two constraints: The loop index range must be globally static, and the loop body must not contain a wait statement. The while loops are supported, but the loop body must contain at least one wait statement. The loop statements with no iteration scheme (infinite loops) are supported, but the loop body must contain at least one wait statement. next Next statements are fully supported. exit Exit statements are fully supported. return Return statements are fully supported. null Null statements are fully supported.
Concurrent Statements
block Guards on block statements are supported. Ports and generics in block statements are unsupported. process Sensitivity lists in process statements are ignored. concurrent procedure call Concurrent procedure call statements are fully supported. concurrent assertion Concurrent assertion statements are ignored. concurrent signal assignment The guarded keyword is supported. The transport keyword is ignored. Multiple waveforms are unsupported. component instantiation Type conversion on the formal port of a connection specification is unsupported. generate The generate statements are fully supported.
now function The now function is unsupported. TEXTIO package The TEXTIO package is unsupported. predefined attributes These predefined attributes are supported: base, left, right, high, low, range, reverse_range, ascending, and length. The event and stable attributes are supported only in the if and wait statements, as described in wait Statements on page 5-50.
generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand
Glossary
anonymous type A predefined or underlying type with no name, such as universal integers. ASIC Application-specific integrated circuit. behavioral view The set of Verilog statements that describe the behavior of a design by using sequential statements. These statements are similar in expressive capability to those found in many other programming languages. See also the data flow view, sequential statement, and structural view definitions. bit-width The width of a variable, signal, or expression in bits. For example, the bit-width of the constant 5 is 3 bits. character literal Any value of type CHARACTER, in single quotation marks. computable Any expression whose (constant) value FPGA Compiler II / FPGA Express can determine during translation.
GL-1
constraints The designers specification of design performance goals. FPGA Compiler II / FPGA Express uses constraints to direct the optimization of a design to meet area and timing goals. convert To change one type to another. Only integer types and subtypes are convertible, along with same-sized arrays of convertible element types. data flow view The set of VHDL/Verilog statements that describe the behavior of a design by using concurrent statements. These descriptions are usually at the level of Boolean equations combined with other operators and function calls. See also the behavioral view and structural view definitions. design constraints See constraints. flip-flop An edge-sensitive memory device. HDL Hardware Description Language. identifier A sequence of letters, underscores, and numbers. An identifier cannot be a VHDL/Verilog reserved word, such as type or loop. An identifier must begin with a letter or an underscore. latch A level-sensitive memory device. netlist A network of connected components that together define a design.
GL-2
optimization The modification of a design in an attempt to improve some performance aspect. FPGA Compiler II / FPGA Express optimizes designs and tries to meet specified design constraints for area and speed. port A signal declared in the interface list of an entity. reduction operator An operator that takes an array of bits and produces a single-bit result, namely the result of the operator applied to each successive pair of array elements. register A memory device containing one or more flip-flops or latches used to hold a value. resource sharing The assignment of a similar VHDL/Verilog operation (for example, +) to a common netlist cell. Netlist cells are the resourcesthey are equivalent to built hardware. RTL Register transfer level, a set of structural and data flow statements. sequential statement A set of VHDL/Verilog statements that execute in sequence. signed value A value that can be positive, zero, or negative. structural view The set of VHDL/Verilog statements used to instantiate primitive and hierarchical components in a design. A VHDL/Verilog design at the structural level is also called a netlist. See also the behavioral view and data flow view definitions.
GL-3
subtype A type declared as a constrained version of another type. synthesis The creation of optimized circuits from a high-level description. When VHDL/Verilog is used, synthesis is a two-step process: translation from VHDL/Verilog to gates and optimization of those gates for a specific FPGA library. technology library A library of cells available to FPGA Compiler II / FPGA Express during the synthesis process. A technology library can contain area, timing, and functional information on each cell. translation The mapping of high-level language constructs onto a lower-level form. FPGA Compiler II / FPGA Express translates RTL VHDL/ Verilog descriptions to gates. type In VHDL/Verilog, the mechanism by which objects are restricted in the values they are assigned and the operations that can be applied to them. unsigned A value that can be only positive or zero. variable An electrical quantity that can be used to transmit information. A signal is declared with a type and receives its value from one or more drivers. Signals are created in Verilog through either wire or reg declarations. VHDL VHSIC hardware description language.
GL-4
VHSIC Very high speed integrated circuit, a high-technology program of the United States Department of Defense.
GL-5
GL-6
Index
Symbols
B-25, B-25 & (concatenation operator) 4-8 ** (exponentiation operator) 4-12 * (multiplying operator) 4-11 * function B-12, B-24 + (adding operator) 4-8 + (unary operator) 4-10 + function B-11, B-24 /= (relational operator) 4-6 /= function B-14 / (multiplying operator) 4-11 <= function B-14 < function B-14 = (relational operator) 4-6 = function B-14, B-26 >= (relational operator) 4-6 >= function B-14, B-25 > (relational operator) 4-6 > function B-14, B-25 - (adding operator) 4-8 - (unary operator) 4-10 - function B-24 function B-11
A
abs (absolute value operator) 4-12 actual parameters subprograms 2-26 adder-subtracter (example) A-17 adding operators 4-8 aggregate target syntax 5-9 aggregates C-12 aggregates (array literals) 4-18 aggregates, record 3-14 algorithms processes 2-19 alias declarations supported C-6 and (logical operator) 4-3 architecture 2-5 dataflow two-input NAND gate 2-34 defined 2-5 overriding entity port names 2-8 RTL two-input NAND gate 2-34 statement, entity 2-5 structural two-input NAND gate 2-33 arithmetic functions numeric_std
IN-1
binary B-23 unary B-23 arithmetic operators adding 4-8 multiplying 4-11 negating 4-10 arithmetic optimization considering overflow from carry bits 8-10 introduction 8-6 array attributes RANGE example 5-28 array data type attributes high 3-12 index 3-12 left 3-12 length 3-12 low 3-12 predefined 3-12 range 3-12 reverse_range 3-12 right 3-12 using 3-12 concatenating 4-9 constrained array_type_name 3-10 defining 3-10 illustration 3-10 index 3-10 syntax 3-10 definition of 3-9 index constrained 3-9 ordering 4-6 unconstrained advantages 3-11 array_type_name 3-11 defining 3-11 element_type_name 3-11 range_type_name 3-11 syntax 3-11
array literals as aggregates 4-18 as bit strings 4-28 array_type_name 3-10, 3-11 arrival time 8-8 assert statement C-13 assignment statement aggregate target 5-9 field target 5-8 indexed name target 5-4 signal syntax 5-12 simple name target 5-3 slice target 5-7 syntax 5-2 variable syntax 5-11 async_set_reset attribute 7-5 async_set_reset_local attribute 7-5 async_set_reset_local_all attribute 7-5 asynchronous designs optimization 8-37 using 8-23 asynchronous processes 6-3 attribute declarations C-6 attributes array 3-12 as operands 4-20 ENUM_ENCODING B-17 synthesis_off 7-8 synthesis_on 7-8 VHDL ENUM_ENCODING 3-5 ENUM_ENCODING values 3-7 ATTRIBUTES package B-2, B-31
B
binary arithmetic functions example B-11 numeric_std B-23
IN-2
binary bit string 4-28 bit string literals 4-28 BIT type 3-17 bit vectors as bit strings 4-28 bit width (of operands) 4-15 BIT_VECTOR type 3-17, B-4 block 2-17 block statement block_declarative_item 6-10 edge-sensitive latch 6-13 guarded 6-10 guarded blocks 6-12 level-sensitive latch 6-12 nested blocks 6-11 block statements guards C-15 block_declarative_item entity architecture 2-6 in block statement 6-10 body subprogram 2-23 Boolean reduction functions B-30 BOOLEAN type 3-17 buffer port mode 2-4, 2-24, 2-25 built_in directive logic functions B-18 type conversion B-19 using B-17 built_in pragma example of using B-17 bus resolution function 6-9 bused clock syntax 7-22
C
carry-lookahead adder (example) A-32 carry-out bit example of using B-13
case statement invalid usages 5-21 syntax 5-17 character literals 4-26 character string literals 4-28 CHARACTER type 3-17 clock, bused 7-22 combinational feedback paths 8-35 combinational logic 8-2 combinational processes 5-55, 6-5 common subexpressions sharing 8-12 comparison functions numeric_std B-24 compiler directives 5-45 component declaration generic parameter 2-11 N-bit adder 2-11 port name and order 6-23 two-input AND gate, example 2-11 implication directives 5-46 example 5-47 latches and registers 5-55 three-state driver 7-59 instantiation defined 2-17 direct 6-25 port map 6-23 search order 2-13 statement 2-13, 6-22 mapping subprogram to 5-45 component declarations C-6 component implication registers 7-1 computable operands 4-16 concatenation operator 4-9 concurrent procedure call eqivalent process 6-14
IN-3
syntax 6-14 concurrent signal assignment 6-17 conditional signal assignment 6-18 selected signal assignment 6-20 concurrent statement block 2-17 component instantiation 2-17 procedure call 2-17 signal assignment 2-18 supported C-15 conditional signal assignment equivalent process 6-19 syntax 6-18 conditionally assigned variable 7-19 conditionally specified signal 8-36 constant declaration defined 2-18 supported C-5 value 2-18 constant propagation 8-21 constants record aggregates 3-14 constrained data array 3-10 constructs, VHDL architecture 2-5 constant declaration 2-18 subtype declaration 2-32 type declaration 2-32 variable declaration 2-20, 2-31 block constant declaration 2-18 subtype declaration 2-32 type declaration 2-32 component instantiation 2-13 declaration constant 2-18 signal 2-21 variable 2-20, 2-31 entity constant declaration 2-18 defined 2-2
subtype declaration 2-32 type declaration 2-32 operator overloading 2-30 package constant declaration 2-18 subtype declaration 2-32 type declaration 2-32 process constant declaration 2-18 defined 2-19 subtype declaration 2-32 type declaration 2-32 signal bus resolution function 6-9 resolution function 2-40 subprogram constant declaration 2-18 function 2-22, 2-24 overloading 2-29 procedure 2-22, 2-23 subtype declaration 2-32 type declaration 2-32 subtype declaration 2-32 defined 2-32 variable declaration 2-20, 2-31 control unit (example) counting A-29 state machine A-24 CONV_INTEGER functions B-8 CONV_SIGNED functions B-9 CONV_UNSIGNED functions B-8 conversion functions arithmetic binary B-11 for adders and subtracters B-10 unary B-12 numeric_std TO_INTEGER B-22 TO_SIGNED B-22
IN-4
TO_UNSIGNED B-22 std_logic_arith package B-8 count zeros (example) combinational A-19 sequential A-22 COUNTER3 description structural design 2-15 critical path 8-8
D
data type abstract BOOLEAN 3-1 advantages 3-2 array constrained 3-10 syntax 3-10 array attributes high 3-12 index 3-12 left 3-12 length 3-12 low 3-12 range 3-12 reverse_range 3-12 right 3-12 BIT 3-18 BIT_VECTOR 3-19 BOOLEAN 3-18 CHARACTER 3-18 described 3-1 enumeration syntax 3-3 hardware-related BIT 3-1 integer defined 3-19 syntax 3-8 new type defined BYTE, example 3-2 predefined STANDARD package 3-1
record 3-13 subtype defined 3-3 syntax 2-32 supported C-4 SYNOPSYS std_logic_signed 3-9 std_logic_unsigned 3-9 data types numeric_std SIGNED B-22 UNSIGNED B-22 dataflow architecture NAND2 entity 2-34 declaration constant 2-18 example 2-18 incorrect use of port name example 2-9 signal example 2-21 incorrect use of port name example 2-9 logical 4-4 subprogram function syntax 2-24 procedure syntax 2-23 subtype 2-32 supported C-5 variable defined 2-20, 2-31 example 2-20, 2-31 definitions register inference 7-1 design architecture concurrent statement 2-17 block 2-17 block_declarative_item 2-6 component instantiation 2-13, 2-17 procedure call 2-17 process 2-17, 2-19 signal assignment 2-18 declaration section component 2-10
IN-5
constant 2-10 signal 2-10 subprogram 2-10 type 2-10 design units package 2-35, 2-36 subprogram 2-22 organization, illustrated 2-5 Design Compiler asynchronous designs 8-23 design style data type enumeration 3-3 integer 3-8 data types 3-2 design unit package 2-35 supported C-3 designs efficiency 8-22 structure 8-3 direct component instantiation 6-25 directives built_in identifying B-6 using B-17 component implication 5-46 map_to_entity 5-45, 6-14 resolution_method 2-41 return_port_name 5-45 synthetic 9-2 translate_off, warning 9-3 translate_on, warning 9-3 using 2-42 dont care inference example 8-29 simulation versus synthesis 8-33 using 8-32
E
edge expression 7-58
element_type_name 3-11 encoding values ENUM_ENCODING attribute 3-7 vectors ENUM_ENCODING attribute 3-6 entity architecture defined 2-2 syntax 2-5 three-bit counter 2-7 two-input NAND gate 2-34 composition 2-2 consistency component instantiation 2-14 defined 2-2 generic specification example 2-5 syntax 2-3 port specification overriding port names 2-8 port modes 2-4, 2-24, 2-25 syntax 2-4 specification NAND2 gate 2-3, 2-34 three-bit counter 2-7 ENUM_ENCODING attribute 3-5, B-17 values 3-7 vectors 3-7 enumerated types ordering 4-6 enumeration data type encoding ENUM_ENCODING attribute 3-5 ENUM_ENCODING value 3-7 example 3-5 literal value 3-4 example COLOR 3-4 encoding 3-5 MY_LOGIC 3-4 literal, overloaded 3-4
IN-6
syntax 3-3 enumeration literals 4-27 equality functions example B-14 equality operators 4-6 escaped identifier.See extended identifier examples adder-subtracter A-17 asynchronous design incorrect 8-27 carry-lookahead adder A-32 case statement enumerated type 5-18 combinational process 6-5, 6-6 component implication 5-47 control unit counting A-29 state machine A-24 count zeros combinational A-19 sequential A-22 dont care usage 8-29 enumeration encoding dont care 8-29 for ... generate 6-28 function call 5-42 if statement 5-15 integer data type definitions 3-8 Mealy finite state machine A-5 Moore finite state machine A-2 PLA A-51 ROM A-7 sequential processes 6-6 serial-to-parallel converter counting bits A-40 shifting bits A-47 simulation driver 9-3 subprograms component implication 5-47 declarations 5-36 function call 5-42
synchronous design 8-23 three-state component registered input 7-67 two-phase clocked design 7-20 wait statement 5-56 in a loop 5-52 multiple waits 5-52 waveform generator complex A-13 simple A-10 exit statement 5-33 exponentiation operator 4-12 expression tree 8-7 subexpressions in 8-9 expressions described 4-1 relational true 4-7 supported C-12 use 4-1 using parentheses in 8-9 expressions, VHDL, tick () 4-29 extended identifier C-8
F
falling_edge 7-22, 7-28 feedback paths 8-35 field target syntax 5-8 file declarations C-5 flip-flop definition 7-1 inference 7-22 for ... generate statement example 6-28 syntax 6-26 for ... loop statement and exit statement 5-33 arrays 5-28 label as identifier in 5-25, 6-27 syntax 5-23, 5-25
IN-7
formal parameters subprograms 2-26 fully specified signal 8-35 variable 8-35 function call 4-22, 5-41 declaration syntax 2-24 resolution allowed 2-41 bus 6-9 creating 2-40 directives, using 2-41 example 2-42 marking 2-41 signal 2-40 syntax, declaration 2-40 syntax, subtype 2-41 syntax, type 2-40 value 2-22 functions description 5-38 implementations mapped to component 5-47 mapped to gates 5-49 return statement 5-43
values mapping 2-14 guard on block statement C-15 guarded blocks in block statement 6-12 guarded keyword C-15
H
hdlin_pragma_keyword variable 9-2 hexadecimal bit string 4-28 high attribute 3-12 high impedance state 7-59
I
identifier C-8 extended C-9 identifiers defined 4-23 enumeration literals 4-27 if ... generate statement syntax 6-31 if statement creating registers 7-23 implying registers 7-1 incompletely specified 8-35 indexed name target 5-4 indexed names computability 4-25 using 4-24 inequality operators 4-6 inference report example 7-3 inferred registers limitations 7-57 instantiation component direct 6-25 integer data type
G
generate statements for ... generate 6-26 if ... generate 6-26 generic map component instantiation 2-13 parameter component declaration 2-11 two-input AND gate 2-11 specification entity 2-3 entity syntax 2-3
IN-8
bits, accessing std_logic_signed package 3-9 std_logic_unsigned package 3-9 defining 3-8 definitions example 3-8 encoding 3-8 INTEGER type 3-17 subrange 3-8
K
keywords C-17
L
language constructs, VHDL concurrent statements assertion C-15 block 2-17, C-15 component instantiation 2-13, 2-17, C-15 function 2-22, 2-24 generate C-15 procedure 2-22, 2-23 procedure call 2-17, C-15 process 2-17, 2-19, C-15 signal assignment 2-18, C-15 data types access C-4 array 3-10, C-4 enumeration 3-3, C-4 file C-5 floating C-4 incomplete type declarations C-5 integer 3-8, C-4 physical C-4 record C-4 subtype 2-32 dataflow entity, NAND2 2-34 declaration constant 2-18
signal 2-21 variable 2-20, 2-31 declarations alias C-6 attribute C-6 component C-6 constant C-5 file C-5 interface C-5 shared variable C-5 signal C-5 variable C-5 design units architecture 2-5, C-3 configuration 2-34, C-3 entity C-3 entity, NAND2 2-3 library C-3 package 2-35, 2-36, C-3 subprogram C-3 subprogram, overloading 2-29 expressions aggregate C-12 allocator C-12 based literal C-12 function call C-12 null literal C-12 physical literal C-12 static expression C-12 string C-12 type conversion C-12 universal expression C-13 names attribute C-7 indexed C-7 operator symbol C-7 selected C-7 simple C-7 slice C-7 operands aggregate C-12 allocator C-12
IN-9
based literal C-12 function call C-12 null literal C-12 physical literal C-12 static expression C-12 string C-12 type conversion C-12 universal expression C-13 operators addition C-9 logical C-9 miscellaneous C-10 multiplying C-9 overloading 2-30, C-10 relational C-9 short-circuit operation C-10 signing C-9 predefined language environment now function C-16 predefined attributes C-16 severity_level type C-16 TEXTIO package C-16 time type C-16 reserved words C-17 sequential statements assertion C-13 case C-14 exit C-14 if C-14 loop C-14 next C-14 null C-14 procedure call C-14 report C-13 return C-14 signal C-13 statement labels C-13 variable C-13 wait C-13 specifications attribute C-6 configuration C-6
disconnection C-6 latch definition 7-1 latch inference local variables 7-11 latches edge-sensitive not in guarded block statement 6-13 level-sensitive guarded block statement 6-12 left attribute 3-12 length attribute 3-12 literal enumeration character, defined 3-3 identifier, defined 3-3 literals as operands 4-26 bit strings 4-28 character 4-26 character string 4-28 enumeration 4-27 numeric 4-26 string 4-28 logic combinational 8-2 logical operators 4-3 loop statement 5-22 syntax 5-23 low attribute 3-12
M
map_to_entity directive 5-45, 6-14 mapping generic values example 2-14 instantiation 2-14 port connections example 2-15 expressions 2-15
IN-10
Mealy finite state machine (example) A-5 mod (multiplying operator) 4-11 Moore finite state machine (example) A-2 multiple driven signals 6-8 multiplication using shifts B-16 multiplying operators 4-11
N
names C-7 attributes 4-20 field names 4-30 qualified 4-30 record names 4-30 slice names 4-32 nand (logical operator) 4-3 NAND2 entity syntax dataflow architecture 2-34 RTL architecture 2-34 specification 2-3 structural architecture 2-33 NATURAL subtype 3-17 N-bit adder declaration example 2-11 nested blocks in block statement 6-11 netlist defined 2-13 next statement in named loops 5-32 noncomputable operands 4-16 nor (logical operator) 4-3 not (logical operator) 4-3 null range 4-33 null slice 4-33 null statement 5-58 numeric literals 4-26 numeric_std package
B-25, B-25 * function B-24 + function B-24 /= equality function B-26 = equality function B-26 >= ordering function B-25 > ordering function B-25 - function B-24 accessing B-21 arithmetic functions binary B-23 binary example B-24 unary B-23 unary example B-24 comparison functions equality B-26 ordering B-25 conversion functions TO_INTEGER B-22 TO_UNSIGNED B-22 UNSIGNED B-22 data types SIGNED B-22 UNSIGNED B-22 IEEE documentation B-1 location B-21 logical operators AND B-26 NAND B-26 NOR B-26 NOT B-26 OR B-26 XNOR B-26 XOR B-26 report_design_lib command B-21 resize function B-23 rotate functions B-28 rotate operators B-28 shift functions ROTATE_LEFT B-27 ROTATE_RIGHT B-27 SHIFT_LEFT B-27
IN-11
SHIFT_RIGHT B-27 shift operators B-28 unsupported components B-21 use with std_logic_arith package B-20
O
octal bit string 4-28 one_cold attribute 7-7 one_hot attribute 7-7 operands aggregates 4-18 attributes 4-20 bit width 4-15 computable 4-16 defined 4-14 field 4-30 function call 4-22, 5-41 identifiers 4-23 in expressions defined 4-1 grouping 4-5 integer predefined operators 4-8 literal 4-26 character 4-26 enumeration 4-27 numeric 4-26 string 4-28 noncomputable 4-16 qualified expressions 4-29 record 4-30 slice names 4-32 supported C-12 type conversions 4-34 operators absolute value 4-12 adding 4-8 arithmetic adding 4-8 multiplying 4-11 negation 4-10
array catenation 4-9 relational 4-6 catenation 4-9 described 4-2 equality 4-6 exponentiation 4-12 in expressions 4-1 logical 4-3 multiplying predefined 4-11 restrictions on use 4-11 ordering 4-6 and array types 4-6 and enumerated types 4-6 overloading 2-30 defined 2-30 examples 2-30 precedence 4-3 predefined 4-2 relational described 4-5 std_logic_arith package 4-7 rotate C-11 numeric_std B-28 shift C-10 numeric_std B-28 sign 4-10 supported C-9 unary 4-10 xnor C-11 optimization arithmetic expressions 8-6 NAND2 gate 2-33 or (logical operator) 4-3 ordering operators 4-6 ordering functions example B-14 others (in aggregates) 4-20 others (in case statement) 5-17 overflow characteristics
IN-12
arithmetic optimization 8-10 overloading enumeration literal 3-4 enumeration literals 4-27 operators 2-30 defined 2-30 resolving by qualification 4-30 subprograms 2-29 defined 2-29
P
package body syntax 2-39 component declaration in 2-35 constant declaration in 2-35 declaration example 2-38 syntax 2-37 defined 2-35 numeric_std IEEE documentation B-1 package_body_declarative_item 2-39 STANDARD 3-17 std_logic_arith 4-7 std_logic_signed 3-9 std_logic_unsigned 3-9 structure body 2-36 declaration 2-36 subprogram in 2-35 TEXTIO 3-16 type declaration in 2-35 use statement syntax 2-36, 2-38 package_body_declarative_item 2-39 package_declarative_item 2-37 package_name 2-37 packages Synopsys-supplied B-1 parameters, subprogram actual 2-26
formal 2-26 PLA (example) A-51 port as signal 2-21 connections, mapping example 2-15 map 2-13 mode buffer 2-4, 2-24 entity port specification 2-4, 2-24, 2-25 in 2-4, 2-24, 2-25 inout 2-4, 2-24 out 2-4, 2-24 name consistency among entities 2-9, 2-12 incorrect use 2-9 type consistency among components 2-12 POSITIVE subtype 3-17 pragma keyword comment hdlin_pragma_keyword variable 9-2 pragmas.See directives predefined attributes array 3-12 supported C-7 predefined attributes, supported C-16 predefined language environment C-16 predefined VHDL operators 4-3 procedure call (defined) 2-17 call syntax 5-39 subprogram declaration syntax 2-23 subprogram description 5-38 process as algorithm 2-19 declaration 2-19 defined 2-19 description 2-19 sequential statements in 2-19 process statement 6-2, 6-10 processes asynchronous 6-3
IN-13
combinational example 6-5 combinational logic 5-55 sensitivity lists 6-3 sequential example 6-6 sequential logic 5-55 synchronous 6-3 wait statement 5-50
Q
qualified expressions 4-29
R
range attribute 3-12 range_type_name 3-11 record aggregates 3-14 record data type 3-13 record operands 4-30 records as aggregates C-12 register definition of 7-1 inference 7-1 register inference attribute async_set_reset 7-5 async_set_reset_local 7-5 async_set_reset_local_all 7-5 one_cold 7-7 one_hot 7-7 sync_set_reset 7-6 sync_set_reset_local 7-6 sync_set_reset_local_all 7-6 D latch 7-10 definition 7-1 edge expressions 7-22 if statement 7-23 if versus wait 7-23
signal edge 7-22 SR latch 7-8 templates 7-3 wait statement 7-22 wait versus if 7-23 relational operators 4-5 rem (multiplying operator) 4-11 report statement C-13 reserved words C-17 resize function numeric_std B-23 resolution function allowed 2-41 creating 2-40 directive, using 2-41 directives resolution_method three_state 2-41 resolution_method wired_and 2-41 resolution_method wired_or 2-41 example 2-42 marking 2-41 signal 2-40 syntax declaration 2-40 subtype 2-41 type 2-40 resolution functions bus 6-9 resolution_method three_state directive 2-41 wired_and directive 2-41 wired_or directive 2-41 resolved signal creating 2-42 example 2-42 subtype declaration 2-40 syntax 2-41 using 2-42 return statement 5-43 return_port_name directive 5-45 reverse_range attribute 3-12
IN-14
right attribute 3-12 rising_edge 7-22, 7-26 ROM (example) A-7 rotate functions numeric_std B-28 rotate operators C-11 numeric_std B-28 RTL Analyzer architecture NAND2 entity 2-34
S
selected signal assignment equivalent process 6-22 syntax 6-20 sensitivity lists 6-3 sequential processes 5-55, 6-6 sequential statement if, syntax 5-15 sequential statements supported C-13 serial-to-parallel converter (example) counting bits A-40 shifting bits A-47 shared variable C-5 sharing common subexpressions automatically determined 8-12 shift functions example B-15 numeric_std B-27 shift operations example B-16 shift operators C-10 numeric_std B-28 signal as port 2-21 assignment 2-18 examples 5-11, 5-13 syntax 5-12
declaration 2-21 example 3-4 logical 4-4 in package 2-37 multiple drivers bus 6-9 resolution function 2-40 resolved 2-40 signals concurrent signal assignment 6-17 conditional signal assignment 6-18 drivers 6-8 edge detection 7-22 registering 7-54 selected signal assignment 6-20 supported C-5 three-state 6-8 SIGNED data type defined B-6, B-7 std_logic_arith package B-4 SIGNED data types numeric_std package B-22 simple name target 5-3 simulation dont care values 8-33 driver example 9-3 slice names limitations 4-33 syntax 4-32 slice target syntax 5-7 specifications C-6 STANDARD package 3-17 state machine (example) controller A-24 Mealy A-5 Moore A-2 statement assignment aggregate target, syntax 5-9 field target, syntax 5-8 indexed name target, syntax 5-4
IN-15
slice target, syntax 5-7 case enumerated type 5-18 invalid usages 5-21 syntax 5-17 concurrent block 2-17 component instantiation 2-17 procedure call 2-17 process 2-17, 2-19 signal assignment 2-18 for ... loop syntax 5-25 loop syntax 5-23 loop syntax 5-22 sequential assignment, syntax 5-2 if 5-15 while ... loop syntax 5-24 statement labels C-13 std_logic_1164 package B-2 std_logic_arith package B-2, B-3 _REDUCE functions B-30 * function B-12 + function B-11 /= function B-14 <= function B-14 < function B-14 = function B-14 >= function B-14 > function B-14 function B-11 arithmetic functions B-10 Boolean reduction functions B-30 built_in functions B-6 comparison functions B-13 CONV_INTEGER functions B-8 CONV_SIGNED functions B-9 CONV_UNSIGNED functions B-8 conversion functions B-10 data types B-6
modifying the package B-5 ordering functions B-14 shift function B-15 using the package B-4 std_logic_misc package B-30 std_logic_signed package 3-9 std_logic_unsigned package 3-9 string literals 4-28 bit 4-28 character 4-28 STRING type 3-17 structural architecture NAND2 entity 2-33 structural design component instantiation statement 2-13 description COUNTER3 2-15 subexpressions in expression tree 8-9 subprogram body calls, examples 2-26 examples 2-29 function syntax 2-28 procedure syntax 2-26 declaration examples 2-25 function syntax 2-24 overloading 2-29 procedure, syntax 2-23 syntax 2-28 overloading defined 2-29 examples 2-29 parameter 2-26 profile 2-29 sequential statement 2-22 subprograms calling 5-37 defined 5-35 defining 5-36 mapping to components
IN-16
example 5-47 matching entity 5-45 procedure versus function 5-38 subrange integer data type 3-8 subtype data type declaration 2-32 defining 3-21 SYN_FEED_THRU example of using B-20 sync_set_reset attribute 7-6 sync_set_reset_local attribute 7-6 sync_set_reset_local_all attribute 7-6 synchronous designs 8-23 example 8-23 processes 6-3 synopsys keyword comment hdlin_pragma_keyword variable 9-2 Synopsys packages B-1 std_logic_misc package B-30 Synopsys-defined package std_logic_arith 3-21 std_logic_signed integers 3-9 overload for arithmatic 3-9 std_logic_unsigned integers 3-9 overload for arithmatic 3-9 syntax array data type constrained 3-10 unconstrained 3-11 assignment statement aggregate target 5-9 field target 5-8 indexed name target 5-4 signal 5-2, 5-12 simple name target 5-3 slice target 5-7 variable 5-2, 5-11
bused clock 7-22 case statement 5-17 clock, bused 7-22 component declaration statement 2-10 instantiation statement 2-13 constant declaration 2-18 enumeration data type 3-3 for ... loop statement 5-25 generic_declaration 2-3 if statement 5-15 integer data type 3-8 loop statement 5-22, 5-23 NAND2 dataflow architecture 2-34 RTL architecture 2-34 specification 2-3 structural architecture 2-33 operator overloading 2-30 package body 2-39 resolution function declaration 2-40 subtype 2-41 type 2-40 signal declaration 2-21 subprogram overloading 2-29 subprogram declaration body, examples 2-29 body, function syntax 2-28 function 2-24 procedure 2-23 procedure body 2-27 subtype 2-32 type declaration 2-30 use statement, package 2-36 variable declaration 2-20, 2-31 while ... loop statement 5-24 synthetic comments hdlin_pragma_keyword variable 9-2
IN-17
T
target signal assignment syntax 5-3 variable assignment syntax 5-2 TEXTIO package 3-16 three-bit counter circuit description entity architecture 2-7 entity specification 2-7 three-state gate 7-65 registered enable 7-67 without registered enable 7-68 inference 7-59 registered drivers 7-65, 7-67 registered input 7-67 signals 6-8 tick () in VHDL expressions 4-29 time type C-16 TO_INTEGER function conversion numeric_std B-22 TO_SIGNED function conversion numeric_std B-22 TO_UNSIGNED function conversion numeric_std B-22 translate_off directive, warning 9-3 translate_on directive, warning 9-3 transport keyword C-15 two-input AND gate component declaration example 2-11 two-input NAND gate dataflow architecture syntax 2-34 RTL architecture syntax 2-34 specification syntax 2-3 structural architecture 2-33
two-input N-bit comparator example 2-5 two-phase design 7-20 type conversion syntax 4-34 types as aggregates C-12
U
unary arithmetic functions example B-12 numeric_std B-23 unary operators sign 4-10 unconstrained arrays example using A-17 unconstrained data array 3-9, 3-10 UNSIGNED data type defined B-6 std_logic_arith package B-4 UNSIGNED data types numeric_std package B-22 use statement 2-36
V
variable assignment examples 5-11, 5-13 syntax 5-2, 5-11 declaration 2-20, 2-31 defined 2-20, 2-31 example 3-4 initializing 2-20, 2-31 variables conditionally-assigned 7-19 hdlin_pragma_keyword 9-2 vectors encoding ENUM_ENCODING attribute 3-6
IN-18
VHDL aggregates 4-18 architectures 2-5, 6-1 array data type 3-9 BIT data type 3-18 BIT_VECTOR data type 3-19 BOOLEAN data type 3-18 case statement 5-17 CHARACTER data type 3-18 component implication 5-46 instantiation 2-13 concurrent procedure call 6-14 concurrent statement block 6-1 process 6-1, 6-2, 6-10 concurrent statements supported C-15 configuration 2-34 data type supported enumeration C-4 data type unsupported integer C-4 data type, supported enumeration 3-3 integer 3-8 data type, unsupported access (pointer) types 3-20 file (disk file) types 3-20 floating-point 3-20 physical 3-20 declarations C-5 design units C-3 directives 9-2 enumeration data type 3-3 errors in descriptions 8-38 exit statement 5-33 expressions, supported C-12 for ... loop statement 5-23, 5-25, 6-27 functions 2-22 generate statement 6-26 identifiers 4-23
integer data type 3-8, 3-19 keywords C-17 literals 4-26 names C-7 NATURAL subtype 3-19 null statement 5-58 operands categories 4-14 supported C-12 operators precedence 4-3 predefined 4-2 supported C-9 package composition 2-35 use statement syntax 2-36 port modes 2-4, 2-24, 2-25 POSITIVE subtype 3-19 predefined attributes, supported C-7 predefined data types 3-16 predefined language environment C-16 procedures 2-22 process statement 6-2, 6-10 qualified expressions 4-29 record data type 3-13 reserved words C-17 return statement 5-43 sensitivity lists 6-3 sequential statements, supported C-13 shorthand expressions 8-22 specifications C-6 STANDARD package 3-17 STRING type 3-19 subprograms 2-22, 5-35 subtype data type 3-3, 3-21 TEXTIO package 3-16 three-state components 7-59 type conversion 4-34 wait statement 5-50 VHDL Analyzer in synthesis process 8-38 VHDL assertions 7-8
IN-19
VHDL Compiler asynchronous designs 8-23 attributes supported C-7 Synopsys C-7 ATTRIBUTES package 3-5 component consistency 2-12 implication 5-46 instantiation, entities 2-14 design efficiency 8-22 design structure 8-3 directives 9-2 dont care information 8-29 entities consistency 2-12 enumeration encoding 3-5 integer encoding 3-8 operators supported C-9 port names consistency 2-12 sensitivity lists 6-3
source directives 9-1, 9-2 syntax checking 8-38 wait statement limitations 5-54 usages 5-50
W
wait statement 5-50 creating registers 7-22 example 5-56 multiple waits 5-52 while loop 5-52 waveform generator (example) complex A-13 simple A-10 while ... loop statement syntax 5-24
X
xnor (logical operator) 4-3 xnor operator C-11 xor (logical operator) 4-3
IN-20