PrecisionRTL Style
PrecisionRTL Style
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
14
15
15
15
17
19
20
21
21
23
24
24
24
27
28
29
30
30
31
31
32
32
32
33
33
33
34
34
35
37
39
39
41
42
42
43
43
43
44
45
Table of Contents
46
48
48
49
51
53
54
54
55
55
56
57
59
60
60
61
Chapter 2
Verilog Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
macromodule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Numbers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Net Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Register Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Parameter Data Type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Continuous Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Net Declaration Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
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. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
66
66
67
68
69
70
70
71
71
72
72
73
75
75
77
77
77
78
78
82
82
83
83
84
86
89
90
91
91
Table of Contents
Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Inout Ports in Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Access of Global Variables from Functions and Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
System Task Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
System Function Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Initial Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Compiler Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Verilog Issues and Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Comparing With X and Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Variable Indexing of Bit Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Synthesis Directives. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
parallel_case and full_case directives. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
translate_off and translate_on directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
attribute directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Syntax and Semantic Restrictions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Verilog 2001 Support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Supported Verilog 2001 Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Detailed Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Chapter 3
SystemVerilog Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SystemVerilog Support in Precision. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Reading SystemVerilog files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Compilation Unit Scope Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Introduction to SystemVerilog for
Design and Synthesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Literal Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Data Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Attributes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Operators and Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Procedural Statements and Control flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tasks and Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Hierarchy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Compiler Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SystemVerilog Example Designs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
115
116
118
123
126
126
126
127
131
132
134
135
138
138
Chapter 4
Inferring Arithmetic and Relational Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
VHDL/Verilog Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Optimization Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Resource Sharing and Common Subexpression Elimination . . . . . . . . . . . . . . . . . . . . . . .
Reducing Counter Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
155
155
155
156
156
157
107
107
110
111
Table of Contents
158
158
160
161
162
163
164
165
166
167
168
169
170
173
174
Chapter 5
Boolean Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
VHDL/Verilog Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Optimization Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Unintended Combinatorial Loops (Latches). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using Variables before they are assigned. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
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. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
175
175
175
175
175
178
178
179
180
181
182
183
184
185
186
187
188
189
190
Chapter 6
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
191
191
191
191
192
192
192
193
193
193
Table of Contents
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 . . . . . . . . . . . . .
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. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
193
194
195
195
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
226
227
228
229
230
231
Chapter 7
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
233
233
233
233
233
234
234
234
236
242
Table of Contents
242
242
243
249
249
250
250
250
251
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
273
Chapter 8
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
277
277
278
279
280
281
282
282
283
283
289
289
290
291
292
295
298
Chapter 9
DSP Blocks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Common Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Table of Contents
301
301
302
303
304
305
306
307
309
311
313
315
318
Chapter 10
Exemplar VHDL Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The Exemplar Packages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Predefined Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Predefined Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Predefined Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Predefined Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Interfacing With Other VHDL Tools. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Performing Post-layout Functional Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Working with the Synopsys Package. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
323
323
324
324
325
329
331
331
332
Index
End-User License Agreement
List of Examples
Example 2-1. Verilog Defparm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Example 3-1. SystemVerilog ALU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Example 3-2. SystemVerilog Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Example 3-3. SystemVerilog FSM 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Example 3-4. SystemVerilog FSM 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Example 3-5. SystemVerilog FSM 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Example 3-6. SystemVerilog FSM Reencoded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Example 3-7. SystemVerilog Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Example 5-1. VHDL Bi-Directional Bus. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Example 5-2. Verilog Bi-Directional Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Example 8-1. VHDL Safe Finite State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
Example 8-2. Verilog Safe Finite State Machine with Default Clause . . . . . . . . . . . . . . . . . 286
Example 8-3. Verilog Safe Finite State Machine with an unreachable state and without Default
Clause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
Example 8-4. VHDL Three Process FSM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
Example 8-5. Verilog Three Process FSM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Example 8-6. VHDL Moore State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Example 8-7. Verilog Moore State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Example 8-8. VHDL Mealy State Machine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Example 8-9. Verilog Mealy State Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Example 9-1. Verilog DSP MULT-ADD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Example 9-2. VHDL DSP MULT-ADD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Example 9-3. Verilog DSP MULT-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
Example 9-4. VHDL DSP MULT-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
Example 9-5. Verilog DSP MULT-ACC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
Example 9-6. VHDL DSP MULT-ACC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Example 9-7. Verilog DSP MULT-ACC-ADDSUB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Example 9-8. VHDL DSP MULT-ACC-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Example 9-9. Verilog Fully Pipelined 35x18 Multiplier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Example 9-10. VHDL Fully Pipelined 35x18 Multiplier . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Example 9-11. Verilog DSP48 Instantiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Example 9-12. VHDL DSP48 Instantiation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
10
List of Figures
Figure 3-1. SystemVerilog File Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 7-1. Asynchronous ROM Mapped into Block RAM . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 7-2. How to Set rom_block Attribute in VHDL. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 7-3. How to Set rom_block Attribute in Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 7-4. VHDL ROM Implemented Using CASE Statement. . . . . . . . . . . . . . . . . . . . . .
Figure 7-5. VHDL ROM Implement Using Array of Constants . . . . . . . . . . . . . . . . . . . . . .
Figure 7-6. VHDL Memory Initialization Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 7-7. Verilog ROM Using CASE Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 7-8. Verilog ROM Using Array of Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 7-9. Verilog ROM Initialization Using $readmemh Function . . . . . . . . . . . . . . . . . .
Figure 7-10. Verilog ROM Initialization Using $readmemb Function . . . . . . . . . . . . . . . . .
Figure 8-1. Setting FSM encoding Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 9-1. Adding dedicated_mult via the GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 9-2. DSP MULT-ADD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 9-3. DSP MULT-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 9-4. DSP MULT-ACC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 9-5. DSP MULT-ACC-ADDSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 9-6. 35x18 Multiplier Implemented in 18-bit Blocks. . . . . . . . . . . . . . . . . . . . . . . . .
Figure 9-7. Partial Products used to Build 35x18 Mult . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
110
235
235
236
236
237
238
239
240
241
241
281
302
307
309
311
313
315
315
11
List of Tables
Table 2-1. Operators Supported by Precision RTL Synthesis . . . . . . . . . . . . . . . . . . . . . . .
Table 3-1. Supported SystemVerilog Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 3-2. SystemVerilog Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 4-1. VHDL and Verilog Operator Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 4-2. Arithmetic Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 5-1. VHDL and Verilog Boolean Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 5-2. Boolean Logic Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 6-1. Register Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 7-1. Supported Byte-Enable Device Families . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 7-2. Memory Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 8-1. FSM Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 9-1. DSP Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table 10-1. Exemplar Package Attributes Recognized by the VHDL Parser . . . . . . . . . . .
12
79
107
138
155
158
175
179
195
242
251
289
306
324
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.
13
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:
14
Configuration
Processes
Precision Synthesis Style Guide, 2010a Update1
July 2010
Note
Precision RTL Synthesis supports all IEEE 1076-1993 synthesizable features.
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.
15
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;
16
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
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.
17
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;
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,
18
retains its value. In synthesis terms, this translates into a D-flipflop, clocked on wrclk,
and enabled by ce.
intreg
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:
B0010_0001 X5F
Decimal Literals:
27
Based Literals:
2#1001#
Physical Literals:
2 ns
Identifiers:
Idle TeSTing
a % #
-5 4E3
76_562
8#65_07"
5.0 V
O63_07
4.25
14#C5#E+2
15 pF
a
true_story
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.
19
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:
20
Enumerated types.
Integer types
Floating-point types
Physical types
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 ;
21
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.
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)
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 ;
22
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 ;
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.
23
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.
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.
24
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)
is the name of the right most element in array v. Its value is the bit literal 1.
seven(7)
is the name of the left most element in array v. Its value is the bit literal 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.
25
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.
26
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 a dot (.) and the element name:
my_birthday.year selects the year field out of my_birthday and returns the integer value 1993.
27
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) ;
28
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.
29
Precision RTL Synthesis also understands the predefined types CHARACTER, STRING,
SEVERITY_LEVEL, TIME, REAL and FILE.
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.
30
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.
31
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 ;
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.
32
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
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, 2010a Update1
July 2010
33
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 ;
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.
34
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 282 and How Precision Implements a Safe
FSM on page 283.
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
35
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
36
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 ;
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
37
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 ;
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.
38
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 ;
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):
=
<=
/=
>
<
>=
NOR
OR
XOR
NAND
NOT
39
mod
rem
abs
/
**
Concatenation of elements into an array of elements:
&
(,,,,)
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.
40
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) ;
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.
41
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.
42
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.
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
43
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) ;
44
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.
45
46
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 ;
47
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 ;
48
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.
49
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 ;
50
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 ;
51
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 ;
52
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.
53
54
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.
55
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.
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.
56
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 ;
...
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.
57
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;
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.
58
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 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
59
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:
60
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.
Global, non-constant signals, that is, signals declared in a package, are supported. The
following limitations apply to such signals.
o
Allocators are not supported, because they perform dynamic allocation of resources,
which is not synthesizable.
after
Loop restrictions
clause ignored.
61
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.
-----
Leading
Falling
Falling
Leading
edge
edge
edge
edge
of
of
of
of
clk
clk
clk
(boolean) clk
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
62
allows free usage of the clock edge conditions, either in guarded blocks, processes or
subprograms.
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.
63
64
Chapter 2
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:
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.
65
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.
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:
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.
66
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
Prefix
Legal Characters
binary
01xXzZ_?
octal
0-7xXzZ_?
decimal
0-9_
hexcadecimal
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.
x, X
Unknown value.
z, Z, ?
Tri-state value.
Examples:
334
32b101
3b11
20hf_ffff
10bZ
67
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 (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
68
// 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
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).
69
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 ;
70
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.
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, 2010a Update1
July 2010
71
?
?
?
?
intreg[0]
intreg[1]
intreg[2]
intreg[3]
:
:
:
:
1bZ
1bZ
1bZ
1bZ
,
,
,
;
endmodule
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.
72
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
=
=
=
=
intreg[0];
intreg[1];
intreg[2];
intreg[3];
endmodule
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.
73
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
.........
.........
74
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.
75
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;
//
.we(load),
.we(load),
.we(load),
.we(load),
.o(data[0])
.o(data[1])
.o(data[2])
.o(data[3])
);
);
);
);
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());
76
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 2-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
77
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
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
...
78
The operators supported by Precision RTL Synthesis are listed in Table 2-1.
Table 2-1. Operators Supported by Precision RTL Synthesis
Operator
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
^~ 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.
79
>
<=
>=
==
!=
If the bit value of any operand is X (unknown), then the entire resulting value is X.
===
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.
===
Logical Operators
Precision RTL Synthesis supports the following logical operators:
!
80
&&
||
Bit-Wise Operators
Precision RTL Synthesis supports the following bit_wise operators:
~
&
^~
~^
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:
~&
~|
~^
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
81
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]} ;
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
82
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
83
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
84
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
85
+ !s[0] * s[1] * b;
+ 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.
86
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
87
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
88
Note
For additional information on the handling of default statements during optimization,
see Advanced FSM Optimization on page 282 and How Precision Implements a Safe
FSM on page 283.
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] ;
...
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.
for
89
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
90
If any loop construct is NOT bound by constants or by clock events, then Precision RTL
Synthesis issues the iteration limit reached error.
91
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);
92
Tasks
Tasks are always displayed as statements:
my_task(a,b,c,d);
93
always @ (i)
begin
r = i;
T (r, o1); // o1 = i, r = ~i
o2 = r;
// o2 = ~i;
end
endmodule
94
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
95
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.
96
Synthesis Directives
Verilog pragmas are also called synthesis directives.
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.
97
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>
//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
UDP
specify
real
initial
time
The following gates: pulldown, pullup, nmos, mmos, pmos, rpmos, cmos,
primitives
block
data type
98
wait
statements
force
release
Named port specification (not to be confused with passing arguments by name, which
is supported)
Edge triggers on sensitivity list must be single bit variable, or array indexing expression.
vectored declaration
statement
statement
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
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.
99
Power Operator
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;
100
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;
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.
101
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.
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.
103
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 (...);
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]: ...
104
105
106
Chapter 3
SystemVerilog Language Features
This section describes the supported SystemVerilog constructs in Precision as well as an
introduction to the key features in the new language extension.
SystemVerilog Construct
Literal Values
3.3
3.6
String literals
3.7
Array literals
3.8
Structure literals
Data Types
4.3
4.5
4.9
User-defined types
4.10
Enumerations
4.11
4.13
4.14
Casting
4.16
Bit-stream casting
4.17
Arrays
5.2
5.3
Multiple dimensions
107
5.5
5.7
Array assignment
5.8
Arrays as arguments
Data Declarations
6.3
Constants
6.4
Variables
6.5
Nets
6.6
6.7
6.8
Signal aliasing
6.9
Type compatibility
Assignment operators
8.4
8.5
8.7
Size
8.8
Sign
8.9
8.10
Buit-in Methods
8.11
Static Prefixes
8.12
Concatenation
8.13
Assignment patterns
8.15
Aggregate expressions
Procedural Statements
108
10.3
10.4
Selection statements
10.5
10.6
Jump statements
10.8
10.10
Event control
Precision Synthesis Style Guide, 2010a Update1
July 2010
Combinational logic
11.3
Latched logic
11.4
Sequential logic
11.5
Continuous assignments
Tasks
12.3
Functions
12.4
12.5
Hierarchy
19.2
Packages
19.3
19.5
Module declarations
19.8
19.11
Module instances
19.12
Interfaces
20.3
Ports in interfaces
20.4
Modports
20.6
20.7
Parameterized interfaces
20.9
22.7
Compiler Directives
23.2
`define macros
23.3
`include
109
110
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 112.
In Compilation Unit Scope Example 1 on page 111 and Compilation Unit Scope Example 2
on page 112, the typedef declaration T can be made visible in module "middle" (file named
middle.sv) using the -all_file_cunit_scope=true option.
111
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
T out;
endmodule
112
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.
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
113
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.
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;
typedef int T;
endpackage
114
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.
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.
115
Literal Values
SystemVerilog supported literal value types include:
Integer
Logic
Real
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
Prefix
Legal Characters
binary
01xXzZ_?
octal
0-7xXzZ_?
decimal
0-9_
hexcadecimal
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.
Special characters in numbers:
116
x, X
Unknown value.
z, Z, ?
Tri-state value.
Examples
334
32b101
3b011
20hf_ffff
10bZ
=
=
=
=
=
=
//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
begin
........
........
end
endmodule
117
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:
Void
Enumerations
Chandle
String
Event
Union (unpacked)
Tagged Union
Class
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>]
118
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 (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
// 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
119
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;
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)
120
Example
reg a = 1bz;
Integer
integer (4-state Verilog-2001 data type,32 bit signed integer)
Example
integer a = -10;
my_bit;
endmodule
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]
Example
typedef enum bit [2:0]{A, B, C, D, E, F} type_enum;
type_enum var_enum;
Example
struct packed{
logic field0;
int field1;
bit [7:0] field2;
121
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;
Casting
int(2.0 * 3.0);
shortint{8hFA,8hCE};
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
122
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
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
Example
logic [1:0][2:0][3:0] l1;
bit [5:0][3:0]b1;
123
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.
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
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
124
//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;
error
end
..........
..........
endmodule
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.
Example
int
int
int
A =
A =
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 same type and dimension
//out = argfunc(temp1); //error incompatible size
//out = argfunc(temp2); //error incompatible dimension
125
endmodule
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;
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.
Example
int a;
a += 2;
a *= 3;
a--;
126
// a = a + 2;
// a = a * 3;
// a = a - 1;
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
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
127
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);
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
128
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;
129
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
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
130
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;
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
131
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
Task
Example
module taskfunc(input int in1,in2,input bit clk,output int out1,out2);
132
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];
end
endfunction
endmodule
Void Functions
Return value of functions can be ignored by casting the function to void type.
void(some_function());
133
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
134
Note
Precision Synthesis does not support port as a declaration of an event.
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
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.
135
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;
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;
136
raddr;
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
137
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.
Description
ALU
Counter
FSM 1
FSM 2
138
Description
FSM 3
This design shows how typedef enum, union, unique case, and
always_ff are used an arbiter design.
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.
Interface
139
ALU
This design is a generic ALU design utilizing these SystemVerilog constructs: struct, union,
always_comb, typedef, priority case.
Example 3-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,
140
+ 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 3-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
141
142
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 3-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,
143
[7:0] key;
[7:0] temprary;
[7:0] decoded;
144
(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
key
key
key
=
=
=
=
{7{current_state[3]}};
{7{current_state[3]}};
{7{current_state[3]}};
8b0;
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 3-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,
145
current_state;
(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;
end
endmodule
//======================================
module decoder (input bit [7:0] in,
input bit [3:0] current_state,
output bit [7:0] out_decoded);
146
bit
bit
[7:0] key;
[7:0] decoded;
(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;
FSM 3
This design shows how typedef enum, union, unique case, and always_ff are used an arbiter
design.
Example 3-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
147
clock, reset,
logic req_0, req_1,
logic gnt_0, gnt_1);
148
IDLE;
next_state;
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
149
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 3-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
150
151
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 3-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
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;
152
data.data_out = latch;
raddr;
waddr;
wdata;
rdata;
rdata;
// Instantiate interfaces
address_bus #(.p1(p1)) addr();
data_bus
#(.p2(p2)) data();
control_bus
ctrl();
// Instantiate memory module
153
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
154
Chapter 4
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 4-1. VHDL and Verilog Operator Differences
Arithmetic Operators
Operation
VHDL
Relational Operators
Verilog
Operation
VHDL
Verilog
Addition
Equality
==
Subtraction
Inequality
/=
!=
Multiplication
Lass Than
<
<
Division
Less Than or
Equal To
<=
<=
Exponential
**
N/A
Greater Than
>
>
155
VHDL
Relational Operators
Verilog
Modulus
mod
Remainder
rem
N/A
Absolute Value
abs
N/A
Operation
Greater Than or
Equal To
VHDL
>=
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.
156
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 ;
...
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.
157
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.
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:
Description
Up Counter
Counter that counts up on each positive clock edge, and rolls over to
zero when it reaches 256.
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.
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.
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.
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.
Down Counter
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
158
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.
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.
Adder / Subtractor
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
Pipelined Multiplier
159
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;
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
y <= cnt;
END ARCHITECTURE;
160
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
161
162
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
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
163
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
y <= count;
END PROCESS;
END ARCHITECTURE;
164
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;
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
y <= cnt;
END ARCHITECTURE;
165
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;
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
y <= cnt;
END ARCHITECTURE;
166
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
167
168
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
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));
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;
END ENTITY;
endmodule
ARCHITECTURE rtl OF addsub IS
BEGIN
add <= a + b;
sub <= c - d;
inc <= e + 1;
dec <= f - 1;
END ARCHITECTURE;
169
170
171
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
172
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
173
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;
174
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
Chapter 5
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 5-1. VHDL and Verilog Boolean Operators
Boolean Operator
VHDL
Verilog
AND
and
&& (logical)
OR
or
|| (logical)
XOR
xor
NOT
not
! (logical)
NAND
nand
no explicit operator
NOR
nor
no explicit operator
XNOR
xnor
~^ or ^~ (bitwise)
^ (logical)
& (bitwise)
| (bitwise)
^ (bitwise)
~ (bitwise)
Optimization Issues
The following subsections describe some of the optimization issues that may be encountered
when inferring boolean logic.
175
Boolean Logic
Optimization Issues
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
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!
176
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 =>
next_state <= state3;curr_state(1)
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.
177
Boolean Logic
Attributes Relating to Boolean Logic
ACTUAL RESULT
DESIRED RESULT
+1
0
Count_old
+1
1
Clock
Reset
Count_old
Clock
Reset
178
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.
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
Description
Basic Gates
Tri-State
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) three-state drivers.
Bi-Directional Bus
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.
Seven Segment
Decoder
Priority Encoder
Multiplexer
Parallel Mux
Serial Mux
179
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;
180
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
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;
endmodule
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 ;
Verilog
module tristate (a, en, y);
input a, en;
output y;
assign y = en ? a : 1bZ;
endmodule
181
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 ;
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
182
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.
183
Boolean Logic
Generic Width Decoder
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;
184
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
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:
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.
185
Boolean Logic
Seven Segment Decoder
VHDL
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
Verilog
module seven_seg_dec (a, y);
input [3:0] a;
output [6:0] y;
ENTITY seven_seg_dec IS
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;
186
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
7b 1111110;
7b 0100000;
7b 1101101;
7b 1111001;
7b 0110011;
7b 1011011;
7b 1011111;
7b 1110000;
7b 1111111;
7b 1111011;
: y =
7b 1111110;
endcase
endmodule
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
187
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;
188
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
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
189
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;
190
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
Chapter 6
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.
191
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.
192
Registers
VHDL / Verilog Differences
until
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.
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
193
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:
194
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.
Registers
Attributes That Affect Registers
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
Description
D Latch
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
Generic N-bit register with a clock and a clock enable signal, but no
set or reset signal.
D Flip Flop
195
Registers
Register Examples
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 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.
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.
196
Registers
Register Examples
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 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 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.
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.
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.
Gated Clock
Conversion-OR
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.
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.
197
Registers
Register Examples
Description
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.
Asynchronous Right
Shifter
Synchronous Right
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.
Bi-Directional Shifter This is identical to the right shifter, except that is can shift either right
or left.
Right Logical Shifter
198
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
Verilog
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
reg q;
always @ (d)
if (en)
q = d;
endmodule
PROCESS (d)
BEGIN
IF (en = 1) THEN
q <= d;
END IF;
END PROCESS;
END ARCHITECTURE;
199
Registers
D Latch with Asynchronous Set and Reset
VHDL
Verilog
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;
200
reg q;
always @ (d or reset or set)
if (reset)
q = 0;
else if (set)
q = 1;
else if (en)
q = d;
endmodule
Registers
Generic N-Bit Register with Enable
VHDL
Verilog
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 ;
201
Registers
D Flip Flop
D Flip Flop
Basic D Flip Flop with no clock enable, set, or reset signals.
VHDL
Verilog
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY dff IS
PORT(clk, d : IN STD_LOGIC;
q : OUT STD_LOGIC);
END ENTITY ;
202
Registers
D Flip Flop with Enable
VHDL
Verilog
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;
203
Registers
D Flip Flop with Synchronous Reset
VHDL
Verilog
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;
204
Registers
D Flip Flop with Asynchronous Reset
VHDL
Verilog
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;
205
Registers
D Flip Flop with Synchronous Set
VHDL
Verilog
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;
206
Registers
D Flip Flop with Asynchronous Set
VHDL
Verilog
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;
207
Registers
D Flip Flop with Enable and Synchronous Reset
VHDL
Verilog
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;
208
Registers
D Flip Flop with Enable and Asynchronous Reset
VHDL
Verilog
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;
209
Registers
D Flip Flop with Enable and Synchronous Set
VHDL
Verilog
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;
210
Registers
D Flip Flop with Enable and Asynchronous Set
VHDL
Verilog
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;
211
Registers
D Flip Flop with Synchronous Reset and Set
VHDL
Verilog
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;
212
Registers
D Flip Flop with Asynchronous Reset and Set
VHDL
Verilog
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;
213
Registers
D Flip Flop with Enable and Synchronous Reset and Set
VHDL
Verilog
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;
214
Registers
D Flip Flop with Enable and Asynchronous Reset and Set
VHDL
Verilog
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;
215
Registers
D Flip Flop with Asynchronous Reset and Synchronous Set
VHDL
Verilog
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;
216
Registers
D Flip Flop with Enable and Asynchronous Reset and Synchronous Set
VHDL
Verilog
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;
217
Registers
D Flip Flop with Synchronous Reset and Asynchronous Set
VHDL
Verilog
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;
218
Registers
D Flip Flop with Enable and Synchronous Reset and Asynchronous Set
VHDL
Verilog
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;
219
Registers
Gated Clock Conversion-AND
RTL
Optimized
3. synthesize
For additional information on gated clock
conversion, see the Constraining and
Synthesizing chapter of the Precision RTL Synthesis Users Manual.
VHDL
Verilog
//
//
//
//
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;
220
input
input
output
reg
clk, gate;
din;
dout;
dout;
wire
assign
gate_1;
gate_1 = clk & gate;
Registers
Gated Clock Conversion-NAND
RTL
Optimized
3. synthesize
For additional information on gated
clock conversion, see the Constraining
and Synthesizing chapter of the Precision RTL Synthesis Users Manual.
VHDL
Verilog
//
//
//
//
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;
input
input
output
reg
clk, gate;
din;
dout;
dout;
wire
assign
gate_1;
gate_1 = ~(clk & gate);
221
Registers
Gated Clock Conversion-OR
RTL
Optimized
3. synthesize
For additional information on gated
clock conversion, see the Constraining and Synthesizing chapter of the Precision RTL Synthesis
Users Manual.
VHDL
Verilog
//
//
//
//
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;
222
input
input
output
reg
clk, gate;
din;
dout;
dout;
wire
assign
gate_1;
gate_1 = clk | gate;
Registers
Gated Clock Conversion-NOR
RTL
3. synthesize
For additional information on gated
clock conversion, see the Constraining
and Synthesizing chapter of the Precision RTL Synthesis Users Manual.
VHDL
Verilog
//
//
//
//
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;
input
input
output
reg
clk, gate;
din;
dout;
dout;
wire
assign
gate_1;
gate_1 = ~(clk | gate);
223
Registers
Gated Clock Conversion-Cascaded Clocks
RTL
Optimized
224
Registers
Gated Clock Conversion-Cascaded Clocks
VHDL
Verilog
-----------
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
module cascaded_gated_clk (
clk, gate, din, dout);
input
input
output
reg
clk;
[3:1] gate, din;
[3:1] dout;
[3:1] dout;
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;
225
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
Verilog
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;
226
Registers
Asynchronous Right Shifter
VHDL
Verilog
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;
227
Registers
Synchronous Right Shifter
VHDL
Verilog
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;
228
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
Verilog
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;
229
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
Verilog
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;
230
Registers
Right Logical Shifter
Verilog
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
endmodule
231
Registers
Right Logical Shifter
232
Chapter 7
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.
233
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.
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
234
Memory
Common Guidelines
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 7-1.
235
Memory
Common Guidelines
236
mem
mem
mem
mem
mem
mem
mem
<=
<=
<=
<=
<=
<=
<=
"1111101100110100";
"0000101011011110";
"1101110110101000";
"1101110111010110";
"0111101000000010";
"0011110000111010";
"0110101010111000";
Memory
Common Guidelines
237
Memory
Common Guidelines
) ;
238
Memory
Common Guidelines
239
Memory
Common Guidelines
240
Memory
Common Guidelines
dd ]
241
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
Device Family
Stratix II
Altera
Stratix III
Stratix IV
Virtex-4
Xilinx
Virtex-5
Virtex-6
242
Memory
Common Guidelines
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
Read-First or Write-First
Write mode determines the behavior of the data available on the output after a write
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
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.
243
Memory
Common Guidelines
244
Memory
Common Guidelines
else if(byteena[1]) mem[addr][15:8] = din[15:8];
end
endmodule
=
=
=
=
din[7:0];
din[15:8];
din[23:16];
din[31:24];
245
Memory
Common Guidelines
246
Memory
Common Guidelines
247
Memory
Common Guidelines
248
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
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.
249
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.
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.
250
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.
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.
Memory
Memory Coding Examples
Description
Synchronous RAM
example source file: ram_synch
Asynchronous RAM
example source file: ram_asynch
ram_reset2.v
251
Memory
Memory Coding Examples
252
Example
Description
ROM
example source file: rom_sin
Synchronous ROM
example source file: rom_to_blockram
Memory
Synchronous RAM
Synchronous RAM
RAM with synchronous data input, data output and address lines.
VHDL
Verilog
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);
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
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;
endmodule
END ARCHITECTURE ;
253
Memory
RAM with Synchronous Input
Verilog
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 ;
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
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;
254
Memory
RAM with Synchronous Output
Verilog
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 ;
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
255
Memory
RAM with Synchronous Address
Verilog
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 ;
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
256
Memory
RAM with Synchronous Input/Output
Verilog
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;
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
257
Memory
Asynchronous RAM
Asynchronous RAM
RAM with asynchronous data input, data output and address lines.
VHDL
Verilog
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 ;
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
258
Memory
Synchronous I/O RAM
Verilog
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;
parameter d_width = 4;
parameter a_width = 4;
input [a_width-1:0] address;
input wr_en, read_en, inclock,
outclock;
259
Memory
I/O RAM with Synchronous Input
Verilog
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);
PORT (data
: 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;
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
260
Memory
I/O RAM with Synchronous Output
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
261
Memory
I/O RAM with Synchronous Address
Verilog
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);
IF (wr_en = 1) THEN
mem(TO_INTEGER(address)) <= data ;
END IF ;
BEGIN
addr_clock);
parameter d_width = 4;
parameter a_width = 4;
data)
if (wr_en)
mem[address] <= data;
assign data = read_en ? mem
[add_save]:bz;
endmodule
END ARCHITECTURE ;
262
Memory
I/O RAM with Synchronous Input/Output
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
263
Memory
I/O Asynchronous RAM
264
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
Memory
Dual Port RAM
Verilog
module ram_dualport
(write_clock,
wea,
read_clock,
data_in,
addr_write,
addr_read,
data_out);
input write_clock,
wea,
read_clock;
always @(posedge
write_clock)
if (wea)
mem[addr_write] <=
data_in;
always @(posedge
read_clock)
data_out <= mem
[addr_read];
endmodule
265
Memory
Resets for Memory
define WIDTH_A 9
define WIDTH_D 4
define RAM_DEPTH 256
define WIDTH_A 8
define WIDTH_D 4
define RAM_DEPTH 256
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
266
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 251.
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;
267
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
268
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;
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;
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
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;
END ARCHITECTURE;
269
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 251.
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 :
270
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;
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;
271
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
272
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
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;
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 251.
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;
273
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;
274
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 251.
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;
275
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
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
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;
endmodule
276
Chapter 8
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)
A clock specification
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.
277
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).
278
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.
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
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
279
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.
280
From the GUI menu selection Tool -> Set Options...Input dialog box
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.
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.
281
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.
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.
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.
282
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 8-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"
283
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 8-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"
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 8-3 on
page 287.
operation can be selected either from the GUI, as shown in Example 8-1, or by using
attributes in the code. Alternatively the boolean attribute save_fsm can be applied to the
enumerated type.
Safe FSM
284
285
Example 8-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
286
Example 8-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
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:
287
288
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
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
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
Example 8-1
Example 8-2
Example 8-3
289
Verilog
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;
290
Verilog
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;
291
292
THEN
<= s1;
<= s0;
THEN
<= s2;
<= s0;
THEN
<= s3;
<= s0;
s0;
2b01;
2b00;
2b10;
2b00;
2b11;
293
294
295
296
end
end
end
end
end
end
297
298
299
300
Chapter 9
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
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)
MULT
MULT-ACC
MULT-ADD
MULT-ADDSUB
MULT-ACC-ADDSUB
301
DSP Blocks
Common Guidelines
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
If you prefer to use the GUI, right-click on a multiplier operator and choose Use Dedicated
from the popup menu.
Multiplier -> ON
302
DSP Blocks
Common Guidelines
signed[sub_in_width-1:0]
signed[sub_in_width-1:0]
clk;
a;
b;
303
DSP Blocks
Common Guidelines
304
DSP Blocks
Attributes Relating to DSP Blocks
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*]
305
DSP Blocks
DSP Code Examples
Description
MULT-ADD
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
306
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 9-2. DSP MULT-ADD
signed[sub_in_width-1:0]
signed[sub_in_width-1:0]
signed[sub_out_width-1:0]
clk, load;
dataa;
datab;
datac;
mult0_result;
reg_dataa;
reg_datab;
reg_datab1;
reg_datac;
preg;
result;
307
DSP Blocks
MULT-ADD
308
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 9-3. DSP MULT-ADDSUB
signed[sub_in_width-1:0] dataa;
signed[sub_in_width-1:0] datab;
signed[sub_out_width-1:0] datac;
clk, load;
output
reg
reg
reg
reg
reg
wire
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;
309
DSP Blocks
MULT-ADDSUB
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)
;
;
;
;
310
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 9-4. DSP MULT-ACC
signed[sub_in_width-1:0]
signed[sub_in_width-1:0]
clk;
a;
b;
311
DSP Blocks
MULT-ACC
IN
IN
IN
OUT
: integer := 9;
: integer := 18);
312
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 9-5. DSP MULT-ACC-ADDSUB
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;
313
DSP Blocks
MULT-ACC-ADDSUB
314
DSP Blocks
Fully Pipelined 35x18 Multiplier
315
DSP Blocks
Fully Pipelined 35x18 Multiplier
clk;
signed[sub_in_width_a-1:0] a;
signed[sub_in_width_b-1:0] b;
signed[sub_out_width-1:0] preg;
//a,b,
reg
reg
reg
reg_a;
reg_b;
reg_preg;
316
DSP Blocks
Fully Pipelined 35x18 Multiplier
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;
317
DSP Blocks
Instantiating DSP Functions
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(),
318
P (A
B+ CIN) Multiply-accumulate
DSP Blocks
Instantiating DSP Functions
.RSTC(),
.RSTCTRL(),
.RSTP(),
.RSTCARRYIN(),
.RSTM(),
.SUBTRACT());
319
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);
320
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;
321
DSP Blocks
Instantiating DSP Functions
322
Chapter 10
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.
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, 2010a Update1
July 2010
323
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 10-1 are recognized by the 2004c compile mode VHDL parser, and
declared in both the exemplar and the exemplar_1164 package:
Table 10-1. Exemplar Package Attributes Recognized by the VHDL Parser
Attribute
Type
Description
required_time
time
arrival_time
time
output_load
real
max_load
real
clock_cycle
time
pulse_width
time
input_drive
time
nobuf
boolean
pin_number
string
array_pin_number*
array of strings
preserve_signal
boolean
buffer_sig
string
modgen_sel
modgen_select
*VHDL only.
324
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.
325
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
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.
326
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
Same as sl, but bits are shifted to the right side of the vector. Bits on left side are zero-filled.
sr2
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
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
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)
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)
327
(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"
-- 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)
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 :
328
"11011"
(22 + 5 == 27)
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)
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"
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.
329
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
330
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 down to 0.
trstmem (busname)
When a bus is not driven, this procedure drives the bus to the last driven state.
331
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.
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
Package Name
syn_ari.vhd
ARITHMETIC
syn_attr.vhd
ATTRIBUTES
syn_type.vhd
TYPES
syn_arit.vhd
STD_LOGIC_ARITH
syn_misc.vhd
STD_LOGIC_MISC
syn_unsi.vhd
STD_LOGIC_UNSIGNED
syn_sign.vhd
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.
332
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.
Manually include these packages with the batch mode option in the appropriate library.
vhdl_file=libname::filename
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).
333
334
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, 302
A
alias, 59
Array types
VHDL
array types as scalar, 21
constrained array types, 29
enumerated-index array types, 26
IEEE 1164 array types, 41
pre-defined operators, 42
syntax and semantics, 24
synthesis issues, 26
type conversions, 29
unconstrained array types, 25
Assignment statements
in VHDL, 37
signal, 37
variable, 37
Attributes
dedicated_mult, 301
disable_fsm, 281
Exemplar predefined attributes, 43
fsm_implementation, 281
fsm_state, 281, 282
in VHDL source code, 42
type_encoding, 282
type_encoding_style, 282
user-defined attributes, 43
VHDL predefined attributes, 43
B
block statement, 45
bus class, 51
C
Cascaded clocks - conversion, 224
case statements
automatic full case detection, 87
automatic parallel case detection, 87
Precision Synthesis Style Guide, 2010a Update1
July 2010
casex statement, 88
casez statement, 88
multiplexer generation, 86
Verilog case statement, 84
VHDL case statement, 34
component instantiation, 51
components
declared, 52
structure module, 51
conditional statement, 34
configuration declaration, 15
continuous assignment
net declaration assignment, 71
statement, 72
D
Data types
SystemVerilog, 118
Verilog
net data type, 69
parameter data type, 70
register data type, 70
WAND and WOR net types, 70
Dataflow Environment
operators, 14
statements, 14
design root, 15
directives
parallel_case and full_case, 97
translate_off and translate_on, 97
disable statement, 90
disable_fsm attribute, 281
DSP
2004c Compile Mode, 302
attributes, 305
dedicated_mult attribute, 301, 302, 305
frontend_dissolve attribute, 305
guidelines, 301
inference, 301, 302
instantiation, 302, 318
335
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, 311
Mult-Acc-AddSub, 313
Mult-Add, 307
Mult-AddSub, 309
multipliers, 302
pipelined 35x18 multiplier, 315
reset handling, 301, 303
use_resource attribute, 305
E
Entity and package
usage, 58
enumerated type, 21
Enumerated types, 21, 26, 27
Exemplar package
description, 323
predefined attributes, 324
predefined functions, 325
predefined procedures, 329
predefined types, 324
F
Finding definition of component, 56
Flip-flops
asynchronous set and reset, 191
clock enable, 192
predefined procedure, 330
synchronous set and reset, 191
Floating-point types
as a scalar in VHDL, 21
operator overloading, 42
synthesis resolution, 23
type conversion in VHDL, 29
VHDL, 23
VHDL semantics, 23
for loops
SystemVerilog, 128
Verilog, 89
VHDL, 35
fsm_implementation attribute, 281
fsm_state attribute, 281, 282
Functions
in Verilog, 92
in VHDL, 46
336
G
Gated Clock Conversion
AND, 220
cascaded clocks, 224
NAND, 221
NOR, 223
OR, 222
generate statement, 35
generic
size, 33
Generics
generic list, 33
I
IEEE 1076, 30
IEEE 1076-1987, 15
IEEE 1076-1993, 15
IEEE 1164, 30
IEEE 1164 standard logic, 41
IEEE 1364, see Verilog
if-else statement, 83
integer types
VHDL
and arithmetic behavior, 21
arithmetic operators, 40
integer pre-defined type, 22
integer range limits, 22
integer type example, 29
related types, 29
syntax, 21
synthesis encoding of integer types, 24
synthesis issues, 22
L
Latches, 193
Literal values, 116
Literals
VHDL
constant values, 19
defined, 19
Loop variables
VHDL, 33
M
Module instantiation
parameter overrides, 77
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
package
body, 57
header, 57
Packages, 57
Partitioning
blocks, 45
processes, 45
Physical types, 21, 24
Ports
VHDL
port statement, 32
Post-layout functional simulation, 331
Pragmas
Verilog, 97
procedure statement, 46
Processes, 17
O
objects
array, 25
array naming, 26
declared, 20
elements, 27
enumeration type, 21
generic, 33
loop variable, 33
physical type, 24
port, 32
ports, 32
record, 27
signal, 31
variable, 32, 193
operand, 78
Operators
IEEE 1076 pre-defined, 39
Verilog
arithmetic operator, 79
bit-wise operator, 81
concatenation, 82
conditional operator, 81
logical operator, 80
reduction operator, 81
relational and equality operator, 80
shift operator, 81
signed and unsigned attribute, 82
VHDL
arithmetic, 26, 40
concatenation, 40
exemplar package, 26
exemplar_1164 package, 26
logical, 39, 40
overloading, 20, 42
pre-defined, 39
relational, 39
vector arithmetics, 40
R
Record types, 21, 27
Registers
AND gated clock, 220
cascaded clocks, 224
NAND gated clock, 221
NOR gated clock, 223
OR gated clock, 222
Resolution functions, 48
S
Signals, 31
Signed attribute
on operators, 82
Statements
VHDL
assignment statement, 37
basic statements, 33
conditional statement, 34
generate statement, 35
loop statement, 35
loop variable, 33
selection statement, 34
std_logic, 31, 40, 48, 49
Subprograms
function, 46
procedure, 46
Subtypes, 28, 29
337
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, 332
Syntax and semantic restrictions, 60
synthesis tool restrictions, 60
VHDL language Restriction, 61
Synthesis directives
attribute, 97
translate_off and translate_on, 97
SystemVerilog, 107
define macro, 138
always_comb, 131
always_latch, 131
always_seq, 132
argument passing by name, 134
array assignment, 125
array literals, 118
array type literal, 116
array types, 123
arrays as arguments, 125
assignment operators, 126
attributes, 126
break, 129
compiler directives, 138
constants, 126
continue, 129
data types, 118
casting, 122
enumerations, 121
integer types, 120
structures, 121
unions, 121
user defined types, 121
do...while loop, 128
example designs, 138
for loops, 128
function, 133
implicit .* port connections, 135
implicit .name port connections, 135
indexing arrays, 124
integer and logic literals, 117
integer type, 116
interfaces, 135
language features, 107
literal values, 116
logic type, 116
multi-dimensioned arrays, 123
338
T
Tasks, 93
type_encoding attribute, 282
type_encoding_style attribute, 282
Types
array types, 24
enumeration type, 21
floating-point type, 23
IEEE 1076 predefined type, 30
IEEE 1076 predefined types, 30
IEEE 1164, 31
integer type, 21
physical type, 24
record type, 27
subtypes, 28
type conversions, 29
U
Unsigned attribute
on operators, 82
V
variable statement, 193
Verilog
if-else statement, 83
parameter data type, 70
pragmas, 97
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, 70
signed and unsigned attributes, 82
Verilog 2001 Support, 99
VHDL
architectures, 14
array types, 21
basic statements, 33
blocks, 45
dataflow environment, 14
entities, 14
enumerated-index array types, 26
environment
interfacing with other VHDL tools, 331
IEEE 1076-1987, 15
IEEE 1076-1993, 15
integer type, 21
loop variables, 33
object
signal, 14
package handling, 15
procedure statement, 46
variable statement, 193
void, 133
W
while loop, 35
339
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
340
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.
4.
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
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/.
7.
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.
8.
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.
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.