You are on page 1of 359

Precision Synthesis Style Guide

Includes Precision RTL Synthesis, Precision RTL Plus & Precision Hi-Rel Release 2011a Update2 November 2011

1995-2011 Mentor Graphics Corporation All rights reserved.


This document contains information that is proprietary to Mentor Graphics Corporation. The original recipient of this document may duplicate this document in whole or in part for internal business purposes only, provided that this entire notice appears in all copies. In duplicating any part of this document, the recipient agrees to make every reasonable effort to prevent the unauthorized use and distribution of the proprietary information.

This document is for information and instruction purposes. Mentor Graphics reserves the right to make changes in specifications and other information contained in this publication without prior notice, and the reader should, in all cases, consult Mentor Graphics to determine whether any changes have been made. The terms and conditions governing the sale and licensing of Mentor Graphics products are set forth in written agreements between Mentor Graphics and its customers. No representation or other affirmation of fact contained in this publication shall be deemed to be a warranty or give rise to any liability of Mentor Graphics whatsoever. MENTOR GRAPHICS MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS MATERIAL INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. MENTOR GRAPHICS SHALL NOT BE LIABLE FOR ANY INCIDENTAL, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING BUT NOT LIMITED TO LOST PROFITS) ARISING OUT OF OR RELATED TO THIS PUBLICATION OR THE INFORMATION CONTAINED IN IT, EVEN IF MENTOR GRAPHICS CORPORATION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. RESTRICTED RIGHTS LEGEND 03/97 U.S. Government Restricted Rights. The SOFTWARE and documentation have been developed entirely at private expense and are commercial computer software provided with restricted rights. Use, duplication or disclosure by the U.S. Government or a U.S. Government subcontractor is subject to the restrictions set forth in the license agreement provided with the software pursuant to DFARS 227.72023(a) or as set forth in subparagraph (c)(1) and (2) of the Commercial Computer Software - Restricted Rights clause at FAR 52.227-19, as applicable. Contractor/manufacturer is: Mentor Graphics Corporation 8005 S.W. Boeckman Road, Wilsonville, Oregon 97070-7777. Telephone: 503.685.7000 Toll-Free Telephone: 800.592.2210 Website: www.mentor.com SupportNet: supportnet.mentor.com/ Send Feedback on Documentation: supportnet.mentor.com/user/feedback_form.cfm

TRADEMARKS: The trademarks, logos and service marks ("Marks") used herein are the property of Mentor Graphics Corporation or other third parties. No one is permitted to use these Marks without the prior written consent of Mentor Graphics or the respective third-party owner. The use herein of a thirdparty Mark is not an attempt to indicate Mentor Graphics as a source of a product, but is intended to indicate a product from, or associated with, a particular third party. A current list of Mentor Graphics trademarks may be viewed at: www.mentor.com/terms_conditions/trademarks.cfm.

Table of Contents
Chapter 1 VHDL Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Entities and Architectures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Entity and Package Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Entity Compiled as the Design Root. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enumerated Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Integer Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Floating-point Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Physical Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Syntax and Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Array Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Record Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Type Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IEEE 1076 Predefined Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IEEE 1164 Predefined Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Signals. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Constants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Loop Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conditional Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Selection Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Loop Statements and Generate Statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Assignment Statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IEEE 1076 Predefined Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IEEE 1164 Predefined Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VHDL Predefined Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mentor Graphics Predefined Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . User-Defined Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Attributes in the Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 16 17 17 17 19 21 22 23 23 25 26 26 26 29 30 31 32 32 33 33 34 34 34 35 35 35 36 36 37 39 41 41 43 44 44 45 45 45 46 47

Precision Synthesis Style Guide, 2011a Update2 November 2011

Table of Contents

Functions and Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resolution Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Syntax and Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synthesis Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Component Instantiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Binding a Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Option 1 - Using a Default Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Option 2 - Using a Configuration Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Option 3 - Matching a Component Name to a Library Cell . . . . . . . . . . . . . . . . . . . . . . . . Option 4 - Creating a Black Box by Omitting the Entity . . . . . . . . . . . . . . . . . . . . . . . . . . Finding Definitions of Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Packages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Syntax and Semantic Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synthesis Tool Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VHDL Language Restrictions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 2 VHDL 2008 Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conditional and Selected Sequential Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Simplified Case Expression Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unconstrained Element Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Context Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Extensions to Generate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fixed Point Package. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Expressions Port Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Read Out Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Simplified Sensitivity List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Block Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Matching Case Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Array-Scalar Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Logical Reduction Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Matching Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conditional Operator Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Maximum and Minimum Function Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unconstrained Record Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 3 Verilog Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . macromodule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Numbers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Net Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Register Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameter Data Type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Continuous Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Net Declaration Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

48 50 50 51 53 55 56 56 57 57 58 59 61 62 62 63 67 67 68 69 69 71 71 72 72 73 73 74 74 75 75 75 76 76 77 78 78 79 80 81 82 82 83 83

Precision Synthesis Style Guide, 2011a Update2 November 2011

Table of Contents

Continuous Assignment Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedural Assignments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Always Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Module Instantiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Technology-Specific Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameter Override During Instantiation of Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defparam Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . unconnected_drive and nounconnected_drive. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . signed and unsigned Attributes on Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . If-Else Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Case Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Case Statement and Multiplexer Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . for Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Disable Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . forever, repeat, while and Generalized Form of for Loop . . . . . . . . . . . . . . . . . . . . . . . . . Functions and Tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inout Ports in Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Access of Global Variables from Functions and Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . System Task Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . System Function Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initial Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compiler Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Verilog Issues and Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Comparing With X and Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Variable Indexing of Bit Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synthesis Directives. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . parallel_case and full_case directives. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . translate_off and translate_on directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . attribute directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Syntax and Semantic Restrictions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Verilog 2001 Support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Supported Verilog 2001 Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Detailed Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 4 SystemVerilog Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SystemVerilog Support in Precision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How Precision Reads SystemVerilog files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compilation Unit Scope Settings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Altering the Compilation Unit Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . When Option -all_file_cunit_scope=false (Default in Precision). . . . . . . . . . . . . . . . . . . . Basic Language Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

84 84 85 87 87 89 89 89 90 90 94 94 95 95 96 98 101 102 103 103 104 105 105 106 106 106 107 107 107 107 108 109 109 109 109 110 111 111 112 119 119 122 123 123 126 127

Precision Synthesis Style Guide, 2011a Update2 November 2011

Table of Contents

Literal Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Data Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operators and Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedural Statements and Control flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tasks and Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hierarchy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compiler Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unpacked Array Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Foreach Loop Support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Removing Text Substitution Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Set Membership Operator (Inside Operator) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example Designs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 5 Inferring Arithmetic and Relational Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VHDL/Verilog Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Optimization Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resource Sharing and Common Subexpression Elimination . . . . . . . . . . . . . . . . . . . . . . . Reducing Counter Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes That Affect Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arithmetic Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Up Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Up Counter with Enable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Up Counter with Enable and Load . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Up Counter with Enable, Load, and Cout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Up Counter with Asynchronous Load and Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Down Counter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bidirectional Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BCD Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adder with Carry-In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adder / Subtractor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arithmetic Logic Unit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Divide By N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Pipelined Multiplier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 6 Boolean Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VHDL/Verilog Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Optimization Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unintended Combinatorial Loops (Latches). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Variables before they are assigned. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

128 130 135 138 139 139 139 143 145 147 148 150 150 151 151 152 152 169 169 169 170 170 171 172 172 174 175 176 177 178 179 180 181 182 183 184 187 188 189 189 189 189 189 192

Precision Synthesis Style Guide, 2011a Update2 November 2011

Table of Contents

Attributes Relating to Boolean Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Boolean Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Basic Gates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tri-State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tri-State Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bi-Directional Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generic Width Decoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I/O Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Seven Segment Decoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Priority Encoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Multiplexer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parallel Mux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Serial Mux. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 7 Registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronous Sets and Resets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asynchronous Sets and Resets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Clock Enable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VHDL / Verilog Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Determining the Clock Edge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asynchronous set and reset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VHDL Wait Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Predefined Flip-flops and Latches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VHDL Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Optimization Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes That Affect Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Register Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Latch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Latch with Asynchronous Set and Reset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generic N-Bit Register with Enable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Synchronous Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Asynchronous Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Synchronous Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Asynchronous Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable and Synchronous Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable and Asynchronous Reset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable and Synchronous Set. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable and Asynchronous Set. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Synchronous Reset and Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Asynchronous Reset and Set. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable and Synchronous Reset and Set . . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable and Asynchronous Reset and Set . . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Asynchronous Reset and Synchronous Set . . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable and Asynchronous Reset and Synchronous Set . . . . . . . . . . . . .

192 193 194 195 196 197 198 199 200 201 202 203 204 205 205 205 205 206 206 206 207 207 207 207 208 209 209 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231

Precision Synthesis Style Guide, 2011a Update2 November 2011

Table of Contents

D Flip Flop with Synchronous Reset and Asynchronous Set . . . . . . . . . . . . . . . . . . . . . . D Flip Flop with Enable and Synchronous Reset and Asynchronous Set . . . . . . . . . . . . . Gated Clock Conversion-AND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Gated Clock Conversion-NAND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Gated Clock Conversion-OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Gated Clock Conversion-NOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Gated Clock Conversion-Cascaded Clocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Right Shifter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asynchronous Right Shifter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronous Right Shifter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Serial Shifter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bi-Directional Shifter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Right Logical Shifter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 8 Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Single Port RAMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dual Port RAMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resets for Memories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ROMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . General Coding Guidelines for ROM Inference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Smart ROM to RAM Inference and Mapping Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . Suggested Coding Techniques for RAM and ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Byte-Enable Memories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Supported Byte-Enable Device Families . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inferring Byte-Enabled RAM in Precision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Supported Byte-Enable RTL Coding Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VHDL/Verilog Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initializing RAM in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Optimization Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initialization Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes Relating to Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Memory Coding Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronous RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . RAM with Synchronous Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . RAM with Synchronous Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . RAM with Synchronous Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . RAM with Synchronous Input/Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asynchronous RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronous I/O RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I/O RAM with Synchronous Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I/O RAM with Synchronous Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I/O RAM with Synchronous Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I/O RAM with Synchronous Input/Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I/O Asynchronous RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dual Port RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resets for Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

232 233 234 235 236 237 238 240 241 242 243 244 245 247 247 247 247 247 248 248 248 250 256 256 256 257 263 263 264 264 264 265 267 268 269 270 271 272 273 274 275 276 277 278 279 280

Precision Synthesis Style Guide, 2011a Update2 November 2011

Table of Contents

ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Synchronous ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 Chapter 9 Finite State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Optimization Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Encoding Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Specifying the Encoding Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes Relating to Finite State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . FSM Encoding using a Verilog Pragma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Advanced FSM Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Safe Finite State Machines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How Precision Implements a Safe FSM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Leonardo/Precision Differences. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Coding Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Single Process State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Two Process State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Three Process State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Moore State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mealy State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 10 DSP Blocks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Basic Requirements for DSP Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . General Inference Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inference and Instantiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Reset Design Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vendor Specific DSP Optimizations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attributes Relating to DSP Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DSP Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MULT-ADD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MULT-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MULT-ACC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MULT-ACC-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fully Pipelined 35x18 Multiplier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Instantiating DSP Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 11 Exemplar VHDL Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Exemplar Packages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Predefined Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Predefined Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Predefined Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Predefined Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interfacing With Other VHDL Tools. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Performing Post-layout Functional Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Precision Synthesis Style Guide, 2011a Update2 November 2011

291 291 292 293 294 295 296 296 297 297 303 303 304 305 306 309 312 315 315 315 315 316 317 318 319 320 321 323 325 327 329 332 337 337 338 338 339 343 345 345
9

Table of Contents

Working with the Synopsys Package. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 Index End-User License Agreement

10

Precision Synthesis Style Guide, 2011a Update2 November 2011

List of Examples
Example 3-1. Verilog Defparm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 Example 4-1. SystemVerilog ALU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Example 4-2. SystemVerilog Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Example 4-3. SystemVerilog FSM 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 Example 4-4. SystemVerilog FSM 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Example 4-5. SystemVerilog FSM 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 Example 4-6. SystemVerilog FSM Reencoded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 Example 4-7. SystemVerilog Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 Example 6-1. VHDL Bi-Directional Bus. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 Example 6-2. Verilog Bi-Directional Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 Example 9-1. VHDL Safe Finite State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Example 9-2. Verilog Safe Finite State Machine with Default Clause . . . . . . . . . . . . . . . . . 300 Example 9-3. Verilog Safe Finite State Machine with an unreachable state and without Default Clause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 Example 9-4. VHDL Three Process FSM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 Example 9-5. Verilog Three Process FSM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 Example 9-6. VHDL Moore State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 Example 9-7. Verilog Moore State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310 Example 9-8. VHDL Mealy State Machine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 Example 9-9. Verilog Mealy State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 Example 10-1. Verilog DSP MULT-ADD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 Example 10-2. VHDL DSP MULT-ADD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 Example 10-3. Verilog DSP MULT-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Example 10-4. VHDL DSP MULT-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 Example 10-5. Verilog DSP MULT-ACC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 Example 10-6. VHDL DSP MULT-ACC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Example 10-7. Verilog DSP MULT-ACC-ADDSUB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 Example 10-8. VHDL DSP MULT-ACC-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 Example 10-9. Verilog Fully Pipelined 35x18 Multiplier . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 Example 10-10. VHDL Fully Pipelined 35x18 Multiplier . . . . . . . . . . . . . . . . . . . . . . . . . . 331 Example 10-11. Verilog DSP48 Instantiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 Example 10-12. VHDL DSP48 Instantiation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333

11

Precision Synthesis Style Guide, 2011a Update2 November 2011

List of Figures
Figure 4-1. SystemVerilog File Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 8-1. Asynchronous ROM Mapped into Block RAM . . . . . . . . . . . . . . . . . . . . . . . . . Figure 8-2. How to Set rom_block Attribute in VHDL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 8-3. How to Set rom_block Attribute in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 8-4. VHDL ROM Implemented Using CASE Statement. . . . . . . . . . . . . . . . . . . . . . Figure 8-5. VHDL ROM Implement Using Array of Constants . . . . . . . . . . . . . . . . . . . . . . Figure 8-6. VHDL Memory Initialization Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 8-7. Verilog ROM Using CASE Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 8-8. Verilog ROM Using Array of Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 8-9. Verilog ROM Initialization Using $readmemh Function . . . . . . . . . . . . . . . . . . Figure 8-10. Verilog ROM Initialization Using $readmemb Function . . . . . . . . . . . . . . . . . Figure 9-1. Setting FSM encoding Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 10-1. Adding dedicated_mult via the GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 10-2. DSP MULT-ADD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 10-3. DSP MULT-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 10-4. DSP MULT-ACC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 10-5. DSP MULT-ACC-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 10-6. 35x18 Multiplier Implemented in 18-bit Blocks. . . . . . . . . . . . . . . . . . . . . . . . Figure 10-7. Partial Products used to Build 35x18 Mult . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 249 249 250 250 251 252 253 254 255 255 295 316 321 323 325 327 329 329

Precision Synthesis Style Guide, 2011a Update2 November 2011

12

List of Tables
Table 3-1. Operators Supported by Precision RTL Synthesis . . . . . . . . . . . . . . . . . . . . . . . Table 4-1. Supported SystemVerilog Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 4-2. SystemVerilog Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 5-1. VHDL and Verilog Operator Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 5-2. Arithmetic Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 6-1. VHDL and Verilog Boolean Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 6-2. Boolean Logic Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 7-1. Register Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 8-1. Supported Byte-Enable Device Families . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 8-2. Memory Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 9-1. FSM Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 10-1. DSP Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table 11-1. Exemplar Package Attributes Recognized by the VHDL Parser . . . . . . . . . . . 91 119 152 169 172 189 193 209 256 265 303 320 338

13

Precision Synthesis Style Guide, 2011a Update2 November 2011

List of Tables

14

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 1 VHDL Language Features


VHDL is a high level description language for system and circuit design. The language supports various levels of abstraction. In contrast to regular netlist formats that supports only structural description and a boolean entry system that supports only dataflow behavior, VHDL supports a wide range of description styles. These include structural descriptions, dataflow descriptions and behavioral descriptions. The structural and dataflow descriptions show a concurrent behavior. That is, all statements are executed concurrently, and the order of the statements is not relevant. On the other hand, behavioral descriptions are executed sequentially in processes, procedures and functions in VHDL. The behavioral descriptions resemble high-level programming languages. VHDL allows a mixture of various levels of design entry abstraction. Precision RTL Synthesis Synthesizes will accept all levels of abstraction, and minimize the amount of logic needed, resulting in a final netlist description in the technology of your choice. VHDL is fully simulatable, but not fully synthesizable. There are several VHDL constructs that do not have valid representation in a digital circuit. Other constructs do, in theory, have a representation in a digital circuit, but cannot be reproduced with guaranteed accuracy. Delay time modeling in VHDL is an example. State-of-the-art synthesis algorithms can optimize Register Transfer Level (RTL) circuit descriptions and target a specific technology. Scheduling and allocation algorithms, which perform circuit optimization at a very high and abstract level, are not yet robust enough for general circuit applications. Therefore, the result of synthesizing a VHDL description depends on the style of VHDL that is used. This manual is intended to give you guidelines to achieve a circuit implementation that satisfies the timing and area constraints set for a given target circuit, while still using a high level of abstraction in the VHDL source code. This chapter provides an introduction to the basic language constructs in VHDL: defining logic blocks, structural, dataflow and behavioral descriptions, concurrent and sequential functionality, design partitioning and more. Precision RTL Synthesis synthesizes all levels of abstraction, and minimizes the amount of logic needed, resulting in a final netlist description in your technology.

Precision Synthesis Style Guide, 2011a Update2 November 2011

15

VHDL Language Features Entities and Architectures

Entities and Architectures


The basic building blocks in VHDL are Entities and Architectures. An entity describes the boundaries of the logic block. Its ports and its generics are declared here. An architecture describes the contents of the block in structural, dataflow and behavioral constructs.
entity small_block is port (a, b, c : in bit ; o1 : out bit ; o2 : out bit ) ; end small_block ; architecture rtl of small_block is signal s : bit ; begin o1 <= s or c ; s <= a and b ; o2 <= s xor c ; end rtl ;

This VHDL description shows the implementation of small_block, a block that describes some simple logic functions. The entity describes the boundary. The port list is given with a direction (in this case in or out), and a type (bit) for each port. The name of the entity is small_block. The name of the architecture is rtl which is linked to the entity with the name small_block. While multiple architectures may exist for each entity, only one architecture may be executed. By default, the last defined architecture is linked to the entity. The architecture describes the contents of the small_block. The architecture starts with a declarative region; for example, the internal signal s is declared. The architecture also has a type (bit); this is similar to the ports in the entity. A signal is another form of an object in VHDL. All objects and expressions in VHDL are strongly typed. This means that all objects are of a defined type and issues an error message if there is a type mismatch. For example, you cannot assign an integer of type signal to a bit. The architecture contents starts after the begin statement. This is called the dataflow environment. All statements in the dataflow environment are executed concurrently; the order of the statements is irrelevant. This is why it is valid to use s before s is assigned anything. Assignment of a value to a signal is done with the <= sign. In the first statement, o1 is assigned the result value of s or c. The operator or is a predefined operator. Additional details about the various dataflow statements and operators are given in the sections:
16

Configuration Processes
Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Entities and Architectures

Entity and Package Handling


Packages and entities in VHDL are stored in libraries. You can load VHDL files (with packages and entities) separately into a directory that is assigned as a resource library. An example of a predefined package is the package STANDARD (which is pre-defined for VHDL), that Precision RTL Synthesis loads from file standard.vhd in <precision install directory>/pkgs/techdata/vhdl. Precision RTL Synthesis can handle either VHDL IEEE 1076-1987 or IEEE 1076-1993 dialects of VHDL. The default is 93. To run 87-style VHDL, select the menu Tools > Set Options... > +Input > VHDL and click VHDL_87, or use the command:
setup_design -variable vhdl_87=TRUE

Note Precision RTL Synthesis supports all IEEE 1076-1993 synthesizable features.

Entity Compiled as the Design Root


When the VHDL source is read, Precision RTL Synthesis starts compiling the first file listed in the Input Files list, then compiles the second file, and so on. By default, the last entity compiled in the source files is used as the top-level entity. After the root (top) entity is found, Precision RTL Synthesis tries to find a matching architecture. By default, the it will choose the LAST architecture described in the source VHDL file that matches the top-level entity.

Configuration
In summary, a configuration declaration provides the mechanism for delayed component binding specification. The entity name identifies the root entity to be elaborated. The optional architecture name provides the name of the architecture to be elaborated. A configuration declaration can configure each component instantiation individually with a different entity or architecture. The configuration declaration can also configure some lower level component instantiation of the current component being configured. With the help of the configuration declaration, you can try out different possible bindings of the component instantiations by keeping the basic hierarchical structure of the top level design intact.

Precision Synthesis Style Guide, 2011a Update2 November 2011

17

VHDL Language Features Entities and Architectures

Note If you use con for configuration and ent for entity then the name of the hierarchy cell created is con_ent.

library ieee; use ieee.std_logic_1164.all; package global_decl is type log_arr is array(std_logic) of std_logic; constant std_to_bin : log_arr:=('X','X','0','1','X','X','0', '1','X'); function to_bin (from : std_logic) return std_logic; end; library ieee; use ieee.std_logic_1164.all; use work.global_decl.all; package body global_decl is function to_bin (from : std_logic) return std_logic is begin return std_to_bin(from); end ; end package body;

library ieee; library work; use ieee.std_logic_1164.all; use work.global_decl.all; entity en1 is port (a: in std_logic; b: out std_logic); end; architecture ar1 of en1 is begin b <= to_bin (a); end; architecture ar2 of en1 is begin b <= not (to_bin (a)); end;

18

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Entities and Architectures

library ieee; library work; use ieee.std_logic_1164.all; use work.global_decl.all; entity en2 is port (a: in std_logic; b, c: out std_logic); end; architecture arc of en2 is component en1 port (a: in std_logic; b: out std_logic); end component; begin c1: en1 port map (a => a, b => b); c2: en1 port map (a => a, b => c); end; library work; configuration binding of en2 is for arc

for end for end end end

c1: en1 use entity work.en1 (ar1); for; c2: en1 use entity work.en1 (ar2); for; for; binding ;

Processes
Processes are sections of sequentially executed statements, as opposed to the dataflow environment, where all statements are executed concurrently. In a process, the statement ordering does matter. In fact, processes resemble the sequential coding style of high level programming languages. Also, processes offer a variety of powerful statements and constructs that make them very suitable for high-level behavioral descriptions. A process can be called from the dataflow area. Each process is a sequentially executed program, but all processes run concurrently. In a sense, multiple processes resemble multiple programs that can run simultaneously. Processes communicate with each other via signals that are declared in the architecture. Also, the ports defined in the entity can be used in the processes.

Precision Synthesis Style Guide, 2011a Update2 November 2011

19

VHDL Language Features Entities and Architectures

entity experiment is port ( source : in bit_vector(3 downto 0) ; ce : in bit ; wrclk : in bit ; selector : in bit_vector(1 downto 0) ; result : out bit ); end experiment; architecture rtl of experiment is signal intreg : bit_vector(3 downto 0) ; begin -- dataflow environment writer : process -- process statement -- declarative region (empty here) begin -- sequential environment -- sequential (clocked) statements wait until wrclkevent and wrclk = 1 ; if (ce=1) then intreg <= source ; end if ; end process writer;

reader : process (intreg, selector) -- process statement -- with sensitivity list -- declarative region (empty here) begin -- sequential (not-clocked) statements case selector is when "00" => result <= intreg(0) ; when "01" => result <= intreg(1) ; when "10" => result <= intreg(2) ; when "11" => result <= intreg(3) ; end case ; end process reader; end rtl ;

This example describes a circuit that can load a source vector of 4 bits, on the edge of a write clock (wrclk), store the value internally in a register (intreg) if a chip enable (ce) is active, while it produces one bit of the register constantly (not synchronized). The bit is selected by a selector signals of two bits. The description consists of two processes, one to write the value into the internal register, and one to read from it. The two processes communicate via the register value intreg. The first process (writer) includes a wait statement. The wait statement causes the process to execute only if its condition is TRUE. In this case, the wait statement waits until a positive edge occurs on the signal wrclk (expression wrclkevent and wrclk=1). Each time the edge occurs, the statements following the wait statements are executed. In this case, the value of the input signal source is loaded into the internal signal intreg only if ce is 1. If ce is 0,

20

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Literals intreg

retains its value. In synthesis terms, this translates into a D-flipflop, clocked on wrclk, and enabled by ce.

The second process (reader) does not have a wait statement. Instead, it has a sensitivity list, with the signals intreg and selector there. This construct defines that the whole process is executed each time either intreg or selector changes. If the process is executed, the output signal result gets updated with depending on the values of intreg and selector. Note that this leads to combinational behavior, since result depends on only intreg and selector, and each time either of these signals changes, result gets updated. A process has an optional name (in this case writer and reader), a sensitivity list OR a wait statement, and a declarative region where signals, variables, functions etc. can be declared which are used only within the process. Each statement is executed sequentially, as in a programming language. Not all constructs, or combinations of constructs, in a process lead to behavior that can be implemented as logic.

Literals
Constant values in VHDL are given in literals. Literals are lexical elements. The following is an overview, with examples given for each type of literal. Character Literals: String Literals: Bit String Literals: Decimal Literals: Based Literals: Physical Literals: Identifiers:
0 X a % #

1110100 XXX try me! $^&@! B0010_0001 X5F 27 -5 4E3 76_562 8#65_07" 5.0 V a O63_07 4.25 14#C5#E+2

2#1001# 2 ns

15 pF true_story

Idle TeSTing

Literals are used to define types and as constant values in expressions. This list provides a brief description of their function in VHDL which will be more clear after the descriptions of types and expressions. The _ in bit string literals, decimal literals and based literals helps to order your literal, but does not represent a value. Character literals contain only a single character, and are single quoted. String literals contain an array of characters, and are double quoted.

Precision Synthesis Style Guide, 2011a Update2 November 2011

21

VHDL Language Features Literals

Bit String Literals are a special form of string literals. They contain an array of the characters 0 and 1, and are preceded by one of three representation forms. B is the bit representation (0 or 1 allowed), X the hexadecimal representation (0 to F allowed) and O the octal representation (0 to 7 allowed). X"5F" is exactly the same as B"01011111", which is again the same as the string literal "01011111". Bit string literals can contain underscores, which are ignored and only inserted for readability. Decimal literals are integer or real values. Based literals are also integer or real values, but they are written in a based form. 8#75# is the same as decimal 61. However it is not the same as the bit literal value O"75" since the bit literal value is an array (of bits) and the based literal is a integer. Physical literals are sometimes required for simulation. As they are not used in the synthesized part of the design, we do not go into detail about them. Identifiers can be enumerated literals. They are case-insensitive, like all identifiers in VHDL. Their use becomes more clear with the discussion of VHDL types.

Types
A type is a set of values. VHDL supports a large set of types, but here we concentrate on types that are useful for synthesis. VHDL is a strongly typed language: every object in a VHDL source needs to be declared and needs to be of a specific type. This allows the VHDL compiler to check that each object stores a value that is in its type. This avoids confusion about the intended behavior of the object, and in general allows the user to catch errors early in the design process. It also allows overloading of operators and subprograms. It also make coding in VHDL a little more difficult, but tends to produce cleaner, better maintainable code. VHDL defines four classes of types: Scalar types Composite types Access types File types

Access types and File type cannot be applied for logic synthesis, since they require dynamic resource allocation, which is not possible in a synthesized hardware. Therefore, we will not discuss these. Instead, only scalar types and composite types will be discussed. These are all scalar types in VHDL:

22

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Literals

Enumerated types. Integer types Floating-point types Physical types VHDL has two forms of composite types:
o o

Array types Record types.

Enumerated Types
Syntax and Semantics
An enumerated type consists of a set of literals (values). It indicates that objects of that type cannot contain any other values than the ones specified in the enumerated type. An example of an enumerated type is the pre-defined type bit. This is how the type bit is declared:
type bit is (0,1) ;

Any object of type bit can only contain the (literal) values 0 and 1. The VHDL compiler will error out (type error) if a different value could be assigned to the object. Enumerated types are also often used to declare the (possible) states of a state machine. Here is an example of the declaration of the states of an imaginary state machine are declared:
type states is (IDLE, RECEIVE, SEND) ;

Once an object of this type is declared, the object can contain only one of these three state values.

Integer Types
Syntax and Semantics
When designing arithmetic behavior, it is very helpful to work with integer types. An integer type defines the set of integer values in its range. This is how an integer type is defined:
type my_integer is range 0 to 15 ;

Precision Synthesis Style Guide, 2011a Update2 November 2011

23

VHDL Language Features Literals

Any object of type my_integer can only contain integer values in the range specified. VHDL pre-defines an integer type called integer, that at least covers a range of integer values that can be represented in twos complement with 32 bits:
type integer is range -2147483647 to 2147483647;

Actually, VHDL 1076 does not define the maximum bounds of the predefined type integer nor of any other integer type, it just states that it should at least include this range.

Integer Synthesis issues


Precision RTL Synthesis can synthesize with any integer type that contains no values outside the range -2147483648 to 2147483647. Precision RTL Synthesis stores integer values (constant ones) using (32 bit) integers internally. If more than 32 bits are needed for a particular circuit design, you should use arrays to represent them. Do not use integer types that exceed the range, since many other VHDL tools have the same restrictions as Precision RTL Synthesis. Precision RTL Synthesis needs to do encoding for integer types, since an integer range requires multiple bits to represent. The synthesis tools will analyze the range of an integer type and calculate the number of bits needed to represent it. If there are no negative values in the integer range, Precision RTL Synthesis will create an unsigned representation. For example, consider the following object of the type my_integer from the previous section:
signal count : my_integer ;

The signal count will be represented as unsigned, consisting of four bits. When synthesized, the four bits will be named as elements of a bus in the resulting netlist:
count(3) count(2) count(1) count(0) the MSB bit

the LSB bit

If the range includes negative numbers, Precision RTL Synthesis will use twos-complement representation of the integer values. For example, any object of the predefined type integer will be represented with 32 bits where the MSB bit represents the sign bit. Example:
signal big_value : integer ;

24

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Literals

Now, Precision RTL Synthesis will represent the signal big_value as 32 bits:
big_value(31) the sign bit big_value(30) the MSB bit : : big_value(1) big_value(0) the LSB bit

Floating-point Types
Syntax and Semantics
As any high-level programming language, VHDL defines floating-point types. Floating-point types approximate the real numbers. Here is an example of the declaration of a floating-point type:
type my_real is range 0.0 to 1.0 ;

VHDL pre-defines a very general floating-point type called real.


type real is range -1.0E38 to 1.0E38 ;

Like the integer types, maximum bounds of any floating-point type are not defined by the language. However, the floating-point type should but should at least include -1.0E38 to 1.0E38. Nothing in the language defines anything about the accuracy of the resolution of the floatingpoint type values.

Synthesis Issues for Floating-point Types


In general, since the resolution of floating-point types is not defined by the language, it is difficult to come up with a good rule for encoding floating-point types. While in a regular (software) compilers floating-point types are represented in 32, 64 or 128 bits, the floating-point operations just require time. In hardware compilers like a logic synthesis tool, floating-point operations would require massive amounts of actual synthesized hardware, unless the resolution and bounds of the floating-point type are kept under very close control. In summary, Precision RTL Synthesis does not currently support synthesis of floating point objects. Floating-point types and objects can however be used in constant expression.

Precision Synthesis Style Guide, 2011a Update2 November 2011

25

VHDL Language Features Literals

For example, an attribute could get a (compile time constant) floating-point expression, and the synthesis tools will calculate the expression and set the floating-point value on the attribute.

Physical Types Syntax and Semantics


VHDL allows the definition of physical types. Physical types represent relations between quantities. A good example of a physical type is the predefined type time:
type time is range -2147483647 to 2147483647 units fs; ps = 1000 fs; ns = 1000 ps; us = 1000 ns; ms = 1000 us; sec = 1000 ms; min = 60 sec; hr = 60 min; end units;

Objects of physical types can contain physical values of the quantities specified in the type, as long as the values do not exceed the range of the type. Type time is often used in VHDL designs to model delay.

Synthesis Issues for Physical Types


Physical types, objects and values are normally only used for simulation purposes. Objects and values of type time are used in after clauses to model delay. Precision RTL Synthesis attempts to synthesize any physical value that is within the range of the type. The encoding follows the encoding for integer types, and expresses the value with respect to the base quantity (fs in the type time). It is not common practice however to synthesize logic circuitry to model physical values. Precision RTL Synthesis handles constant expressions of physical values without any problems. For example, attributes of type time can receive constant values of type v. This is often used to model arrival time and required time properties in the design.

Array Types
Syntax and Semantics
An array type in VHDL specifies a collection of values of the same type. There are constrained and unconstrained array types.
26
Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Literals

For an constrained array type, the number of elements and the name of the elements (the index) is defined and fixed. Example:
type byte is array (7 downto 0) of bit ;

In this example, type byte defines an array of 8 element, each of type bit. The elements are named with indexes ranging from 7 (for the left most element in the array) downto 0 (for the right most element in the array). Example of an array object:
constant seven : byte := "00000111" ;

Individual elements of the array object can now be referred to using indexing:
seven(0) seven(7)

is the name of the right most element in array v. Its value is the bit literal 1. is the name of the left most element in array v. Its value is the bit literal 0.

Parts of the array can be retrieved using slicing:


seven(3 downto 0) is the name of the right most four elements in array seven. The value is an array of four bits: "0111". The indexes of this array range from 3 down to 0.

For an unconstrained array type, the number of elements and the name of the elements in not yet defined. An example is the pre-defined type bit_vector:
type bit_vector is array (natural range <>) of bit ;

Here, the array type defines that the element type is bit, and that the index type is type natural. Type natural is an integer subtype that includes all non-negative integers. The meaning of this is that the index value for any object of type bit_vector can never be negative. By defining an unconstrained array type, you defer specifying a size for the array. Still, in order to define a valid object of an unconstrained array type, we need to constrain the index range. This is normally done on the object declaration:
constant eight : bit_vector (7 downto 0) := "00001000" ;

Unconstrained array types are very important, since they allow you to declare many differentsize objects and to use these objects through each other, without introducing type conflicts.

Precision Synthesis Style Guide, 2011a Update2 November 2011

27

VHDL Language Features Literals

The type of the element of an (constrained or unconstrained) array type is not restricted to enumerated type bit as in the examples. Actually, an array element type can be any type except for an unconstrained array type. You can define an array of integers, an array of 6-bit arrays, an array of records etc. However, you cannot declare an array of (the unconstrained array type) bit_vector. If you want an unconstrained array type where you need more indexes to remain unconstrained, you need a multi-dimensional array type:
type matrix is array (natural range <>, natural range <>) of bit ;

Multi-dimensional (constrained and unconstrained) array type are useful when modeling RAMs, ROMs and PLAs in VHDL. Indexes and slices of multi-dimensional arrays need to specify all index dimensions, separated by a comma. Finally, the index type of an array type does not have to be an integer (sub)type. It can also be an enumerated type.

Synthesis Issues for Array Types


There are no synthesis restrictions in Precision RTL Synthesis on using arrays. Precision RTL Synthesis supports arrays of anything (within the language rules), multi-dimensional arrays, array types with enumerated index type. Negative indexes are also allowed. Naming of array objects is straightforward. Precision RTL Synthesis appends the index for each element after the array name. If the element type consists of multiple bits, the synthesis tools append the element indexes to the array name with its index. It is important to understand that there is no Most Significant Bit (MSB) or Least Significant Bit (LSB) defined in an array type or array object. The semantics of what is interpreted as MSB or LSB is defined by the operations on the array. In the example of object seven the user probably meant the left most bit to be the MSB, and the right most bit the LSB. However, this is not defined by the language, just by the user. Additions, subtractions, and multiplications have to be defined by the user. Most synthesis tool vendors define (arithmetic) operations on arrays in packages that are shipped with the product. Most of these packages assume that leftmost bit is the MSB and the rightmost bit is the LSB. As an example of this, the packages exemplar and exemplar_1164 define arithmetic operators the bit_vector and the IEEE 1164 array equivalent std_logic_vector type. In these packages, the leftmost bit is assumed to be the MSB.

28

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Literals

Record Types
Syntax and Semantics
A record type defines a collection of values, just like the array type. All elements of an array must be of the same type. Elements of a record can be of different types:
type date is record day : integer range 1 to 31 ; month : month_name ; year : integer range 0 to 4000 ; end record ;

The element type month_name in this example could be an enumerated type with all names of the months as literals. The elements of a record type can again be of any type, but cannot be an unconstrained array. Consider the following object of type date:
constant my_birthday : date := (29, june, 1963) ;

Individual elements of a record object can be accessed with a selected name. A selected name consists of the object name, followed by an underscore(_) and the element name:
my_birthday_year selects the year field out of my_birthday and returns the integer value 1963.

Synthesis Issues for Record Types


Precision RTL Synthesis does not impose any restrictions (except for language rules) on record types and record objects. Naming of the individual bits that result after synthesizing a record object follow the selected naming rule of the language: Each bit in a record object get the record name followed by an underscore, followed by the element name. If the element synthesizes into multiple bits, the index of the bits in each element are appended to that. As an example, the five bits that represent the day field in my_birthday will be named as follows:
my_birthday_day(0) LSB in my_birthday.day my_birthday_day(1) my_birthday_day(2) my_birthday_day(3) my_birthday_day(4) MSB in my_birthday.day

Precision Synthesis Style Guide, 2011a Update2 November 2011

29

VHDL Language Features Literals

Subtypes
A subtype is a type with a constraint.
subtype <subtype_name> is <base_type> [<constraint>] ;

A subtype allows you to restrict the values that can be used for an object without actually declaring a new type. This speeds up the debugging cycle, since the simulator will do a run-time check on values being out of the declared range. Declaring a new type would cause type conflicts. Here is an example:
type big_integer is range 0 to 1000 ; type small_integer is range 0 to 7; signal intermediate : small_integer ; signal final : big_integer ; final <= intermediate * 5 ; <- type error occurs because big_integer and small_integer are NOT the same type

With a type-conversion (see next section), you can cast one integer into another one to avoid the error. Still, it is cleaner to use a subtype declaration for the (more constrained) small_integer type:
type big_integer is range 0 to 1000 ; subtype small_integer is big_integer range 0 to 7; signal intermediate : small_integer ; signal final : big_integer ; final <= intermediate * 5 ;<- NO type error occurs ! because big_integer and small_integer have the same base-type (big_integer).

Subtypes can be used to constraint integer types (as in the example), floating-point type, and unconstrained arrays. Declaring a subtype that constraints an unconstrained array type is exactly the same as declaring a constrained array type:
type bit_vector is array (natural range <>) of bit ; subtype eight_bit_vector is bit_vector (7 downto 0) ;

30

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Literals

has the same effect as:


type eight_bit_vector is array (7 downto 0) of bit ;

Just as in the integer type example, subtypes of one and the same unconstrained base-type are compatible (will not cause type errors), but when two constrained array types are used, they will cause type errors if objects of both types are intermixed in expressions. Type conversion is then the only possibility to let objects of the two types be used together in expressions without type errors. There are no synthesis restrictions on the use of subtypes.

Type Conversions
In cases where it is not possible to declare one type and one subtype instead of two separate types, VHDL has the concept of type conversion. Type conversion is similar to type casting in high level programming languages. To cast an expression into a type, use the following syntax:
<type>(<expression>)

Type conversion is allowed between related types. There is a long and detailed discussion in the VHDL LRM about what related types are, but in general, if it is obvious to you that the compiler should be able to figure out how to translate values of one type to values of another type, the types are probably related. For example, all integer types are related, all floating-point types are related and all array types of the same element type are related. So, the problem of type error between two different types in example of the previous section could be solved with a type conversion:
type big_integer is range 0 to 1000 ; type small_integer is range 0 to 7; signal intermediate : small_integer ; signal final : big_integer ; final <= big_integer(intermediate * 5) ;<- NO type error occurs now, since the compiler knows how to translate small_integer into big_integer with the type conversion.

Precision Synthesis Style Guide, 2011a Update2 November 2011

31

VHDL Language Features Literals

IEEE 1076 Predefined Types


The VHDL IEEE 1076 standard predefines a number of types. The following lists the ones which are most important for synthesis:
type bit is (0,1) ; type bit_vector is array (integer range <>) of bit ; type integer is range MININT to MAXINT ; subtype positive is integer range 0 to MAXINT ; subtype natural is integer range 0 to MAXINT ; type boolean is (TRUE,FALSE) ;

Precision RTL Synthesis also understands the predefined types CHARACTER, STRING, SEVERITY_LEVEL, TIME, REAL and FILE.

IEEE 1164 Predefined Types


A problem with the 1076 standard is that it does not specify any multi-valued logic types for simulation purposes, but rather left this to the user and/or tool vendor. The IEEE 1164 Standard specifies a 9-valued logic. Precision RTL Synthesis supports these types, although some restrictions apply to the values you can use for synthesis. The meaning of the different type values of the IEEE 1164 standard are as follows:
U X 0 1 Z W L H -

Uninitialized Forcing Unknown Forcing Low Forcing High High Impedance Weak Unknown Weak Low Weak High Dont Care

The weak values on a node can always be overwritten by a forcing value. The high impedance state can be overwritten by all other values. Most of these values are meaningful for simulation purposes only. Some restrictions apply if you want to use these values for synthesis. Only the values 0,1,X,- and Z have a well-described meaning for synthesis.

32

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Objects

Some examples of IEEE 1164 type statements are:


type std_ulogic is (U,X,0,1,Z,W,L,H,-) ; type std_ulogic_vector is array (natural range <>) of std_ulogic ; subtype std_logic is resolution_func std_ulogic ; type std_logic_vector is (natural range <>) of std_logic ; subtype X01Z is resolution_func std_ulogic range X to Z ; -- includes X,0,1,Z

The identifier resolution_func is a function that defines which value should be generated in case multiple values are assigned to an object of the same type. This is called the resolution function of the type. Resolution functions are supported as long as they do not return any metalogical values. To use the IEEE 1164 types you must load the IEEE package into your VHDL description. This is done with the following statements:
library ieee ; use ieee.std_logic_1164.all ;

Objects
Objects in VHDL (signals, variables, constants, ports, loop variables, generics) can contain values. Values can be assigned to objects, and these values can be used elsewhere in the description by using the object in an expression. All objects except loop variables have to be declared before they are used. This section describes the various objects in VHDL and their semantics.

Signals
Signals represent wires in a logic circuit. Here are a few examples of signal declarations:
signal foo : bit_vector (5 downto 0) := B"000000" ; signal aux : bit ; signal max_value : integer ;

Signals can be declared in all declarative regions in VHDL except for functions and procedures. The declaration assigns a name to the signal (foo); a type, with or without a range restriction (bit_vector(5 downto 0)); and optionally an initial (constant) value. Initial values on signals are usually ignored by synthesis. Signals can be assigned values using an assignment statement (e.g., aux <= 0 ;). If the signal is of an array type, elements of the signals array can be accessed and assigned using indexing or slicing.

Precision Synthesis Style Guide, 2011a Update2 November 2011

33

VHDL Language Features Objects

Assignments to signals are not immediate, but scheduled to be executed after a delta delay. This effect is an essential difference between variables and signals.

Constants
Constants can not be assigned a value after their declaration. Their only value is the initial constant value. Initialization of a constant is required. An example of declaring a constant is:
constant ZEE_8 : std_logic_vector (7 downto 0) := "ZZZZZZZZ" ;

Variables
Variables can not be declared or used in the dataflow areas or in packages, only in processes, functions and procedures. An example of declaring a variable is:
variable temp : integer range 0 to 10 := 5 ;

Assignments to a variable are immediate. This effect is an essential difference between variables and signals. The initial assignment to a variable is optional. The initial assignment to a variable in a process is usually ignored by synthesis.

Ports
A port is an interface terminal of an entity. A port represents an ordinary port in a netlist description. Ports in VHDL are, just like other objects, typed and can have an initial value. In addition, a port has a direction. This is a property that indicates the possible information flow through the port. Possible directions are in, out, inout and buffer, where inout and buffer indicate bidirectional functionality.
entity adder is port ( input_vector : in bit_vector (7 downto 0) ; output_vector : out bit_vector (7 downto 0) ) ; end adder ;

After declaration, a port can be used in the architecture of the entity as if it were a normal signal, with the following restrictions: first, you cannot assign to a port with direction in, and second, you cannot use a port of direction out in an expression.

34

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Statements

Generics
A generic is a property of an entity. A good example of a generic is the definition of the size of the interface of the entity. Generics are declared in a generic list.
entity increment is generic ( size : integer := 8 ) ; port ( ivec : in bit_vector (size-1 downto 0) ; ovec : out bit_vector (size-1 downto 0)) ; end increment ;

The generic size can be used inside the entity (e.g., to define the size of ports) and in the architecture that matches the entity. In this example, the generic size is defined as an integer with an initial value 8. The sizes of the input and output ports of the entity increment are set to be 8 bits unless the value of the generic is overwritten by a generic map statement in the component instantiation of the entity.
inst_1 : increment generic map (size=>16) port map (ivec=>invec, ovec=>outvec) ;

Here, a 16-bit incrementer is instantiated, and connected to the signals invec and outvec. Precision RTL Synthesis fully supports generics and generic map constructs and imposes no restriction on the type of the generic (such as integer, positive, natural, real, string,std_logic, std_logic_vector, boolean, or time). Generics are very useful in generalizing your VHDL description for essential properties like sizes of interfaces or for passing timing information for simulation to instantiated components.

Loop Variables
A loop variable is a special object in the sense that it does not have to be declared. The loop variable gets its type and value from the specified range in the iteration scheme.
for i in 5 downto 0 loop a(i) <= b(i) and ena ; end loop ;

In this code fragment, i becomes an integer with values 0,1,2...5 respectively, when the loop statements are executed 6 times. A loop variable can only be used inside the loop, and there can be no assignments to the loop variable. For synthesis, the range specified for the loop variable must be a compile-time constant, otherwise the construct is not synthesizable.

Statements
This section briefly discusses the basic statements that can be used in VHDL descriptions.
Precision Synthesis Style Guide, 2011a Update2 November 2011

35

VHDL Language Features Statements

Conditional Statements
signal a : integer ; signal output_signal, x, y, z : bit_vector (3 downto 0) ; .... if a = 1 then output_signal <= x ; elsif a = 2 then output_signal <= y ; elsif a = 3 then output_signal <= z ; else output_signal <= "0000" ; end if ;

This code fragment describes a multiplexer function, implemented with an if-then-else statement. This statement can only be used in a sequential environment, such as a process, procedure or a function. The same functionality in the dataflow environment is accomplished with the use of the conditional signal assignment statement:
signal a : integer ; signal output_signal, x, y, z : bit_vector (3 downto 0) ; .... output_signal <= x when a=1 else y when a=2 else z when a=3 else "0000" ;

Selection Statements
If many conditional clauses have to be performed on the same selection signal, a case statement is a better solution than the if-then-else construct:
signal output_signal, sel, x, y, z : bit_vector (3 downto 0) ; .... case sel is when "0010" => output_signal <= x ; when "0100" => output_signal <= y ; when "1000" => output_signal <= z ; when "1010" | 1100" | "0110" => output_signal <= x and y and z ; when others => output_signal <= "0000" ; end case ;

The | sign indicates that particular case has to be entered if any of the given choices is true (or functionality). Each case can contain a sequence of statements.

36

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Statements

The case statement can only be used in a sequential environment. In the dataflow environment, the selected signal assignment statement has the equivalent behavior:
signal output_signal, sel, x, y, z : bit_vector (3 downto 0) ; .... with sel select output_signal <= x when "0010", y when "0100", z when "1000", x and y and z when "1010" | "1100" |"0110", "0000" when others ;

Note For additional information on the handling of others during optimization, see Advanced FSM Optimization on page 296 and How Precision Implements a Safe FSM on page 297.

Loop Statements and Generate Statements


In many cases, especially with operations on arrays, many statements look alike, but differ only on minor points. In that case, you might consider using a loop statement.
signal result, input_signal : bit_vector (5 downto 0) ; signal ena : bit ; .... for i in 0 to 5 loop result(i) <= ena and input_signal(i) ; end loop ;

In this code fragment, each bit of a input signal is anded with a single bit enable signal, to produce an output array signal. The loop variable i does not have to be declared. It holds an integer value since the loop range is an integer range. The previous example showed a for loop. VHDL also has a while loop. Here is an example:
process -- no sensitivity list begin wait until clk event AND clk=1; output_signal <= 0; while (input_signal < 6) loop wait until clk event AND clk=1; output_signal <= output_signal +1; end loop; end process;

Precision RTL Synthesis supports almost every type of loop. The tool supports any for loop with the exception of for loops that contain wait until statements. The tool also supports any

Precision Synthesis Style Guide, 2011a Update2 November 2011

37

VHDL Language Features Statements

kind of NEXT and EXIT statements applicable on an outer while loop with multiple wait statements. loops are supported as long as they have a valid wait statement in every possible path within the loop. If a while loop does not have a single wait statement, and it is bound by constants, then the tool synthesized the design correctly. This is shown in the following example:
While variable i : integer ; ...... i := 0 ; while (i < 6) loop result(i) <= ena AND input_signal(i) ; i := i + 1 ; end loop ;

The tool supports EXIT and NEXT statements within while loops. For example, we could write the while loop as follows:
process -- no sensitivity list begin wait until clk event AND clk=1; output_signal <= 0; while (TRUE) loop exit if (input_signal < 6); wait until clk event AND clk=1; output_signal <= output_signal +1; end loop; end process;

The loop statement can only be used inside sequential environments. Its equivalent statement in the dataflow environment is the generate statement:
signal result, input_signal : bit_vector (5 downto 0) ; signal ena : bit ; .... G1 : for i in 0 to 5 generate result(i) <= ena and input_signal(i) ; end generate ;

The generate statement is preceded by a label (G1). A label is required in the generate statement but is optional in the loop statement. The generate statement does not allow EXIT and NEXT statements. The reason is that the statements inside the generate statement are executed concurrently. So there is no way to

38

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Statements

know when to exit. The generate statement has no while equivalent, for the same reason. Instead however, there is a if equivalent in the generate statement:
signal result, input_signal : bit_vector (5 downto 0) ; G1 : for i in 0 to 5 generate G2 : if i < 3 generate result(i) <= input_signal(i) ; end generate ; G3 : if (i >= 4) generate result(i) <= NOT input_signal (i); end generate ; end generate ;

The condition must evaluate to a run-time constant. That is a language requirement. There is no else part possible in a generate statement. We consider this a flaw in the language, but Mentor Graphics synthesis tools have to comply with it. Precision RTL Synthesis does not have any synthesis restrictions for the generate statement.

Assignment Statements
Assignments can be done to signals, ports and variables in VHDL. Assignments to signals and ports are done with the <= operator.
signal o, a, b : std_logic_vector (5 downto 0) ; .... o <= a xor b ;

In this code fragment o gets assigned the value of the vector-XOR (bit by bit) of vectors v and b. The type of the object on the left hand side of the assignment should always match the type of the value on the right hand side of the assignment. Signal assignments can be used both in dataflow environment and sequential environments. Assignments to variables are done with the := sign.
variable o : std_logic_vector (5 downto 0) ; signal a, b : std_logic_vector (5 downto 0) ; .... o := a AND NOT b ;

Variable assignments can only be used in sequential environments. Types on left and right hand side of the := sign should match. There is one important difference between assignments to signals and assignments to variables: when the values are updated. The value of a variable in a variable assignment is updated

Precision Synthesis Style Guide, 2011a Update2 November 2011

39

VHDL Language Features Statements

immediately after the assignment. The value of a signal in a signal assignment is not updated immediately, but gets scheduled until after a delta (delay) time. This delay time is not related to actual time, but is merely a simulation characteristic. This behavior of the signal assignment does not have any effect for signal assignments in a dataflow environment, since assignments are done concurrently there. However, in a process, the actual value of the signal changes only after the complete execution of the process. The following example illustrates this effect. It shows the description of a multiplexer that can select one bit out of a four bit vector using two select signals.
entity mux is port ( s1, s2 : in bit ; inputs : in bit_vector (3 downto 0) ; result : out bit ) ; end mux ; architecture wrong of mux is begin process (s1,s2,inputs) signal muxval : integer range 0 begin muxval <= 0 ; if (s1 = '1') then muxval if (s2 = '1') then muxval -- use muxval as index of result <= inputs (muxval) end process ; end wrong ;

to 3 ;

<= muxval+1 ;end if; <= muxval+2 ;end if; array inputs ;

This description does not behave as intended. The problem is because muxval is a signal; the value of muxval is not immediately set to the value defined by bits a and b. Instead, muxval still has the same value it had when the process started when the if statement is executed. All assignments to muxval are scheduled until after the process finishes. This means that muxval still has the value it got from the last time the process was executed, and that value is used to select the bit from the input vector.

40

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Operators

The solution to this problem is to make muxval a variable. In that case, all assignments done to muxval are immediate, and the process works as intended.
entity mux is port ( s1, s2 : in bit ; inputs : in bit_vector (3 downto 0) ; result : out bit) ; end mux ; architecture right of mux is begin process (s1,s2,inputs) variable muxval : integer range begin muxval := 0 ; if (s1 = 1) then muxval if (s2 = 1) then muxval -- Use muxval as index of result <= inputs (muxval) end process ; end right ;

0 to 3 ;

:= muxval+1 ;end if; := muxval+2 ;end if; array inputs ;

As a general rule, if you use signal assignments in processes, do not use the value of the signal after the assignment, unless you explicitly need the previous value of the signal. Alternatively, you can use a variable instead.

Operators
IEEE 1076 Predefined Operators
VHDL predefines a large number of operators for operations on objects of various types. The following is an overview: Relational operators on ALL types (predefined or not): = /= < <= > >=

Logical operators on pre-defined types BIT and BOOLEAN: AND OR NAND NOR XOR NOT

Precision Synthesis Style Guide, 2011a Update2 November 2011

41

VHDL Language Features Operators

Arithmetic operators on all integer types: + * / ** Concatenation of elements into an array of elements: & (,,,,) mod rem abs

Relational operators operate on any type. The basis of comparing two values is derived from the order of definition. For example in the std_logic type the value U is smaller than the value 1 because U is defined first in the order of values in the type. The comparison of two arrays is accomplished by comparing each element of the array. The left most element is the most significant one for comparisons.
signal a : bit_vector (7 downto 0) ; signal b : bit_vector (9 downto 5) ;

In this example, a(7) is the most significant bit for comparisons with vector a, and b(9) is the most significant bit for comparisons with vector b. Logical operators work in a straightforward manner and do the appropriate operations on types BIT and BOOLEAN, and also for one-dimensional arrays of BIT and BOOLEAN. In the latter case, the logical operation is executed on each element of the array. The result is an array with the same size and type as the operands. Arithmetic operators work on integers and on all types derived from integers. Precision RTL Synthesis supports arithmetic operators on vectors, described in the exemplar package.

42

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Operators

Concatenation operators can group elements of the same type into an array of that type. Consider the following examples:
signal a, b, c : bit ; signal x : bit_vector (5 downto 0) ; signal y : bit_vector (3 downto 0) ; .... -- using concatenation operator x <= a & b & c & B"00" & 0 ; -- using an aggregate y <= (1, 0, b, c) ;

This description is the same as the following one:


signal a, b, c : bit ; signal x : bit_vector (5 downto 0) ; signal y : bit_vector (3 downto 0) ; .... x(5) <= a ; x(4) <= b ; x(3) <= c ; x(2 downto 0) <= "000" ; y(0) <= 1 ; y(1) <= 0 ; y(2) <= b ; y(3) <= c ;

The aggregate operator in VHDL is especially useful when assigning to a vector of unknown or large size:
signal o : bit_vector (255 downto 0) ; .... o <= (0=>1,others=>0) ;

In this example, o(0) is assigned 1 and all other elements of o (independent of its size) get value 0.

IEEE 1164 Predefined Operators


The IEEE 1164 standard logic package describes a set of new types for logic values. However, the binary operators that are predefined in VHDL only operate on bit and boolean types, and arrays of bits and booleans. Therefore, the IEEE standard logic type package redefines the logical operators (and, or, not, etc.) for the types std_logic, std_ulogic and the array types std_logic_vector and std_ulogic_vector.

Precision Synthesis Style Guide, 2011a Update2 November 2011

43

VHDL Language Features Attributes

Operator Overloading
The operators +, -, *, mod, abs, < ,>, etc. are predefined for integer and floating-point types, and the operators and, or, not etc. are predefined on the type bit and boolean. If you want to use an operator that is not pre-defined for the types you want to use, use operator overloading in VHDL to define what the operator should do. Suppose you want to add an integer and a bit according to your own semantics, and you want to use the + operator:
function + (a: integer; b: bit) return integer is begin if (b=1) then return a+1 ; else return a ; end if ; end + ; signal o, t: integer range 0 to 255 ; signal b : bit ; ... t <= o + 5 + b ;

The first + in the assignment to t is the pre-defined + operator on integers. The second + is the user defined overloaded operator that adds a bit to an integer. The character around the + operator definition is needed to distinguish the operator definition from a regular function definition. Operator overloading is also necessary if you defined your own logic type and would like to use any operator on it. If you want to do arithmetic operations (+, -, etc.) on the array types bit_vector or std_logic_vector, it will be more efficient for synthesis to use the pre-defined operators from the exemplar and the exemplar_1164 packages. Precision RTL Synthesis fully supports operator overloading as described by the language.

Attributes
In VHDL, attributes can be set on a variety of objects, such as signals and variables, and many other identifiers, like types, functions, labels etc. An attribute indicates a specific property of the signal, and is of a defined type. Using attributes at the right places creates a very flexible style of writing VHDL code. An example of this is given at the end of this section.

44

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Attributes

VHDL Predefined Attributes


VHDL pre-defines a large set of attributes for signals. The following example shows the definition of two vectors and the values of the VHDL predefined attributes for them.
signal vector_up : bit_vector (9 downto 4) ; signal vector_dwn : bit_vector (25 downto 0) ; .... vector_upLEFT-- returns integer 9 vector_dwnLEFT-- returns integer 25 vector_upRIGHT-- returns integer 4 vector_dwnRIGHT-- returns integer 0 vector_upHIGH-- returns integer 9 vector_dwnHIGH-- returns integer 25 vector_upLOW-- returns integer 4 vector_dwnLOW-- returns integer 0 vector_upLENGTH-- returns integer 6 vector_dwnLENGTH-- returns integer 26 vector_upRANGE -- returns range 4 to 9 vector_dwnRANGE-- returns range 25 downto 0 vector_upREVERSE_RANGE-- returns range 4 to 9 vector_dwnREVERSE_RANGE-- returns range 0 to 25

The attributes do not have to be written in capitals; VHDL is case-insensitive for identifiers. An important VHDL predefined attribute for synthesis is the EVENT attribute. Its value reveals edges of signals.

Mentor Graphics Predefined Attributes


Apart from the VHDL predefined types, Mentor Graphics also supplies a set of predefined attributes that are specifically helpful for guiding the synthesis process or controlling downstream tools. Refer to Predefined Attributes on page 338.

User-Defined Attributes
Attributes can also be user defined. In this case, the attribute first has to be declared, with a type, and then its value can be set on a signal or other object. This value can then be used with the construct. The following is an example:
signal my_vector : bit_vector (4 downto 0) ; attribute MIDDLE : integer ; attribute MIDDLE of my_vector : signal is my_vectorLENGTH/2 ; .... my_vectorMIDDLE -- returns integer 2

Precision Synthesis Style Guide, 2011a Update2 November 2011

45

VHDL Language Features Attributes

Using Attributes in the Source Code


To indicate where attributes in a VHDL description are useful, consider the following example.
entity masked_parity is port ( source : in bit_vector (5 downto 0) ; mask : in bit_vector (5 downto 0) ; result : out bit ) ; end masked_parity ; architecture soso of masked_parity is begin process (source, mask) variable tmp : bit ; variable masked_source : bit_vector (5 downto 0) ; begin masked_source := source and mask ; tmp := masked_source(0) ; for i in 1 to 5 loop tmp := tmp XOR masked_source(i) ; end loop ; result <= tmp ; end process ; end soso ;

This example calculates the parity of the bits of a source vector, where each bit can be masked. This VHDL description is correct, but is not very flexible. Suppose the application changes slightly and requires a different size input. Then the VHDL description has to be modified significantly, since the range of the vector affects many places in the description. The information is not concentrated, and there are many dependencies. Attributes can resolve these dependencies. Here is an improved version of the same example, where attributes LEFT, RIGHT, and RANGE define the dependencies on the size of the vector.
entity masked_parity is generic ( size : integer := 5) ; port ( source : in bit_vector (size downto 0) ; mask : in bit_vector (sourceRANGE) ; result : out bit ) ; end masked_parity ; architecture better of masked_parity is begin process (source, mask) variable tmp : bit ; variable masked_source : bit_vector (sourceRANGE) ;

46

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Blocks

begin masked_source := source and mask ; tmp := masked_source(sourceLEFT) ; for i in sourceLEFT+1 to sourceRIGHT loop tmp := tmp xor masked_source(i) ; end loop ; result <= tmp ; end process ; end better ;

If the application requires a different size parity checker, this time we only have to modify the source vector range, and the attributes ensure that the rest of the description gets adjusted accordingly. Now the information is concentrated.

Blocks
When using processes and dataflow statements it is possible to use VHDL as a high level hardware description language. However, as the descriptions get more and more complicated, some form of design partitioning, or hierarchy, is required or desirable. VHDL offers a variety of methods for design partitioning. One form of partitioning is to divide a description into various processes. In the following sections four more forms of partitioning are discussed: blocks, subprograms (functions and procedures), components and packages. A block is a method to cluster a set of related dataflow statements. Signals, subprograms, attributes, etc. that are local to the block can be defined in a block declarative region. All statements in a block are executed concurrently, and thus define a dataflow environment.

architecture xxx of yyy is signal global_sig ,g1,g2,c bit ; begin B1 : block -- block declarative region signal local_sig : bit ; begin -- block concurrent statements local_sig <= global_sig ; -- Block in a block B2 : block (c=1) -- Block has GUARD expression port (o1,o2 : out bit)-- Block port declarations port map (o1=>g1,o2=>g2) ; begin o1 <= guarded local_sig ; o2 <= global_sig ; end block ; end block ; end xxx ;

Precision Synthesis Style Guide, 2011a Update2 November 2011

47

VHDL Language Features Functions and Procedures

Blocks can be nested, for example. Signals, ports and generics declared outside the block can be used inside the block, either directly (as global_sig is used in block B2), or via a port map (as g1 is connected to o1 in block B2) or generic maps (for generics). There is no real difference between the two methods, except that the port (generic) map construct is a cleaner coding style which could reduce errors when using or assigning to global objects. A block can also have a GUARD expression (c=1 in block B2). In that case, an assignment inside the block that contains the keyword GUARDED will only be executed when the GUARD expression is TRUE. In the example, o1 only gets the value of local_sig when c=1. GUARDED blocks and assignments provide a interesting alternative to construct latches or flip-flops in the synthesized circuit. For examples, refer to Registers on page 205. Precision RTL Synthesis fully support blocks, with port/generic lists and port/generic maps and the GUARD options of blocks.

Functions and Procedures


Subprograms (function and procedures) are powerful tools to implement functionality that is repeatedly used. Functions take a number of arguments that are all inputs to the function, and return a single value. Procedures take a number of arguments that can be inputs, outputs or inouts, depending on the direction of the flow of information through the argument. All statements in functions and procedures are executed sequentially, as in a process. Also, variables that are local to the subprogram can be declared in the subprogram. Local signals are not allowed. As an example, suppose you would like to add two vectors. In this case, you could define a function that performs the addition. The following code fragment shows how an addition of two 6-bit vectors is done.
function vector_adder (x : bit_vector(5 downto 0); y : bit_vector(5 downto 0)) return bit_vector(5 downto 0) is -- declarative region variable carry : bit ; variable result : bit_vector(5 downto 0) ; begin -- sequential statements carry := 0 ; for i in 0 to 5 loop result (i) := x(i) xor y(i) xor carry ; carry := carry AND (x(i) OR y(i)) OR x(i) AND y(i) ; end loop ; return result ; end vector_adder ;

48

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Functions and Procedures

That vector addition, implemented this way, is not very efficient for synthesis. The packages exemplar and exemplar_1164 provide vector additions that can implement efficient/fast adders more easily. An example of a procedure is shown. The procedure increments a vector only if an enable signal is high.
procedure increment ( vect : inout bit_vector(5 downto 0); ena : in bit :=1) is begin if (ena=1) then vect := vector_adder (vect, "000001") ; end if ; end increment ;

This incrementer procedure shows the behavior of an in/out port. The parameter vect is both set and used in this procedure. Also, the procedure statements use a call to the previously defined vector_adder function. If an input of a function or a procedure is not connected when it is used, that input will get the initial value as declared on the interface list. For example, input ena will get (initial) value 1 if it is not connected in a procedure call to the procedure increment. It is an error if an input is not connected and also does not have an initial value specified. One important feature of subprograms in VHDL is that the arguments can be unbound. The given examples operate on vectors of 6 bits. If you want to use the subprograms for arbitrary length vectors, you could specify the length-dependencies with attributes and not specify a range on the parameters (leave them unbound). Here is a redefinition of both the vector addition function and the incrementer procedure for arbitrary length vectors.
function vector_adder (x : bit_vector; y : bit_vector) return bit_vector is variable carry : bit := 0 ; variable result : bit_vector(xRANGE) ; begin for i in xRANGE loop result (i) := x(i) XOR y(i) XOR carry ; carry := carry AND (x(i) OR y(i)) OR x(i) AND y(i) ; end loop ; return result ; end vector_adder ; procedure increment (vect : inout bit_vector; ena : in bit :=1) is begin if (ena=1) then vect := vector_adder (x=>vect, "000001" ) ; end if ; end increment ;

Precision Synthesis Style Guide, 2011a Update2 November 2011

49

VHDL Language Features Resolution Functions

In the procedure increment example, name association was added in the parameter list of the vector_adder call. The name association (e.g., x=>vect) is an alternative way to connect a formal parameter (x) to its actual parameter (vect). Name associations (as well as positional associations) are helpful if the number of parameters is large. Subprograms can be called from the dataflow environment and from any sequential environment (processes and other sub-programs). If a procedure output or inout is a signal, the corresponding parameter of the procedure should also be declared as a signal. Subprograms can be overloaded. That is, there could be multiple subprograms with the same name, but with different parameter list types or return types. Precision RTL Synthesis performs the overlaod resolution. In the last example, the variable carry was initialized in when it was declared. This is a more compact way of setting the starting value of a variable in a function or procedure. The initial value does not have to be a constant. It could be a nonconstant value also (like the value of one of the parameters). Precision RTL Synthesis fully supports all VHDL language features of functions and procedures.

Resolution Functions
Syntax and Semantics
In a concurrent area in VHDL, all statements happen concurrently. That means that if there are two assignments to the same signal, then the final value of the signal needs to be resolved. In VHDL, you can only have multiple concurrent assignments to a signal if the type of the signal is resolved. A resolved type is a type with a resolution function. A good example of a resolved type is the type std_logic from the IEEE 1164 package:
subtype std_logic is resolved std_ulogic ;

50

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Resolution Functions

The word resolved in this declaration refers to a resolution function called resolved. Here is how it is specified in the std_logic_1164 package:
function resolved ( s : std_ulogic_vector ) return std_ulogic is variable result : std_ulogic := Z; -- weakest state default attribute synthesis_return of result:variable is WIRED_THREE_STATE ; begin -- the test for a single driver is essential otherwise the -- loop would return X for a single driver of - and that -- would conflict with the value of a single driver unresolved -- signal. if (sLENGTH = 1) then return s(sLOW); else for i in srange loop result := resolution_table(result, s(i)); end loop; end if return result; end resolved;

The resolution function of type std_logic takes a vector of the (unresolved) base-type of std_logic : std_ulogic. It returns a single std_ulogic. Now if you have two concurrent assignments to any signal of type std_logic, the resolution function will be called to determine the final value of the signal. The resolution function will be called with a vector with two elements, where each element contains the value of a concurrent assignment. Inside the resolution function, the final value of the signal is defined, based on the two assignment values.

Synthesis Issues
Resolution functions are especially useful when you want to model nets with multiple drivers (like buses with three-state drivers). However, VHDL lets you define a resolution function freely, without any special restrictions. The resolution function is thus just another function, only it gets called wherever there are multiple assignments to a signal of the (sub) type it is attached to. You can define a resolution function and attach it to a subtype, and Precision RTL Synthesis will synthesize the circuitry it implies for each multiple assignment. In many cases, the resolution function mimics a certain electrical behavior for the simulator. In the case of the IEEE type std_logic, and its resolution function resolved, the resolution function resembles tri-states being wired together. Therefore, the synthesis directive attribute (synthesis_result) is set to WIRED_THREE_STATE. This synthesis directive is a hint to Precision RTL Synthesis to interpret the elements of the incoming vector as parallel three-state assignments, where the three-state condition is derived from the assignment. That way, any three-state drivers can be created with multiple assignments.

Precision Synthesis Style Guide, 2011a Update2 November 2011

51

VHDL Language Features Resolution Functions

Lets go through one example step by step, to show what the resolution function is doing:
entity test_resolver is port (a, b : bit ; o : out bit ) ; end test_resolver ; architecture rtl of test_resolver is signal tmp : bit ; begin tmp <= a ; tmp <= b ; o <= tmp ; end rtl ;

When the example is executed, Precision RTL Synthesis will give the following error:
Error, multiple sources on unresolved signal TMP; also line 10.

This message is obvious, since you did not explain what should happen when a and b force (different) values concurrently onto signal TMP. For that, write a resolution function. Suppose you want the concurrent assignments to be ANDed. Then you should write a resolution function that performs an AND operation of the elements of its input vector. Also attach the resolution function to TMP. You could do that in two ways: 1. Create a subtype of bit, say, rbit, and attach the resolution function to that subtype, just as we did for the type std_logic. 2. Directly attach the resolution function to the signal TMP. This is the easiest way, and it is useful if there are not many signals that need the resolution function. The second method is:
entity test_resolver is port (a, b : bit ; o : out bit ) ; end test_resolver ; architecture rtl of test_resolver is -- Write the resolution function that ANDs the elements: function my_and_resolved (a : bit_vector) return bit is variable result : bit := 1 ;

52

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Component Instantiation

begin for i in arange loop result := result AND a(i) ; end loop ; return result ; end my_and_resolved ; -- Declare the signal and attach the resolution function to it: signal tmp : my_and_resolved bit ; begin tmp <= a ; tmp <= b ; o <= tmp ; end rtl ;

Precision RTL Synthesis will synthesize this description and tmp becomes the AND of a and b.

Component Instantiation
Components are a method of introducing structure in a VHDL description. A component represents a structural module in the design. Using components, it is possible to describe a netlist in VHDL. Components are instantiated in the dataflow environment. Here is an example of a structural VHDL description where four one-bit rams and a counter module are instantiated.
entity scanner is port ( reset : in bit ; stop : in bit ; load : in bit ; clk : in bit ; load_value : in bit_vector (3 downto 0) ; data : out bit_vector (3 downto 0) ) ; end scanner ; architecture rtl of scanner is component RAM_32x1 port ( a0, a1, a2, a3, a4 : in bit ; we, d : in bit ; o : out bit ) ; end component ;

Precision Synthesis Style Guide, 2011a Update2 November 2011

53

VHDL Language Features Component Instantiation

component counter generic (size : integer := 4 ) ; port ( clk : in bit ; enable : in bit ; reset : in bit ; result : out bit_vector (4 downto 0) ) ; end component ; signal ena : bit ; signal addr : bit_vector (4 downto 0) ; begin for i in 0 to 3 generate ram : RAM_32x1 port map (a0=>addr(0), a1=>addr(1), a2=>addr(2), a3=>addr(3), a4=>addr(4), d=>data(i), we=>load, o=>data(i) ) ; end generate ; ena <= not stop ; count : counter generic map (size=>addrlength) port map(clk=>clk, enable=>ena, reset=>reset, result=>addr) ; end rtl ;

The generate statement is used here to instantiate the four RAMs. Components have to be declared before they can be used. This is done in the declaration area of the architecture, or in a package (see next section). The declaration defines the interface of the component ports with their type and their direction. Actually this example is just a netlist of components. We added one dataflow statement (the assignment to ena) to show that structure and behavior can be mixed in VHDL. The ports of the component are connected to actual signals (or ports) with the port map construct. The generics of the component are connected to actual values with the generic map construct. In this example the generic size is set to 4 with the attribute length on the array addr. If no generic value was set to size (or if the generic map construct was completely absent), size gets value 4, as indicated by the initial value on size in the generic list of the component. It is an error if a generic (or input port) is not connected in a generic map (or port map) construct and there is no initial value given in the component generic (or port) list. In the example, the input ports of the component RAM_32x1 are individual bits (a0, a1, a2, a3, a4). If the input would have been declared as a bit_vector (0 to 4), then the individual bits could be connected with indexed formal names:
.. port map (a(0) => addr(0), a(1) => addr(1), a(2) => addr(2), a(3) => addr(3), a(4) => addr(4), ...

54

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Binding a Component

or with a sliced formal name:


.. port map (a(0 to 4) => addr(0 to 4), .....

or simply with a full identifier association:


.. port map ( a => addr, .....

Precision RTL Synthesis supports any form of slicing or indexing of formal parameter names, as long as the VHDL language rules are obeyed (formal name should be static). Precision RTL Synthesis also supports type-transformation functions in port and generic associations as long as they are synthesizable. Type transformation functions are not very often used and so are not explained here.

Binding a Component
The definition of the components counter and RAM_32x1 are not yet given in the example. The process of giving a contents definition for a component is called binding in VHDL. With Precision RTL Synthesis, there are four ways to do component binding: 1. Specify an entity with the same name as the component and an architecture for it. This way, the component gets bound to the entity with the same name. This is called default binding in VHDL. 2. Specify a configuration specification. Here you can bind a component to an entity with a different name, and you can even connect component ports to entity ports with a different name. 3. Use a source technology in Precision RTL Synthesis that contains a cell with the same name as the component. Precision RTL Synthesis will bind the component to the technology cell (and include functional, timing and area information for it). 4. Do not specify any entity for the component. This way, Precision RTL Synthesis will issue a warning and create a black-box for the component.

Precision Synthesis Style Guide, 2011a Update2 November 2011

55

VHDL Language Features Binding a Component

Option 1 - Using a Default Binding


The component counter is a good example of the first option:
entity counter is generic (size : integer ) ; port ( clk : in bit ; enable : in bit ; reset : in bit ; result : out bit_vector (size-1 downto 0) ) ; end counter ; architecture rtl of counter is begin process (clk,reset) begin if (reset=1) then result <= (others=>0) ; elsif (clkevent and clk=1) then if (enable=1) then result <= result + "1" ; end if ; end if ; end process ; end rtl ;

This description only includes behavior. There is no component instantiated, although it is possible, and it makes hierarchical design possible. Note that in this case the overloaded + operator is used on vectors, as defined in the exemplar package. Also note that an asynchronous reset construction is used to reset the counter value.

Option 2 - Using a Configuration Specification


The second option gives more freedom to bind an entity to a component. Suppose you have a counter entity that does exactly what you need, but it is named differently, and (or) has differently named ports and generics:
entity alternative is generic (N : integer) ; port (clock : in bit ; ena : bit : reset : bit ; output : out bit_vector (N-1 downto 0) ) ; end alternative ; architecture ex of alternative is begin ..... end ex ;

56

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Binding a Component

The following example configuration specification could be used to bind the component counter to the entity alternative, for a particular or all instances of the counter component. The configuration specification is added after the counter component declaration:
component counter generic (size : integer) ; port (clk : in bit ; enable : in bit ; reset : in bit ; result : out bit_vector(4 downto 0) ) ; end component counter ; for all:counter use entity work.alternative(ex) generic map (N=>size) port map (clock=>clk, ena=>enable, reset=>reset,output=>result) ;

This configuration specification binds all instances of component counter to an entity called alternative (architecture ex) in the work library, and it connects the generics and ports of the entity to differently named generics and ports in the component. If the ports and generics have the same name in the entity and the architecture, the generic map and port map dont have to be given. If there is only one architecture of the entity alternative then the architecture (ex) does not have to be given either. If not all, but just one or two instances of the component counter should be bound to the entity alternative, then replace all by a list of instance (label) names. Configuration specifications are a very powerful method to quickly switch definitions of components to a different alternative. The tool fully supports all forms of configuration specifications that are allowed in the language. If no configuration specification is given, the synthesis tools use the default binding as explained in the first option.

Option 3 - Matching a Component Name to a Library Cell


In the third option, if you use a component name that matches the name of a cell in the target technology library, then that cell will be instantiated in the design. In this case, assume that the name RAM_32x1 is the name of a RAM cell in the target technology library.

Option 4 - Creating a Black Box by Omitting the Entity


The fourth option is to omit declaring an entity for the component. This is helpful when hierarchy has to be preserved. This technique can be effectively used to maintain hierarchy. Precision RTL Synthesis generates an empty module for each component it cannot find in the present file as an entity or as a library cell in the source technology. Empty modules show up as blocks in the final netlist. They are not touched by the synthesis and optimization process. Components without a definition can also help to isolate a particular difficult or user-defined
Precision Synthesis Style Guide, 2011a Update2 November 2011

57

VHDL Language Features Binding a Component

part of the design from the synthesis operations. Clock generators or other asynchronous circuits or time-critical user-defined modules are an example of this.

Finding Definitions of Components


In order to instantiate an entity into a VHDL description, you must first declare a component for it. If you use a component instantiation in your VHDL design, Precision RTL Synthesis tries to find the definition of that component. There are three possibilities. 1. The component is a cell in a source technology library. 2. The component has a matching (named) entity in the VHDL source 3. The component has no definition. If a source technology is specified, then the component in the source technology library is searched for. This is especially helpful if the component represents a particular macro in the source technology. If the component is not present in the source technology, Precision RTL Synthesis tries to find an entity and architecture for it. The entity (and architecture) could be present in the same file, or in an included VHDL file. If Precision RTL Synthesis cannot find a matching entity for the component, then the contents of the component are undefined, and the following warning is issued:
Warning, component component_name has no definition

Working with components without a definition can be useful if a particular module of the design is not synthesizable. A clock generator or a delay-module is an example of this. The contents of that module should be provided separately to the physical implementation tools. Leaving components undefined is also useful in two other cases: 1. To preserve hierarchy through the synthesis process. 2. For using hard and soft macros in the target technology. It is possible to explicitly leave the contents of a component empty, even though there is a entity/architecture for it or a cell in the source technology library. In this case, you should specify the boolean attribute dont_touch on the component, or on the corresponding entity.

58

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Packages

This can be useful when only a part of the hierarchy of a design has to be synthesized or if a user-defined simulatable but not synthesizable block is run through Precision RTL Synthesis. Here is an example of how to set the dont_touch attribute:
component clock_gen ..... end component ; attribute dont_touch : boolean ; attribute dont_touch of clock_gen:component is true ;

You can apply dont_touch to a particular instance of a component by setting this attribute on the label of the component instantiation statement. This has the same effect as if the attribute were added to the underlying entity.

Packages
A package is a cluster of declarations and definitions of objects, functions, procedures, components, attributes etc. that can be used in a VHDL description. You cannot define an entity or architecture in a package, so a package by itself does not represent a circuit. A package consists of two parts. The package header, with declarations, and the package body, with definitions. An example of a package is std_logic_1164, the IEEE 1164 logic types package. It defines types and operations on types for 9-valued logic. To include functionality from a package into a VHDL description, the use clause is used.
library ieee ; use ieee.std_logic_1164.all ; entity xxx is port ( x : std_logic ;

-- type std_logic is known since it is -- defined in package -- std_logic_1164

...

This example shows how the IEEE 1164 standard logic types and functions become accessible to the description in entity xxx. This is the general form to include a package in a VHDL description:
library lib ; use lib.package.selection ;

The use clause is preceded by a library clause. The predefined libraries work and std do not have to be declared in a library clause before they are used in a use clause. All other libraries do need to be declared.

Precision Synthesis Style Guide, 2011a Update2 November 2011

59

VHDL Language Features Packages

The selection can consist of only one name of a object, component, type or subprogram that is present in the package, or the word all, in which case all functionality defined in the package is loaded into Precision RTL Synthesis, and can be used in the VHDL description.

library ieee; use ieee.std_logic_1164.all; package global_decl is type log_arr is array(std_logic) of std_logic; constant std_to_bin : log_arr:=('X','X','0','1','X','X','0','1','X'); function to_bin (from : std_logic) return std_logic; end; library ieee; use ieee.std_logic_1164.all; use work.global_decl.all; package body global_decl is function to_bin (from : std_logic) return std_logic is begin return std_to_bin(from); end ; end package body;

How to Use Packages


A functionality described in a VHDL package is included into the VHDL design using the use clause. This is the general form of the use clause:
library lib ; use lib.package.selection ;

The use clause is preceded by a library clause. There are predefined libraries work and std that do not have to be declared in a library clause before they are used in a use clause. All other libraries need the top to be declared. Library std is normally only used to include packages predefined in VHDL1076, but library work is free to be used for any user-defined packages. User-defined library names are also allowed. Precision searches for packages in the library specified by the use statement. If automap_work is enabled, Precision searches the library work for the package instead. If the package cannot be found, Precision issues an error message. The selection can consist of only one name of an object, component, type or subprogram that is present in the package, or the word all, in which case all functionality defined in the package is used in the VHDL description.

60

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Aliases

As an example, the IEEE 1164 std_logic_1164 package (that defines the multi-valued logic types that are often used for circuit design), is included with the following statements:
library ieee ; use ieee.std_logic_1164.all ;

This package is loaded from the file:


<precision install directory>/pkgs/techdata/vhdl/ex_ii64.vhd.

This file contains only the declarations of the functions of the std_logic_1164 package. The bodies of the functions are built into Precision RTL Synthesis for synthesis efficiency. The contents of the package you include with a use clause becomes visible and is usable only within the scope where you use the use clause. The VHDL scoping rules are not explained in this manual. However, if you start a new entity (and architecture), always make sure that you include the packages you need with use clauses just before the entity.

Aliases
An alias is an alternate name for an existing object. By using an alias of an object, you actually use the object to which it refers. By assigning to an alias, you actually assign to the object to which the alias refers.
signal vec : std_logic_vector (4 downto 0) ; alias mid_bit : std_logic is vec(2) ; -- Assignment : mid_bit <= 0 ; -- is the same as vec(2) <= 0 ;

Aliases are often useful in unbound function calls. For instance, if you want to make a function that takes the AND operation of the two left most bits of an arbitrary array parameter. If you want to make the function general enough to handle arbitrary sized arrays, this function could look like this:
function left_and (arr: std_logic_vector) return std_logic is begin return arr(arrleft) and arr(arrleft-1) ; end left_and ; -- Function does not work for ascending index ranges of arr.

This function will only work correctly if the index range of arr is descending (downto). Otherwise, arrleft-1 is not a valid index number. VHDL does not have a simple attribute that will give the one-but-leftmost bit out of an arbitrary vector, so it will be difficult to make a

Precision Synthesis Style Guide, 2011a Update2 November 2011

61

VHDL Language Features Syntax and Semantic Restrictions

function that works correctly both for ascending and descending index ranges. Instead, you could make an alias of arr, with a known index range, and operate on the alias:

function left_and (arr : std_logic_vector) return std_logic is alias aliased_arr : std_logic_vector (0 to arrlength-1) is arr ; begin return aliased_arr(0) and aliased_arr(1) ; end left_and ; -- Function works for both ascending and descending index -- ranges of arr.

Precision RTL Synthesis fully supports aliases.

Syntax and Semantic Restrictions


VHDL as the IEEE Standard 1076 is a extended language with many constructs that are useful for simulation. However, during the initial development of the language, logic synthesis was not taken into account. Therefore, a number of constructs or combination of constructs cannot be implemented in actual circuits. VHDL 1076 is fully simulatable, but not fully synthesizable.

Synthesis Tool Restrictions


This section discusses the syntax and semantic restrictions of the VHDL parsers of Precision RTL Synthesis. Operations on files not supported. Files in VHDL could behave like ROMs or RAMs, but Precision RTL Synthesis does not support using file (types), and will ignore, but accept, file (type) declarations. Operations on objects of real types are not supported. Objects of real types have no defined bit-resolution. Precision RTL Synthesis ignores, but accepts declarations of (objects of) real types. Operations on objects of access types are not supported, since they lead to unsynthesizable behavior. Precision RTL Synthesis ignores, but accepts declarations of (objects of) access types. Attributes BEHAVIOR, STRUCTURE, LAST_EVENT, LAST_ACTIVE, and TRANSACTION are not supported. Global, non-constant signals, that is, signals declared in a package, are supported. The following limitations apply to such signals.
o o

Attributes such as ALLOW_INIT_VAL are ignored. Memory cannot be inferred for such signals.
Precision Synthesis Style Guide, 2011a Update2 November 2011

62

VHDL Language Features Syntax and Semantic Restrictions

Allocators are not supported, because they perform dynamic allocation of resources, which is not synthesizable. Resolution functions with a synthesis directive are allowed.

VHDL Language Restrictions


Apart from these restrictions, which are mostly tool-related, there are some basic restrictions that apply to VHDL descriptions for synthesis. Since they occur quite often, additional descriptions are presented here to clarify the problems involved for synthesis. Here is the list:
after

clause ignored.

Restrictions on Initialization values. Loop restrictions Restrictions on edge-detecting attributes (EVENT and STABLE). Restrictions on wait statements. Restrictions on multiple drivers on one signal.

A more detailed description of these restrictions follows below:

After Clause Ignored


The after clause refers to delay in a signal. Since delay values cannot be guaranteed in synthesis, they are ignored by the synthesis tools.

Restrictions on Initialization Values


Initialization values are allowed in a number of constructs in VHDL: 1. Initial value of a signal in a signal declaration. 2. Initial value of a variable in a variable declaration in a process. 3. Initial value of a variable in a variable declaration in a subprogram (procedure or function). 4. Initial value of a generic or port in a component declaration. 5. Initial value of a parameter in a subprogram interface list. The problem with initialization values for synthesis is that some initial values define the initial value of an object before actual simulation is done. This behavior corresponds to controlling the power-up state of a device that would be synthesized from the VHDL description. Since synthesis cannot control the power-up state of a device, this kind of initial value cannot be synthesized. However, if after initialization there is never an change of value, the behavior can be synthesized, and resembles a simple constant value.
Precision Synthesis Style Guide, 2011a Update2 November 2011

63

VHDL Language Features Syntax and Semantic Restrictions

Precision RTL Synthesis fully supports initialization values, except for initializing objects that can change their value after initialization. That is, the following form of initialization values are NOT supported because they imply power-up behavior of the synthesized device: 1. Initial values of a signal in a signal declaration. 2. Initial value of a variable in a variable declaration in a process. 3. Initial value of an OUTPUT or INOUT port in an interface list. All other forms of initialization values are supported by the synthesis tools.

Loop Restrictions
Loops are supported if they are bound by constants or they have wait until statements to prevent combinational loops.

Restrictions On Edge-Detecting Attributes ('event)


Most restrictions on VHDL to assure correct compilation into a logic circuit are on the constructs that define edges or changes on signals. The EVENT attribute is the best example of this. signalEVENT is TRUE only if signal changes. Then it is TRUE for one simulation delta of time. In all other cases it is FALSE. The STABLE attribute is the boolean inversion of EVENT. There are two restrictions for synthesis on usage of the EVENT and the STABLE attribute: 1. An EVENT or STABLE attribute can be used only to specify a leading or falling clock edge. For example:
clkevent and clk=1 clkevent and clk=0 NOT clkstable and clk=0 clkevent and clk ----Leading Falling Falling Leading edge edge edge edge of of of of clk clk clk (boolean) clk

2. Clock edge expressions can only be used as conditions. For example:


if (clkevent and clk=1) then ... wait until NOT clkstable and clk=0 ; wait until clk=1 ; --Implicit clock edge due to --VHDL semantics of wait block (clkevent and clk=1... --Block GUARD condition

These restrictions originate from the fact that binary logic circuits have a restricted number of elements that are active ONLY during signal edges. Basically, only (set/resettable) edge triggered flip-flops show that behavior. Within these restrictions, Precision RTL Synthesis

64

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL Language Features Syntax and Semantic Restrictions

allows free usage of the clock edge conditions, either in guarded blocks, processes or subprograms.

Restrictions on Wait Statements


All state-of-the-art VHDL synthesis tools on the market right now have strong restrictions with respect to wait statements and use of edge-detecting attributes ( 'event and 'stable). Here are the (informal) restrictions for the wait statement: Multiple wait statements are supported in a process with some synthesis restrictions. All the control paths should have at least one wait statement and all of the wait statements should be identical with a single bit clock expression. The expression in the until condition must specify a leading or falling single clock edge. (Examples are shown above in the EVENT attribute section.)

All assignments inside the process result in the creation of registers. Each register (flip-flop) is clocked with the single clock signal. There are a number of cases where multiple waits are synthesizable and resemble statemachine behavior. In Precision RTL Synthesis, multiple waits are supported.

Restrictions on Multiple Drivers on One Signal


VHDL does not allow multiple drivers on a signal of an unresolved type. For signals of resolved types, VHDL defines that a (user-defined) resolution function defines what the signal value is going to be in case there are multiple driver (simultaneous assignments) to the signal. A resolution function with meta-logical values (Z, X, etc.) in general leads to behavior that is not synthesizable (since logic circuits cannot produce meta-logical values). Therefore, in general, VHDL synthesis tools do not allow multiple drivers on a signal. However, if the resolution function defines the behavior of multiple three-state drivers on a bus, multiple drivers of a signal could represent synthesizable behavior. The Z value is in general used to identify three-state behavior. The resolution function of the IEEE std_logic (resolved) type is written so that multiple drivers on a signal of std_logic do resemble multiple three-state drivers on a bus. Therefore, the synthesis tools accept multiple assignments to the same signal as long as each assignment is conditionally set to the Z value. The synthesis tools allow free usage of Z assignments (either from dataflow statements, process statements or from within procedures). Precision RTL Synthesis implements three-state drivers to mimic the three-state behavior. It is important to note that Precision RTL Synthesis does not check if there could be a busconflict on the driven bus. In this case, the simulation would just call the resolution function again to resolve the value (normally producing a meta-logical value), but the behavior for synthesis is not defined. Avoiding bus conflicts is the responsibility of the user.

Precision Synthesis Style Guide, 2011a Update2 November 2011

65

VHDL Language Features Syntax and Semantic Restrictions

66

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 2 VHDL 2008 Language Features


This section describes key VHDL 2008 Language Support features that are supported in Precision Synthesis. These features include: Conditional and Selected Sequential Assignments Simplified Case Expression Support Unconstrained Element Support Context Declarations Extensions to Generate Fixed Point Package Expressions Port Map Read Out Ports Simplified Sensitivity List Block Comments Matching Case Statement Array-Scalar Operators Logical Reduction Operators Matching Relational Operators Conditional Operator Support Maximum and Minimum Function Support Unconstrained Record Elements

Conditional and Selected Sequential Assignments


VHDL 2008 allows conditional and selected signal assignment statements in concurrent (signals only) and sequential (signals and variables) modes. Prior to VHDL-2008, this was limited to conditional and selected signal assignments in concurrent context only. A conditional statement (when?) carries the same semantics as an if-else-if statement. A select statement (select?) carries the same semantics as a case (case?) statement. By extending support for
Precision Synthesis Style Guide, 2011a Update2 November 2011

67

VHDL 2008 Language Features Simplified Case Expression Support

these conditional and select statements for variables and signals and also in sequential mode, the semantics of the language are made consistent. Thus, the choice list in a selected expression can even contain dont-cares (-) when the select? usage is done. The following example describes this clearly. Example VHDL 2002
Process (d, reset) Begin If reset = '1' then Q <= '0' Else Q <= d; End if; End Process; Process (val1, val2, val3, val4, sel) Begin Case sel is When "00" => q <= val1; When "01" => q <= val2; When "10" => q <= val3; When "11" => q <= val4; End case; End process;

VHDL 2008
Process (reset, d) Begin Q <= '0' when reset else d; End process;

Process (val1, val2, val3, val4, sel) Begin with sel select q <= val1 when "00", val2 when "01", val3 when "10", val4 when "11"; end process;

Simplified Case Expression Support


After associating values 1 and 0 to the first and second elements in an array for a case expression, other elements can be assigned to value 1 provided the case expression is locally static. Prior to VHDL 2008, assigning values to elements after the first and second assignments was not possible. Thus, the following examples are now valid with VHDL 2008.

68

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL 2008 Language Features Unconstrained Element Support

Example VHDL 2002


Variable s: bit_vector (3 downto 0); Variable c: bit; Subtype bv5 is bit_vector(4 downto 0 ); . Case (bv5'(s &c)) When "00000" => When "00001" => . When others => . End case Variable s: downto 0); . Case (s) When "0001" When "0010" When others End case bit_vector( 3

VHDL 2008
Variable s: bit_vector (3 downto 0); Variable c: bit; . Case (s &c) When "00000" => When "00001" => . When others => . End case

=> => . => .

Variable s: bit_vector( 3 downto 0); . Case (s) When (0 => '1' others => '0') => When (1 => '1' others => '0') => . When others => . End case

Unconstrained Element Support


VHDL 2008 allows array elements to be unconstrained. It is not necessary to define an arrays size and this can instead be determined during signal/variable/constant declaration during elaboration. The keyword open can be used to skip constraints during declaration. Example
Type M_unconstrained is array (natural range<>, natural range <>) of bit; Type A_unconstrained is array (character range<>) of M_unconstrained; Type A1_partially_constrained is array (character range 'a' to 'z') of M_unconstrained; Subtype s4 is A_unconstrained(open)(0 to 7, 31 downto 16);

Note Support for unconstrained elements currently exists only for arrays and not for records.

Context Declarations
In VHDL 2008, you can create context declarations of your libraries and use clauses. Example

Precision Synthesis Style Guide, 2011a Update2 November 2011

69

VHDL 2008 Language Features Context Declarations context widget_context is library IEEE; use IEEE.std_logic_1164.all, IEEE.numeric_std.all; use widget_lib.widget_defs.all; use widget_lib.widget_comps.all; end context widget_context; ........... library widget_lib; context widget_lib.widget_context;

70

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL 2008 Language Features Extensions to Generate

Extensions to Generate
VHDL 2008 introduces support for if-else-if and case generate statements. Previously, the generate feature was restricted to the if statement only. Example VHDL 2002
for I in width -1 downto 0 generate begin if I = width - 1 generate adder_1: adder(in1, in2, out1); end generate if not I = width - 1 generate adder_2: adder(in3[i],in2[i], out2); end generate end generate

VHDL 2008
for I in width -1 downto 0 generate begin if I = width - 1 generate adder_1: adder(in1, in2, out1); else generate adder_2: adder(in3[i],in2[i], out2); end generate end generate

Fixed Point Package


VHDL 2008 adds support for Fixed Point Package which provides a representation of floating numbers in the form of fixed point representation. The types supported in fixed point package are ufixed (unsigned fixed point) and sfixed (signed fixed point) types. These types are always supposed to have downto ranges with positive ranges for integral part and negative ranges for fractional part. This is very useful for DSP applications. Annex G of the LRM 1076-2008 contains more information about the usage of this package. Example 6.5 is represented as
signal y: ufixed(4 downto -5); .... Y <= 0011010000; -- 6.5

Also, since package generics are not supported currently, support for fixed_generic_pkg does not exist currently.

Precision Synthesis Style Guide, 2011a Update2 November 2011

71

VHDL 2008 Language Features Expressions Port Map

Expressions Port Map


VHDL 2008 allows input ports to be connected to expressions instead of the need to create temporary signals. Example
Inst1 : trial_ent port map (cin1 => CONV_INTEGER(STD_LOGIC_VECTOR(tdin1) or x"1010") , cin2 => tdin2, cout1 => tdout1);

Read Out Ports


VHDL 2008 allows output ports to be read. Though this feature is mainly intended to help the verification of assertions and monitors, language semantics do not stop it from being used in algorithmic behavior. The scope of this feature will support reading output port in architectures, sub-programs etc. In case of variables in sub-programs, the value propagation won't be done as per LRM but in case of signals the connection will be as passed by reference. VHDL 2002
Entity dff is Port (clk, d: in bit; q, q_n: out bit); End entity; Architecture rtl of dff is Signal q_int: bit; Begin Process (clk) Begin If (clk = '1') then q_int <= d; end if; end process; q <= q_int; q_n <= q_int; end rtl;

VHDL 2008
Entity dff is Port (clk, d: in bit; q, q_n: out bit); End entity; Architecture rtl of dff is Begin Process (clk) Begin If (clk = '1') then q <= d; end if; end process; q_n <= q; end rtl;

72

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL 2008 Language Features Simplified Sensitivity List

Simplified Sensitivity List


VHDL 2008 introduces the keyword 'all' which can be used in process sensitivity list. This will ensure that all signals are appropriately added in the sensitivity list. Example VHDL 2002
Process(in1, in2, in3, in4) Begin Out1 <= in1; Out2 <= in2; Out3 <= in3; Out4 <= in4; End process

VHDL 2008
Process (all) Begin Out1 <= in1; Out2 <= in2; Out3 <= in3; Out4 <= in4; End process

Block Comments
VHDL 2008 introduces C-style multi-line comments starting with '/*' and ending with '*/'. The nesting of block comments is, however, not allowed in VHDL 2008. Example VHDL 2002
Entity dff is Port (clk, d: in bit; q, q_n: out bit); End entity; Architecture rtl of dff is Signal q_int: bit; Begin Process (clk) -- This line -- and this line -- must be commented Begin If (clk = '1') then q_int <= d; end if; end process; q <= q_int; q_n <= q_int; end rtl;

VHDL 2008
Entity dff is Port (clk, d: in bit; q, q_n: out bit); End entity; Architecture rtl of dff is Signal q_int: bit; Begin Process (clk) /* This line and this line must be commented*/ Begin If (clk = '1') then q_int <= d; end if; end process; q <= q_int; q_n <= q_int; end rtl;

Precision Synthesis Style Guide, 2011a Update2 November 2011

73

VHDL 2008 Language Features Matching Case Statement

Matching Case Statement


In VHDL 2008, case statements are introduced with Don't Care in the choice statement by usage of 'case?'. A simple example is described here where the value of the case expression Xin is matched with expressions containing don't care. The restriction on Xin is that its value cannot contain a '-' which is an error. It is also an error if any two choice lists contain the same value. Therefore, the values "---1" and "--1-" in choice lists should yield an error due to an overlap of choices. The case expression is bit/std_ulogic or its vector. Example
case? Xin is when "--1" => Zout <= Ain; when "-10" => Zout <= Bin; when others => Zout <= Cin;

Array-Scalar Operators
Array Scalar Operators allow a scalar operand to be applied to all the elements of an array. The array-scalar logical operators are AND, OR, NAND, NOR, XOR and XNOR for bit, Boolean and std_ulogic types. In the example shown here, the AND operator is applied to each bit of A with ASel and result is stored in T.
A : IN BIT_VECTOR (3 downto 0); ASel : In BIT; T <= A and ASel;

74

Precision Synthesis Style Guide, 2011a Update2 November 2011

VHDL 2008 Language Features Logical Reduction Operators

Logical Reduction Operators


Logical Reduction Operators allow an array to be reduced to array element type by the application of the operator. The logical reduction operators AND, OR, NAND, NOR, XOR and XNOR are pre-defined for bit and Boolean vectors. They must be defined in std_logic_1164 package for std_ulogic_vector and std_logic_vector. The following is an example of parity bit calculation in both VHDL 2008 and VHDL 2002. VHDL 2002
Parity <= data(0) xor data(1) xor data(2) xor data(3);

VHDL 2008
Parity <= xor data;

Matching Relational Operators


VHDL 2008 introduces relational operators that return the result of the bit type or std_ulogic type instead of Boolean result. The matching relational operators are "?=", "?/=", "?<", "?<=", "?>" and "?>=". The following example demonstrates the use of matching relational operators which dont require the use of a when-else statement as was the case prior to VHDL-2008. VHDL 2002
Control_sig <= '1' when x = y else '0'

VHDL 2008
Control_Sig <= x ?= y;

Conditional Operator Support


VHDL 2008 adds a conditional operator "??" which converts bit/std_ulogic type to boolean type. This simplifies the task of writing conditional expressions. The operator is implicitly inferenced in expressions by applying the operator tothe entire expression. The "??" operator can be used in until, if, elseif, while and when statements. The following example shows implicit inference of the conditional operator. Example VHDL 2002
if a ='1' and b = '1' then Q <= d; end if;

VHDL 2008
if a and b then Q <= d; end if;

Precision Synthesis Style Guide, 2011a Update2 November 2011

75

VHDL 2008 Language Features Maximum and Minimum Function Support

Maximum and Minimum Function Support


VHDL 2008 introduces pre-defined maximum and minimum functions with semantics "[ScalarType, ScalarType] return ScalarType" and "[DiscreteArrayType, DiscreteArrayType] return DiscreteArrayType". Maximum and minimum functions make use of the "<" operator for ordering. VHDL 2008 also predefines maximum and minimum functions as reduction operators on array values with semantic "[ArrayType] return ArrayElementType".

Unconstrained Record Elements


VHDL 2008 allows you to keep record elements unconstrained during type definition. These can be constrained later during elaboration or signal declaration. Example:
type myrec is record a : std_logic_vector; b : bit; c : bit_vector; end record; signal s : myrec((3 downto 0), open, (2 downto 0));

In this example, the constraints of a and c elements are defined only during signal declaration and not during type definition.

76

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 3 Verilog Language Features


Verilog HDL is a high level description language for system and circuit design. The language supports various levels of abstraction. Where a regular netlist format supports only structural description, Verilog supports a wide range of description styles. This includes structural descriptions, data flow descriptions and behavioral descriptions. Verilog allows a mixture of various levels of design entry. Precision RTL Synthesis accepts all levels of abstraction from Register-transfer-level down, and minimizes the amount of logic needed, resulting in a final netlist description in the technology of your choice. Verilog is completely simulatable, but not completely synthesizable. Some Verilog constructs have no valid representation in a digital circuit. Other constructs do, in theory, have a representation in a digital circuits, but cannot be reproduced with guaranteed accuracy. Delay time modeling in Verilog is an example of that. State-of-the-art synthesis algorithms can optimize Register Transfer Level (RTL) circuit descriptions and target a specific technology. The synthesis result of a Verilog design depends on the style of Verilog that is used. You should understand the concepts of synthesis-specific Verilog coding style at the RTL level, in order to achieve the desired circuit implementation. This manual is intended to give the Verilog designer guidelines to achieve a circuit implementation that satisfies the timing and area constraints that are set for the target circuit, while still using a high level of abstraction in the Verilog source code. This goal will be discussed both in the general case for synthesis applications, as well as for Precision RTL Synthesis specifically. Examples are used extensively; Verilog rules are not emphasized. Knowledge of the basic constructs of Verilog is assumed. For more information on the Verilog language, refer to the Verilog Hardware Description Language Reference Manual, published by Open Verilog International. This chapter provides an introduction to the basic language constructs in Verilog: Defining logic blocks: Data flow and behavioral descriptions Concurrent and sequential functionality Numbers and data types.

Precision synthesizes all levels of abstraction and minimizes the amount of logic needed resulting in a final netlist description in the technology of your choice.

Precision Synthesis Style Guide, 2011a Update2 November 2011

77

Verilog Language Features Modules

Modules
A basic building block in Verilog is a module. The module describes both the boundaries of the logic block and the contents of the block, in structural, data flow and behavioral constructs.

module small_block (a, b, c, o1, o2); input a, b, c; output o1, o2; wire s; assign o1 = s || c ; assign s = a && b ; assign o2 = s ^ c ; endmodule

Note Precision RTL Synthesis supports empty top level modules.

This Verilog description shows the implementation of small_block, a block that describes some simple logic functions. The port list is declared, the port directions are specified, then an internal wire is declared. A wire in Verilog represents physical connection in hardware. It can connect between modules or gates, and does not store a value. A wire can be used anywhere inside the module, but can only be assigned by: Connecting it to an output of a gate or a module. Assigning to it using a continuous assignment.

This module contains only dataflow behavior. Dataflow behavior is described using continuous assignments. All continuous assignments are executed concurrently, thus the order of these assignments does not matter. This is why it is valid to use s before s is assigned. In the first statement o1 is assigned the result of the logical OR of s and c. | | denotes the logical OR operation. More details about the various dataflow statements and operators are given in the following sections.

macromodule
Precision RTL Synthesis supports macromodule, which is treated as module.

78

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Numbers

Numbers
Numbers in Verilog can be either constants or parameters. Constants can be either sized or unsized. Either one can be specified in binary, octal, hexadecimal, or decimal format. Name binary octal decimal hexcadecimal Prefix b o d h Legal Characters 01xXzZ_? 0-7xXzZ_? 0-9_ 0-9a-fA-FxXzZ_?

If a prefix is preceded by a number, this number defines the bit width of the number, for instance, 8b 01010101. If no such number exists, the number is assumed to be 32 bits wide. If no prefix is specified, the number is assumed to be 32 bits decimal. Precision RTL Synthesis produces a warning when encountering non-synthesizable constants such as float. The value 0 is assumed. For example, in
x = 2.5 + 8;

will evaluate to 8.

Special characters in numbers: _


x, X z, Z, ?

A separator to improve readability. Unknown value. Tri-state value.

Examples:
334 32b101

32 bits wide decimal number 32 bits wide binary number (zero left filled) 3 bits wide binary number (i.e. 011) 20 bits wide hexadecimal number 10 bits wide all tri-state

3b11 20hf_ffff 10bZ

Precision Synthesis Style Guide, 2011a Update2 November 2011

79

Verilog Language Features Data Types

Data Types
Verilog defines three main data types: net register parameter

By default these data types are scalars, but all can take an optional range specification as a means of creating a bit vector. The range expression is of the following form:
[<most significant bit> : <least significant bit>]

Some of these data types are used in the example below, along with the range expression syntax. Further details on the data types are presented in the following sections.
// This design implements a Manchester Encoder // module manenc (clk , data , load , sdata, ready); parameter max_count = 7; input clk, load; input [max_count:0] data; output sdata, ready ; reg reg reg reg sdata, ready ; [2:0] count; [max_count:0] sout; phase;

// Phase encoding always @ (posedge clk) begin sdata = sout[max_count] ^ phase; phase = ~phase ; end

80

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Data Types

// Shift data always @ (posedge phase) begin if ((count == 0) & !load) begin sout[max_count:1] = sout[max_count - 1 :0]; sout[0] = 1'b0; ready = 1'b1; end else if ((count == 0) & load ) begin sout = data; count = count + 1; ready = 1'b0; end else if (count == max_count) begin sout[max_count:1] = sout[max_count - 1 :0]; sout[0]= 1'b0; count = 0; end else begin sout[max_count:1] = sout[max_count - 1 :0]; sout[0]= 1'b0; count = count + 1; end end endmodule

Net Data Types


The net data types supported by Precision RTL Synthesis are
wire tri supply0 supply1 wand wor

These data types are used to represent physical connections between structural entities in the Verilog design, such as a wire between two gates, or a tristate bus. Values cannot be assigned to net data types within always blocks. (tri0, tri1, triand, trior and trireg are also net data types, but are not yet supported by Precision RTL Synthesis).

Precision Synthesis Style Guide, 2011a Update2 November 2011

81

Verilog Language Features Data Types

wire and tri Nets


The wire and tri net data types are identical in usage (syntax and function). The two different names are provided for design clarity. Nets driven by a single gate are usually declared as wire nets, as shown in Modules in this chapter, while nets driven by multiple gates are usually declared as tri nets.

Supply Nets
The supply1 and supply0 net data types are used to describe the power (VCC) and ground supplies in the circuit. For example, to declare a ground net with the name GND, the following code is used:
supply0 GND ;

WAND and WOR Net Types


Verilog wand and wor statements result into AND and OR logic respectively, since wired logic is not available in all technologies.
wor out; out = a&b out = c&d; endmodule

Register Data Type


A register, declared with keyword reg, represents a variable in Verilog. Where net data types do not store values, reg data types do. Registers can be assigned only in an always block, task or function. When a variable is assigned a value in an always block that has a clock edge event expression (posedge or negedge), a flip-flop is synthesized by Precision RTL Synthesis. To avoid the creation of flip-flops for reg data types, separate the combinational logic into a different always block (that does not have a clock edge event expression as a trigger).

Parameter Data Type


The parameter data type is used to represent constants in Verilog. Parameters are declared by using the keyword parameter and a default value. Parameters can be overridden when a module is instantiated.

82

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Continuous Assignments

Declaration Local to Begin-End Block


Local declaration of registers and integers is allowed inside a named begin-end block. If the begin-end block contains a @ posedge ck statement, then the declaration is not supported.
input [10:0] data; always @ (data) begin: named_block integer i; parity = 0; for (i = 0; i < 11; i= i + 1) parity = parity ^ data[i]; end //named_block

Array of Reg and Integer Declaration


Memory declaration and usage of an array of registers or integers is now allowed.
input [3:0] address; input [7:0] date_in; output [7:0] data_out; reg [7:0] data_out, mem [3:0]; always @ (address or date_in or we) if (we) mem [address] = date_in; else data_out = mem [address];

Continuous Assignments
A continuous assignment is used to assign values to nets and ports. The nets or ports may be either scalar or vector in nature. (Assignments to a bit select or a constant part select of a vector are also allowed.) Because nets and ports are being assigned values, continuous assignments are allowed only in the dataflow portion of the module. As such, the net or port is updated whenever the value being assigned to it changes. Continuous assignments may be made at the same time the net is declared, or by using the assign statement.

Net Declaration Assignment


The net declaration assignment uses the same statement for both the declaration of the net and the continuous assignment:
wire [1:0] sel = selector ;

Only one net declaration assignment can be made to a specific net, in contrast to the continuous assignment statement, where multiple assignments are allowed.
Precision Synthesis Style Guide, 2011a Update2 November 2011

83

Verilog Language Features Procedural Assignments

Continuous Assignment Statement


The continuous assignment statement (assign) is used to assign values to nets and ports that have previously been declared. The following example describes a circuit that loads a source vector of 4 bits on the edge of a clock (wrclk), and stores the value internally in a register (intreg) if the chip enable (ce) is active. One bit of the register output is put on a tristate bus (result_int) based on a bit selector signal (selector), with the bus output clocked through a final register (result).
module tri_asgn (source, ce, wrclk, selector, result) ; input [3:0] source ; input ce, wrclk ; input [1:0] selector ; output result ; reg [3:0] intreg ; reg result ; // net declaration assignment wire [1:0] sel = selector ; tri result_int ; // continuous assignment statement assign result_int = (sel == 2b00) result_int = (sel == 2b01) result_int = (sel == 2b10) result_int = (sel == 2b11) always @(posedge wrclk) begin if (ce) begin intreg = source ; result = result_int ; end end endmodule

? ? ? ?

intreg[0] intreg[1] intreg[2] intreg[3]

: : : :

1bZ 1bZ 1bZ 1bZ

, , , ;

Procedural Assignments
Procedural assignments are different from continuous assignments in that procedural assignments are used to update register variables. Assignments may be made to the complete variable, or to a bit select or part select of the register variable. Both blocking and non-blocking procedural assignments are allowed. Blocking assignments, specified with the = operator, are used to designate assignments that must be executed before the execution of the statements that follow it in a sequential block. This means that the value of a register variable in a blocking assignment is updated immediately after the assignment.

84

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Always Blocks

Non-blocking assignments, specified with the <= operator, are used to schedule assignments without blocking the procedural flow. It can be used whenever register assignments within the same time step can be made without regard to order or dependence upon each other. Also, in contrast to the blocking assignment, the value of a register variable in a non-blocking assignment is updated at the end of the time step. This behavior does not affect assignments done in the dataflow environment, since assignments are done concurrently there. However, in a sequential block, such as an always block, the value of the variable in a non-blocking assignment changes only after the complete execution of the sequential block.

Always Blocks
blocks are sections of sequentially executed statements, as opposed to the dataflow environment, where all statements are executed concurrently. In an always block, the order of the statements does matter. In fact, always blocks resemble the sequential coding style of high level programming languages. Also, always blocks offer a variety of powerful statements and constructs that make them very suitable for high level behavioral descriptions.
Always module mux_case (source, ce, wrclk, selector, result); input [3:0] source; input ce, wrclk; input [1:0] selector; output result; reg [3:0] intreg; reg result, result_int; always @(posedge wrclk) begin if (ce) intreg = source; result = result_int; end always @(intreg or selector) case (selector) 2b00: result_int 2b01: result_int 2b10: result_int 2b11: result_int endcase endmodule

= = = =

intreg[0]; intreg[1]; intreg[2]; intreg[3];

An always block can be called from the dataflow area. Each always block is a sequentially executed program, but all always blocks run concurrently. In a sense, multiple always blocks resemble multiple programs that can run simultaneously. Always blocks communicate with each other via variables of type reg which are declared in the module. Also, the ports and wires defined in the module can be used in the always blocks.

Precision Synthesis Style Guide, 2011a Update2 November 2011

85

Verilog Language Features Always Blocks

This example describes a circuit that can load a source vector of 4 bits, on the edge of a write clock (wrclk), store the value internally in a register (intreg) if a chip enable (ce) is active, while it produces one bit of the register constantly (not synchronized). The bit is selected by a selector signal of 2 bits, and is clocked out through the register result. The description consists of two always blocks, one to write the value into the internal register and clock the output, and one to read from it. The two always blocks communicate via the register values intreg and result_int. The first always block is a synchronous block. As is explained later, the always block executes only if the event expression at the event control evaluates to true. In this case, the event expression evaluates to true when a positive edge occurs on the input wrclk (event expression posedge wrclk). Each time the edge occurs, the statements inside the always statement are executed. In this case, the value of the input source is loaded into the internal variable intreg only if ce is 1. If ce is 0, intreg retains its value. In synthesis terms, this translates into a D flip-flop, clocked on wrclk, and enabled by ce. Also, the intermediate output result_int is loaded into the output result (a D flip-flop clocked on wrclk). The second always block is a combinational block. In this case, the event expression evaluates to true when either intreg or selector changes. When this happens, the statements inside the always statement are executed, and the output result_int gets updated depending on the values of intreg and selector. Note that this leads to combinational behavior (essentially a multiplexer), since result_int only depends on intreg and selector, and each time either of these signals changes, result_int gets updated. The reason for separating the two always blocks is to avoid the creation of a register for the variable result_int. result_int must be of reg data type, because it is assigned in an always block, but it does not need to be registered logic. Not all constructs, or combinations of constructs, in an always block lead to behavior that can be implemented as logic. Precision RTL Synthesis supports empty always statements. Note that constants on the sensitivity list have no effect in simulation or synthesis. Any kind of expression inside a sensitivity list is legal in Verilog and is accepted by the synthesis tools. For synthesis, all the leaf level identifiers of the expression are considered to be in the sensitivity list, so some simulation mismatch might be seen after synthesis.
always @ (inp1[2:0] or 3'b011 or {a, b}) // allowed ......... .........

86

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Module Instantiation

Module Instantiation Technology-Specific Macros


In many cases, the target technology library includes a number of hard macros and soft macros that perform specific arithmetic logic functions. These macros are optimized for the target technology and have high performance. With Precision RTL Synthesis, it is possible to use component instantiation of soft macros or hard macros in the target technology. An added benefit is that the time needed for optimization of the whole circuit can be significantly reduced since the synthesis tools do not have to optimize the implementation of the dedicated functions any more. Suppose you want to add two 8 bit vectors, and there is an 8 bit adder macro available in your target technology. You could use the + operator to add these two vectors. The alternative is to define a component that has the same name and inputs and outputs as the hard macro you want to use. Instantiate the component in your Verilog description and connect the inputs and output to the their appropriate signals. Precision RTL Synthesis instantiates the hard macro without having to bother with the complicated optimization of the internal logic implemented by the macro. This speeds up the optimization process considerably. In the netlist produced by Precision RTL Synthesis, the macro appears as a black box that the downstream place and route tools recognize. If your arithmetic functions cannot be expressed in hard macros or soft macros immediately (for instance if you need a 32 bit adder, but only have an 8 bit adder macro), you could write a Verilog description that instantiates the appropriate number of these macros.

Precision Synthesis Style Guide, 2011a Update2 November 2011

87

Verilog Language Features Technology-Specific Macros

Module instantiation can be used to implement individual gates or cells, macros, or to add hierarchy to your design. Here is an example that generates an address for RAM and instantiates the RAM cells:
module scanner (reset, stop, load, clk, load_value, data) ; input reset, stop, load, clk; input [3:0] load_value; output [3:0] data; reg [4:0] addr; // Instantiate and connect 4 32x1-bit rams RAM_32x1 U0 (.a(addr), .d(load_value[0]), RAM_32x1 U1 (.a(addr), .d(load_value[1]), RAM_32x1 U2 (.a(addr), .d(load_value[2]), RAM_32x1 U3 (.a(addr), .d(load_value[3]),

.we(load), .we(load), .we(load), .we(load),

.o(data[0]) .o(data[1]) .o(data[2]) .o(data[3])

); ); ); );

// Generate the address for the rams always @(posedge clk or posedge reset) begin if (reset) addr = 5b0 ; else if (~stop ) addr = addr + 5b1 ; end endmodule module RAM_32x1 ( a, we, d, o); input [4:0] a; input we, d ; output o; endmodule

For this example, if the RAM module RAM_32x1 is a cell or macro in a library, Precision RTL Synthesis will implement that cell or macro in the output netlist. To do that, the library in which the cell or macro exists must be specified as the Technology in the Setup Design step. Precision RTL Synthesis supports empty named port connections, e.g.,
nd2 x1 (.a(f), .b());

88

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Technology-Specific Macros

Parameter Override During Instantiation of Module


Parameter overriding during module instantiation is supported by Precision RTL Synthesis.
module top (a, b); input [3:0] a; output [3:0] b; do_assign #(4) name (a, b); endmodule module do_assign (a, b); parameter n = 2; input [n-1:0] a; output [n-1:0] b; assign b = a; endmodule

Defparam Statement
When using the defparam statement, parameter values can be changed in any module instance throughout the design, provided the hierarchical name of the parameter is used. Note In Precision RTL Synthesis, the hierarchical name is restricted to single level only. This means that when the defparam statement is used, you can override any parameter value of an instance in the current module only. Example 3-1. Verilog Defparm
module top (a, b); input [3:0] a; output [3:0] b; wire top; do_assign name (a, b); defparam name.n = 4; endmodule module do_assign (a, b); parameter n = 2; input [n-1:0] a; output [n-1:0] b; assign b = a; endmodule

unconnected_drive and nounconnected_drive


These directives are specified as outside modules only. unconnected_drive takes either pull0 or pull1 as a parameter and causes all the unconnected input ports to be pulled down or

Precision Synthesis Style Guide, 2011a Update2 November 2011

89

Verilog Language Features Operators

up, according to the parameter. nounconnected_ drive restores the normal condition (where the unconnected input ports are connected to high-Z).
unconnected_drive pull1 module with_unconn_port (o, i); output o; input i; assign o = i; endmodule nounconnected_drive module test (i, o1, o2); input i; output o1, o2; with_unconn_port I1 (o1,); // o1 = 1 with_unconn_port I2 (o2, i); // o2 = i endmodule

Operators
This section describes the operators available for use in Verilog expressions.

Operands
An operand in an expression can be one of the following: Number Net (including bit-select and part-select) Register (including bit-select and part-select) A call to a function that returns any of the above

Bit-selects take the value of a specific bit from a vector net or register. Part-selects are a set of two or more contiguous bits from a vector net or register. For example:
... wire bit_int ; reg [1:0] part_int ; reg [3:0] intreg; bit_int = intreg[1] ;// bit-select of intreg assigned to bit_int part_int = intreg[2:1] ;// part-select of intreg assigned to part_int ...

90

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Operators

The operators supported by Precision RTL Synthesis are listed in Table 3-1. Table 3-1. Operators Supported by Precision RTL Synthesis Operator + < == != ! && || ~ & | ^ ^~ or ~^ & | ^ << >> ?: {} > * <= / >= Description arithmetic relational logical equality logic inequality logical negation logical and logical or bit-wise negation bit-wise and bit-wise inclusive or bit-wise exclusive or bit-wise equivalence reduction and reduction or reduction xor left shift right shift conditional concatenation

Arithmetic Operators
Precision RTL Synthesis supports the following arithmetic operators:
+ * /

If the bit value of any operand is X (unknown), then the entire resulting value is X. The / operator is supported in the case where the divisor is a constant and a power of two.

Precision Synthesis Style Guide, 2011a Update2 November 2011

91

Verilog Language Features Operators

Relational and Equality Operators


Precision RTL Synthesis supports the following relational and equality operators:
< > <= >= == !=

If the bit value of any operand is X (unknown), then the entire resulting value is X.
=== ===

and !== Operators are Treated as == and !=

and !== operators are treated as == and != for synthesis purposes if either one of the operands is nonconstant. If both the operands are constant, they can be used to compare metalogical values. In simulation, the difference between == and === is that one can compare metalogical characters exactly with === but not with ==. Any metalogical character causes the output of == to be unknown x. The difference between != and !== is the same.
module triple_eq_neq (in1, in2, O); output [10:0] O; input [2:0] in1, in2; assign O[0] = 3'b0x0 === 3'b0x0, // output is 1 O[1] = 3'b0x0 !== 3'b0x0, // output is 0 O[2] = 3'b0x0 === 3'b1x0, // output is 0 O[3] = 3'b0x0 !== 3'b1x0, // output is 1O[4]=in1===3'b0x0, // LHS is non constant so this // produces warning that comparison // metalogical character is // with zero. output is 0 O[5] = in1 !== 3'b0x0, // LHS is non constant so this // produces warning that comparison // with metalogical character is // zero.output is 1,because it // checks for not equality O[6] = in1 === 3'b010, // normal comparison O[7] = in1 !== 3'b010, // normal comparison O[8] = in1 === in2, // normal comparison O[9] = in1 !== in2, // normal comparison O[10] = 3'b00x === 1'bx; // output is 1 endmodule

Logical Operators
Precision RTL Synthesis supports the following logical operators:
! && ||

92

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Operators

Bit-Wise Operators
Precision RTL Synthesis supports the following bit_wise operators:
~ & | ^ ^~ ~^

These operators perform bit-wise operations on equivalent bits in the operands.

Reduction Operators
Precision RTL Synthesis supports the following reduction operators:
& | ^

These operators perform reduction operations on a single operand. Operations are performed on the first and second bits of the operand, then on the result of that operation with the third bit of the operand, until the limit of the vector is reached. The result is a single bit value. The following operators:
~& ~| ~^

are negations of the &, |, and ^ operators.

Shift Operators
Precision RTL Synthesis supports the following shift operators:
<< >>

Conditional Operator
The conditional operator statement has the following syntax:
conditional_expression ? true_expression : false_expression

Precision Synthesis Style Guide, 2011a Update2 November 2011

93

Verilog Language Features Operators

The result of this operation is true_expression if conditional_expression evaluates to true, and false_expression if false. In the following example, result is assigned the value of intreg[0] if sel = 2b00, otherwise result is assigned Z:
... output result ; reg [3:0} intreg ; wire [1:0] sel ; assign result = (~sel[0] && ~sel[1]) ? intreg[0] : 1bZ ; ...

Concatenation
The concatenation of bits from multiple expressions is accomplished using the characters { and }. For example, the following expressions are equivalent:
foo = {a[4:3], 1b0, c[1:0]} ; foo = {a[4], a[3], 1b0, c[1], c[0]} ;

For a = 5b11010, c = 5b10101, the result is foo = 5b11001.

signed and unsigned Attributes on Operators


and unsigned attributes change the type of a particular operator. Comparison between two bit vectors are always done unsigned, but if the functionality needs to be signed, a signed attribute can be used just after the comparator.
signed input [3:0] A, B; output o; assign o = A < signed B; // Signed comparator.

Similarly, an unsigned attribute can be used to perform an unsigned operation between two integers. The shift operators always do a logical shift. By using the signed directive, they can be made to do an arithmetic shift. Arithmetic right shift shifts in the sign bit and the left shift shifts in the least significant bit (e.g., 4b0001 << signed 1 produces 4b0011).

Operator Precedence
The operator precedence rules determine the order in which operations are performed in a given expression. Parentheses can be used to change the order in an expression. The operators

94

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Statements

supported by Precision RTL Synthesis are listed below in order from highest precedence to lowest, with operators on the same line having the same precedence.
+ * + << < == & ^ | && || ? : / >> > != ^~ ! ~ (binary) (binary) <= >= (unary)

~^

(ternary)

Statements
This section presents information on the use of if-else, case and for statements for specifying designs.

If-Else Statements
The if-else conditional construct is used to specify conditional decisions. As an example, here is the design from Procedural Assignments, with the multiplexer described with this construct instead of the case statement:
module mux_case (source, ce, wrclk, selector, result); input [3:0]source; input ce, wrclk; input [1:0]selector; output result; reg [3:0]intreg; reg result, result_int; always @(posedge wrclk) begin // if statement for chip enable on register if (ce) intreg = source; result = result_int; end always @(intreg or selector) begin

Precision Synthesis Style Guide, 2011a Update2 November 2011

95

Verilog Language Features Statements

// if-else construct for multiplexer functionality if (sel == 2b00) result_int = intreg[0] ; else if (sel == 2b01) result_int = intreg[1] ; else if (sel == 2b10) result_int = intreg[2] ; else if (sel == 2b11) result_int = intreg[3] ; end endmodule

This example describes a circuit that can load a source vector of 4 bits, on the edge of a write clock (wrclk), store the value internally in a register (intreg) if a chip enable (ce) is active, while it produces one bit of the register constantly (not synchronized). The bit is selected by a selector signal of 2 bits, and is clocked out through the register result.

Case Statements
If many conditional clauses have to be performed on the same selection signal, a case statement is a better solution than the if-else construct. The following example describes a traffic light controller (state machine with binary encoding):
module traffic (clock, sensor1, sensor2, red1, yellow1, green1, red2, yellow2, green2); input clock, sensor1, sensor2; output red1, yellow1, green1, red2, yellow2, green2; parameterst0 = 0, st1 = 1, st2 = 2, st3 = 3, st4 = 4, st5 = 5, st6 = 6, st7 = 7; reg [2:0] state, nxstate ; reg red1, yellow1, green1, red2, yellow2, green2; always @(posedge clock) state = nxstate; always @(state or sensor1 or sensor2) begin red1 = 1b0; yellow1 = 1b0; green1 = 1b0; red2 = 1b0; yellow2 = 1b0; green2 = 1b0; case (state) st0: begin green1 = 1b1; red2 = 1b1; if (sensor2 == sensor1) nxstate = st1; else if (~sensor1 & sensor2) nxstate = st2; end

96

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Statements

st1: begin green1 = 1b1; red2 = 1b1; nxstate = st2; end st2: begin green1 = 1b1; red2 = 1b1; nxstate = st3; end st3: begin yellow1 = 1b1; red2 = 1b1; nxstate = st4; end st4: begin red1 = 1b1; green2 = 1b1; if (~sensor1 & ~sensor2) nxstate = st5; else if (sensor1 & ~sensor2) nxstate = st6; end st5: begin red1 = 1b1; green2 = 1b1; nxstate = st6; end st6: begin red1 = 1b1; green2 = 1b1; nxstate = st7; end st7: begin red1 = 1b1; yellow2 = 1b1; nxstate = st0; end endcase end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

97

Verilog Language Features Statements

Case Statement and Multiplexer Generation


The case statement, as defined by the Verilog LRM, is evaluated by order, and the first expression to match the control expression is executed (during simulation). For synthesis, this implies a priority encoding. However, in many cases the case statement is used to imply a multiplexer. This is true whenever the case conditions are mutually exclusive (the control expressions equal only one condition at any given time). In Verilog, the case items can be non-constants also. In such a situation, Precision RTL Synthesis cannot automatically detect that the case statements are full or parallel, so you can include a Verilog directive that tells the tool whether it is full or parallel. Refer the topic Synthesis Directives on page 109 for details. Consider the following Verilog code fragment:
case (1b1) s[0]: o = a; s[1]: o = b; endcase

This code results in the equation:


o = s[0] * a + !s[0] * s[1] * b;

If parallel_case is specified, the following equation will be synthesized:


o = s[0] * a + s[1] * b;

This equation is simpler than the first. For a bigger case statement the amount of logic reduction can be significant. This cannot be determined automatically since the case items are nonconstants. Note Using these directives can cause simulation differences between behavioral and postsynthesis netlists.

98

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Statements

Automatic Full Case Detection


The casex statement below is full case (it covers all possible values 000 to 111). The default statement is not necessary and is ignored by the synthesis tool, resulting in a warning message. The synthesis tools also do full-case detection for normal case and casez statements.
input [2:0] sel; casex (sel) 3'b10x: ... 3'bx10: ... 3'bx11: ... 3'b00x: ... default: .... endcase

Precision RTL Synthesis does full coverage analysis for the if-then-else structure. The following example is considered a full if-then-else. The last else is ignored and a warning is issued.
wire [1:0] data; if (data == 2) ........... else if (data == 1) ........... else if (data == 3) ........... else if (data == 0) ........... else // Ignored for synthesis purpose endmodule

Automatic Parallel Case Detection


statements are priority-encoded by definition. Precision RTL Synthesis automatically detects parallel case and produce a warning message saying that case conditions are mutually exclusive. The following case statement is treated as parallel case.
casex input [2:0] sel; casex (sel) 3'b10x: ... 3'bx10: ... 3'bx11: ... 3'b00x: ... default: .... endcase

Precision Synthesis Style Guide, 2011a Update2 November 2011

99

Verilog Language Features Statements

Precision RTL Synthesis does parallel case detection for case and casez statements. It also extracts the parallelism of a mutually exclusive if-then-else structure as shown below.
wire [1:0] data; if (data == 2) ........... else if (data == 1) ........... else if (data == 3) ........... else if (data == 0) ...........

casex Statement
The casex statement is used when comparison to only a subset of the selection signal is desired. For example, in the following Verilog code only the three least significant bits of vect are compared to 001. The comparison ignores the three most significant bits.
casex (vect) 6bXXX001 : <statement> ; // this statement is executed if vect[2:0] = 3b001 endcase

casez Supported
casez is used in Verilog to specify don't care bits of the case tags. The zs in the case tags are not compared when a comparison between the case expression sel and the tags is done. ... casez (sel) 3'b10z: ... 3'bz10: ... 3'bz11: ... 3'b00z: ... default: .... endcase

case and default Statements


Precision RTL Synthesis allows the default statement to appear anywhere in a case, casez, or casex statement, and supports the case statement with only one default entry.

100

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Statements

Note For additional information on the handling of default statements during optimization, see Advanced FSM Optimization on page 296 and How Precision Implements a Safe FSM on page 297.

for Statements
for loops are used for repetitive operations on vectors. In the following example, each bit of an

input signal is ANDed with a single bit enable signal to produce the result:
... input clk ; reg [4:0] input_signal, result ; reg enable ; integer i; always @ (posedge clk) for (i = 0; i < 5; i = i + 1) result[i] = enable & input_signal[i] ; ...

for

loops are supported if they are bound by constants. for loops are also supported if they contain a @ posedge clk statement which prevents infinite combinatorial loops.

Precision Synthesis Style Guide, 2011a Update2 November 2011

101

Verilog Language Features Statements

Disable Statement
The disable statement disables a named block or a task. Disabling of one block from another block is supported only if the second block is contained in the first one. Below is an example of disabling a named block.
module add_up_to (up_to_this, the_out); input [3:0] up_to_this; output the_out; reg [7:0] the_out; integer i; always @ (up_to_this) begin: blk the_out = 0; for (i = 0; i < 16; i = i + 1) begin the_out = the_out + i; if (i == up_to_this) disable blk; end end endmodule //Below is an example of disabling a task. module add_up_to (up_to_this, the_out); input [3:0] up_to_this; output the_out; reg [7:0] the_out; always @ (up_to_this) begin add_upto_this (up_to_this, the_out); end task add_upto_this; input [3:0] up_to_this; output [7:0] the_out; integer i; begin the_out = 0; for (i = 0; i < 16; i = i + 1) begin the_out = the_out + i; if (i == up_to_this) disable add_upto_this; end end endtask endmodule

102

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Functions and Tasks

forever, repeat, while and Generalized Form of for Loop


forever, repeat, while, and the generalized form of the for loop are supported as long as they satisfy the conditions of for loops. The following forever example, is a counter with synchronous reset. module forever_example (clk, reset, out); input clk, reset; output [3:0]out; reg [3:0]out; always begin @(posedge clk) out = 0; begin: for_ever forever begin: name @(posedge clk) if (reset) disable for_ever; out = out + 1; end end end endmodule module repeat_example (i, o); input i; output o; reg o; always @ (i) begin o = i; repeat (4'b1011) o = ~o; // o = ~i end endmodule

If any loop construct is NOT bound by constants or by clock events, then Precision RTL Synthesis issues the iteration limit reached error.

Functions and Tasks


Pieces of Verilog can be grouped together in functions and tasks, which can then be used as subprograms in the Verilog code. This is useful for repeated code, or for readability of the main module. Tasks and functions appear similar, but are used in different ways. A task is a subprogram with inputs and outputs, and replaces any piece of verilog code in a module. Expressions in a task can be both combinational and sequential.

Precision Synthesis Style Guide, 2011a Update2 November 2011

103

Verilog Language Features Functions and Tasks

Functions have only inputs and returns a value by its name. Functions are purely combinational.

Functions
Functions are defined inside a module and can be freely used once they are defined. Functions are always used in an expression, behavioral or dataflow:
assign y = func(a,b);

or
x = func(z);

An example of a function is given below.


module calculator ( a, b, clk, s, operator ); input [7:0] a, b; input clk; input [1:0] operator; output [7:0] s; reg [7:0] s; parameter ADD = 2b00, SUB = 2b01, MUL = 2b10; function [15:0] mult; input [ 7:0] a, b ; reg [15:0] r; integer i; begin if (a[0] == 1) r = b; else r = 0; for (i = 1; i < 7; i = i + 1) begin if (a[i] == 1 ) r = r + b << i ; end mult = r; end endfunction always @ (posedge clk) begin case (operator) ADD: s = a + b ; SUB: s = a - b ; MUL: s = mult(a,b); endcase end endmodule

104

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Functions and Tasks

Tasks
Tasks are always displayed as statements:
my_task(a,b,c,d);

Precision RTL Synthesis supports empty tasks. An example of a task is presented below.
task demux ( state, load, bait, enable, ready, write, read ); input [2:0] state; output load, bait, enable, ready, write, read; parameter LOAD = 3b000, WAIT = 3b100, ENAB = 3b110, READ = 3b111, WRIT = 3b011, STRO = 3b001; case (state) LOAD: {state, WAIT: {state, ENAB: {state, READ: {state, WRIT: {state, STRO: {state, endcase endtask

load, bait, enable, ready, write, read} = 6b100000; load, bait, enable, ready, write, read} = 6b010000; load, bait, enable, ready, write, read} = 6b001000; load, bait, enable, ready, write, read} = 6b000100; load, bait, enable, ready, write, read} = 6b000010; load, bait, enable, ready, write, read} = 6b000001;

Inout Ports in Task


Precision RTL Synthesis supports inout ports in a task statement. Any value passed through inout ports can be used and modified inside the task.
module inoutintask (i, o1, o2); input i; output o1, o2; reg r, o1, o2; task T ; inout io; output o; begin o = io; io = ~io; end endtask

Precision Synthesis Style Guide, 2011a Update2 November 2011

105

Verilog Language Features System Task Calls

always @ (i) begin r = i; T (r, o1); // o1 = i, r = ~i o2 = r; // o2 = ~i; end endmodule

Access of Global Variables from Functions and Tasks


Global variables can be accessed for both reading and writing.
module x (clk, reset, i1, i2, o); input clk, reset, i1, i2; output o; reg o; reg [1:0] state; task T; //without any port begin case (state) 2'b00: o = i1; 2'b01: o = i2; 2'b10: o = ~i1; 2'b11: o = ~i2; endcase state = state + 1; // next state end endtask always @ (posedge clk or posedge reset) if (reset) begin state = 0; o = 0; end else T; endmodule

System Task Calls


Precision RTL Synthesis accepts system task calls. System task calls are ignored and a warning is issued.

System Function Calls


Precision RTL Synthesis accepts system function calls. The value 0 is assumed for system function calls and a warning is issued.

106

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Initial Statement

Initial Statement
Precision RTL Synthesis accepts initial statements. The actual value is ignored.

Compiler Directives
Verilog supports a large list of compiler directives. Most of them are useful for simulation, but are meaningless for synthesis purposes. A few directives are supported by the synthesis tools, and those directives have to do with macro substitution and conditional compilation. Following is a list of these directives:
define ifdef else endif include signed unsigned unconnected_drive nounconnected_drive

Verilog Issues and Limitations


Verilog is a language that has been developed for simulation purposes. Synthesis was not an issue in the development of the language. As a result, there are a number of Verilog constructs that cannot be synthesized. There has been very little written that explains which constructs cannot be synthesized into logic circuits and why. This chapter provides explanations on why certain Verilog constructs cannot be synthesized into logic circuits and what changes have to be made to reach the intended behavior to obtain a synthesizable Verilog description. Some obvious restrictions of the language are first presented, followed by a list summarizing Verilog syntax and semantic restrictions for Mentor Graphics synthesis tools. In addition, some guidelines are presented that should enable you to write Verilog that is easy to synthesize and give you a feeling for synthesis complexity problems you might introduce when you write your Verilog design.

Comparing With X and Z


Consider the Verilog modeling case where an if clause should be entered if a part of a vector has a particular value. The rest of the vector does not really matter. You might want to write this as follows:
if (vect == 6bXXX001) begin ...

Precision Synthesis Style Guide, 2011a Update2 November 2011

107

Verilog Language Features Verilog Issues and Limitations

The user intention is to do a comparison to 001 (the right most three bits) and forget about the left three bits. However, Verilog defines comparison on vectors as the AND of comparison of each individual element. Also, comparison of two elements is only true if both elements have exactly the same value. This means that in order for this condition to be true, the three left most bits have to be 'X'. But in logic synthesis, a bit can only be '0' or '1', so the condition is always be false. In fact, this condition is not doing what was intended for simulation as well, since if any of the left most three bits does not have the value 'X' explicitly, the result is false. However, comparison to 'X' is allowed using the casex construct. This is implemented in the following manner:
casex (vect) 6bXXX001 : endcase

<statement> ;

In this case, only the three least significant bits of vect are compared to "001". The comparison ignores the three most significant bits.

Variable Indexing of Bit Vectors


Precision RTL Synthesis supports variable indexing of a vector. The limitation is that only variable indexing of the form bit select is supported. Or more specifically, variable indexing of the form part select is not supported because it is not a synthesizable construct. The semantics of variable indexing varies depending on whether the variable indexing is done on the left hand side of an assignment or on the right hand side of the assignment. The righthand side variable indexing generates a multiplexer controlled by the index. The left-hand variable indexing generates a de-multiplexer controlled by the index. set of decoders enabling. The following example shows both examples.
module tryit (input_bus, in_bit, control_input, output_bus, out_bit); input [3:0] input_bus ; input [1:0] control_input ; input in_bit ; output [3:0] output_bus ; output out_bit ; reg [1:0] control_input ; reg [3:0] input_bus, output_bus ; reg in_bit, out_bit ; always @ (control_input or input_bus or in_bit) begin out_bit = input_bus [control_input] ; output_bus [control_input] = in_bit ; end endmodule

108

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Synthesis Directives

Synthesis Directives
Verilog pragmas are also called synthesis directives.

parallel_case and full_case directives


and full_case directives are allowed as synthesis directive on a case by case basis. Precision RTL Synthesis detects the true full and parallel cases automatically. However, there are cases (like onehot encoded state machine) that are not inherently parallel/full, but the environment guarantees that the case statement is parallel and/or full. In such a condition the following two synthesis directives are very useful.
parallel_case input [3:0] inp_state; // example of onehot encoded machine case (1'b1) // pragma parallel_case full_case inp_state[0]: ....... inp_state[1]: ....... inp_state[2]: ....... inp_state[3]: ....... endcase

translate_off and translate_on directives


translate_off and translate_on synthesis directives are allowed to comment out a portion of code that you may want to retain for some purpose other than synthesis. // code for synthesis // pragma translate_off $display (.....); // not for synthesis // pragma translate_on // code for synthesis endmodule

State and S0, S1, S2, S3 are of enum type ee1. They cannot be used for any boolean or arithmetic operation. Bit or port select from state or its values is also considered an error. Enumerated type module ports are not allowed.

attribute directive
You can set attributes on design objects to refine and control the synthesis process. For example, by setting one of the pre-defined Precision inff, outff and triff attributes on a signal to true, you can improve the timing performance of the I/O by moving the first/last register in the path to the pad.

Precision Synthesis Style Guide, 2011a Update2 November 2011

109

Verilog Language Features Synthesis Directives

Note An attribute can only be set on an object after the object is declared. The syntax of this directive is as follows:
// pragma attribute <object_name> <attribute_name> <attribute_value>

Verilog 2001 syntax is also supported:


(* synthesis, <attribute_name> [ = <optional_value> ] *)

As a synthesis directive inside a declaration:


wire [1:0] /* synthesis preserve_signal = 1 */ my_wire ;

//example module expr (a, b, c, out1, out2); input [15:0] a, b, c; output [15:0] out1, out2; assign out1 = a + b; assign out2 = b + c; // pragma attribute out1 modgen_sel fastest endmodule

Syntax and Semantic Restrictions


The following list provides a summary of the syntax and semantic restrictions of the Precision RTL Synthesis Verilog HDL parser.
UDP

primitives block

specify real

variables and constants statement net types

initial

tri0, tri1, tri1, tri1, tri1, time

data type

Named events and event triggers The following gates: pulldown, pullup, nmos, mmos, pmos, rpmos, cmos,
rcmos, tran, rtran, tranif0, rtranif0, tranif1, rtranif1 wait

statements

Parallel block, join and for.

110

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Verilog 2001 Support

System task enable and system function call


force

statement statement

release

Blocking assignment with event control Named port specification (not to be confused with passing arguments by name, which is supported) Concatenation in port specification Bit selection in port specification Procedural assign and de-assign Supported Verilog Features Edge triggers on sensitivity list must be single bit variable, or array indexing expression. Indexing of parameters is not allowed. Loops must be bounded by constants or contain (@ posedge clk) statement. Supported Verilog Features Delay and delay control. vectored declaration

Verilog 2001 Support


The Verilog-2001 Standard was approved by the IEEE in June of 2000 and includes enhancements to the previously existing Verilog standard in the following areas: Enhance the Verilog language to help with today's deep-submicron and intellectual property modeling issues Ensure that all enhancements were both useful and practical, and that simulator and synthesis vendors would implement Verilog-2001 in their products Correct any ambiguities in the Verilog-1995 standard (IEEE 1364-1995)

Verilog 2001 expands the construct set of Verilog - 1995 but does not replace or change the behavior of previously implemented constructs. You may seamlessly mix new and previously existing constructs.

Supported Verilog 2001 Constructs


Precision Synthesis offers support for the following Verilog-2001 constructs:

Precision Synthesis Style Guide, 2011a Update2 November 2011

111

Verilog Language Features Verilog 2001 Support

Signed arithmetic extensions Comma-separated sensitivity list Combinational logic sensitivity token Combined port / data type declarations ANSI-style port lists Power Operator Automatic width extension past 32 bits Register declaration with initialization

Detailed Description
Combinational logic sensitivity token
To properly model combinational logic using a Verilog always procedure, the sensitivity list must include all input signals used by that block of logic. In large, complex blocks of combinational logic, it is easy to inadvertently omit an input from the sensitivity list, which can lead to simulation and synthesis mismatches. Verilog-2000 adds a new wild card token, @*, which represents a combinational logic sensitivity list. The @* token indicates that the simulator or synthesis tool should automatically be sensitive to any values used by the procedure in decisions or in expressions on the right-hand side of assignment statements. In the following example, the @* token will cause the procedure to automatically be sensitive to changes on sel, a or b.
always @* //combinational logic sensitivity if (sel) y = a; else y = b;

Combined port / data type operator


Verilog requires that signals connected to the input or outputs of a module have two declarations: the direction of the port, and the data type of the signal. In Verilog-1995, these two declarations had to be done as two separate statements. Verilog-2000 adds a simpler syntax, by combining the declarations into one statement.
module mux8 (y, a, b, en); output reg [7:0] y; input wire [7:0] a, b; input wire en;

112

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Verilog 2001 Support

Power Operator
Verilog-2001 adds a power operator, represented by an ** token. This operator preforms similar functionality as the C pow() function. It will return a real number if either operand is a real value, and an integer value if both operands are integer values. One practical application of the power operator is to calculate values such as 2n. For example:
always @(posedge clock) result = base ** exponent;

Signed Arithmetic Extensions


For integer math operations, Verilog uses the data types of the operands to determine if signed or unsigned arithmetic should be performed. If either operand is unsigned, unsigned operations are performed. To perform signed arithmetic, both operands must be signed. In Verilog-1995, the integer data type is signed, and the reg and net data types are unsigned. A limitation in Verilog- 1995 is that the integer data type has a fixed vector size, which is 32-bits in most Verilog simulators. Thus, signed integer math in Verilog-1995 is limited to 32-bit vectors. The Verilog-2000 standard adds five enhancements to provide greater signed arithmetic capability: Reg and net data types can be declared as signed Function return values can be declared as signed Integer numbers in any radix can be declared as signed Operands can be converted from unsigned to signed Arithmetic shift operators have been added

The Verilog-1995 standard has a reserved keyword, signed, but this keyword was not used in Verilog-1995. Verilog-2000 uses this keyword to allow reg data types, net data types, ports, and functions to be declared as signed types. Some example declarations are:
reg signed [63:0] data; wire signed [7:0] vector; input signed [31:0] a; function signed [128:0] alu;

In Verilog-1995, a literal integer number with no radix specified is considered a signed value, but a literal integer with a radix specified is considered an unsigned value. Verilog-2000 adds an additional specifier, the letter 's', which can be combined with the radix specifier, to indicate that the literal number is a signed value.
16'hC501 //an unsigned 16-bit hex value 16'shC501 //a signed 16-bit hex value

In addition to being able to declare signed data types and values, Verilog-2000 adds two new system functions, $signed and $unsigned. These system functions are used to convert an unsigned value to signed, or vice-versa.

Precision Synthesis Style Guide, 2011a Update2 November 2011

113

Verilog Language Features Verilog 2001 Support reg [63:0] a; //unsigned data type always @(a) begin result1 = a / 2; //unsigned arithmetic result2 = $signed(a) / 2; //signed arithmetic end

One more signed arithmetic enhancement in Verilog-2000 is arithmetic shift operators, represented by >>> and <<< tokens. An arithmetic right-shift operation maintains the sign of a value, by filling with the sign-bit value as it shifts. For example, if the 8-bit variable D contained 8'b10100011, a logical right shift and an arithmetic right shift by 3 bits would yield the following:
D >> 3 //logical shift yields 8'b00010100 D >>> 3 //arithmetic shift yields 8'b11110100

Comma-Separated Sensitivity List


Verilog-2000 adds a second way to list signals in a sensitivity list, by separating the signal names with commas instead of the or keyword. The following two sensitivity lists are functionally identical:
always @(a or b or c or d or sel) always @(a, b, c, d, sel)

The new, comma-separated sensitivity list does not add any new functionality. It does, however, make Verilog syntax more intuitive, and more consistent with other signal lists in Verilog.

ANSI-Style Port Lists


Verilog-1995 uses the older Kernighan and Ritchie C language syntax to declare module ports, where the order of the ports is defined within parentheses, and the declarations of the ports are listed after the parentheses. Verilog-1995 tasks and functions omit the parentheses list, and use the order of the input and output declarations to define the input/output order. Verilog-2000 updates the syntax for declaring inputs and outputs of modules, tasks, and functions to be more like the ANSI C language. That is, the declarations can be contained in the parentheses that show the order of inputs and outputs.
module mux8 ( output reg [7:0] y, input wire [7:0] a, input wire [7:0] b, input wire en ); function [63:0] alu ( input [63:0] a, input [63:0] b, input [7:0] opcode );

Automatic Width Extension Past 32 Bits


With Verilog-1995, assigning an unsized high-impedance value (e.g.: 'bz) to a bus that is greater than 32 bits would only set the lower 32 bits to high-impedance. The upper bits would be set to
114
Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Verilog 2001 Support

0. To set the entire bus to high-impedance requires explicitly specifying the number of high impedance bits. For example:
Verilog-1995: parameter WIDTH = 64; reg [WIDTH-1:0] data; data = 'bz; //fills with 'h00000000zzzzzzzz data = 64'bz; //fills with 'hzzzzzzzzzzzzzzzz

The fill rules in Verilog-1995 make it difficult to write models that are easily scaled to new vector sizes. redefinable parameters can be used to scale vector widths, but the Verilog source code must still be modified to alter the literal value widths used in assignment statements. Verilog-2000 changes the rule for assignment expansion so that an unsized value of Z or X will automatically expand to fill the full width of the vector on the left-hand side of the assignment.
Verilog-2000: parameter WIDTH = 64; reg [WIDTH-1:0] data; data = 'bz; //fills with 'hzzzzzzzzzzzzzzzz

This Verilog-2001 enhancement is not backward compatible with Verilog-1995. However, the IEEE standards group felt the Verilog-1995 behavior was a bug in the standard that needed to be corrected. It is expected that all existing models with greater than 32-bit busses have avoided this bug by explicitly specifying the vector sizes. Therefore, there should not be any compatibility problems with existing models.

Register Declaration with Initialization


Verilog-2000 adds the ability to initialize variables at the time they are declared, instead of requiring a separate initial procedure to initialize variables. The initial value assigned to the variable will take place within simulation time zero, just as if the value had been assigned within an initial procedure.
Verilog-1995: reg clock; initial clk = 0; Verilog-2000: reg clock = 0;

In-Line Parameter Passing


Verilog-1995 has two methods of redefining parameters within a module instance: explicit redefinition using defparam statements, and in-line implicit redefinition using the # token as part of the module instance. The latter method is more concise, but because it redefines parameter by their declaration position, it is error-prone and is not self-documenting. The following example illustrates the two Verilog-1995 methods for parameter redefinition.
module ram (...);

Precision Synthesis Style Guide, 2011a Update2 November 2011

115

Verilog Language Features Verilog 2001 Support parameter WIDTH = 8; parameter SIZE = 256; ... endmodule module my_chip (...); ... //Explicit parameter redefinition by name RAM ram1 (...); defparam ram1.SIZE = 1023; //Implicit parameter redefintion by position RAM #(8,1023) ram2 (...); endmodule

Verilog-2001 adds a third method to redefine parameters, in-line explicit redefinition. This new method allows inline parameter values to be listed in any order, and document the parameters being redefined.
//In-line explicit parameter redefintion RAM #(.SIZE(1023)) ram2 (...);

File and Line Compiler Directives


Verilog tools need to keep track of the line number and the file name of Verilog source code. This information can be used for error messages, and can be accessed by the Verilog PLI. If Verilog source is pre-processed by some other tool, however, the line and file information of the original source code can be lost. Verilog-2001 adds a `line compiler directive, which can be used to specify the original source code line number and file name. This allows the location in an original file to be maintained if another process modifies the source, such as by adding or removing lines of source text.

Attributes
The Verilog language was originally created as a hardware description language for digital simulation. As tools other than simulation have adopted Verilog as a source input, there has been a need for these tools to be able add tool specific information to the Verilog language. In Verilog- 1995, there was no mechanism for adding tool-specific information, which led to nonstandard methods, such as hiding synthesis commands in Verilog comments. Verilog-2001 adds a mechanism for specifying properties about objects, statements and groups of statements in the HDL source. These properties are referred to as attributes. Attributes are used by Precision Synthesis to apply optimization directives and thus control the results. An attribute is contained within the tokens (* and *). Attributes can be associated with all instances of an object, or with a specific instance of an object. Attributes can be assigned values, including strings, and attribute values can be re-defined for each instance of an object. Verilog-2001 does not define any standard attributes. A complete list of supported attributes is provided in the Precision RTL Synthesis Reference Manual. An example is provided below:
(* parallel case *) case (1'b1) //1-hot FSM state[0]: ... state[1]: ... state[2]: ...

116

Precision Synthesis Style Guide, 2011a Update2 November 2011

Verilog Language Features Verilog 2001 Support endcase

Enhanced Conditional Compilation


Verilog-1995 supports limited conditional compilation: `ifdef, `else, `endif, and `undef. Verilog-2001 adds two new directives: `ifndef and `elsif.

Precision Synthesis Style Guide, 2011a Update2 November 2011

117

Verilog Language Features Verilog 2001 Support

118

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 4 SystemVerilog Language Features


This section describes SystemVerilog constructs supported in Precision as well as an introduction to the key features in the new language extension.

SystemVerilog Support in Precision


The synthesizable subset of SystemVerilog is supported in all versions of Precision (RTL, RTL Plus, and Physical) and strictly follows the syntax described in the IEEE Std 1800-2005 specification. Supported constructs are shown in Table 4-1. Refer to the IEEE Std 1800-2005 for details on each construct as well as the information presented in this section. Table 4-1. Supported SystemVerilog Constructs IEEE 1800-2005 Literal Values 3.3 3.6 3.7 3.8 Data Types 4.3 4.5 4.9 4.10 4.11 4.13 4.14 4.16 4.17 Arrays 5.2 5.3 Packed and unpacked arrays Multiple dimensions Integer data types Void data type User-defined types Enumerations Structures and unions (packed unions only) Singular and aggregate types Casting Bit-stream casting Default attribute type Integer and logic literals String literals Array literals Structure literals SystemVerilog Construct

Precision Synthesis Style Guide, 2011a Update2 November 2011

119

SystemVerilog Language Features SystemVerilog Support in Precision

Table 4-1. Supported SystemVerilog Constructs (cont.) 5.4 5.5 5.7 5.8 Data Declarations 6.3 6.4 6.5 6.6 6.7 6.8 6.9 8.3 8.4 8.5 8.7 8.8 8.9 8.10 8.11 8.12 8.13 8.15 10.3 10.4 10.5 10.6 10.8 10.10
120

Indexing and slicing of arrays Array querying functions Array assignment Arrays as arguments Constants Variables Nets Scope and lifetime Nets, regs, and logic Signal aliasing Type compatibility Assignment operators Operations on logic and bit types Wild equality and wild inequality Size Sign Operator precedence and associativity Buit-in Methods Static Prefixes Concatenation Assignment patterns Aggregate expressions Blocking and nonblocking assignments Selection statements Loop statements (except foreach) Jump statements Named blocks and statement labels Event control
Precision Synthesis Style Guide, 2011a Update2 November 2011

Operators and Expressions

Procedural Statements

SystemVerilog Language Features SystemVerilog Support in Precision

Table 4-1. Supported SystemVerilog Constructs (cont.) Processes 11.2 11.3 11.4 11.5 12.2 12.3 12.4 12.5 Hierarchy 19.2 19.3 19.5 19.8 19.11 19.12 Interfaces 20.3 20.4 20.6 20.7 20.9 22.4 22.7 23.2 23.3 Ports in interfaces Modports Tasks and functions in interfaces Parameterized interfaces Acces to interface objects Expression size system function Array querying system functions `define macros `include Packages Compilation unit support Module declarations Port declarations (all types) Module instances Port connection rules Combinational logic Latched logic Sequential logic Continuous assignments Tasks Functions Task and function argument passing Import and export function

Tasks and Functions

System Tasks and System Functions

Compiler Directives

Precision Synthesis Style Guide, 2011a Update2 November 2011

121

SystemVerilog Language Features How Precision Reads SystemVerilog files

How Precision Reads SystemVerilog files


Precisions default setting assumes that any file with a *.sv extension is a SystemVerilog file while any file with a *.v is a Verilog 2001 file. Users commonly use the *.v extension when writing Verilog and SystemVerilog files. In that case, Precisions file settings must be changed to assume that all *.v files will obey SystemVerilog syntax. Because SystemVerilog is largely backward compatible with Verilog, purely Verilog files will be read correctly. This can be done with the following command,
setup_design -language_syntax_verilog=sv

or via the GUI as shown in Figure 4-1, SystemVerilog File Settings. Figure 4-1. SystemVerilog File Settings

122

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Compilation Unit Scope Settings

Compilation Unit Scope Settings


A compilation-unit scope, as described in the IEEE 1800-2005 specification (section 19.3), is a scope that is local to the compilation unit. It contains all declarations that lie outside of any other scope. SystemVerilog supports separate compilation using compiled units. Precision compiles each SystemVerilog into its own compilation unit. The declarations in each compilation unit scope are accessible only within its corresponding source file. The compilation-unit scope allows users to easily share declarations (e.g., types) across the unit of compilation, but without having to declare a package from which the declarations are subsequently imported. Thus, the compilation-unit scope is similar to an implicitly defined anonymous package. Because it has no name, the compilation-unit scope cannot be used with an import statement.

Altering the Compilation Unit Scope


The Precision Synthesis tool provides two use models for defining which files constitute a compilation unit. The `include statement can be used to include the contents of a header file into the compilation unit scope. 1. Each file is a separate compilation unit in which case the declarations in each compilation-unit scope are accessible only within its corresponding file (default flow). 2. All files on a given compilation command line make a single compilation unit in which case the declarations within those files are accessible anywhere else within the constructs defined within those files. To enable this setting, enter the following command in Precision:
setup_design -all_file_cunit_scope=true

Note Using a single compilation unit scope will cause Precision Synthesis to check for more than one inclusion (`include) of a header file and issue an error message when this condition is detected. An example of this is shown in One Compile Unit Scope Error Example 1 on page 124. In Compilation Unit Scope Example 1 on page 123 and Compilation Unit Scope Example 2 on page 124, the typedef declaration T can be made visible in module "middle" (file named middle.sv) using the -all_file_cunit_scope=true option.

Compilation Unit Scope Example 1


In this example, module named "top" has a type definition "T" that is visible because it is declared in the compilation unit scope of file top.sv. Module named "middle" is defined in file middle.sv. The type definition "T" will not be visible to module "middle" because "T" is declared in different compilation unit scope.

Precision Synthesis Style Guide, 2011a Update2 November 2011

123

SystemVerilog Language Features Compilation Unit Scope Settings File: top.sv typedef int T; module top; T in1; // T visible here T out; assign out = in1; endmodule File: middle.sv module middle; T in1; // cannot refer to T as declared in compilation // unit scope of file top.sv T out; endmodule

Compilation Unit Scope Example 2


In this example, module named "middle" is defined in file middle.sv, cannot refer to type definition "T" because the typedef int T statement is in the compilation unit scope of file top.sv.
File: typedef.h typedef logic T; File: top.sv `include typedef.h module top; T in1; T out; endmodule File: middle.sv module middle; T in1; T out; endmodule

//cannot refer to T as declared in Compilation //unit scope of file top.sv

This behavior is the default in Precision.

Normal Errors Related to Compilation Unit Scope


When option -all_file_cunit_scope is true.

One Compile Unit Scope Error Example 1


Multiple declarations or multiple `include of the same header file leads to an error. Here is an example of such multiple references.
File: top.sv `include typedef.h module top; endmodule

124

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Compilation Unit Scope Settings File: middle.sv `include typedef.h module middle; endmodule

Correction: This can be corrected by either defining `include typedef.h once, in case of single compilation unit scope, or using a guarded macro.

One Compile Unit Scope Error Example 2


In this example, the file "top.sv" is compiled first; in module named "top" TYPDEF_H is defined and then the typdef declaration "T" becomes visible. Secondly, file middle.sv is compiled and because TYPEDEF_H is already defined, the type definition "T" does not occur in the scope of middle.sv.
File: typedef.h `ifndef TYPEDEF_H `define TYPEDEF_H typedef int T `endif File: top.sv module top; `include typedef.h T in1; endmodule File: middle.sv `include typedef.h module middle; T in1; endmodule

//not visible here

Correction: This can be corrected by moving the `include to only compilation unit scope as given below
File: top.sv `include typedef.h module top; endmodule File: middle.sv `include typedef.h T in1; // visible here as T is declared in single // compilation unit scope module middle; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

125

SystemVerilog Language Features Compilation Unit Scope Settings

When Option -all_file_cunit_scope=false (Default in Precision)


Default Compile Unit Scope Error Example 1
In this case each file will have a separate compilation unit scope, therefore modules "top" and "middle" will have in1 variable with different enum typedef declaration. SystemVerilog allows only the same enum type can be assigned to each other, so instantiation of "middle" in "top" results in connecting different enum declarations, resulting in an error message. Similar issues can arise in the case of unpacked structures and unions.
File: typedef.h `ifndef TYPEDEF_H `define TYPEDEF_H typedef enum logic [1:0] {RED, GREEN, BLUE, BLACK} T; `endif File: top.sv `include typedef.h module top; T in1; middle m1(.in1(in1)); // incorrect connection of in1 as enum variables // of different typedef. endmodule File: middle.sv `include typedef.h module middle(in1); T input in1; endmodule

Correction: Set the option -all_file_cunit_scope=true which will create single typedef declaration in compilation unit scope for "T" and result in the enum variables being the same type.

New Design Rules for Packages and Compilation Unit Scope


Packages are not permitted to refer to compilation unit items. An example of such of reference is the following small design
typedef int T; package p; T foo; endpackage

Packages may depend on other packages, so compilation unit declarations that packages need should be factored into separate packages. For example, the previous design should be changed as shown:
package shared_types;

126

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs typedef int T; endpackage package p; import shared_types::*; T foo; endpackage

It is important to note that "import" statements immediately before a package declaration are compilation unit imports and not imports into the subsequent package. Package references may not look into such an import. For example, the following approach will not work:
package shared_types; typedef int T; endpackage; import shared_types::*; package p; T foo; // cannot refer to T since it is imported into // the compilation unit, not into the package endpackage

Designs must be factored so that packages do not refer to anything in the compilation unit.

Basic Language Constructs


This section provides an introduction to basic language constructs in SystemVerilog. For this, you are required to know the basics of Verilog constructs. For more information on the Verilog language, refer to the Verilog Hardware Description Language Reference Manual, published by Open Verilog International. The following basic language constructs in SystemVerilog are described in detail: Literal Values Data Types Arrays Data Declarations Attributes Operators and Expressions Procedural Statements and Control flow Processes Tasks and Functions

Precision Synthesis Style Guide, 2011a Update2 November 2011

127

SystemVerilog Language Features Basic Language Constructs

Hierarchy Interfaces Compiler Directives Unpacked Array Concatenation Foreach Loop Support Removing Text Substitution Macros Set Membership Operator (Inside Operator)

Precision synthesizes all levels of abstraction and minimizes the amount of logic needed resulting in a final netlist description in the technology of your choice.

Literal Values
Literal value types that are supported in System Verilog include: Integer Logic Real String of type packed array Array Structure Literals Note The SystemVerilog Time literal is not supported in Precision Synthesis. Numbers in Verilog can be either constants or parameters. Constants can be either sized or unsized. Either one can be specified in binary, octal, hexadecimal, or decimal format. Name binary octal decimal hexcadecimal Prefix b o d h Legal Characters 01xXzZ_? 0-7xXzZ_? 0-9_ 0-9a-fA-FxXzZ_?

If a prefix is preceded by a number, this number defines the bit width of the number, for instance, 8b 01010101. If no such number exists, the number is assumed to be 32 bits wide. If no prefix is specified, the number is assumed to be 32 bits decimal.

128

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Special characters in numbers: _


x, X z, Z, ?

A separator to improve readability. Unknown value. Tri-state value.

Examples
334 32b101

32 bits wide decimal number 32 bits wide binary number (zero left filled) 3 bits wide binary number (i.e. 011) 20 bits wide hexadecimal number 10 bits wide all tri-state

3b011 20hf_ffff 10bZ

Integer and Logic Literals (sized and unsized)


Example
module literal1(output int i1); assign i1 = 32d4; logic [1:0][1:0] s1 logic [1:0][3:0] s2 logic [1:0][7:0] l1 logic [1:0][7:0] l2 logic [1:0][7:0] l3 logic [1:0][7:0] l4 ...... endmodule //32b00000000000000000000000000000100 4bzzzz; 8d1; // 8b00000001 0; // sets all bits to 0 1; // sets all bits to 1 x; // sets all bits to x z; // sets all bits to z

= = = = = =

Real Literals
Example
module literal2 #(parameter PI = 3.14) (input bit [2:0] sel , output integer out1); parameter R = 134.09e-2; integer r1 = 2.1-2.3/1.2+1.7*3; integer r2 = 2.1e-30+3.1E31-7.902e33; integer r3 = (5.1e+31/2.3E34)*4.56+7.03E1; integer r4 = 2*PI*R; integer r5 = 2.4; // will be rounded off to nearest integer 2 integer r6 = 2.8; // will be rounded off to nearest integer 3 integer r7 = 2.5; // will be rounded off to 3 always_comb

Precision Synthesis Style Guide, 2011a Update2 November 2011

129

SystemVerilog Language Features Basic Language Constructs begin ........ ........ end endmodule

String Literals of type packed arrays


Example
byte c1 = "A" ; bit [0:1] [7:0] c2 = "ab"; byte c3 = "";

Array Literals
Example
int n[0:1][0:2] = {{0,1,2},{3{4}}}; int n1[0:1][0:5] = {2{{3{4, 5}}}}; int n2[0:2] = {1:1, default:0};

Data Types
SystemVerilog data types supported by Precision Synthesis include: Integer (integer, int, shortint, longint, byte, logic, bit, reg) Void User Defined Types Enumerations Structures (packed/unpacked) and Unions (packed)

Precision Synthesis does not support the following data types: Real and Short Real Chandle String Event Union (unpacked) Tagged Union Class

130

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Some of these data types (bit,reg,logic) can take an optional range specification as a means of creating a bit vector. The range expression is of the following form:
[<most significant bit> : <least significant bit>]

Some of these data types are used in the example below, along with the range expression syntax. More details on the data types are presented in the following sections.
// This design implements a Manchester Encoder // module manenc (reset, clk , data , load , sdata, ready); parameter max_count = 7; input clk, load; input [max_count:0] data; output sdata, ready ; reg reg reg reg sdata, ready ; [2:0] count; [max_count:0] sout; phase;

// Phase encoding always @ (posedge clk) begin sdata = sout[max_count] ^ phase; phase = ~phase ; end

Precision Synthesis Style Guide, 2011a Update2 November 2011

131

SystemVerilog Language Features Basic Language Constructs

// Shift data always @ (posedge phase) begin if ((count == 0) & !load) begin sout[max_count:1] = sout[0:max_count - 1]; sout[0] = 1b0; ready = 1b1; end else if ((count == 0) & load ) begin sout = data; count = count + 1; ready = 1b0; end else if (count == max_count) begin sout[max_count:1] = sout[0:max_count - 1]; sout[0]= 1b0; count = 0; end else begin sout[max_count:1] = sout[0:max_count - 1]; sout[0]= 1b0; count = count + 1; end end endmodule

Integer Data Types


Shortint
shortint (2-state SystemVerilog data type, 16 bit signed integer)

Example
shortint a = 5d10;

Int
int (2-state SystemVerilog data type, 32 bit signed integer)

Example
int a = -10;

Longint
longint (2-state SystemVerilog data type, 64 bit signed integer)

Example
longint a;

132

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Byte
byte (2-state SystemVerilog data type, 8 bit signed integer or ASCII character)

Example
byte a = -2b10;

Bit
bit (2-state SystemVerilog data type, user-defined vectorsize)

Example
bit a = 1b0;

Logic
logic (4-state SystemVerilog data type, user-defined vector size)

Example
logic [1:0]a = 2bx1;

Reg
reg (4-state Verilog-2001 data type, user-defined vector size)

Example
reg a = 1bz;

Integer
integer (4-state Verilog-2001 data type,32 bit signed integer)

Example
integer a = -10;

User Defined Types


Example
module userdeftypes; typedef bit my_bit b ; endmodule my_bit;

Precision Synthesis Style Guide, 2011a Update2 November 2011

133

SystemVerilog Language Features Basic Language Constructs

Enumerations
Enum datatype is of type int unless specified otherwise.

Example
enum {WAIT, LOAD, STORE} state;
//This is of type int. i.e. 32 bit signed enum bit [2:0]{A, B, C, D, E, F} var_enum; //This is of type bit [2:0]

Users can also define types using enum.

Example
typedef enum bit [2:0]{A, B, C, D, E, F} type_enum; type_enum var_enum;

Structures (packed/unpacked) and Unions (packed)


Packed Structures can be declared as follows. Each element of packed structure must be of packed type.

Example
struct packed{ logic field0; int field1; bit [7:0] field2; } st_var;

Unpacked structures may have unpacked elements.

Example
strcut{ int field0[1:0]; reg [3:0] field1[3:0]; bit [7:0] field2; } st_upkd_var;

Packed union can be declared as follows: Each Element of the packed union must be packed and the width of each element of packed union must be the same.

Example
union packed{ logic [7:0] field0; byte field1; bit [7:0] field2; } un_var;

134

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Casting
int(2.0 * 3.0); shortint{8hFA,8hCE};

A decimal number as a data type means a number of bits.


17(x - 2);

The signedness can also be changed.


signed(x);

Example
module test1(); typedef logic [3:0] l3; typedef logic l4 [3:0] ; l3 var1; int in1,in2; always begin in1 = 9; var1 = l3 (in1); // var1 = 1001 in2 = signed (var1); // in2 = -7 in2 = in1 + signed(var1); // 9-7 = 2 end endmodule

Arrays
Packed and Unpacked Arrays
bit [7:0] c1; // packed array logic u [7:0]; // unpacked array

Example
module array1(); bit signed [15:0] array ; shortint a,b ; int intarr1[2][3]; always begin array = -2b10 ; a = array[7:0] ; b = array ; end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

135

SystemVerilog Language Features Basic Language Constructs

Multi-dimensioned Arrays
bit [1:5] [1:6] foo4 [1:7] [1:8];// 1 to 6 varies most rapidly, followed // by 1 to 5, then 1 to 8 and then 1 to 7

Example
//declaration module mdarray1(); bit [7:0] md [1:2] ; // 2 entries (unpacked) always begin //usage md[1] = "A" ; md[2] = "B" ; end endmodule of one byte (packed)

Enhancement over Verilog-2001 is support for multiple packed dimensions.

Example
logic [1:0][2:0][3:0] l1; bit [5:0][3:0]b1;

Multiple unpacked dimensions can also be defined in stages with typedef.

Example
module mdarray2(); typedef bit[1:5] bsix; //packed array bsix [1:0] memten; //1 to 5 varies most rapidly typedef bit ubsix [1:5] ubsix umemten [1:0] ; ; //unpacked array

always begin memten[1] = 5b10100; umemten[0][1] = 1b1; end endmodule

Out of range index values will generate an Error for both reading from and writing to an array.

Indexing and Slicing of Arrays


Precision Synthesis will allow selection of one or more contiguous elements using a slice name.An single element of a packed or unpacked array can be selected using an indexed name. Indexing and Slicing of an array with single packed dimension and with multiple unpacked dimensions.

136

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Packed Example
//packed dim //no. 1 2 3 logic [1:0][2:0][3:0]l1; l1[1] = 12d5; //indexing Packed Dim 1 l1[1:0] = 24d15; //slicing Packed Dim 1 l1[1][0] = 4d5; //indexing Packed Dim 2 l1[1][1:0] = 8d9;//slicing Packed Dim 2 l1[1][2][1:0] = 3b101;//slicing Packed Dim 3

Indexing and Slicing of any packed Multi-Dimension array is also supported.

Unpacked Example
module slice1(); //declarations bit [3:0] [7:0] j; bit [3:0]uj [7:0] ; byte k ; bit [31:0] busA [7:0]; int busB [1:0]; always begin //usage j[3] = "A"; j[2:0] = "ABC" ; j[1][3:0] = 4d3; busB = busA[7:6] ; busA[3:2] = busB; uj[3] = "A"; // uj[2:0] = "ABC" ; // uj[1][3:0] = 4d3; end .......... .......... endmodule

error

Array Assignment
Precision will type check following two things during array assignment: 1. Source and target are both arrays, with the same number of unpacked dimensions. 2. The length of each unpacked dimension is the same.

Precision Synthesis Style Guide, 2011a Update2 November 2011

137

SystemVerilog Language Features Basic Language Constructs

Example
int int int A = A = A[10:1]; // fixed-size array of 10 elements B[0:9]; // fixed-size array of 10 elements C[24:1]; // fixed-size array of 24 elements B; // ok. Compatible type and same size C; // type check error: different sizes

Arrays as Arguments
Example
module arrayarg(in,out); input int in[1:2][0:1]; output int out; int temp1[1:2][0:2]; int temp2[1:2]; reg temp3[1:2][0:1]; function int argfunc (int inf[0:1][0:1]) ; argfunc = inf[0][0]; endfunction always begin out = argfunc(in); //ok //out = argfunc(temp1); //out = argfunc(temp2); //out = argfunc(temp3); end endmodule

same type and dimension //error incompatible size //error incompatible dimension //error incompatible type

Data Declarations
Constants
Constants are named data items which never change. A constant declared with the const keyword, can only be set to an expression of literals, parameters, local parameters, genvars, a constant function of these, or other constants. This is also supported in Precision Synthesis.

Example
const logic c1 = 1b1;

138

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Attributes
Default Attribute Type
The default type of an attribute with no value is bit, with a value of 1. Otherwise, the attribute takes the type of the expression.

Operators and Expressions


Assignment Operators
Precision Synthesis will support all new assignment operators introduced in SystemVerilog 3.1, such as +=,-=, *=, /=, %=, &=, |=, <<=, >>=, <<<=, >>>= and the increment and decrement operators, ++ and --. All Operators are of fixed type and size.

Example
int a; a += 2; a *= 3; a--; // a = a + 2; // a = a * 3; // a = a - 1;

Procedural Statements and Control flow


Selection Statements
Precision Synthesis supports the keywords unique and priority, which can be used before an if or case statement. A priority if indicates that a series of if...else...if conditions shall be evaluated in the order listed.

Example
module prioritytest(in1, in2, in3, cond, out); input in1, in2, in3 ; input [1:0]cond; output out; reg out; always@(in1, in2, in3, cond) begin priority if(cond[1] == 1b1) out = in1; else if(cond[0] == 1b0) out = in2; else

Precision Synthesis Style Guide, 2011a Update2 November 2011

139

SystemVerilog Language Features Basic Language Constructs out = in3; end endmodule

Example
module prioritycase1(in, cond, out); input in ; input [1:0] cond; output reg [2:0] out; always@(in, cond) begin priority casex(cond) 2b00: out =1; 2b0x: out = in; 2b11: out =0; default: out = in; endcase end endmodule

Example
module uniquecase1(in, cond, out); input in ; input [1:0]cond; output reg [2:0] out; always@(in, cond) begin unique casex(cond) 2b00: out =1; 2b01: out = in; 2b11: out =0; default: out = in; endcase end endmodule

Loop Statements The Do While Loop


Precision Synthesis supports SystemVerilog Do...While loop structures.
do { statement } while(condition);

Example
module dowhiletest(out, in);

140

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs input [9:0] in; output [9:0] out; reg [9:0] out; integer i; reg [9:0] temp; always@( in ) begin i = 0; temp = 0; out = 0; do begin temp[i] = in[i]; i=i+1; end while ( (i<2) ); out = temp; end endmodule

Enhanced For Loop


Example
module fortest1(out,out1, in1,in2,clk); output reg [2:0]out; output reg [2:0]out1; input [5:0]in1,in2,clk; reg [2:0]temp; integer j,k,i; always@(clk,in1) begin temp = in1; for(integer i=0,k=0,j=0;i<3;i=i+1,k=k+1) begin out[j]=temp[j]; temp[i]=temp[i]+1; out[k]=temp[k]+1; out1[k]=in1[j] & in2; end out =temp; //out1=j; end endmodule

Jump Statements (Break, Continue and Return)


Precision Synthesis supports the following four SystemVerilog jump statements. 1. break -> out of loop 2. continue -> skip to end of loop 3. return expression -> exit from a function
Precision Synthesis Style Guide, 2011a Update2 November 2011

141

SystemVerilog Language Features Basic Language Constructs

4. return -> exit from a task or void function

Return Example
module returntest(in1,in2,cond,out1); input [1:0] in1,in2,cond; output [1:0] out1; reg [1:0] out1; function [1:0] function1; input [1:0] in1,in2,cond; if(cond==2b00) return in1|in2;// use of return else function1 = in1 ~^ in2; endfunction always @(in1 or in2 or cond) begin out1 = function1(in1,in2,cond); end endmodule

Similarly Break and Continue can be used inside a While, Do-While, Repeat or Forever loop:
module for2(out ); //input [9:0] in; output [9:0] out; reg [9:0] out; reg [9:0] in; integer i; reg [9:0] temp; reg a, b; always@( in ) begin in = 2b01; temp = 0; out = 0; for(i=0 ; i<5 ;i=i+1) // flag1 begin temp[i] = i; if( (i<2 ) ) continue;// disable flag1 else break;// disable flag2 end // flag2 out = temp; end endmodule

142

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Named Blocks
The Block name is specified after a Begin statement and is preceded by a colon. Precision Synthesis will allow a matching Block name (optional) to be specified after the block end.

Example
module namedblock(input reg always @(in1 or in2) begin : label1 out = in1 + in2; end : label1 endmodule in1 , in2, output reg out);

Precision Synthesis will issue a Block name mismatch error if the Begin and End names do not match:
begin : label1 out = in1 + in2; end : label2 //mismatch

Processes
Combinatorial Logic
Example
module comb_logic(in1,in2,out); input int in1,in2; output int out; int w; always_comb out <=in1 & in2; always_comb w <=in1 | in2; endmodule

Precision Synthesis will give a warning message if the logic inside always_comb is not purely combinational.

Example
module latch(sel,data,out); input sel; input byte data; output [7:0]out;

Precision Synthesis Style Guide, 2011a Update2 November 2011

143

SystemVerilog Language Features Basic Language Constructs logic [7:0]out; always_comb begin if(sel == 1b0) out = data; end endmodule Warning: Latch inferred for net out[7] inside always_comb block

Latched Logic
Example
module latch_logic(in1,in2,out); input in1,in2; output out; reg out; reg w; always_latch if(in1) out<=in1; always_latch if(in2) w<=in2; endmodule

If latch is not inferred inside always_latch then Precision Synthesis will give a Warning message.

Sequential Logic
Example
module ff(in1,in2,out); input in1,in2; output out; reg d,out; reg clk,reset; always_ff begin @(changed clk or negedge reset) if(! reset) out <= 0; else out <= d; end endmodule

144

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Tasks and Functions


Precision Synthesis supports the following additions for tasks and functions. 1. Default direction will be input if no direction is specified. 2. Default data type will be logic if no data type is specified. 3. Returning from a task or function before reaching the end. 4. Support for output port and inout port in functions. 5. Passing Argument values by name instead of position. 6. Default argument values. 7. Allowing arrays as formal argument to the tasks/functions.

Task
Example
module taskfunc(input int in1,in2,input bit clk,output int out1,out2); always @* begin task1(in1,in2,clk,out1); end task task1(input [7:0] in1, in2,input clk,output int out1); reg [3:0][7:0] temp; begin temp[0] <= in1 + in2; out1 <= temp; end endtask endmodule

Function
Example
module taskfunct1(input int in1,in2,sel,output int out1,out2); always_comb begin out2 = fun1(in1,in2,sel,out1); end function [7:0] fun1(input [7:0] in1, in2,input [1:0] sel,output int out1); reg [1:0][7:0] temp; begin temp[0] = in1 + in2; temp[1] = in1 - in2; out1 = temp; if (sel == 2b00) return temp[0]; else if (sel == 2b01) return temp[1];

Precision Synthesis Style Guide, 2011a Update2 November 2011

145

SystemVerilog Language Features Basic Language Constructs end endfunction endmodule

Void Functions
Return value of functions can be ignored by casting the function to void type.
void(some_function());

Default Argument Value


Example
module addVal(input byte in1, in2, output byte out1,out2); always_comb begin add1(in1, ,out1); // equivalent to add1(in1,1,out); add1(, in2,out1); // equivalent to add1(0,in2,out); out2 = add2(in1,); // equivalent to out2 = add2(in1,1); out2 = add2(,in2); // equivalent to out2 = add2(0,in2); end task add1(input byte in1 = 0, in2 = 1,output byte out); out = in1 + in2; endtask //function definition with default arg. values. function byte add2(input byte in1 = 0, in2 = 1); add2 = in1 + in2; endfunction endmodule

Argument Passing by Name


module taskfunct3(input int in1,in2,sel,output int out1,out2); always_comb begin out2 = fun1(.in1(in1),.in2(in2),.sel(sel),.out1(out1)); end function [7:0] fun1(input [7:0] in1, in2,input sel,output int out1); begin out1 = in1 + in2; if(sel == 1b0) return in1; else return in2; end endfunction endmodule

146

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

Hierarchy
Port Declarations
Precision Synthesis will allow Port as a declaration of a net, or a variable of any type, including an array. There is language support for all basic types (such as, shortint, longint, int, bit, logic, byte) as ports, and for arrays, struct, union and interface as ports.

Example
module portdecl (in1,in2,out); typedef struct { bit isfloat; union packed{ int i; int f; } n; } tagged_t; // named structure input int in1; input logic in2; output tagged_t out; endmodule

Note Precision Synthesis does not support port as a declaration of an event.

Port Connection Rules for new SystemVerilog Data Types Instantiation Using Implicit .name Port Connections
Precision Synthesis will allow the capability to implicitly instantiate ports using a .name syntax if the instance-port name and size match the connecting variable-port name and size.

Example
module alu ( output reg [7:0] alu_out, output reg zero, input [7:0] ain, bin, input [2:0] opcode); // RTL code for the alu module endmodule module alu_accum3 ( output [15:0] dataout, input [7:0] ain, bin, input [2:0] opcode, input clk, rst_n); wire [7:0] alu_out; alu alu (.alu_out, .zero(), .ain, .bin, .opcode); endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

147

SystemVerilog Language Features Basic Language Constructs

Instantiation Using Implicit .* Port Connections


Example
module alu_accum4 ( output [15:0] dataout, input [7:0] ain, bin, input [2:0] opcode, input clk, rst_n); wire [7:0] alu_out; alu alu (.*, .zero()); endmodule

Interfaces
Example
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design Module : top, memory --- Purpose : This design shows how the interface feature can he used to -bundle and reuse I/O among different modules in the design. -It also illustrates how modport is used to define port -directions. --- The following new constructs in SV are used: -- interface, typedef, always_comb ---- Version: 1.0 -- Precision: 2005c -- Date: Dec 23 2005 -----------------------------------------------------------------------*/ interface address_bus; parameter p1 = 7; wire [p1:0] read_address; wire [p1:0] write_address; modport address_port_in (input endinterface

read_address, input write_address);

interface data_bus; parameter p2 = 7; wire [p2:0] data_in; wire [p2:0] data_out; modport data_port (input data_in, output data_out); endinterface

interface control_bus; wire reset; wire clk;

148

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs wire wren; wire ren; modport memory_control (input reset, input clk, input wren, input ren); endinterface //----------------------------------------------------module memory (address_bus.address_port_in addr, control_bus.memory_control ctrl, data_bus.data_port data); parameter p1 =7; parameter p2 =7; typedef logic [7:0] BYTE; BYTE memory[(2*p1+1):0][(2*p1+1):0]; BYTE latch; assign data.data_out = latch;

always @ (posedge ctrl.clk) begin if(ctrl.reset) begin for(int i = (2*p1+1); i >= 0; i--) begin for(int j = (2*p1+1); j >= 0; j--) begin memory[i][j] = 0; end end latch = 0; end else begin if(ctrl.ren) begin latch = memory[addr.read_address[3:0]][addr.read_address[7:4]]; end if(ctrl.wren) begin memory[addr.write_address[3:0]] [addr.write_address[7:4]] = data.data_in; end end end endmodule //----------------------------------------------------module top (clk, reset, wren, ren, raddr, waddr, wdata, rdata); parameter p1 =7; parameter p2 =7; input input input input input clk; reset; wren; ren; [p1:0] raddr;

Precision Synthesis Style Guide, 2011a Update2 November 2011

149

SystemVerilog Language Features Basic Language Constructs input input output logic [p1:0] [p2:0] [p2:0] [p2:0] waddr; wdata; rdata; rdata;

// Instantiate interfaces address_bus #(.p1(p1)) addr(); data_bus #(.p2(p2)) data(); control_bus ctrl(); // Instantiate memory module memory #(.p1(p1), .p2(p2)) mem_i (.*); assign assign assign assign assign assign assign ctrl.clk = clk; ctrl.reset = reset; ctrl.wren = wren; ctrl.ren = ren; addr.read_address = raddr; addr.write_address = waddr; data.data_in = wdata;

always_comb begin rdata = data.data_out; end endmodule

Compiler Directives
`Define Macro
In SystemVerilog, the macro can include ", \" and . An " overrides the usual lexical meaning of ", and indicates that the expansion should include an actual quotation mark. A \" indicates that the expansion should include the escape sequence \. A delimits lexical tokens without introducing white space, allowing identifiers to be constructed from arguments.

Example
`define foo(f) f_suffix //This expands: foo(bar)to:bar_suffix.

Unpacked Array Concatenation


Unpacked array concatenation provides a flexible way to populate an unpacked array using a collection of elements and arrays. An unpacked array concatenation can appear as the source

150

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Basic Language Constructs

expression in an assignment-like context. It cannot appear in any other context. The target of such an assignment-like context is an array whose slowest-varying dimension is an unpacked fixed-size.

Example
int A3[1:3]; assign A3 = {1,2,3}; module top (clk, in1, in2, out); parameter type T = logic; input T clk; input T [0:3] in1,in2; output T [31:0] out; T [0:7] u [0:3]; T [0:3] t [0:0] [0:1]; assign t[0][0] = in1; assign t[0][1] = in1; assign out[31:0] = {u[0],u[1],u[2],u[3]}; always @(posedge clk) begin u = {t[0],in1,in2}; end endmodule

Foreach Loop Support


The foreach loop construct specifies iterations over the elements of an array. Its argument is an identifier that designates any type of array followed by a comma-separated list of loop variables enclosed in square brackets. Each loop variable corresponds to one of the dimensions of the array.

Example
int prod [1:8] [1:3]; foreach( prod[ k, m ] ) prod[k][m] = k * m; // initialize

Removing Text Substitution Macros


The `undefineall directive removes definitions for all text macros previously defined by the `define compiler directive within the compilation unit. The directive specification does not affect built-in macros

Example
`undefineall // remove any user macros from other files

Precision Synthesis Style Guide, 2011a Update2 November 2011

151

SystemVerilog Language Features Example Designs

Set Membership Operator (Inside Operator)


The Inside Operator checks for the set membership of any expression by scanning through the list of expressions or ranges specified as sets. It returns 1'b1 if the match is found and 1'b0 otherwise. The Inside Operator uses the equality operator (==) for non-integral expressions and the wildcard equality operator (?=) for integral expressions.

Example
logic [2:0] val; while ( val inside {3'b1?1} ) ...// matches 3'b101, 3'b111, 3'b1x1, 3'b1z1

Example Designs
The following table provides a brief description of the examples in this section. The code files are available in the Precision Synthesis software tree in the following directory:
<precision_install_dir>/shared/examples/style_guide_hdl/SystemVerilog

Table 4-2. SystemVerilog Examples Example ALU Counter FSM 1 Description This design is a generic ALU design utilizing these SystemVerilog constructs: struct, union, always_comb, typedef, priority case. This design is a parameterized counter utilizing these SystemVerilog constructs: union, and typedef enum. This design shows how mixed constructs between Verilog-2001 and SV are used within the same FSM design. The SystemVerilog constructs used are: union, typedef enum, unique case, always_ff, always_comb. This design shows how Verilog-2001 and SystemVerilog union, typedef enum, unique case, and always_ff can be combined in the same FSM design. This design shows how typedef enum, union, unique case, and always_ff are used an arbiter design. This example uses the classic traffic light control design to illustrate const, enum, unique case, always_ff, always_comb elements, and FSM state encoding override by an applied synthesis pragma. This design uses the SystemVerilog interface feature to bundle and reuse I/O among different modules in the design. Modport is used to define port direction.

FSM 2

FSM 3 FSM Reencoded

Interface

152

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Example Designs

ALU
This design is a generic ALU design utilizing these SystemVerilog constructs: struct, union, always_comb, typedef, priority case. Example 4-1. SystemVerilog ALU
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : ALU --- Purpose : This design is a generic ALU design coded in SystemVerilog -- The following new constructs in SV are used: -- struct -- union -- always_comb -- typedef -- priority case --- Rev: 1.0 -- Precision: 2005c -- Date: Dec 23 2005 -----------------------------------------------------------------------*/ module ALU(inp_pack, out); typedef enum bit[1:0] {ADD, SUB, typedef union packed { shortint signed in1; shortint unsigned in2; }inp; typedef union packed { int signed out1; int unsigned out2; }out_vec; typedef enum bit {SIGN, UNSIGN} operation; typedef struct packed { inp in1, in2; instruction instr; operation op; }input_packet; input input_packet inp_pack; output out_vec out; always_comb begin priority case(inp_pack.instr) ADD : begin if(inp_pack.op == SIGN) SL, SR} instruction;

Precision Synthesis Style Guide, 2011a Update2 November 2011

153

SystemVerilog Language Features Example Designs out.out1 = inp_pack.in1.in1 else out.out2 = inp_pack.in1.in2 end SUB : begin if(inp_pack.op == SIGN) out.out1 = inp_pack.in1.in1 else out.out2 = inp_pack.in1.in2 end SL : begin if(inp_pack.op == SIGN) out.out1 = inp_pack.in1.in1 else out.out2 = inp_pack.in1.in2 end SR : begin if(inp_pack.op == SIGN) out.out1 = inp_pack.in1.in1 else out.out2 = inp_pack.in1.in2 end default: begin out.out1 = 0; out.out2 = 0; end endcase end endmodule + inp_pack.in2.in1; + inp_pack.in2.in2;

- inp_pack.in2.in1; - inp_pack.in2.in2;

<< inp_pack.in2.in1; << inp_pack.in2.in2;

>> inp_pack.in2.in1; >> inp_pack.in2.in2;

Counter
This design is a parameterized counter utilizing these SystemVerilog constructs: union, and typedef enum. Example 4-2. SystemVerilog Counter
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : counter --- Purpose : This design is a parameterized counter design coded in -SystemVerilog. The design can be counted in either binary -or decimal mode. -- if mode is 1 then counter operates in binary mode -- if mode is 0 then counter operates in decimal mode -- if incdec is 1 then it increments -- if incdec is 0 then it decrements --- The following new constructs in SV are used: -- union -- typedef enum

154

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Example Designs --- Rev: 1.0 -- Precision: 2005c -- Date: Dec 23 2005 -----------------------------------------------------------------------*/ module counter (mode,incdec,reset,clk,out); input reset,clk; input mode,incdec; output [2:0] out; localparam BINARY = 1; localparam STEP = 1; typedef enum logic [2:0] {state[8]} binary_type; typedef enum logic [2:0] {gray0 = 3b000,gray1 = 3b001, gray2 = 3b011,gray3 = 3b010, gray4 = 3b110,gray5 = 3b111, gray6 = 3b101,gray7 = 3b100 } gray_type; union packed { binary_type binary_count; gray_type gray_count; }cs; assign out = cs; always @(posedge clk or negedge reset) begin if(!reset) begin if(mode == BINARY) cs.binary_count <= cs.binary_count.first(); else cs.gray_count <= cs.gray_count.first(); end else begin if(mode == BINARY) if(incdec) cs.binary_count <= cs.binary_count.next(STEP); else cs.binary_count <= cs.binary_count.prev(STEP); else if(incdec) cs.gray_count <= cs.gray_count.next(STEP); else cs.gray_count <= cs.gray_count.prev(STEP); end end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

155

SystemVerilog Language Features Example Designs

FSM 1
This design shows how mixed constructs between Verilog-2001 and SV are used within the same FSM design. The SystemVerilog constructs used are: union, typedef enum, unique case, always_ff, always_comb. Example 4-3. SystemVerilog FSM 1
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design Module : FSM, encoder, decoder --- Purpose : This design shows how typedef enum can be coded using SV and -how mixed constructs between Verilog-2001 and SV are used -within the same design. --- The following new constructs in SV are used: -- union, typedef enum, unique case, always_ff, always_comb ---- Version: 1.0 -- Precision: 2005c -- Date: Dec 23 2005 -----------------------------------------------------------------------*/ module FSM( input bit [7:0] in, input bit clk, reset, output bit [7:0] out_encoded, out_decoded); bit [7:0] intermediate; typedef enum bit[3:0] {s0 s3 s6 s9 s12 s15 STATE current_state;

= = = = = =

4b0000, 4b0011, 4b0110, 4b1001, 4b1100, 4b1111}

s1 = 4b0001, s4 = 4b0100, s7 = 4b0111, s10 = 4b1010, s13 = 4b1101, STATE;

s2 s5 s8 s11 s14

= = = = =

4b0010, 4b0101, 4b1000, 4b1011, 4b1110,

encode a(in, current_state, out_encoded); decode b(intermediate, current_state, out_decoded); assign intermediate = out_encoded; always_ff @ (posedge clk) begin if(reset) current_state <= current_state.first(); else current_state <= current_state.next(); end endmodule //======================================

156

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Example Designs module encode ( input bit [7:0] in, input bit [3:0] current_state, output bit [7:0] out_encoded); bit [7:0] lock; assign out_encoded = in ^ lock; always_comb begin unique case (current_state) 0000: lock = {7{current_state[0]}}; 0001: lock = {7{current_state[0]}}; 0010: lock = {7{current_state[0]}}; 0011: lock = {7{current_state[0]}}; 0100: lock = {7{current_state[1]}}; 0101: lock = {7{current_state[1]}}; 0110: lock = {7{current_state[1]}}; 0111: lock = {7{current_state[1]}}; 1000: lock = {7{current_state[2]}}; 1001: lock = {7{current_state[2]}}; 1010: lock = {7{current_state[2]}}; 1011: lock = {7{current_state[2]}}; 1100: lock = {7{current_state[3]}}; 1101: lock = {7{current_state[3]}}; 1110: lock = {7{current_state[3]}}; 1111: lock = {7{current_state[3]}}; default: lock = 8b0; endcase end endmodule //====================================== module decode (input bit [7:0] in, input bit [3:0] current_state, output bit [7:0] out_decoded); bit bit bit [7:0] key; [7:0] temprary; [7:0] decoded;

assign out_decoded = decoded; always_comb begin unique case 0000: 0001: 0010: 0011: 0100: 0101: 0110: 0111: 1000: 1001: 1010: 1011: 1100:

(current_state) key = {7{current_state[0]}}; key = {7{current_state[0]}}; key = {7{current_state[0]}}; key = {7{current_state[0]}}; key = {7{current_state[1]}}; key = {7{current_state[1]}}; key = {7{current_state[1]}}; key = {7{current_state[1]}}; key = {7{current_state[2]}}; key = {7{current_state[2]}}; key = {7{current_state[2]}}; key = {7{current_state[2]}}; key = {7{current_state[3]}};

Precision Synthesis Style Guide, 2011a Update2 November 2011

157

SystemVerilog Language Features Example Designs 1101: 1110: 1111: default: endcase key key key key = = = = {7{current_state[3]}}; {7{current_state[3]}}; {7{current_state[3]}}; 8b0;

for(int i = 0; i < 8; i++) begin if(in[i] == 1b1) decoded[i] = ~key[i]; else decoded[i] = key[i]; end end endmodule //======================================

FSM 2
This design shows how Verilog-2001 and SystemVerilog union, typedef enum, unique case, and always_ff can be combined in the same FSM design. Example 4-4. SystemVerilog FSM 2
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design Module : FSM, encoder, decoder --- Purpose : This design shows how typedef enum can be coded using SV and -how mixed constructs between Verilog-2001 and SV are used -within the same design --- The following new constructs in SV are used: -- union, typedef enum, unique case, always_ff ---- Version: 1.0 -- Precision: 2005c -- Date: Dec 23 2005 -----------------------------------------------------------------------*/ module FSM2( in, reset, clk, out_encoded, out_decoded); input bit [7:0] in; input bit clk; input bit reset; output bit [7:0] out_encoded; output bit [7:0] out_decoded; bit [7:0] intermediate; typedef enum bit[3:0] {s0 s3 s6 = 4b0000, s1 = 4b0011, s4 = 4b0110, s7 = 4b0001, s2 = 4b0100, s5 = 4b0111, s8 = 4b0010, = 4b0101, = 4b1000,

158

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Example Designs s9 = 4b1001, s10 = 4b1010, s11 = 4b1011, s12 = 4b1100, s13 = 4b1101, s14 = 4b1110, s15 = 4b1111} STATE; STATE current_state;

encode a(in, current_state, out_encoded); decode b(intermediate, current_state, out_decoded); assign intermediate = out_encoded; always_ff @ (posedge clk) begin if(reset) current_state = current_state.first(); else current_state = current_state.next(); end endmodule //====================================== module encoder ( input bit [7:0] in, input bit [3:0] current_state, output bit [7:0] out_encoded); bit [7:0] lock; assign out_encoded = in ^ lock; always @* begin unique case 0000: 0001: 0010: 0011: 0100: 0101: 0110: 0111: 1000: 1001: 1010: 1011: 1100: 1101: 1110: 1111: default: endcase end endmodule //====================================== module decoder (input bit [7:0] in, input bit [3:0] current_state, output bit [7:0] out_decoded);

(current_state) lock = {7{current_state[0]}}; lock = {7{current_state[0]}}; lock = {7{current_state[0]}}; lock = {7{current_state[0]}}; lock = {7{current_state[1]}}; lock = {7{current_state[1]}}; lock = {7{current_state[1]}}; lock = {7{current_state[1]}}; lock = {7{current_state[2]}}; lock = {7{current_state[2]}}; lock = {7{current_state[2]}}; lock = {7{current_state[2]}}; lock = {7{current_state[3]}}; lock = {7{current_state[3]}}; lock = {7{current_state[3]}}; lock = {7{current_state[3]}}; lock = 8b0;

Precision Synthesis Style Guide, 2011a Update2 November 2011

159

SystemVerilog Language Features Example Designs

bit bit

[7:0] key; [7:0] decoded;

assign out_decoded = decoded; always @* begin unique case 0000: 0001: 0010: 0011: 0100: 0101: 0110: 0111: 1000: 1001: 1010: 1011: 1100: 1101: 1110: 1111: default: endcase

(current_state) key = {7{current_state[0]}}; key = {7{current_state[0]}}; key = {7{current_state[0]}}; key = {7{current_state[0]}}; key = {7{current_state[1]}}; key = {7{current_state[1]}}; key = {7{current_state[1]}}; key = {7{current_state[1]}}; key = {7{current_state[2]}}; key = {7{current_state[2]}}; key = {7{current_state[2]}}; key = {7{current_state[2]}}; key = {7{current_state[3]}}; key = {7{current_state[3]}}; key = {7{current_state[3]}}; key = {7{current_state[3]}}; key = 8b0;

for(int i = 0; i < 8; i++) begin if(in[i] == 1b1) decoded[i] = ~key[i]; else decoded[i] = key[i]; end end endmodule

FSM 3
This design shows how typedef enum, union, unique case, and always_ff are used an arbiter design. Example 4-5. SystemVerilog FSM 3
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design Module: arbiter --- Purpose : This design shows how typedef enum can be coded using SV and -how mixed constructs between Verilog-2001 and SV are used -within the same design

160

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Example Designs --- The following new constructs in SV are used: -- union, typedef enum, unique case, always_ff ---- Version: 1.1 -- Precision: 2006a -- Date: June 15 2007 -----------------------------------------------------------------------*/ module arbiter (input input output clock, reset, logic req_0, req_1, logic gnt_0, gnt_1);

//-------------Internal Constants-------------------------localparam int SIZE = 3; typedef enum logic [SIZE-1:0] {IDLE = 3b001, GNT0 = 3b010, GNT1 = 3b100}STATE_T; STATE_T state,next_state; //----------Code startes Here-----------------------always_comb // @ (state or req_0 or req_1) --> senslist not required. begin : FSM_COMBO //next_state = 3b000; --> illegal syntax ! unique case(state) IDLE : if (req_0 == 1b1) begin next_state = GNT0; end else if (req_1 == 1b1) begin next_state= GNT1; end else begin next_state = IDLE; end GNT0 : if (req_0 == 1b1) begin next_state = GNT0; end else begin next_state = IDLE; end GNT1 : if (req_1 == 1b1) begin next_state = GNT1; end else begin next_state = IDLE; end default : next_state = IDLE; endcase end

always_ff @ (posedge clock) begin : FSM_SEQ if (reset == 1b1) begin

Precision Synthesis Style Guide, 2011a Update2 November 2011

161

SystemVerilog Language Features Example Designs state <= end else begin state <= end end //----------Output Logic----------------------------always_ff @ (posedge clock) begin : OUTPUT_LOGIC if (reset == 1b1) begin gnt_0 <= 1b0; gnt_1 <= 1b0; end else begin priority case(state) IDLE : begin gnt_0 <= 1b0; gnt_1 <= 1b0; end GNT0 : begin gnt_0 <= 1b1; gnt_1 <= 1b0; end GNT1 : begin gnt_0 <= 1b0; gnt_1 <= 1b1; end default:begin gnt_0 <= 1b0; gnt_1 <= 1b0; end endcase end end // End Of Block OUTPUT_LOGIC endmodule // End of Module arbiter IDLE;

next_state;

162

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Example Designs

FSM Reencoded
This example uses the classic traffic light control design to illustrate const, enum, unique case, always_ff, always_comb elements, and FSM state encoding override by an applied synthesis pragma. Example 4-6. SystemVerilog FSM Reencoded
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design Module : trafficLight --- Purpose : This design shows how typedef enum can be coded using SV and -how mixed constructs between Verilog-2001 and SV are used -within the same design --- The following new constructs in SV are used: -- const, enum, unique case, always_ff, always_comb ---- Version: 1.0 -- Precision: 2005c -- Date: Dec 23 2005 -----------------------------------------------------------------------*/ module trafficLight ( output reg green_light, yellow_light, red_light, input sensor, input clock, resetN); byte yellow_downcnt,green_downcnt; const int GREEN_COUNT = 8d30; const int YELLOW_COUNT = 8d05; enum logic[2:0] {RED = 3b001, GREEN = 3b011, YELLOW = 3b100 }State, Next /* synthesis fsm_state = onehot */; always_ff @(posedge clock, negedge resetN) if(!resetN) State <= RED; else begin State <= Next; if(State == GREEN) begin if(green_downcnt == 0) green_downcnt = GREEN_COUNT; else green_downcnt = green_downcnt - 1; end if(State == YELLOW) begin

Precision Synthesis Style Guide, 2011a Update2 November 2011

163

SystemVerilog Language Features Example Designs if(yellow_downcnt == 0) yellow_downcnt = YELLOW_COUNT; else yellow_downcnt = yellow_downcnt - 1; end end always_comb begin: set_next_state Next = State; unique case (State) RED: if(sensor) Next = GREEN; GREEN: if(green_downcnt == 0) Next = YELLOW; YELLOW: if(yellow_downcnt == 0) Next = RED; endcase end:set_next_state always_comb begin: set_outputs {red_light, green_light, yellow_light} = 3b000; unique case(State) RED: red_light = 1; GREEN: green_light = 1; YELLOW: yellow_light = 1; endcase end: set_outputs endmodule

164

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Example Designs

Interface
This design uses the SystemVerilog interface feature to bundle and reuse I/O among different modules in the design. Modport is used to define port direction. Example 4-7. SystemVerilog Interface
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design Module : top, memory --- Purpose : This design shows how the interface feature can he used to -bundle and reuse I/O among different modules in the design. -It also illustrates how modport is used to define port -directions. --- The following new constructs in SV are used: -- interface, typedef, always_comb ---- Version: 1.0 -- Precision: 2005c -- Date: Dec 23 2005 -----------------------------------------------------------------------*/ interface address_bus; parameter p1 = 7; wire [p1:0] read_address; wire [p1:0] write_address; modport address_port_in (input endinterface

read_address, input write_address);

interface data_bus; parameter p2 = 7; wire [p2:0] data_in; wire [p2:0] data_out; modport data_port (input data_in, output data_out); endinterface

interface control_bus; wire reset; wire clk; wire wren; wire ren; modport memory_control (input reset, input clk, input wren, input ren); endinterface //----------------------------------------------------module memory (address_bus.address_port_in addr, control_bus.memory_control ctrl, data_bus.data_port data); parameter p1 =7;

Precision Synthesis Style Guide, 2011a Update2 November 2011

165

SystemVerilog Language Features Example Designs parameter p2 =7; typedef logic [7:0] BYTE; BYTE memory[(2*p1+1):0][(2*p1+1):0]; BYTE latch; assign data.data_out = latch;

always @ (posedge ctrl.clk) begin if(ctrl.reset) begin for(int i = (2*p1+1); i >= 0; i--) begin for(int j = (2*p1+1); j >= 0; j--) begin memory[i][j] = 0; end end latch = 0; end else begin if(ctrl.ren) begin latch = memory[addr.read_address[3:0]][addr.read_address[7:4]]; end if(ctrl.wren) begin memory[addr.write_address[3:0]] [addr.write_address[7:4]] = data.data_in; end end end endmodule //----------------------------------------------------module top (clk, reset, wren, ren, raddr, waddr, wdata, rdata); parameter p1 =7; parameter p2 =7; input clk; input reset; input wren; input ren; input [p1:0] input [p1:0] input [p2:0] output [p2:0] logic [p2:0]

raddr; waddr; wdata; rdata; rdata;

// Instantiate interfaces address_bus #(.p1(p1)) addr(); data_bus #(.p2(p2)) data(); control_bus ctrl(); // Instantiate memory module

166

Precision Synthesis Style Guide, 2011a Update2 November 2011

SystemVerilog Language Features Example Designs memory #(.p1(p1), .p2(p2)) mem_i (.*); assign assign assign assign assign assign assign ctrl.clk = clk; ctrl.reset = reset; ctrl.wren = wren; ctrl.ren = ren; addr.read_address = raddr; addr.write_address = waddr; data.data_in = wdata;

always_comb begin rdata = data.data_out; end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

167

SystemVerilog Language Features Example Designs

168

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 5 Inferring Arithmetic and Relational Operators


Arithmetic and relational logic, commonly known as data path logic, has traditionally been difficult to synthesize with logic synthesis software. This is especially true for FPGAs, where each target technology has a different way to optimally utilize resources. Modgen provides an automatic mechanism to overload data path operators, such as "+", "-" and "\" technologyspecific implementations.

Common Guidelines
The following lists shows some of the guidelines for when using arithmetic and relational operators: Integer type values : Synthesis tools can handle up to 32-bit integers within the range of -2147483648 to 2147483647. During compilation, the integer signals are converted to a multi-bit representation. If the integer range only contains positive values, then a unsigned representation will be used. If the range includes negative numbers, Precision RTL Synthesis will use twos-complement representation of the integer values. Floating Point type values : Precision RTL Synthesis does not currently support synthesis of floating point objects. Floating-point types and objects can however be used in constant expression

VHDL/Verilog Differences
The following table shows the operator symbol differences between VHDL and Verilog: Table 5-1. VHDL and Verilog Operator Differences Arithmetic Operators Operation Addition Subtraction Multiplication Division Exponential VHDL
+ * / **

Relational Operators Operation Equality Inequality Lass Than Less Than or Equal To Greater Than VHDL
= /= < <= >

Verilog
+ * / N/A

Verilog
== != < <= >

Precision Synthesis Style Guide, 2011a Update2 November 2011

169

Inferring Arithmetic and Relational Operators Optimization Issues

Table 5-1. VHDL and Verilog Operator Differences (cont.) Arithmetic Operators Operation Modulus Remainder Absolute Value VHDL
mod rem abs

Relational Operators Operation Greater Than or Equal To VHDL


>=

Verilog
% N/A N/A

Verilog
>=

Optimization Issues
The " + ", " - ", " * ", and "abs" (in VHDL) operators work on integers (and on arrays; with the exemplar package). If you use overloaded operators to calculate compile time constants, the synthesis tools will not generate any logic for them. If you are not working with compile time constant operands, arithmetic logic is generated for arithmetic operators. The pre-defined + on integers generates an adder. The number of bits of the adder depends on the size of the operands. If you use integers, a 32 bit (signed) adder is generated. If you use ranged integers, the size of the adder is defined so that the entire range can be represented in bits. For example, if the two numbers have a range of 0 to 255, then an 8 bit (unsigned) adder is generated. If one of the operands is a constant, initially a full-sized adder is still generated but logic minimization eliminates much of the logic inside the adder, since half of the inputs of the adder are constant. The pre-defined " - " on integers generates a subtractor. Same remarks apply as with the " + " operator. The pre-defined " * " multiplication operator on integers generates a multiplier. Full multiplication is supported when a module generator is used. The pre-defined " / " division operator on integers generates a divider. Only division by a power of two is supported. In this case, there is no logic generated, only shifting of the non-constant operand. With module generation you could define your own technology-specific divider. The predefined " ** " exponentiation in VHDL is only supported if both operands are constant. " = ", " /= " or " != ", " < ", " > ", " <= ", and " >= " generate comparators with the appropriate functionality. Operations on integers are done in twos complement implementation if the integer range extends below 0. If the integer range is only positive, an unsigned implementation is used. There are a number of other ways to generate arithmetic logic.

Resource Sharing and Common Subexpression Elimination


Precision RTL Synthesis automatically does common sub-expression elimination. For the following example, only one adder (a+b) is created. The adder is used for both the if

170

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators Optimization Issues

conditions. For bigger expressions you need to use parentheses properly to direct the tool to perform for CSE.
... reg a, b, c, d ; always @ (a or b) begin if ( a+b == c ) //This adder will be shared ... else if ( a+b == d) // with this one. ... else ... end ; ...

Reducing Counter Logic


Applications may involve a counter that counts up to an input signal value, and when that value is reached, some actions are needed and the counter is reset to 0.
... begin if (count == input_signal) ... count = 0 ; else count = count + 1 ; end ; ...

In this example Precision RTL Synthesis builds an incrementer and a full-size comparator that compares the incoming signal with the counter value. It is usually better to preset the counter to the input_signal and count down, until zero is reached.
... begin if (count == 0) ... count = input_signal ; else count = count - 1 ; end ; ...

Now, one decrementer is needed plus a comparison to a constant (0). Since comparisons to constants are a lot cheaper to implement, this new behavior is much easier to synthesize, and results in a smaller circuit.

Precision Synthesis Style Guide, 2011a Update2 November 2011

171

Inferring Arithmetic and Relational Operators Attributes That Affect Operators

Even better results can be obtained with the use of hard macros and soft macros of the target technology, as well as the use of hierarchy in the design. The following two sections explain this in more detail.

Attributes That Affect Operators


The following attributes affect how operators are implemented: dedicated_mult : Specifies how a multiplier operator should be mapped to resource within the FPGA

Arithmetic Examples
The following table shows the VHDL and Verilog examples described in this section. The code files are available in the Precision Synthesis software tree in the following directory:
<precision_install_dir>/shared/examples/style_guide_hdl/Arithmetic:

Table 5-2. Arithmetic Examples Example Up Counter Up Counter with Enable Up Counter with Enable and Load Up Counter with Enable, Load, and Cout Up Counter with Asynchronous Load and Reset Down Counter Description Counter that counts up on each positive clock edge, and rolls over to zero when it reaches 256. Counter that has an enable signal, that stops the counting when the enable signal is low. The counter counts up on each positive clock edge, and rolls over to zero when it reaches 16. Counter that has an enable signal that stops the counting when the enable signal is low, and a load that will load the value in input a when the load is high. Counter that has an active high enable signal, an active high load that loads the value from a, and a cout bit that becomes high when the counter is zero. Counter that has an asynchronous load and reset. The reset resets the count to zero and the load loads the value in input a into the count. Counter that counts down to zero, then rolls over to 256. It has synchronous load and reset signals.

Bidirectional Counter Counter that can count either up or down, as determined by the input up_down. BCD Counter Counter that counts in binary coded decimal. In this case, the counter only counts to 9, then rolls over to 0. There are synchronous load and reset signals, and an enable signal.

172

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators Arithmetic Examples

Table 5-2. Arithmetic Examples Example Adder with Carry-In Adder / Subtractor Description Example of a carry-in adder. The adder adds the two inputs, a and b to the carry-in bit, and outputs the sum. Example of an adder/subtractor that adds the inputs a and b, subtracts the input c from d, increments e by one, and decrements f by one.

Arithmetic Logic Unit Example of an ALU that performs (0) addition (with carry-in), (1) subtraction, (2) and, (3) or, (4) xor, (5) not, (6) nand, (7) nor, (8) xnor, (9) greater than, (10) less than, (11) greater than or equal to, (12) less than or equal to, (13) equality, (14) shift left, and (15) shift right, according to the input sel. Divide By N Example of a divide by n clock divider. It takes an input clock edge, and outputs a high bit every n clock edges, where n is 2^width. The output signal for the divided clock is the divide signal. Example that shows a pipelined multiplier, implemented using a for loop.

Pipelined Multiplier

Precision Synthesis Style Guide, 2011a Update2 November 2011

173

Inferring Arithmetic and Relational Operators Up Counter

Up Counter
Counter that counts up on each positive clock edge, and rolls over to zero when it reaches 256. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY counter_up IS PORT(reset, load : IN STD_LOGIC; clk : IN STD_LOGIC; a : IN UNSIGNED(7 DOWNTO 0); y : OUT UNSIGNED(7 DOWNTO 0) ); END ENTITY; ARCHITECTURE rtl OF counter_up IS SIGNAL cnt : UNSIGNED(7 DOWNTO 0); constant up : STD_LOGIC := 1; BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk = 1) THEN IF (reset = 1) THEN cnt <= 00000000; ELSIF (load = 1) THEN cnt <= a; ELSIF (up = 1) THEN cnt <= cnt + 1; END IF; END IF; END PROCESS; y <= cnt; END ARCHITECTURE;

Verilog
module counter_up (a, clk, reset, load, y); parameter num_range = 256; parameter up = 1; input [7:0] a; input clk, reset, load; output [7:0] y; reg [7:0] cnt; always @(posedge clk) if (reset) cnt <= 0; else if (load) cnt <= a; else if (up) cnt <= cnt + 1; assign y = cnt; endmodule

174

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators Up Counter with Enable

Up Counter with Enable


Counter that has an enable signal, that stops the counting when the enable signal is low. The counter counts up on each positive clock edge, and rolls over to zero when it reaches 16. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY counter_up_en IS GENERIC(width: INTEGER:=4); PORT(clk, en, reset : IN STD_LOGIC; count : OUT UNSIGNED(width-1 DOWNTO 0) ); END ENTITY ; ARCHITECTURE rtl OF counter_up_en IS SIGNAL count_temp:UNSIGNED(width-1 DOWNTO 0); BEGIN count <= count_temp; PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (reset = 1) THEN count_temp <= (OTHERS=>0); ELSIF (en = 1) THEN count_temp <= count_temp + 1; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module counter_up_en (clk, en, count, reset); parameter width = 4; input clk, en, reset; output [width - 1:0] count; reg [width - 1:0] count; always @(posedge clk) if (reset) count = 0; else if (en) count = count + 1; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

175

Inferring Arithmetic and Relational Operators Up Counter with Enable and Load

Up Counter with Enable and Load


Counter that has an enable signal that stops the counting when the enable signal is low, and a load that will load the value in input a when the load is high. The load has priority over the enable. The counter counts up on each positive clock edge, and rolls over to zero when it reaches 16. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY counter_up_en_ld IS GENERIC(width: INTEGER:=4); PORT(clk, en : IN STD_LOGIC; load, reset : IN STD_LOGIC; a : IN UNSIGNED(width-1 DOWNTO 0); count : OUT UNSIGNED (width-1 DOWNTO 0) ); END ENTITY ; ARCHITECTURE rtl OF counter_up_en_ld IS SIGNAL count_temp:UNSIGNED (width-1 DOWNTO 0); BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (reset = 1) THEN count_temp <= (OTHERS=>0); ELSIF (load = 1) THEN count_temp <= a; ELSIF (en = 1) THEN count_temp <= count_temp + 1; END IF; END IF; END PROCESS; count <= count_temp; END ARCHITECTURE;

Verilog
module counter_up_en_load (clk, en, a, load, count, reset); parameter width = 4; input clk, en, load, reset; input [width - 1:0] a; output [width - 1:0] count; reg [width - 1:0] count; always @(posedge clk) if (reset) count <= 0; else if (load) count <= a; else if (en) count <= count + 1; endmodule

176

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators Up Counter with Enable, Load, and Cout

Up Counter with Enable, Load, and Cout


Counter that has an active high enable signal, an active high load that loads the value from a, and a cout bit that becomes high when the counter is zero. The load has priority over the enable. The counter counts up on each positive clock edge, and rolls over to zero at 16. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY counter_up_en_load_cout IS GENERIC(width: INTEGER:=4); PORT(clk, en : IN STD_LOGIC; reset, load: IN STD_LOGIC; a : IN UNSIGNED (width - 1 DOWNTO 0); cout : OUT STD_LOGIC; count : OUT UNSIGNED (width-1 DOWNTO 0) ); END ENTITY; ARCHITECTURE rtl OF counter_up_en_load_cout IS SIGNAL count_temp : UNSIGNED (width-1 DOWNTO 0); CONSTANT max : UNSIGNED (width-1 DOWNTO 0 ) := (OTHERS=>1); BEGIN count <= count_temp; PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (reset = 1) THEN count_temp <= (OTHERS=>0); cout <= 0; ELSIF (load = 1) THEN count_temp <= a; ELSIF (en = 1) THEN count_temp <= count_temp + 1; END IF; IF (count_temp = 0000) THEN cout <= 1; ELSE cout <=0; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module counter_up_en_load_cout (clk, en, load, a, cout, count, reset); parameter width = 4; input clk, en, load, reset; input [width - 1:0] a; output cout; output [width - 1:0] count; reg [width - 1:0] count; reg cout; always @(posedge clk) begin if (reset) count <= 0; else if (load) count <= a; else if (en) count <= count + 1; if (count == 0) cout <= 1; else cout <= 0; end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

177

Inferring Arithmetic and Relational Operators Up Counter with Asynchronous Load and Reset

Up Counter with Asynchronous Load and Reset


Counter that has an asynchronous load and reset. The reset resets the count to zero and the load loads the value in input a into the count. These both operate independent of the clock edge, and therefore must be included in the sensitivity list The counter counts up to 256, then rolls over to zero. VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY counter_up_asynch IS PORT ( a: IN UNSIGNED (7 DOWNTO 0); clk, reset, load: IN STD_LOGIC; y: OUT UNSIGNED (7 DOWNTO 0)); END ENTITY; ARCHITECTURE rtl OF counter_up_asynch IS SIGNAL count : UNSIGNED(7 DOWNTO 0); BEGIN PROCESS (clk, reset, load) BEGIN IF (reset = 1) THEN count <= 00000000; ELSIF (load = 1) THEN count <= a; ELSIF (clkEVENT AND clk = 1) THEN count <= count + 1; END IF; y <= count; END PROCESS; END ARCHITECTURE;

Verilog
module counter_up_asynch (a, clk, reset, load, y); input [7:0] a; input clk, reset, load; output [7:0] y; reg [7:0] cnt; always @(posedge clk or posedge reset or posedge load) if (reset) cnt <= 0; else if (load) cnt <= a; else cnt <= cnt + 1; assign y = cnt; endmodule

178

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators Down Counter

Down Counter
Counter that counts down to zero, then rolls over to 256. It has synchronous load and reset signals. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY counter_down IS PORT(reset, load : IN STD_LOGIC; clk : IN STD_LOGIC; a : IN UNSIGNED(7 DOWNTO 0); y : OUT UNSIGNED(7 DOWNTO 0) ); END ENTITY; ARCHITECTURE rtl OF counter_down IS SIGNAL cnt : UNSIGNED (7 DOWNTO 0); CONSTANT down : STD_LOGIC := 1; BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk = 1) THEN IF (reset = 1) THEN cnt <= 00000000; ELSIF (load = 1) THEN cnt <= a; ELSIF (down = 1) THEN cnt <= cnt - 1; END IF; END IF; END PROCESS; y <= cnt; END ARCHITECTURE;

Verilog
module counter_down (a, clk, reset, load, y); parameter num_range = 256; parameter down = 1; input [7:0] a; input clk, reset, load; output [7:0] y; reg [7:0] cnt; always @(posedge clk) if (reset) cnt <= 0; else if (load) cnt <= a; else if (down) cnt <= cnt - 1; assign y = cnt; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

179

Inferring Arithmetic and Relational Operators Bidirectional Counter

Bidirectional Counter
Counter that can count either up or down, as determined by the input up_down. When up_down is high it counts up, when it is low it counts down. There are also asynchronous load and reset signals. The maximum count value is 256. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY count_updn IS PORT(reset, load : IN STD_LOGIC; updn, clk : IN STD_LOGIC; a : IN UNSIGNED(7 DOWNTO 0); y : OUT UNSIGNED(7 DOWNTO 0) ); END count_updn; ARCHITECTURE rtl OF count_updn IS SIGNAL cnt : UNSIGNED (7 DOWNTO 0); BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk = 1) THEN IF (reset = 1) THEN cnt <= 00000000; ELSIF (load = 1) THEN cnt <= a; ELSIF (updn = 1) THEN cnt <= cnt + 1; ELSE cnt <= cnt - 1; END IF; END IF; END PROCESS; y <= cnt; END ARCHITECTURE;

Verilog
module bidir_counter (a, clk, reset, load, up_down, y); input [7:0] a; input clk, reset, load, up_down; output [7:0] y; reg [7:0] cnt; always @(posedge clk) if (reset) cnt <= 0; else if (load) cnt <= a; else if (up_down) cnt <= cnt + 1; else cnt <= cnt - 1; assign y = cnt; endmodule

180

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators BCD Counter

BCD Counter
Counter that counts in binary coded decimal. In this case, the counter only counts to 9, then rolls over to 0. There are synchronous load and reset signals, and an enable signal. VHDL
LIBRARY ieee ; USE ieee.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; ENTITY counter_bcd IS PORT(en, reset : IN STD_LOGIC; clk, load : IN STD_LOGIC; a : IN UNSIGNED(3 DOWNTO 0); count : OUT UNSIGNED (3 DOWNTO 0); cout : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF counter_bcd IS SIGNAL count_temp : UNSIGNED (3 DOWNTO 0); BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (reset = 1) THEN count_temp <= 0000; ELSIF (load = 1) THEN count_temp <= a; ELSIF (count_temp = 9) THEN count_temp <= 0000; cout <= 1; ELSIF (en = 1) THEN count_temp <= count_temp+1; cout <= 0; END IF; END IF; END PROCESS; count <= count_temp; END ARCHITECTURE;

Verilog
module counter_bcd (clk, en, reset, load, a, count, cout); input clk, en, reset, load; input [3:0] a; output cout; output [3:0] count; reg cout; reg [3:0] count; always @(posedge clk) if (reset) count <= 0; else if (load) count <= a; else if (count == 9) begin count <= 0; cout <= 1; end else if (en) begin count <= count + 1; cout <= 0; end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

181

Inferring Arithmetic and Relational Operators Adder with Carry-In

Adder with Carry-In


Example of a carry-in adder. The adder adds the two inputs, a and b to the carry-in bit, and outputs the sum. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY adder_cin IS GENERIC (width : INTEGER := 4); PORT (a, b : IN UNSIGNED (width-1 DOWNTO 0); cin : IN STD_LOGIC; sum: OUT UNSIGNED (width DOWNTO 0)); END ENTITY; ARCHITECTURE rtl OF adder_cin IS BEGIN PROCESS (a, b, cin) BEGIN IF (cin = 1) THEN sum <= (0 & a) + (0 & b) + 1; ELSE sum <= (0 & a) + (0 & b); END IF; END PROCESS; END ARCHITECTURE;

Verilog
module adder_cin (a, b, cin, sum); parameter width = 4; input [width - 1:0] a; input [width - 1:0] b; input cin; output [width:0] sum; reg [width:0] sum; always @(a or b or cin) if (cin) sum = {1b0,a} + {1b0,b} + 1; else sum = {1b0,a} + {1b0,b}; endmodule

182

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators Adder / Subtractor

Adder / Subtractor
Example of an adder/subtractor that adds the inputs a and b, subtracts the input c from d, increments e by one, and decrements f by one. VHDL
LIBRARY ieee ; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY addsub IS PORT (a, b, c, d, e, f : IN UNSIGNED (3 DOWNTO 0); add, sub, inc, dec : OUT UNSIGNED (3 DOWNTO 0)); END ENTITY; endmodule ARCHITECTURE rtl OF addsub IS BEGIN add <= a + b; sub <= c - d; inc <= e + 1; dec <= f - 1; END ARCHITECTURE;

Verilog
module addsub (a, b, c, d, e, f, add, sub, inc, dec); input [3:0] a, b, c, d, e, f; output [3:0] add, sub, inc, dec; assign assign assign assign add sub inc dec = = = = a c e f + + b; d; 1; 1;

Precision Synthesis Style Guide, 2011a Update2 November 2011

183

Inferring Arithmetic and Relational Operators Arithmetic Logic Unit

Arithmetic Logic Unit


Example of an ALU that performs (0) addition (with carry-in), (1) subtraction, (2) and, (3) or, (4) xor, (5) not, (6) nand, (7) nor, (8) xnor, (9) greater than, (10) less than, (11) greater than or equal to, (12) less than or equal to, (13) equality, (14) shift left, and (15) shift right, according to the input sel. VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY ALU IS PORT ( cin : IN STD_LOGIC; sel : IN UNSIGNED (3 DOWNTO 0); a, b : IN UNSIGNED (7 DOWNTO 0); cout: OUT STD_LOGIC; y: OUT UNSIGNED (7 DOWNTO 0) ); END ENTITY; ARCHITECTURE rtl OF ALU IS SIGNAL temp: UNSIGNED (8 DOWNTO 0); BEGIN PROCESS (sel, a, b, cin) BEGIN cout <= 0; y <= 00000000; CASE (sel) IS WHEN 0000 => temp <= (0 & a) + (0 & b) + (0 & cin); y <= temp (7 DOWNTO 0); cout <= temp (8); WHEN 0001 => y <= a - b; IF (a < b) THEN cout <= 1; ELSE cout <= 0; END IF; WHEN 0010 => y <= a AND b; WHEN 0011 => y <= a OR b; WHEN 0100 => y <= a XOR b; WHEN 0101 => y <= NOT a; WHEN 0110 => y <= a nor b; WHEN 0111 => y <= a NAND b; WHEN 1000 => y <= a XNOR b; WHEN 1001 => IF (a > b) THEN cout <= 1; ELSE cout <= 0; END IF; WHEN 1010 => IF (a < b) THEN cout <= 1; ELSE cout <= 0; END IF; WHEN 1011 =>

184

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators Arithmetic Logic Unit IF (a >= b) THEN cout <= 1; ELSE cout <= 0; END IF; WHEN 1100 => IF (a <= b) THEN cout <= 1; ELSE cout <= 0; END IF; WHEN 1101 => IF (a = b) THEN cout <= 1; ELSE cout <= 0; END IF; WHEN 1110 => y <= shift_left (a, 1); WHEN 1111 => y <= shift_right (b, 1); WHEN OTHERS => y <= XXXXXXXX; END CASE; END PROCESS; END ARCHITECTURE;

Precision Synthesis Style Guide, 2011a Update2 November 2011

185

Inferring Arithmetic and Relational Operators Arithmetic Logic Unit

Verilog
module ALU (sel, a, b, cin, cout, y); input cin; input [7:0] sel, a, b; output cout; output [7:0] y; reg cout; reg [7:0] y; reg [8:0] temp; always @ (sel or a or b or cin) begin cout = 0; y = 8b00000000; case (sel) 4b0000: begin temp = a + b + cin; y = temp [7:0]; cout = temp [8]; end 4b0001: begin y = a - b; cout = (a > b) ? 1 : 0; end 4b0010: y = a & b; 4b0011: y = a | b; 4b0100: y = a ^ b; 4b0101: y = !a; 4b0110: y = !(a | b); 4b0111: y = !(a & b); 4b1000: y = a ~^ b; 4b1001: cout = (a > b) ? 1 : 0; 4b1010: cout = (a < b) ? 1 : 0; 4b1011: cout = (a >= b) ? 1 : 0; 4b1100: cout = (a <= b) ? 1 : 0; 4b1101: cout = (a == b) ? 1 : 0; 4b1110: y = a << 1; 4b1111: y = b >> 1; endcase end endmodule

186

Precision Synthesis Style Guide, 2011a Update2 November 2011

Inferring Arithmetic and Relational Operators Divide By N

Divide By N
Example of a divide by n clock divider. It takes an input clock edge, and outputs a high bit every n clock edges, where n is 2^width. The output signal for the divided clock is the divide signal. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; ENTITY divide_by_n IS generic (width : NATURAL := 8); PORT (data_in : IN UNSIGNED (width-1 DOWNTO 0); load : IN STD_LOGIC; clk : IN STD_LOGIC; reset : IN STD_LOGIC; divide : OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF divide_by_n IS SIGNAL cnt_reg : UNSIGNED (width-1 DOWNTO 0); constant max_cnt : UNSIGNED (width1 DOWNTO 0) := (OTHERS=>1); BEGIN cnt_it : PROCESS (clk, reset) BEGIN IF (reset = 1) THEN cnt_reg <= (OTHERS => 0); ELSIF (clk = 1 AND clkEVENT) THEN IF (load = 1) THEN cnt_reg <= data_in; ELSE cnt_reg <= cnt_reg+01; END IF; END IF; END PROCESS; divide <= 1 WHEN cnt_reg = max_cnt ELSE 0; END ARCHITECTURE ;

Verilog
module divide_by_n (data_in, load, clk, reset, divide); parameter width = 8; input [width-1:0] data_in; input load, clk, reset; output divide; wire divide; wire [width-1:0] max_cnt = (1 << width) -1; reg [width-1:0] cnt_reg; always @(posedge clk or posedge reset) if (reset) cnt_reg <= 0; else if (load) cnt_reg <= data_in; else cnt_reg <= cnt_reg + 1; assign divide = (cnt_reg==max_cnt) ? 1 : 0; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

187

Inferring Arithmetic and Relational Operators Pipelined Multiplier

Pipelined Multiplier
Example that shows a pipelined multiplier, implemented using a for loop. VHDL
LIBRARY ieee ; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY pipelined_mult IS generic (size : INTEGER := 16; level : INTEGER := 4); PORT (a : IN UNSIGNED (size-1 DOWNTO 0); b : IN UNSIGNED (size-1 DOWNTO 0); clk : IN STD_LOGIC; y : OUT UNSIGNED (2*size-1 DOWNTO 0)); END ENTITY; ARCHITECTURE rtl OF pipelined_mult IS TYPE levels_of_registers IS array (level-1 DOWNTO 0) OF UNSIGNED (2*size-1 DOWNTO 0); SIGNAL a_int,b_int : UNSIGNED (size-1 DOWNTO 0); SIGNAL pdt_int : levels_of_registers; BEGIN y <= UNSIGNED (pdt_int (level-1)); PROCESS(clk) BEGIN IF (clkEVENT AND clk = 1) THEN a_int <= UNSIGNED (a); b_int <= UNSIGNED (b); pdt_int(0) <= a_int * b_int; FOR i IN 1 TO level-1 LOOP pdt_int (i) <= pdt_int (i-1); END LOOP; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module pipelined_multiplier (a, b, clk, y); parameter size = 16, level = 4; input [size-1 : 0] a; input [size-1 : 0] b; input clk; output [2*size-1 : 0] y; reg [size-1 : 0] a_int, b_int; reg [2*size-1 : 0] pdt_int [level-1 : 0]; integer i; assign y = pdt_int [level-1]; always @ (posedge clk) begin a_int <= a; b_int <= b; pdt_int[0] <= a_int * b_int; for (i = 1; i < level; i = i + 1) pdt_int [i] <= pdt_int [i-1]; end endmodule

188

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 6 Boolean Logic


Boolean Logic, or combinational logic, is made up of the basic gates. This is created using conditional statements, such as an if-then-else or case statement.

Common Guidelines
Synthesis tools implement boolean logic from boolean logic operators in the HDL design or can be inferred.

VHDL/Verilog Differences
The following table shows the boolean operators for VHDL and Verilog: Table 6-1. VHDL and Verilog Boolean Operators Boolean Operator AND OR XOR NOT NAND NOR XNOR VHDL and or xor not nand nor xnor Verilog && (logical) || (logical) ^ (logical) ! (logical) & (bitwise) | (bitwise) ^ (bitwise) ~ (bitwise)

no explicit operator no explicit operator ~^ or ^~ (bitwise)

Optimization Issues
The following subsections describe some of the optimization issues that may be encountered when inferring boolean logic.

Unintended Combinatorial Loops (Latches)


According to the VHDL LRM, if nothing is assigned to a signal during a run through a process, the signal must retain its old value. In synthesis, If no assignment is made to a signal in a combinatoric process, combinational loops (latches) have to be generated to preserve the old value.

Precision Synthesis Style Guide, 2011a Update2 November 2011

189

Boolean Logic Optimization Issues

Incomplete CASE statement


Not assigning a value to a signal during an iteration through a process infers a latch. Typically, these are really dont care conditions. Assigning the signal to some value will be less costly in terms of area. In this example, we see that not assigning to out_sig in the clause for state3 implies a latch. As a general rule, every clause in a case statement should assign a value to the same outputs.

PROCESS (curr_state,a,b); BEGIN CASE curr_state IS WHEN state1 => next_state <= state2; out_sig <= a; WHEN state2 => next_state <= state3; out_sig <= b; WHEN state3 => next_state <= state1; -- No assignment to out_sig END CASE; end process

next_state curr_state A B

out_sig

next_state(0)

next_state(1) curr_state(0) curr_state(1) a b out_sig

To fix this problem you can assign the out_sig signal a value before the case statement is entered, thus removing the implied latch. The resulting design is 30% smaller, and does not have combinatoric feedback which will require latching. It is important to understand that omitting a VHDL statement can imply extra logic!

190

Precision Synthesis Style Guide, 2011a Update2 November 2011

Boolean Logic Optimization Issues

PROCESS (curr_state,a,b); BEGIN out_sig <= 0; -- default CASE curr_state IS WHEN state1 => next_state <= state2; out_sig <= a; curr_state(0) WHEN state2 => curr_state(1) next_state <= state3; a out_sig <= b; WHEN state3 => next_state <= state1; b END CASE; end process;

next_state(0

next_state(1)

out_sig

Incomplete IF statements
IF-THEN-ELSE statements can also be incomplete. For example, consider the following:
PROCESS(a,b,c,d) BEGIN IF (a = 1) THEN out_sig <= x; ELSIF (b = 1) THEN out_sig <= y; ENDIF; END PROCESS;

Note that a latch is required to hold the value in the case where a=b=0. To eliminate this latch, you could add an ELSE clause.

Incomplete Reset Conditions


In this example, count_old must be retained when reset is 0. This causes a loop to be created. This is likely not the intended results.
PROCESS (clk, reset); BEGIN if (reset = 0) then count <= 0; elsif rising_edge(clk) then count_old <= count; count <= count + 1; end if; end process; count_old

is not assigned in the reset condition. The value must be retained

Precision Synthesis Style Guide, 2011a Update2 November 2011

191

Boolean Logic Attributes Relating to Boolean Logic

DESIRED RESULT
+1

ACTUAL RESULT
0 Count_old +1 1 Count_old

Clock

Reset

Clock

Reset

Using Variables before they are assigned


Synthesis ignores the simulation initial value assigned to temp. Synthesis only recognizes hardware resets. With this in mind, you can see that the variable temp on the (right-hand side) of the assignment does not have a value the first time through the loop. This occurs each time d changes. So the old value will be latched.
ENTITY parity is PORT (d : IN std_logic_vector(7 DOWNTO 0); y : OUT std_logic); END parity; ARCHITECTURE comb_loop OF parity is BEGIN PROCESS (d) VARIABLE temp : std_logic := 0; BEGIN FOR i IN dRANGE LOOP temp := temp XOR d(i); -- Used Before Assigned! END LOOP; y <= temp; END PROCESS; END comb_loop;

Attributes Relating to Boolean Logic


The following attributes affect boolean logic: array_pin_number: This VHDL only attribute makes it easier to assign pin numbers to buses. preserve_driver: added to a net to retain the driving gate through optimization. This attribute may prevent some optimization with the surrounding logic but it will keep the logic and the net name. This attribute is typically used when you need to retain a signal name for additional constraints or simulation points. preserve_z: prevents tri-states from being mapped to MUX logic.

192

Precision Synthesis Style Guide, 2011a Update2 November 2011

Boolean Logic Boolean Examples

Boolean Examples
The following table shows the VHDL and Verilog examples described in this section. The code files are available in the Precision Synthesis software tree in the following directory:
<precision_install_dir>/shared/examples/style_guide_hdl/Boolean_Logic

Table 6-2. Boolean Logic Examples Example Basic Gates Tri-State Tri-State Bus Bi-Directional Bus Generic Width Decoder Seven Segment Decoder Priority Encoder Multiplexer Parallel Mux Serial Mux Description Example that demonstrates how to create each of the basic gates. Example of how to implement tri-state logic. This third state is the high-impedance state. Example of a generic width tri-state bus with the width set to 4. A bus is an array of bits with (multiple) three-state drivers. Example of a generic width bi-directional bus set to a width of 4. Example of a generic width decoder. The width in and width out are specified in the entity. This decoder has an input width of 2, and an output width of 4. Example of a decoder that could be used with a seven segment LED display. Example of an 8-bit priority encoder. Example of a generic bus width 8 to 1 multiplexer. It is implemented using a case statement. Example of a parallel multiplexer. All inputs have equal priority in a parallel MUX. Example design that creates a series of muxes, which forms priority using if statements.

Precision Synthesis Style Guide, 2011a Update2 November 2011

193

Boolean Logic Basic Gates

Basic Gates
Example that demonstrates how to create each of the basic gates.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY basic_gates IS PORT (a, b: IN STD_LOGIC; y_and, y_or, y_xor, y_not, y_nand, y_nor, y_xnor: OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF basic_gates IS BEGIN y_and <= a AND b; y_or <= a OR b; y_xor <= a XOR b; y_not <= NOT a; y_nand <= a NAND b; y_nor <= a NOR b; y_xnor <= a XNOR b; END ARCHITECTURE;

Verilog
module basic_gates (a, b, y_and, y_or, y_xor, y_not, y_nand, y_nor, y_xnor); input a, b; output y_and, y_or, y_xor, y_not, y_nand, y_nor, y_xnor; assign assign assign assign assign assign assign endmodule y_and = a & b; y_or = a | b; y_xor = a ^ b; y_not = ~a; y_nand = !(a & b); y_nor = !(a | b); y_xnor = a ~^ b;

194

Precision Synthesis Style Guide, 2011a Update2 November 2011

Boolean Logic Tri-State

Tri-State
Example of how to implement tri-state logic. This third state is the high-impedance state. In VHDL, you cannot have a BIT type variable when using tri-states; instead, use the STD_LOGIC type. A tri-state gives a third possible state on top of the standard high and low logic levels. This is called high-impedance, and is specified using the letter Z. In the conditional clause of the signal assignment, both a and en can be full expressions. Precision RTL Synthesis generates combinational logic driving the input or the enable of the tristate buffer for these expressions. However, the use of the z value in an expression is illegal.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY tristate IS PORT(a, en : IN STD_LOGIC; y : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF tristate IS BEGIN y <= a WHEN (en = 1) ELSE Z; END ARCHITECTURE;

Verilog
module tristate (a, en, y); input a, en; output y; assign y = en ? a : 1bZ; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

195

Boolean Logic Tri-State Bus

Tri-State Bus
Example of a generic width tri-state bus with the width set to 4. A bus is an array of bits with (multiple) threestate drivers. In VHDL, the type of the bus signal should be std_logic_vector, because the BIT type does not support tri-states. The Z character for tri-states has to be a string literal when used in a bus. You can still introduce a data conflict with tristates by enabling more than one tristate on a net. Precision RTL Synthesis does not check for a possible bus conflict. Make sure that you can never have that possibility by carefully generating the enable signals for the tristate conditions. These examples show assignments to outputs. However, it is certainly possible to do the assignments to an internal wire as well.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY tristate_bus IS GENERIC(width : INTEGER := 4); PORT(en : IN STD_LOGIC; a : IN UNSIGNED(width-1 DOWNTO 0); y : OUT UNSIGNED(width-1 DOWNTO 0) ); END ENTITY ; ARCHITECTURE rtl OF tristate_bus IS BEGIN y <= a WHEN (en=1) ELSE (OTHERS=>Z); END ARCHITECTURE;

Verilog
module tristate_bus (a, en, y); parameter width = 4; input [width - 1:0] a; input en; output [width - 1:0] y; assign y = en ? a : 4bZ; endmodule

196

Precision Synthesis Style Guide, 2011a Update2 November 2011

Boolean Logic Bi-Directional Bus

Bi-Directional Bus
Example of a generic width bi-directional bus set to a width of 4. Bidirectional I/O buffers will be created if an external port is both used and assigned inside the architecture. If the output itself is used again internally, the port must be declared to be inout. An enable signal could also be generated from inside the architecture, instead of being a primary input. If needed, a suitable bidirectional buffer is selected from the target technology library. If there is no bidirectional buffer available, it selects a combination of a three-state buffer and an input buffer.

Example 6-1. VHDL Bi-Directional Bus


LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY bidir_bus IS GENERIC(width : INTEGER := 4); PORT( bidir : INOUT UNSIGNED(width-1 DOWNTO 0); out_enable : IN STD_LOGIC; a : IN UNSIGNED(width-1 DOWNTO 0); y : OUT UNSIGNED(width-1 DOWNTO 0) ); END ENTITY ; ARCHITECTURE rtl OF bidir_bus IS BEGIN y <= bidir; bidir <= a WHEN out_enable = 1 ELSE (OTHERS => Z); END ARCHITECTURE;

Example 6-2. Verilog Bi-Directional Bus


module bidir_bus (bidir, out_enable, a, y); parameter width = 4; input out_enable; input [width-1:0] a; output [width-1:0] y; inout [width-1:0] bidir; wire [width-1:0] y, a; assign y = bidir; assign bidir = out_enable ? a : 4bz; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

197

Boolean Logic Generic Width Decoder

Generic Width Decoder


Example of a generic width decoder. The width in and width out are specified in the entity. This decoder has an input width of 2, and an output width of 4.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY decoder_gen IS GENERIC(widthin : INTEGER := 2; widthout : INTEGER := 4); PORT(a : IN UNSIGNED(widthin-1 DOWNTO 0); y : OUT UNSIGNED(widthout-1 DOWNTO 0)); END ENTITY; ARCHITECTURE rtl OF decoder_gen IS BEGIN PROCESS (a) BEGIN FOR i IN 0 TO widthout - 1 LOOP IF (to_integer(a) = i) THEN y(i) <= 1; ELSE y(i) <= 0; END IF; END LOOP; END PROCESS; END ARCHITECTURE;

Verilog
module decoder_gen (a, y); parameter widthin = 2; parameter widthout = 4; input [widthin - 1:0] a; output [widthout - 1:0] y; reg [widthout - 1:0] y; integer i; always @(a) for (i=0; i<=widthout-1; i=i+1) if (a == i) y[i] = 1; else y[i] = 0; endmodule

198

Precision Synthesis Style Guide, 2011a Update2 November 2011

Boolean Logic I/O Buffers

I/O Buffers
IO Buffers must be added to a design before it can go through place and route. Precision provides several options by which you can specify the IO buffers to use. By default, Precision RTL Synthesis automatically assigns I/O buffers to the ports of you design unless you turn off the feature from the GUI pulldown menu Tools > Set Options... Input > Options > Add IO Pads. You can also disable the feature with the command setup_design addio=false. You can also overwrite any default buffer assignment that Precision RTL Synthesis may make by assigning the buffer_sig attribute to a port or a net. In addition, you may also choose to instantiate the buffer component directly into the design. Either way, it is important to realize that if you specify buffer names in the HDL source, Precision RTL Synthesis checks the source technology library to find the buffer you are requesting. If the buffer is not found, an error occurs. The following list describes the available methods on inserting two-terminal IO buffers into your design: HDL Instantiation. You can directly instantiate buffers as vender cells. This approach gives you full control, which may be necessary if the buffer is complex (more than two pins). The disadvantage is that it will make the HDL design become technology specific. Consider the following code segment:

module special_buffer_example (inp, clk, outp, inoutp) ; input inp, clk ; output outp ; inout inoutp ; wire intern_in, intern_out, io_control ; OUTPUT_FF A1(.c(clk), .d(intern_out), .t(io_control),.o(inoutp)); INPUT_BUFFER A2(.i(inp), .o(intern_in)) ; endmodule

In this example, component instantiation forces an OUTPUT_FF buffer (complex I/O output/flip-flop buffer) on the bidirectional pin inoutp. Also an input buffer INPUT_BUFFER is specified to pick up the value from inp to be used internally. In the case of component instantiation of I/O buffers, the right source technology must be specified when you setup the design to assure that Precision RTL Synthesis takes the instantiated I/O buffer from the right library. buffer_sig attribute. This attribute is attached to a port in the source VHDL. This also makes your HDL source code technology specific, but attributes can be over-ridden in the synthesis tool, so it is less of a problem to re-target a design. Automatic IO Instantiation. During synthesize, IO buffers will be placed on external signals. In addition, many technologies buffer clock signals with special buffers. The control over the buffer selection is limited here, but if the results are ok, this is certainly the easiest and most technology-independent method. This option is chosen via a checkbox in the Setup Design dialog box.
199

Precision Synthesis Style Guide, 2011a Update2 November 2011

Boolean Logic Seven Segment Decoder

Seven Segment Decoder


Example of a decoder that could be used with a seven segment LED display.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY seven_seg_dec IS

Verilog
module seven_seg_dec (a, y); input [3:0] a; output [6:0] y; reg [6:0] y;

PORT( a : IN UNSIGNED(3 DOWNTO 0); y : OUT UNSIGNED(6 DOWNTO 0)); END ENTITY ; ARCHITECTURE rtl OF seven_seg_dec IS BEGIN PROCESS (a) BEGIN CASE a IS WHEN 0000 => y <= 1111110; WHEN 0001 => y <= 0100000; WHEN 0010 => y <= 1101101; WHEN 0011 => y <= 1111001; WHEN 0100 => y <= 0110011; WHEN 0101 => y <= 1011011; WHEN 0110 => y <= 1011111; WHEN 0111 => y <= 1110000; WHEN 1000 => y <= 1111111; WHEN 1001 => y <= 1111011; WHEN OTHERS => Y <= 1111110; END CASE; END PROCESS; END ARCHITECTURE;

always @(a) case (a) 0 : y = 1 : y = 2 : y = 3 : y = 4 : y = 5 : y = 6 : y = 7 : y = 8 : y = 9 : y = default endcase endmodule

7b 1111110; 7b 0100000; 7b 1101101; 7b 1111001; 7b 0110011; 7b 1011011; 7b 1011111; 7b 1110000; 7b 1111111; 7b 1111011; : y = 7b 1111110;

200

Precision Synthesis Style Guide, 2011a Update2 November 2011

Boolean Logic Priority Encoder

Priority Encoder
Example of an 8-bit priority encoder. In this case, priority is given to the highest bit that is set in the input bits.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY priority_encoder IS PORT(a : IN unsigned(7 DOWNTO 0); valid : OUT STD_LOGIC; y : OUT unsigned(2 DOWNTO 0)); END ENTITY ; ARCHITECTURE rtl OF priority_encoder IS BEGIN PROCESS (a) BEGIN valid <= 0; y <= XXX; FOR i IN 7 DOWNTO 0 LOOP IF (a(i) = 1) THEN y <= to_unsigned(i,3); valid <= 1; exit; END IF; END LOOP; END PROCESS; END ARCHITECTURE;

Verilog
module priority_encoder (a, valid, y); input [7:0] a; output valid; output [2:0] y; integer i; reg valid; reg [2:0] y; always @ (a) begin valid = 0; y = 3b X; for (i = 0; i < 8; i = i + 1) if (a[i]) begin valid = 1; y = i; end end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

201

Boolean Logic Multiplexer

Multiplexer
Example of a generic bus width 8 to 1 multiplexer. It is implemented using a case statement.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY mux_8to1 IS GENERIC(width : INTEGER := 4); PORT (Sel : IN INTEGER RANGE 0 TO 7; a0,a1 : IN UNSIGNED(width-1 DOWNTO 0); a2,a3 : IN UNSIGNED(width-1 DOWNTO 0); a4,a5 : IN UNSIGNED(width-1 DOWNTO 0); a6,a7 : IN UNSIGNED(width-1 DOWNTO 0); y : OUT UNSIGNED(width-1 DOWNTO 0)); END ENTITY; ARCHITECTURE rtl OF mux_8to1 IS BEGIN PROCESS (Sel,a0,a1,a2,a3,a4,a5,a6,a7) BEGIN CASE Sel IS WHEN 0 => y <= a0; WHEN 1 => y <= a1; WHEN 2 => y <= a2; WHEN 3 => y <= a3; WHEN 4 => y <= a4; WHEN 5 => y <= a5; WHEN 6 => y <= a6; WHEN 7 => y <= a7; END CASE; END PROCESS; END ARCHITECTURE;

Verilog
module mux_8to1 (sel, a0, a1, a2, a3, a4, a5, a6, a7, y); parameter width = 4; input [2:0] sel; input [width - 1:0] a0, a1, a2, a3; input [width - 1:0] a4, a5, a6, a7; output [width - 1:0] y; reg [width - 1:0] y; always @ (sel or a0 or a1 or a2 or a3 or a4 or a5 or a6 or a7) case (sel) 0 : y = a0; 1 : y = a1; 2 : y = a2; 3 : y = a3; 4 : y = a4; 5 : y = a5; 6 : y = a6; 7 : y = a7; default : y = a0; endcase endmodule

202

Precision Synthesis Style Guide, 2011a Update2 November 2011

Boolean Logic Parallel Mux

Parallel Mux
Example of a parallel multiplexer. All inputs have equal priority in a parallel MUX.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY parallel_mux IS PORT(a, b, c, d : IN std_logic; sel : IN unsigned(1 DOWNTO 0); muxout : OUT std_logic ); END ENTITY; ARCHITECTURE rtl OF parallel_mux IS BEGIN PROCESS (a, b, c, d, sel) IS BEGIN CASE sel IS WHEN 00 => muxout <= a; WHEN 01 => muxout <= b; WHEN 10 => muxout <= c; WHEN OTHERS => muxout <= d; END CASE; END PROCESS; END ARCHITECTURE;

Verilog
module parallel_mux (a, b, c, d, sel, muxout); input a, b, c, d; input [1:0] sel; output muxout; reg muxout; always @(a or b or c or d or sel) case (sel) 2b00 : muxout = a; 2b01 : muxout = b; 2b10 : muxout = c; default : muxout = d; endcase endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

203

Boolean Logic Serial Mux

Serial Mux
Example design that creates a series of muxes, which forms priority using if statements. In this design, priority is given to z, then y, and then x.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY serial_mux IS PORT( a, b, c, d : IN STD_LOGIC; x, y, z : IN STD_LOGIC; outp : OUT STD_LOGIC ); END ENTITY; ARCHITECTURE rtl OF serial_mux IS BEGIN PROCESS (a, b, c, d, x, y, z) BEGIN IF z = 1 THEN outp <= a; ELSIF y = 1 THEN outp <= b; ELSIF x = 1 THEN outp <= c; ELSE outp <= d; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module serial_mux (a, b, c, d, x, y, z, outp); input a, b, c, d; input x, y, z; output outp; reg outp; always @(a or b or c or d or x or y or z) if (z) outp = a; else if (y) outp = b; else if (x) outp = c; else outp = d; endmodule

204

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 7 Registers
HDL synthesis produces registered and combinational logic. All combinational behavior around the registers is, unless prohibited by the user, optimized automatically. The style of coding combinational behavior, such as if-then-else and case statements, has some effect on the final circuit result, but the style of coding sequential behavior has significant impact on your design. The purpose of this section is to show how sequential behavior is produced with VHDL and Verilog, so that you understand why registers are generated at certain places and not in others.

Common Guidelines
A level sensitive latch is generated anytime a signal must retain its value until being set again. An edge triggered flip-flop is generated if a signal assignment is executed only on the leading (or only on the trailing) edge of another signal. For that reason, the condition under which the assignment is done must include an edge-detecting construct. The three most added features to a latch or flip flop are the reset, set, and clock enable signals. The set and reset signal can be either synchronous or asynchronous, depending on how they need to function.

Synchronous Sets and Resets


All conditional assignments to the output variable translate into combinational logic in front of the D-input of the flip-flop. For instance, we can make a synchronous reset on the flip-flop by doing a conditional assignment to the output that assigns the output to zero if the reset input is high. Any variable meant as a synchronous set or reset should not be included in the sensitivity list for the block.

Asynchronous Sets and Resets


If we want the reset signal to have immediate effect on the output, but still want the regular assignment to the output to happen on the leading clock edge, we require the behavior of an asynchronous reset. In order to have an asynchronous set or reset, the input signal MUST be in the sensitivity list. If it is not in the sensitivity list, the block will not be executed when the variable changes. Asynchronous set and reset can both be used. This results in combinational logic driving the set and reset input of the flip-flop of the target signal. There can be several asynchronous conditional clauses, but any asynchronous assignments must have higher priority than the synchronous assignments. A flip-flop is generated for each signal that is assigned in the

Precision Synthesis Style Guide, 2011a Update2 November 2011

205

Registers VHDL / Verilog Differences

synchronous signal assignment. The asynchronous clauses result in combinational logic that drives the set and reset inputs of the flip-flops. If there is no synchronous clause, all logic becomes combinational.

Clock Enable
It is also possible to specify an enable signal in a process. Some technologies (specifically Xilinx and Altera) have a special enable pin on their basic flip-flop. The synthesis tools recognize the function of the enable from the HDL description and generate a flip-flop with an enable signal, when specified in code. If an enable pin does not exist in the target technology a multiplexer is generated in front of the data input of the flip-flop.

VHDL / Verilog Differences


The following subsections highlight some of the differences between VHDL and Verilog:

Determining the Clock Edge


In VHDL, the EVENT attribute on a signal is the most commonly used edge-detecting mechanism. The EVENT attribute operates on a signal and returns a boolean. The result is always FALSE, unless the signal showed a change (edge) in value. If the signal started the process by a change in value, the EVENT attribute is TRUE all the way through the process. The attribute STABLE is the boolean inversion of the EVENT attribute. Hence, CLK'EVENT is the same as NOT CLK'STABLE. Another way to generate registers in VHDL is by using the wait until statement. The wait until clause can be used in a process, and is synthesizable, as long as all of the control paths inside the process contain at least one wait statement. There is no sensitivity list on this process. In VHDL, a process can have a sensitivity list or a wait statement, but not both. In this example, the process is executed if clk changes since clk is present in the wait condition. Also, the wait condition can be simplified to wait until clk=1, since the process only starts if clk changes, and thus clk'event is always true. Multiple wait statements per process are also supported as long as all of the statements have the same wait until clause. In Verilog, the two most commonly used constructs are posedge and negedge. The posedge construct detects transitions (is true) from 0 to 1. The negedge construct detects transitions from 1 to 0. In VHDL, synchronous signals are allowed to be on the sensitivity list for the process. In Verilog, only asynchronous signals appear in the sensitivity list.

206

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers VHDL / Verilog Differences

Asynchronous set and reset


For an asynchronous set or reset, both languages require the signals to be included in the sensitivity list. However, they react differently if it is left out. In VHDL, if the reset signal was set, the process would start anytime there was a clock event, up or down. This behavior cannot be synthesized into logic. In Verilog, the asynchronous reset would be synthesize the same as a synchronous reset.

VHDL Wait Statements


until

Another way to generate registers in VHDL is by using the wait until statement. The wait clause can be used in a process, and is synthesizable, as long as all of the control paths inside the process contain at least one wait statement. The following code fragment generates an edge triggered flip-flop between signal input_foo and output_foo:
signal input_foo, output_foo, clk : bit ; ... process begin wait until clkevent and clk=1 ; output_foo <= input_foo ; end process ;

There is no sensitivity list on this process. In VHDL, a process can have a sensitivity list or a wait statement, but not both. In this example, the process is executed if clk changes since clk is present in the wait condition. Also, the wait condition can be simplified to wait until clk=1 ;, since the process only starts if clk changes, and thus clk'event is always true. Multiple wait statements per process are also supported as long as all of the statements have the same wait until clause. Precision RTL Synthesis does not support asynchronous reset behavior with wait statements. A synchronous reset remains possible however, by describing the reset behavior after the wait statement.

Predefined Flip-flops and Latches


Flip-flops and latches can also be generated by using predefined VHDL procedures from the exemplar package. These procedure calls cause Precision RTL Synthesis to instantiate the required flip-flop or D-latch. There are various forms of these procedures available, including versions with asynchronous preset and clear.

VHDL Variables
Variables (like signals) can also generate flip-flops. Since the variable is defined in the process itself, and its value never leaves the process, the only time a variable generates a flip-flop is

Precision Synthesis Style Guide, 2011a Update2 November 2011

207

Registers Optimization Issues

when the variable is used before it is assigned in a clocked process. For instance, the following code segment generates a three-bit shift register.
signal input_foo, output_foo, clk : bit ; ... process (clk) variable a, b : bit ; begin if (clkevent and clk=1) then output_foo <= b ; b := a ; a := input_foo ; end if ; end process ;

In this case, the variables a and b are used before they are assigned. Therefore, they pass their values from the last run through the process, which is the assigned value delayed by one clock cycle. If the variables are assigned before they are used, you will get a different circuit:
signal input_foo, output_foo, clk : bit ; ... process (clk) variable a, b : bit ; begin if (clkevent and clk=1) then a := input_foo ; b := a ; output_foo <= b ; end if ; end process ;

Here, a and b are assigned before they are used, and therefore do not generate flip-flops. Instead, they generate a single wire. Only one flip-flop remains in between.

Optimization Issues
The following list shows some of the reasons why Precision may replicate or remove registers from the RTL design: Excessive fanout: If the load is too large, the load may be split between multiple drivers, or the load may be cut and the driver duplicated. Moving the Flip-Flop to an Input/Output Block: If the flip flop does not use the set, reset, or clock enable pins, it can be placed into an IO block. This decreases the external setup time, in exchange for an increase in the internal setup time. The number of logic blocks used can also be decreased.

208

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Attributes That Affect Registers

Attributes That Affect Registers


The following list summaries the attributes that affect register replication and IO placement: dont_retime: Specifies that the retiming algorithm can be disabled on individual registers or modules. inff: Tells Precision Synthesis whether or not to map the first register in the input path to a register in the IO block. By default, Precision maps the first register to the IO block if this attribute is not present. The attribute is applied to the input port. iob (Xilinx only): Specifies that the placement of the register is to be forced into the IOB. This may increase the IO frequency at the possible expense of the internal chip frequency. For bi-directional ports, you can individually control the movement of flops using the inff, outff, and triff attributes. max_fanout: Allows you to change the fanout limit on the specified net. outff: Tells Precision Synthesis whether or not to map the candidate register in the output path to a register in the IO block. By default, Precision maps the register to the IO block if this attribute is not present. The attribute is applied to the output port. triff: Tells Precision Synthesis whether or not to map the candidate register in the path to a register in the IO block.

Register Examples
The following table shows the VHDL and Verilog examples described in this section. The code files are available in the Precision Synthesis software tree in the following directory:
<precision_install_dir>/shared/examples/style_guide_hdl/Registers

Table 7-1. Register Examples Example D Latch Description A D Latch is level sensitive and, therefore, has no clock signal.

D Latch with an asynchronous set and reset signal. If the reset signal D Latch with Asynchronous Set and is high, the output will immediately become zero, and if the set is high, the output will become one. Reset Generic N-Bit Register with Enable D Flip Flop Generic N-bit register with a clock and a clock enable signal, but no set or reset signal. Basic D Flip Flop with no clock enable, set, or reset signals.

Precision Synthesis Style Guide, 2011a Update2 November 2011

209

Registers Register Examples

Table 7-1. Register Examples Example D Flip Flop with Enable Description The clock enable only allows the output to be assigned when the enable is high. It is a synchronous signal, meaning that the output will only be set on a clock edge, regardless of when the enable signal changes. The synchronous reset is checked only on a clock edge, so it is not required in the sensitivity list. The reset sets the output to zero when it is high. The asynchronous reset sets the output to zero whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list. The synchronous set is checked only on a clock edge, so it is not required in the sensitivity list. The set sets the output to one when it is high. The asynchronous set sets the output to one whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list. The enable only allows the output to be set if the enable is high. The synchronous reset is checked only on a clock edge, so it is not required in the sensitivity list. The enable only allows the output to be set if the enable is high. The asynchronous reset sets the output to zero whenever it becomes high, independent of the clock-edge. The enable only allows the output to be set if the enable is high. The synchronous set is checked only on a clock edge, so it is not required in the sensitivity list. The enable only allows the output to be set if the enable is high. The asynchronous set sets the output to one whenever it becomes high, independent of the clock-edge. Example with both a synchronous reset and a synchronous set. These are both checked only after a clock edge, and do not need to appear in the sensitivity list. Example with both an asynchronous reset and an asynchronous set, which both operate independent from the clock signal, and must appear in the sensitivity list. Reset has priority over set. The enable only allows the output to be set if the enable is high. There is both a synchronous reset and a synchronous set. These are both checked only after a clock edge, and do not need to appear in the sensitivity list. Reset has priority over set, which has priority over enable.

D Flip Flop with Synchronous Reset D Flip Flop with Asynchronous Reset D Flip Flop with Synchronous Set D Flip Flop with Asynchronous Set D Flip Flop with Enable and Synchronous Reset D Flip Flop with Enable and Asynchronous Reset D Flip Flop with Enable and Synchronous Set D Flip Flop with Enable and Asynchronous Set D Flip Flop with Synchronous Reset and Set D Flip Flop with Asynchronous Reset and Set D Flip Flop with Enable and Synchronous Reset and Set

210

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Register Examples

Table 7-1. Register Examples Example D Flip Flop with Enable and Asynchronous Reset and Set D Flip Flop with Asynchronous Reset and Synchronous Set D Flip Flop with Enable and Asynchronous Reset and Synchronous Set Description The enable only allows the output to be set if the enable is high. There is both an asynchronous reset and an asynchronous set, which both operate independent from the clock signal, and must appear in the sensitivity list. The asynchronous reset sets the output to zero whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list. The enable only allows the output to be set if the enable is high. The asynchronous reset sets the output to zero whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list.

The asynchronous set sets the output to one whenever it becomes D Flip Flop with high, independent of the clock-edge. It is required to be in the Synchronous Reset and Asynchronous Set sensitivity list. The synchronous reset is checked only on a clock edge, so it is not required in the sensitivity list. The reset sets the output to zero when it is high. D Flip Flop with Enable and Synchronous Reset and Asynchronous Set The enable only allows the output to be set if the enable is high. The asynchronous set sets the output to one whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list. The synchronous reset is checked only on a clock edge, so it is not required in the sensitivity list. The reset sets the output to zero when it is high. Reset has priority over set, which has priority over enable. The AND gate driving the D Flip Flop will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop. The NAND gate driving the D Flip Flop will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop. The OR gate driving the D Flip Flop will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop. The NOR gate driving the D Flip Flop will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop.

Gated Clock Conversion-AND Gated Clock Conversion-NAND Gated Clock Conversion-OR Gated Clock Conversion-NOR

The AND gates driving the Flip Flops will be converted to a D Flip Gated Clock Conversion-Cascaded Flop with Clock Enable, if the target technology supports such a Flip Flop. Logic optimization will also reduce the number of logic levels, Clocks as shown in the optimized result below.

Precision Synthesis Style Guide, 2011a Update2 November 2011

211

Registers Register Examples

Table 7-1. Register Examples Example Right Shifter Description This shifter is fully synchronous with the clock edge. If the enable signal is high, and the load signal is low, it will shift the input data one bit to the right for the output. If the enable and load signals are both high, it will output the input data. If the enable is low, it will latch the output data. This is an asynchronous right shifter with load, clear, and enable signals. This is a synchronous right shifter with load, clear, and enable signals. An 8-bit serial shifter that has an enable signal which, when high, stops the shifter. If the enable is low, the output data will be set to the least significant bit of the temporary register, and the temporary register will be shifted right one bit.

Asynchronous Right Shifter Synchronous Right Shifter Serial Shifter

Bi-Directional Shifter This is identical to the right shifter, except that is can shift either right or left. Right Logical Shifter Example of a right logical shifter. It uses a for loop to implement the shift, and a RAM to store the data that is being shifted.

212

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Latch

D Latch
A D Latch is level sensitive and, therefore, has no clock signal. This is a D Latch with an enable, and no set or reset signals. The sensitivity list is required, and indicates that the block is executed whenever the signal d change. Also, since the assignment to the register q is hidden in a conditional clause, q cannot change (preserves its old value) if en is 0. If ena is 1, q is immediately updated with the value of d, whenever that changes. This is the behavior of a level-sensitive latch. In technologies where level-sensitive latches are not available, Precision RTL Synthesis translates the initially generated latches to the gate equivalent of the latch, using a combinational loop.

VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY d_latch IS PORT (d, en: IN STD_LOGIC; q: OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF d_latch IS BEGIN PROCESS (d) BEGIN IF (en = 1) THEN q <= d; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module d_latch (d, en, q); input d, en; output q; reg q; always @ (d) if (en) q = d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

213

Registers D Latch with Asynchronous Set and Reset

D Latch with Asynchronous Set and Reset


D Latch with an asynchronous set and reset signal. If the reset signal is high, the output will immediately become zero, and if the set is high, the output will become one. In this example, the reset signal has priority. The extra boolean logic is added to model the priority defined in the model but it is typically optimized away during technology mapping.

VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY d_latch_asynch IS PORT (d, en, reset, set: IN STD_LOGIC; q: OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF d_latch_asynch IS BEGIN PROCESS (d, reset, set) BEGIN IF (reset = 1) THEN q <= 0; ELSIF (set = 1) THEN q <= 1; ELSIF (en = 1) THEN q <= d; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module d_latch_asynch (d, en, reset, set, q); input d, en, reset, set; output q; reg q; always @ (d or reset or set) if (reset) q = 0; else if (set) q = 1; else if (en) q = d; endmodule

214

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Generic N-Bit Register with Enable

Generic N-Bit Register with Enable


Generic N-bit register with a clock and a clock enable signal, but no set or reset signal.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY register_gen_en IS GENERIC(width : INTEGER := 4); PORT (clk, en : IN STD_LOGIC; d : IN UNSIGNED(width-1 DOWNTO 0); q : OUT UNSIGNED(width-1 DOWNTO 0)); END ENTITY ; ARCHITECTURE rtl OF register_gen_en IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module register_gen_en (clk, en, d, q); parameter width = 4; input clk, en; input [width - 1:0] d; output [width - 1:0] q; reg [width - 1:0] q; always @(posedge clk) if (en) q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

215

Registers D Flip Flop

D Flip Flop
Basic D Flip Flop with no clock enable, set, or reset signals.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff IS PORT(clk, d : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN q <= d; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff (clk, d, q); input clk, d; output q; reg q; always @(posedge clk) q <= d; endmodule

216

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Enable

D Flip Flop with Enable


The clock enable only allows the output to be assigned when the enable is high. It is a synchronous signal, meaning that the output will only be set on a clock edge, regardless of when the enable signal changes.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_e IS PORT (clk, d, en : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_e IS BEGIN PROCESS(clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_e (clk, en, d, q,); input clk, en, d; output q; reg q; always @(posedge clk) if (en) q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

217

Registers D Flip Flop with Synchronous Reset

D Flip Flop with Synchronous Reset


The synchronous reset is checked only on a clock edge, so it is not required in the sensitivity list. The reset sets the output to zero when it is high.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_sr IS PORT (clk, d, reset : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_sr IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF reset = 1 THEN q <= 0; ELSE q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_sr (clk, reset, d, q); input clk, reset, d; output q; reg q; always @(posedge clk) if (reset) q <= 0; else q <= d; endmodule

218

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Asynchronous Reset

D Flip Flop with Asynchronous Reset


The asynchronous reset sets the output to zero whenever it becomes high, independent of the clockedge. It is required to be in the sensitivity list.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_ar IS PORT (clk, d, reset : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_ar IS BEGIN PROCESS (clk,reset) BEGIN IF reset = 1 THEN q <= 0; ELSIF (clkEVENT AND clk=1) THEN q <= d; ELSE NULL; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_ar (clk, reset, d, q); input clk, reset, d; output q; reg q; always @(posedge clk or posedge reset) if (reset) q <= 0; else q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

219

Registers D Flip Flop with Synchronous Set

D Flip Flop with Synchronous Set


The synchronous set is checked only on a clock edge, so it is not required in the sensitivity list. The set sets the output to one when it is high.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_ss IS PORT (clk, d, set : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_ss IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (set = 1) THEN q <= 1; ELSE q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_ss (clk, d, set, q); input clk, d, set; output q; reg q; always @(posedge clk) if (set) q <= 1; else q <= d; endmodule

220

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Asynchronous Set

D Flip Flop with Asynchronous Set


The asynchronous set sets the output to one whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_as IS PORT (clk, d, set : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_as IS BEGIN PROCESS (clk, set) BEGIN IF (set = 1) THEN q <= 1; ELSIF (clkEVENT AND clk=1) THEN q <= d; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_as (clk, d, set, q); input clk, d, set; output q; reg q; always @(posedge clk or posedge set) if (set) q <= 1; else q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

221

Registers D Flip Flop with Enable and Synchronous Reset

D Flip Flop with Enable and Synchronous Reset


The enable only allows the output to be set if the enable is high. The synchronous reset is checked only on a clock edge, so it is not required in the sensitivity list. The reset sets the output to zero when it is high. This example gives reset priority over enable.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_sr_e IS PORT (clk, d : IN STD_LOGIC; en, reset : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF dff_sr_e IS BEGIN PROCESS(clk) BEGIN IF (clkEVENT AND clk=1) THEN IF reset = 1 THEN q <= 0; ELSIF en = 1 THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_sr_e (clk, reset, en, d, q); input clk, reset, en, d; output q; reg q; always @(posedge clk) if (reset) q <= 0; else if (en) q <= d; endmodule

222

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Enable and Asynchronous Reset

D Flip Flop with Enable and Asynchronous Reset


The enable only allows the output to be set if the enable is high. The asynchronous reset sets the output to zero whenever it becomes high, independent of the clockedge. The reset signal is required to be in the sensitivity list. This example gives reset priority over enable.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_ar_e IS PORT (clk, d : IN STD_LOGIC; en, reset : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_ar_e IS BEGIN PROCESS(clk, reset) BEGIN IF (reset = 1) THEN q <= 0; ELSIF (clkEVENT AND clk=1) THEN IF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_ar_e (clk, rst, en, d, q); input clk, rst, en, d; output q; reg q; always @(posedge clk or posedge rst) if (rst) q <= 0; else if (en) q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

223

Registers D Flip Flop with Enable and Synchronous Set

D Flip Flop with Enable and Synchronous Set


The enable only allows the output to be set if the enable is high. The synchronous set is checked only on a clock edge, so it is not required in the sensitivity list. The set sets the output to one when it is high. This example gives reset priority over enable.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_ss_e IS PORT (clk,d,set,en : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_ss_e IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (set = 1) THEN q <= 1; ELSIF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_ss_e (clk, en, a, set, y); input clk, en, a, set; output y; reg y; always @(posedge clk) if (set) y <= 1; else if (en) y <= a; endmodule

224

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Enable and Asynchronous Set

D Flip Flop with Enable and Asynchronous Set


The enable only allows the output to be set if the enable is high. The asynchronous set sets the output to one whenever it becomes high, independent of the clock-edge. The set signal is required to be in the sensitivity list. This example gives set priority over enable.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_as_e IS PORT (clk, d : IN STD_LOGIC; set, en : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_as_e IS BEGIN PROCESS (clk, set) BEGIN IF (set = 1) THEN q <= 1; ELSIF (clkEVENT AND clk=1) THEN IF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_as_e (clk, d, set, en, q); input clk, d, en, set; output q; reg q; always @(posedge clk or posedge set) if (set) q <= 1; else if (en) q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

225

Registers D Flip Flop with Synchronous Reset and Set

D Flip Flop with Synchronous Reset and Set


Example with both a synchronous reset and a synchronous set. These are both checked only after a clock edge, and do not need to appear in the sensitivity list.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_sr_ss IS PORT (clk, d, set, reset : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF dff_sr_ss IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (reset = 1) THEN q <= 0; ELSIF (set = 1) THEN q <= 1; ELSE q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_sr_ss (clk, reset, set, d, q); input clk, reset, set, d; output q; reg q; always @(posedge clk) if (reset) q <= 0; else if (set) q <= 1; else q <= d; endmodule

226

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Asynchronous Reset and Set

D Flip Flop with Asynchronous Reset and Set


Example with both an asynchronous reset and an asynchronous set, which both operate independent from the clock signal, and must appear in the sensitivity list. Reset has priority over set. Asynchronous set and reset can both be used. This results in combinational logic driving the set and reset input of the flip-flop of the target signal. There can be several asynchronous conditional clauses, but any asynchronous assignments must have higher priority than the synchronous assignments. A flip-flop is generated for each signal that is assigned in the synchronous signal assignment. The asynchronous clauses result in combinational logic that drives the set and reset inputs of the flip-flops. If there is no synchronous clause, all logic becomes combinational.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_ar_as IS PORT (clk, d, set, reset : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_ar_as IS BEGIN PROCESS (clk, set, reset) BEGIN IF (reset = 1) THEN q <= 0; ELSIF (set = 1) THEN q <= 1; ELSIF (clkEVENT AND clk=1) THEN q <= d; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_ar_as (clk, reset, set, d, q); input clk, reset, set, d; output q; reg q; always @(posedge clk or posedge reset or posedge set) if (reset) q <= 0; else if (set) q <= 1; else q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

227

Registers D Flip Flop with Enable and Synchronous Reset and Set

D Flip Flop with Enable and Synchronous Reset and Set


The enable only allows the output to be set if the enable is high. There is both a synchronous reset and a synchronous set. These are both checked only after a clock edge, and do not need to appear in the sensitivity list. Reset has priority over set, which has priority over enable.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_sr_ss_e IS PORT (clk, d : IN STD_LOGIC; set, reset, en : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_sr_ss_e IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk=1) THEN IF (reset = 1) THEN q <= 0; ELSIF (set = 1) THEN q <= 1; ELSIF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_sr_ss_e (clk, en, reset, set, d, q); input clk, en, reset, set, d; output q; reg q; always @(posedge clk) if (reset) q <= 0; else if (set) q <= 1; else if (en) q <= d; endmodule

228

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Enable and Asynchronous Reset and Set

D Flip Flop with Enable and Asynchronous Reset and Set


The enable only allows the output to be set if the enable is high. There is both an asynchronous reset and an asynchronous set, which both operate independent from the clock signal, and must appear in the sensitivity list. Reset has priority over set, which has priority over enable.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_ar_as_e IS PORT (clk, d : IN STD_LOGIC; set, reset, en : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_ar_as_e IS BEGIN PROCESS (clk, set, reset) BEGIN IF (reset = 1) THEN q <= 0; ELSIF (set = 1) THEN q <= 1; ELSIF (clkEVENT AND clk=1) THEN IF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_ar_as_e (clk, en, reset, set, d, q); input clk, en, reset, set, d; output q; reg q; always @(posedge clk or posedge reset or posedge set) if (reset) q <= 0; else if (set) q <= 1; else if (en) q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

229

Registers D Flip Flop with Asynchronous Reset and Synchronous Set

D Flip Flop with Asynchronous Reset and Synchronous Set


The asynchronous reset sets the output to zero whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list. The synchronous set is checked only on a clock edge, so it is not required in the sensitivity list. The set sets the output to one when it is high.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_ar_ss IS PORT (clk, d, set, reset : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_ar_ss IS BEGIN PROCESS (clk, reset) BEGIN IF (reset = 1) THEN q <= 0; ELSIF (clkEVENT AND clk=1) THEN IF (set = 1) THEN q <= 1; ELSE q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_ar_ss (clk, reset, set, d, q); input clk, reset, set, d; output q; reg q; always @(posedge clk or posedge reset) if (reset) q <= 0; else if (set) q <= 1; else q <= d; endmodule

230

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Enable and Asynchronous Reset and Synchronous Set

D Flip Flop with Enable and Asynchronous Reset and Synchronous Set
The enable only allows the output to be set if the enable is high. The asynchronous reset sets the output to zero whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list. The synchronous set is checked only on a clock edge, so it is not required in the sensitivity list. The set sets the output to one when it is high. Reset has priority over set, which has priority over enable.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_ar_ss_e IS PORT (clk, d : IN STD_LOGIC; set, reset, en : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_ar_ss_e IS BEGIN PROCESS (clk, reset) BEGIN IF (reset = 1) THEN q <= 0; ELSIF (clkEVENT AND clk=1) THEN IF (set = 1) THEN q <= 1; ELSIF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_ar_ss_e (clk, en, reset , set, d, q); input clk, en, reset, set, d; output q; reg q; always @(posedge clk or posedge reset) if (reset) q <= 0; else if (set) q <= 1; else if (en) q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

231

Registers D Flip Flop with Synchronous Reset and Asynchronous Set

D Flip Flop with Synchronous Reset and Asynchronous Set


The asynchronous set sets the output to one whenever it becomes high, independent of the clock-edge. It is required to be in the sensitivity list. The synchronous reset is checked only on a clock edge, so it is not required in the sensitivity list. The reset sets the output to zero when it is high.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_sr_as IS PORT (clk, d, set, reset : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF dff_sr_as IS BEGIN PROCESS (clk, set) BEGIN IF (set = 1) THEN q <= 1; ELSIF (clkEVENT AND clk=1) THEN IF (reset = 1) THEN q <= 0; ELSE q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_sr_as (clk, reset, set, d, q); input clk, reset, set, d; output q; reg q; always @(posedge clk or posedge set) if (set) q <= 1; else if (reset) q <= 0; else q <= d; endmodule

232

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers D Flip Flop with Enable and Synchronous Reset and Asynchronous Set

D Flip Flop with Enable and Synchronous Reset and Asynchronous Set
The enable only allows the output to be set if the enable is high. The asynchronous set sets the output to one whenever it becomes high, independent of the clockedge. It is required to be in the sensitivity list. The synchronous reset is checked only on a clock edge, so it is not required in the sensitivity list. The reset sets the output to zero when it is high. Reset has priority over set, which has priority over enable.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY dff_sr_as_e IS PORT (clk, d : IN STD_LOGIC; set, reset, en : IN STD_LOGIC; q : OUT STD_LOGIC); END ENTITY ; ARCHITECTURE rtl OF dff_sr_as_e IS BEGIN PROCESS (clk, set) BEGIN IF (set = 1) THEN q <= 1; ELSIF (clkEVENT AND clk=1) THEN IF (reset = 1) THEN q <= 0; ELSIF (en = 1) THEN q <= d; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module dff_sr_as_e (clk, en, reset, set, d, q); input clk, en, reset, set, d; output q; reg q; always @(posedge clk or posedge set) if (set) q <= 1; else if (reset) q <= 0; else if (en) q <= d; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

233

Registers Gated Clock Conversion-AND

Gated Clock Conversion-AND


The AND gate driving the D Flip Flop will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop. Follow these steps: 1. compile 2. define gating clock using the create_clock command 3. synthesize For additional information on gated clock conversion, see the Constraining and Synthesizing chapter of the Precision RTL Synthesis Users Manual. Optimized

RTL

VHDL
-- How to infer gated clock: ---- compile ---- create_clock gate -period 10 ---- synthesize library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; ENTITY and_gated_clk IS port ( clk, gate, din: in std_logic; dout: out std_logic ); END and_gated_clk; ARCHITECTURE rtl OF and_gated_clk IS signal gated_clk: std_logic; begin gated_clk <= clk AND gate; process (gated_clk) begin if rising_edge (gated_clk) then dout <= din; end if; end process; END RTL;

Verilog
// // // // How to infer gated clock: - compile - create_clock gate -period 10 - synthesize

module and_gated_clk ( clk, gate, din, dout); input input output reg wire assign clk, gate; din; dout; dout; gate_1; gate_1 = clk & gate;

always @ (posedge gate_1) dout <= din; endmodule

234

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Gated Clock Conversion-NAND

Gated Clock Conversion-NAND


The NAND gate driving the D Flip Flop will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop. Follow these steps: 1. compile 2. define gating clock using the create_clock command 3. synthesize For additional information on gated clock conversion, see the Constraining and Synthesizing chapter of the Precision RTL Synthesis Users Manual. Optimized

RTL

VHDL
-- How to infer gated clock: -- - compile -- - create_clock gate -period 10 -- - synthesize library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; ENTITY nand_gated_clk IS port (clk, gate, din: in std_logic; dout: out std_logic ); END nand_gated_clk; ARCHITECTURE rtl OF nand_gated_clk IS signal gated_clk: std_logic; begin gated_clk <= clk NAND gate; process (gated_clk) begin if rising_edge (gated_clk) then dout <= din; end if; end process; END RTL;

Verilog
// // // // How to infer gated clock: - compile - create_clock gate -period 10 - synthesize

module nand_gated_clk ( clk, gate, din, dout); input input output reg wire assign clk, gate; din; dout; dout; gate_1; gate_1 = ~(clk & gate);

always @ (posedge gate_1) dout <= din; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

235

Registers Gated Clock Conversion-OR

Gated Clock Conversion-OR


The OR gate driving the D Flip Flop will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop. Follow these steps: 1. compile 2. define gating clock using the create_clock command 3. synthesize For additional information on gated clock conversion, see the Constraining and Synthesizing chapter of the Precision RTL Synthesis Users Manual.

RTL

Optimized

VHDL
-- How to infer gated clock: -- - compile -- - create_clock gate -period 10 -- - synthesize library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; ENTITY or_gated_clk IS port (clk, gate, din: in std_logic; dout: out std_logic ); END or_gated_clk; ARCHITECTURE rtl OF or_gated_clk IS signal gated_clk: std_logic; begin gated_clk <= clk OR gate; process (gated_clk) begin if rising_edge (gated_clk) then dout <= din; end if; end process; END RTL;

Verilog
// // // // How to infer gated clock: - compile - create_clock gate -period 10 - synthesize

module or_gated_clk ( clk, gate, din, dout); input input output reg wire assign clk, gate; din; dout; dout; gate_1; gate_1 = clk | gate;

always @ (posedge gate_1) dout <= din; endmodule

236

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Gated Clock Conversion-NOR

Gated Clock Conversion-NOR


The NOR gate driving the D Flip Flop will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop. Follow these steps: 1. compile 2. define gating clock using the create_clock command 3. synthesize For additional information on gated clock conversion, see the Constraining and Synthesizing chapter of the Precision RTL Synthesis Users Manual. Optimized

RTL

VHDL
-- How to infer gated clock: -- - compile -- - create_clock gate -period 10 -- - synthesize library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; ENTITY nor_gated_clk IS port ( clk, gate, din: in std_logic; dout: out std_logic ); END nor_gated_clk; ARCHITECTURE rtl OF nor_gated_clk IS signal gated_clk: std_logic; begin gated_clk <= clk NOR gate; process (gated_clk) begin if rising_edge (gated_clk) then dout <= din; end if; end process; END RTL;

Verilog
// // // // How to infer gated clock: - compile - create_clock gate -period 10 - synthesize

module nor_gated_clk ( clk, gate, din, dout); input input output reg wire assign clk, gate; din; dout; dout; gate_1; gate_1 = ~(clk | gate);

always @ (posedge gate_1) dout <= din; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

237

Registers Gated Clock Conversion-Cascaded Clocks

Gated Clock Conversion-Cascaded Clocks


The AND gates driving the Flip Flops will be converted to a D Flip Flop with Clock Enable, if the target technology supports such a Flip Flop. Logic optimization will also reduce the number of logic levels, as shown in the optimized result below. After the design is compiled, the gating clock must be defined using the create_clock command. For additional information on gated clock conversion, see the Constraining and Synthesizing chapter of the Precision RTL Synthesis Users Manual.

RTL

Optimized

238

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Gated Clock Conversion-Cascaded Clocks

VHDL
----------The gated clock can be arbitrarily deep. All of the gated clock in the cascade will be converted to clock enables provided that all of them satisfied all of the requirements for successful conversion. However, if the first gated clock fails to convert, all subsequent gated clocks in the same chain would normally fail to convert as illustrated by the below RTL behavior.

Verilog
// // // // // // // // // // // // // // // // The gated clock can be arbitrarily deep. All of the gated clocks in the cascade will be converted to clock enables, provided that all of them satisfied all of the requirements for successful conversion. However, if the first gated clock fails to convert, all subsequent gated clocks in the same chain would normally fail to convert as illustrated by the below RTL behavior. How to infer gated clock: - compile - create_clock gate(1) -period 10 - synthesize

-- How to infer gated clock: -compile -create_clock gate(1) -period 10 -synthesize library ieee; use ieee.std_logic_1164.all; entity cascaded_gated_clk is port( clk : in std_logic; din, gate: in std_logic_vector (3 downto 1); dout: out std_logic_vector (3 downto 1) ); end entity cascaded_gated_clk; architecture rtl of cascaded_gated_clk is signal gate_1, gate_2, gate_3 : std_logic; begin gate_1 <= clk and gate(1); gate_2 <= gate_1 and gate(2); gate_3 <= gate_2 and gate(3); gate_1_clocked : process begin wait until gate_1 = 1; dout(1) <= din(1); end process gate_1_clocked; gate_2_clocked : process begin wait until gate_2 = 1; dout(2) <= din(2); end process gate_2_clocked; gate_3_clocked : process begin wait until gate_3 = 1; dout(3) <= din(3); end process gate_3_clocked; end architecture rtl;

module cascaded_gated_clk ( clk, gate, din, dout); input input output reg clk; [3:1] gate, din; [3:1] dout; [3:1] dout;

wire gate_1, gate_2, gate_3; assign assign assign gate_1 = clk && gate[1]; gate_2 = gate_1 && gate[2]; gate_3 = gate_2 && gate[3];

always @(posedge gate_1) if (gate_1) dout[1] = din[1]; always @(posedge gate_2) if (gate_2) dout[2] = din[2]; always @(posedge gate_3) if (gate_3) dout[3] = din[3]; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

239

Registers Right Shifter

Right Shifter
This shifter is fully synchronous with the clock edge. If the enable signal is high, and the load signal is low, it will shift the input data one bit to the right for the output. If the enable and load signals are both high, it will output the input data. If the enable is low, it will latch the output data.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY shift_rt IS GENERIC(width : INTEGER := 4); PORT (clk, en, load : IN STD_LOGIC; data_in : IN UNSIGNED(width-1 DOWNTO 0); data_out : OUT UNSIGNED(width-1 DOWNTO 0)); END shift_rt ; ARCHITECTURE rtl OF shift_rt IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk = 1) THEN IF (en = 1) THEN IF load = 1 THEN data_out <= data_in; ELSE data_out <= shift_right(data_in,1); END IF; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module shift_rt (clk, en, load, data_in, data_out); parameter width = 4; input clk, en, load; input [width - 1:0] data_in; output [width - 1:0] data_out; reg [width - 1:0] data_out; always @(posedge clk) if (en) if (load) data_out <= data_in; else data_out <= data_in >> 1; endmodule

240

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Asynchronous Right Shifter

Asynchronous Right Shifter


This is an asynchronous right shifter with load, clear, and enable signals. Because it is asynchronous, all of these signals must be in the sensitivity list. The clear has priority over the load, which has priority over the enable. If the reset is high, the output becomes all zeros, if the load is high the output is set to the input, and if the enable is high the output is shifted right one bit.

VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY shift_rt_asynch IS GENERIC (width : INTEGER := 4); PORT (clk, clear, en, load : IN STD_LOGIC; a : IN UNSIGNED(width-1 DOWNTO 0); y : OUT UNSIGNED(width-1 DOWNTO 0)); END ENTITY; ARCHITECTURE rtl OF shift_rt_asynch IS BEGIN PROCESS (clk, load, clear) BEGIN IF (clear = 1) THEN y <= 0000; ELSIF (load = 1) THEN y <= a; ELSIF (clkEVENT AND clk = 1) THEN IF (en = 1) THEN y <= shift_right (a, 1); END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module shift_rt_asynch (clk, enable, load, clear, a, y); parameter width = 4; input clk, enable, load, clear; input [width - 1:0] a; output [width - 1:0] y; reg [width - 1:0] y; always @(posedge clk or posedge load or posedge clear) if (clear) y <= 0; else if (load) y <= a; else if (enable) y <= y >> 1; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

241

Registers Synchronous Right Shifter

Synchronous Right Shifter


This is a synchronous right shifter with load, clear, and enable signals. The clear has priority over the load, which has priority over the enable. If the reset is high, the output becomes all zeros, if the load is high the output is set to the input, and if the enable is high the output is shifted right one bit.

VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY shift_rt_synch IS GENERIC (width : INTEGER := 4); PORT (clk, clear, en, load : IN STD_LOGIC; a : IN UNSIGNED(width-1 DOWNTO 0); y : OUT UNSIGNED(width-1 DOWNTO 0)); END ENTITY; ARCHITECTURE rtl OF shift_rt_synch IS BEGIN PROCESS (clk) BEGIN IF (clear = 1) THEN y <= 0000; ELSIF (load = 1) THEN y <= a; ELSIF (clkEVENT AND clk = 1) THEN IF (en = 1) THEN y <= shift_right (a, 1); END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module shift_rt_synch (clk, en, load, clear, a, y); parameter width = 4; input clk, en, load, clear; input [width - 1:0] a; output [width - 1:0] y; reg [width - 1:0] y; always @(posedge clk) if (clear) y <= 0; else if (load) y <= a; else if (en) y <= y >> 1; endmodule

242

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Serial Shifter

Serial Shifter

An 8-bit serial shifter that has an enable signal which, when high, stops the shifter. If the enable is low, the output data will be set to the least significant bit of the temporary register, and the temporary register will be shifted right one bit. The input bit a is placed in the most significant bit of the temporary register after the bits are shifted right.

VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY shift_serial IS PORT (clk, en, a: IN STD_LOGIC; y: OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF shift_serial IS SIGNAL temp: UNSIGNED(7 DOWNTO 0); BEGIN PROCESS (clk, en) BEGIN IF (clkEVENT AND clk = 1) THEN IF(en = 1) THEN temp <= shift_right(temp, 1); temp(7) <= a; END IF; END IF; y <= temp(0); END PROCESS; END ARCHITECTURE;

Verilog
module shift_serial (a, clk, en, y); input a, clk, en; output y; reg [7:0] temp; always @(posedge clk) begin if (en) begin temp = temp >> 1; temp[7] = a; end end assign y = temp[0]; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

243

Registers Bi-Directional Shifter

Bi-Directional Shifter
This is identical to the right shifter, except that is can shift either right or left. The direction of the shift is determined by the input bit rt. If rt is high, it shifts right; if it is low, it shifts left.

VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY shift_bi IS GENERIC(width : INTEGER := 4); PORT (clk, en, load, rt : IN STD_LOGIC; data_in : IN UNSIGNED(width1 DOWNTO 0); data_out : OUT UNSIGNED(width-1 DOWNTO 0)); END shift_bi ; ARCHITECTURE rtl OF shift_bi IS BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk = 1) THEN IF (en = 1) THEN IF load = 1 THEN data_out <= data_in; ELSIF rt = 1 THEN data_out <= shift_right(data_in,1); ELSE data_out <= shift_left(data_in,1); END IF; END IF; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module shift_bi (clk, en, load, rt, data_in, data_out); parameter width = 4; input clk, en, load, rt; input [width - 1:0] data_in; output [width - 1:0] data_out; reg [width - 1:0] data_out; always @(posedge clk) if (en) if (load) data_out <= data_in; else if (rt) data_out <= data_in >> 1; else data_out <= data_in << 1; endmodule

244

Precision Synthesis Style Guide, 2011a Update2 November 2011

Registers Right Logical Shifter

Right Logical Shifter


Example of a right logical shifter. It uses a for loop to implement the shift, and a RAM to store the data that is being shifted. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY shift_right_logical IS GENERIC ( delay_max : INTEGER := 15; data_width : INTEGER := 8 ); PORT( clk : IN STD_LOGIC; data_in : IN UNSIGNED (data_width-1 DOWNTO 0); delay : IN INTEGER RANGE delay_max-1 DOWNTO 0; data_out : OUT UNSIGNED (data_width-1 DOWNTO 0)); END ENTITY; ARCHITECTURE rtl OF shift_right_logical IS TYPE srltype IS ARRAY(delay_max-1 DOWNTO 0) OF UNSIGNED(data_width-1 DOWNTO 0); SIGNAL internal : srltype; BEGIN PROCESS (clk) BEGIN IF (clkEVENT AND clk = 1) THEN internal <= internal (delay_max-2 DOWNTO 0) & data_in ; END IF; END PROCESS; data_out <= internal(delay); END ARCHITECTURE;

Verilog
module shift_right_logical (clk, delay, data_in, data_out); parameter max_delay = 15; parameter delay_width = 4; parameter data_width = 8; input clk; input [0:delay_width] delay; input [0:data_width] data_in; output [0:data_width] data_out; reg [0:data_width-1] shift [max_delay-1:0]; integer i; always @(posedge clk) begin for (i = (max_delay-1); i>0; i=i-1) begin shift[i] <= shift[i-1]; end shift[0] <= data_in; end assign data_out = shift[delay]; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

245

Registers Right Logical Shifter

246

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 8 Memory
Precision RTL Synthesis detects a RAM or ROM from the style of the RTL code at a technology-independent level, then maps the element to a generic module in the RTL database at Compile time. During the technology mapping phase of synthesis, Precision maps the generic RAM or ROM module to the equivalent Vendor-specific implementation.

Common Guidelines
The following subsections describes some general guidelines for inferring memories within Precision. Although Precision may infer the memory on compile, it may not implement the memory within the technology until that specific memory configuration is supported. Refer to the technology specific sections in the Reference Manual for more information of technology specific implementations of memories.

Single Port RAMs


Precision supports numerous single port RAM configurations from asynchronous to registering the datain, address, and dataout line.

Dual Port RAMs


A dual-port RAM such as a FIFO-type RAM with a separately clocked input and output is often used to buffer data transfers between two clock domains that are operating at different frequencies.

Resets for Memories


Precision supports 2 types of resets for memories: 1. Reset that clear the contents of memory. For this type of memory, Precision creates any necessary glue logic for reset implementation. 2. Reset that clear the output registers on read ports of the memory. For this type of memory, resets are supported through the use of builtin reset pin (typically the sync pin) present in the RAM cell of the FPGA device.

Precision Synthesis Style Guide, 2011a Update2 November 2011

247

Memory Common Guidelines

ROMs
You can implement ROM behavior in the HDL source code with CASE statements or you can specify the ROM as an array of constants. Precision RTL Synthesis infers both synchronous and asynchronous ROM. The circuit is first mapped to technology-independent modgen ROM module, then to the technology-specific cell(s). By default, the minimum size of a detected ROM is 64 unique addressed memory locations. Precision Synthesis utilizes a smart algorithm that absorbs registers into an asynchronous ROM output, thereby enabling ROM to block RAM mapping. Additionally, the critical timing path is more predictable when mapping to RAM instead of using conventional ROM decoders. This is because the timing is mostly constrained by READ/WRITE operations and not the levels of combinational logic.

General Coding Guidelines for ROM Inference


ROMs can be modeled by different methodologies. Precision Synthesis supports a wide range of coding styles. It is always helpful to understand and follow the following coding guidelines when modeling a ROM. Determine what type of ROM, e.g. Synchronous or Asynchronous Determine the mapping technology and its specific hardware architectures Determine whether or not ROM values require optimizations during synthesis, e.g. CASE Statement would be used instead of the Explicit constant arrays if you would like Precision Synthesis to optimize these ROM values

Smart ROM to RAM Inference and Mapping Algorithms


In general, most if not all, block RAMs have synchronous read and write operations. Hence, in order to successfully map any type of hardware into block RAMs, the output port must be synchronous. In FPGA designs, it is quite common to have ROM hardware with an asynchronous output port. In fact, most of the ROMs do have an asynchronous output port, thereby limiting them from being mapped into Block RAMs.

248

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Common Guidelines

Figure 8-1. Asynchronous ROM Mapped into Block RAM

To minimize hardware incompatibility and increase the ROM to RAM mapping rate, Precision Synthesis has an intelligent algorithm where it will automatically pull in available registers through the levels of logic that the ROM drives, as shown in Figure 8-1.

Controlling ROM to RAM Mapping Options


You can control ROM to block RAM mapping options by inserting either an attribute or pragma into the HDL source file. By default, the mapping option will be decided by Precision Synthesis mapping heuristics, depending on the address size and depth of the ROM. Here are the code snippet examples of how you can set the attribute/pragma to control the mapping options. Figure 8-2. How to Set rom_block Attribute in VHDL
entity rom_to_blockram is generic ( addr_width_c : integer := 6; data_width_c : integer := 16); port(clk : in std_logic; addr : in std_logic_vector(addr_width_c-1 downto 0); dout : out std_logic_vector(data_width_c-1 downto 0) ); end entity rom_to_blockram; architecture rtl of rom_to_blockram is signal mem : std_logic_vector(data_width_c-1 downto 0); signal reg_addr : std_logic_vector(addr_width_c-1 downto 0); attribute rom_block : boolean; attribute rom_block of mem : signal is TRUE; begin

Precision Synthesis Style Guide, 2011a Update2 November 2011

249

Memory Common Guidelines

Figure 8-3. How to Set rom_block Attribute in Verilog


`define WIDTH_A 6 `define WIDTH_D 16 `define RAM_DEPTH 256 module rom_to_blockram ( addr, clk, dout ); input [`WIDTH_A-1:0] addr; input clk; reg [`WIDTH_A-1:0] reg_addr; reg [`WIDTH_D-1:0] mem; output reg [`WIDTH_D-1:0] dout; //pragma attribute mem rom_block TRUE always @ (posedge clk) begin

Suggested Coding Techniques for RAM and ROM


VHDL Coding Techniques
Using the CASE Statement
Figure 8-4. VHDL ROM Implemented Using CASE Statement
architecture rtl of rom_to_blockram is signal mem : std_logic_vector(data_width_c-1 downto 0); signal reg_addr : std_logic_vector(addr_width_c-1 downto 0); attribute rom_block : boolean; attribute rom_block of mem : signal is TRUE; begin process (clk) begin if (clk'event and clk = '1') then dout <= mem ; reg_addr <= addr; end if; end process; process (reg_addr) begin CASE reg_addr IS WHEN "000000" => WHEN "000001" => WHEN "000010" => WHEN "000011" => WHEN "000100" => WHEN "000101" => WHEN "000110" =>

mem mem mem mem mem mem mem

<= <= <= <= <= <= <=

"1111101100110100"; "0000101011011110"; "1101110110101000"; "1101110111010110"; "0111101000000010"; "0011110000111010"; "0110101010111000";

250

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Common Guidelines

VHDL Explicit Constant Arrays


Figure 8-5. VHDL ROM Implement Using Array of Constants
entity rom_to_ram_const is port(clk : in std_logic; addr : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(15 downto 0) ); end entity rom_to_ram_const; architecture rtl of rom_to_ram_const is type mem_type is array (15 downto 0) of std_logic_vector(15 downto 0) ; CONSTANT mem : mem_type := ( (0000000000000001), (0000000000000010), (0000000000000100), (0000000000001000), (0000000000010000), (0000000000100000), (0000000001000000), (0000000010000000), (0000000100000000), (0000001000000000), (0000010000000000), (0000100000000000), (0001000000000000), (0010000000000000), (0100000000000000),

Precision Synthesis Style Guide, 2011a Update2 November 2011

251

Memory Common Guidelines

VHDL Memory Initialization


Figure 8-6. VHDL Memory Initialization Example
LIBRARY IEEE ; USE IEEE.std_logic_1164.ALL ; USE IEEE.std_logic_unsigned.ALL ; USE STD.textio.ALL ; USE IEEE.std_logic_textio.ALL ; ENTITY ram_synch IS GENERIC (d_width : INTEGER := 16 ; a_width : INTEGER := 8 ; INIT_FILE_FORMAT_HEX : boolean := true

) ;

PORT (data_in : IN std_logic_vector(d_width-1 DOWNTO 0) ; address : IN std_logic_vector(a_width-1 DOWNTO 0) ; wr_en, inclock, outclock : IN STD_LOGIC ; dout : OUT std_logic_vector(d_width-1 DOWNTO 0) ); END ENTITY ; ARCHITECTURE infer OF ram_synch IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF std_logic_vector(d_width-1 DOWNTO 0); SIGNAL address_save : std_logic_vector(a_width-1 DOWNTO 0) ; FUNCTION initmem RETURN mem_type IS VARIABLE i : NATURAL ; VARIABLE depth : INTEGER := 2**a_width ; VARIABLE value : LINE ; VARIABLE data : std_logic_vector(d_width-1 downto 0) ; VARIABLE memt : mem_type ; FILE initfile : text OPEN READ_MODE is D:\Temp\ram_init.txt ; BEGIN WHILE NOT endfile(initfile) AND i <= depth-1 LOOP readline(initfile,value); IF (INIT_FILE_FORMAT_HEX = true) THEN hread(value,data) ; ELSE read(value,data) ; END IF ; memt(i) := data ; i := i + 1 ; END LOOP ; RETURN memt ; END initmem ; SIGNAL mem : mem_type := initmem ; BEGIN ram : PROCESS (inclock,outclock) BEGIN IF (inclock = 1 AND inclockEVENT) THEN IF (wr_en = 1) THEN mem(CONV_INTEGER(address_save)) <= data_in ; END IF ; address_save <= address ; END IF ; IF (outclock = 1 AND outclockEVENT) THEN dout <= mem(CONV_INTEGER(address_save)) ; END IF ; END PROCESS ram ; END ARCHITECTURE ;

252

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Common Guidelines

Verilog Coding Techniques


Using the CASE Statement
Figure 8-7. Verilog ROM Using CASE Statement
`define WIDTH_A 6 `define WIDTH_D 16 `define RAM_DEPTH 256 module rom_to_blockram ( addr, clk, dout ); input [`WIDTH_A-1:0] addr; input clk; reg [`WIDTH_A-1:0] reg_addr; reg [`WIDTH_D-1:0] mem; output reg [`WIDTH_D-1:0] dout; //pragma attribute mem rom_block TRUE always @ (posedge clk) begin dout <= mem; reg_addr <= addr; end always @(reg_addr ) begin case (reg_addr ) 6'b000000 : mem = 16'b1111101100110100; 6'b000001 : mem = 16'b0000101011011110; 6'b000010 : mem = 16'b1101110110101000; 6'b000011 : mem = 16'b1101110111010110; 6'b000100 : mem = 16'b0111101000000010; 6'b000101 : mem = 16'b0011110000111010; 6'b000110 : mem = 16'b0110101010111000; 6'b000111 : mem = 16'b0101001110110100; 6'b001000 : mem = 16'b0011111110111110; 6'b001001 : mem = 16'b1111100110000100; 6'b001010 : mem = 16'b0111100111101100; 6'b001011 : mem = 16'b1111100101101000; 6'b001100 : mem = 16'b1101101100111000; 6'b001101 : mem = 16'b0110110111100100; 6'b001110 : mem = 16'b1000001011100010; 6'b001111 : mem = 16'b1111110010111000; 6'b010000 : mem = 16'b1000010100110000; 6'b010001 : mem = 16'b0010100010111000; 6'b010010 : mem = 16'b1010101010101010; 6'b010011 : mem = 16'b1111010100010100; 6'b010100 : mem = 16'b1110001110000100; 6'b010101 : mem = 16'b0111010000010000; 6'b010110 : mem = 16'b1110000000110010; 6'b010111 : mem = 16'b0010111001010000; 6'b011000 : mem = 16'b0100100011001100; 6'b011001 : mem = 16'b0011010110111010; 6'b011010 : mem = 16'b0101100100101100; 6'b011011 : mem = 16'b1101000111111000; 6'b011100 : mem = 16'b0101100010001100; 6'b011101 : mem = 16'b1010001011001100; 6'b011110 : mem = 16'b1001011101111000; 6'b011111 16'b0111011100010000

Precision Synthesis Style Guide, 2011a Update2 November 2011

253

Memory Common Guidelines

Verilog Explicit Constant Arrays


Figure 8-8. Verilog ROM Using Array of Constants
module input input output rom_to_ram_const (clk, addr, data_out); logic clk; logic [7:0] addr; logic [15:0] data_out;

typedef logic [15:0] mem_type [15:0]; const mem_type mem = { 16'b0000000000000001, 16'b0000000000000010, 16'b0000000000000100, 16'b0000000000001000, 16'b0000000000010000, 16'b0000000000100000, 16'b0000000001000000, 16'b0000000010000000, 16'b0000000100000000, 16'b0000001000000000, 16'b0000010000000000, 16'b0000100000000000, 16'b0001000000000000, 16'b0010000000000000, 16'b0100000000000000, 16'b1000000000000000 }; //pragma attribute mem rom_block 1 always_ff @(posedge clk) begin data_out <= mem[integer'(addr)]; end endmodule

254

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Common Guidelines

The $readmemh Function


Figure 8-9. Verilog ROM Initialization Using $readmemh Function
define addr_width 8 define data_width 16 module readmemh( input clk, rst, input [addr_width-1:0] addr, output reg [data_width-1:0] dataout); reg [addr_width-1:0] reg_addr; //pragma attribute mem rom_block 0 reg [data_width-1:0] mem[0:2**addr_width-1]; initial begin // Make sure to provide the actual physical path for the binary file $readmemh("./rom_init.hex", mem); end always@(posedge clk) begin if (rst) reg_addr <= 0; else reg_addr <= addr; end always@(posedge clk)

The $readmemb Function


Figure 8-10. Verilog ROM Initialization Using $readmemb Function
define addr_width 8 define data_width 16 module readmemb( input clk, rst, input [addr_width-1:0] addr, output reg [data_width-1:0] dataout); reg [addr_width-1:0] reg_addr; reg [data_width-1:0] mem[0:2**addr_width-1]; //pragma attribute mem rom_block 1 initial begin // Make sure to provide the actual physical path for the binary file $readmemb("./rom_init.bin", mem); end always@(posedge clk) begin if (rst) reg_addr <= 0; else reg_addr <= addr; end always@(posedge clk) d t t < [

dd ]

Precision Synthesis Style Guide, 2011a Update2 November 2011

255

Memory Common Guidelines

Byte-Enable Memories
Some FPGA devices have memory resources that have byte-enable pins control writing data to a selected byte, instead of the entire data width. Precision has enhanced RAM inference support of byte-enable RAM. The example below of a 16-bit data word RAM will write to all 16 bits during a write cycle:
always @(posedge clk) begin dout = mem[addr]; if (WE) begin mem [addr][15:0] = din [15:0]; end end

The code can be restructured to select the memory byte, or bytes, enabled during a write cycle:
always @(posedge clk) begin dout = mem[addr]; if (WE) begin if(byteena[0]) mem [addr][7:0] = din [7:0]; if(byteena[1]) mem [addr][15:8] = din [15:8]; end end

Supported Byte-Enable Device Families


Table 8-1. Supported Byte-Enable Device Families Vendor Altera Device Family Stratix II Stratix III Stratix IV Virtex-4 Xilinx Virtex-5 Virtex-6

Inferring Byte-Enabled RAM in Precision


Byte-enabled RAM inference and implementation occurs during both the Compile and Synthesize stages in the Precision flow.

256

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Common Guidelines

Compile Stage Operations


Precision infers byte-enable pins during the Compile stage Precision creates the appropriate byte-enable glue logic to pass to the Synthesize stage. The type of glue logic depends on the following memory attributes:
o o o

Read-First or Write-First Byte-enable has overlapping conditions Single or dual port configuration

Synthesis Stage Operations


During synthesis, Precision detects the byte enable functionality and maps the RAM to the FPGA technology RAM cell using its dedicated byte-enable port. For Alteras altsyncram cell, Precision makes use of the separate byte enable pin named .byteena_a. For Xilinx BRAMs, Precision makes use of the technology cells write-enable pins (4 are available) as the byte-enables.

Supported Byte-Enable RTL Coding Styles


Several characteristics of byte-enabled memory, as described in the RTL, determine how the memory and respective glue logic are inferred in Precision: Write mode determines the behavior of the data available on the output after a write
o o o

Write First outputs the newly written data onto the output bus Read First outputs the previously stored data while new data is being written No Change maintains the output previously generated by a read operation

Enable priority versus independent byte-write determines the priority of enable pins when multiple byte-enable pins control different data bytes of a single memory address. If there is no explicit priority, then each enable pin is considered an independent bytewrite enable. Overlapping conditions when a single byte-wide enable controls the same address space controlled by another multi-byte-wide enable Single or Dual Port determines whether the memory has independent access ports for read and write operations.

Precision Synthesis Style Guide, 2011a Update2 November 2011

257

Memory Common Guidelines

Byte-Enabled Coding Style Samples


The following are different RTL coding examples of byte-write enable memories with the characteristics described previously.

Read First Memory Styles


Read First, Independant Byte-Enable, Single Port
CASE Statement module byte_ram (clk, we, byteena, addr, din, dout); parameter datawidth = 32; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [3:0] byteena; input [datawidth-1:0] din; input [addrwidth-1:0] addr; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin dout = mem[addr]; if (we) casex (byteena[3:0]) // synopsys parallel_case full_case 4'bxxx1: mem [addr][7:0] = din [7:0]; 4'bxx1x: mem [addr][15:8] = din [15:8]; 4'bx1xx: mem [addr][23:16] = din [23:16]; 4'b1xxx: mem [addr][31:24] = din [31: 24]; endcase end endmodule IF Statements module byte_ram (clk, we, byteena, addr, din, dout); parameter datawidth = 16; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din; input [addrwidth-1:0] addr; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin dout = mem[addr]; if (we) if(byteena[0]) mem[addr][7:0] = din[7:0];

258

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Common Guidelines else if(byteena[1]) mem[addr][15:8] = din[15:8]; end endmodule

Read First, Priority-Enable, Single Port


module byte_ram (clk, wen, byteena, addr, din, dout); parameter datawidth = 32; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, wen; input [3:0] byteena; input [datawidth-1:0] din; input [addrwidth-1:0] addr; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin dout = mem[addr]; if(wen) begin if (byteena[0]) mem[addr][7:0] else if(byteena[1]) mem[addr][15:8] else if(byteena[2]) mem[addr][23:16] else if(byteena[3]) mem[addr][31:24] end end endmodule

= = = =

din[7:0]; din[15:8]; din[23:16]; din[31:24];

Read First/ Independent Byte-Enable / Overlapping Conditions / Single Port


module byte_ram (clk, we, byteena, addr, din1, din2, dout); parameter datawidth = 16; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din1, din2; input [addrwidth-1:0] addr; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin dout = mem[addr]; if (we) if(byteena[0]) mem[addr][7:0] = din1; else if(byteena[1]) mem[addr] = din2; end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

259

Memory Common Guidelines

Read First / Independent Byte-Enable / Overlapping Conditions / Dual Port


module byte_ram (clk, we, byteena, addr1, addr2, din1, din2, dout); parameter datawidth = 16; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din1, din2; input [addrwidth-1:0] addr1, addr2; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin dout = mem[addr1]; if (we) if(byteena[0]) mem[addr1][7:0] = din1; else if(byteena[1]) mem[addr2] = din2; end endmodule

Read First / Independent Byte-Enable / Partial addresses Dual Port


module byte_ram (clk, we, byteena, addr1, addr2, din1, din2, dout); parameter datawidth = 16; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din1, din2; input [addrwidth-1:0] addr1, addr2; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin dout = mem[addr1]; if (we) if(byteena[0]) mem[addr1][7:0] = din1; else if(byteena[1]) mem[addr2] [15:8] = din2; end endmodule

260

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Common Guidelines

Write First Memory Styles


Write First / Independent Byte Write / Single Port
Using CASEX Statement module byte_ram (clk, we, byteena, addr, din, dout); parameter datawidth = 16; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din; input [addrwidth-1:0] addr; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin if (we) casex (byteena[1:0]) 2'bx1: mem [addr][7:0] = din [7:0]; 2'b1x: mem [addr][15:8] = din [15:8]; endcase dout = mem[addr]; end endmodule Using the IF Construct module byte_ram (clk, we, byteena, addr, din, dout); parameter datawidth = 16; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din; input [addrwidth-1:0] addr; output reg[datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin if (we) if(byteena[0]) mem[addr][7:0] = din[7:0]; if(byteena[1]) mem[addr][15:8] = din[15:8]; dout = mem[addr]; end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

261

Memory Common Guidelines

Write First / Priority Enable / Single Port


module byte_ram (clk, wen, byteena, addr, din, dout); parameter datawidth = 32; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, wen; input [3:0] byteena; input [datawidth-1:0] din; input [addrwidth-1:0] addr; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin if(wen) if(byteena[0]) mem[addr][7:0] = din[7:0]; else if(byteena[1]) mem[addr][15:8] = din[15:8]; else if(byteena[2]) mem[addr][23:16] = din[23:16]; else if(byteena[3]) mem[addr][31:24] = din[31:24]; dout = mem[addr]; end endmodule

Write First / Independent Byte-Write / Overlapping conditions / Single Port


module byte_ram (clk, we, byteena, addr, din1, din2, dout); parameter datawidth = 16; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din1, din2; input [addrwidth-1:0] addr; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin if (we) if(byteena[0]) mem[addr][7:0] = din1; if(byteena[1]) mem[addr] = din2; dout = mem[addr]; end endmodule

Write First / Independent Byte-Write / Overlapping Conditions / Dual Port


module byte_ram (clk, we, byteena, addr1, addr2, din1, din2, dout); parameter datawidth = 16;

262

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory VHDL/Verilog Differences parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din1, din2; input [addrwidth-1:0] addr1, addr2; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin if (we) if(byteena[0]) mem[addr1][7:0] = din1; if(byteena[1]) mem[addr2] = din2; dout = mem[addr1]; end endmodule

Write First / Independent Byte-Enable / Partial addresses / Dual Port


module byte_ram (clk, we, byteena, addr1, addr2, din1, din2, dout); parameter datawidth = 16; parameter addrwidth = 10; parameter mem_depth = (2**addrwidth)-1; input clk, we; input [1:0] byteena; input [datawidth-1:0] din1, din2; input [addrwidth-1:0] addr1, addr2; output reg [datawidth-1:0] dout; reg [datawidth-1:0] mem [0:mem_depth]; always @(posedge clk) begin if (we) if(byteena[0]) mem[addr1][7:0] = din1; if(byteena[1]) mem[addr2] [15:8] = din2; dout = mem[addr1]; end endmodule

VHDL/Verilog Differences
Initializing RAM in Verilog
You can use the $readmemh (hex) and $readmemb (binary) Verilog functions to initialize RAMs and ROMs. When an initialized RAM or ROM is inferred, the appropriate attributes on the associated RAM/ROM instances in the netlist are set.

Precision Synthesis Style Guide, 2011a Update2 November 2011

263

Memory Optimization Issues

Optimization Issues
Initialization Values
The following lists describes how Precision maps the initialization values to attributes in the EDIF file for each supported technology: Xilinx Virtex block RAMs use the INIT_XX and INITP_XX attributes. Xilinx Distributed RAMs use the INIT attribute on the flop. Altera APEX LPM_RAMs use a hex file with the filename specified by the LPM_FILE attribute. Altera Stratix ALTSYNCRAMs use a hex file with the filename specified by the LPM_FILE attribute. Lattice devices supporting sysMEM EBRs have the attribute INIT_VAL_XX applied by Precision Synthesis. The MEM_INIT_FILE attribute can also be used, as decribed in Memory Initialization section of Designing with Lattice Devices chapter, Precision Synthesis Reference Manual.

Attributes Relating to Memory


The following attributes affect memory inferencing: block_ram (HDL only): Allows you to disable the mapping of a particular RAM instance to block RAM in Xilinx technologies. block_rom (HDL only): Allows attempt to infer a ROM for the signal that has the attribute specified. ram_block (HDL only): Guides Precision to map an inferred RAM structure into the target technologys block RAM resource. If the target technology doesnt support block RAM, then the structure will be mapped into distributed RAM or logic. ram_block_type (Altera only): Guides Precision to map an inferred RAM structure into the target technologys Block RAM resource type. If the target technology doesnt support Block RAM, then the structure will be mapped into distributed RAM or logic. rom_block (HDL only): Guides Precision to map an inferred ROM structure and transform it into the target technologys block RAM resource. If the target technology doesnt support block RAM, then the structure will be mapped into distributed RAM or logic.

264

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Memory Coding Examples

Memory Coding Examples


The following table shows the VHDL and Verilog examples described in this section. The code files are available in the Precision Synthesis software tree in the following directory:
<precision_install_dir>/shared/examples/style_guide_hdl/Memory

Table 8-2. Memory Examples Example Synchronous RAM example source file: ram_synch RAM with Synchronous Input example source file: ram_synch_in RAM with Synchronous Output example source file: ram_synch_out RAM with Synchronous Address example source file: ram_synch_in RAM with Synchronous Input/Output example source file: ram_synch_io Asynchronous RAM example source file: ram_asynch Synchronous I/O RAM example source file: ramio_synch I/O RAM with Synchronous Input example source file: ramio_synch_in I/O RAM with Synchronous Output example source file: ramio_synch_out I/O RAM with Synchronous Address example source file: ramio_synch_add I/O RAM with Synchronous Input/Output example source file: ramio_synch_io I/O Asynchronous RAM example source file: ramio_asynch Dual Port RAM example source file: ram_dualport Resets for Memory example source files: ram_reset1.v and
ram_reset2.v

Description RAM with synchronous data input, data output and address lines. RAM with synchronous data input and asynchronous address lines and data output. RAM with synchronous data output and asynchronous address and data input. RAM with synchronous address lines and asynchronous data input and data output. RAM with synchronous data input and data output and asynchronous address lines RAM with asynchronous data input, data output and address lines. RAM with synchronous address, data input, and data output lines. RAM with synchronous data input and asynchronous address and data output lines. RAM with synchronous data output and asynchronous address and data input lines. RAM with synchronous address and asynchronous data input and data output lines. RAM with synchronous data input and data output and asynchronous address line. RAM with asynchronous data input, data output and address lines. A 32 by 8 dual port RAM. There are separate read and write clocks as well as separate read and write addresses. Precision supports 2 types of reset for memory; reset that clears the contents of the memory array, and reset that clears the output registers on read ports.

Precision Synthesis Style Guide, 2011a Update2 November 2011

265

Memory Memory Coding Examples

Table 8-2. Memory Examples Example ROM example source file: rom_sin Synchronous ROM example source file: rom_to_blockram Description This is an example of read-only memory. This is an example of synchronous read-only memory.

266

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Synchronous RAM

Synchronous RAM
RAM with synchronous data input, data output and address lines. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ram_synch IS GENERIC (d_width a_width : NATURAL := 4 ; : NATURAL := 4);

Verilog
module ram_synch (data_in, address, wr_en, inclock, outclock, dout); parameter d_width = 4; parameter a_width = 4; input [d_width-1:0] data_in; input [a_width-1:0] address; input wr_en, inclock, outclock; output [d_width-1:0] dout; reg [d_width-1:0] dout; reg [d_width-1:0] mem [1<<a_width:0]; reg [a_width-1:0] address_save; always @(posedge inclock) begin if (wr_en) mem[address_save] <= data_in; address_save <= address; end always @(posedge outclock) dout <= mem[address_save]; endmodule

PORT (data_in : IN UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, inclock, outclock : IN STD_LOGIC; dout : OUT UNSIGNED(d_width-1 DOWNTO 0) ); END ENTITY; ARCHITECTURE infer OF ram_synch IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; SIGNAL address_save : UNSIGNED(a_width-1 DOWNTO 0); BEGIN ram : PROCESS (inclock,outclock) BEGIN IF (inclock = 1 AND inclockEVENT) THEN IF (wr_en = 1) THEN mem(TO_INTEGER(address_save)) <= data_in; END IF ; address_save <= address; END IF; IF (outclock = 1 AND outclockEVENT) THEN dout <= mem(TO_INTEGER(address_save)); END IF; END PROCESS ram; END ARCHITECTURE ;

Precision Synthesis Style Guide, 2011a Update2 November 2011

267

Memory RAM with Synchronous Input

RAM with Synchronous Input


RAM with synchronous data input and asynchronous address lines and data output. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ram_synch_in IS GENERIC (d_width : NATURAL := 4 ; a_width : NATURAL := 8); PORT (data_in : IN UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, inclock : IN STD_LOGIC ; dout : OUT UNSIGNED(d_width-1 DOWNTO 0)); END ENTITY ; ARCHITECTURE infer OF ram_synch_in IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width - 1 DOWNTO 0); SIGNAL mem: mem_type ; BEGIN ram : PROCESS (inclock) BEGIN IF (inclock = 1 AND inclockEVENT) THEN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data_in ; END IF ; END IF; END PROCESS ram; dout <= mem(TO_INTEGER(address)); END ARCHITECTURE ; assign dout = mem[address]; endmodule

Verilog
module ram_synch_in (data_in, address, wr_en, inclock, dout); parameter d_width = 4; parameter a_width = 8; input [d_width-1:0] data_in; input [a_width-1:0] address; input wr_en, inclock; output [d_width-1:0] dout; reg [d_width-1:0] mem [1<<a_width:0]; always @(posedge inclock) begin if (wr_en) mem[address] <= data_in; end

268

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory RAM with Synchronous Output

RAM with Synchronous Output


RAM with synchronous data output and asynchronous address and data input. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ram_synch_out IS GENERIC (d_width : NATURAL := 4; a_width : NATURAL := 4); PORT (data_in : IN UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, outclock : IN STD_LOGIC; dout : OUT UNSIGNED(d_width-1 DOWNTO 0)); END ENTITY; ARCHITECTURE infer OF ram_synch_out IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; BEGIN ram: PROCESS (address,data_in,wr_en,outclock) BEGIN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data_in ; END IF ; IF (outclock = 1 AND outclockEVENT) THEN dout <= mem(TO_INTEGER(address)); END IF; END PROCESS ram; END ARCHITECTURE ;

Verilog
module ram_synch_out (data_in, address, wr_en, outclock, dout); parameter d_width = 4; parameter a_width = 4; input [d_width-1:0] data_in; input [a_width-1:0] address; input wr_en, outclock; output [d_width-1:0] dout; reg [d_width-1:0] dout; reg [d_width-1:0] mem [1<<a_width:0]; always @(address or data_in or wr_en or outclock) if (wr_en) mem[address] <= data_in; always @(posedge outclock) dout <= mem[address]; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

269

Memory RAM with Synchronous Address

RAM with Synchronous Address


RAM with synchronous address lines and asynchronous data input and data output. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ram_synch_add IS GENERIC (d_width : NATURAL := 4 ; a_width : NATURAL := 4); PORT (data_in : IN UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, addr_clk : IN STD_LOGIC; dout : OUT UNSIGNED(d_width-1 DOWNTO 0)); END ENTITY; ARCHITECTURE infer OF ram_synch_add IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0) ; SIGNAL mem: mem_type ; SIGNAL address_save : UNSIGNED(a_width-1 DOWNTO 0) ; BEGIN ram : PROCESS (wr_en, data_in, address, addr_clk) BEGIN IF (wr_en = 1) THEN mem(TO_INTEGER(address_save)) <= data_in; END IF ; IF (addr_clkEVENT AND addr_clk = 1) THEN address_save <= address; END IF; END PROCESS ram; dout <= mem(TO_INTEGER(address_save)); END ARCHITECTURE ;

Verilog
module ram_synch_addr (data_in, address, wr_en, addr_clock, dout); parameter d_width = 4; parameter a_width = 4; input [d_width-1:0] data_in; input [a_width-1:0] address; input wr_en, addr_clock; output [d_width-1:0] dout; reg [d_width-1:0] mem [1<<a_width:0]; reg [a_width-1:0] address_save; always @(wr_en or data_in or address) if (wr_en) mem[address_save] = data_in; always @(posedge addr_clock) address_save <= address; assign dout = mem[address_save]; endmodule

270

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory RAM with Synchronous Input/Output

RAM with Synchronous Input/Output


RAM with synchronous data input and data output and asynchronous address lines VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ram_synch_io IS GENERIC (d_width : NATURAL := 4; a_width : NATURAL := 4); PORT (data_in : IN UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, inclock, outclock : IN STD_LOGIC ; dout : OUT UNSIGNED(d_width-1 DOWNTO 0)); END ENTITY; ARCHITECTURE infer OF ram_synch_io IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; BEGIN ram : PROCESS (inclock,outclock) BEGIN IF (inclock = 1 AND inclockEVENT) THEN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data_in ; END IF ; END IF; IF (outclock = 1 AND outclockEVENT) THEN dout <= mem(TO_INTEGER(address)); END IF; END PROCESS ram; END ARCHITECTURE ;

Verilog
module ram_synch_io (data_in, address, wr_en, inclock, outclock, dout); parameter d_width = 4; parameter a_width = 4; input [d_width-1:0] data_in; input [a_width-1:0] address; input wr_en, inclock, outclock; output [d_width-1:0] dout; reg [d_width-1:0] dout; reg [d_width-1:0] mem [1<<a_width:0]; always @(posedge inclock) if (wr_en) mem[address] <= data_in; always @(posedge outclock) dout <= mem[address]; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

271

Memory Asynchronous RAM

Asynchronous RAM
RAM with asynchronous data input, data output and address lines. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY ram_asynch IS GENERIC (d_width : NATURAL := 4; a_width : NATURAL := 4); PORT (data_in : IN UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en : IN STD_LOGIC; dout : OUT UNSIGNED(d_width-1 DOWNTO 0)); END ENTITY ; ARCHITECTURE infer OF ram_asynch IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; BEGIN asynch : PROCESS (wr_en,address,data_in) BEGIN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data_in; END IF ; END PROCESS ; dout <= mem(TO_INTEGER(address)); END ARCHITECTURE ;

Verilog
module ram_asynch (data_in, address, wr_en, dout); parameter d_width = 4; parameter a_width = 4; input [d_width-1:0] data_in; input [a_width-1:0] address; input wr_en; output [d_width-1:0] dout; reg [d_width-1:0] dout; reg [d_width-1:0] mem [1<<a_width:0]; always @(wr_en or address or data_in) begin if (wr_en) mem[address] <= data_in; dout <= mem[address]; end endmodule

272

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Synchronous I/O RAM

Synchronous I/O RAM


RAM with synchronous address, data input, and data output lines. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ramio_synch IS GENERIC (d_width : NATURAL := 4 ; a_width : NATURAL := 4); PORT (data : INOUT UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, read_en, inclock, outclock : IN STD_LOGIC); END ENTITY; ARCHITECTURE infer OF ramio_synch IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; SIGNAL data_tmp : UNSIGNED(d_width-1 DOWNTO 0); SIGNAL address_save : UNSIGNED(a_width-1 DOWNTO 0); BEGIN sync_in : PROCESS (inclock,outclock) BEGIN IF (inclock = 1 AND inclockEVENT) THEN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data ; END IF ; address_save <= address; END IF; IF (outclock = 1 AND outclockEVENT) THEN data_tmp <= mem(TO_INTEGER(address_save)); END IF; END PROCESS sync_in; data <= data_tmp WHEN (read_en = 1) ELSE (OTHERS => Z); END ARCHITECTURE ;

Verilog
module ramio_synch (data, address, wr_en, read_en, inclock, outclock); parameter d_width = 4; parameter a_width = 4; input [a_width-1:0] address; input wr_en, read_en, inclock, outclock; inout [d_width-1:0] data; reg [d_width-1:0] mem [1<<a_width:0]; reg [d_width-1:0] data_tmp; reg [a_width-1:0] address_save; always @(posedge inclock) begin if (wr_en) mem[address] <= data; address_save <= address; end always @(posedge outclock) data_tmp <= mem[address_save]; assign data = read_en ? data_tmp : bz; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

273

Memory I/O RAM with Synchronous Input

I/O RAM with Synchronous Input


RAM with synchronous data input and asynchronous address and data output lines. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ramio_synch_in IS GENERIC (d_width : NATURAL := 4 ; a_width : NATURAL := 4); : INOUT UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, read_en, inclock : IN STD_LOGIC ); END ENTITY; ARCHITECTURE infer OF ramio_synch_in IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; BEGIN sync_in : PROCESS (inclock) BEGIN IF (inclock = 1 AND inclockEVENT) THEN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data ; END IF ; END IF; END PROCESS sync_in; data <= mem(TO_INTEGER(address)) WHEN (read_en = 1) ELSE (OTHERS => Z); END ARCHITECTURE ; PORT (data

Verilog
module ramio_synch_in (data, address, wr_en, read_en, inclock); parameter d_width = 4; parameter a_width = 4; input [a_width-1:0] address; input wr_en, read_en, inclock; inout [d_width-1:0] data; reg [d_width-1:0] mem [1<<a_width:0]; always @(posedge inclock) if (wr_en) mem[address] <= data; assign data = read_en?mem[address]:bz; endmodule

274

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory I/O RAM with Synchronous Output

I/O RAM with Synchronous Output


RAM with synchronous data output and asynchronous address and data input lines. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ramio_synch_out IS GENERIC (d_width : NATURAL := 4; a_width : NATURAL := 4); PORT (data : INOUT UNSIGNED (d_width-1 DOWNTO 0); address : IN UNSIGNED (a_width-1 DOWNTO 0); wr_en, read_en, outclock : IN STD_LOGIC); END ENTITY; ARCHITECTURE infer OF ramio_synch_out IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; SIGNAL data_tmp : UNSIGNED(d_width-1 DOWNTO 0); BEGIN sync_in : PROCESS (wr_en,address, data,outclock) BEGIN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data ; END IF ; IF (outclock=1 AND outclockEVENT) THEN data_tmp <= mem(TO_INTEGER(address)); END IF; END PROCESS sync_in; data <= data_tmp WHEN (read_en = 1) ELSE (OTHERS => Z); END ARCHITECTURE ;

Verilog
module ramio_synch_out (data, address, wr_en, read_en, outclock); parameter d_width = 4; parameter a_width = 4; input [a_width-1:0] address; input wr_en, read_en, outclock; inout [d_width-1:0] data; reg [d_width-1:0] mem [1<<a_width:0]; reg [d_width-1:0] data_tmp; always @(wr_en or address or data) if (wr_en) mem[address] <= data; always @(posedge outclock) data_tmp <= mem[address]; assign data = read_en ? data_tmp:bz; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

275

Memory I/O RAM with Synchronous Address

I/O RAM with Synchronous Address


RAM with synchronous address and asynchronous data input and data output lines. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ramio_synch_add IS GENERIC (d_width : NATURAL := 4 ; a_width : NATURAL := 4); PORT (data : INOUT UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, read_en, addr_clock : IN STD_LOGIC); END ENTITY; ARCHITECTURE infer OF ramio_synch_add IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; SIGNAL address_save : UNSIGNED(a_width-1 DOWNTO 0); BEGIN ram : PROCESS (address, addr_clock, wr_en, data) BEGIN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data ; END IF ; IF (addr_clock = 1 AND addr_clockEVENT) THEN address_save <= address; END IF; END PROCESS ram; data <= mem(TO_INTEGER(address_save)) WHEN (read_en = 1) ELSE (OTHERS => Z); END ARCHITECTURE ;

Verilog
module ramio_synch_add (data, address, wr_en, read_en, addr_clock); parameter d_width = 4; parameter a_width = 4; input [a_width-1:0] address; input wr_en, read_en, addr_clock; inout [d_width-1:0] data; reg [d_width-1:0] mem [1<<a_width:0]; reg [a_width-1:0] add_save; always @(posedge addr_clock) add_save <= address; always @(address or wr_en or data) if (wr_en) mem[address] <= data; assign data = read_en ? mem [add_save]:bz; endmodule

276

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory I/O RAM with Synchronous Input/Output

I/O RAM with Synchronous Input/Output


RAM with synchronous data input and data output and asynchronous address line. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ramio_synch_io IS GENERIC (d_width : NATURAL := 4 ; a_width : NATURAL := 4); PORT (data : INOUT UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, read_en, inclock, outclock : IN STD_LOGIC ); END ENTITY; ARCHITECTURE infer OF ramio_synch_io IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED (d_width-1 DOWNTO 0); SIGNAL mem: mem_type ; SIGNAL data_tmp : UNSIGNED (d_width-1 DOWNTO 0); BEGIN sync_in : PROCESS (inclock,outclock) BEGIN IF (inclock = 1 AND inclockEVENT) THEN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data ; END IF ; END IF; IF (outclock = 1 AND outclockEVENT) THEN data_tmp <= mem(TO_INTEGER(address)); END IF; END PROCESS sync_in; data <= data_tmp WHEN (read_en = 1) ELSE (OTHERS => Z); END ARCHITECTURE ;

Verilog
module ramio_synch_io (data, address, wr_en, read_en, inclock, outclock); parameter d_width = 4; parameter a_width = 4; input [a_width-1:0] address; input wr_en, read_en, inclock, outclock; inout [d_width-1:0] data; reg [d_width-1:0] mem [1<<a_width:0]; reg [d_width-1:0] data_tmp; always @(posedge inclock) if (wr_en) mem[address] <= data; always @(posedge outclock) data_tmp <= mem[address]; assign data = read_en ? data_tmp : bz; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

277

Memory I/O Asynchronous RAM

I/O Asynchronous RAM


RAM with asynchronous data input, data output and address lines. VHDL
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL ; USE ieee.numeric_std.ALL; ENTITY ramio_asynch IS GENERIC (d_width : NATURAL := 4 ; a_width : NATURAL := 4); PORT (data : INOUT UNSIGNED(d_width-1 DOWNTO 0); address : IN UNSIGNED(a_width-1 DOWNTO 0); wr_en, read_en : IN STD_LOGIC) ; END ENTITY ; ARCHITECTURE infer OF ramio_asynch IS TYPE mem_type IS ARRAY (2**a_width DOWNTO 0) OF UNSIGNED(d_width - 1 DOWNTO 0); SIGNAL mem: mem_type ; BEGIN asynch : PROCESS (wr_en,address,data) BEGIN IF (wr_en = 1) THEN mem(TO_INTEGER(address)) <= data ; END IF ; END PROCESS ; data <= mem(TO_INTEGER(address)) WHEN (read_en = 1) ELSE (OTHERS => Z); END ARCHITECTURE ;

Verilog
module ramio_asynch (data, address, wr_en, read_en); parameter d_width = 4; parameter a_width = 4; input [a_width-1:0] address; input wr_en, read_en; inout [d_width-1:0] data; reg [d_width-1:0] mem [1<<a_width:0]; always @(wr_en or address or data) if (wr_en) mem[address] <= data; assign data = read_en ? mem [address]:bz; endmodule

278

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Dual Port RAM

Dual Port RAM


A 32 by 8 dual port RAM. There are separate read and write clocks as well as separate read and write addresses. VHDL
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY ram_dualport IS PORT (write_clk, wea : IN STD_LOGIC; rd_clk : IN STD_LOGIC; data_in : IN UNSIGNED(7 DOWNTO 0); addr_write, addr_read : IN UNSIGNED (4 DOWNTO 0); data_out : OUT UNSIGNED(7 DOWNTO 0)); END ENTITY; ARCHITECTURE infer OF ram_dualport IS TYPE mem_type IS ARRAY (31 DOWNTO 0) OF UNSIGNED(7 DOWNTO 0); SIGNAL MEM : mem_type; BEGIN ram_proc: PROCESS (write_clk, rd_clk) BEGIN IF (write_clkEVENT AND write_clk=1) THEN IF wea=1 THEN MEM(TO_INTEGER(addr_write)) <= data_in; END IF; END IF; IF ( rd_clkEVENT AND rd_clk=1 ) THEN data_out <= MEM(TO_INTEGER(addr_read)); END IF; END PROCESS ram_proc; END ARCHITECTURE;

Verilog
module ram_dualport (write_clock, wea, read_clock, data_in, addr_write, addr_read, data_out); input write_clock, wea, read_clock; input [7:0] data_in; input [4:0] addr_write, addr_read; output [7:0] data_out; reg [7:0] data_out; reg [7:0] mem [31:0]; always @(posedge write_clock) if (wea) mem[addr_write] <= data_in; always @(posedge read_clock) data_out <= mem [addr_read]; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

279

Memory Resets for Memory

Resets for Memory


Precision supports 2 types of reset for memory; reset that clears the contents of the memory array, and reset that clears the output registers on read ports. The Verilog source files shown below are named ram_reset1.v and ram_reset1.v, are located in the examples directory, as noted in Memory Coding Examples on page 265

Verilog reset memory contents


define WIDTH_A 9 define WIDTH_D 4 define RAM_DEPTH 256 module top ( addr, we, clk, din, dout, rst ); input [WIDTH_A-1:0] addr; input we, rst; input clk; input [WIDTH_D-1:0] din; output [WIDTH_D-1:0] dout; reg [WIDTH_D-1:0] mem[0:RAM_DEPTH-1]; reg [WIDTH_D-1:0] dout; reg [WIDTH_A:0] i; always @( posedge clk or posedge rst ) begin if( rst) begin for (i = 0 ; i <= 255; i = i+1) mem[i] <= 0; end else begin if( we ) mem[addr] <= din; dout <= mem[addr]; end end endmodule

Verilog reset read port registers


define WIDTH_A 8 define WIDTH_D 4 define RAM_DEPTH 256 module top ( addr, we, clk, din, dout, rst ); input [WIDTH_A-1:0] addr; input we, rst; input clk; input [WIDTH_D-1:0] din; output [WIDTH_D-1:0] dout; reg [WIDTH_D-1:0] mem[0:RAM_DEPTH-1]; reg [WIDTH_D-1:0] dout; always @( posedge clk ) begin if( we ) mem[addr] <= din; if( rst) dout <= 0; else dout <= mem[addr]; end endmodule

280

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory ROM

ROM
This is an example of read-only memory. VHDL The HDL source file shown below is named rom_sin.vhd and is located in the examples directory, as noted in Memory Coding Examples on page 265.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; ENTITY rom_sin IS PORT (addr: IN UNSIGNED(6 DOWNTO 0); sin: OUT UNSIGNED(10 DOWNTO 0)); attribute rom_block : boolean; attribute rom_block of sin : signal is TRUE; END ENTITY; ARCHITECTURE rtl OF rom_sin BEGIN lut: PROCESS (addr) BEGIN CASE addr IS WHEN 0000000 => sin WHEN 0000001 => sin WHEN 0000010 => sin WHEN 0000011 => sin WHEN 0000100 => sin WHEN 0000101 => sin WHEN 0000110 => sin WHEN 0000111 => sin WHEN 0001000 => sin WHEN 0001001 => sin WHEN 0001010 => sin WHEN 0001011 => sin WHEN 0001100 => sin WHEN 0001101 => sin WHEN 0001110 => sin WHEN 0001111 => sin WHEN 0010000 => sin WHEN 0010001 => sin WHEN 0010010 => sin WHEN 0010011 => sin WHEN 0010100 => sin WHEN 0010101 => sin WHEN 0010110 => sin WHEN 0010111 => sin WHEN 0011000 => sin WHEN 0011001 => sin WHEN 0011010 => sin WHEN 0011011 => sin WHEN 0011100 => sin WHEN 0011101 => sin WHEN 0011110 => sin WHEN 0011111 => sin IS

<= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <=

00000000110; 00000001100; 00000010011; 00000011001; 00000100000; 00000100110; 00000101101; 00000110011; 00000111001; 00001000000; 00001000110; 00001001101; 00001010011; 00001011010; 00001100000; 00001100110; 00001101101; 00001110011; 00001111010; 00010000000; 00010000111; 00010001101; 00010010011; 00010011010; 00010100000; 00010100111; 00010101101; 00010110011; 00010111010; 00011000000; 00011000111; 00011001101;

Precision Synthesis Style Guide, 2011a Update2 November 2011

281

Memory ROM WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN WHEN 0100000 0100001 0100010 0100011 0100100 0100101 0100110 0100111 0101000 0101001 0101010 0101011 0101100 0101101 0101110 0101111 0110000 0110001 0110010 0110011 0110100 0110101 0110110 0110111 0111000 0111001 0111010 0111011 0111100 0111101 0111110 0111111 1000000 1000001 1000010 1000011 1000100 1000101 1000110 1000111 1001000 1001001 1001010 1001011 1001100 1001101 1001110 1001111 1010000 1010001 1010010 1010011 1010100 1010101 1010110 1010111 1011000 1011001 => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= 00011010011; 00011011010; 00011100000; 00011100111; 00011101101; 00011110011; 00011111010; 00100000000; 00100000111; 00100001101; 00100010011; 00100011010; 00100100000; 00100100110; 00100101101; 00100110011; 00100111010; 00101000000; 00101000110; 00101001101; 00101010011; 00101011001; 00101100000; 00101100110; 00101101100; 00101110011; 00101111001; 00101111111; 00110000110; 00110001100; 00110010010; 00110011001; 00110011111; 00110100101; 00110101011; 00110110010; 00110111000; 00110111110; 00111000101; 00111001011; 00111010001; 00111010111; 00111011110; 00111100100; 00111101010; 00111110000; 00111110111; 00111111101; 01000000011; 01000001001; 01000001111; 01000010110; 01000011100; 01000100010; 01000101000; 01000101111; 01000110101; 01000111011;

282

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory ROM WHEN 1011010 WHEN 1011011 WHEN 1011100 WHEN 1011101 WHEN 1011110 WHEN 1011111 WHEN 1100000 WHEN 1100001 WHEN 1100010 WHEN 1100011 WHEN 1100100 WHEN 1100101 WHEN 1100110 WHEN 1100111 WHEN 1101000 WHEN 1101001 WHEN 1101010 WHEN 1101011 WHEN 1101100 WHEN 1101101 WHEN 1101110 WHEN 1101111 WHEN 1110000 WHEN 1110001 WHEN 1110010 WHEN 1110011 WHEN 1110100 WHEN 1110101 WHEN 1110110 WHEN 1110111 WHEN 1111000 WHEN 1111001 WHEN 1111010 WHEN 1111011 WHEN 1111100 WHEN 1111101 WHEN 1111111 WHEN OTHERS END CASE; END PROCESS lut; END ARCHITECTURE; => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= 01001000001; 01001000111; 01001001101; 01001010100; 01001011010; 01001100000; 01001100110; 01001101100; 01001110010; 01001111000; 01001111110; 01010000101; 01010001011; 01010010001; 01010010111; 01010011101; 01010100011; 01010101001; 01010101111; 01010110101; 01010111011; 01011000001; 01011000111; 01011001101; 01011010011; 01011011001; 01011011111; 01011100101; 01011101011; 01011110001; 01011110111; 01011111101; 01100000011; 01100001001; 01100001111; 01100010101; 01100100001; 00000000000;

Precision Synthesis Style Guide, 2011a Update2 November 2011

283

Memory ROM

Verilog The HDL source file shown below is named rom_sin.v and is located in the examples directory, as noted in Memory Coding Examples on page 265.
module rom_sin (addr, sin); input [6:0] addr; output [10:0] sin; reg [10:0] sin; //pragma attribute sin rom_block 1 always@(addr) case (addr) 0000000 : 0000001 : 0000010 : 0000011 : 0000100 : 0000101 : 0000110 : 0000111 : 0001000 : 0001001 : 0001010 : 0001011 : 0001100 : 0001101 : 0001110 : 0001111 : 0010000 : 0010001 : 0010010 : 0010011 : 0010100 : 0010101 : 0010110 : 0010111 : 0011000 : 0011001 : 0011010 : 0011011 : 0011100 : 0011101 : 0011110 : 0011111 : 0100000 : 0100001 : 0100010 : 0100011 : 0100100 : 0100101 : 0100110 : 0100111 : 0101000 : 0101001 : 0101010 : 0101011 :

sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

00000000110; 00000001100; 00000010011; 00000011001; 00000100000; 00000100110; 00000101101; 00000110011; 00000111001; 00001000000; 00001000110; 00001001101; 00001010011; 00001011010; 00001100000; 00001100110; 00001101101; 00001110011; 00001111010; 00010000000; 00010000111; 00010001101; 00010010011; 00010011010; 00010100000; 00010100111; 00010101101; 00010110011; 00010111010; 00011000000; 00011000111; 00011001101; 00011010011; 00011011010; 00011100000; 00011100111; 00011101101; 00011110011; 00011111010; 00100000000; 00100000111; 00100001101; 00100010011; 00100011010;

284

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory ROM 0101100 0101101 0101110 0101111 0110000 0110001 0110010 0110011 0110100 0110101 0110110 0110111 0111000 0111001 0111010 0111011 0111100 0111101 0111110 0111111 1000000 1000001 1000010 1000011 1000100 1000101 1000110 1000111 1001000 1001001 1001010 1001011 1001100 1001101 1001110 1001111 1010000 1010001 1010010 1010011 1010100 1010101 1010110 1010111 1011000 1011001 1011010 1011011 1011100 1011101 1011110 1011111 1100000 1100001 1100010 1100011 1100100 1100101 : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin sin = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 00100100000; 00100100110; 00100101101; 00100110011; 00100111010; 00101000000; 00101000110; 00101001101; 00101010011; 00101011001; 00101100000; 00101100110; 00101101100; 00101110011; 00101111001; 00101111111; 00110000110; 00110001100; 00110010010; 00110011001; 00110011111; 00110100101; 00110101011; 00110110010; 00110111000; 00110111110; 00111000101; 00111001011; 00111010001; 00111010111; 00111011110; 00111100100; 00111101010; 00111110000; 00111110111; 00111111101; 01000000011; 01000001001; 01000001111; 01000010110; 01000011100; 01000100010; 01000101000; 01000101111; 01000110101; 01000111011; 01001000001; 01001000111; 01001001101; 01001010100; 01001011010; 01001100000; 01001100110; 01001101100; 01001110010; 01001111000; 01001111110; 01010000101;

Precision Synthesis Style Guide, 2011a Update2 November 2011

285

Memory ROM 1100110 1100111 1101000 1101001 1101010 1101011 1101100 1101101 1101110 1101111 1110000 1110001 1110010 1110011 1110100 1110101 1110110 1110111 1111000 1111001 1111010 1111011 1111100 1111101 1111111 default endcase endmodule : : : : : : : : : : : : : : : : : : : : : : : : : sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = sin = : sin 01010001011; 01010010001; 01010010111; 01010011101; 01010100011; 01010101001; 01010101111; 01010110101; 01010111011; 01011000001; 01011000111; 01011001101; 01011010011; 01011011001; 01011011111; 01011100101; 01011101011; 01011110001; 01011110111; 01011111101; 01100000011; 01100001001; 01100001111; 01100010101; 01100100001; = 00000000000;

286

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Synchronous ROM

Synchronous ROM
This is an example of synchronous read-only memory. The ROM will map into block RAM resources, if available in the target device technology. VHDL The HDL source file shown below is named rom_to_blockram.vhd and is located in the examples directory, as noted in Memory Coding Examples on page 265.
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity rom_to_blockram is generic ( addr_width_c : integer := 6; data_width_c : integer := 16); port( clk : in std_logic; addr : in std_logic_vector(addr_width_c-1 downto 0); dout : out std_logic_vector(data_width_c-1 downto 0) ); end entity rom_to_blockram; architecture rtl of rom_to_blockram is signal mem : std_logic_vector(15 downto 0); signal reg_addr : std_logic_vector(addr_width_c-1 downto 0); attribute rom_block : boolean; attribute rom_block of mem : signal is TRUE; begin process (clk) begin if (clkevent and clk = 1) then dout <= mem ; reg_addr <= addr; end if; end process; process (reg_addr) begin CASE reg_addr IS WHEN 000000 => WHEN 000001 => WHEN 000010 => WHEN 000011 => WHEN 000100 => WHEN 000101 => WHEN 000110 => WHEN 000111 => WHEN 001000 => WHEN 001001 => WHEN 001010 => WHEN 001011 => WHEN 001100 => WHEN 001101 => WHEN 001110 =>

mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem

<= <= <= <= <= <= <= <= <= <= <= <= <= <= <=

1111101100110100; 0000101011011110; 1101110110101000; 1101110111010110; 0111101000000010; 0011110000111010; 0110101010111000; 0101001110110100; 0011111110111110; 1111100110000100; 0111100111101100; 1111100101101000; 1101101100111000; 0110110111100100; 1000001011100010;

Precision Synthesis Style Guide, 2011a Update2 November 2011

287

Memory Synchronous ROM WHEN 001111 WHEN 010000 WHEN 010001 WHEN 010010 WHEN 010011 WHEN 010100 WHEN 010101 WHEN 010110 WHEN 010111 WHEN 011000 WHEN 011001 WHEN 011010 WHEN 011011 WHEN 011100 WHEN 011101 WHEN 011110 WHEN 011111 WHEN 100000 WHEN 100001 WHEN 100010 WHEN 100011 WHEN 100100 WHEN 100101 WHEN 100110 WHEN 100111 WHEN 101000 WHEN 101001 WHEN 101010 WHEN 101011 WHEN 101100 WHEN 101101 WHEN 101110 WHEN 101111 WHEN 110000 WHEN 110001 WHEN 110010 WHEN 110011 WHEN 110100 WHEN 110101 WHEN 110110 WHEN 110111 WHEN 111000 WHEN 111001 WHEN 111010 WHEN 111011 WHEN 111100 WHEN 111101 WHEN 111110 WHEN 111111 WHEN OTHERS END CASE ; end process; => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= <= 1111110010111000; 1000010100110000; 0010100010111000; 1010101010101010; 1111010100010100; 1110001110000100; 0111010000010000; 1110000000110010; 0010111001010000; 0100100011001100; 0011010110111010; 0101100100101100; 1101000111111000; 0101100010001100; 1010001011001100; 1001011101111000; 0111011100010000; 0111011111011010; 1000110110101100; 1001111100001000; 0010000001011100; 1111001010000000; 1001011010010010; 1000010001001010; 0011000100110000; 0011110010101100; 0000011010011000; 1111101100010110; 0110000010101110; 0011100100010010; 1001110101000000; 0000111000001010; 0011001110010100; 1110101110011010; 0001100001110110; 1010011001111100; 0000010010000100; 1000000010000010; 1011111100100000; 0000110011011100; 0010001011000110; 0001000000001000; 1011011000100000; 0000100110100010; 0000111110011100; 0000011010010100; 0110011111100010; 1100111010110010; 0110000111111010; 0000000000000000;

end architecture rtl;

288

Precision Synthesis Style Guide, 2011a Update2 November 2011

Memory Synchronous ROM

Verilog The HDL source file shown below is named rom_to_blockram.v and is located in the examples directory, as noted in Memory Coding Examples on page 265.
define WIDTH_A 6 define WIDTH_D 16 define RAM_DEPTH 256 module rom_to_blockram ( addr, clk, dout ); input [WIDTH_A-1:0] addr; input clk; reg [WIDTH_A-1:0] reg_addr; reg [WIDTH_D-1:0] mem; output reg [WIDTH_D-1:0] dout; //pragma attribute mem rom_block TRUE always @ (posedge clk) begin dout <= mem; reg_addr <= addr; end always @(reg_addr ) case (reg_addr ) 6b000000 : mem 6b000001 : mem 6b000010 : mem 6b000011 : mem 6b000100 : mem 6b000101 : mem 6b000110 : mem 6b000111 : mem 6b001000 : mem 6b001001 : mem 6b001010 : mem 6b001011 : mem 6b001100 : mem 6b001101 : mem 6b001110 : mem 6b001111 : mem 6b010000 : mem 6b010001 : mem 6b010010 : mem 6b010011 : mem 6b010100 : mem 6b010101 : mem 6b010110 : mem 6b010111 : mem 6b011000 : mem 6b011001 : mem 6b011010 : mem 6b011011 : mem 6b011100 : mem 6b011101 : mem 6b011110 : mem 6b011111 : mem 6b100000 : mem 6b100001 : mem 6b100010 : mem begin = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 16b1111101100110100; 16b0000101011011110; 16b1101110110101000; 16b1101110111010110; 16b0111101000000010; 16b0011110000111010; 16b0110101010111000; 16b0101001110110100; 16b0011111110111110; 16b1111100110000100; 16b0111100111101100; 16b1111100101101000; 16b1101101100111000; 16b0110110111100100; 16b1000001011100010; 16b1111110010111000; 16b1000010100110000; 16b0010100010111000; 16b1010101010101010; 16b1111010100010100; 16b1110001110000100; 16b0111010000010000; 16b1110000000110010; 16b0010111001010000; 16b0100100011001100; 16b0011010110111010; 16b0101100100101100; 16b1101000111111000; 16b0101100010001100; 16b1010001011001100; 16b1001011101111000; 16b0111011100010000; 16b0111011111011010; 16b1000110110101100; 16b1001111100001000;

Precision Synthesis Style Guide, 2011a Update2 November 2011

289

Memory Synchronous ROM 6b100011 6b100100 6b100101 6b100110 6b100111 6b101000 6b101001 6b101010 6b101011 6b101100 6b101101 6b101110 6b101111 6b110000 6b110001 6b110010 6b110011 6b110100 6b110101 6b110110 6b110111 6b111000 6b111001 6b111010 6b111011 6b111100 6b111101 6b111110 6b111111 default endcase end endmodule : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem mem = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 16b0010000001011100; 16b1111001010000000; 16b1001011010010010; 16b1000010001001010; 16b0011000100110000; 16b0011110010101100; 16b0000011010011000; 16b1111101100010110; 16b0110000010101110; 16b0011100100010010; 16b1001110101000000; 16b0000111000001010; 16b0011001110010100; 16b1110101110011010; 16b0001100001110110; 16b1010011001111100; 16b0000010010000100; 16b1000000010000010; 16b1011111100100000; 16b0000110011011100; 16b0010001011000110; 16b0001000000001000; 16b1011011000100000; 16b0000100110100010; 16b0000111110011100; 16b0000011010010100; 16b0110011111100010; 16b1100111010110010; 16b0110000111111010; 16b0000000000000000;

290

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 9 Finite State Machines


This section describes the basic form of a finite state machine description, including HDL coding style, power-up and reset, state encoding and other issues.

Common Guidelines
Basic Requirements of a Finite State Machine (FSM)
Enumerated type definition declaring state names A state register that holds the current state of the machine A clock specification Specification of the state transitions Specification of the outputs Reset/set specification (necessary for initialization in synthesis)

Processes
A state machine generally has between one and three processes. It is recommended to have three processes, which should include the following: 1. The first process is sequential, and handles the reset condition and latches in the next state on the active edge of the clock, thus storing the current state of the FSM. 2. The second process is combinatorial, and consists of a case statement. This process determines the next state based on the current state and the inputs. 3. The third process is combinational, and is used to set outputs. Alternatively, you can set the outputs in the second process.

Precision Synthesis Style Guide, 2011a Update2 November 2011

291

Finite State Machines Optimization Issues

Types of State Machines


There are two basic types of state machines, Mealy and Moore. In a Moore machine, the outputs do not directly depend on the inputs, only on the present state. In a Mealy machine, the outputs depend directly on the present state and the inputs. In a Moore machine, there is always a register between the inputs and the outputs. This does not have to be the case in Mealy machines.

Power Up and Reset


For simulation, the state machine will initialize into the left most value of the enumeration type, but for synthesis it is unknown in which state the machine powers up. Since Precision Synthesis does state encoding on the enumeration type of the state machine, the state machine could even power up in a state that is not even defined in VHDL. Therefore, to get simulation and synthesis consistency, it is very important to supply a reset to the state machine.

Optimization Issues
Inferred Latches
The assignments to outputs and next_state in the state transition process can create unintended latches if not properly handled. The languages define that any signal that is not assigned anything must retain its value. This means that if you forget to assign something to an output (or the next state) under a certain condition in the case statement, the synthesis tools will have to preserve the value. Since the state transition process is not clocked, latches will have to be generated. You could easily forget to assign an output if the value does not matter. The synthesis tools will warn you about this, since it is a common user error in VHDL: Make sure to always assign something to the next state and the state machine outputs under every condition in the process to avoid this problem. To be absolutely sure, you could also assign a value to the signal at the very beginning of the process (before the start of the case statement). Graphical state-machine entry tools often generate state machine descriptions that do not always assign values to the outputs under all conditions. Precision Synthesis will issue a warning about this, and you could either manually fix it in the VHDL description, or make sure you fully specify the state machine in the graphical entry tool. The synthesis tools cannot fill in the missing specifications, since it is bounded by the semantics of the language on this issue.

Case Statements
In general, case statements are better suited for state machines than if-else if-else structures. A case statement is more efficient than a if-else if-else statement because that would build a priority encoder to test the state (and likely more logic in the implementation).

292

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Optimization Issues

The 'others' or 'default' clause in a case statement is synthesized if all the declared states are not used in the state machines case statement. Synthesis generates logic to cover these unused states. In addition to the 'others' or 'default' clause, if the state machine behavior for all possible state values are explicitly specified, then the default clause is redundant and is ignored.

Exact FSM Implementation by Disabling FSM Optimization


Sometimes it is necessary to synthesize FSMs exactly as they are described in HDL with state representations explicitly defined using constants. This may aid post-synthesis verification as the FSM states are more easily identified and traced back to their HDL descriptions. Exact implementation requires not only specification of FSM states as constant values, but also disabling FSM optimization. Disabling FSM optimization: prevents extraction and re-encoding of the state vector prevents removal of redundant or unreachable states

Automatic FSM extraction and advanced optimization can be disabled either globally or on individual FSMs. To disable FSM optimization globally, use the command:
setup_design -advanced_fsm_optimization=false

or use the GUI checkbox:


Tools > Set Options > Inputs > Advanced FSM Optimization

To disable FSM optimization on an individual FSM, attach the boolean HDL code attribute disable_fsm to the net corresponding to the state vector. Note When Advanced FSM optimization is disabled, options such as encoding style, Safe FSM, and state output re-encoding do not affect the FSM synthesis.

Encoding Styles
You can allow Precision Synthesis to automatically select a Finite State Machine encoding style for you (the default) or you can specify a specific encoding style. The following FSM encoding schemes are available: Binary - Most area efficient. Will use a minimum number of registers to implement the state vector resulting in the smallest overall area. Binary is generally not the optimal encoding for FPGAs because of the abundance of registers these devices offer. Precision will use Binary for small FSMs in FPGAs. One-hot - Provides the fastest clock to out timing. One-hot FSM encoding uses a separate register for each bit of the state vector. The state register is connected directly to the FSM outputs providing the fastest clock to out timing. One-hot FSMs generally

Precision Synthesis Style Guide, 2011a Update2 November 2011

293

Finite State Machines Optimization Issues

result in the fastest performance and are the most common encoding selected by Precision's Auto selection Two-hot - Offers a compromise between the area advantages of binary and the performance advantages of one-hot. Two hot FSM uses 2 register output bits driven to a logical one to define the decoding. For example, if you have an FSM with 8 states, one hot encoding requires 8 registers, a binary encoding requires 3 registers, and a two-hot encoding requires 5 registers. You should use two-hot encoding when trying to reduce the register count of a high-performance design Gray - Creates FSMs using Gray encoding. Gray counters are used to avoid glitches going from one value to the next, however, because a general state machine has more arbitrary transitions, such behavior cannot be guaranteed. In Advanced FSM Optimization, Gray encoding encodes the longest transition sequence in decreasing length. If Advanced FSM Optimization is not used then the Gray encoding will operate sequentially on the enumerated type. Gray encoding may reduce glitches. Random - When all else fails. Random encoding will use a randomly encoded state vector. Random FSM encoding is not recommended but can be used when all other encoding schemes have failed to provide the desired result. Auto (default) - Automatically selects the optimal encoding. The Auto option automatically selects an encoding scheme for an FSM based on the target technology and the state vector size. When using Auto, the encoding is selected based on the number of states in the FSM. There is a lower limit and an upper limit. Small state machines that fall below the lower limit will be implemented as binary, state machines between the lower and upper limits will be implemented as one-hot, and extremely large FSMs will again be implemented as binary.

For many designs, one-hot encoding provides the smallest and fastest implementation of the state machine. Precision running in the default Auto encoding mode will use binary for state machines of 4 or less states, but will use one-hot encoding for larger state machines (States > 16). For very large state machines (States > 512) Precision will revert to using binary as one bit per state becomes excessive.

Specifying the Encoding Style


Precision provides several methods for choosing the state machine encoding style: From the GUI menu selection Tool -> Set Options...Input dialog box The Tcl command setup_design -encoding VHDL code attributes safe_fsm and type_encoding_style Verilog synthesis enum pragma

294

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Optimization Issues

Figure 9-1. Setting FSM encoding Style

You can also specify encoding from a Tcl script or the command line using the following command:
setup_design -encoding=auto | binary | onehot | twohot | random | gray

And, encoding can be specified on an individual FSM basis through HDL attributes as outlined in the next sections.

Attributes Relating to Finite State Machines


The following attributes affect FSM implementation: disable_fsm (HDL only): This attribute disables Precision FSM optimization of a single state machine. The attribute can be set on any state variable, effectively blocking FSM optimizations. enum_encoding (VHDL Only): The VHDL attribute enum_encoding is used to specify the encoding of an enumerated type. The string attribute should contain the literal representation of each state in the order they appear in the type definition. fsm_implementation (HDL Only): Directs Precision to attempt to place FSMs into dedicated synchronous RAM structures. Use this attribute to reduce logic consumption by moving FSM next state logic to available synchronous RAM block(s). fsm_state: The value of this attribute specifies the encoding style to be used for encoding the state machine. Possible values are auto, binary, onehot, twohot, random, and gray.

Precision Synthesis Style Guide, 2011a Update2 November 2011

295

Finite State Machines Optimization Issues

safe_fsm: Specifies that the Finite State Machine should be built as a safe FSM. type_encoding (VHDL Only): Specifies the style of encoding for a Finite State Machine. This needs to be set separately for each state machine if there are multiple state machines of different types. type_encoding_style (VHDL Only): Specifies the style of encoding for a Finite State Machine. This needs to be set separately for each state machine if there are multiple state machines of different types.

FSM Encoding using a Verilog Pragma


When using Verilog to specify FSM encoding, assign to an attribute a set of parameters to define an enumerated type, and then assign another attribute to the state register as follows:
// Define the states. Enum pragma allows Precision to chose encoding. parameter [2:0] /* synthesis enum my_enum_type */ st0 = 0, st1 = 1, st2 = 2, st3 = 3, st4 = 4, st5 = 5, st6 = 6, st7 = 7; reg [2:0] /* synthesis enum binary */ state_reg, nxstate_reg ;

Valid strings for specifying the encoding style are binary, onehot, twohot, random, or gray. Not specifying an encoding allows Precision to encode automatically based on state count.

Advanced FSM Optimization


The Advanced FSM Optimization switch is on by default, you can turn it off if you want to disable the FSM extraction globally for your design. To disable FSM optimization globally using the command:
setup_design -advanced_fsm_optimization=false

or disable the GUI checkbox:


Tools > Set Options > Inputs > Advanced FSM Optimization

To disable FSM optimization on an individual FSM, attach the boolean HDL code attribute disable_fsm to the net corresponding to the state vector. Note When Advanced FSM optimization is disabled, options such as encoding style, Safe FSM, and state output re-encoding do not affect the FSM synthesis.

296

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Safe Finite State Machines

Safe Finite State Machines


If the FSM is erroneously sent to an invalid state (not one of the defined states), creating a Safe FSM allows the FSM to recover to a valid state. Precision Synthesis supports the ability to create a Safe State Machine. A safe state machine is a state machine that a transition will always be to a valid state. Although state machine optimization will create a design which contains only valid transitions under normal circumstances, in safety critical situations where, for example, radiation could potentially change one of the bits, it is important to know that the state machine will recover to a valid state at the next clock. For safe finite state machines, the generated implementation logic has a defined behavior for each possible 2n values of the state variable, irrespective of the ability to reach the state. One-hot encoded safe FSM may use larger area and increased number of registers as compared to a binary encoded safe FSM. Therefore Precision applies binary encoding for safe FSMs by default. However with binary encoding for safe fsms, invalid transition to another valid or default state due to effects like Single Event Upset (SEU), is not detected with any indication. If one-hot encoding is used for Safe FSMs, invalid state caused by SEU gets detected (as in 0001 to 0011 for a regular one-hot encoded FSM). Safe FSM creation is enabled using setup_design -use_safe_fsm command or set the GUI checkbox Tools > Set Options > Inputs > Use Safe FSM (as shown in Figure 9-1 on page 295). The Use Safe FSM switch is applicable to all FSMs in the design. To overwrite the default safe FSM binary encoding style with one-hot encoding, you can use the command:
setup_design -use_safe_fsm=true -encoding=onehot

How Precision Implements a Safe FSM


operation can be selected either from the GUI, as shown in Example 9-1, or alternatively the boolean attribute safe_fsm (also FSM_COMPLETE) can be applied to the enumerated type (see Example 9-1).
Safe FSM

The Precision tool implements SAFE_FSM as described below: Irrespective of the size of state machine encoding is always Binary unless there is a switch or attribute to override. If you specified an encoding style (one-hot, two-hot, gray, binary, random), the states are encoded in the specified style. Unreachable states are never pruned (reference Example 9-2). State PAD is unreachable and would have been pruned under default implementation. But this state will be preserved if safe_fsm option is exercised.
"default"

or "others" clause is specified:

Precision Synthesis Style Guide, 2011a Update2 November 2011

297

Finite State Machines Safe Finite State Machines

If in addition to the default clause, the state machine behavior for all 2n possible state values has also been explicitly specified, then the default clause is redundant and is pruned away. Otherwise, the default branch is preserved even if it is unreachable. Consider Example 9-2 below, under normal circumstances the state machine will always be in one of the reachable states IDLE, WAIT, EVEN, ODD, PAD. In a safe implementation, the default clause will be preserved. If the state machine ever takes the value greater than 3'h4, next_state will take the value IDLE and the FSM will move to the IDLE state in the next clock cycle.
"default"

clause is not specified:

For the missing choices, if any, don't care values are used to ensure a complete and unique mapping from the logical to the physical states. Refer to Example 9-3 on page 301.
Safe FSM

operation can be selected either from the GUI, as shown in Example 9-1, or by using attributes in the code. Alternatively the boolean attribute save_fsm can be applied to the enumerated type. To illustrate the use of safe finite state machines, here is an example: Example 9-1. VHDL Safe Finite State Machine
LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY safe1 IS PORT (clock, in1, in2, reset : IN std_logic; state1, state2, state3, state4, state5, state_other : OUT std_logic); END ; ARCHITECTURE rtl OF safe1 IS TYPE state_t IS ( ST1, ST2, ST3, ST4, ST5 ); SIGNAL state, nxstate : state_t; attribute SAFE_FSM: boolean; attribute SAFE_FSM of state_t:type is true; BEGIN update_state :-- Update the state on the clock edge PROCESS (reset, clock) BEGIN IF (reset=1) THEN state <= ST1 ; ELSIF clockevent and clock=1 THEN state <= nxstate ; END IF ; END PROCESS; output_sig : PROCESS (state) BEGIN state1 <= 0; state2 <= 0;

298

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Safe Finite State Machines state3 <= 0; state4 <= 0; state5 <= 0; state_other <= 0; if( state = ST1 ) then state1 <= 1; elsif ( state = ST2 ) then state2 <= 1; elsif ( state = ST3 ) then state3 <= 1; elsif ( state = ST4 ) then state4 <= 1; elsif ( state = ST5 ) then state5 <= 1; else state_other <= 1; end if; END PROCESS; transitions :-- set the outputs and next state PROCESS (state, in1, in2) BEGIN nxstate <= state; CASE state IS WHEN ST1 => IF in1 = 1 then nxstate <= ST2; ELSIF in2 = 1 then nxstate <= ST3; END IF; WHEN ST2 => IF in1 = 1 then nxstate <= ST3; ELSIF in2 = 1 then nxstate <= ST4; END IF; WHEN ST3 => IF in1 = 1 then nxstate <= ST4; ELSIF in2 = 1 then nxstate <= ST5; END IF; WHEN ST4 => IF in1 = 1 then nxstate <= ST5; ELSIF in2 = 1 then nxstate <= ST1; END IF; WHEN ST5 => IF in1 = 1 then nxstate <= ST1; ELSIF in2 = 1 then nxstate <= ST2; END IF; WHEN others => nxstate <= ST1; END CASE; END PROCESS;

Precision Synthesis Style Guide, 2011a Update2 November 2011

299

Finite State Machines Safe Finite State Machines END rtl;

Example 9-2. Verilog Safe Finite State Machine with Default Clause
assign incr_st = state + 1; //Combinational block for Transition and Output Functions always @(state) begin next_out_err = out_err; next_state = state; case (state) IDLE: if (horz_init) begin if(out_en) next_out_err = 1b1; next_state = incr_st; end WAIT: if (in_data_valid) next_state = incr_st; EVEN: if (horz_init) begin if(out_en) next_out_err = 1b1; next_state = WAIT; end else if (hs_valid) begin if (eol) next_state = PAD; else next_state = incr_st; end ODD: if (horz_init) begin if(out_en) next_out_err = 1b1; next_state = WAIT; end else if (hs_valid) begin if (eol) next_state = IDLE; else next_state = EVEN; end PAD: if (horz_init) if(out_en) next_out_err = 1b1; else next_state = IDLE; default: next_state = IDLE; endcase end // Synchronous block for register inference always @(posedge clk) if (reset) begin state <= IDLE; out_err <= 1b0; end else begin

300

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Safe Finite State Machines state <= next_state; out_err <= next_out_err; end

Example 9-3. Verilog Safe Finite State Machine with an unreachable state and without Default Clause
// State values using define macros define IDLE 3h0 define WAIT 3h1 define EVEN 3h2 define ODD 3h3 define PAD 3h4 always @(posedge clk) if (reset) begin state <= IDLE; out_err <= 1b0; end else begin case (state) //mentor full_case IDLE: if (horz_init) state <= WAIT; WAIT: if (in_data_valid) state <= ODD; EVEN: if (horz_init) begin if(out_en) out_err <= 1b1; state <= WAIT; end else if (hs_valid) begin if (eol) state <= IDLE; else state <= WAIT; end ODD: if (horz_init) begin if(out_en) out_err <= 1b1; state <= WAIT; end else if (hs_valid) begin if (eol) state <= IDLE; else state <= EVEN; end PAD: if (horz_init) if(out_en) out_err <= 1b1; else state <= IDLE; endcase end

In this Example 9-3 under safe_fsm option: Binary encoding will be applied. Unreachable state PAD will be preserved. Don't care values will be used to take care of the missing choices (Possible values of state variable "state" which have not been covered in the RTL i.e. 3'h5, 3'h6 and 3'h7) and the following logic will be generated:

Precision Synthesis Style Guide, 2011a Update2 November 2011

301

Finite State Machines Safe Finite State Machines always @(posedge clk) if (reset) begin state <= IDLE; out_err <= 1'b0; end else begin casex (state) 3'b000: if (horz_init) state <= WAIT; 3'b001: if (in_data_valid) state <= ODD; 3'bx10: if (horz_init) begin if(out_en) out_err <= 1'b1; state <= WAIT; end else if (hs_valid) begin if (eol) state <= IDLE; else state <= WAIT; end 3'bx11: if (horz_init) begin if(out_en) out_err <= 1'b1; state <= WAIT; end else if (hs_valid) begin if (eol) state <= IDLE; else state <= EVEN; end 3'b10x: if (horz_init) if(out_en) out_err <= 1'b1; else state <= IDLE; endcase end

302

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Leonardo/Precision Differences

Leonardo/Precision Differences
In Precision, you can also specify the encoding style using the following command:
setup_design -encoding = auto | binary | onehot | twohot | random | gray

In Leonardo, you can use the encoding variable.

Coding Examples
The following table shows the VHDL and Verilog examples described in this section. The code files are available in the Precision Synthesis software tree in the following directory:
<install_dir>/shared/examples/style_guide_hdl/Finite_State_Machines

Table 9-1. FSM Examples Example Single Process State Machine Two Process State Machine Three Process State Machine Description State machine with only one process. In this process, the state and output are both updated according to the current state only. State machine with two processes. The first process is used to update the state, based on the input. The second process updates the output, based on the current state. The first process updates the current state according to the next state. The second process sets the next state based on the input. The third process updates the output based on the current state.

Moore State Machine Moore style state machine. The defining factor of a Moore state machine is that the output is dependent only on the current state, and not dependent on the input. Moore state machines can have one to three processes. Mealy State Machine Mealy state machine. The defining factor of a Mealy state machine is that the output is dependent on the input. Mealy state machines can have either two or three processes. VHDL Safe Finite State Machine Verilog Safe Finite State Machine with Default Clause Verilog Safe Finite State Machine with an unreachable state and without Default Clause

Example 9-1 Example 9-2 Example 9-3

Precision Synthesis Style Guide, 2011a Update2 November 2011

303

Finite State Machines Single Process State Machine

Single Process State Machine


State machine with only one process. In this process, the state and output are both updated according to the current state only. VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY fsm_single IS PORT (a, clk, reset: IN STD_LOGIC; y: OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF fsm_single IS TYPE state_type IS (s0, s1, s2, s3); SIGNAL state: state_type; BEGIN PROCESS (clk, reset) BEGIN IF (reset = 1) THEN state <= s0; y <= a; ELSIF (clkEVENT AND clk = 1) THEN CASE state IS WHEN s0 => state <= s1; y <= 1; WHEN s1 => state <= s2; y <= 1; WHEN s2 => state <= s3; y <= 0; WHEN s3 => state <= s0; y <= 0; END CASE; END IF; END PROCESS; END ARCHITECTURE;

Verilog
module fsm_single (a, clk, reset, y); input a, clk, reset; output y; reg y; reg [1:0] state; always @ (posedge clk or posedge reset) if (reset) begin state = 2b00; y = a; end else case (state) 2b00: begin state = 2b01; y = 1b1; end 2b01: begin state = 2b10; y = 1b1; end 2b10: begin state = 2b11; y = 1b0; end 2b11: begin state = 2b00; y = 1b0; end endcase endmodule

304

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Two Process State Machine

Two Process State Machine


State machine with two processes. The first process is used to update the state, based on the input. The second process updates the output, based on the current state. VHDL
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY fsm_two IS PORT (a, clk, reset: IN STD_LOGIC; y: OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF fsm_two IS TYPE state_type IS (s0, s1, s2, s3); SIGNAL state: state_type; BEGIN PROCESS (clk, reset) BEGIN IF (reset = 1) THEN state <= s0; ELSIF (clkEVENT AND clk = 1) THEN CASE state IS WHEN s0 => IF (a = 1) THEN state <= s1; ELSE state <= s0; END IF; WHEN s1 => IF (a = 1) THEN state <= s2; ELSE state <= s0; END IF; WHEN s2 => IF (a = 1) THEN state <= s3; ELSE state <= s0; END IF; WHEN s3 => state <= s0; END CASE; END IF; END PROCESS; PROCESS (state) BEGIN CASE state IS WHEN s0 => y <= 1; WHEN s1 => y <= 1; WHEN s2 => y <= 0; WHEN s3 => y <= 0; END CASE; END PROCESS; END ARCHITECTURE;

Verilog
module fsm_two (a, clk, reset, y); input a, clk, reset; output y; reg y; reg [1:0] state; always @ (posedge clk or posedge reset) begin if (reset) begin state = 2b00; end else begin case (state) 2b00: begin if (a) state = 2b01; else state = 2b00; end 2b01: begin if (a) state = 2b10; else state = 2b00; end 2b10: begin if (a) state = 2b11; else state = 2b00; end 2b11: state = 2b00; default: state = state; endcase end end always @ (state) begin case (state) 2b00: y = 1b1; 2b01: y = 1b1; 2b10: y = 1b0; 2b11: y = 1b0; default:y = y; endcase end endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

305

Finite State Machines Three Process State Machine

Three Process State Machine


The first process updates the current state according to the next state. The second process sets the next state based on the input. The third process updates the output based on the current state. Example 9-4. VHDL Three Process FSM
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; ENTITY fsm_three IS PORT ( a, clk, reset: IN STD_LOGIC; y: OUT STD_LOGIC); END ENTITY; ARCHITECTURE rtl OF fsm_three IS TYPE state_type IS (s0, s1, s2, s3); SIGNAL state, nextstate : state_type; BEGIN PROCESS (clk, reset) BEGIN IF (reset = 1) THEN state <= s0; ELSIF (clkEVENT AND clk = 1) THEN state <= nextstate; END IF; END PROCESS; PROCESS (state, a) BEGIN CASE state IS WHEN s0 => IF (a = 1) nextstate ELSE nextstate END IF; WHEN s1 => IF (a = 1) nextstate ELSE nextstate END IF; WHEN s2 => IF (a = 1) nextstate ELSE nextstate END IF; WHEN s3 => nextstate <= END CASE; END PROCESS;

THEN <= s1; <= s0;

THEN <= s2; <= s0;

THEN <= s3; <= s0;

s0;

306

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Three Process State Machine PROCESS (state) BEGIN CASE state IS WHEN s0 => y <= 1; WHEN s1 => y <= 1; WHEN s2 => y <= 0; WHEN s3 => y <= 0; END CASE; END PROCESS; END ARCHITECTURE;

Example 9-5. Verilog Three Process FSM


module fsm_three (a, clk, reset, y); input a, clk, reset; output y; reg y; reg [1:0] state, next_state; always @ (posedge clk or posedge reset) begin if (reset) state = 2b00; else state = next_state; end always @ (state or a) begin case (state) 2b00: begin if (a) next_state = else next_state = end 2b01: begin if (a) next_state = else next_state = end 2b10: begin if (a) next_state = else

2b01; 2b00;

2b10; 2b00;

2b11;

Precision Synthesis Style Guide, 2011a Update2 November 2011

307

Finite State Machines Three Process State Machine next_state = 2b00; end 2b11: next_state = 2b00; default: next_state = state; endcase end always @ (state) begin case (state) 2b00: y = 1b1; 2b01: y = 1b1; 2b10: y = 1b0; 2b11: y = 1b0; default:y = y; endcase end endmodule

308

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Moore State Machine

Moore State Machine


Moore style state machine. The defining factor of a Moore state machine is that the output is dependent only on the current state, and not dependent on the input. Moore state machines can have one to three processes. Example 9-6. VHDL Moore State Machine
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; ENTITY moore IS PORT(clk,cs,refresh : IN STD_LOGIC; ras, cas, ready : OUT STD_LOGIC); END moore; ARCHITECTURE rtl OF moore IS TYPE state_type IS (s0, s1, s2, s3, s4); SIGNAL present_state : state_type; BEGIN PROCESS (clk) BEGIN IF clkEVENT AND clk = 1 THEN CASE present_state IS WHEN s0 => IF (refresh = 1) THEN present_state <= s3; ELSIF (cs <= 1) THEN present_state <= s1; ELSE present_state <= s0; END IF; WHEN s1 => present_state <= s2; WHEN s2 => IF (cs = 0) THEN present_state <= s0; ELSE present_state <= s2; END IF; WHEN s3 => present_state <= s4; WHEN s4 => present_state <= s0; END CASE ; END IF; END PROCESS; PROCESS (present_state) BEGIN CASE present_state IS WHEN s0 => ras <= 1; cas <= 1; ready <= 1; WHEN s1 => ras <= 0;

Precision Synthesis Style Guide, 2011a Update2 November 2011

309

Finite State Machines Moore State Machine cas <= 1; ready <= 0; WHEN s2 => ras <= 0; cas <= 0; ready <= 0; WHEN s3 => ras <= 1; cas <= 0; ready <= 0; WHEN s4 => ras <= 0; cas <= 0; ready <= 0; END CASE; END PROCESS; END ARCHITECTURE;

Example 9-7. Verilog Moore State Machine


module moore (clk, cs, refresh, ras, cas, ready); input clk, cs, refresh; output ras, cas, ready; parameter [2:0] /* synthesis enum estates */ s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4; reg [2:0] /* synthesis enum estates */ present_state; reg ras, cas, ready; always @ (posedge clk) begin case (present_state) s0 : begin if (refresh) present_state = s3; else if (cs) present_state = s1; else present_state = s0; end s1 : begin present_state = s2; end s2 : begin if (~cs) present_state = s0; else present_state = s2; end s3 : begin present_state = s4; end s4 : begin present_state = s0; end default : begin present_state = s0; end

310

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Moore State Machine endcase end always @ (present_state) begin case (present_state) s0 : begin ras = 1b1; cas = 1b1; ready = 1b1; s1 : begin ras = 1b0; cas = 1b1; ready = 1b0; s2 : begin ras = 1b0; cas = 1b0; ready = 1b0; s3 : begin ras = 1b1; cas = 1b0; ready = 1b0; s4 : begin ras = 1b0; cas = 1b0; ready = 1b0; default : begin ras = 1bX; cas = 1bX; ready = 1bX; endcase end endmodule

end

end

end

end

end

end

Precision Synthesis Style Guide, 2011a Update2 November 2011

311

Finite State Machines Mealy State Machine

Mealy State Machine


Mealy state machine. The defining factor of a Mealy state machine is that the output is dependent on the input. Mealy state machines can have either two or three processes. Example 9-8. VHDL Mealy State Machine
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; ENTITY mealy IS PORT(clk,cs,refresh,reset : IN STD_LOGIC; ras,cas,ready : OUT STD_LOGIC); END mealy; ARCHITECTURE rtl OF mealy IS TYPE state_type IS (s0, s1, s2, s3, s4); SIGNAL present_state,next_state : state_type; BEGIN PROCESS (clk, reset) BEGIN IF (reset=1) THEN present_state <= s0; ELSIF (clkEVENT AND clk = 1) THEN present_state <= next_state; END IF; END PROCESS; PROCESS (present_state,refresh,cs) BEGIN CASE present_state IS WHEN s0 => ras <= 1; cas <= 1; ready <= 1; IF (refresh = 1) THEN next_state <= s3; ELSIF (cs = 1) THEN next_state <= s1; ELSE next_state <= s0; END IF; WHEN s1 => ras <= 0; cas <= 1; ready <= 0; next_state <= s2; WHEN s2 => ras <= 0; cas <= 0; ready <= 0; IF (cs = 0) THEN next_state <= s0; ELSE

312

Precision Synthesis Style Guide, 2011a Update2 November 2011

Finite State Machines Mealy State Machine next_state <= s2; END IF; WHEN s3 => ras <= 1; cas <= 0; ready <= 0; next_state <= s4; WHEN s4 => ras <= 0; cas <= 0; ready <= 0; next_state <= s0; END CASE ; END PROCESS ; END ARCHITECTURE ;

Example 9-9. Verilog Mealy State Machine


module mealy (clk, cs, refresh, reset, ras, cas, ready); input clk, cs, refresh, reset; output ras, cas, ready; parameter [2:0] /* synthesis enum estates */ s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4; reg [2:0] /* synthesis enum binary */ present_state, next_state; reg ras, cas, ready; always @ (posedge clk or posedge reset) if (reset) present_state = s0; else present_state = next_state; always @ (present_state or refresh or cs) begin next_state = s0; ras = 1bX; cas = 1bX; ready = 1bX; case (present_state) s0 : begin ras = 1b1; cas = 1b1; ready = 1b1; if (refresh) next_state = s3; else if (cs) next_state = s1; else next_state = s0; end s1 : begin ras = 1b0; cas = 1b1; ready = 1b0; next_state = s2; end s2 : begin

Precision Synthesis Style Guide, 2011a Update2 November 2011

313

Finite State Machines Mealy State Machine ras = 1b0; cas = 1b0; ready = 1b0; if (~cs) next_state = s0; else next_state= s2; end s3 : begin ras = 1b1; cas = 1b0; ready = 1b0; next_state = s4; end s4 : begin ras = 1b0; cas = 1b0; ready = 1b0; next_state = s0; end endcase end endmodule

314

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 10 DSP Blocks


Precision RTL Synthesis detects a DSP operator from the style of the RTL code at a technologyindependent level, then maps the element to a generic DSP operator in the RTL database at compile time. During the technology-mapping phase of synthesis, Precision maps the generic DSP operator to the technology specific DSP block. Depending upon the pipeline register and accumulator resources available within the target devices DSP block, Precision will automatically absorb them into the DSP block where possible.

Common Guidelines
Basic Requirements for DSP Inference
Use the default compiler. If you have 2004c Compile Mode enabled, disable it in Tool -> Set Options... -> Input dialog box -or- use the command:
setup_design -2004c_compile_mode=false

(default compiler enabled) Use the dedicated_mult attribute set ON to enable mapping into DSP blocks, otherwise multipliers will be mapped into logic and carry chain resources (default is dedicated_mult=ON) Reset handling should match the technology requirement for synchronous or asynchronous signal behavior

General Inference Support


There are a great many possible operations that fall into the DSP arena, the most common are supported across all DSP resource rich technologies: MULT MULT-ACC MULT-ADD MULT-ADDSUB MULT-ACC-ADDSUB

Precision Synthesis Style Guide, 2011a Update2 November 2011

315

DSP Blocks Common Guidelines

Inference and Instantiation


Precision Synthesis supports Verilog 2001 and VHDL DSP cell instantiation just like any other specific technology cells. Both DSP cell instantiation and specific vendor DSP netlist generation should be avoided due to their complex nature and technology dependence. Precision Synthesis supports advanced DSP inferencing across different vendors and technologies, and is the recommended approach. DSP inferencing relies on use of the default compiler and the dedicated_mult attribute. If you have 2004c Compile Mode enabled, disable it from the menu selection Tool -> Set Options... -> Input dialog box, or use the command:
setup_design -2004c_compile_mode=false.

Add the attribute named dedicated_mult to multipliers in your design to control inference mapping. Set the value of dedicated_mult to ON for mapping into DSP blocks (default), use the value OFF to map to carry-chain logic and LUTs.
set_attribute -name dedicated_mult -value ON (default) set_attribute -name dedicated_mult -value OFF

Multiplier -> ON

If you prefer to use the GUI, right-click on a multiplier operator and choose Use Dedicated from the popup menu. Figure 10-1. Adding dedicated_mult via the GUI

316

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks Common Guidelines

Reset Design Requirements


For optimal results, carefully compare the reset signal behavior in your design to the style used in the target device DSP block, otherwise Precision will not be able to absorb registers into the DSP blocks. While the general design guideline is to use only synchronous reset in programmable logic design, a few devices use asynchronous reset signal behavior within their DSP blocks, for example, Altera Stratix/Stratix II and LatticeECP. An alternative is to avoid specifying a reset signal within your VHDL process or Verilog block:
/*------------------------------------------------------------------------ Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : mult_acc --- Purpose : This design example shows how to infer a multiply-accumulate -- DSP operator using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 -----------------------------------------------------------------------*/ module mult_acc (a, b, clk, data_out); parameter sub_in_width = 9; parameter sub_out_width = 18; input input input signed[sub_in_width-1:0] signed[sub_in_width-1:0] clk; a; b;

output signed[sub_out_width-1:0] data_out; reg signed[sub_out_width-1:0] multout_reg, accum_out; reg signed[sub_in_width-1:0] a_reg, b_reg; always @(posedge clk) begin // set number of pipeline registers on the A, B inputs to 1 a_reg <= a; b_reg <= b; // set number of pipeline registers on the mult output to 1 multout_reg <= a_reg * b_reg; // set number of pipeline registers on the accumulated output to 1 accum_out <= accum_out + multout_reg; end assign data_out = accum_out; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

317

DSP Blocks Common Guidelines

Vendor Specific DSP Optimizations


Xilinx Virtex-4/5 DSP48 Optimization and Retiming
The following is brief list of DSP specific inference and optimization information found in the Designing with Xilinx Devices chapter of the Precision Synthesis Reference Manual. Inferring Virtex-4/5 DSP48 cells Supported MULT-ADD and MULT-ACC modes implemented in single DSP48 cells Virtex-5 extended capabilities DSP Retiming for select Xilinx technologies
o o o o o o

Register repositioning across a single DSP Register repositioning inside a single DSP Register repositioning across a cascaded DSP chain Outside register repositioning into the DSP block Supported technologies for DSP retiming DSP retiming in different precision flows

318

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks Attributes Relating to DSP Blocks

Attributes Relating to DSP Blocks


The following attributes affect DSP implementation: dedicated_mult: Use the dedicated_mult attribute to control whether or not the Modgen operator mult utilizes DSP block or multiplier resources in the target technology. If dedicated_mult=ON, then both DSP blocks (or multipliers) and carry chains can be inferred (based on size). If set to OFF, then only carry chains will be inferred and multiplier operations will be mapped into logic. For a complete description of the dedicated_mult attribute, see dedicated_mult in the Attributes section of the Precision RTL Synthesis Reference Manual. frontend_dissolve (HDL only): Adding the attribute or pragma frontend_dissolve directly into HDL source files may significantly improve QoR on some hierarchical DSP designs. The heuristic of this attribute will be automated into a future release. Do not use this attribute on blackboxes or technology cells that you intend to preserve, or on any other type of designs beside DSP. use_resource: The most aggressive DSP mapping can be enabled using the use_resource attribute in your Precision constraints file. Add use_resource with the value DSP to the adders and incrementers in your design with these constraint file lines:

set_attribute -design rtl -name use_resource -value DSP -instance [get_cells -hier *add*] set_attribute -design rtl -name use_resource -value DSP -instance [get_cells -hier *inc*]

Precision Synthesis Style Guide, 2011a Update2 November 2011

319

DSP Blocks DSP Code Examples

DSP Code Examples


The following table shows the VHDL and Verilog examples described in this section. The code files are available in the Precision Synthesis software tree in the following directory:
<install_dir>/shared/examples/style_guide_hdl/dsp/inferred_dsp <install_dir>/shared/examples/style_guide_hdl/dsp/instantiated_dsp

Table 10-1. DSP Code Examples Example MULT-ADD Description Example of coding style for MULT-ADD, in which Precision Synthesis will infer MULT_ADD operator and map the MULTIPLIER with pipeline registers, and adder logic into a single DSP block. Sample coding style for MULT-ADDSUB, in which Precision Synthesis will infer MULT_ADDSUB operator and map MULTIPLIER with pipeline registers, and ADDSUB logic into a single DSP block. This is a simple example of MULT_ACC operator, both MULT and ADD_SUB operator will be inferred and pulled into a single DSP block This is an example of MULT-ACC-ADDSUB operator, both MULT and ADD_SUB operator will be inferred and pulled into a single DSP block

MULT-ADDSUB

MULT-ACC

MULT-ACCADDSUB

Fully Pipelined 35x18 This fully pipelined 35 x 18 bit multiplier can be modeled by Multiplier Precision Synthesis without having to use vendors CoreGen, Mega Wizards, or manual instantiations. The same source code can then be conveniently used to target different devices. Instantiating DSP Functions Both DSP cell instantiation and specific vendor DSP netlist generation should be avoided due to their complex nature and technology dependence. Precision Synthesis supports Verilog 2001 and VHDL DSP cell instantiation just like any other technology specific cells. We recommend using Precision Synthesis to infer all of the DSP functions when possible.

320

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks MULT-ADD

MULT-ADD
Example of coding style for MULT-ADD, in which Precision Synthesis will infer MULT_ADD operator and map the MULTIPLIER with pipeline registers, and adder logic into a single DSP block. Figure 10-2. DSP MULT-ADD

Example 10-1. Verilog DSP MULT-ADD


module mult_add (clk, load, dataa, datab, datac, preg); parameter sub_in_width = 18; parameter sub_out_width = 48; input input input input signed[sub_in_width-1:0] signed[sub_in_width-1:0] signed[sub_out_width-1:0] clk, load; dataa; datab; datac;

output signed[sub_out_width-1:0] preg; reg signed[sub_out_width-1:0] reg signed[sub_in_width-1:0] reg signed[sub_in_width-1:0] reg signed[sub_in_width-1:0] reg signed[sub_out_width-1:0] reg signed[sub_out_width-1:0] wire signed[sub_out_width-1:0] mult0_result; reg_dataa; reg_datab; reg_datab1; reg_datac; preg; result;

always @(posedge clk) begin reg_datac <= datac; reg_dataa <= dataa; reg_datab <= datab; reg_datab1 <= reg_datab; mult0_result <= reg_dataa * reg_datab1; preg <= result; end assign result = load ? reg_datac : reg_datac + mult0_result; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

321

DSP Blocks MULT-ADD

Example 10-2. VHDL DSP MULT-ADD


--------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : mult_add -- Purpose : This design example shows how to infer a mult_add -- DSP operator using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 -------------------------------------------------------------------------library ieee ; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; entity mult_add is generic (sub_in_width : integer := 18; sub_out_width : integer := 48); port ( dataa: in signed (sub_in_width-1 downto 0) ; datab: in signed (sub_in_width-1 downto 0) ; datac: in signed (sub_out_width-1 downto 0) ; preg: out signed (sub_out_width-1 downto 0) ; load, clk: in std_logic ) ; end mult_add; architecture rtl of mult_add is signal reg_dataa, reg_datab, reg_datab1 : signed (sub_in_width-1 downto 0); signal datac1, reg_preg, result: signed (sub_out_width-1 downto 0); signal mult0_result : signed (sub_in_width*2-1 downto 0); begin process (clk) begin if (clkevent and clk =1) then reg_dataa <= signed (dataa); reg_datab <= signed (datab); reg_datab1 <= reg_datab; datac1 <= signed (datac); mult0_result <= reg_dataa * reg_datab1; reg_preg <= signed (result); end if; end process; preg <= reg_preg; result <= (mult0_result + datac1) when (load = 1) else (datac1); end rtl ;

322

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks MULT-ADDSUB

MULT-ADDSUB
Sample coding style for MULT-ADDSUB, in which Precision Synthesis will infer MULT_ADDSUB operator and map MULTIPLIER with pipeline registers, and ADDSUB logic into a single DSP block. Figure 10-3. DSP MULT-ADDSUB

Example 10-3. Verilog DSP MULT-ADDSUB


/*-------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : mult_add_sub --- Purpose : This design example shows how to infer a multiply-add_sub -- DSP operator using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 ------------------------------------------------------------------------*/ module mult_add_sub (clk, load, dataa, datab, datac, preg); parameter sub_in_width = 9; parameter sub_out_width = 18; input input input input output reg reg reg reg reg wire signed[sub_in_width-1:0] dataa; signed[sub_in_width-1:0] datab; signed[sub_out_width-1:0] datac; clk, load; signed[sub_out_width-1:0] signed[sub_out_width-1:0] signed[sub_in_width-1:0] signed[sub_in_width-1:0] signed[sub_out_width-1:0] signed[sub_out_width-1:0] signed[sub_out_width-1:0] preg; mult0_result; reg_dataa; reg_datab; reg_datac; preg; result;

always @(posedge clk) begin // Set number of pipeline registers on the A, B, and C inputs to 1 reg_datac <= datac; reg_dataa <= dataa; reg_datab <= datab; // Set number of pipeline registers on the mult output to 1 mult0_result <= reg_dataa * reg_datab; // Set number of pipeline registers on the product output to 1 preg <= result; end // Multiply-add_sub assign result = load ? reg_datac - mult0_result : reg_datac + mult0_result; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

323

DSP Blocks MULT-ADDSUB

Example 10-4. VHDL DSP MULT-ADDSUB


--------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : mult_add_sub --- Purpose : This design example shows how to infer a multiply-add_sub -- DSP operator using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 -------------------------------------------------------------------------library ieee ; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; entity mult_add_sub is generic (sub_in_width : integer := 9; sub_out_width : integer := 18); port( dataa : in datab : in datac : in preg : out load, clk: in ) ; end mult_add_sub;

signed (sub_in_width-1 signed (sub_in_width-1 signed (sub_out_width-1 signed (sub_out_width-1 std_logic

downto downto downto downto

0) 0) 0) 0)

; ; ; ;

architecture RTL of mult_add_sub is signal reg_dataa, reg_datab : signed (sub_in_width-1 downto 0); signal mult0_result, reg_datac : signed (sub_out_width-1 downto 0); signal reg_preg, result : signed (sub_out_width-1 downto 0); begin process (clk) begin if (clkevent and clk =1) then reg_dataa <= signed (dataa); reg_datab <= signed (datab); reg_datac <= signed (datac); mult0_result <= reg_dataa * reg_datab; reg_preg <= signed (result); end if; end process; preg <= reg_preg; result <= (reg_datac - mult0_result) when (load = 1) else (reg_datac + mult0_result); end RTL ;

324

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks MULT-ACC

MULT-ACC
This is a simple example of MULT_ACC operator, both MULT and ADD_SUB operator will be inferred and pulled into a single DSP block In order to maximize inputs and outputs data width to 18 and 48 bits respectively, SIGNED extended must be declared on both input and output port declarations Figure 10-4. DSP MULT-ACC

Example 10-5. Verilog DSP MULT-ACC


/*------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : mult_acc --- Purpose : This design example shows how to infer a multiply-accumulate -- DSP operator using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 -----------------------------------------------------------------------*/ module mult_acc (a, b, clk, data_out); parameter sub_in_width = 9; parameter sub_out_width = 18; input input input signed[sub_in_width-1:0] signed[sub_in_width-1:0] clk; a; b;

output signed[sub_out_width-1:0] data_out; reg signed[sub_out_width-1:0] multout_reg, accum_out; reg signed[sub_in_width-1:0] a_reg, b_reg; always @(posedge clk) begin // set number of pipeline registers on the A, B inputs to 1 a_reg <= a; b_reg <= b; // set number of pipeline registers on the mult output to 1 multout_reg <= a_reg * b_reg; // set number of pipeline registers on the accumulated output to 1 accum_out <= accum_out + multout_reg; end assign data_out = accum_out; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

325

DSP Blocks MULT-ACC

Example 10-6. VHDL DSP MULT-ACC


--------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : mult_acc --- Purpose : This design example shows how to infer a multiply-add_sub -- DSP operator using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 -------------------------------------------------------------------------LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_arith.ALL; USE ieee.std_logic_signed.ALL; USE ieee.std_logic_unsigned.ALL; ENTITY mult_acc IS generic (sub_in_width sub_out_width PORT (a : b : clk : data_out: END mult_acc; IN IN IN OUT

: integer := 9; : integer := 18);

STD_LOGIC_VECTOR (sub_in_width-1 DOWNTO 0); STD_LOGIC_VECTOR (sub_in_width-1 DOWNTO 0); STD_LOGIC; STD_LOGIC_VECTOR (sub_out_width-1 DOWNTO 0));

ARCHITECTURE RTL OF mult_acc IS SIGNAL a_reg, b_reg : signed (sub_in_width-1 DOWNTO 0); SIGNAL multout_reg : signed (sub_out_width-1 DOWNTO 0); SIGNAL accum_out : signed (sub_out_width-1 DOWNTO 0); BEGIN PROCESS (clk) BEGIN IF (clkevent and clk = 1) THEN a_reg <= signed(a); b_reg <= signed(b); multout_reg <= a_reg * b_reg; accum_out <= accum_out + multout_reg ; END IF; END process; data_out <= std_logic_vector(accum_out); END RTL;

326

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks MULT-ACC-ADDSUB

MULT-ACC-ADDSUB
This is an example of MULT-ACC-ADDSUB operator, both MULT and ADD_SUB operator will be inferred and pulled into a single DSP block In order to maximize inputs and outputs data width to 18 and 48 bits respectively, SIGNED extended must be declared on both input and output port declarations Figure 10-5. DSP MULT-ACC-ADDSUB

Example 10-7. Verilog DSP MULT-ACC-ADDSUB


module mult_acc_addsub_example5 (dataout, dataax, dataay, clk, addsub); parameter sub_in_width = 18; parameter sub_out_width = 48; parameter sub_in1_width = 18; define sub_in_width 18 define sub_out_width 48 output input input reg reg reg reg reg signed[sub_out_width-1:0] dataout; signed[sub_in_width-1:0] dataax, dataay; clk, addsub; signed[sub_out_width-1:0] reg_dataout;

signed[sub_in_width-1:0] reg_dataax, reg_dataay; signed[sub_out_width-1:0] reg_multout; reg_addsub, reg_addsub_1; signed[sub_out_width-1:0] wire_adder_out;

always @(reg_multout or reg_dataout or reg_addsub_1) begin if ( reg_addsub_1 ) wire_adder_out <= reg_dataout + reg_multout; else wire_adder_out <= reg_dataout - reg_multout; end always @(posedge clk) begin reg_dataout <= wire_adder_out; reg_dataax <= dataax; reg_dataay <= dataay; reg_multout <= reg_dataax * reg_dataay; reg_addsub <= addsub; reg_addsub_1 <= reg_addsub; end assign dataout = reg_dataout; endmodule

Precision Synthesis Style Guide, 2011a Update2 November 2011

327

DSP Blocks MULT-ACC-ADDSUB

Example 10-8. VHDL DSP MULT-ACC-ADDSUB


library ieee ; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; entity mult_acc_addsub_example5 is generic (sub_in_width : integer := 18; sub_out_width : integer := 48); port (dataax : in signed (sub_in_width-1 downto 0) ; dataay : in signed (sub_in_width-1 downto 0) ; dataout : out signed (sub_out_width-1 downto 0) ; addsub, clk : in std_logic) ; end mult_acc_addsub_example5; architecture rtl of mult_acc_addsub_example5 is signal reg_dataax, reg_dataay : signed (sub_in_width-1 downto 0); signal reg_dataout, wire_adder_out: signed (sub_out_width-1 downto 0); signal reg_multout : signed ((sub_in_width*2)-1 downto 0); signal reg_addsub, reg_addsub_1 : std_logic; begin process (clk) begin if (clkevent and clk =1) then reg_dataout <= wire_adder_out; reg_dataax <= dataax; reg_dataay <= dataay; reg_multout <= reg_dataax * reg_dataay; reg_addsub <= addsub; reg_addsub_1 <= reg_addsub; end if; end process; process (reg_multout, reg_dataout , reg_addsub_1) begin if (reg_addsub_1 = 1) then wire_adder_out <= reg_dataout + reg_multout; else wire_adder_out <= reg_dataout - reg_multout; end if; end process; dataout <= reg_dataout; end rtl;

328

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks Fully Pipelined 35x18 Multiplier

Fully Pipelined 35x18 Multiplier


This fully pipelined 35 x 18 bit multiplier can be modeled by Precision Synthesis without having to use vendors CoreGen, Mega Wizards, or manual instantiations. The same source code can then be conveniently used to target different devices. Simple MULT-ACC operators can be inferred and cascaded by Precision Synthesis to design a wide, fully pipelined 35 x 18 multiplier. An extra input register is required to synchronize the partial inputs and outputs. Pipelining does increase clock latency, but this is usually not a problem in DSP algorithms. Precision Synthesis automatically optimizes wider multipliers by performing multiplication on partial products and intelligently cascading them. Figure 10-6. 35x18 Multiplier Implemented in 18-bit Blocks

Figure 10-7. Partial Products used to Build 35x18 Mult

Precision Synthesis Style Guide, 2011a Update2 November 2011

329

DSP Blocks Fully Pipelined 35x18 Multiplier

Example 10-9. Verilog Fully Pipelined 35x18 Multiplier


/*------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : pipeline_mult_example7 --- Purpose : This design example shows how to infer a pipelined multiplier -- DSP operator using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 ------------------------------------------------------------------------*/ module pipeline_mult_example7(a, b, preg, clk); parameter sub_in_width_a = 35; parameter sub_in_width_b = 18; parameter sub_out_width = 53; input input input output //a,b, reg reg reg clk; signed[sub_in_width_a-1:0] a; signed[sub_in_width_b-1:0] b; signed[sub_out_width-1:0] preg; and p pipelined registers signed[sub_in_width_a-1:0] signed[sub_in_width_b-1:0] signed[sub_out_width-1:0]

reg_a; reg_b; reg_preg;

always @ (posedge clk) begin reg_a <= a; reg_b <= b; reg_preg <= reg_a * reg_b; end assign preg = reg_preg; endmodule

330

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks Fully Pipelined 35x18 Multiplier

Example 10-10. VHDL Fully Pipelined 35x18 Multiplier


--------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : pipeline_mult_example7 --- Purpose : This design example shows how to infer a pipelined multiplier -- DSP operator using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 -------------------------------------------------------------------------library ieee ; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; entity pipeline_mult_example7 is generic (sub_in_width_a : integer := 35; sub_in_width_b : integer := 18; sub_out_width : integer := 53); port (a : in signed (sub_in_width_a-1 downto 0); b : in signed (sub_in_width_b-1 downto 0); preg : out signed (sub_out_width-1 downto 0); clk : in std_logic ); end pipeline_mult_example7; architecture rtl of -- a, b, and p are signal reg_a signal reg_b signal reg_preg pipeline_mult_example7 is pipelined registers : signed (sub_in_width_a-1 downto 0); : signed (sub_in_width_b-1 downto 0); : signed (sub_out_width-1 downto 0);

begin process (clk) begin if (clkevent and clk =1) then reg_a <= a; reg_b <= b; reg_preg <= reg_a * reg_b; end if; end process; preg <= reg_preg; end rtl;

Precision Synthesis Style Guide, 2011a Update2 November 2011

331

DSP Blocks Instantiating DSP Functions

Instantiating DSP Functions


Both DSP cell instantiation and specific vendor DSP netlist generation should be avoided due to their complex nature and technology dependence. Precision Synthesis supports Verilog 2001 and VHDL DSP cell instantiation just like any other technology specific cells. We recommend using Precision Synthesis to infer all of the DSP functions when possible. If neither the current inference support offered by Precision Synthesis nor Core Generator are able to meet your specific needs, we recommend contacting your local Mentor Graphics FAE for details on how to properly instantiate these complex cells. For the DSP48 in specific, its extremely important that you enable all the control signals correctly based on the opmode settings. Example 10-11. Verilog DSP48 Instantiation
/*-------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : mult_acc --- Purpose : This design example shows how to instantiate a DSP48 block -- using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c.Prod -- Date: Jan 05 2006 -------------------------------------------------------------------------*/ module mult_acc ( clk, dataa, datab, datac, result); parameter sub_in_width = parameter sub_out_width = input [sub_in_width-1:0] input [sub_in_width-1:0] input [sub_out_width-1:0] input clk; output [sub_out_width-1:0] 18; 48; dataa; datab; datac; result;

DSP48 DSP48_1( .BCOUT(), .P(result), .PCOUT(), .A(dataa), .B(datab), .BCIN(), .C(datac), .CARRYIN(), .CARRYINSEL(), .CEA(), .CEB(), .CEC(), .CECARRYIN(), .CECINSUB(), .CECTRL(), .CEM(), .CEP(), .CLK(clk), //With OPMODE setting to 7b0100101, // mode is selected .OPMODE(7b0100101), .PCIN(), .RSTA(), .RSTB(),

P (A

B+ CIN) Multiply-accumulate

332

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks Instantiating DSP Functions .RSTC(), .RSTCTRL(), .RSTP(), .RSTCARRYIN(), .RSTM(), .SUBTRACT());

// Number of pipeline registers on the A input, 0, 1 or 2 defparam DSP48_1.AREG=2; // Number of pipeline registers on the A input, 0, 1 or 2 defparam DSP48_1.BREG=2; // Number of pipeline registers on the C input, 0 or 1 defparam DSP48_1.CREG=1; // B input DIRECT from fabric or CASCADE from another DSP48 defparam DSP48_1.B_INPUT=DIRECT; // Backward compatibility,NONE or MULT18X18 defparam DSP48_1.LEGACY_MODE=MULT18X18S; // Number of pipeline registers on the P output, 0 or 1 defparam DSP48_1.PREG=1; // Number of pipeline registers for the CARRYIN input, 0 or 1 defparam DSP48_1.CARRYINREG =0; // Number of pipeline registers for the CARRYINSEL, 0 or 1 defparam DSP48_1.CARRYINSELREG =0; // Number of pipeline registers on the SUBTRACT input, 0 or 1 defparam DSP48_1.SUBTRACTREG =0; endmodule

Example 10-12. VHDL DSP48 Instantiation


---------------------------------------------------------------------------- Copyright (c) 2006 Mentor Graphics Corporation. All rights reserved. -- The following information has been generated by Mentor Graphics -- and may be freely distributed and modified. --- Design name : mult_acc --- Purpose : This design example shows how to instantiate a DSP48 block -- using Precision synthesis tool --- Rev: 1.0 -- Precision: 2005c -- Date: Jan 05 2006 --------------------------------------------------------------------------library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith; use ieee.std_logic_signed; entity mult_acc is generic(sub_in_width : natural := 18; sub_out_width : natural := 48); port(clk : in std_logic; dataa, datab : in std_logic_vector ( sub_in_width-1 downto 0); datac : in std_logic_vector (sub_out_width-1 downto 0); result : out std_logic_vector (sub_out_width-1 downto 0)); end entity mult_acc;

Precision Synthesis Style Guide, 2011a Update2 November 2011

333

DSP Blocks Instantiating DSP Functions architecture RTL of mult_acc is component DSP48 generic(AREG B_INPUT BREG CARRYINREG CARRYINSELREG CREG LEGACY_MODE MREG OPMODEREG PREG SUBTRACTREG port(BCOUT : out P : out PCOUT : out A : in B : in BCIN : in C : in CARRYIN : in CARRYINSEL : in CEA : in CEB : in CEC : in CECARRYIN : in CECINSUB : in CECTRL : in CEM : in CEP : in CLK : in OPMODE : in PCIN : in RSTA : in RSTB : in RSTC : in RSTCARRYIN : in RSTCTRL : in RSTM : in RSTP : in SUBTRACT : in end component;

: integer := 1; : string := DIRECT; : integer := 1; : integer := 1; : integer := 1; : integer := 1; : string := MULT18X18S; : integer := 1; : integer := 1; : integer := 1; : integer := 1 ); std_logic_vector( sub_in_width-1 std_logic_vector(sub_out_width-1 std_logic_vector(sub_out_width-1 std_logic_vector( sub_in_width-1 std_logic_vector( sub_in_width-1 std_logic_vector( sub_in_width-1 std_logic_vector(sub_out_width-1 std_ulogic; std_logic_vector(1 downto 0); std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_logic_vector(6 downto 0); std_logic_vector(sub_out_width-1 std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic; std_ulogic );

downto downto downto downto downto downto downto

0); 0); 0); 0); 0); 0); 0);

downto 0);

signal result_out, cin, pcin : std_logic_vector(sub_out_width-1 downto 0); signal ain, bin, bcin : std_logic_vector( sub_in_width-1 downto 0); begin DSP48_1 : DSP48 generic map( -- Number pipeline registers on the A input, 0, 1 or 2 AREG => 2, -- B input DIRECT from fabric or CASCADE from another DSP48 B_INPUT => DIRECT, -- Number of pipeline registers on the B input, 0, 1 or 2 BREG => 2 , -- Number of pipeline registers for the CARRYIN input, 0 or 1

334

Precision Synthesis Style Guide, 2011a Update2 November 2011

DSP Blocks Instantiating DSP Functions CARRYINREG => 0, -- Number of pipeline registers for the CARRYINSEL, 0 or 1 CARRYINSELREG => 0, -- Number of pipeline registers on the C input, 0 or 1 CREG => 1 , -- Backward compatibility,NONE or MULT18X18 LEGACY_MODE => MULT18X18S, -- Number of pipeline registers on OPMODE input, 0 or 1 OPMODEREG => 0, -- Number of pipeline registers on the P output, 0 or 1 PREG => 1, -- Number of pipeline registers on the SUBTRACT input, 0 or 1 SUBTRACTREG => 0 ) port map(BCOUT => open, P => result_out, PCOUT => open, A => ain, B => bin, BCIN => bcin, C => cin, CARRYIN => 0, CARRYINSEL => 00, CEA => 1, CEB => 1, CEC => 1, CECARRYIN => 0, CECINSUB => 0, CECTRL => 0, CEM => 0, CEP => 1, CLK => clk, -- With OPMODE setting to 7b0100101, P (A B+ CIN) -- Multiply-accumulate mode is selected OPMODE => 0100101, PCIN => pcin, RSTA => 0, RSTB => 0, RSTC => 0, RSTCARRYIN => 0, RSTCTRL => 0, RSTM => 0, RSTP => 0, SUBTRACT => 0 ); result <= result_out(sub_out_width-1 downto 0); --ain <= X000 & dataa; --bin <= X000 & datab; --cin <= X000000000 & datac; ain <= dataa; bin <= datab; cin <= datac; end architecture RTL;

Precision Synthesis Style Guide, 2011a Update2 November 2011

335

DSP Blocks Instantiating DSP Functions

336

Precision Synthesis Style Guide, 2011a Update2 November 2011

Chapter 11 Exemplar VHDL Package


This appendix describes the contents of the Exemplar, Precision and Synopsys VHDL packages. These packages contain predefined types, attributes, and functions to increase a designers productivity.

The Exemplar Packages


There are a number of operations in VHDL that occur regularly. An example is the translation of vectors to integers and back. For this reason, Mentor Graphics provides packages that define attributes, types, functions and procedures that are frequently used. Using the functions and procedures reduces the amount of initial circuitry that is generated, compared to writing the behavior explicitly in a user-defined function or procedure. This reduces the cpu-time for compilation and also could result in a smaller circuit implementation due to improved optimization. This section discusses the defined functionality in the Mentor Graphics packages: precision, exemplar, and exemplar_1164. The package bodies are not read by the synthesis tools; the functions are built-in. The packages are used for simulation only, and editing them does not change the synthesized logic. The VHDL source for these packages is given in the files mgc_attr.vhd, exemplar.vhd and ex_1164.vhd, respectively in the <precision install directory>/pkgs/rtlc_psr/rtlc/auxi/packages/EXEMPLAR directory. The exemplar_1164 package defines the same functionality as the exemplar package, but operates on the IEEE 1164 multi-valued logic types. If you are using the IEEE 1164 types in your VHDL description, you should include the IEEE standard logic type definition into your VHDL description with a use clause. The VHDL source of the IEEE 1164 types package is in the file std_1164.vhd in the <precision install directory>/pkgs/techdata/vhdl directory. If you also want to use the Mentor Graphics functions that operate on these types, you should include the package exemplar_1164 with a use clause. For example:
library ieee; use ieee.std_logic_1164.all; library exemplar; use exemplar_1164.all;

If you do not use the IEEE 1164 types, but still want to use the Mentor Graphics functions, just include the package exemplar in your VHDL description with a use clause. All functions are then defined with the predefined types bit and bit_vector, and on the four-valued types elbit and elbit_vector.
Precision Synthesis Style Guide, 2011a Update2 November 2011

337

Exemplar VHDL Package The Exemplar Packages

Predefined Types
The exemplar package defines a four-valued type called elbit and its array equivalent elbit_vector. The elbit type includes the bit values 0, 1, X and Z. Mentor Graphics recommends that you use the IEEE 1164 standard logic types, and the exemplar_1164 package.

Predefined Attributes
Precision RTL Synthesis uses attributes to control synthesis of the described circuit. You can use the set_attribute interactive shell command to set object attributes within the hierarchical database. You may find it more convenient to define attributes in the VHDL source. The attributes recognized by Precisions default compiler appear in the precision_attributes package (<precision install directory>/pkgs/techdata/vhdl/mgc_attr.vhd). See Attributes in Precision Synthesis Reference Manual for details on each supported attribute. The following attributes shown in Table 11-1 are recognized by the 2004c compile mode VHDL parser, and declared in both the exemplar and the exemplar_1164 package: Table 11-1. Exemplar Package Attributes Recognized by the VHDL Parser Attribute
required_time arrival_time output_load max_load clock_cycle pulse_width input_drive nobuf pin_number array_pin_number* preserve_signal buffer_sig modgen_sel

Type time time real real time time time boolean string array of strings boolean string
modgen_select

Description Set required time on output Set arrival_time on input Specify load set on output Specify max load allowed on input Specify clock length on clock pin Specify pulse width on clock pin Specify delay/unit load for input Reject buffer insertion for a input Specify location of input or output pin Specify location for each bit of a bus Signals function will survive synthesis Specify explicit buffer on a pin Specify time requirement for module generators driving this signal

*VHDL only.

338

Precision Synthesis Style Guide, 2011a Update2 November 2011

Exemplar VHDL Package The Exemplar Packages

In order to set a particular attribute on a signal (or port) in VHDL, you should use the normal attribute specification statement in VHDL. Here are some examples:
library exemplar ; use exemplar.exemplar.all ; -- Include the exemplar package entity test is port ( my_input : in bit ; my_output : out bit_vector (5 downto 0) ; ) ; attribute pin_number of my_input:signal is "P15" ; attribute array_pin_number of my_output:signal is ("P14","P13","P12","P11","P10","P9") ; attribute required_time of my_output:signal is 5 ns ; end test ; architecture exemplar of test is signal internal_signal : bit ; attribute preserve_signal of internal_signal:signal is TRUE ; attribute modgen_sel of internal_signal:signal is FAST ; begin ...

Since variables do not represent one unique node in the circuit implementation (they represent a different circuit node after each assignment) the attributes are effective on all circuit nodes the variable represents. This could lead to unexpected behavior. So you should be careful using the attributes on variables. All attributes work both on single-bit signals and on arrays of bits. In the case an attribute is set on a signal that is an array of bits (bit_vector, elbit_vector or std_logic_vector) the value of the attribute is set to all circuit nodes in the vector. An exception is the pin_number attribute which only operates on single bit ports. Use the array_pin_number attribute to set pin numbers on all bits of a bus. Refer to Chapter 2, Attributes, in the Precision RTL Synthesis Reference Manual for detailed information on each attribute.

Predefined Functions
The package exemplar defines a set of functions that are often used in VHDL for synthesis. First of all, the package defines the overloaded operators and, nand, or, nor, xor, and not for the types elbit and elbit_vector, as well a for elbit_matrix, a two-dimensional array type of elbit values. The exemplar package defines a large set of functions for both the standard bit and bit_vector types. For backwards compatibility, these functions are also defined for elbit and elbit_vector types. These functions are discussed below.

Precision Synthesis Style Guide, 2011a Update2 November 2011

339

Exemplar VHDL Package The Exemplar Packages

All functions are also defined with the IEEE 1164 types std_logic, std_ulogic, std_logic_vector, and std_ulogic_vector in the package exemplar_1164 in file ex_1164.vhd.
bool2elb(l: boolean)return std_logic;

Takes a boolean, and returns a std_logic bit. Boolean value TRUE will become std_logic value 1, FALSE will become 0.
elb2bool(l: std_logic)return boolean;

Takes a std_logic value and returns a boolean. The std_logic value 1 will become TRUE, all other values become FALSE.
int2boo(l: integer)return boolean;

Takes an integer and returns a boolean. Integer value 0 will return FALSE, all other integer values return TRUE.
boo2int(l: boolean)return integer;

Takes a boolean and returns an integer. Boolean value TRUE will return 1, FALSE will return 0.
evec2int(l: std_logic_vector)return integer;

Takes a vector of bits and returns the (positive) integer representation. The left most bit in the vector is assumed the MSB for the value of the integer. The vector is interpreted as an unsigned representation.
int2evec (l: integer, size : integer := 32)return std_logic_vector;

Takes a integer and returns the vector representation. The size of the vector becomes equal to the value of an optional second argument (size). If this argument is not specified, the size of the return vector defaults to 32. The left most bit in the resulting vector is the MSB of the returned value. If the integer value of the first parameter is negative, the MSB is the sign bit.
elb2int(l: std_logic)return integer;

Takes a std_logic value and returns an integer. The std_logic value 1 will return integer value 1, all other values will return integer value 0. For all shifter functions that follow, the shift amount (r) could either be a compile time constant or not. If it is, the synthesized circuit will only consist of a re-ordering of the wires in the array. Otherwise, Precision RTL Synthesis will synthesize a shifter circuit.
sl (l: std_logic_vector; r: integer)return std_logic_vector;

Takes a vector l and an integer r and returns a vector. The resulting vector is the same size as l, but all bits of l are shifted left r places. The bits on the right side of the result vector are zerofilled. The integer r must be non-negative.
340
Precision Synthesis Style Guide, 2011a Update2 November 2011

Exemplar VHDL Package The Exemplar Packages sl2 (l: std_logic_vector; r: integer)return std_logic_vector;

Same as sl, but the vector l is treated as a 2-complement (signed) representation. Sign bit is the left most bit in vector. Bits on the right are zero-filled.
sr (l: std_logic_vector; r: integer)return std_logic_vector;

Same as sl, but bits are shifted to the right side of the vector. Bits on left side are zero-filled.
sr2 (l: std_logic_vector; r: integer)return std_logic_vector;

Same as sr, but the vector l is treated as a 2-complement representation. Sign bit is the left most bit in vector. Bits on the left side are sign-bit filled.
add (op_l, op_r: std_logic_vector)return std_logic_vector;

Takes two vectors and returns a vector. The resulting vector is one bit larger than the largest of the input vectors, and represents the addition of the input vectors, including the carry bit. The left most bit is assumed to be the MSB. The add function is a vector addition of two unsigned vectors. The smallest input vector is 0, extended on the MSB side to the size of the largest input vector before addition is performed.
add ("1011","0100") result : "01111" add ("0011","100") result : "00111" add2 (add (11,4) == 15) (add (3,4) == 7)

(op_l, op_r: std_logic_vector)return std_logic_vector;

Same as add, but now the vectors are assumed to be in 2-complement representation. Sign bit is the left most bit in the vectors. The smallest input vector is sign-bit extended on the MSB side to the size of the largest vector before addition is performed.
add2 ("1011","0100") result : "00001" add2 ("0011","100") result : "11111" sub (add2 (-5,4) == 1) (add2 (3,-4) == -1)

(op_l, op_r: std_logic_vector) return std_logic_vector;

Same as add, but the subtraction function is implemented on unsigned vectors. op_r is subtracted from op_l.
sub sub ("1011","0100")result : "00111" ("0011","100") result : "11111" (sub (11,4) == 7) (sub(3,4) == 31)

Actually this is an under-flow of unsigned!


sub2 (op_l, op_r: std_logic_vector) return std_logic_vector;

Precision Synthesis Style Guide, 2011a Update2 November 2011

341

Exemplar VHDL Package The Exemplar Packages

Same as add2, but the subtraction function is implemented on 2-complement representation vectors. op_r is subtracted from op_1.
sub2 ("1011","0100") result : "10111" sub2 ("1011", "100") result : "11111" extend (op_l: std_logic_vector; op_r: integer) return std_logic_vector; (sub2(-5,4) == -9) (sub2(-5,-4) == -1)

Takes a vector op_l and an integer op_r and returns a vector. The vector op_l is extended in size up to op_r elements. The input vector op_l is zero-extended on the MSB side. The left most bit in the vector is assumed the MSB. There is also a version of extend that takes a single (std_logic) value and extends it to a vector of size op_r.
extend ("1001",7) result : "001001" extend (1,3) result : "001" extend ("011001001", 4)result : "1001" extend2 (op_l: std_logic_vector; op_r: integer) return std_logic_vector;

-- Truncation

Same as extend, but the vector is in 2s-complement representation. The input vector is sign-bit extended. There is also a version of extend2 that takes a single (std_logic) value and signextends it to a vector of size op_r.
extend2 ("1001",7) result : "1111001" extend2 (1,3) result : "111" extend2 ("011001001",4) result : "1001" -- Truncation comp2(op: std_logic_vector)return std_logic_vector;

Takes a vector and returns a vector of the same size. This function assumes the input vector to be in 2-complement representation and will return the complement (negative) value of the input value. The right most bit is assumed to be the LSB.
comp2 ("1001") result : "0111" "+" ( comp2 (-7) == 7)

(op_l, op_r: std_logic_vector) return std_logic_vector;

Takes two vectors and returns a vector. As add, but now the carry bit is not saved. The resulting vector is the same size as the largest input vector. Overflow wraps around. This function implements addition of unsigned vectors.
"10110" + "101" result :

"11011"

(22 + 5 == 27)

342

Precision Synthesis Style Guide, 2011a Update2 November 2011

Exemplar VHDL Package The Exemplar Packages "-" (op_l, op_r: std_logic_vector) return std_logic_vector;

Same as +, only the subtraction function is performed. op_r is subtracted from op_l. This function implements subtraction of unsigned vectors.
"10110" - "101" result : "10001" "mult"

(22 - 5 == 17)

(op_l, op_r: std_ulogic_vector) return std_ulogic_vector;

Takes two vectors and returns a vector. The size of the resulting vector is the size of both input vectors added. In each vector, the left most bit is the MSB. The mult function performs UNSIGNED multiplication of the two input vectors. In case of unequal-length input vectors, the smallest vector is zero-extended on the MSB side to the size of the largest input vector before the multiplication is performed.
mult ("1011", "0100") result: "00101100" (mult(11,4)==44) mult ("1", "1111") result: "00001111" (mult(1,15)==15) "mult2" (op_l, op_r: std_ulogic_vector) return std_ulogic_vector;

Like mult, but now the vectors are assumed to be in 2-complement representation. The sign bit is the left most bit in each vector. In case of unequal-length input vectors, the smallest vector is sign-bit extended on the MSB side to the size of the largest input vector before the multiplication is performed.

Predefined Procedures
There are various ways to generate flip-flops and d-latches with VHDL, such as using processes and specifying behavior that represents the behavior of flip-flops and dlatches. However, in some cases it is useful to instantiate technology independent flip-flops or dlatches in the VHDL dataflow environment immediately. A more structural oriented VHDL style will be possible that way. The exemplar package includes the definition of procedures that represent flip-flops or dlatches with various set or reset facilities that operate on single bits or vectors (to create registers). The exemplar package defines these procedures on signals of type bit, bit_vector, elbit and elbit_vector, while the package exemplar_1164 defines the same procedures for the IEEE 1164 types std_logic, std_ulogic, std_logic_vector and std_ulogic_vector. In the description below only examples for bit and bit_vector are given, but the full definition of the procedures, for the types listed above, is available for simulation purposes in the files exemplar.vhd and ex_1164.vhd.

Precision Synthesis Style Guide, 2011a Update2 November 2011

343

Exemplar VHDL Package The Exemplar Packages

Flipflops
dff[_v](data, clock, q) dffc[_v](data, clear, clock, q) dffp[_v](data, preset, clock, q) dffpc[_v](data, preset, clear, clock, q)

Here dff is the single bit D flip-flop and dff_v is the vectored D flip-flop. dff has no preset or clear inputs, dffc has an active-high asynchronous clear (set q to 0) input, dffp has an active-high asynchronous preset (set q to 1) input, and dffpc has both a preset and a clear input. If both preset and clear are asserted, q is not defined. All inputs are active high, the clock input is positive edge triggered. For the vectored dffs, the number of flip-flops that will be instantiated is defined by the size of the input (d) and output (q) vectors of the dff#_v instantiation. (The size of d and q vectors must be the same.) If q is a port of the VHDL entity, it must be declared as an INOUT port, since q is used bidirectionally in each of these functions.

Latches
dlatch[_v](data, enable, q) dlatchc[_v](data, clear, enable, q) dlatchp[_v](data, preset, enable, q) dlatchpc[_v](data, preset, clear, enable, q)

These define a level sensitive D-type latch with an enable. The latch is enabled (transparent) when the enable input is 1, disabled when the input is 0. dlatch has no preset or clear capability, dlatchc has an asynchronous active-high clear (set q to 0) input, dlatchp has an asynchronous active-high preset (set q to 1), and dlatchpc has both preset and clear. If both preset and clear are asserted, q is not defined. dlatch_v creates the vector equivalent procedures to generate registers of dlatches.

Tristate Buses
When a signal is assigned in multiple concurrent statements, the synthesis implementation requires that in each statement the signal is assigned a Z value under at least one condition. A tristate gate is created in this case, with the enable of the gate corresponding to the inverse of the condition where the Z is assigned in the model. This is the only case where multiple assignments to a signal in different concurrent statements is allowed. It is also possible for the user to specify what to do in the case where none of the drivers of the bus are enabled. To address this situation, three pre-defined procedures have been declared to handle the three standard tristate bus conditions: PULLUP, PULLDN and TRSTMEM. These drive an otherwise undriven bus to the values 1, 0, or retain the current value, respectively. Only one of these functions may be specified for a given bus. Precision RTL Synthesis will build the

344

Precision Synthesis Style Guide, 2011a Update2 November 2011

Exemplar VHDL Package Interfacing With Other VHDL Tools

appropriate logic to implement the specified function in the technology. If the technology includes pull-up or pull-down resistors or repeater cells on internal buses these will be used. If these resistors are not available, an additional tristate gate, with an enable which is the NOR of all the other enable. The tristate gate input is either VCC, GND or the value on the bus is created to implement the specified function. Precision RTL Synthesis also determines what the default state for a bus is in the technology. If the default matches the specified function, no extra logic is created. If no termination is specified, then the undriven tristate value depends on the technology used. The tristate bus procedures defined below may be used with signals of type bit, elbit, (package exemplar) std_logic and std_ulogic (package exemplar_1164).
pullup (busname)

When a bus is not driven, this procedure pulls the bus up to 1.


pulldn (busname)

When a bus is not driven, this procedure pulls the bus down to 0.
trstmem (busname)

When a bus is not driven, this procedure drives the bus to the last driven state.

Interfacing With Other VHDL Tools


The VHDL parsers in Precision RTL Synthesis are compliant with the IEEE VHDL 1076-1987 standard. Hence, apart from the VHDL restrictions for synthesis, interfacing with tools that generate VHDL or operate on VHDL should not introduce compatibility problems. However, since VHDL 1076 does not define file handling, there might be mismatches in the way the tools handle files. Many VHDL simulators incorporate a directory structure to store separately compiled VHDL files. Precision RTL Synthesis does not use separate compilation of VHDL files. Therefore, all packages and components that are used for a VHDL design description should be identified before running Precision RTL Synthesis, as explained in the previous section.

Performing Post-layout Functional Simulation


You should always load the packages and entities in your design into the simulator prior to simulating the root entity. For simulation, the exemplar and exemplar_1164 packages can be found in the <precision install directory>/pkgs/techdata/vhdl directory. The files are named exemplar.vhd and ex_1164.vhd, respectively. Refer to the topic The Exemplar Packages for more information on these packages.

Precision Synthesis Style Guide, 2011a Update2 November 2011

345

Exemplar VHDL Package Working with the Synopsys Package

If you desire, a post-synthesis functional simulation can be performed using the structural VHDL output from Precision RTL Synthesis. In your design flow, you should choose the appropriate netlist output for the target technology.

Working with the Synopsys Package


Users that have existing VHDL files for Synopsys VHDL Compiler can rely on one or more of the Synopsys pre-defined VHDL packages. Precision RTL Synthesis supports all these packages; a use clause includes the packages in your design. The Synopsys packages define a set of types and functions that contain Synopsys pragmas that VHDL Compiler uses as synthesis directives. These pragmas are correctly interpreted by the Precision Synthesis tools:
pragma translate_on pragma translate_off synopsys translate _on synopsys translate_off synopsys synthesis_on synopsys synthesis_off

Except for a use clause for each Synopsys package that you need in your VHDL file, you should not have to load any Synopsys package into Precision RTL Synthesis. Precision RTL Synthesis locates the packages that you want to use in the directory <precision install directory>/pkgs/techdata/vhdl. Here is the list of files with the contained packages: File Name
syn_ari.vhd syn_attr.vhd syn_type.vhd syn_arit.vhd syn_misc.vhd syn_unsi.vhd syn_sign.vhd

Package Name
ARITHMETIC ATTRIBUTES TYPES STD_LOGIC_ARITH STD_LOGIC_MISC STD_LOGIC_UNSIGNED STD_LOGIC_SIGNED

Note: Precision RTL Synthesis locates the packages (from the use clause in your VHDL description). Precision RTL Synthesis loads any of the listed files from the <precision install directory>/pkgs/techdata/vhdl directory, or reads a file without the synthesis directives. However, without the synthesis directives, Precision RTL Synthesis cannot efficiently synthesize any of the Synopsys packages. Precision RTL Synthesis assumes that the Synopsys libraries are called from either the VHDL library SYNOPSYS or the VHDL library IEEE.

346

Precision Synthesis Style Guide, 2011a Update2 November 2011

Exemplar VHDL Package Working with the Synopsys Package

Note The VHDL library IEEE is a storage recommended by Synopsys.

If you store your Synopsys library (on your VHDL simulator) somewhere else than in these libraries, then you have to manually include the (package) files needed from the <precision install directory>/pkgs/techdata/vhdl directory. Precision RTL Synthesis does not recognize the libraries as Synopsys packages.
vhdl_file=libname::filename

Manually include these packages with the batch mode option in the appropriate library.

Use the analyze libname filename interactive command line shell option and argument. Make sure again that you use the files from the <precision install directory>/pkgs/techdata/vhdl directory (with synthesis directive attributes).

Precision Synthesis Style Guide, 2011a Update2 November 2011

347

Exemplar VHDL Package Working with the Synopsys Package

348

Precision Synthesis Style Guide, 2011a Update2 November 2011

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Index
Numerics
2004c Compile Mode, 316 casex statement, 100 casez statement, 100 multiplexer generation, 98 Verilog case statement, 96 VHDL case statement, 36 component instantiation, 53 components declared, 54 structure module, 53 conditional statement, 36 configuration declaration, 17 continuous assignment net declaration assignment, 83 statement, 84

A
alias, 61 Array types VHDL array types as scalar, 23 constrained array types, 31 enumerated-index array types, 28 IEEE 1164 array types, 43 pre-defined operators, 44 syntax and semantics, 26 synthesis issues, 28 type conversions, 31 unconstrained array types, 27 Assignment statements in VHDL, 39 signal, 39 variable, 39 Attributes dedicated_mult, 315 disable_fsm, 295 Exemplar predefined attributes, 45 fsm_implementation, 295 fsm_state, 295, 296 in VHDL source code, 44 type_encoding, 296 type_encoding_style, 296 user-defined attributes, 45 VHDL predefined attributes, 45

D
Data types SystemVerilog, 130 Verilog net data type, 81 parameter data type, 82 register data type, 82 WAND and WOR net types, 82 Dataflow Environment operators, 16 statements, 16 design root, 17 directives parallel_case and full_case, 109 translate_off and translate_on, 109 disable statement, 102 disable_fsm attribute, 295 DSP 2004c Compile Mode, 316 attributes, 319 dedicated_mult attribute, 315, 316, 319 frontend_dissolve attribute, 319 guidelines, 315 inference, 315, 316 instantiation, 316, 332

B
block statement, 47 bus class, 53

C
Cascaded clocks - conversion, 238 case statements automatic full case detection, 99 automatic parallel case detection, 99
Precision Synthesis Style Guide, 2011a Update2 November 2011

349

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Mult-Acc, 325 Mult-Acc-AddSub, 327 Mult-Add, 321 Mult-AddSub, 323 multipliers, 316 pipelined 35x18 multiplier, 329 reset handling, 315, 317 use_resource attribute, 319

G
Gated Clock Conversion AND, 234 cascaded clocks, 238 NAND, 235 NOR, 237 OR, 236 generate statement, 37 generic size, 35 Generics generic list, 35

E
Entity and package usage, 60 enumerated type, 23 Enumerated types, 23, 28, 29 Exemplar package description, 337 predefined attributes, 338 predefined functions, 339 predefined procedures, 343 predefined types, 338

I
IEEE 1076, 32 IEEE 1076-1987, 17 IEEE 1076-1993, 17 IEEE 1164, 32 IEEE 1164 standard logic, 43 IEEE 1364, see Verilog if-else statement, 95 integer types VHDL and arithmetic behavior, 23 arithmetic operators, 42 integer pre-defined type, 24 integer range limits, 24 integer type example, 31 related types, 31 syntax, 23 synthesis encoding of integer types, 26 synthesis issues, 24

F
Finding definition of component, 58 Flip-flops asynchronous set and reset, 205 clock enable, 206 predefined procedure, 344 synchronous set and reset, 205 Floating-point types as a scalar in VHDL, 23 operator overloading, 44 synthesis resolution, 25 type conversion in VHDL, 31 VHDL, 25 VHDL semantics, 25 for loops SystemVerilog, 141 Verilog, 101 VHDL, 37 fsm_implementation attribute, 295 fsm_state attribute, 295, 296 Functions in Verilog, 104 in VHDL, 48

L
Latches, 207 Literal values, 128 Literals VHDL constant values, 21 defined, 21 Loop variables VHDL, 35

M
Module instantiation parameter overrides, 89

350

Precision Synthesis Style Guide, 2011a Update2 November 2011

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z N
Net data types supply net, 82 Verilog WAND and WOR, 82 wire and tri net, 82 Numbers, 79

P
package body, 59 header, 59 Packages, 59 Partitioning blocks, 47 processes, 47 Physical types, 23, 26 Ports VHDL port statement, 34 Post-layout functional simulation, 345 Pragmas Verilog, 109 procedure statement, 48 Processes, 19

O
objects array, 27 array naming, 28 declared, 22 elements, 29 enumeration type, 23 generic, 35 loop variable, 35 physical type, 26 port, 34 ports, 34 record, 29 signal, 33 variable, 34, 207 operand, 90 Operators IEEE 1076 pre-defined, 41 Verilog arithmetic operator, 91 bit-wise operator, 93 concatenation, 94 conditional operator, 93 logical operator, 92 reduction operator, 93 relational and equality operator, 92 shift operator, 93 signed and unsigned attribute, 94 VHDL arithmetic, 28, 42 concatenation, 42 exemplar package, 28 exemplar_1164 package, 28 logical, 41, 42 overloading, 22, 44 pre-defined, 41 relational, 41 vector arithmetics, 42

R
Record types, 23, 29 Registers AND gated clock, 234 cascaded clocks, 238 NAND gated clock, 235 NOR gated clock, 237 OR gated clock, 236 Resolution functions, 50

S
Signals, 33 Signed attribute on operators, 94 Statements VHDL assignment statement, 39 basic statements, 35 conditional statement, 36 generate statement, 37 loop statement, 37 loop variable, 35 selection statement, 36 std_logic, 33, 42, 50, 51 Subprograms function, 48 procedure, 48 Subtypes, 30, 31
351

Precision Synthesis Style Guide, 2011a Update2 November 2011

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Synopsys integration and packages, 346 Syntax and semantic restrictions, 62 synthesis tool restrictions, 62 VHDL language Restriction, 63 Synthesis directives attribute, 109 translate_off and translate_on, 109 SystemVerilog, 119 define macro, 150 always_comb, 143 always_latch, 144 always_seq, 144 argument passing by name, 146 array assignment, 137 array literals, 130 array type literal, 128 array types, 135 arrays as arguments, 138 assignment operators, 139 attributes, 139 break, 141 compiler directives, 150 constants, 138 continue, 141 data types, 130 casting, 135 enumerations, 134 integer types, 132 structures, 134 unions, 134 user defined types, 133 do...while loop, 140 example designs, 152 for loops, 141 function, 145 implicit .* port connections, 148 implicit .name port connections, 147 indexing arrays, 136 integer and logic literals, 129 integer type, 128 interfaces, 148 language features, 119 literal values, 128 logic type, 128 multi-dimensioned arrays, 136 named blocks, 143 packed arrays, 135 port declarations, 147 processes, 143 real literals, 129 real type, 128 return, 141 return expression, 141 selection statements, 139 slicing arrays, 136 string literals, 130 string of type packed array, 128 structure literals, 128 task, 145 tasks and functions, 145 Time literal, 128 unpacked arrays, 135 void functions, 146

T
Tasks, 105 type_encoding attribute, 296 type_encoding_style attribute, 296 Types array types, 26 enumeration type, 23 floating-point type, 25 IEEE 1076 predefined type, 32 IEEE 1076 predefined types, 32 IEEE 1164, 33 integer type, 23 physical type, 26 record type, 29 subtypes, 30 type conversions, 31

U
Unsigned attribute on operators, 94

V
variable statement, 207 Verilog if-else statement, 95 parameter data type, 82 pragmas, 109

352

Precision Synthesis Style Guide, 2011a Update2 November 2011

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
register data type, 82 signed and unsigned attributes, 94 Verilog 2001 Support, 111 VHDL architectures, 16 array types, 23 basic statements, 35 blocks, 47 dataflow environment, 16 entities, 16 enumerated-index array types, 28 environment interfacing with other VHDL tools, 345 IEEE 1076-1987, 17 IEEE 1076-1993, 17 integer type, 23 loop variables, 35 object signal, 16 package handling, 17 procedure statement, 48 variable statement, 207 void, 146

W
while loop, 37

Precision Synthesis Style Guide, 2011a Update2 November 2011

353

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

354

Precision Synthesis Style Guide, 2011a Update2 November 2011

End-User License Agreement


The latest version of the End-User License Agreement is available on-line at: www.mentor.com/eula IMPORTANT INFORMATION USE OF ALL SOFTWARE IS SUBJECT TO LICENSE RESTRICTIONS. CAREFULLY READ THIS LICENSE AGREEMENT BEFORE USING THE PRODUCTS. USE OF SOFTWARE INDICATES CUSTOMERS COMPLETE AND UNCONDITIONAL ACCEPTANCE OF THE TERMS AND CONDITIONS SET FORTH IN THIS AGREEMENT. ANY ADDITIONAL OR DIFFERENT PURCHASE ORDER TERMS AND CONDITIONS SHALL NOT APPLY.

END-USER LICENSE AGREEMENT (Agreement) This is a legal agreement concerning the use of Software (as defined in Section 2) and hardware (collectively Products) between the company acquiring the Products (Customer), and the Mentor Graphics entity that issued the corresponding quotation or, if no quotation was issued, the applicable local Mentor Graphics entity (Mentor Graphics). Except for license agreements related to the subject matter of this license agreement which are physically signed by Customer and an authorized representative of Mentor Graphics, this Agreement and the applicable quotation contain the parties' entire understanding relating to the subject matter and supersede all prior or contemporaneous agreements. If Customer does not agree to these terms and conditions, promptly return or, in the case of Software received electronically, certify destruction of Software and all accompanying items within five days after receipt of Software and receive a full refund of any license fee paid.
1. ORDERS, FEES AND PAYMENT. 1.1. To the extent Customer (or if agreed by Mentor Graphics, Customers appointed third party buying agent) places and Mentor Graphics accepts purchase orders pursuant to this Agreement (Order(s)), each Order will constitute a contract between Customer and Mentor Graphics, which shall be governed solely and exclusively by the terms and conditions of this Agreement, any applicable addenda and the applicable quotation, whether or not these documents are referenced on the Order. Any additional or conflicting terms and conditions appearing on an Order will not be effective unless agreed in writing by an authorized representative of Customer and Mentor Graphics. 1.2. Amounts invoiced will be paid, in the currency specified on the applicable invoice, within 30 days from the date of such invoice. Any past due invoices will be subject to the imposition of interest charges in the amount of one and one-half percent per month or the applicable legal rate currently in effect, whichever is lower. Prices do not include freight, insurance, customs duties, taxes or other similar charges, which Mentor Graphics will state separately in the applicable invoice(s). Unless timely provided with a valid certificate of exemption or other evidence that items are not taxable, Mentor Graphics will invoice Customer for all applicable taxes including, but not limited to, VAT, GST, sales tax and service tax. Customer will make all payments free and clear of, and without reduction for, any withholding or other taxes; any such taxes imposed on payments by Customer hereunder will be Customers sole responsibility. If Customer appoints a third party to place purchase orders and/or make payments on Customers behalf, Customer shall be liable for payment under Orders placed by such third party in the event of default. 1.3. All Products are delivered FCA factory (Incoterms 2000), freight prepaid and invoiced to Customer, except Software delivered electronically, which shall be deemed delivered when made available to Customer for download. Mentor Graphics retains a security interest in all Products delivered under this Agreement, to secure payment of the purchase price of such Products, and Customer agrees to sign any documents that Mentor Graphics determines to be necessary or convenient for use in filing or perfecting such security interest. Mentor Graphics delivery of Software by electronic means is subject to Customers provision of both a primary and an alternate e-mail address. 2. GRANT OF LICENSE. The software installed, downloaded, or otherwise acquired by Customer under this Agreement, including any updates, modifications, revisions, copies, documentation and design data (Software) are copyrighted, trade secret and confidential information of Mentor Graphics or its licensors, who maintain exclusive title to all Software and retain all rights not expressly granted by this Agreement. Mentor Graphics grants to Customer, subject to payment of applicable license fees, a nontransferable, nonexclusive license to use Software solely: (a) in machine-readable, object-code form (except as provided in Subsection 5.2); (b) for Customers internal business purposes; (c) for the term of the license; and (d) on the computer hardware and at the site authorized by Mentor Graphics. A site is restricted to a one-half mile (800 meter) radius. Customer may have Software temporarily used by an employee for telecommuting purposes from locations other than a Customer office, such as the employee's residence, an airport or hotel, provided that such employee's primary place of employment is the site where the Software is authorized for use. Mentor Graphics standard policies and programs, which vary depending on Software, license fees paid or services purchased, apply to the following: (a) relocation of Software; (b) use of Software, which may be limited, for example, to execution of a single session by a single user on the authorized hardware or for a restricted period of time (such limitations may be technically implemented through the use of authorization codes or similar devices); and (c) support services provided, including eligibility to receive telephone support, updates, modifications, and revisions. For the avoidance of doubt, if Customer requests any change or enhancement to Software, whether in the course of

receiving support or consulting services, evaluating Software, performing beta testing or otherwise, any inventions, product improvements, modifications or developments made by Mentor Graphics (at Mentor Graphics sole discretion) will be the exclusive property of Mentor Graphics. 3. ESC SOFTWARE. If Customer purchases a license to use development or prototyping tools of Mentor Graphics Embedded Software Channel (ESC), Mentor Graphics grants to Customer a nontransferable, nonexclusive license to reproduce and distribute executable files created using ESC compilers, including the ESC run-time libraries distributed with ESC C and C++ compiler Software that are linked into a composite program as an integral part of Customers compiled computer program, provided that Customer distributes these files only in conjunction with Customers compiled computer program. Mentor Graphics does NOT grant Customer any right to duplicate, incorporate or embed copies of Mentor Graphics real-time operating systems or other embedded software products into Customers products or applications without first signing or otherwise agreeing to a separate agreement with Mentor Graphics for such purpose. BETA CODE. 4.1. Portions or all of certain Software may contain code for experimental testing and evaluation (Beta Code), which may not be used without Mentor Graphics explicit authorization. Upon Mentor Graphics authorization, Mentor Graphics grants to Customer a temporary, nontransferable, nonexclusive license for experimental use to test and evaluate the Beta Code without charge for a limited period of time specified by Mentor Graphics. This grant and Customers use of the Beta Code shall not be construed as marketing or offering to sell a license to the Beta Code, which Mentor Graphics may choose not to release commercially in any form. 4.2. If Mentor Graphics authorizes Customer to use the Beta Code, Customer agrees to evaluate and test the Beta Code under normal conditions as directed by Mentor Graphics. Customer will contact Mentor Graphics periodically during Customers use of the Beta Code to discuss any malfunctions or suggested improvements. Upon completion of Customers evaluation and testing, Customer will send to Mentor Graphics a written evaluation of the Beta Code, including its strengths, weaknesses and recommended improvements. 4.3. Customer agrees to maintain Beta Code in confidence and shall restrict access to the Beta Code, including the methods and concepts utilized therein, solely to those employees and Customer location(s) authorized by Mentor Graphics to perform beta testing. Customer agrees that any written evaluations and all inventions, product improvements, modifications or developments that Mentor Graphics conceived or made during or subsequent to this Agreement, including those based partly or wholly on Customers feedback, will be the exclusive property of Mentor Graphics. Mentor Graphics will have exclusive rights, title and interest in all such property. The provisions of this Subsection 4.3 shall survive termination of this Agreement. 5. RESTRICTIONS ON USE. 5.1. Customer may copy Software only as reasonably necessary to support the authorized use. Each copy must include all notices and legends embedded in Software and affixed to its medium and container as received from Mentor Graphics. All copies shall remain the property of Mentor Graphics or its licensors. Customer shall maintain a record of the number and primary location of all copies of Software, including copies merged with other software, and shall make those records available to Mentor Graphics upon request. Customer shall not make Products available in any form to any person other than Customers employees and on-site contractors, excluding Mentor Graphics competitors, whose job performance requires access and who are under obligations of confidentiality. Customer shall take appropriate action to protect the confidentiality of Products and ensure that any person permitted access does not disclose or use it except as permitted by this Agreement. Customer shall give Mentor Graphics written notice of any unauthorized disclosure or use of the Products as soon as Customer learns or becomes aware of such unauthorized disclosure or use. Except as otherwise permitted for purposes of interoperability as specified by applicable and mandatory local law, Customer shall not reverse-assemble, reverse-compile, reverse-engineer or in any way derive any source code from Software. Log files, data files, rule files and script files generated by or for the Software (collectively Files), including without limitation files containing Standard Verification Rule Format (SVRF) and Tcl Verification Format (TVF) which are Mentor Graphics proprietary syntaxes for expressing process rules, constitute or include confidential information of Mentor Graphics. Customer may share Files with third parties, excluding Mentor Graphics competitors, provided that the confidentiality of such Files is protected by written agreement at least as well as Customer protects other information of a similar nature or importance, but in any case with at least reasonable care. Customer may use Files containing SVRF or TVF only with Mentor Graphics products. Under no circumstances shall Customer use Software or Files or allow their use for the purpose of developing, enhancing or marketing any product that is in any way competitive with Software, or disclose to any third party the results of, or information pertaining to, any benchmark. 5.2. If any Software or portions thereof are provided in source code form, Customer will use the source code only to correct software errors and enhance or modify the Software for the authorized use. Customer shall not disclose or permit disclosure of source code, in whole or in part, including any of its methods or concepts, to anyone except Customers employees or contractors, excluding Mentor Graphics competitors, with a need to know. Customer shall not copy or compile source code in any manner except to support this authorized use. 5.3. Customer may not assign this Agreement or the rights and duties under it, or relocate, sublicense or otherwise transfer the Products, whether by operation of law or otherwise (Attempted Transfer), without Mentor Graphics prior written consent and payment of Mentor Graphics then-current applicable relocation and/or transfer fees. Any Attempted Transfer without Mentor Graphics prior written consent shall be a material breach of this Agreement and may, at Mentor Graphics option, result in the immediate termination of the Agreement and/or the licenses granted under this Agreement. The terms

4.

of this Agreement, including without limitation the licensing and assignment provisions, shall be binding upon Customers permitted successors in interest and assigns. 5.4. The provisions of this Section 5 shall survive the termination of this Agreement. 6. SUPPORT SERVICES. To the extent Customer purchases support services, Mentor Graphics will provide Customer updates and technical support for the Products, at the Customer site(s) for which support is purchased, in accordance with Mentor Graphics then current End-User Support Terms located at http://supportnet.mentor.com/about/legal/. AUTOMATIC CHECK FOR UPDATES; PRIVACY. Technological measures in Software may communicate with servers of Mentor Graphics or its contractors for the purpose of checking for and notifying the user of updates and to ensure that the Software in use is licensed in compliance with this Agreement. Mentor Graphics will not collect any personally identifiable data in this process and will not disclose any data collected to any third party without the prior written consent of Customer, except to Mentor Graphics outside attorneys or as may be required by a court of competent jurisdiction. LIMITED WARRANTY. 8.1. Mentor Graphics warrants that during the warranty period its standard, generally supported Products, when properly installed, will substantially conform to the functional specifications set forth in the applicable user manual. Mentor Graphics does not warrant that Products will meet Customers requirements or that operation of Products will be uninterrupted or error free. The warranty period is 90 days starting on the 15th day after delivery or upon installation, whichever first occurs. Customer must notify Mentor Graphics in writing of any nonconformity within the warranty period. For the avoidance of doubt, this warranty applies only to the initial shipment of Software under an Order and does not renew or reset, for example, with the delivery of (a) Software updates or (b) authorization codes or alternate Software under a transaction involving Software re-mix. This warranty shall not be valid if Products have been subject to misuse, unauthorized modification or improper installation. MENTOR GRAPHICS ENTIRE LIABILITY AND CUSTOMERS EXCLUSIVE REMEDY SHALL BE, AT MENTOR GRAPHICS OPTION, EITHER (A) REFUND OF THE PRICE PAID UPON RETURN OF THE PRODUCTS TO MENTOR GRAPHICS OR (B) MODIFICATION OR REPLACEMENT OF THE PRODUCTS THAT DO NOT MEET THIS LIMITED WARRANTY, PROVIDED CUSTOMER HAS OTHERWISE COMPLIED WITH THIS AGREEMENT. MENTOR GRAPHICS MAKES NO WARRANTIES WITH RESPECT TO: (A) SERVICES; (B) PRODUCTS PROVIDED AT NO CHARGE; OR (C) BETA CODE; ALL OF WHICH ARE PROVIDED AS IS. 8.2. THE WARRANTIES SET FORTH IN THIS SECTION 8 ARE EXCLUSIVE. NEITHER MENTOR GRAPHICS NOR ITS LICENSORS MAKE ANY OTHER WARRANTIES EXPRESS, IMPLIED OR STATUTORY, WITH RESPECT TO PRODUCTS PROVIDED UNDER THIS AGREEMENT. MENTOR GRAPHICS AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT OF INTELLECTUAL PROPERTY. 9. LIMITATION OF LIABILITY. EXCEPT WHERE THIS EXCLUSION OR RESTRICTION OF LIABILITY WOULD BE VOID OR INEFFECTIVE UNDER APPLICABLE LAW, IN NO EVENT SHALL MENTOR GRAPHICS OR ITS LICENSORS BE LIABLE FOR INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS) WHETHER BASED ON CONTRACT, TORT OR ANY OTHER LEGAL THEORY, EVEN IF MENTOR GRAPHICS OR ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO EVENT SHALL MENTOR GRAPHICS OR ITS LICENSORS LIABILITY UNDER THIS AGREEMENT EXCEED THE AMOUNT RECEIVED FROM CUSTOMER FOR THE HARDWARE, SOFTWARE LICENSE OR SERVICE GIVING RISE TO THE CLAIM. IN THE CASE WHERE NO AMOUNT WAS PAID, MENTOR GRAPHICS AND ITS LICENSORS SHALL HAVE NO LIABILITY FOR ANY DAMAGES WHATSOEVER. THE PROVISIONS OF THIS SECTION 9 SHALL SURVIVE THE TERMINATION OF THIS AGREEMENT.

7.

8.

10. HAZARDOUS APPLICATIONS. CUSTOMER ACKNOWLEDGES IT IS SOLELY RESPONSIBLE FOR TESTING ITS PRODUCTS USED IN APPLICATIONS WHERE THE FAILURE OR INACCURACY OF ITS PRODUCTS MIGHT RESULT IN DEATH OR PERSONAL INJURY (HAZARDOUS APPLICATIONS). NEITHER MENTOR GRAPHICS NOR ITS LICENSORS SHALL BE LIABLE FOR ANY DAMAGES RESULTING FROM OR IN CONNECTION WITH THE USE OF MENTOR GRAPHICS PRODUCTS IN OR FOR HAZARDOUS APPLICATIONS. THE PROVISIONS OF THIS SECTION 10 SHALL SURVIVE THE TERMINATION OF THIS AGREEMENT. 11. INDEMNIFICATION. CUSTOMER AGREES TO INDEMNIFY AND HOLD HARMLESS MENTOR GRAPHICS AND ITS LICENSORS FROM ANY CLAIMS, LOSS, COST, DAMAGE, EXPENSE OR LIABILITY, INCLUDING ATTORNEYS FEES, ARISING OUT OF OR IN CONNECTION WITH THE USE OF PRODUCTS AS DESCRIBED IN SECTION 10. THE PROVISIONS OF THIS SECTION 11 SHALL SURVIVE THE TERMINATION OF THIS AGREEMENT. 12. INFRINGEMENT. 12.1. Mentor Graphics will defend or settle, at its option and expense, any action brought against Customer in the United States, Canada, Japan, or member state of the European Union which alleges that any standard, generally supported Product acquired by Customer hereunder infringes a patent or copyright or misappropriates a trade secret in such jurisdiction. Mentor Graphics will pay costs and damages finally awarded against Customer that are attributable to the action. Customer understands and agrees that as conditions to Mentor Graphics obligations under this section Customer must: (a) notify Mentor Graphics promptly in writing of the action; (b) provide Mentor Graphics all reasonable information and assistance

to settle or defend the action; and (c) grant Mentor Graphics sole authority and control of the defense or settlement of the action. 12.2. If a claim is made under Subsection 12.1 Mentor Graphics may, at its option and expense, (a) replace or modify the Product so that it becomes noninfringing; (b) procure for Customer the right to continue using the Product; or (c) require the return of the Product and refund to Customer any purchase price or license fee paid, less a reasonable allowance for use. 12.3. Mentor Graphics has no liability to Customer if the action is based upon: (a) the combination of Software or hardware with any product not furnished by Mentor Graphics; (b) the modification of the Product other than by Mentor Graphics; (c) the use of other than a current unaltered release of Software; (d) the use of the Product as part of an infringing process; (e) a product that Customer makes, uses, or sells; (f) any Beta Code or Product provided at no charge; (g) any software provided by Mentor Graphics licensors who do not provide such indemnification to Mentor Graphics customers; or (h) infringement by Customer that is deemed willful. In the case of (h), Customer shall reimburse Mentor Graphics for its reasonable attorney fees and other costs related to the action. 12.4. THIS SECTION 12 IS SUBJECT TO SECTION 9 ABOVE AND STATES THE ENTIRE LIABILITY OF MENTOR GRAPHICS AND ITS LICENSORS FOR DEFENSE, SETTLEMENT AND DAMAGES, AND CUSTOMERS SOLE AND EXCLUSIVE REMEDY, WITH RESPECT TO ANY ALLEGED PATENT OR COPYRIGHT INFRINGEMENT OR TRADE SECRET MISAPPROPRIATION BY ANY PRODUCT PROVIDED UNDER THIS AGREEMENT. 13. TERMINATION AND EFFECT OF TERMINATION. If a Software license was provided for limited term use, such license will automatically terminate at the end of the authorized term. 13.1. Mentor Graphics may terminate this Agreement and/or any license granted under this Agreement immediately upon written notice if Customer: (a) exceeds the scope of the license or otherwise fails to comply with the licensing or confidentiality provisions of this Agreement, or (b) becomes insolvent, files a bankruptcy petition, institutes proceedings for liquidation or winding up or enters into an agreement to assign its assets for the benefit of creditors. For any other material breach of any provision of this Agreement, Mentor Graphics may terminate this Agreement and/or any license granted under this Agreement upon 30 days written notice if Customer fails to cure the breach within the 30 day notice period. Termination of this Agreement or any license granted hereunder will not affect Customers obligation to pay for Products shipped or licenses granted prior to the termination, which amounts shall be payable immediately upon the date of termination. 13.2. Upon termination of this Agreement, the rights and obligations of the parties shall cease except as expressly set forth in this Agreement. Upon termination, Customer shall ensure that all use of the affected Products ceases, and shall return hardware and either return to Mentor Graphics or destroy Software in Customers possession, including all copies and documentation, and certify in writing to Mentor Graphics within ten business days of the termination date that Customer no longer possesses any of the affected Products or copies of Software in any form. 14. EXPORT. The Products provided hereunder are subject to regulation by local laws and United States government agencies, which prohibit export or diversion of certain products and information about the products to certain countries and certain persons. Customer agrees that it will not export Products in any manner without first obtaining all necessary approval from appropriate local and United States government agencies. 15. U.S. GOVERNMENT LICENSE RIGHTS. Software was developed entirely at private expense. All Software is commercial computer software within the meaning of the applicable acquisition regulations. Accordingly, pursuant to US FAR 48 CFR 12.212 and DFAR 48 CFR 227.7202, use, duplication and disclosure of the Software by or for the U.S. Government or a U.S. Government subcontractor is subject solely to the terms and conditions set forth in this Agreement, except for provisions which are contrary to applicable mandatory federal laws. 16. THIRD PARTY BENEFICIARY. Mentor Graphics Corporation, Mentor Graphics (Ireland) Limited, Microsoft Corporation and other licensors may be third party beneficiaries of this Agreement with the right to enforce the obligations set forth herein. 17. REVIEW OF LICENSE USAGE. Customer will monitor the access to and use of Software. With prior written notice and during Customers normal business hours, Mentor Graphics may engage an internationally recognized accounting firm to review Customers software monitoring system and records deemed relevant by the internationally recognized accounting firm to confirm Customers compliance with the terms of this Agreement or U.S. or other local export laws. Such review may include FLEXlm or FLEXnet (or successor product) report log files that Customer shall capture and provide at Mentor Graphics request. Customer shall make records available in electronic format and shall fully cooperate with data gathering to support the license review. Mentor Graphics shall bear the expense of any such review unless a material non-compliance is revealed. Mentor Graphics shall treat as confidential information all information gained as a result of any request or review and shall only use or disclose such information as required by law or to enforce its rights under this Agreement. The provisions of this Section 17 shall survive the termination of this Agreement. 18. CONTROLLING LAW, JURISDICTION AND DISPUTE RESOLUTION. The owners of certain Mentor Graphics intellectual property licensed under this Agreement are located in Ireland and the United States. To promote consistency around the world, disputes shall be resolved as follows: excluding conflict of laws rules, this Agreement shall be governed by and construed under the laws of the State of Oregon, USA, if Customer is located in North or South America, and the laws of Ireland if Customer is located outside of North or South America. All disputes arising out of or in relation to this Agreement shall be submitted to the exclusive jurisdiction of the courts of Portland, Oregon when the laws of Oregon apply, or Dublin, Ireland when the laws of Ireland apply. Notwithstanding the foregoing, all disputes in Asia arising out of or in relation to this Agreement shall be resolved by arbitration in Singapore before a single arbitrator to be appointed by the chairman of the Singapore International

Arbitration Centre (SIAC) to be conducted in the English language, in accordance with the Arbitration Rules of the SIAC in effect at the time of the dispute, which rules are deemed to be incorporated by reference in this section. This section shall not restrict Mentor Graphics right to bring an action against Customer in the jurisdiction where Customers place of business is located. The United Nations Convention on Contracts for the International Sale of Goods does not apply to this Agreement. 19. SEVERABILITY. If any provision of this Agreement is held by a court of competent jurisdiction to be void, invalid, unenforceable or illegal, such provision shall be severed from this Agreement and the remaining provisions will remain in full force and effect. 20. MISCELLANEOUS. This Agreement contains the parties entire understanding relating to its subject matter and supersedes all prior or contemporaneous agreements, including but not limited to any purchase order terms and conditions. Some Software may contain code distributed under a third party license agreement that may provide additional rights to Customer. Please see the applicable Software documentation for details. This Agreement may only be modified in writing by authorized representatives of the parties. Waiver of terms or excuse of breach must be in writing and shall not constitute subsequent consent, waiver or excuse.

Rev. 100615, Part No. 246066

You might also like