Precision RTL Synthesis Style Guide

Precision RTL Synthesis Style Guide
Precision RTL Synthesis
Style Guide
2003c Update1
March 2004
Copyright  Mentor Graphics Corporation 2002-2004.
All rights reserved.
This document contains information that is proprietary to Mentor Graphics Corporation. The original
recipient of this document may duplicate this document in whole or in part for internal business purposes
only, provided that this entire notice appears in all copies. In duplicating any part of this document, the
recipient agrees to make every reasonable effort to prevent the unauthorized use and distribution of the
proprietary information.
End-User License Agreement
Trademark Information
This document is for information and instruction purposes. Mentor Graphics reserves the right to make
changes in specifications and other information contained in this publication without prior notice, and the
reader should, in all cases, consult Mentor Graphics to determine whether any changes have been
made.
The terms and conditions governing the sale and licensing of Mentor Graphics products are set forth in
written agreements between Mentor Graphics and its customers. No representation or other affirmation
of fact contained in this publication shall be deemed to be a warranty or give rise to any liability of Mentor
Graphics whatsoever.
MENTOR GRAPHICS MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS MATERIAL
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR 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.
This is an unpublished work of Mentor Graphics Corporation.
Table of Contents
Table of Contents
About This Manual ............................................................................................ 1-xi
Chapter 1
Introduction to VHDL Synthesis .............................................................................................. 1-1
Overview................................................................................................................................... 1-1
VHDL and Synthesis ................................................................................................................ 1-2
Chapter 2
VHDL Language Features ........................................................................................................ 2-1
Entities and Architectures ......................................................................................................... 2-1
Configuration ......................................................................................................................... 2-2
Processes ................................................................................................................................ 2-5
Literals ...................................................................................................................................... 2-7
Types...................................................................................................................................... 2-8
Enumerated Types ................................................................................................................. 2-9
Integer Types ....................................................................................................................... 2-10
Floating-point Types............................................................................................................ 2-11
Physical Types ..................................................................................................................... 2-12
Syntax and Semantics .......................................................................................................... 2-12
Array Types ......................................................................................................................... 2-13
Record Types ....................................................................................................................... 2-15
Subtypes............................................................................................................................... 2-16
Type Conversions ................................................................................................................ 2-17
IEEE 1076 Predefined Types............................................................................................... 2-18
IEEE 1164 Predefined Types............................................................................................... 2-18
Objects .................................................................................................................................... 2-20
Signals.................................................................................................................................. 2-20
Constants.............................................................................................................................. 2-20
Variables .............................................................................................................................. 2-20
Ports ..................................................................................................................................... 2-21
Generics ............................................................................................................................... 2-21
Loop Variables..................................................................................................................... 2-22
Statements ............................................................................................................................... 2-22
Conditional Statements ....................................................................................................... 2-22
Selection Statements ............................................................................................................ 2-23
Loop Statements and Generate Statements.......................................................................... 2-24
Assignment Statements........................................................................................................ 2-26
Operators................................................................................................................................. 2-28
IEEE 1076 Predefined Operators......................................................................................... 2-28
IEEE 1164 Predefined Operators......................................................................................... 2-30
Operator Overloading .......................................................................................................... 2-30
Attributes ................................................................................................................................ 2-31
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
iii
Table of Contents
Table of Contents (cont.)
VHDL Predefined Attributes ............................................................................................... 2-32
Mentor Graphics Predefined Attributes ............................................................................... 2-32
User-Defined Attributes....................................................................................................... 2-33
Using Attributes in the Source Code ................................................................................... 2-33
Blocks ..................................................................................................................................... 2-34
Functions And Procedures ...................................................................................................... 2-35
Resolution Functions .............................................................................................................. 2-38
Syntax and Semantics .......................................................................................................... 2-38
Synthesis Issues ................................................................................................................... 2-39
Component Instantiation......................................................................................................... 2-40
Binding a Component ............................................................................................................. 2-42
Option 1 - Using a Default Binding..................................................................................... 2-43
Option 2 - Using a Configuration Specification .................................................................. 2-44
Option 3 - Matching a Component Name to a Library Cell ................................................ 2-45
Option 4 - Creating a Black Box by Omitting the Entity .................................................... 2-45
Packages.................................................................................................................................. 2-45
Aliases..................................................................................................................................... 2-47
Chapter 3
The Art of VHDL Synthesis ...................................................................................................... 3-1
Registers, Latches and Resets ................................................................................................... 3-1
Level-Sensitive Latch ............................................................................................................ 3-1
Edge-Sensitive Flip-Flops...................................................................................................... 3-2
Wait Statements ..................................................................................................................... 3-5
Variables ................................................................................................................................ 3-6
Predefined Flip-flops and Latches ......................................................................................... 3-7
Assigning I/O Buffers From VHDL ......................................................................................... 3-7
Buffer Assignment Using Component Instantiation.............................................................. 3-8
Three-state Buffers ................................................................................................................... 3-9
Bidirectional Buffers............................................................................................................... 3-11
Buses ....................................................................................................................................... 3-11
State Machines ........................................................................................................................ 3-12
General State Machine Description ..................................................................................... 3-12
VHDL Coding Style For State Machines ............................................................................ 3-14
Power-up And Reset ............................................................................................................ 3-15
Encoding Methods ............................................................................................................... 3-16
Arithmetic And Relational Logic ........................................................................................... 3-16
Resource Sharing ................................................................................................................. 3-18
Ranged Integers ................................................................................................................... 3-19
Advanced Design Optimization........................................................................................... 3-20
Technology-Specific Macros .................................................................................................. 3-21
Multiplexers and Selectors...................................................................................................... 3-22
ROMs, PLAs And Decoders................................................................................................... 3-23
iv
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Table of Contents
Table of Contents (cont.)
Chapter 4
The VHDL Environment........................................................................................................... 4-1
Entity and Package Handling................................................................................................... 4-1
Entity Compiled as the Design Root...................................................................................... 4-1
Finding Definitions of Components ...................................................................................... 4-2
How to Use Packages ............................................................................................................ 4-3
Interfacing With Other VHDL Tools........................................................................................ 4-4
VHDL Simulators .................................................................................................................. 4-4
Synopsys ................................................................................................................................ 4-6
The exemplar Packages ............................................................................................................ 4-7
Predefined Types ................................................................................................................... 4-8
Predefined Attributes ............................................................................................................. 4-8
Predefined Functions ........................................................................................................... 4-10
Predefined Procedures ......................................................................................................... 4-14
Syntax and Semantic Restrictions........................................................................................... 4-16
Synthesis Tool Restrictions ................................................................................................. 4-16
VHDL Language Restrictions ............................................................................................. 4-17
Chapter 5
Introduction to Verilog Synthesis ............................................................................................. 5-1
Verilog and Synthesis ............................................................................................................... 5-2
Verilog 2001 Support................................................................................................................ 5-3
Introduction............................................................................................................................ 5-3
Supported Verilog 2001 Constructs....................................................................................... 5-3
Detailed Description .............................................................................................................. 5-4
Chapter 6
Verilog Language Features........................................................................................................ 6-1
Modules .................................................................................................................................... 6-1
’macromodule’....................................................................................................................... 6-2
Numbers.................................................................................................................................... 6-2
Data Types ................................................................................................................................ 6-3
Net Data Types ...................................................................................................................... 6-5
Register Data Type ................................................................................................................ 6-6
Parameter Data Type ............................................................................................................. 6-6
Continuous Assignments .......................................................................................................... 6-7
Net Declaration Assignment .................................................................................................. 6-8
Continuous Assignment Statement ........................................................................................ 6-8
Procedural Assignments ........................................................................................................... 6-9
Always Blocks ........................................................................................................................ 6-10
Module Instantiation ............................................................................................................... 6-13
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
v
Table of Contents
Table of Contents (cont.)
Parameter Override During Instantiation of Module ........................................................... 6-14
Defparam Statement ............................................................................................................ 6-14
’unconnected_drive’ and ’nounconnected_drive’................................................................ 6-15
Operators................................................................................................................................. 6-15
Operands .............................................................................................................................. 6-16
‘signed and ‘unsigned Attributes on Operators ................................................................... 6-20
Operator Precedence ............................................................................................................ 6-20
Statements ............................................................................................................................... 6-20
If-Else Statements ................................................................................................................ 6-21
Case Statements ................................................................................................................... 6-22
Case Statement and Multiplexer Generation ....................................................................... 6-23
for Statements ...................................................................................................................... 6-26
Disable Statement ................................................................................................................ 6-27
forever, repeat, while and Generalized Form of for Loop ................................................... 6-28
Functions and Tasks................................................................................................................ 6-29
Functions.............................................................................................................................. 6-29
Tasks .................................................................................................................................... 6-30
Inout Ports in Task ............................................................................................................... 6-32
Access of Global Variables from Functions and Tasks ....................................................... 6-33
System Task Calls................................................................................................................... 6-33
System Function Calls ............................................................................................................ 6-33
Initial Statement ...................................................................................................................... 6-34
Compiler Directives ............................................................................................................. 6-34
Chapter 7
The Art of Verilog Synthesis ..................................................................................................... 7-1
Registers, Latches, and Resets .................................................................................................. 7-1
Level-Sensitive Latch ........................................................................................................... 7-1
Edge-Sensitive Flip-flops ...................................................................................................... 7-2
Assigning I/O Buffers from Verilog ......................................................................................... 7-4
Buffer Assignment Using Component Instantiation.............................................................. 7-5
Tristate Buffers ......................................................................................................................... 7-5
Bidirectional Buffers................................................................................................................. 7-8
Buses ......................................................................................................................................... 7-8
State Machines ........................................................................................................................ 7-10
Moore Machines .................................................................................................................. 7-12
Mealy Machines................................................................................................................... 7-16
Issues in State Machine Design ........................................................................................... 7-18
Arithmetic and Relational Logic............................................................................................. 7-23
Resource Sharing and Common Subexpression Elimination .............................................. 7-24
Comparator Design .............................................................................................................. 7-25
Technology-Specific Macros .................................................................................................. 7-26
Synthesis Directives................................................................................................................ 7-26
vi
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Table of Contents
Table of Contents (cont.)
parallel_case and full_case directives.................................................................................. 7-26
translate_off and translate_on directives ............................................................................. 7-27
attribute directive ................................................................................................................. 7-28
Chapter 8
Verilog and Synthesis of Logic .................................................................................................. 8-1
Comparing With X and Z ......................................................................................................... 8-1
Variable Indexing of Bit Vectors.............................................................................................. 8-2
Syntax and Semantic Restrictions............................................................................................. 8-3
Unsupported Verilog Features ............................................................................................... 8-3
Chapter 9
Operators, Counters, and Memory .......................................................................................... 9-1
Inferring Operators ................................................................................................................... 9-1
Inferring a Pipelined Multiplier ............................................................................................. 9-3
Mapping Operators to Dedicated Resources ......................................................................... 9-6
Inferring Counters.................................................................................................................. 9-7
Inferring Memory ..................................................................................................................... 9-8
How Memory Inferencing Works.......................................................................................... 9-8
Initializing a RAM in Verilog.............................................................................................. 9-12
Inferring ROM from the HDL Source Code........................................................................ 9-13
Chapter 10
State Machine Synthesis .......................................................................................................... 10-1
FSM Encoding Styles ............................................................................................................. 10-1
FSM Encoding using VHDL Attributes .............................................................................. 10-3
FSM Encoding using a Verilog Pragma .............................................................................. 10-3
Advanced FSM Optimization .............................................................................................. 10-3
Safe State Machines................................................................................................................ 10-4
How Precision Implements a Safe FSM .............................................................................. 10-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
vii
Table of Contents
List of Figures
Figure 1-1. Top-Down Design Flow with Precision RTL Synthesis....................................... 1-2
Figure 5-1. Top Down Design Flow with Precision RTL Synthesis ....................................... 5-2
Figure 7-1. DRAM Interface with Refresh ............................................................................ 7-11
Figure 9-1. Pipelined Multiplier - Before Pipelining............................................................... 9-4
Figure 9-2. Figure 2 - Pipelined Multiplier - After Retiming .................................................. 9-5
Figure 9-3. Changing the Mapping of a Multiplier in a Stratix Device................................... 9-6
Figure 9-4. Inferring an 8-Bit Loadable Down-Counter.......................................................... 9-7
Figure 9-5. Inferring Synch Single-Port RAM from VHDL ................................................... 9-9
Figure 9-6. Inferring Synch Single-Port RAM from Verilog ................................................ 9-10
Figure 9-7. Inferring Synch Dual-Port RAM from VHDL.................................................... 9-11
Figure 9-8. Inferring Synch Dual-Port RAM from Verilog................................................... 9-12
Figure 10-1. Specifying the FSM EncodSpecifying the FSM Encoding Style ..................... 10-2
viii
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Table of Contents
List of Tables
Table 6-1. Operators Supported by Precision RTL Synthesis ............................................... 6-16
Table 9-1. Operators that are Recognized by Precision ........................................................... 9-2
Table 9-2. Optimal Number of Pipeline Stages ....................................................................... 9-4
Table 9-3. Technologies that Support Pipelining .................................................................... 9-5
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
ix
Table of Contents
List of Tables (cont.)
x
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
About This Manual
Before you use Precision Synthesis to perform RTL synthesis on your design, you should
already have a good understanding of the syntax and semantics of VHDL and /or Verilog. This
manual describes how Precision RTL Synthesis views these two HDL languages and makes
recommendations on the style to use to achieve the best synthesized design.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
xi
xii
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 1
Introduction to VHDL Synthesis
Overview
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,
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
1-1
VHDL and Synthesis
Introduction to VHDL Synthesis
resulting in a final netlist description in the technology of your choice. The Top-Down Design
Flow is shown in Figure 1-1.
Figure 1-1. Top-Down Design Flow with Precision RTL Synthesis
Write RTL code
Simulate the RTL design
Synthesize to generic gates
Precision RTL
Synthesis
Map to technology cells
Optimize for speed/area
Run implementation tools
Simulate the final design
VHDL and Synthesis
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
1-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Introduction to VHDL Synthesis
VHDL and Synthesis
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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
1-3
VHDL and Synthesis
1-4
Introduction to VHDL Synthesis
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 2
VHDL Language Features
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.
Entities and Architectures
The basic building blocks in VHDL are Entities and Architectures. An entity describes the
boundaries of the logic block. Its ports and its generics are declared here. An architecture
describes the contents of the block in structural, dataflow and behavioral constructs.
entity small_block is
port (a, b, c : in bit ;
o1 : out bit ;
o2 : out bit
) ;
end small_block ;
architecture rtl of small_block is
signal s : bit ;
begin
o1 <= s or c ;
s <= a and b ;
o2 <= s xor c ;
end rtl ;
This VHDL description shows the implementation of small_block, a block that describes
some simple logic functions.
The entity describes the boundary. The port list is given with a direction (in this case in or out),
and a type (bit) for each port. The name of the entity is small_block. The name of the
architecture is rtl which is linked to the entity with the name small_block. While multiple
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-1
Entities and Architectures
VHDL Language Features
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
following sections:
•
Configuration
•
Processes
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.
NOTE: If you use “con” for configuration and “ent” for entity then the name of the hierarchy
cell created is “con_ent”.
2-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Entities and Architectures
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;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-3
Entities and Architectures
VHDL Language Features
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;
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;
continued.........
2-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Entities and Architectures
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 c1: en1 use entity work.en1 (ar1);
end for;
for c2: en1 use entity work.en1 (ar2);
end for;
end for;
end binding ;
Processes
Processes are sections of sequentially executed statements, as opposed to the dataflow
environment, where all statements are executed concurrently. In a process, the order of the
statements does matter. In fact, processes resemble the sequential coding style of high level
programming languages. Also, processes offer a variety of powerful statements and constructs
that make them very suitable for high level behavioral descriptions.
A process can be called from the dataflow area. Each process is a sequentially executed
program, but all processes run concurrently. In a sense, multiple processes resemble multiple
programs that can run simultaneously. Processes communicate with each other via signals that
are declared in the architecture. Also the ports defined in the entity can be used in the processes.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-5
Entities and Architectures
VHDL Language Features
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 wrclk’event and wrclk = ’1’ ;
if (ce=’1’) then
intreg <= source ;
end if ;
end process writer;
reader : process (intreg, selector)
-- process statement
-- with sensitivity list
-- declarative region (empty
here)
begin
-- sequential (not-clocked) statements
case selector is
when "00" => result <= intreg(0) ;
when "01" => result <= intreg(1) ;
when "10" => result <= intreg(2) ;
when "11" => result <= intreg(3) ;
end case ;
end process reader;
end rtl ;
This example describes a circuit that can load a source vector of 4 bits, on the edge of a write
clock (wrclk), store the value internally in a register (intreg) if a chip enable (ce) is active,
while it produces one bit of the register constantly (not synchronized). The bit is selected by a
selector signals of two bits.
The description consists of two processes, one to write the value into the internal register, and
one to read from it. The two processes communicate via the register value intreg.
2-6
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Literals
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 wrclk’event 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’,
intreg retains its value. In synthesis terms, this translates into a D-flipflop, clocked on wrclk,
and enabled by ce.
The second process (reader) does not have a wait statement. Instead, it has a sensitivity list,
with the signals intreg and selector there. This construct defines that the whole process is
executed each time either intreg or selector changes. If the process is executed, the output
signal result gets updated with depending on the values of intreg and selector. Note that
this leads to combinational behavior, since result depends on only intreg and selector, and
each time either of these signals changes, result gets updated.
A process has an optional name (in this case writer and reader), a sensitivity list OR a wait
statement, and a declarative region where signals, variables, functions etc. can be declared
which are used only within the process. Each statement is executed sequentially, as in a
programming language.
Not all constructs, or combinations of constructs, in a process lead to behavior that can be
implemented as logic.
Literals
Constant values in VHDL are given in literals. Literals are lexical elements. The following is an
overview, with examples given for each type of literal.
Character Literals:
’0’
String Literals:
“1110100” “XXX” “try me!” “$^&@!”
Bit String Literals:
B“0010_0001” X”5F’
Decimal Literals:
27
Based Literals:
2#1001#
Physical Literals:
2 ns
Identifiers:
Idle TeSTing
’X’
’a’ ’%’#
-5 4E3
76_562
8#65_07"
5.0 V
O“63_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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-7
Literals
VHDL Language Features
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.
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:
2-8
•
Scalar types
•
Composite types
•
Access types
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
•
Literals
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:
•
Enumerated types.
•
Integer types
•
Floating-point types
•
Physical types
•
VHDL has two forms of composite 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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-9
Literals
VHDL Language Features
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 ;
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 two’s 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.
Synthesis issues
Precision RTL Synthesis can synthesize with any integer type that contains no values outside
the range -2147483648 to 2147483647. Precision RTL Synthesis stores integer values (constant
ones) using (32 bit) integers internally. If more than 32 bits are needed for a particular circuit
design, you should use arrays to represent them. Do not use integer types that exceed the range,
since many other VHDL tools have the same restrictions as Precision RTL Synthesis.
Precision RTL Synthesis needs to do encoding for integer types, since an integer range requires
multiple bits to represent. The synthesis tools will analyze the range of an integer type and
calculate the number of bits needed to represent it.
If there are no negative values in the integer range, Precision RTL Synthesis will create an
unsigned representation. For example, consider the following object of the type my_integer
from the previous section:
signal count : my_integer ;
The signal count will be represented as unsigned, consisting of four bits. When synthesized, the
four bits will be named as elements of a bus in the resulting netlist:
count(3)
count(2)
count(1)
count(0)
2-10
the MSB bit
the LSB bit
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Literals
If the range includes negative numbers, Precision RTL Synthesis will use two’s-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 ;
Now, Precision RTL Synthesis will represent the signal big_value as 32 bits:
big_value(31) the sign bit
big_value(30) the MSB bit
:
:
big_value(1)
big_value(0) the LSB bit
Floating-point Types
Syntax and Semantics
As any high-level programming language, VHDL defines floating-point types. Floating-point
types approximate the real numbers.
Here is an example of the declaration of a floating-point type:
type my_real is range 0.0 to 1.0 ;
VHDL pre-defines a very general floating-point type called real.
type real is range -1.0E38 to 1.0E38 ;
Like the integer types, maximum bounds of any floating-point type are not defined by the
language. However, the floating-point type should but should at least include -1.0E38 to
1.0E38.
Nothing in the language defines anything about the accuracy of the resolution of the floatingpoint type values.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-11
Literals
VHDL Language Features
Synthesis Issues
In general, since the resolution of floating-point types is not defined by the language, it is
difficult to come up with a good rule for encoding floating-point types. While in a regular
(software) compilers floating-point types are represented in 32, 64 or 128 bits, the floating-point
operations just require time. In hardware compilers like a logic synthesis tool, floating-point
operations would require massive amounts of actual synthesized hardware, unless the resolution
and bounds of the floating-point type are kept under very close control.
In summary, Precision RTL Synthesis does not currently support synthesis of floating point
objects. Floating-point types and objects can however be used in constant expression.
For example, an attribute could get a (compile time constant) floating-point expression, and the
synthesis tools will calculate the expression and set the floating-point value on the attribute.
Physical Types
Syntax and Semantics
VHDL allows the definition of physical types. Physical types represent relations between
quantities. A good example of a physical type is the predefined type time:
type time is range -2147483647 to 2147483647
units
fs;
ps = 1000 fs;
ns = 1000 ps;
us = 1000 ns;
ms = 1000 us;
sec = 1000 ms;
min = 60 sec;
hr = 60 min;
end units;
Objects of physical types can contain physical values of the quantities specified in the type, as
long as the values do not exceed the range of the type. Type time is often used in VHDL
designs to model delay.
Synthesis Issues
Physical types, objects and values are normally only used for simulation purposes. Objects and
values of type time are used in after clauses to model delay.
Precision RTL Synthesis attempts to synthesize any physical value that is within the range of
the type. The encoding follows the encoding for integer types, and expresses the value with
2-12
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Literals
respect to the base quantity (fs in the type time). It is not common practice however to
synthesize logic circuitry to model physical values.
Precision RTL Synthesis handles constant expressions of physical values without any problems.
For example, attributes of type time can receive constant values of type v. This is often used to
model arrival time and required time properties in the design.
Array Types
Syntax and Semantics
An array type in VHDL specifies a collection of values of the same type. There are constrained
and unconstrained array types.
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’.
Parts of the array can be retrieved using slicing:
seven(3 downto 0) is the name of the right most four elements in array seven. The value is an
array of four bits: "0111". The indexes of this array range from 3 down to 0.
For an unconstrained array type, the number of elements and the name of the elements in not yet
defined. An example is the pre-defined type bit_vector:
type bit_vector is array (natural range <>) of bit ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-13
Literals
VHDL Language Features
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.
The type of the element of an (constrained or unconstrained) array type is not restricted to
enumerated type bit as in the examples. Actually, an array element type can be any type except
for an unconstrained array type.
You can define an array of integers, an array of 6-bit arrays, an array of records etc. However,
you cannot declare an array of (the unconstrained array type) bit_vector.
If you want an unconstrained array type where you need more indexes to remain unconstrained,
you need a multi-dimensional array type:
type matrix is array (natural range <>, natural range <>) of bit ;
Multi-dimensional (constrained and unconstrained) array type are useful when modeling
RAMs, ROMs and PLAs in VHDL. Indexes and slices of multi-dimensional arrays need to
specify all index dimensions, separated by a comma.
Finally, the index type of an array type does not have to be an integer (sub)type. It can also be an
enumerated type.
Synthesis Issues
There are no synthesis restrictions in Precision RTL Synthesis on using arrays. Precision RTL
Synthesis supports arrays of anything (within the language rules), multi-dimensional arrays,
array types with enumerated index type. Negative indexes are also allowed.
Naming of array objects is straightforward. Precision RTL Synthesis appends the index for each
element after the array name. If the element type consists of multiple bits, the synthesis tools
append the element indexes to the array name with its index.
It is important to understand that there is no Most Significant Bit (MSB) or Least Significant Bit
(LSB) defined in an array type or array object. The semantics of what is interpreted as MSB or
LSB is defined by the operations on the array. In the example of object seven the user probably
2-14
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Literals
meant the left most bit to be the MSB, and the right most bit the LSB. However, this is not
defined by the language, just by the user.
Additions, subtractions, and multiplications have to be defined by the user. Most synthesis tool
vendors define (arithmetic) operations on arrays in packages that are shipped with the product.
Most of these packages assume that leftmost bit is the MSB and the rightmost bit is the LSB. As
an example of this, the packages exemplar and exemplar_1164 define arithmetic operators the
bit_vector and the IEEE 1164 array equivalent std_logic_vector type. In these packages,
the leftmost bit is assumed to be the MSB.
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
1993.
selects the year field out of my_birthday and returns the integer value
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-15
Literals
VHDL Language Features
Synthesis Issues
Precision RTL Synthesis does not impose any restrictions (except for language rules) on record
types and record objects.
Naming of the individual bits that result after synthesizing a record object follow the selected
naming rule of the language: Each bit in a record object get the record name followed by a dot,
followed by the element name. If the element synthesizes into multiple bits, the index of the bits
in each element are appended to that. As an example, the five bits that represent the day field in
my_birthday will be named as follows:
my_birthday.day(0) LSB in my_birthday.day
my_birthday.day(1)
my_birthday.day(2)
my_birthday.day(3)
my_birthday.day(4) MSB in my_birthday.day
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
2-16
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Literals
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) ;
has the same effect as:
type eight_bit_vector is array (7 downto 0) of bit ;
Just as in the integer type example, subtypes of one and the same unconstrained base-type are
compatible (will not cause type errors), but when two constrained array types are used, they will
cause type errors if objects of both types are intermixed in expressions. Type conversion is then
the only possibility to let objects of the two types be used together in expressions without type
errors. There are no synthesis restrictions on the use of subtypes.
Type Conversions
In cases where it is not possible to declare one type and one subtype instead of two separate
types, VHDL has the concept of type conversion. Type conversion is similar to type ’casting’
in high level programming languages. To cast an expression into a type, use the following
syntax:
<type>(<expression>)
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-17
Literals
VHDL Language Features
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.
IEEE 1076 Predefined Types
The VHDL IEEE 1076 standard predefines a number of types. The following lists the ones
which are most important for synthesis:
type bit is (’0’,’1’) ;
type bit_vector is array (integer range <>) of bit ;
type integer is range MININT to MAXINT ;
subtype positive is integer range 0 to MAXINT ;
subtype natural is integer range 0 to MAXINT ;
type boolean is (TRUE,FALSE) ;
Precision RTL Synthesis also understands the predefined types CHARACTER, STRING,
SEVERITY_LEVEL, TIME, REAL and FILE.
IEEE 1164 Predefined Types
A problem with the 1076 standard is that it does not specify any multi-valued logic types for
simulation purposes, but rather left this to the user and/or tool vendor. The IEEE 1164 Standard
specifies a 9-valued logic. Precision RTL Synthesis supports these types, although some
restrictions apply to the values you can use for synthesis.
The meaning of the different type values of the IEEE 1164 standard are as follows:
2-18
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
’U’
Uninitialized
’X’
Forcing Unknown
’0’
Forcing Low
’1’
Forcing High
’Z’
High Impedance
’W’
Weak Unknown
’L’
Weak Low
’H’
Weak High
’-’
Dont Care
Literals
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’,v,’X’,’-’ and ’Z’ have a welldescribed meaning for synthesis.
Some examples of IEEE 1164 type statements are:
type std_ulogic is (’U’,’X’,’0’,’1’,’Z’,’W’,’L’,’H’,’-’) ;
type std_ulogic_vector is array (natural range <>) of std_ulogic ;
subtype std_logic is resolution_func std_ulogic ;
type std_logic_vector is (natural range <>) of std_logic ;
subtype X01Z is resolution_func std_ulogic range ’X’ to ’Z’ ;
-- includes X,0,1,Z
The identifier resolution_func is a function that defines which value should be generated in
case multiple values are assigned to an object of the same type. This is called the resolution
function of the type. Resolution functions are supported as long as they do not return any
metalogical values.
To use the IEEE 1164 types you must load the IEEE package into your VHDL description. This
is done with the following statements:
library ieee ;
use ieee.std_logic_1164.all ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-19
Objects
VHDL Language Features
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 signal’s array can be
accessed and assigned using indexing or slicing.
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 ;
2-20
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Objects
Assignments to a variable are immediate. This effect is an essential difference between
variables and signals. The initial assignment to a variable is optional. The initial assignment to a
variable in a process is usually ignored by synthesis.
Ports
A port is an interface terminal of an entity. A port represents an ordinary port in a netlist
description. Ports in VHDL are, just like other objects, typed and can have an initial value. In
addition, a port has a “direction.” This is a property that indicates the possible information flow
through the port. Possible directions are in, out, inout and buffer, where inout and buffer
indicate bidirectional functionality.
entity adder is
port (
input_vector : in bit_vector (7 downto 0) ;
output_vector : out bit_vector (7 downto 0)
) ;
end adder ;
After declaration, a port can be used in the architecture of the entity as if it were a normal signal,
with the following restrictions: first, you cannot assign to a port with direction in, and second,
you cannot use a port of direction out in an expression.
Generics
A generic is a property of an entity. A good example of a generic is the definition of the size of
the interface of the entity. Generics are declared in a generic list.
entity increment is
generic ( size : integer := 8 ) ;
port ( ivec : in bit_vector (size-1 downto 0) ;
ovec : out bit_vector (size-1 downto 0)) ;
end increment ;
The generic size can be used inside the entity (e.g., to define the size of ports) and in the
architecture that matches the entity. In this example, the generic size is defined as an integer
with an initial value 8. The sizes of the input and output ports of the entity increment are set to
be 8 bits unless the value of the generic is overwritten by a generic map statement in the
component instantiation of the entity.
inst_1 : increment
generic map (size=>16)
port map (ivec=>invec, ovec=>outvec) ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-21
Statements
VHDL Language Features
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. 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.
Conditional Statements
signal a : integer ;
signal output_signal, x, y, z : bit_vector (3 downto 0) ;
....
if a = 1 then
output_signal <= x ;
elsif a = 2 then
output_signal <= y ;
elsif a = 3 then
output_signal <= z ;
else
output_signal <= "0000" ;
end if ;
This code fragment describes a multiplexer function, implemented with an if-then-else
statement. This statement can only be used in a sequential environment, such as a process,
procedure or a function.
2-22
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Statements
The same functionality in the dataflow environment is accomplished with the use of the
conditional signal assignment statement:
signal a : integer ;
signal output_signal, x, y, z : bit_vector (3 downto 0) ;
....
output_signal <= x when a=1 else
y when a=2 else
z when a=3 else
"0000" ;
Selection Statements
If many conditional clauses have to be performed on the same selection signal, a case statement
is a better solution than the if-then-else construct:
signal output_signal, sel, x, y, z : bit_vector (3 downto 0) ;
....
case sel is
when "0010" => output_signal <= x ;
when "0100" => output_signal <= y ;
when "1000" => output_signal <= z ;
when "1010" | ”1100" | "0110" => output_signal <= x and y and z ;
when others => output_signal <= "0000" ;
end case ;
The “|” sign indicates that particular case has to be entered if any of the given choices is true
(or functionality). Each case can contain a sequence of statements.
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 ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-23
Statements
VHDL Language Features
Loop Statements and Generate Statements
In many cases, especially with operations on arrays, many statements look alike, but differ only
on minor points. In that case, you might consider using a loop statement.
signal result, input_signal : bit_vector (5 downto 0) ;
signal ena : bit ;
....
for i in 0 to 5 loop
result(i) <= ena and input_signal(i) ;
end loop ;
In this code fragment, each bit of a input signal is “anded” with a single bit enable signal, to
produce an output array signal. The loop variable i does not have to be declared. It holds an
integer value since the loop range is an integer range.
The previous example showed a for loop. VHDL also has a while loop. Here is an example:
process -- no sensitivity list
begin
wait until clk’ event AND clk=’1’;
output_signal <= 0;
while (input_signal < 6) loop
wait until clk’ event AND clk=’1’;
output_signal <= output_signal +1;
end loop;
end process;
Precision RTL Synthesis supports almost every type of loop. The tool supports any for loop
with the exception of for loops that contain wait until statements. The tool also supports any
kind of NEXT and EXIT statements applicable on an outer while loop with multiple wait
statements.
While 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:
2-24
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Statements
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
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-25
Statements
VHDL Language Features
know when to exit. The generate statement has no while equivalent, for the same reason.
Instead however, there is a if equivalent in the generate statement:
signal result, input_signal : bit_vector (5 downto 0) ;
G1 : for i in 0 to 5 generate
G2 : if i < 3 generate
result(i) <= input_signal(i) ;
end generate ;
G3 : if (i >= 4) generate
result(i) <= NOT input_signal (i);
end generate ;
end generate ;
The condition must evaluate to a run-time constant. That is a language requirement.
There is no else part possible in a generate statement. We consider this a flaw in the language,
but Mentor Graphics synthesis tools have to comply with it.
Precision RTL Synthesis does not have any synthesis restrictions for the generate statement.
Assignment Statements
Assignments can be done to signals, ports and variables in VHDL. Assignments to signals and
ports are done with the <= operator.
signal o, a, b : std_logic_vector (5 downto 0) ;
....
o <= a xor b ;
In this code fragment o gets assigned the value of the vector-XOR (bit by bit) of vectors v and
b. The type of the object on the left hand side of the assignment should always match the type of
the value on the right hand side of the assignment. Signal assignments can be used both in
dataflow environment and sequential environments.
Assignments to variables are done with the “:=” sign.
variable o : std_logic_vector (5 downto 0) ;
signal a, b : std_logic_vector (5 downto 0) ;
....
o := a AND NOT b ;
Variable assignments can only be used in sequential environments. Types on left and right hand
side of the “:=” sign should match.
2-26
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Statements
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
immediately after the assignment. The value of a signal in a signal assignment is not updated
immediately, but gets “scheduled” until after a delta (delay) time.
This delay time is not related to actual time, but is merely a simulation characteristic. This
behavior of the signal assignment does not have any effect for signal assignments in a dataflow
environment, since assignments are done concurrently there. However, in a process, the actual
value of the signal changes only after the complete execution of the process.
The following example illustrates this effect. It shows the description of a multiplexer that can
select one bit out of a four bit vector using two select signals.
entity mux is
port ( s1, s2 : in bit ;
inputs : in bit_vector (3 downto 0) ;
result : out bit
) ;
end mux ;
architecture wrong of mux is
begin
process (s1,s2,inputs)
signal muxval : integer range 0
begin
muxval <= 0 ;
if (s1 = '1') then muxval
if (s2 = '1') then muxval
-- use muxval as index of
result <= inputs (muxval)
end process ;
end wrong ;
to 3 ;
<= muxval+1 ;end if;
<= muxval+2 ;end if;
array ’inputs’
;
This description does not behave as intended. The problem is because muxval is a signal; the
value of muxval is not immediately set to the value defined by bits a and b. Instead, muxval still
has the same value it had when the process started when the if statement is executed. All
assignments to muxval are scheduled until after the process finishes. This means that muxval
still has the value it got from the last time the process was executed, and that value is used to
select the bit from the input vector.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-27
Operators
VHDL Language Features
The solution to this problem is to make muxval a variable. In that case, all assignments done to
muxval are immediate, and the process works as intended.
entity mux is
port (
s1, s2 : in bit ;
inputs : in bit_vector (3 downto 0) ;
result : out bit) ;
end mux ;
architecture right of mux is
begin
process (s1,s2,inputs)
variable muxval : integer range
begin
muxval := 0 ;
if (s1 = ’1’) then muxval
if (s2 = ’1’) then muxval
-- Use muxval as index of
result <= inputs (muxval)
end process ;
end right ;
0 to 3 ;
:= muxval+1 ;end if;
:= muxval+2 ;end if;
array ’inputs’
;
As a general rule, if you use signal assignments in processes, do not use the value of the signal
after the assignment, unless you explicitly need the previous value of the signal. Alternatively,
you can use a variable instead.
Operators
IEEE 1076 Predefined Operators
VHDL predefines a large number of operators for operations on objects of various types. The
following is an overview:
Relational operators on ALL types (predefined or not):
= <=
/= >
<
>=
Logical operators on pre-defined types BIT and BOOLEAN:
AND NOR
OR XOR
NAND
NOT
2-28
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Operators
Arithmetic operators on all integer types:
+ 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.
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) ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-29
Operators
VHDL Language Features
This description is the same as the following one:
signal a, b, c : bit ;
signal x : bit_vector (5 downto 0) ;
signal y : bit_vector (3 downto 0) ;
....
x(5) <= a ;
x(4) <= b ;
x(3) <= c ;
x(2 downto 0) <= "000" ;
y(0) <= ’1’ ;
y(1) <= ’0’ ;
y(2) <= b ;
y(3) <= c ;
The aggregate operator in VHDL is especially useful when assigning to a vector of unknown or
large size:
signal o : bit_vector (255 downto 0) ;
....
o <= (0=>’1’,others=>’0’) ;
In this example, o(0) is assigned ’1’ and all other elements of o (independent of its size) get
value ’0’.
IEEE 1164 Predefined Operators
The IEEE 1164 standard logic package describes a set of new types for logic values. However,
the binary operators that are predefined in VHDL only operate on bit and boolean types, and
arrays of bits and booleans. Therefore, the IEEE standard logic type package redefines the
logical operators (and, or, not, etc.) for the types std_logic, std_ulogic and the array types
std_logic_vector and std_ulogic_vector.
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
2-30
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Attributes
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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-31
Attributes
VHDL Language Features
VHDL Predefined Attributes
VHDL pre-defines a large set of attributes for signals. The following example shows the
definition of two vectors and the values of the VHDL predefined attributes for them.
signal vector_up : bit_vector (9 downto 4) ;
signal vector_dwn : bit_vector (25 downto 0) ;
....
vector_up’LEFT-- returns integer 9
vector_dwn’LEFT-- returns integer 25
vector_up’RIGHT-- returns integer 4
vector_dwn’RIGHT-- returns integer 0
vector_up’HIGH-- returns integer 4
vector_dwn’HIGH-- returns integer 25
vector_up’LOW-- returns integer 9
vector_dwn’LOW-- returns integer 0
vector_up’LENGTH-- returns integer 6
vector_dwn’LENGTH-- returns integer 26
vector_up’RANGE -- returns range 4 to 4
vector_dwn’RANGE-- returns range 25 to 0
vector_up’REVERSE_RANGE-- returns range 4 to 9
vector_dwn’REVERSE_RANGE-- returns range 0 to 25
The attributes do not have to be written in capitals; VHDL is case-insensitive for identifiers.
An important VHDL predefined attribute for synthesis is the EVENT attribute. Its value reveals
edges of signals.
Mentor Graphics Predefined Attributes
Apart from the VHDL predefined types, Mentor Graphics also supplies a set of predefined
attributes that are specifically helpful for guiding the synthesis process or controlling downstream tools.
2-32
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Attributes
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_vector’LENGTH/2 ;
....
my_vector’MIDDLE
-- returns integer 2
Using Attributes in the Source Code
To indicate where attributes in a VHDL description are useful, consider the following example.
entity masked_parity is
port ( source : in bit_vector (5 downto 0) ;
mask : in bit_vector (5 downto 0) ;
result : out bit
) ;
end masked_parity ;
architecture soso of masked_parity is
begin
process (source, mask)
variable tmp : bit ;
variable masked_source : bit_vector (5
downto 0) ;
begin
masked_source := source and mask ;
tmp := masked_source(0) ;
for i in 1 to 5 loop
tmp := tmp XOR masked_source(i) ;
end loop ;
result <= tmp ;
end process ;
end soso ;
This example calculates the parity of the bits of a source vector, where each bit can be masked.
This VHDL description is correct, but is not very flexible. Suppose the application changes
slightly and requires a different size input. Then the VHDL description has to be modified
significantly, since the range of the vector affects many places in the description. The
information is not concentrated, and there are many dependencies. Attributes can resolve these
dependencies.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-33
Blocks
VHDL Language Features
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 (source’RANGE) ;
result : out bit
) ;
end masked_parity ;
architecture better of masked_parity is
begin
process (source, mask)
variable tmp : bit ;
variable masked_source : bit_vector (source’RANGE) ;
begin
masked_source := source and mask ;
tmp := masked_source(source’LEFT) ;
for i in source’LEFT+1 to source’RIGHT 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.
2-34
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Functions And Procedures
A block is a method to cluster a set of related dataflow statements. Signals, subprograms,
attributes, etc. that are local to the block can be defined in a block declarative region. All
statements in a block are executed concurrently, and thus define a dataflow environment.
architecture xxx of yyy is
signal global_sig ,g1,g2,c bit ;
begin
B1 : block
-- block declarative region
signal local_sig : bit ;
begin
-- block concurrent statements
local_sig <= global_sig ;
-- Block in a block
B2 : block (c=’1’)
-- Block has “GUARD” expression
port (o1,o2 : out bit)-- Block port declarations
port map (o1=>g1,o2=>g2) ;
begin
o1 <= guarded local_sig ;
o2 <= global_sig ;
end block ;
end block ;
end xxx ;
Blocks can be nested, for example.
Signals, ports and generics declared outside the block can be used inside the block, either
directly (as global_sig is used in block B2), or via a port map (as g1 is connected to o1 in
block B2) or generic maps (for generics). There is no real difference between the two methods,
except that the port (generic) map construct is a cleaner coding style which could reduce errors
when using or assigning to global objects.
A block can also have a GUARD expression (c=’1’ in block B2). In that case, an assignment
inside the block that contains the keyword GUARDED will only be executed when the GUARD
expression is TRUE. In the example, o1 only gets the value of local_sig when c=’1’. GUARDED
blocks and assignments provide a interesting alternative to construct latches or flip-flops in the
synthesized circuit. For examples, refer to Registers, Latches and Resets on page 3-1.
Precision RTL Synthesis fully support blocks, with port/generic lists and port/generic maps and
the GUARD options of blocks.
Functions And Procedures
Subprograms (function and procedures) are powerful tools to implement functionality that is
repeatedly used. Functions take a number of arguments that are all inputs to the function, and
return a single value. Procedures take a number of arguments that can be inputs, outputs or
inouts, depending on the direction of the flow of information through the argument. All
statements in functions and procedures are executed sequentially, as in a process. Also,
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-35
Functions And Procedures
VHDL Language Features
variables that are local to the subprogram can be declared in the subprogram. Local signals are
not allowed.
As an example, suppose you would like to add two vectors. In this case, you could define a
function that performs the addition. The following code fragment shows how an addition of two
6-bit vectors is done.
function vector_adder (x : bit_vector(5 downto 0); y : bit_vector(5
downto 0)) return bit_vector(5 downto 0) is
-- declarative region
variable carry : bit ;
variable result : bit_vector(5 downto 0) ;
begin
-- sequential statements
carry := ’0’ ;
for i in 0 to 5 loop
result (i) := x(i) xor y(i) xor carry ;
carry := carry AND (x(i) OR y(i)) OR x(i) AND y(i) ;
end loop ;
return result ;
end vector_adder ;
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.
2-36
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Functions And Procedures
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(x’RANGE) ;
begin
for i in x’RANGE 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 ;
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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-37
Resolution Functions
VHDL Language Features
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 ;
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
(s’LENGTH = 1) then
return s(s’LOW);
else
for i in s’range 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.
2-38
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Resolution Functions
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.
Let’s 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:
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-39
Component Instantiation
VHDL Language Features
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’ ;
begin
for i in a’range 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
2-40
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Component Instantiation
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 ;
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=>addr’length)
port map(clk=>clk, enable=>ena,
reset=>reset, result=>addr) ;
end rtl ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-41
Binding a Component
VHDL Language Features
The generate statement is used here to instantiate the four RAMs.
Components have to be declared before they can be used. This is done in the declaration area of
the architecture, or in a package (see next section). The declaration defines the interface of the
component ports with their type and their direction. Actually this example is just a netlist of
components. We added one dataflow statement (the assignment to ena) to show that structure
and behavior can be mixed in VHDL.
The ports of the component are connected to actual signals (or ports) with the port map
construct. The generics of the component are connected to actual values with the generic map
construct. In this example the generic size is set to 4 with the attribute length on the array addr.
If no generic value was set to size (or if the generic map construct was completely absent),
size gets value 4, as indicated by the initial value on size in the generic list of the component.
It is an error if a generic (or input port) is not connected in a generic map (or port map) construct
and there is no initial value given in the component generic (or port) list.
In the example, the input ports of the component RAM_32x1 are individual bits (a0, a1, a2, a3,
a4). If the input would have been declared as a bit_vector (0 to 4), then the individual bits
could be connected with indexed formal names:
.. port map (a(0) => addr(0), a(1) => addr(1), a(2) => addr(2),
a(3) => addr(3), a(4) => addr(4), ...
or with a sliced formal name:
.. port map (a(0 to 4) => addr(0 to 4), .....
or simply with a full identifier association:
.. port map ( a => addr, .....
Precision RTL Synthesis supports any form of slicing or indexing of formal parameter names,
as long as the VHDL language rules are obeyed (formal name should be static).
Precision RTL Synthesis also supports type-transformation functions in port and generic
associations as long as they are synthesizable. Type transformation functions are not very often
used and so are not explained here.
Binding a Component
The definition of the components counter and RAM_32x1 are not yet given in the example. The
process of giving a contents definition for a component is called binding in VHDL. With
Precision RTL Synthesis, there are four ways to do component binding:
2-42
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Binding a Component
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.
Option 1 - Using a Default Binding
The component counter is a good example of the first option:
entity counter is
generic (size : integer ) ;
port ( clk : in bit ;
enable : in bit ;
reset : in bit ;
result : out bit_vector (size-1 downto 0)
) ;
end counter ;
architecture rtl of counter is
begin
process (clk,reset)
begin
if (reset=’1’) then
result <= (others=>’0’) ;
elsif (clk’event and clk=’1’) then
if (enable=’1’) then
result <= result + "1" ;
end if ;
end if ;
end process ;
end rtl ;
This description only includes behavior. There is no component instantiated, although it is
possible, and it makes hierarchical design possible.
Note that in this case the overloaded ’+’ operator is used on vectors, as defined in the exemplar
package. Also note that an asynchronous reset construction is used to reset the counter value.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-43
Binding a Component
VHDL Language Features
Option 2 - Using a Configuration Specification
The second option gives more freedom to bind an entity to a component. Suppose you have a
counter entity that does exactly what you need, but it is named differently, and (or) has
differently named ports and generics:
entity alternative is
generic (N : integer) ;
port (clock : in bit ;
ena : bit :
reset : bit ;
output : out bit_vector (N-1 downto 0) ) ;
end alternative ;
architecture ex of alternative is
begin
.....
end ex ;
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 don’t 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.
2-44
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Packages
The tool fully supports all forms of configuration specifications that are allowed in the
language.
If no configuration specification is given, the synthesis tools use the default binding as
explained in the first option.
Option 3 - Matching a Component Name to a Library
Cell
In the third option, if you use a component name that matches the name of a cell in the target
technology library, then that cell will be instantiated in the design. In this case, assume that the
name RAM_32x1 is the name of a RAM cell in the target technology library.
Option 4 - Creating a Black Box by Omitting the Entity
The fourth option is to omit declaring an entity for the component. This is helpful when
hierarchy has to be preserved. This technique can be effectively used to maintain hierarchy.
Precision RTL Synthesis generates an empty module for each component it cannot find in the
present file as an entity or as a library cell in the source technology. Empty modules show up as
blocks in the final netlist. They are not touched by the synthesis and optimization process.
Components without a definition can also help to isolate a particular difficult or user-defined
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.
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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-45
Packages
VHDL Language Features
To include functionality from a package into a VHDL description, the use clause is used.
library ieee ;
use ieee.std_logic_1164.all ;
entity xxx is
port ( x : std_logic ; -- type std_logic is known since it
is
-- defined in package
-- std_logic_1164
...
This example shows how the IEEE 1164 standard logic types and functions become accessible
to the description in entity xxx.
This is the general form to include a package in a VHDL description:
library lib ;
use lib.package.selection ;
The use clause is preceded by a library clause. The predefined libraries work and std do not
have to be declared in a library clause before they are used in a use clause. All other libraries
do need to be declared.
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;
2-46
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
VHDL Language Features
Aliases
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(arr’left) and arr(arr’left-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, arr’left-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
function that works correctly both for ascending and descending index ranges. Instead, you
could make an alias of arr, with a known index range, and operate on the alias:
function left_and (arr : std_logic_vector) return std_logic is
alias aliased_arr : std_logic_vector (0 to arr’length-1) is
arr ;
begin
return aliased_arr(0) and aliased_arr(1) ;
end left_and ;
-- Function works for both ascending and descending index
-- ranges of arr.
Precision RTL Synthesis fully supports aliases.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
2-47
Aliases
2-48
VHDL Language Features
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 3
The Art of VHDL Synthesis
This chapter explains the relationship between constructs in VHDL and the logic which is
synthesized. It focuses on coding styles with the best performance for synthesis.
Registers, Latches and Resets
VHDL synthesis produces registered and combinational logic at the RTL level. 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, so that
you understand why registers are generated at certain places and not in others.
Most examples explain the generation of these modules with short VHDL descriptions in a
process. If you are not working in a process, but just in the dataflow area of an architecture in
VHDL, it is possible to generate these modules using predefined procedures in the
exemplar.vhd package.
Level-Sensitive Latch
This first example describes a level-sensitive latch:
signal input_foo, output_foo, ena : bit ;
...
process (ena, input_foo)
begin
if (ena = ’1’) then
output_foo <= input_foo ;
end if ;
end process ;
In this example, the sensitivity list is required, and indicates that the process is executed
whenever the signals ena or input_foo change. Also, since the assignment to the global signal
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-1
Registers, Latches and Resets
The Art of VHDL Synthesis
output_foo is hidden in a conditional clause, output_foo cannot change (will preserve its old
value) if ena is ’0’. If ena is ’1’, output_foo is immediately updated with the value of
input_foo, whenever it 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.
Latches can also be generated in dataflow statements, using a guarded block:
b1 : block (ena=’1’)
begin
output_foo <= GUARDED input_foo ;
end block ;
Edge-Sensitive Flip-Flops
The Event Attribute
An edge triggered flip-flop is generated from a VHDL description only if a signal assignment is
executed on the leading (or on the falling) edge of another signal. For that reason, the condition
under which the assignment is done should include an edge-detecting mechanism. The event
attribute on a signal is the most commonly used edge-detecting mechanism.
The event attribute operates on a signal and returns a boolean. The result is always false,
unless the signal showed a change (edge) in value. If the signal started the process by a change
in value, the event attribute is TRUE all the way through the process.
Here is one example of the event attribute, used in the condition clause in a process. Precision
RTL Synthesis recognizes an edge triggered flip-flop from this behavior, with output_foo
updated only on the leading edge of clk.
signal input_foo, output_foo, clk : bit ;
....
process (clk)
begin
if (clk’event and clk=’1’) then
output_foo <= input_foo ;
end if ;
end process ;
The attribute stable is the boolean inversion of the event attribute. Hence, clk’event is the
same as NOT clk’stable. Precision RTL Synthesis supports both attributes.
3-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
Registers, Latches and Resets
Synchronous Sets And Resets
All conditional assignments to signal output_foo inside the if clause translate into
combinational logic in front of the D-input of the flip-flop. For instance, we could make a
synchronous reset on the flip-flop by doing a conditional assignment to output_foo:
signal input_foo, output_foo, clk, reset : bit ;
...
process (clk)
begin
if (clk’event and clk = ’1’) then
if reset = ’1’ then
output_foo <= ’0’ ;
else
output_foo <= input_foo ;
end if ;
end if ;
end process ;
Signals reset and input_foo do not have to be on the sensitivity list (although it is allowed)
since a change in their values does not result in any action inside the process.
Alternatively, dataflow statements could be used to specify a synchronous reset, using a
GUARDED block and a conditional signal assignment.
b3 : block (clk’event and clk=’1’)
begin
output_foo <= GUARDED ’0’ when reset=’1’ else
input_foo ;
end block ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-3
Registers, Latches and Resets
The Art of VHDL Synthesis
Asynchronous Sets And Resets
If the reset signal should have immediate effect on the output, but the assignment to
output_foo from input_foo should happen only on the leading clock edge, an asynchronous
reset is required. Here is the process:
signal input_foo, output_foo, clk, reset : bit ;
...
process (clk,reset)
begin
if (reset = ’1’) then
output_foo <= ’0’ ;
elsif (clk’event and clk = ’1’) then
output_foo <= input_foo ;
end if ;
end process ;
Now reset HAS TO BE on the sensitivity list! If it were not there, VHDL semantics require that
the process should not start if reset changes. It would only start if clk changes. That means that
if reset becomes ’1’, output_foo would be set to ’0’ if clk either goes up, or goes down, but
not before any change of clk. This behavior cannot be synthesized into logic. Precision RTL
Synthesis issues an error message that reminds you to put reset on the sensitivity list.
Asynchronous set and reset can both be used. It is also possible to have expressions instead of
the fixed ’0’ or ’1’ in the assignments to output_foo in the reset and set conditions. This
results in combinational logic driving the set and reset input of the flip-flop of the target signal.
The following code fragment shows the structure of such a process:
process (clock, asynchronously_used_signals )
begin
if (boolean_expression) then
asynchronous signal_assignments
elsif (boolean_expression) then
asynchronous signal_assignments
elsif (clock’event and clock = constant ) then
synchronous signal_assignments
end if ;
end process ;
There can be several asynchronous elsif clauses, but the synchronous elsif clause (if present)
has to be the last one in the if clause. A flip-flop is generated for each signal that is assigned in
the synchronous signal assignment. The asynchronous clauses result in combinational logic that
drives the set and reset inputs of the flip-flops. If there is no synchronous clause, all logic
becomes combinational.
3-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
Registers, Latches and Resets
Clock Enable
It is also possible to specify an enable signal in a process. Some technologies have a special
enable pin on their basic building blocks. Precision RTL Synthesis recognize the function of the
enable from the VHDL description and generates a flip-flop with an enable signal from the
following code fragment:
signal input_foo, output_foo, enable, clk : bit ;
...
process (clk)
begin
if (clk’event and clk=’1’) then
if (enable=’1’) then
output_foo <= input_foo ;
end if ;
end if ;
end process ;
In dataflow statements, a clock enable can be constructed with a GUARDED block and a
conditional signals assignment.
b4: block (clk’event and clk=’1’)
begin
output_foo <= GUARDED input_foo when enable=’1’
else output_foo ;
end block ;
Wait Statements
Another way to generate registers is by using the wait until statement. The wait until
clause can be used in a process, and is synthesizable, as long as all of the control paths inside the
process contain at least one wait statement. The following code fragment generates an edge
triggered flip-flop between signal input_foo and output_foo:
signal input_foo, output_foo, clk : bit ;
...
process
begin
wait until clk’event and clk=’1’ ;
output_foo <= input_foo ;
end process ;
There is no sensitivity list on this process. In VHDL, a process can have a sensitivity list or a
wait statement, but not both. In this example, the process is executed if clk changes since clk is
present in the wait condition. Also, the wait condition can be simplified to wait until
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-5
Registers, Latches and Resets
The Art of VHDL Synthesis
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.
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
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 (clk’event 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 (clk’event and clk=’1’) then
a := input_foo ;
b := a ;
output_foo <= b ;
end if ;
end process ;
Here, a and b are assigned before used, and therefore do not generate flip-flops. Instead, they
generate a single wire. Only one flip-flop remains in between input_foo and output_foo
because of the signal assignment in the clocked process.
3-6
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
Assigning I/O Buffers From VHDL
Predefined Flip-flops and Latches
Flip-flops and latches can also be generated by using predefined procedures from the exemplar
package. These procedure calls cause Precision RTL Synthesis to instantiate the required flipflop or D-latch. There are various forms of these procedures available, including versions with
asynchronous preset and clear.
Assigning I/O Buffers From VHDL
By default, Precision RTL Synthesis automatically assigns I/O buffers to the ports of you design
unless you turn off the feature with the command setup_design -addio=false. And, you can
overwrite any default buffer assignment that Precision RTL Synthesis may make by assigning
the buffer_sig attribute to a port or a net in the VHDL. 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 VHDL 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 code fragment illustrates how to assign a buffer named “CLOCK_BUFFER” to a
clock port in the VHDL source.
entity example is
port ( inp, clk
: in std_logic;
outp
: out std_logic;
inoutp : inout std_logic
);
attribute buffer_sig : string ;
attribute buffer_sig of clk:signal is “CLOCK_BUFFER” ;
end example;
Port clk is connected to the input of the external clock buffer CLOCK_BUFFER. An intermediate
node called manual_clk appears on CLOCK_BUFFER’s output.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-7
Assigning I/O Buffers From VHDL
The Art of VHDL Synthesis
Buffer Assignment Using Component Instantiation
It is also possible to instantiate buffers in the VHDL source file with component instantiation. In
particular, if you want a specific complex input or output buffer to be present on a specific input
or output, component instantiation is a very powerful method:
entity special is
port ( inp : in std_logic ;
clk : in std_logic ;
...
outp : out std_logic;
inoutp : inout std_logic
) ;
end special ;
architecture rtl of special is
component OUTPUT_FLIPFLOP
port ( c,d,t : in std_logic ;
o : out std_logic
) ;
end component ;
component INPUT_BUFFER
port ( i : in std_logic ;
o : out std_logic
) ;
end component ;
signal intern_in, intern_out, io_control :
std_logic ;
begin
b1 : OUTPUT_FLIPFLOP port map (c=>clk,
d=>intern_out,
t=>io_control, o=>inoutp)
;
b2 : INPUT_BUFFER port map (i=>inoutp,
o=>intern_in) ;
...
end rtl ;
In this example, component instantiation forces an OUTPUT_FLIPFLOP buffer on the
bidirectional pin inoutp. Also an input buffer INPUT_BUFFER is specified to pick up the value
from this pin to be used internally.
Precision RTL Synthesis will look for definitions of VHDL instantiated components in the
source library that is defined in the setup_design command.
3-8
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
Three-state Buffers
Three-state Buffers
Three-state buffers and bidirectional buffers (covered in the next section) are very easy to
generate from a VHDL description.
A disabled three-state buffer will be in a high-impedance state. VHDL itself does not predefine
a high-impedance state, but the IEEE 1164 standard logic package defines the ’Z’ character
literal to have a behavior that exactly resembles the behavior of the high-impedance state of a
three-state buffer. A signal (a port or an internal signal) of the standard logic type can be
assigned a ’Z’ value. The synthesis tools recognize the ’Z’ value and creates a three-state
buffer from a conditional assignment with ’Z’:
entity three-state is
port (
input_signal : in std_logic ;
ena : in std_logic ;
output_signal : out std_logic
) ;
end three-state ;
architecture rtl of three-state is
begin
output_signal <= input_signal when ena = ’1’ else
’Z’ ;
end rtl ;
In the when clause, both input_signal and the condition ena=’1’ can be full expressions.
Precision RTL Synthesis generates combinational logic driving the input or the enable of the
three-state buffer for these expressions.
Normally, simultaneous assignment to one signal in VHDL is not allowed for synthesis, since it
would cause data conflicts. However, if a conditional ’Z’ is assigned in each assignment,
simultaneous assignment resembles multiple three-state buffers driving the same bus.
entity three-state is
port (
input_signal_1, input_signal_2 : in std_logic ;
ena_1, ena_2 : in std_logic ;
output_signal : out std_logic
) ;
end three-state ;
architecture rtl of three-state is
begin
output_signal <= input_signal_1 when ena_1 = ’1’ else ’Z’ ;
output_signal <= input_signal_2 when ena_2 = ’1’ else ’Z’ ;
end rtl ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-9
Three-state Buffers
The Art of VHDL Synthesis
Precision RTL Synthesis does not check for bus-conflicts on three-state assignments. Therefore,
make sure that the enable signals of the three-state drivers are never simultaneously active. In
this example, ena_1 and ena_2 should never be ’1’ simultaneously.
These examples show assignments to output ports (device ports). It is also possible to do the
assignments to an internal signal. This will create internal buses in such a case.
Three-state buffers can also be generated from process statements:
driver1 : process (ena_1, input_signal_1) begin
if (ena_1=’1’) then
output_signal <= input_signal_1 ;
else
output_signal <= ’Z’ ;
end if ;
end process ;
driver2 : process (ena_2, input_signal_2) begin
if (ena_2=’1’) then
output_signal <= input_signal_2 ;
else
output_signal <= ’Z’ ;
end if ;
end process ;
If the target technology does not have any internal three-state drivers, then use one of the
following methods:
•
•
3-10
Transform the three-state buffers into regular logic with the -tristate batch mode
option.
Set the tristate_map variable is set to TRUE in the interactive shell.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
Bidirectional Buffers
Bidirectional Buffers
Bidirectional I/O buffers will be created by Precision RTL Synthesis if an external port is both
used and assigned inside the architecture. Here is an example:
entity bidir_function is
port (
bidir_port : inout std_logic ;
ena : in std_logic ;
...
) ;
end bidir_function ;
architecture rtl of bidir_function is
signal internal_signal, internal_input : std_logic
;
begin
bidir_port <= internal_signal when ena = ’1’ else
’Z’ ;
internal_input <= bidir_port ;
...
-- use internal_input
...
-- generate internal_signal
end rtl ;
The difference with the previous example is that in this case, the output itself is used again
internally. Note that for that reason, the port bidir_port is declared to be inout.
The enable signal ena could also be generated from inside the architecture, instead of being a
primary input as in this example.
Precision RTL Synthesis selects a suitable bidirectional buffer 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.
Buses
The examples in the previous sections all use single bits as signals. In reality, buses are often
used: arrays of bits with (multiple) three-state drivers. In this case, the type of the bus signal
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-11
State Machines
The Art of VHDL Synthesis
should be std_logic_vector. All examples given still apply for buses, although the ’Z’
character literal now has to be a string literal. Here is one example:
entity three-state is
port (
input_signal_1, input_signal_2 : in
std_logic_vector (7 downto 0) ;
ena_1, ena_2 : in std_logic ;
output_signal : out std_logic_vector(7 downto
0)
) ;
end three-state ;
architecture rtl of
begin
output_signal <=
else
output_signal <=
else
end rtl ;
three-state is
input_signal_1 when ena_1 = ’1’
“ZZZZZZZZ” ;
input_signal_2 when ena_2=’1’
“ZZZZZZZZ” ;
This code generates two sets of eight three-state buffers, two on each line of the bus
output_signal.
As with single three-state drivers, buses can be an internal signal, or ports. Similarly, buses can
be created using processes.
State Machines
This section describes a basic form of a general state machine description. VHDL coding style,
power-up and reset, state encoding and other issues will be discussed.
General State Machine Description
There are various ways to describe a state machine in VHDL. This section will only show the
most commonly used description.
The possible states of the state machine are listed in an enumerated type. A signal of this type
(present_state) defines in which state the state machine appears. In a case statement of one
process, a second signal (next_state) is updated depending on present_state and the inputs. In
the same case statement, the outputs are also updated. Another process updates present_state
with next_state on a clock edge, and takes care of the state machine reset.
3-12
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
State Machines
Here is the VHDL code for such a typical state machine description. This design implements a
RAS-CAS controller for DRAM refresh circuitry.
entity ras_cas is
port ( clk, cs, refresh, reset : in bit ;
ras, cas, ready : out bit ) ;
end ras_cas ;
architecture rtl of ras_cas is
-- Define the possible states of the state machine
type state_type is (s0, s1, s2, s3, s4) ;
signal present_state, next_state : state_type ;
begin
registers : process (clk, reset)
begin
-- process to update the present state
if (reset=’1’) then
present_state <= s0 ;
elsif clk’event and clk = ’1’ then
present_state <= next_state;
end if ;
end process ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-13
State Machines
The Art of VHDL Synthesis
transitions : process (present_state, refresh, cs)
begin
-- process to calculate the next state and the outputs
case present_state is
when s0 =>
ras <= ’1’ ; cas <= ’1’ ; ready <= ’1’ ;
if (refresh = ’1’) then
next_state <= s3 ;
elsif (cs = ’1’) then
next_state <= s1 ;
else
next_state <= s0 ;
end if ;
when s1 =>
ras <= ’0’ ; cas <= ’1’ ; ready <= ’0’ ;
next_state <= s2 ;
when s2 =>
ras <= ’0’ ; cas <= ’0’ ; ready <= ’0’ ;
if (cs = ’0’) then
next_state <= s0 ;
else
next_state <= s2 ;
end if ;
when s3 =>
ras <= ’1’ ; cas <= ’0’ ; ready <= ’0’ ;
next_state <= s4 ;
when s4 =>
ras <= ’0’ ; cas <= ’0’ ; ready <= ’0’ ;
next_state <= s0 ;
end case ;
end process ;
end rtl ;
VHDL Coding Style For State Machines
There are various issues of coding style for state-machines that might affect performance of the
synthesized result.
A first issue is the form of state machine that will be created. There are basically two forms of
state machines, Mealy machines and Moore machines. In a Moore machine, the outputs do not
directly depend on the inputs, only on the present state. In a Mealy machine, the outputs depend
directly on the present state and the inputs.
In the RAS-CAS state machine described in the previous section, the outputs ras, cas and ready
only depend on the value of present_state. This means that the description implements a
Moore machine. If the outputs would be set to different values under the input conditions in the
if statements inside the case statement, a Mealy machine would have been created. In a Moore
3-14
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
State Machines
machine, there is always a register in between the inputs and the outputs. This does not have to
be the case in Mealy machines.
A second issue in coding style is the case statement that has been used to test the
present_state. A case statement is more efficient than a if-then-elsif-else statement,
since that would build a priority encoder to test the state (which could mean more logic in the
implementation). It is also important to note that there is no OTHERS entry in the case statement.
An OTHERS entry could create extra logic if not all the states are mentioned in the case
statement.
This extra logic will have to determine if the machine is in any of the already mentioned states
or not. Unless there are a number of states where the state machine behaves exactly the same
(which is not likely since then you could reduce the state machine easily) an OTHERS entry is not
beneficial and will, in general, create more logic than is required.
A third issue is the assignments to outputs and next_state in the state transition process.
VHDL defines that any signal that is not assigned anything should retain its value. This means
that if you forget to assign something to an output (or 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 to 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:
"file.vhd", line xx : Warning, latches might be needed for XXX.
Make sure to always assign something to 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 VHDL on this issue.
Power-up And Reset
For simulation, the state machine will initialize into the leftmost value of the enumeration type,
but for synthesis it is unknown in which state the machine powers up. Since Precision Synthesis
does state encoding on the enumeration type of the state machine, the state machine could even
power up in a state that is not even defined in VHDL. Therefore, to get simulation and synthesis
consistency, it is very important to supply a reset to the state machine.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-15
Arithmetic And Relational Logic
The Art of VHDL Synthesis
In the example state machine shown in General State Machine, an asynchronous reset is used,
but a synchronous reset would be possible. Registers, Latches, and Reset explains more about
how to specify resets on registers in VHDL.
Encoding Methods
Precision Synthesis has several methods to control encoding for state machines that use an
enumerated type for the declaration of the states. In this chapter, the section Enumerated Types
discusses state encoding methods in detail.
Arithmetic And Relational Logic
Logic synthesis is very powerful in optimizing “random” combinational behavior, but has
problems with logic which is arithmetic in nature. Often special precautions have to be taken
into consideration to avoid ending up with inefficient logic or excessive run times.
Alternatively, macros may be used to implement these functions.
Precision RTL Synthesis supports the overloaded operators “+”, “-”, “*”, and “abs”. These
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. For example, the following code segments do not result in logic,
but assign a constant integer 13 to signal foo.
function add_sub (a: integer, b: integer, add : boolean)
return integer is
begin
if (add = TRUE) then
return a + b ;
else
return a - b ;
end if ;
end my_adder ;
signal foo : integer ;
constant left : integer := 12 ;
....
foo <= add_sub (left,6,TRUE) - 5 ;-- Expression evaluates to 13
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 adder is generated. If you use ranged
3-16
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
Arithmetic And Relational Logic
integers, the size of the adder is defined so that the entire range can be represented in bits. For
example, if variables a and b do not evaluate to constants, the following code segment:
variable a, b, c : integer ;
c := a + b ;
generates a 32-bit (signed) adder, but
variable a, b, c : integer range 0 to 255 ;
c := a + b ;
generates an 8-bit (unsigned) adder.
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 subtracter. Same remarks apply as with the “+”
operator.
The pre-defined “*” multiplication on integers generates a multiplier. Full multiplication is
supported when a module generator is used.
The pre-defined “/” division 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 on integers is only supported if both operands are constant.
“=,” “/=,” “<,” “>,” “<=,” and “>=” generate comparators with the appropriate functionality.
Operations on integers are done in two-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. The predefined add, add2, sub,
sub2, +, and - on bit_vector and std_logic_vector types are examples of functions which
do this. For descriptions of these functions, see the topic Predefined Functions in Chapter 4.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-17
Arithmetic And Relational Logic
The Art of VHDL Synthesis
Resource Sharing
Precision RTL Synthesis performs automatic common sub-expression elimination for
arithmetic and boolean expressions. The following example has two adders in the code, but they
are adding the same numbers, a and b.
signal a,b,c,d : integer range 0 to 255 ;
...
process (a,b,c,d) begin
if ( a+b = c ) then
<statements>
elsif ( a+b = d) then <more_statements>
end if ;
end process ;
After automatic common subexpression elimination, only one adder will be used in the final
circuit. Thus, it would create the same logic as the following example.
process
(a,b.c.d)
variable tmp : integer range 0 to 255 ;
begin
tmp := a+b ;
if ( tmp = c ) then <statements>
elsif ( tmp = d) then <more_statements>
end if ;
end process ;
Proper use of parentheses guide the synthesis tools in eliminating common subexpressions. The
following code segment, for example, can be properly modified to share an adder.
o1 <= a + b + c;
o2 <= b + c + d;
Using parentheses, the logic can share an adder for inputs b and c, as shown below.
o1 <= a + (b + c);
o2 <= (b + c) + d;
3-18
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
Arithmetic And Relational Logic
Precision RTL Synthesis automatically performs a limited amount of resource sharing of
arithmetic expressions that are mutually exclusive. Consider the following example:
process (a,b,c,test)
if (test=TRUE)
o <= a +
else
o <= a +
end if ;
end process ;
begin
then
b ;
c ;
Initially, two adders and a multiplexer are created, but after the automatic resource sharing one
adder is reduced, and the final circuit is same as would be created from the following code:
process (a,b,c,test)
variable tmp :
begin
if (test=TRUE)
tmp := b
else
tmp := c
end if ;
o <= a + tmp ;
end process ;
begin
integer range 0 to 255 ;
then
;
;
The limitations of automatic resource sharing are as follows:
•
•
Complex operators must drive the same signal.
Complex operators must be of the same type (for example, two adders) and have the
same width (for example, 8-bit adders).
Ranged Integers
It is best to use ranged integers instead of “unbound” integers. In VHDL, an unbound integer
(integer with no range specified) is guaranteed to include the range -2147483647 to
+2147483647. This means that at least 32 bits are needed to implement an object of this type.
Precision RTL Synthesis has to generate large amounts of logic in order to perform operations
on these objects. Some of this logic may become redundant and get eliminated in the
optimization process, but the run time is slowed down considerably.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-19
Arithmetic And Relational Logic
The Art of VHDL Synthesis
If you use integers as ports, all logic has to remain in place and synthesis algorithms are faced
with a complex problem. Therefore, if you do not need the full range of an integer, specify the
range that you need in the object declaration:
signal small_int : integer range 255 downto 0 ;
small_int
only uses eight bits in this example, instead of the 32 bits if the range was not
specified.
Advanced Design Optimization
Module generation, resource sharing and the use of ranged integers are all examples of how a
particular design can be improved for synthesis without changing the functionality. Sometimes
it is possible to change the functionality of the design slightly, without violating the design
specification constraints, and improve the implementation for synthesis. This requires
understanding of VHDL and what kind of circuitry is generated, as well as understanding of the
specifications of the design. One example of this is given, in the form of a loadable loop
counter.
Often, applications involve a counter that counts up to a input signal value, and if it reaches that
value, some actions are needed and the counter is reset to 0.
process begin
wait until clk’event and clk=’1’ ;
if (count = input_signal) then
count <= 0 ;
else
count <= count + 1 ;
end if ;
end process ;
In this example, Precision RTL Synthesis builds an incrementer and a full-size comparator that
compares the incoming signal with the counter value.
In this example, a full comparator has to be created since the VHDL description indicates that
the comparison has to be done each clock cycle. If the specification allows that the comparison
3-20
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
Technology-Specific Macros
is only done during the reset, we could re-code the VHDL and reduce the overall circuit size by
loading the counter with the input_signal, and then counting down to zero:
process begin
wait until clk’event and clk=’1’ ;
if (count = 0) then
count <= input_signal ;
else
count <= count - 1 ;
end if ;
end process ;
Here, 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.
This is a single example of how to improve synthesis results by changing the functionality of the
design, while staying within the freedom of the design specification. However, the possibilities
are endless, and a designer should try to use the freedom in the design specification to get truly
optimal synthesis performance.
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.
This section will explain how to instantiate technology specific macros in the VHDL source to
assure full control over the synthesized logic. The VHDL description will become technology
dependent.
Note that Precision RTL Synthesis does automatic inference of technology specific macros
from standard (technology independent) arithmetic and relational operators when Module
Generation is used. However, if a particular hard-macro is required, or there is no Module
Generator available for the your technology, manual instantiation will be needed.
With Precision RTL Synthesis, it is possible to use component instantiation of soft macros or
hard macros in the target technology, and use these high performance macros. 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
anymore.
As an example, suppose you would like to build an 8-bit counter in the device family FPGAX.
There is a hard-macro available in the FPGAX library that will do this. Call it the COUNT8. In order
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-21
Multiplexers and Selectors
The Art of VHDL Synthesis
to directly instantiate this macro in VHDL, declare a component COUNT8 and instantiate it with a
component instantiation statement.
component COUNT8
port (pe, c, ce, rd : in std_logic ;
d : in std_logic_vector (7 downto 0) ;
q : out std_logic_vector (7 downto 0)
) ;
end component ;
...
-- clock, count_enable, reset, load, load_data and output are signals
-- in the VHDL source
...
counter_1 : COUNT8 port map (c=>clock, ce=>count_enable,
rd=>reset, pe=>load, d=>load_data, q=>output) ;
Precision RTL Synthesis synthesizes this component as a black-box, since there is no
entity/architecture description. The black box appears in the output file as a symbol.
Multiplexers and Selectors
From a case statement, Precision RTL Synthesis creates either muxes or selector circuits. In the
following example, a selector circuit is created.
case test_vector is
when “000" =>
o <= bus(0) ;
when “001" | ”010" | “100" => o <= bus(1) ;
when “011" | ”101" | “110" => o <= bus(2) ;
when “111" =>
o <= bus(3) ;
end case ;
If the selector value is the index to be selected from an array, the selector resembles a
multiplexer. It is still possible to express this in a case statement, but it is also possible to use a
variable indexed array. For example, if an integer value defines the index of an array, a variable
indexed array creates the multiplexer function:
signal vec : std_logic_vector (15 downto 0) ;
signal o : std_logic ;
signal i : integer range 0 to 15 ;
...
o <= vec(i) ;
3-22
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
ROMs, PLAs And Decoders
selects bit i out of the vector vec. This is equivalent to the more complex writing style with a
case statement:
case i is
when 0 =>
when 1 =>
when 2 =>
when 3 =>
...
end case ;
o
o
o
o
<=
<=
<=
<=
vec(0)
vec(1)
vec(2)
vec(3)
;
;
;
;
For the prior description, Precision RTL Synthesis creates the same multiplexers as they do for
the variable-indexed array.
Precision RTL Synthesis fully supports variable-indexed arrays, including index values that are
enumerated types rather then integers, and index values that are expressions rather then singe
identifiers.
ROMs, PLAs And Decoders
There are many ways to express decoder behavior from a ROM or PLA table. The clearest
description of a ROM would be a case statement with the ROM addresses in the case
conditions, and the ROM data in the case statements. In this section, two other forms are
discussed:
1. Decoder as a constant array of arrays.
2. Decoder as a constant two-dimensional array.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-23
ROMs, PLAs And Decoders
The Art of VHDL Synthesis
The following is an example of a ROM implemented with an array of array type. The ROM
defines a hexadecimal to 7-segment decoder:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY async_sevenseg IS
PORT(
addr : IN
unsigned (3 DOWNTO 0);
data : OUT
unsigned (6 DOWNTO 0)
);
END async_sevenseg ;
ARCHITECTURE rtl OF async_sevenseg IS
SUBTYPE seven_segment IS unsigned(6 DOWNTO 0) ;
TYPE rom_type IS ARRAY (natural RANGE <>) OF seven_segment ;
CONSTANT hex_to_7 : rom_type (0 TO 15) :=
("0111111", -- 0
"0011000", -- 1
"1101101", -- 2 Display segment index numbers :
"1111100", -- 3 2
"1011010", -- 4 1 3
"1110110", -- 5 6
"1110111", -- 6 0 4
"0011100", -- 7 5
"1111111", -- 8
"1111110", -- 9
"1011111", -- A
"1110011", -- B
"0100111", -- C
"1111001", -- D
"1100111", -- E
"1000111") ; -- F
BEGIN
data <= hex_to_7 (to_integer(addr)) ;
END rtl;
The ROM with array of array implementation has the advantage that it can be accessed via a
simple integer value as its address. A disadvantage is that each time another ROM is defined, a
new element type (seven_segment) and a new ROM type (rom_type) have to be defined.
PLA descriptions should allow a ’X’ or ’-’ dont-care value in the input field, to indicate a
product lines’ insensitivity for a particular input. You cannot use a case statement for a PLA
3-24
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of VHDL Synthesis
ROMs, PLAs And Decoders
with dont cares in the input field since a comparison with a value that is not ’0’ or ’1’ will
return FALSE in a case condition (as opposed to just ignoring the input). Instead, a small
procedure or function is needed that explicitly defines comparisons to ’X’ or ’-’. The
following example describes such a procedure. First, a general 2-dimensional PLA array type is
declared.
type std_logic_pla is array (natural range <>, natural range <>)
of std_logic;
...
procedure pla_table (constant invec: std_logic_vector;
signal outvec: out std_logic_vector;
constant table: std_logic_pla) is
variable x : std_logic_vector (table’range(1)) ; -- product lines
variable y : std_logic_vector (outvec’range) ;
-- outputs
variable b : std_logic ;
begin
assert (invec’length + outvec’length = table’length(2))
report “Size of Inputs and Outputs do not match table size”
severity ERROR ;
-- Calculate the AND plane
x := (others=>’1’) ;
for i in table’range(1) loop
for j in invec’range loop
b := table (i,table’left(2)-invec’left+j) ;
if (b=’1’) then
x(i) := x(i) AND invec (j) ;
elsif (b=’0’) then
x(i) := x(i) AND NOT invec(j) ;
end if ;
-- If b is not ’0’ or ’1’ (e.g. ’-’) product line is insensitive to
invec(j)
end loop ;
end loop ;
-- Calculate the OR plane
y := (others=>’0’) ;
for i in table’range(1) loop
for j in outvec’range loop
b := table(i,table’right(2)-outvec’right+j) ;
if (b=’1’) then
y(j) := y(j) OR x(i);
end if ;
end loop ;
end loop ;
outvec <= y ;
end pla_table ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
3-25
ROMs, PLAs And Decoders
The Art of VHDL Synthesis
Once the two-dimensional array type and the PLA procedure are defined, it is easy to generate
and use PLAs (or ROMs). As a simple example, here is a PLA description of a decoder that
returns the position of the first ’1’ in an array. The PLA has five product lines (first dimension)
and seven IOs (four inputs and three outputs) (second dimension).
constant pos_of_fist_one : std_logic_pla (4 downto 0, 6 downto 0) :=
(“1---000",-- first ’1’ is at position 0
“01--001",-- first ’1’ is at position 1
“001-010",-- first ’1’ is at position 2
“0001011",-- first ’1’ is at position 3
“0000111") ;-- There is no ’1’ in the input
signal test_vector : std_logic_vector (3 downto 0) ;
signal result_vector : std_logic_vector (2 downto 0) ;
...
-- Now use the pla table procedure with PLA pos_of_first_one
-- test_vector is the input of the PLA, result_vector the output.
...
pla_table ( test_vector, result_vector, pos_of_first_one) ;
The PLA could have been defined in a array-of-array type also, just as the ROM described
above. A procedure or function for the PLA description will always be necessary to resolve the
dont-care information in the PLA input field.
Precision RTL Synthesis will do a considerable amount of compile-time constant propagation
on each call to the procedure pla_table. This does not affect the final circuit result at all. It just
adds the possibility to specify dont-care information in the PLA input table. In fact, a ROM
described with an array-of-array type and a variable integer index as its address will produce the
same circuit as the ROM specified in a two-dimensional array and using the pla_table
procedure. If the modeled ROM or PLA becomes large, consider a technology-specific solution
by directly instantiating a ROM or PLA component in the VHDL description. Many
FPGA/CPLD vendors supply ROM and/or PLA modules in their library for this purpose.
3-26
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 4
The VHDL Environment
This chapter discusses Precision RTL Synthesis and the VHDL tool environment, including
search paths, interfacing with other VHDL tools, and the exemplar package.
Entity and Package Handling
Packages and entities in VHDL are stored in libraries. You can load VHDL files (with packages
and entities) separately into a directory that is assigned as a resource library.
An example of a predefined package is the package STANDARD (which is
pre-defined for VHDL), that Precision RTL Synthesis loads from file standard.vhd in
<precision install directory>/pkgs/techdata/vhdl.
Precision RTL Synthesis can handle either VHDL IEEE 1076-1987 or IEEE 1076-1993 dialects
of VHDL. The default is 87. To run 93-style VHDL, use the batch mode option -vhdl_93.
Note: Precision RTL Synthesis does not handle all 93 style features. The most commonly used
features of the ’93 extension: shifter and rotator operators, xnor operator and extended
identifiers are supported.
If your design is split into multiple source files, you need to read them in the proper order so that
all terms are defined before they are used in the design. For example, if there is a package
declaration in one file that must be used by the whole design, that file must be read first.
Entity Compiled as the Design Root
When the VHDL source is read, Precision RTL Synthesis starts compiling the first file listed in
the file_input_list, then compiles the second file, and so on. By default, the last entity compiled
in the source files is used as the top-level entity.
After the root (top) entity is found, Precision RTL Synthesis tries to find a matching
architecture. By default, the it will choose the LAST architecture described in the source VHDL
file that matches the top-level entity.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-1
Entity and Package Handling
The VHDL Environment
Finding Definitions of Components
In order to instantiate an entity into a VHDL description, you must first declare a component for
it. If you use a component instantiation in your VHDL design, Precision RTL Synthesis tries to
find the definition of that component. There are three possibilities.
1. The component is a cell in a source technology library.
2. The component has a matching (named) entity in the VHDL source
3. The component has no definition.
If a source technology is specified, then the component in the source technology library is
searched for. This is especially helpful if the component represents a particular macro in the
source technology.
If the component is not present in the source technology, Precision RTL Synthesis tries to find
an entity and architecture for it. The entity (and architecture) could be present in the same file,
or in an included VHDL file.
If Precision RTL Synthesis cannot find a matching entity for the component, then the contents
of the component are undefined, and the following warning is issued:
Warning, component component_name has no definition
Working with components without a definition can be useful if a particular module of the design
is not synthesizable. A clock generator or a delay-module is an example of this. The contents of
that module should be provided separately to the physical implementation tools. Leaving
components undefined is also useful in two other cases:
1. To preserve hierarchy through the synthesis process.
2. For using hard and soft macros in the target technology.
It is possible to explicitly leave the contents of a component empty, even though there is a
entity/architecture for it or a cell in the source technology library. In this case, you should
specify the boolean attribute dont_touch on the component, or on the corresponding entity.
4-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
Entity and Package Handling
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.
How to Use Packages
A functionality described in a VHDL package is included into the VHDL design using the use
clause. This is the general form of the use clause:
library lib ;
use lib.package.selection ;
The use clause is preceded by a library clause. There are predefined libraries work and std that
do not have to be declared in a library clause before they are used in a use clause. All other
libraries need the top to be declared. Library std is normally only used to include packages
predefined in VHDL1076, but library work is free to be used for any user-defined packages.
User-defined library names are also allowed.
If a particular package is not found in the specified library, Precision RTL Synthesis completes
the following steps to find the package:
1. The current work library is searched for the package.
2. If the package is not there, Precision RTL Synthesis searches for a file with the name
package.vhd in the present working directory. The present working directory is the
directory where Precision RTL Synthesis was invoked.
3. If the package is not there, Precision RTL Synthesis searches the directories specified by
the
-search_path switch on the setup_design command. This switch is accessed via the
GUI from the Tools > Set Options... pulldown menu.
4. If the file is not there, Precision RTL Synthesis tries to find the package in the
<precision install directory>/pkgs/techdata/vhdl directory and checks if the
file is a pre-defined package.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-3
Interfacing With Other VHDL Tools
The VHDL Environment
5. If the file is not there, Precision RTL Synthesis issues an error message that the package
can not be found.
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
loaded into the synthesis tools and can be used in the VHDL description.
As an example, the IEEE 1164 std_logic_1164 package (that defines the multi-valued logic
types that are often used for circuit design), is included with the following statements:
library ieee ;
use ieee.std_logic_1164.all ;
This package is loaded from the file:
<precision install directory>/pkgs/techdata/vhdl/ex_ii64.vhd.
This file contains only the declarations of the functions of the std_logic_1164 package. The
bodies of the functions are built into Precision RTL Synthesis for synthesis efficiency.
The contents of the package you include with a use clause becomes visible and is usable only
within the scope where you use the use clause. The VHDL scoping rules are not explained in
this manual. However, if you start a new entity (and architecture), always make sure that you
include the packages you need with use clauses just before the entity.
Interfacing With Other VHDL Tools
The VHDL parsers in Precision RTL Synthesis are compliant with the IEEE VHDL 1076-1987
standard. Hence, apart from the VHDL restrictions for synthesis, interfacing with tools that
generate VHDL or operate on VHDL should not introduce compatibility problems.
However, since VHDL 1076 does not define file handling, there might be mismatches in the
way the tools handle files. Many VHDL simulators incorporate a directory structure to store
separately compiled VHDL files. Precision RTL Synthesis does not use separate compilation of
VHDL files. Therefore, all packages and components that are used for a VHDL design
description should be identified before running Precision RTL Synthesis, as explained in the
previous section.
VHDL Simulators
You should always load the packages and entities in your design into the simulator prior to
simulating the root entity. For simulation, the exemplar and exemplar_1164 packages can be
found in the <precision install directory>/pkgs/techdata/vhdl directory. The files are
named exemplar.vhd and ex_1164.vhd, respectively. Refer to the topic The exemplar
Packages for more information on these packages.
4-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
Interfacing With Other VHDL Tools
Post-Synthesis Functional Simulation
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. Then, use the batch mode effort=reformat switch to produce structural VHDL for simulation. The flow is as follows
(assuming Apex II as the target technology for this example):
1. VHDL synthesis with Precision RTL Synthesis:
spectrum my_design.vhd my_design.edf -target=apexii effort=exhaustive -report=2
2. Produce VHDL netlist:
spectrum my_design.edf my_test.vhd -source=asic target=asic -effort=reformat -report=2
This produces the structural VHDL file my_test.vhd, which may now be simulated.
Precision RTL Synthesis synthesizes all port types into single-bit values. These get written out
in VHDL as ports of type std_logic. The original port types are not preserved.
In Precision RTL Synthesis, the same design can be written into multiple files in multiple
formats. After optimization, choose the appropriate netlist output format for the target
technology; then, you can write a VHDL description of the same synthesized design. By using a
simulatable library of the target technology, this VHDL output can be simulated. The sequence
of synthesis statements should be similar to the following:
load_lib asic
read original.vhd
optimize -tar asic <other options>
write synthesized.edf -- required for target
technology
write synthesized.vhd -- can be used for simulation.
When doing synthesis from a VHDL description, one goal of post-synthesis VHDL simulation
is to simulate the design with the original set of ports (same type, io mode etc.).
•
Use the batch mode option -vhdl_wrapper=filename.
•
Use the create_wrapper interactive shell option to create the wrapper file.
The wrapper consists of an architecture (that connects to the original entity) that instantiates a
component that refers to the synthesized description. Type-conversion functions connect ports
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-5
Interfacing With Other VHDL Tools
The VHDL Environment
of the synthesized description to the ports of the original description. Since both the synthesized
description and the original description have the same name, we need to store the synthesized
description into a different library (in the simulator) than the original one.
Load the synthesized VHDL description in a library called synthesis in your simulator. Then
load the wrapper architecture into the work library. The wrapper links with the originally
compiled entity of the original VHDL description. The wrapper file uses type transformation
functions from a package called typetran to translate the port types. This packages is in the file
<precision install directory>/pkgs/techdata/vhdl/typetran.vhd. You have to load
this package into the simulator before you load the wrapper description.
Now, the original entity can be simulated with the wrapper architecture. Since the wrapper
instantiates the synthesized description, simulation of the synthesized design is done by using
the original entity (ports). The original test vectors can then be used to simulate.
Synopsys
Users that have existing VHDL files for Synopsys VHDL Compiler can rely on one or more of
the Synopsys pre-defined VHDL packages. Precision RTL Synthesis supports all these
packages; a use clause includes the packages in your design.
The Synopsys packages define a set of types and functions that contain Synopsys pragmas that
VHDL Compiler uses as synthesis directives. These pragmas are correctly interpreted by the
following Mentor Graphics tools:
pragma translate_on
pragma translate_off
synopsys translate _on
synopsys translate_off
synopsys synthesis_on
synopsys synthesis_off
Except for a use clause for each Synopsys package that you need in your VHDL file, you
should NOT have to load any Synopsys package into Precision RTL Synthesis. Precision RTL
Synthesis locates the packages that you want to use in the directory <precision install
directory>/pkgs/techdata/vhdl. Here is the list of files with the contained packages:
4-6
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
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
The exemplar Packages
File Name
Package Name
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. 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 vhdl_file=libname::filename in the appropriate library.
Use the analyze libname filename interactive command line shell option and argument.
Make sure again that you use the files from the <precision install
directory>/pkgs/techdata/vhdl directory (with synthesis directive attributes).
The exemplar Packages
There are a number of operations in VHDL that occur regularly. An example is the translation
of vectors to integers and back. For this reason, Mentor Graphics provides packages that define
attributes, types, functions and procedures that are frequently used. Using the functions and
procedures reduces the amount of initial circuitry that is generated, compared to writing the
behavior explicitly in a user-defined function or procedure. This reduces the cpu-time for
compilation and also could result in a smaller circuit implementation due to improved
optimization.
This section discusses the defined functionality in the Mentor Graphics packages exemplar and
exemplar_1164. The package bodies are not read by the synthesis tools; the functions are builtin. The packages are used for simulation only, and editing them does NOT change the
synthesized logic. The VHDL source for these packages is given in the files exemplar.vhd and
exemplar_1164.vhd, respectively in the <precision install
directory>/pkgs/techdata/vhdl directory.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-7
The exemplar Packages
The VHDL Environment
The exemplar_1164 package defines the same functionality as the exemplar package, but
operates on the IEEE 1164 multi-valued logic types.
If you are using the IEEE 1164 types in your VHDL description, you should include the IEEE
standard logic type definition into your VHDL description with a use clause. The VHDL source
of the IEEE 1164 types package is in the file std_1164.vhd in the <precision install
directory>/pkgs/techdata/vhdl directory. If you also want to use the Mentor Graphics
functions that operate on these types, you should include the package exemplar_1164 with a
use clause. For example:
library ieee;
use ieee.std_logic_1164.all;
library exemplar;
use exemplar_1164.all;
If you do not use the IEEE 1164 types, but still want to use the Mentor Graphics functions, just
include the package exemplar in your VHDL description with a use clause. All functions are
then defined with the predefined types bit and bit_vector, and on the four-valued types
elbit and elbit_vector.
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 following
attributes are recognized by the VHDL parser, and declared in both the exemplar and the
exemplar_1164 package:
Attribute
Type
Description
required_time
time
Set required time on output
arrival_time
time
Set arrival_time on input
output_load
real
Specify load set on output
4-8
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
The exemplar Packages
Attribute
Type
Description
max_load
real
Specify max load allowed on input
clock_cycle
time
Specify clock length on clock pin
pulse_width
time
Specify pulse width on clock pin
input_drive
time
Specify delay/unit load for input
nobuf
boolean
Reject buffer insertion for a input
pin_number
string
Specify location of input or output pin
array_pin_number*
array of strings
Specify location for each bit of a bus
preserve_signal
boolean
Signal’s function will survive synthesis
buffer_sig
string
Specify explicit buffer on a pin
modgen_sel
modgen_select
Specify time requirement for module generators
driving this signal
*VHDL only.
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
...
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-9
The exemplar Packages
The VHDL Environment
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.
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.
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;
4-10
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
The exemplar Packages
Takes a vector of bits and returns the (positive) integer representation. The left most bit in the
vector is assumed the MSB for the value of the integer. The vector is interpreted as an unsigned
representation.
int2evec (l: integer, size : integer := 32)return std_logic_vector;
Takes a integer and returns the vector representation. The size of the vector becomes equal to
the value of an optional second argument (size). If this argument is not specified, the size of the
return vector defaults to 32. The left most bit in the resulting vector is the MSB of the returned
value. If the integer value of the first parameter is negative, the MSB is the sign bit.
elb2int(l: std_logic)return integer;
Takes a std_logic value and returns an integer. The std_logic value ’1’ will return integer
value 1, all other values will return integer value 0.
For all shifter functions that follow, the shift amount (r) could either be a compile time constant
or not. If it is, the synthesized circuit will only consist of a re-ordering of the wires in the array.
Otherwise, Precision RTL Synthesis will synthesize a shifter circuit.
sl
(l: std_logic_vector; r: integer)return std_logic_vector;
Takes a vector l and an integer r and returns a vector. The resulting vector is the same size as l,
but all bits of l are shifted left r places. The bits on the right side of the result vector are zerofilled. The integer r must be non-negative.
sl2
(l: std_logic_vector; r: integer)return std_logic_vector;
Same as sl, but the vector l is treated as a 2-complement (signed) representation. Sign bit is the
left most bit in vector. Bits on the right are zero-filled.
sr
(l: std_logic_vector; r: integer)return std_logic_vector;
Same as sl, but bits are shifted to the right side of the vector. Bits on left side are zero-filled.
sr2
(l: std_logic_vector; r: integer)return std_logic_vector;
Same as sr, but the vector l is treated as a 2-complement representation. Sign bit is the left most
bit in vector. Bits on the left side are sign-bit filled.
add
(op_l, op_r: std_logic_vector)return std_logic_vector;
Takes two vectors and returns a vector. The resulting vector is one bit larger than the largest of
the input vectors, and represents the addition of the input vectors, including the carry bit. The
left most bit is assumed to be the MSB. The add function is a vector addition of two unsigned
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-11
The exemplar Packages
The VHDL Environment
vectors. The smallest input vector is ’0’, extended on the MSB side to the size of the largest
input vector before addition is performed.
add ("1011","0100") result : "01111"
add ("0011","100") result : "00111"
add2
(add (11,4) == 15)
(add (3,4) == 7)
(op_l, op_r: std_logic_vector)return std_logic_vector;
Same as add, but now the vectors are assumed to be in 2-complement representation. Sign bit is
the left most bit in the vectors. The smallest input vector is sign-bit extended on the MSB side to
the size of the largest vector before addition is performed.
add2 ("1011","0100") result : "00001"
add2 ("0011","100") result : "11111"
sub
(add2 (-5,4) == 1)
(add2 (3,-4) == -1)
(op_l, op_r: std_logic_vector) return std_logic_vector;
Same as add, but the subtraction function is implemented on unsigned vectors. op_r is
subtracted from op_l.
sub
sub
("1011","0100")result : "00111"
("0011","100") result : "11111"
(sub (11,4) == 7)
(sub(3,4) == 31)
Actually this is an under-flow of unsigned !
sub2
(op_l, op_r: std_logic_vector) return std_logic_vector;
Same as add2, but the subtraction function is implemented on 2-complement representation
vectors. op_r is subtracted from op_1.
sub2 ("1011","0100") result : "10111"
sub2 ("1011", "100") result : "11111"
(sub2(-5,4) == -9)
(sub2(-5,-4) == -1)
extend (op_l: std_logic_vector; op_r: integer)
return std_logic_vector;
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"
4-12
-- Truncation
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
The exemplar Packages
extend2 (op_l: std_logic_vector; op_r: integer)
return std_logic_vector;
Same as extend, but the vector is in 2’s-complement representation. The input vector is sign-bit
extended. There is also a version of extend2 that takes a single (std_logic) value and signextends it to a vector of size op_r.
extend2 ("1001",7)
result : "1111001"
extend2 (’1’,3)
result : "111"
extend2 ("011001001",4)
result : "1001" -- Truncation
comp2(op: std_logic_vector)return
std_logic_vector;
Takes a vector and returns a vector of the same size. This function assumes the input vector to
be in 2-complement representation and will return the complement (negative) value of the input
value. The right most bit is assumed to be the LSB.
comp2 ("1001") result : "0111"
"+"
( comp2 (-7) == 7)
(op_l, op_r: std_logic_vector) return std_logic_vector;
Takes two vectors and returns a vector. As add, but now the carry bit is not saved. The resulting
vector is the same size as the largest input vector. Overflow wraps around. This function
implements addition of unsigned vectors.
"10110" + "101"
result :
"11011"
(22 + 5 == 27)
"-" (op_l, op_r: std_logic_vector) return std_logic_vector;
Same as “+”, only the subtraction function is performed. op_r is subtracted from op_l. This
function implements subtraction of unsigned vectors.
"10110" - "101"
result : "10001"
"mult"
(22 - 5 == 17)
(op_l, op_r: std_ulogic_vector) return std_ulogic_vector;
Takes two vectors and returns a vector. The size of the resulting vector is the size of both input
vectors added. In each vector, the left most bit is the MSB. The mult function performs
UNSIGNED multiplication of the two input vectors. In case of unequal-length input vectors, the
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-13
The exemplar Packages
The VHDL Environment
smallest vector is zero-extended on the MSB side to the size of the largest input vector before
the multiplication is performed.
mult ("1011", "0100") result: "00101100" (mult(11,4)==44)
mult ("1", "1111") result: "00001111" (mult(1,15)==15)
"mult2"
(op_l, op_r: std_ulogic_vector) return std_ulogic_vector;
Like mult, but now the vectors are assumed to be in 2-complement representation. The sign bit
is the left most bit in each vector. In case of unequal-length input vectors, the smallest vector is
sign-bit extended on the MSB side to the size of the largest input vector before the
multiplication is performed.
Predefined Procedures
There are various ways to generate flip-flops and d-latches with VHDL, such as using processes
and specifying behavior that represents the behavior of flip-flops and dlatches. However, in
some cases it is useful to instantiate technology independent flip-flops or dlatches in the VHDL
dataflow environment immediately.
A more structural oriented VHDL style will be possible that way. The exemplar package
includes the definition of procedures that represent flip-flops or dlatches with various set or
reset facilities that operate on single bits or vectors (to create registers).
The exemplar package defines these procedures on signals of type bit, bit_vector, elbit
and elbit_vector, while the package exemplar_1164 defines the same procedures for the
IEEE 1164 types std_logic, std_ulogic, std_logic_vector and std_ulogic_vector. In
the description below only examples for bit and bit_vector are given, but the full definition
of the procedures, for the types listed above, is available for simulation purposes in the files
exemplar.vhd and ex_1164.vhd.
Flip-flops
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
4-14
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
The exemplar Packages
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
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).
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-15
Syntax and Semantic Restrictions
The VHDL Environment
pullup (busname)
When a bus is not driven, this procedure pulls the bus up to 1.
pulldn (busname)
When a bus is not driven, this procedure pulls the bus down to 0.
trstmem (busname)
When a bus is not driven, this procedure drives the bus to the last driven state.
Syntax and Semantic Restrictions
VHDL as the IEEE Standard 1076 is a extended language with many constructs that are useful
for simulation. However, during the initial development of the language, logic synthesis was not
taken into account. Therefore, a number of constructs or combination of constructs cannot be
implemented in actual circuits. VHDL 1076 is fully simulatable, but not fully synthesizable.
Synthesis Tool Restrictions
This section discusses the syntax and semantic restrictions of the VHDL parsers of Precision
RTL Synthesis.
•
•
•
•
•
•
4-16
Operations on files not supported. Files in VHDL could behave like ROMs or RAMs,
but Precision RTL Synthesis does not support using file (types), and will ignore, but
accept, file (type) declarations.
Operations on objects of real types are not supported. Objects of real types have no
defined bit-resolution. Precision RTL Synthesis ignores, but accepts declarations of
(objects of) real types.
Operations on objects of access types are not supported, since they lead to
unsynthesizable behavior. Precision RTL Synthesis ignores, but accepts declarations of
(objects of) access types.
Attributes BEHAVIOR, STRUCTURE, LAST_EVENT, LAST_ACTIVE, and TRANSACTION are not
supported.
Global, non-constant signals are not supported, that is, signals declared in a package.
Allocators are not supported, because they perform dynamic allocation of resources,
which is not synthesizable.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
•
Syntax and Semantic Restrictions
Resolution functions with a synthesis directive are allowed.
VHDL Language Restrictions
Apart from these restrictions, which are mostly tool-related, there are some basic restrictions
that apply to VHDL descriptions for synthesis. Since they occur quite often, additional
descriptions are presented here to clarify the problems involved for synthesis. Here is the list:
•
after
•
Restrictions on Initialization values.
•
Loop restrictions
•
Restrictions on edge-detecting attributes (EVENT and STABLE).
•
Restrictions on wait statements.
•
Restrictions on multiple drivers on one signal.
clause ignored.
A more detailed description of these restrictions follows below:
After Clause Ignored
The after clause refers to delay in a signal. Since delay values cannot be guaranteed in
synthesis, they are ignored by the synthesis tools after they issue a warning.
Restrictions on Initialization Values
Initialization values are allowed in a number of constructs in VHDL:
1. Initial value of a signal in a signal declaration.
2. Initial value of a variable in a variable declaration in a process.
3. Initial value of a variable in a variable declaration in a subprogram (procedure or
function).
4. Initial value of a generic or port in a component declaration.
5. Initial value of a parameter in a subprogram interface list.
The problem with initialization values for synthesis is that some initial values define the initial
value of an object before actual simulation is done. This behavior corresponds to controlling the
power-up state of a device that would be synthesized from the VHDL description. Since
synthesis cannot control the power-up state of a device, this kind of initial value cannot be
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-17
Syntax and Semantic Restrictions
The VHDL Environment
synthesized. However, if after initialization there is never an change of value, the behavior can
be synthesized, and resembles a simple constant value.
Precision RTL Synthesis fully supports initialization values, except for initializing objects that
can change their value after initialization. That is, the following form of initialization values are
NOT supported because they imply power-up behavior of the synthesized device:
1. Initial values of a signal in a signal declaration.
2. Initial value of a variable in a variable declaration in a process.
3. Initial value of an OUTPUT or INOUT port in an interface list.
All other forms of initialization values are supported by the synthesis tools.
Loop Restrictions
Loops are supported if they are bound by constants or they have wait until statements to
prevent combinational loops.
Restrictions On Edge-Detecting Attributes (’event)
Most restrictions on VHDL to assure correct compilation into a logic circuit are on the
constructs that define edges or changes on signals. The ’EVENT attribute is the best example of
this. signal’EVENT is TRUE only if signal changes. Then it is TRUE for one simulation delta of
time. In all other cases it is FALSE. The STABLE attribute is the boolean inversion of EVENT.
There are two restrictions for synthesis on usage of the EVENT and the STABLE attribute:
1. An EVENT or STABLE attribute can be used only to specify a leading or falling clock edge.
For example:
clk’event and clk=’1’
clk’event and clk=’0’
NOT clk’stable and clk=’0’
clk’event and clk
clk
-----
Leading
Falling
Falling
Leading
edge
edge
edge
edge
of
of
of
of
clk
clk
clk
(boolean)
2. Clock edge expressions can only be used as conditions. For example:
if (clk’event and clk=’1’) then ...
wait until NOT clk’stable and clk=’0’ ;
wait until clk=’1’ ;
--Implicit clock edge due to
--VHDL semantics of ’wait’
block (clk’event and clk=’1’... --Block GUARD condition
4-18
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The VHDL Environment
Syntax and Semantic Restrictions
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
allows free usage of the clock edge conditions, either in guarded blocks, processes or
subprograms.
Restrictions on Wait Statements
All state-of-the-art VHDL synthesis tools on the market right now have strong restrictions with
respect to wait statements and use of edge-detecting attributes ( ’event and ’stable). Here are
the (informal) restrictions for the wait statement:
•
•
Multiple wait statements are supported in a process with some synthesis restrictions.
All the control paths should have at least one wait statement and all of the wait
statements should be identical with a single bit clock expression.
The expression in the until condition must specify a leading or falling single clock
edge. (Examples are shown above in the EVENT attribute section.)
All assignments inside the process result in the creation of registers. Each register (flip-flop) is
clocked with the single clock signal.
There are a number of cases where multiple waits are synthesizable and resemble statemachine behavior. In Precision RTL Synthesis, multiple waits are supported.
Restrictions on Multiple Drivers on One Signal
VHDL does not allow multiple drivers on a signal of an unresolved type. For signals of resolved
types, VHDL defines that a (user-defined) resolution function defines what the signal value is
going to be in case there are multiple driver (simultaneous assignments) to the signal.
A resolution function with meta-logical values (’Z’, ’X’, etc.) in general leads to behavior that
is not synthesizable (since logic circuits cannot produce meta-logical values). Therefore, in
general, VHDL synthesis tools do not allow multiple drivers on a signal. However, if the
resolution function defines the behavior of multiple three-state drivers on a bus, multiple drivers
of a signal could represent synthesizable behavior.
The ’Z’ value is in general used to identify three-state behavior. The resolution function of the
IEEE std_logic (resolved) type is written so that multiple drivers on a signal of std_logic do
resemble multiple three-state drivers on a bus. Therefore, the synthesis tools accept multiple
assignments to the same signal as long as each assignment is conditionally set to the ’Z’ value.
The synthesis tools allow free usage of ’Z’ assignments (either from dataflow statements,
process statements or from within procedures). Precision RTL Synthesis implements three-state
drivers to mimic the three-state behavior.
It is important to note that Precision RTL Synthesis does not check if there could be a busconflict on the driven bus. In this case, the simulation would just call the resolution function
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
4-19
Syntax and Semantic Restrictions
The VHDL Environment
again to resolve the value (normally producing a meta-logical value), but the behavior for
synthesis is not defined. Avoiding bus conflicts is the responsibility of the user.
4-20
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 5
Introduction to Verilog Synthesis
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.
The structural and data flow descriptions show a concurrent behavior. All statements are
executed concurrently, and the order of the statements does not matter. On the other hand,
behavioral descriptions are executed sequentially in always blocks, tasks and functions in
Verilog. The behavioral descriptions resemble high-level programming languages.
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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
5-1
Verilog and Synthesis
Introduction to Verilog Synthesis
The high level design flow enabled by the use of Precision RTL Synthesis is shown in
Figure 5-1.
Figure 5-1. Top Down Design Flow with Precision RTL Synthesis
Write RTL code
Simulate the RTL design
Synthesize to generic gates
Precision
Synthesis
Map to technology cells
Optimize for speed/area
Run implementation tools
Simulate the final design
Verilog and Synthesis
Verilog is completely simulatable, but not completely synthesizable. There are a number of
Verilog constructs that 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. Scheduling and allocation algorithms, that
perform circuit optimization at a very high and abstract level, are not yet available for general
5-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Introduction to Verilog Synthesis
Verilog 2001 Support
circuit applications. Therefore, the result of synthesis of a Verilog description depends on the
style of Verilog that is used. You should understand some of the concepts of synthesis specific
to 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.
Verilog 2001 Support
Introduction
The Verilog-2001 Standard was approved by the IEEE in June of 2000 and includes
enhancements to the previously existing Verilog standard in the following areas:
•
•
•
Enhance the Verilog language to help with today's deep-submicron and intellectual
property modeling issues
Ensure that all enhancements were both useful and practical, and that simulator and
synthesis vendors would implement Verilog-2001 in their products
Correct any ambiguities in the Verilog-1995 standard (IEEE 1364-1995)
Verilog 2001 expands the construct set of Verilog - 1995 but does not replace or change the
behavior of previously implemented constructs. You may seamlessly mix new and previously
existing constructs.
Supported Verilog 2001 Constructs
Precision Synthesis offers support for the following Verilog-2001 constructs:
•
Signed arithmetic extensions
•
Comma-separated sensitivity list
•
Combinational logic sensitivity token
•
Combined port / data type declarations
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
5-3
Verilog 2001 Support
Introduction to Verilog Synthesis
•
ANSI-style port lists
•
Power Operator
•
Automatic width extension past 32 bits
•
Register declaration with initialization
Detailed Description
Combinational logic sensitivity token
To properly model combinational logic using a Verilog always procedure, the sensitivity list
must include all input signals used by that block of logic. In large, complex blocks of
combinational logic, it is easy to inadvertently omit an input from the sensitivity list, which can
lead to simulation and synthesis mismatches.
Verilog-2000 adds a new wild card token, @*, which represents a combinational logic
sensitivity list. The @* token indicates that the simulator or synthesis tool should automatically
be sensitive to any values used by the procedure in decisions or in expressions on the right-hand
side of assignment statements. In the following example, the @* token will cause the procedure
to automatically be sensitive to changes on sel, a or b.
always @* //combinational logic sensitivity
if (sel)
y = a;
else
y = b;
Combined port / data type operator
Verilog requires that signals connected to the input or outputs of a module have two
declarations: the direction of the port, and the data type of the signal. In Verilog-1995, these two
declarations had to be done as two separate statements. Verilog-2000 adds a simpler syntax, by
combining the declarations into one statement.
module mux8 (y, a, b, en);
output reg [7:0] y;
input wire [7:0] a, b;
input wire en;
5-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Introduction to Verilog Synthesis
Verilog 2001 Support
Power Operator
Verilog-2001 adds a power operator, represented by an ** token. This operator preforms similar
functionality as the C pow() function. It will return a real number if either operand is a real
value, and an integer value if both operands are integer values. One practical application of the
power operator is to calculate values such as 2n. For example:
always @(posedge clock)
result = base ** exponent;
Signed Arithmetic Extensions
For integer math operations, Verilog uses the data types of the operands to determine if signed
or unsigned arithmetic should be performed. If either operand is unsigned, unsigned operations
are performed. To perform signed arithmetic, both operands must be signed. In Verilog-1995,
the integer data type is signed, and the reg and net data types are unsigned. A limitation in
Verilog- 1995 is that the integer data type has a fixed vector size, which is 32-bits in most
Verilog simulators. Thus, signed integer math in Verilog-1995 is limited to 32-bit vectors. The
Verilog- 2000 standard adds five enhancements to provide greater signed arithmetic capability:
•
Reg and net data types can be declared as signed
•
Function return values can be declared as signed
•
Integer numbers in any radix can be declared as signed
•
Operands can be converted from unsigned to signed
•
Arithmetic shift operators have been added
The Verilog-1995 standard has a reserved keyword, signed, but this keyword was not used in
Verilog-1995. Verilog-2000 uses this keyword to allow reg data types, net data types, ports, and
functions to be declared as signed types. Some example declarations are:
reg signed [63:0] data;
wire signed [7:0] vector;
input signed [31:0] a;
function signed [128:0] alu;
In Verilog-1995, a literal integer number with no radix specified is considered a signed value,
but a literal integer with a radix specified is considered an unsigned value. Verilog-2000 adds an
additional specifier, the letter 's', which can be combined with the radix specifier, to indicate that
the literal number is a signed value.
16'hC501 //an unsigned 16-bit hex value
16'shC501 //a signed 16-bit hex value
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
5-5
Verilog 2001 Support
Introduction to Verilog Synthesis
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.
reg [63:0] a; //unsigned data type
always @(a) begin
result1 = a / 2; //unsigned arithmetic
result2 = $signed(a) / 2; //signed arithmetic
end
One more signed arithmetic enhancement in Verilog-2000 is arithmetic shift operators,
represented by >>> and <<< tokens. An arithmetic right-shift operation maintains the sign of a
value, by filling with the sign-bit value as it shifts. For example, if the 8-bit variable D
contained 8'b10100011, a logical right shift and an arithmetic right shift by 3 bits would yield
the following:
D >> 3 //logical shift yields 8'b00010100
D >>> 3 //arithmetic shift yields 8'b11110100
Comma-Separated Sensitivity List
Verilog-2000 adds a second way to list signals in a sensitivity list, by separating the signal
names with commas instead of the or keyword. The following two sensitivity lists are
functionally identical:
always @(a or b or c or d or sel)
always @(a, b, c, d, sel)
The new, comma-separated sensitivity list does not add any new functionality. It does, however,
make Verilog syntax more intuitive, and more consistent with other signal lists in Verilog.
ANSI-Style Port Lists
Verilog-1995 uses the older Kernighan and Ritchie C language syntax to declare module ports,
where the order of the ports is defined within parentheses, and the declarations of the ports are
listed after the parentheses. Verilog-1995 tasks and functions omit the parentheses list, and use
the order of the input and output declarations to define the input/output order. Verilog-2000
updates the syntax for declaring inputs and outputs of modules, tasks, and functions to be more
like the ANSI C language. That is, the declarations can be contained in the parentheses that
show the order of inputs and outputs.
module mux8 ( output reg [7:0] y,
input wire [7:0] a,
input wire [7:0] b,
input wire en );
function [63:0] alu (
input [63:0] a,
input [63:0] b,
input [7:0] opcode );
5-6
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Introduction to Verilog Synthesis
Verilog 2001 Support
Automatic Width Extension Past 32 Bits
With Verilog-1995, assigning an unsized high-impedance value (e.g.: 'bz) to a bus that is greater
than 32 bits would only set the lower 32 bits to high-impedance. The upper bits would be set to
0. To set the entire bus to high-impedance requires explicitly specifying the number of high
impedance bits. For example:
Verilog-1995:
parameter WIDTH = 64;
reg [WIDTH-1:0] data;
data = 'bz; //fills with 'h00000000zzzzzzzz
data = 64'bz; //fills with 'hzzzzzzzzzzzzzzzz
The fill rules in Verilog-1995 make it difficult to write models that are easily scaled to new
vector sizes. Redefinable parameters can be used to scale vector widths, but the Verilog source
code must still be modified to alter the literal value widths used in assignment statements.
Verilog-2000 changes the rule for assignment expansion so that an unsized value of Z or X will
automatically expand to fill the full width of the vector on the left-hand side of the assignment.
Verilog-2000:
parameter WIDTH = 64;
reg [WIDTH-1:0] data;
data = 'bz; //fills with 'hzzzzzzzzzzzzzzzz
This Verilog-2001 enhancement is not backward compatible with Verilog-1995. However, the
IEEE standards group felt the Verilog-1995 behavior was a bug in the standard that needed to be
corrected. It is expected that all existing models with greater than 32-bit busses have avoided
this bug by explicitly specifying the vector sizes. Therefore, there should not be any
compatibility problems with existing models.
Register Declaration with Initialization
Verilog-2000 adds the ability to initialize variables at the time they are declared, instead of
requiring a separate initial procedure to initialize variables. The initial value assigned to the
variable will take place within simulation time zero, just as if the value had been assigned
within an initial procedure.
Verilog-1995:
reg clock;
initial
clk = 0;
Verilog-2000:
reg clock = 0;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
5-7
Verilog 2001 Support
Introduction to Verilog Synthesis
In-Line Parameter Passing
Verilog-1995 has two methods of redefining parameters within a module instance: explicit
redefinition using defparam statements, and in-line implicit redefinition using the # token as
part of the module instance. The latter method is more concise, but because it redefines
parameter by their declaration position, it is error-prone and is not self-documenting. The
following example illustrates the two Verilog-1995 methods for parameter redefinition.
module ram (...);
parameter WIDTH = 8;
parameter SIZE = 256;
...
endmodule
module my_chip (...);
...
//Explicit parameter redefinition by name
RAM ram1 (...);
defparam ram1.SIZE = 1023;
//Implicit parameter redefintion by position
RAM #(8,1023) ram2 (...);
endmodule
Verilog-2001 adds a third method to redefine parameters, in-line explicit redefinition. This new
method allows inline parameter values to be listed in any order, and document the parameters
being redefined.
//In-line explicit parameter redefintion
RAM #(.SIZE(1023)) ram2 (...);
File and Line Compiler Directives
Verilog tools need to keep track of the line number and the file name of Verilog source code.
This information can be used for error messages, and can be accessed by the Verilog PLI. If
Verilog source is pre-processed by some other tool, however, the line and file information of the
original source code can be lost. Verilog-2001 adds a `line compiler directive, which can be
used to specify the original source code line number and file name. This allows the location in
an original file to be maintained if another process modifies the source, such as by adding or
removing lines of source text.
Attributes
The Verilog language was originally created as a hardware description language for digital
simulation. As tools other than simulation have adopted Verilog as a source input, there has
been a need for these tools to be able add tool specific information to the Verilog language. In
Verilog- 1995, there was no mechanism for adding tool-specific information, which led to nonstandard methods, such as hiding synthesis commands in Verilog comments. Verilog-2001 adds
5-8
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Introduction to Verilog Synthesis
Verilog 2001 Support
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]: ...
endcase
Enhanced Conditional Compilation
Verilog-1995 supports limited conditional compilation: `ifdef, `else, `endif, and `undef.
Verilog-2001 adds two new directives: `ifndef and `elsif.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
5-9
Verilog 2001 Support
5-10
Introduction to Verilog Synthesis
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 6
Verilog Language Features
This chapter provides an introduction to the basic language constructs in Verilog:
•
Defining logic blocks:
•
Data flow and behavioral descriptions
•
Concurrent and sequential functionality
•
Numbers and data types.
Precision synthesizes all levels of abstraction and minimizes the amount of logic needed
resulting in a final netlist description in the technology of your choice.
Modules
A basic building block in Verilog is a module. The module describes both the boundaries of the
logic block and the contents of the block, in structural, data flow and behavioral constructs.
module small_block (a, b, c, o1, o2);
input a, b, c;
output o1, o2;
wire s;
assign o1 = s || c ;
assign s = a && b ;
assign o2 = s ^ c ;
endmodule
Note: Precision RTL Synthesis supports empty top level modules.
This Verilog description shows the implementation of small_block, a block that describes
some simple logic functions.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-1
Numbers
Verilog Language Features
The port list is declared, the port directions are specified, then an internal wire is declared. A
wire in Verilog represents physical connection in hardware. It can connect between modules or
gates, and does not store a value. A wire can be used anywhere inside the module, but can only
be assigned by:
•
Connecting it to an output of a gate or a module.
•
Assigning to it using a continuous assignment.
This module contains only dataflow behavior. Dataflow behavior is described using continuous
assignments. All continuous assignments are executed concurrently, thus the order of these
assignments does not matter. This is why it is valid to use s before s is assigned. In the first
statement o1 is assigned the result of the logical OR of s and c. “| |” denotes the logical OR
operation.
More details about the various dataflow statements and operators are given in the following
sections.
’macromodule’
Precision RTL Synthesis supports ’macromodule’, which is treated as ’module’.
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
’b
01xXzZ_?
octal
’o
0-7xXzZ_?
decimal
’d
0-9_
hexcadecimal
’h
0-9a-fA-FxXzZ_?
If a prefix is preceded by a number, this number defines the bit width of the number, for
instance, 8’b 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.
6-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Data Types
For example, in
x = 2.5 + 8;
x
will evaluate to 8.
Special characters in numbers:
a separator to improve readability.
“_”
’x’, ’X’
unknown value.
’z’, ’Z’, ’?’tri-state
value.
Examples:
334
32 bits wide decimal number
32’b101
32 bits wide binary number (zero left
filled)
3’b11
3 bits wide binary number (ie, 011)
20’h’f_ffff
20 bits wide hexadecimal number
10’bZ
10 bits wide all tri-state
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>]
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-3
Data Types
Verilog Language Features
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
6-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Data Types
// Shift data
always @ (posedge phase)
begin
if ((count == 0) & !load) begin
sout[max_count:1] = sout[0:max_count - 1];
sout[0] = 1’b0;
ready
= 1’b1;
end
else if ((count == 0) & load ) begin
sout = data;
count = count + 1;
ready = 1’b0;
end
else if (count == max_count) begin
sout[max_count:1] = sout[0:max_count - 1];
sout[0]= 1’b0;
count = 0;
end
else begin
sout[max_count:1] = sout[0:max_count - 1];
sout[0]= 1’b0;
count = count + 1;
end
end
endmodule
Net Data Types
The net data types supported by Precision RTL Synthesis are
•
wire
•
tri
•
supply0
•
supply1
•
wand
•
wor
These data types are used to represent physical connections between structural entities in the
Verilog design, such as a wire between two gates, or a tristate bus. Values cannot be assigned to
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-5
Data Types
Verilog Language Features
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).
wire and tri Nets
The wire and tri net data types are identical in usage (syntax and function). The two different
names are provided for design clarity. Nets driven by a single gate are usually declared as wire
nets, as shown in Modules in this chapter, while nets driven by multiple gates are usually
declared as tri nets.
Supply Nets
The supply1 and supply0 net data types are used to describe the power (VCC) and ground
supplies in the circuit. For example, to declare a ground net with the name GND, the following
code is used:
supply0 GND ;
wand and wor Net Types
wand and wor statements result into and or logic respectively, since wired logic is not available
in all technologies.
wor out;
out = a&b
out = c&d;
endmodule
Register Data Type
A register, declared with keyword reg, represents a variable in Verilog. Where net data types do
not store values, reg data types do. Registers can be assigned only in an always block, task or
function. When a variable is assigned a value in an always block that has a clock edge event
expression (posedge or negedge), a flip-flop is synthesized by Precision RTL Synthesis. To
avoid the creation of flip-flops for reg data types, separate the combinational logic into a
different always block (that does not have a clock edge event expression as a trigger).
Parameter Data Type
The parameter data type is used to represent constants in Verilog. Parameters are declared by
using the keyword parameter and a default value. Parameters can be overridden when a
module is instantiated.
6-6
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Continuous Assignments
Declaration Local to Begin-End Block
Local declaration of registers and integers is allowed inside a named begin-end block. If the
begin-end block contains a “@ posedge ck” statement, then the declaration is not supported.
input [10:0] data;
always @ (data)
begin: named_block
integer i;
parity = 0;
for (i = 0; i < 11; i= i + 1)
parity = parity ^ data[i];
end //named_block
Array of reg and integer Declaration
Memory declaration and usage of an array of registers or integers is now allowed.
input [3:0] address;
input [7:0] date_in;
output [7:0] data_out;
reg [7:0] data_out, mem [3:0];
always @ (address or date_in or we)
if (we) mem [address] = date_in;
else data_out = mem [address];
Continuous Assignments
A continuous assignment is used to assign values to nets and ports. The nets or ports may be
either scalar or vector in nature. (Assignments to a bit select or a constant part select of a vector
are also allowed.) Because nets and ports are being assigned values, continuous assignments are
allowed only in the dataflow portion of the module. As such, the net or port is updated whenever
the value being assigned to it changes.
Continuous assignments may be made at the same time the net is declared, or by using the
assign statement.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-7
Continuous Assignments
Verilog Language Features
Net Declaration Assignment
The net declaration assignment uses the same statement for both the declaration of the net and
the continuous assignment:
wire [1:0] sel = selector ;
Only one net declaration assignment can be made to a specific net, in contrast to the continuous
assignment statement, where multiple assignments are allowed.
Continuous Assignment Statement
The continuous assignment statement (assign) is used to assign values to nets and ports that
have previously been declared.
The following example describes a circuit that loads a source vector of 4 bits on the edge of a
clock (wrclk), and stores the value internally in a register (intreg) if the chip enable (ce) is
6-8
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Procedural Assignments
active. One bit of the register output is put on a tristate bus (result_int) based on a bit selector
signal (selector), with the bus output clocked through a final register (result).
module tri_asgn (source, ce, wrclk, selector, result) ;
input [3:0] source ;
input ce, wrclk ;
input [1:0] selector ;
output result ;
reg [3:0] intreg ;
reg result ;
// net declaration assignment
wire [1:0] sel = selector ;
tri result_int ;
// continuous assignment statement
assign
result_int = (sel == 2’b00)
,
result_int = (sel == 2’b01)
,
result_int = (sel == 2’b10)
,
result_int = (sel == 2’b11)
;
always @(posedge wrclk)
begin
if (ce)
begin
intreg = source ;
result = result_int ;
end
end
? intreg[0] : 1’bZ
? intreg[1] : 1’bZ
? intreg[2] : 1’bZ
? intreg[3] : 1’bZ
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
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-9
Always Blocks
Verilog Language Features
means that the value of a register variable in a blocking assignment is updated immediately after
the assignment.
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
Always 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.
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
6-10
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Always Blocks
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.
module mux_case (source, ce, wrclk, selector, result);
input [3:0] source;
input ce, wrclk;
input [1:0] selector;
output result;
reg [3:0] intreg;
reg result, result_int;
always @(posedge wrclk)
begin
if (ce)
intreg = source;
result = result_int;
end
always @(intreg or selector)
case (selector)
2’b00: result_int
2’b01: result_int
2’b10: result_int
2’b11: result_int
endcase
=
=
=
=
intreg[0];
intreg[1];
intreg[2];
intreg[3];
endmodule
This example describes a circuit that can load a source vector of 4 bits, on the edge of a write
clock (wrclk), store the value internally in a register (intreg) if a chip enable (ce) is active,
while it produces one bit of the register constantly (not synchronized). The bit is selected by a
selector signal of 2 bits, and is clocked out through the register result.
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
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-11
Always Blocks
Verilog Language Features
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
.........
.........
6-12
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Module Instantiation
Module Instantiation
Module instantiation can be used to implement individual gates or cells, macros, or to add
hierarchy to your design. Here is an example that generates an address for RAM and instantiates
the RAM cells:
module scanner (reset, stop, load, clk, load_value, data) ;
input reset, stop, load, clk;
input [3:0] load_value;
output [3:0] data;
reg [4:0] addr;
//
Instantiate and connect 4 32x1-bit rams
RAM_32x1 U0 (.a(addr), .d(load_value[0]), .we(load), .o(data[0])
);
RAM_32x1 U1 (.a(addr), .d(load_value[1]), .we(load), .o(data[1])
);
RAM_32x1 U2 (.a(addr), .d(load_value[2]), .we(load), .o(data[2])
);
RAM_32x1 U3 (.a(addr), .d(load_value[3]), .we(load), .o(data[3])
);
// Generate the address for the rams
always @(posedge clk or posedge reset)
begin
if (reset)
addr = 5’b0 ;
else if (~stop )
addr = addr + 5’b1 ;
end
endmodule
module RAM_32x1 ( a, we, d, o);
input [4:0] a;
input we, d ;
output o;
endmodule
For this example, if the RAM module RAM_32x1 is a cell or macro in a library, Precision RTL
Synthesis will implement that cell or macro in the output netlist. To do that, the library in which
the cell or macro exists must be specified as the Technology in the Setup Design step.
Precision RTL Synthesis supports empty named port connections, e.g.,
nd2 x1 (.a(f), .b());
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-13
Module Instantiation
Verilog Language Features
Parameter Override During Instantiation of Module
Parameter overriding during module instantiation is supported by Precision RTL Synthesis.
module top (a, b);
input [3:0] a;
output [3:0] b;
do_assign #(4) name (a, b);
endmodule
module do_assign (a, b);
parameter n = 2;
input [n-1:0] a;
output [n-1:0] b;
assign b = a;
endmodule
Defparam Statement
When using the defparam statement, parameter values can be changed in any module instance
throughout the design, provided the hierarchical name of the parameter is used.
Note: In Precision RTL Synthesis, the hierarchical name is restricted to single level only. This
means that when the defparam statement is used, you can override any parameter value of an
instance in the current module only.
6-14
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Operators
Example:
module top (a, b);
input [3:0] a;
output [3:0] b;
wire top;
do_assign name (a, b);
defparam name.n = 4;
endmodule
module do_assign (a, b);
parameter n = 2;
input [n-1:0] a;
output [n-1:0] b;
assign b = a;
endmodule
’unconnected_drive’ and ’nounconnected_drive’
These directives are specified as outside modules only. ’unconnected_drive’ takes either
pull0 or pull1 as a parameter and causes all the unconnected input ports to be pulled down or
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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-15
Operators
Verilog Language Features
Operands
An operand in an expression can be one of the following:
•
Number
•
Net (including bit-select and part-select)
•
Register (including bit-select and part-select)
•
A call to a function that returns any of the above
Bit-selects take the value of a specific bit from a vector net or register. Part-selects are a set of
two or more contiguous bits from a vector net or register. For example:
...
wire bit_int ;
reg [1:0] part_int ;
reg [3:0] intreg;
bit_int = intreg[1] ;// bit-select of intreg assigned to bit_int
part_int = intreg[2:1] ;// part-select of intreg assigned to
part_int
...
The operators supported by Precision RTL Synthesis are listed in Table 6-1.
Table 6-1. Operators Supported by Precision RTL Synthesis
Operator
6-16
Description
+
-
*
/
arithmetic
<
>
<=
>=
relational
==
logical equality
!=
logic inequality
!
logical negation
&&
logical and
||
logical or
~
bit-wise negation
&
bit-wise and
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Operators
|
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.
Relational and Equality Operators
Precision RTL Synthesis supports the following relational and equality operators:
<
>
<=
>=
==
!=
If the bit value of any operand is ‘X’ (unknown), then the entire resulting value is ‘X’.
===
and !== Operators are Treated as == and !=
=== and !== operators are treated as == and != for synthesis purposes if either one of the
operands is nonconstant. If both the operands are constant, they can be used to compare
metalogical values. In simulation, the difference between == and === is that one can compare
metalogical characters exactly with === but not with ==. Any metalogical character causes the
output of == to be unknown x. The difference between != and !== is the same.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-17
Operators
Verilog Language Features
module triple_eq_neq (in1, in2, O);
output [10:0] O;
input [2:0] in1, in2;
assign
O[0] = 3'b0x0 === 3'b0x0, // output is 1
O[1] = 3'b0x0 !== 3'b0x0, // output is 0
O[2] = 3'b0x0 === 3'b1x0, // output is 0
O[3] = 3'b0x0 !== 3'b1x0, // output is 1O[4]=in1===3'b0x0,
// LHS is non constant so this
// produces warning that comparison
// metalogical character is
// with zero. output is 0
O[5] = in1 !== 3'b0x0,
// LHS is non constant so this
// produces warning that comparison
// with metalogical character is
// zero.output is 1,because it
// checks for not equality
O[6] = in1 === 3'b010,
// normal comparison
O[7] = in1 !== 3'b010,
// normal comparison
O[8] = in1 === in2,
// normal comparison
O[9] = in1 !== in2,
// normal comparison
O[10] = 3'b00x === 1'bx; // output is 1
endmodule
Logical Operators
Precision RTL Synthesis supports the following logical operators:
!
&&
||
Bit-Wise Operators
Precision RTL Synthesis supports the following bit_wise operators:
~
&
|
^
^~
~^
These operators perform bit-wise operations on equivalent bits in the operands.
Reduction Operators
Precision RTL Synthesis supports the following reduction operators:
&
6-18
|
^
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Operators
These operators perform reduction operations on a single operand. Operations are performed on
the first and second bits of the operand, then on the result of that operation with the third bit of
the operand, until the limit of the vector is reached. The result is a single bit value.
The following operators:
~&
~|
~^
are negations of the “&”, “|”, and “^” operators.
Shift Operators
Precision RTL Synthesis supports the following shift operators:
<<
>>
Conditional Operator
The conditional operator statement has the following syntax:
conditional_expression ? true_expression : false_expression
The result of this operation is true_expression if conditional_expression evaluates to
true, and false_expression if false. In the following example, result is assigned the value of
intreg[0] if sel = 2’b00, otherwise result is assigned Z:
...
output result ;
reg [3:0} intreg ;
wire [1:0] sel ;
assign result = (~sel[0] && ~sel[1]) ? intreg[0] : 1’bZ ;
...
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], 1’b0, c[1:0]} ;
foo = {a[4], a[3], 1’b0, c[1], c[0]} ;
For a = 5’b11010, c = 5’b10101, the result is foo = 5’b11001.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-19
Statements
Verilog Language Features
‘signed and ‘unsigned Attributes on Operators
‘signed and ‘unsigned attributes change the type of a particular operator. Comparison
between two bit vectors are always done unsigned, but if the functionality needs to be signed, a
‘signed attribute can be used just after the comparator.
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., 4’b0001 << ‘signed 1 produces 4’b0011).
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
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.
6-20
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Statements
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
// if-else construct for multiplexer functionality
if (sel == 2’b00)
result_int = intreg[0] ;
else if (sel == 2’b01)
result_int = intreg[1] ;
else if (sel == 2’b10)
result_int = intreg[2] ;
else if (sel == 2’b11)
result_int = intreg[3] ;
end
endmodule
This example describes a circuit that can load a source vector of 4 bits, on the edge of a write
clock (wrclk), store the value internally in a register (intreg) if a chip enable (ce) is active,
while it produces one bit of the register constantly (not synchronized). The bit is selected by a
selector signal of 2 bits, and is clocked out through the register result.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-21
Statements
Verilog Language Features
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 = 1’b0; yellow1 = 1’b0; green1 = 1’b0;
red2 = 1’b0; yellow2 = 1’b0; green2 = 1’b0;
case (state)
st0: begin
green1 = 1’b1;
red2 = 1’b1;
if (sensor2 == sensor1)
nxstate = st1;
else if (~sensor1 & sensor2)
nxstate = st2;
end
st1: begin
green1 = 1’b1;
red2 = 1’b1;
nxstate = st2;
end
6-22
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Statements
st2: begin
green1 = 1’b1;
red2 = 1’b1;
nxstate = st3;
end
st3: begin
yellow1 = 1’b1;
red2 = 1’b1;
nxstate = st4;
end
st4: begin
red1 = 1’b1;
green2 = 1’b1;
if (~sensor1 & ~sensor2)
nxstate = st5;
else if (sensor1 & ~sensor2)
nxstate = st6;
end
st5: begin
red1 = 1’b1;
green2 = 1’b1;
nxstate = st6;
end
st6: begin
red1 = 1’b1;
green2 = 1’b1;
nxstate = st7;
end
st7: begin
red1 = 1’b1;
yellow2 = 1’b1;
nxstate = st0;
end
endcase
end
endmodule
Case Statement and Multiplexer Generation
The case statement, as defined by the Verilog LRM, is evaluated by order, and the first
expression to match the control expression is executed (during simulation). For synthesis, this
implies a priority encoding. However, in many cases the case statement is used to imply a
multiplexer. This is true whenever the case conditions are mutually exclusive (the control
expressions equal only one condition at any given time).
In Verilog, the case items can be non-constants also. In such a situation, Precision RTL
Synthesis cannot automatically detect that the case statements are full or parallel, so you can
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-23
Statements
Verilog Language Features
include a Verilog directive that tells the tool whether it is full or parallel. Refer the topic
Synthesis Directives on page 7-26 for details.
Consider the following Verilog code fragment:
case (1’b1)
s[0]: o = a;
s[1]: o = b;
endcase
This code results in the equation:
o = s[0] * a
+ !s[0] * s[1] * b;
If parallel case is specified, the following equation will be synthesized:
o = s[0] * a
+ s[1] * b;
This equation is simpler than the first. For a bigger case statement the amount of logic
reduction can be significant. This cannot be determined automatically since the case items are
nonconstants.
NOTE: Using these directives can cause simulation differences between behavioral and postsynthesis netlists.
Automatic Full Case Detection
The casex statement below is full case (it covers all possible values 000 to 111). The default
statement is not necessary and is ignored by the synthesis tool, resulting in a warning message.
The synthesis tools also do full-case detection for normal case and casez statements.
input [2:0] sel;
casex (sel)
3'b10x: ...
3'bx10: ...
3'bx11: ...
3'b00x: ...
default: ....
endcase
6-24
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Statements
Precision RTL Synthesis does full coverage analysis for the if-then-else structure. The
following example is considered a full if-then-else. The last else is ignored and a warning is
issued.
wire [1:0] data;
if (data == 2)
...........
else if (data == 1)
...........
else if (data == 3)
...........
else if (data == 0)
...........
else
// Ignored for synthesis purpose
endmodule
Automatic Parallel Case Detection
casex statements are priority-encoded by definition. Precision RTL Synthesis automatically
detects parallel case and produce a warning message saying that case conditions are mutually
exclusive. The following case statement is treated as parallel case.
input [2:0] sel;
casex (sel)
3'b10x: ...
3'bx10: ...
3'bx11: ...
3'b00x: ...
default: ....
endcase
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)
...........
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-25
Statements
Verilog Language Features
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)
6’bXXX001 : <statement> ;
// this statement is executed if vect[2:0] = 3’b001
endcase
casez Supported
casez is used in Verilog to specify “don't care” bits of the case tags. The ’z’s in the case tags
are not compared when a comparison between the case expression sel and the tags is done.
...
casez (sel)
3'b10z: ...
3'bz10: ...
3'bz11: ...
3'b00z: ...
default: ....
endcase
’case’ and ’default’ Statements
Precision RTL Synthesis allows the default statement to appear anywhere in a case, casez, or
casex statement, and supports the case statement with only one default entry.
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] ;
...
6-26
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Statements
for loops are supported if they are bound by constants. for loops are also supported if they
contain a “@ posedge clk” statement which prevents infinite combinatorial loops.
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
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-27
Statements
Verilog Language Features
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
forever, repeat, while and Generalized Form of for
Loop
forever, repeat, while, and the generalized form of the for loop are supported as long as they
satisfy the conditions of for loops. The following forever example, is a counter with
synchronous reset.
module forever_example (clk, reset, out);
input clk, reset;
output [3:0]out;
reg [3:0]out;
always
begin
@(posedge clk) out = 0;
begin: for_ever
forever
begin: name
@(posedge clk)
if (reset) disable for_ever;
out = out + 1;
end
end
end
endmodule
6-28
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Functions and Tasks
module repeat_example (i, o);
input i;
output o;
reg o;
always @ (i)
begin
o = i;
repeat (4'b1011)
o = ~o; // o = ~i
end
endmodule
If any loop construct is NOT bound by constants or by clock events, then Precision RTL
Synthesis issues the “iteration limit reached” error.
Functions and Tasks
Pieces of Verilog can be grouped together in functions and tasks, which can then be used as
subprograms in the Verilog code. This is useful for repeated code, or for readability of the main
module.
Tasks and functions appear similar, but are used in different ways. A task is a subprogram with
inputs and outputs, and replaces any piece of verilog code in a module. Expressions in a task can
be both combinational and sequential.
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);
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-29
Functions and Tasks
Verilog Language Features
An example of a function is given below.
module calculator ( a, b, clk, s, operator );
input [7:0] a, b;
input clk;
input [1:0] operator;
output [7:0] s;
reg [7:0] s;
parameter ADD = 2’b00, SUB = 2’b01, MUL = 2’b10;
function [15:0] mult;
input [ 7:0] a, b ;
reg [15:0] r;
integer i;
begin
if (a[0] == 1)
r = b;
else
r = 0;
for (i = 1; i < 7; i = i + 1) begin
if (a[i] == 1 )
r = r + b << i ;
end
mult = r;
end
endfunction
always @ (posedge clk)
begin
case (operator)
ADD: s = a + b ;
SUB: s = a - b ;
MUL: s = mult(a,b);
endcase
end
endmodule
Tasks
Tasks are always displayed as statements:
my_task(a,b,c,d);
Precision RTL Synthesis supports empty tasks.
6-30
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
Functions and Tasks
An example of a task is presented below.
task demux ( state, load, bait, enable, ready, write, read );
input [2:0] state;
output load, bait, enable, ready, write, read;
parameter LOAD = 3’b000, WAIT = 3’b100, ENAB = 3’b110,
READ = 3’b111, WRIT = 3’b011, STRO = 3’b001;
case (state)
LOAD:
{state,
WAIT:
{state,
ENAB:
{state,
READ:
{state,
WRIT:
{state,
STRO:
{state,
endcase
endtask
load, bait, enable, ready, write, read} = 6’b100000;
load, bait, enable, ready, write, read} = 6’b010000;
load, bait, enable, ready, write, read} = 6’b001000;
load, bait, enable, ready, write, read} = 6’b000100;
load, bait, enable, ready, write, read} = 6’b000010;
load, bait, enable, ready, write, read} = 6’b000001;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-31
Functions and Tasks
Verilog Language Features
Inout Ports in Task
Precision RTL Synthesis supports inout ports in a task statement. Any value passed through
inout ports can be used and modified inside the task.
module inoutintask (i, o1, o2);
input i;
output o1, o2;
reg r, o1, o2;
task T ;
inout io;
output o;
begin
o = io;
io = ~io;
end
endtask
always @ (i)
begin
r = i;
T (r, o1); // o1 = i, r = ~i
o2 = r;
// o2 = ~i;
end
endmodule
6-32
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog Language Features
System Task Calls
Access of Global Variables from Functions and Tasks
Global variables can be accessed for both reading and writing.
module x (clk, reset, i1, i2, o);
input clk, reset, i1, i2;
output o;
reg o;
reg [1:0] state;
task T; //without any port
begin
case (state)
2'b00: o = i1;
2'b01: o = i2;
2'b10: o = ~i1;
2'b11: o = ~i2;
endcase
state = state + 1; // next state
end
endtask
always @ (posedge clk or posedge reset)
if (reset) begin
state = 0;
o = 0;
end
else T;
endmodule
System Task Calls
Precision RTL Synthesis accepts system task calls. System task calls are ignored and a warning
is issued.
System Function Calls
Precision RTL Synthesis accepts system function calls. The value 0 is assumed for system
function calls and a warning is issued.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
6-33
Initial Statement
Verilog Language Features
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
6-34
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 7
The Art of Verilog Synthesis
This chapter explains how particular logic constructs can be synthesized with Verilog
restrictions taken into account.
Registers, Latches, and Resets
Verilog synthesis produces registers and combinational logic at the RTL level. All
combinational behavior around the registers is, unless prohibited by the user, optimized
automatically. Hence, the style of coding combinational behavior, like if-then-else and case
statements, has little affect on the final circuit result, but the style of coding sequential behavior
has significant impact on your design.
This section shows how sequential behavior is produced with Verilog, so that you understand
why registers are generated at certain places and why not in others.
Most examples explain the generation of these modules with short Verilog descriptions in an
always block.
Level-Sensitive Latch
This first example describes a level-sensitive latch:
...
input input_foo, ena ;
reg output_foo ;
...
always @ (ena or input_foo)
if (ena)
output_foo = input_foo ;
...
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-1
Registers, Latches, and Resets
The Art of Verilog Synthesis
The sensitivity list is required, and indicates that the always block is executed whenever the
signals ena or input_foo change. Also, since the assignment to the register output_foo is
hidden in a conditional clause, output_foo cannot change (preserves its old value) if ena is 0.
If ena is 1, output_foo is immediately updated with the value of input_foo, 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.
Edge-Sensitive Flip-flops
An edge triggered flip-flop is generated from a Verilog description if a variable assignment is
executed only on the leading (or only on the trailing) edge of another variable. For that reason,
the condition under which the assignment is done must include an edge-detecting construct.
There are a number of edge detecting attributes in Verilog. The two most commonly constructs
are posedge and negedge.
The posedge construct detects transitions (is true) for 0 to 1. The negedge construct detects
transitions from 1 to 0.
Here is one example of the posedge construct, used in the condition clause in an always block.
Precision RTL Synthesis generates an edge-triggered flip-flop out of this behavior, with
output_foo updated only if clk shows a leading edge.
....
input input_foo, clk ;
reg output_foo ;
....
always @ (posedge clk)
output_foo = input_foo ;
....
If the posedge construct is not in the sensitivity list of the always block, a warning is issued
that input_foo is not on the sensitivity list.
7-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
Registers, Latches, and Resets
Synchronous Sets and Resets
All conditional assignments to variable output_foo inside the if clause translate into
combinational logic in front of the D-input of the flip-flop. For instance, we can make a
synchronous reset on the flip-flop by doing a conditional assignment to output_foo:
...
input input_foo, clk, reset ;
reg output_foo ;
...
always @ (posedge clk)
if (reset)
output_foo = 1’b0 ;
else
output_foo = input_foo ;
...
Variables reset and input_foo should not be included on the sensitivity list executing this
block should not occur when they change.
Asynchronous Sets and Resets
If we want the reset signal to have immediate effect on the output, but still let the assignment to
output_foo from input_foo only happen on the leading clock edge, we require the behavior
of an asynchronous reset.
...
input input_foo, clk,
reg output_foo ;
...
always @ (posedge clk
if (reset)
output_foo =
else
output_foo =
...
reset ;
or posedge reset)
1’b0 ;
input_foo ;
Now reset has to be in the sensitivity list. If reset is not there, Verilog semantics require that
the always block does not execute if reset changes. This always block executes only if a
positive change in clk is detected.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-3
Assigning I/O Buffers from Verilog
The Art of Verilog Synthesis
Asynchronous set and reset can both be used. This results in combinational logic driving the set
and reset input of the flip-flop of the target signal. The following code fragment shows the
structure of such a process:
always @(<edge of clock> or
<edge_of_asynchronous_signals> )
if (<asynchronous_signal>)
<asynchronous signal_assignments>
else if (<asynchronous_signal>)
<asynchronous signal_assignments>
...
else
<synchronous signal_assignments>
There can be several asynchronous else if clauses, but the synchronous assignments have to
be the last one in the if clause. A flip-flop is generated for each signal that is assigned in the
synchronous signal assignment. The asynchronous clauses result in combinational logic that
drives the set and reset inputs of the flip-flops.
Clock Enable
It is also possible to specify an enable signal in a process. Some technologies (specifically
Xilinx) have a special enable pin on their basic flip-flop. The synthesis tools recognize the
function of the enable from the Verilog description and generate a flip-flop with an enable
signal from the following code fragment:
...
input input_foo, clk, enable ;
reg output_foo ;
...
always @ (posedge clk)
if (enable)
output_foo = input_foo ;
...
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.
Assigning I/O Buffers from Verilog
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
7-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
Tristate Buffers
Synthesis may make by assigning the buffer_sig attribute to a port or a net in the Verilog. 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 Verilog 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.
Buffer Assignment Using Component Instantiation
It is possible to instantiate buffers in the Verilog source file with component instantiation. In
particular, if you want a specific input or output buffer to be present on a specific input or
output, component instantiation is a very powerful method. Consider the following code
segment:
module special_buffer_example (inp, clk, outp, inoutp) ;
input inp, clk ;
output outp ;
inout inoutp ;
wire intern_in, intern_out, io_control ;
OUTPUT_FF A1(.c(clk), .d(intern_out),
.t(io_control),.o(inoutp));
INPUT_BUFFER A2(.i(inp), .o(intern_in)) ;
endmodule
In this example, component instantiation forces an OUTPUT_FF buffer (complex I/O output/flipflop buffer) on the bidirectional pin inoutp. Also an input buffer INPUT_BUFFER is specified to
pick up the value from inp to be used internally.
In the case of component instantiation of I/O buffers, the right source technology must be
specified when you setup the design to assure that Precision RTL Synthesis takes the
instantiated I/O buffer from the right library.
Tristate Buffers
Tristate buffers and bidirectional buffers (covered in the next sub-section) are very easy to
generate from a Verilog description.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-5
Tristate Buffers
The Art of Verilog Synthesis
Example 1:
// conditional expression
assign o1 = oe1 ? d1 : 1’bz;
assign x = oe2 ? d2 : 1’bz;
assign o1 = x;
// if statement
always @ (oe3 or d3)
if (oe3)
o2 = d3;
else
o2 = 1’bz;
// case statement
always @ (oe4 or d4)
case (oe4)
default : o2 = 1’bz;
1’b1
: o2 = d4;
endcase
Example 2:
module tristate (input_signal, ena, output_signal) ;
input input_signal, ena ;
output output_signal ;
assign output_signal = ena ? input_signal :
1’bz ;
endmodule
Note that in the conditional clause of the assign statement, both input_signal and ena 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. The use of the ’z’ value in any
form inside a clocked always block is also illegal.
7-6
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
Tristate Buffers
Example 3:
assign
output_signal = input_signal & 1’bz;
Normally, simultaneous assignment to one signal in Verilog is not allowed for synthesis, since it
would cause data conflicts. However, if a conditional ’Z’ is assigned in each assignment,
simultaneous assignment resembles multiple tristate buffers driving the same bus.
module tristate_example_2 (input_signal_1, input_signal_2, ena1,
ena2, output_signal) ;
input input_signal_1, input_signal_2, ena1, ena2 ;
output output_signal ;
assign output_signal = ena1 ? input_signal_1 : 1’bz ;
assign output_signal = ena2 ? input_signal_2 : 1’bz ;
endmodule
You can still introduce a data conflict with these simultaneous assignments to output_signal,
by making both ena_1 and ena_2 1’b1. 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.
If the target technology does not have any internal three-state drivers, Precision RTL Synthesis
can transform the three-state buffers into regular logic. You set the option from the GUI with
the pulldown menu Tools > Set Options... Select Input > Optimization in the dialog box and
click on the radio button “Convert tri-states to muxes”.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-7
Bidirectional Buffers
The Art of Verilog Synthesis
Bidirectional Buffers
Bidirectional I/O buffers can be coded in Verilog as follows:
module bidirectional (bidir_port, ena, ...) ;
input ena ;
inout bidir_port ;
assign bidir_port = ena ? internal_output :
1’bZ ;
assign internal_input = bidir_port ;
...
// use internal_input
...
// generate internal_output
endmodule
The difference with the previous examples is that in this case, the output is used again
internally. For this reason, the port bidir_port is declared to be inout.
The enable signal ena can also be generated inside the module instead of being a primary input
as in this example.
Precision RTL Synthesis selects a suitable bidirectional buffer from the target technology
library. If there is no bidirectional buffer available, it selects a combination of a tristate buffer
and an input buffer.
Buses
The examples given above all use single bits as signals. In reality, buses or arrays of bits with
tristatable (multiple) drivers, are often used. Buses are used both internally to the design and as
I/O. For internal tristate buses, the bus signal should be declared as a net.
The following example describes a circuit that loads a source vector of 4 bits on the edge of a
clock (wrclk), and stores the value internally in a register (intreg) if the chip enable (ce) is
7-8
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
Buses
active. One bit of the register output is put on a tristate bus (result_int), based on a 2-bit
selector signal (selector), with the bus output clocked through a final register (result).
module tri_asgn (source, ce, wrclk, selector, result) ;
input [3:0] source ;
input ce, wrclk ;
input [1:0] selector ;
output result ;
reg [3:0] intreg ;
reg result ;
wire [1:0] sel = selector ;
tri result_int ;
// assignment to internal tristate bus
assign
result_int = (~sel[0] && ~sel [1])
,
result_int = (sel[0] && ~sel [1])
,
result_int = (~sel[0] && sel [1])
,
result_int = (sel[0] && sel [1])
;
? intreg[0] : 1’bZ
? intreg[1] : 1’bZ
? intreg[2] : 1’bZ
? intreg[3] : 1’bZ
always @(posedge wrclk)
begin
if (ce)
intreg = source;
result = result_int ;
end
endmodule
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-9
State Machines
The Art of Verilog Synthesis
In the following example of a tristate bus used for output, a source is loaded into a register
(tbuf_in) whose output is a set of tristate buffers.
module tri_bus (d, clk, en, tbuf_out) ;
parameter n = 8 ;
parameter triZ = 8’bZ ;
input [(n-1):0] d ;
input clk, en ;
output [(n-1):0] tbuf_out ;
reg [(n-1):0] tbuf_in ;
assign tbuf_out = en ? tbuf_in : triZ ;
always @ (posedge clk)
tbuf_in = d ;
endmodule
State Machines
There are basically two forms of state machines, Mealy machines and Moore machines. In a
Moore machine, the outputs do not directly depend on the inputs, only on the present state. In a
Mealy machine, the outputs depend directly on the present state and the inputs.
In general, a description of a state machine consists of descriptions of the state transitions, the
output functions and a register function. Because of the register function, an always block in
Verilog is an appropriate way to describe a state machine. if-else-if or case statements in an
always block perform the state transition and output function descriptions.
7-10
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
State Machines
In the following sections, the DRAM interface state machine shown in Figure 7-1 is used to
illustrate state machine design using Verilog.
Figure 7-1. DRAM Interface with Refresh
ras1'b1 cas=1'b1 ready=1'b1
cs=1'b0 refresh=1'b1
ras1'b1 cas=1'b0 ready=1'b0
ras1'b0 cas=1'b1 ready=1'b0
s0
refresh=1'b1
cs=1'b1 refresh=1'b0
s3
s1
ras1'b1
cas=1'b1
ready=1'b1
cs=1'b0
ras1'b1
cas=1'b1
ready=1'b1
ras1'b0 cas=1'b0 ready=1'b0
s4
ras1'b0 cas=1'b0 ready=1'b0
s2
cs=1'b1
ras1'b0 cas=1'b0 ready=1'b0
Altera 04
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-11
State Machines
The Art of Verilog Synthesis
Moore Machines
An example of a Moore machine is:
module moore (clk, cs, refresh, ras, cas, ready) ;
input clk, cs, refresh ;
output ras, cas, ready ;
parameter /* pragma enum ee1 */ s0 = 0, s1 = 1, s2 = 2,
s3 = 3, s4 = 4 ;
reg [2:0]/* pragma enum ee1 */ present_state ;
reg ras, cas, ready ;
always @ (posedge clk)
begin
case (present_state)
s0 : begin
if (refresh)
present_state =
else if (cs)
present_state =
else
present_state =
end
s1 : begin
present_state = s2 ;
end
s2 : begin
if (~cs)
present_state =
else
present_state =
end
s3 : begin
present_state = s4 ;
end
s4 : begin
present_state = s0 ;
end
7-12
s3 ;
s1 ;
s0 ;
s0 ;
s2 ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
State Machines
default : begin
present_state = s0 ;
end
endcase
end
always @ (present_state)
begin
case (present_state)
s0 : begin
ras = 1’b1
end
s1 : begin
ras = 1’b0
end
s2 : begin
ras = 1’b0
end
s3 : begin
ras = 1’b1
end
s4 : begin
ras = 1’b0
end
default : begin
ras = 1’bX
end
endcase
end
endmodule
; cas = 1’b1 ; ready = 1’b1 ;
; cas = 1’b1 ; ready = 1’b0 ;
; cas = 1’b0 ; ready = 1’b0 ;
; cas = 1’b0 ; ready = 1’b0 ;
; cas = 1’b0 ; ready = 1’b0 ;
; cas = 1’bX ; ready = 1’bX ;
Note: The pragma enum ee1 directive is added to the Moore machine example. This directive
indicates that present_state is an enumerated type. This directive allows Precision Synthesis
to automate the state machine encoding. You can then select the encoding for your design on the
GUI or with coded commands.
There are two always blocks in the state machine description. The first is synchronized with the
clock clk and describes the state transitions. This block depends on the present state and the
inputs. The second is not synchronized, but it reacts immediately if there is a change in v. This
second always block describes the functions of the outputs depending on the present state. The
split into two processes is not absolutely necessary. The same functional behavior can be
generated by merging the two always blocks into one. However, the logic that is generated is
somewhat different, as explained below.
Below is exactly the same Moore machine description, but this time it consists of only one
always block. In the first description, the outputs ras, cas and ready were assigned in an
asynchronous (not clocked) always block as a function of present_state. They therefore
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-13
State Machines
The Art of Verilog Synthesis
appear as purely combinational logic. In the description below, the same outputs are generated
in a clocked always block. Therefore, the outputs ras, cas and ready appear at the Q-output of
flip-flops with the combinational logic computing the value of these signals at the D-inputs of
the same flip-flops.
The subtle differences between the two descriptions result in trading off timing behavior and
logic circuitry. The first description builds a circuit where the outputs ripple through logic after
the clock edge. In the second description, the outputs change glitch-free at the clock-edge, and
are stable immediately after that, but at the cost of an additional flip-flop for each output.
module moore_example_2 (clk, cs, refresh, reset, ras, cas, ready)
;
input clk, cs, refresh, reset ;
output ras, cas, ready ;
parameter /* pragma enum ee1 */ s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4
= 4 ;
reg [2:0] /* pragma enum ee1 */ present_state ;
reg ras, cas, ready ;
always @ (posedge clk or posedge reset)
begin
if (reset) // asynchronous reset
begin
present_state = s0 ;
ras = 1’b1 ; cas = 1’b1 ; ready = 1’b1 ;
end
else
begin
case (present_state)
s0 :
if (refresh)
begin
present_state = s3 ;
ras = 1’b1; cas = 1’b0 ; ready = 1’b0 ;
end
7-14
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
s1
s2
s3
s4
State Machines
else if (cs)
begin
present_state = s1 ;
ras = 1’b0; cas = 1’b1 ; ready = 1’b0 ;
end
else
begin
present_state = s0 ;
ras = 1’b1; cas = 1’b1 ; ready = 1’b1 ;
end
:
begin
present_state = s2 ;
ras = 1’b0 ; cas = 1’b0 ; ready = 1’b0 ;
end
:
begin
if (~cs)
begin
present_state = s0 ;
ras = 1’b1; cas = 1’b1 ; ready = 1’b1 ;
end
else
// cs = 1’b1
begin
present_state = s2 ;
ras = 1’b0; cas = 1’b0 ; ready = 1’b0 ;
end
end
:
begin
present_state = s4 ;
ras = 1’b0 ; cas = 1’b0 ; ready = 1’b0 ;
end
:
begin
present_state = s0 ;
ras = 1’b1 ; cas = 1’b1 ; ready = 1’b1 ;
end
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-15
State Machines
The Art of Verilog Synthesis
default:
begin
present_state = s0 ;
ras = 1’bX ; cas = 1’bX ; ready = 1’bX ;
end
endcase
end
end
endmodule
This example also added an asynchronous reset to the design.
Mealy Machines
So far, we have shown a number of examples of Moore machines. In a Mealy machine, outputs
depend on both the present state and the inputs. Below is the state machine again, but now in a
Mealy machine form. Notice that the behavior changes slightly, since the inputs affect the
outputs immediately, without waiting for the new state to be generated.
In the Moore machine example, it was possible to merge the two processes into one,
synchronized with a clock, since all activity was happening on the clock edge. In this Mealy
machine example, however, the outputs are updated even when there is no clock edge. Thus, in
this case, it is not possible to merge the two processes into one.
A Mealy machine is, in general, described with two always blocks, where one block does all
combinational functionality and the other just updates the present state with the next state, on
the clock edge.
7-16
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
State Machines
This code shows an example of a Mealy machine.
module mealy (clk, cs, refresh, ras, cas, ready) ;
input clk, cs, refresh ;
output ras, cas, ready ;
parameter /* pragma enum ee1 */ s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4
= 4 ;
reg [2:0]/* pragma enum ee1 */ present_state, next_state ;
reg ras, cas, ready ;
always @ (posedge clk)
begin
// always block to update the present state
present_state = next_state ;
end
always @ (present_state or refresh or cs)
begin
// always block to calculate the next state and the outputs
next_state = s0 ;
ras = 1’bX ; cas = 1’bX ; ready = 1’bX ;
case (present_state)
s0 : begin
if (refresh)
begin
next_state = s3 ;
ras = 1’b1 ; cas = 1’b0 ; ready = 1’b0 ;
end
else if (cs)
begin
next_state = s1 ;
ras = 1’b0 ; cas = 1’b1 ; ready = 1’b0 ;
end
else
begin
next_state = s0 ;
ras = 1’b1 ; cas = 1’b1 ; ready = 1’b1 ;
end
end
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-17
State Machines
The Art of Verilog Synthesis
s1 : begin
next_state = s2 ;
ras = 1’b0 ; cas = 1’b0 ; ready = 1’b0 ;
end
s2 : begin
if (~cs)
begin
next_state = s0 ;
ras = 1’b1 ; cas = 1’b1 ; ready = 1’b1 ;
end
else
begin
next_state = s2 ;
ras = 1’b0 ; cas = 1’b0 ; ready = 1’b0 ;
end
end
s3 : begin
next_state = s4 ;
ras = 1’b1 ; cas = 1’b0 ; ready = 1’b0 ;
end
s4 : begin
next_state = s0 ;
ras = 1’b0 ; cas = 1’b0 ; ready = 1’b0 ;
end
endcase
end
endmodule
Combinational loops can be generated easily (and are in most cases unwanted) in a Mealy
machine description. If nothing is assigned to a signal in one or more cases (for instance
because you do not care what the value is going to be), Verilog semantics require that the value
of the signal is preserved. In an asynchronized always block as the one shown above, this
means that synthesis must generate a combinational loop or a level-sensitive latch to preserve
the value.
Issues in State Machine Design
This section discusses several issues regarding the design of synthesizable state machines:
7-18
•
State encoding
•
Onehot encoding
•
Initialization of the state machine
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
•
Power-up conditions
•
Semantics of the case statement
State Machines
State Encoding
States must be explicitly specified by the user. This can be done by explicitly using the bit
pattern (e.g., 3’b101), or by defining a parameter (e.g., parameter s3 = 3’b101) and using
the parameter as the case item.
Onehot Encoding
The recommended method to implement a onehot state machine is to set the state machine
variable to an enumerated type with the enum pragma. You can review this method in the
previous Mealy and Moore machine examples in this chapter. Then you can use the encoding
option or pragma to set the state machine encoding to onehot.
The next Verilog example description is for a onehot encoded state machine with the same
functionality as shown in the previous Mealy and Moore machine examples. This Verilog
example allows you to explicitly encode the state machine as onehot.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-19
State Machines
The Art of Verilog Synthesis
module one_hot_mealy (clk, cs, refresh, reset, ras, cas, ready) ;
input clk, cs, refresh, reset ;
output ras, cas, ready ;
reg [4:0] present_state, next_state ;
reg ras, cas, ready ;
always @ (posedge clk)
begin
// always block to update the present state
if (reset)
present_state = 5’b00001 ;
else
present_state = next_state ;
end
always @ (present_state or refresh or cs)
begin
// always block to calculate the next state and the outputs
next_state = 5’b00000 ;
ras = 1’bX ; cas = 1’bX ; ready = 1’bX ;
if (present_state[0])
begin
if (refresh)
begin
next_state = 5’b01000 ;
ras = 1’b1 ; cas = 1’b0 ; ready = 1’b0 ;
end
else if (cs)
begin
next_state = 5’b00010 ;
ras = 1’b0 ; cas = 1’b1 ; ready = 1’b0 ;
7-20
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
State Machines
end
else
begin
next_state = 5’b00001 ;
ras = 1’b1 ; cas = 1’b1 ; ready = 1’b1 ;
end
end
if (present_state[1])
begin
next_state = 5’b00100 ;
ras = 1’b0 ; cas = 1’b0 ; ready = 1’b0 ;
end
if (present_state[2])
begin
if (~cs)
begin
next_state = 5’b00001 ;
ras = 1’b1 ; cas = 1’b1 ; ready = 1’b1 ;
end
else
begin
next_state = 5’b00100 ;
ras = 1’b0 ; cas = 1’b0 ; ready = 1’b0 ;
end
end
if (present_state[3])
begin
next_state = 5’b10000 ;
ras = 1’b1 ; cas = 1’b0 ; ready = 1’b0 ;
end
if (present_state[4])
begin
next_state = 5’b00001 ;
ras = 1’b0 ; cas = 1’b0 ; ready = 1’b0 ;
end
end
endmodule
Some key points from this onehot state machine are:
•
The case statement should not be used for onehot state machine design. When the
casex statement is used for state comparisons, the comparisons must be done on only
one bit of the state vector. If the whole vector is used for comparison, then full binary
encoding logic is synthesized. Also, the case statement needs to be compiled as
parallel_case.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-21
State Machines
•
The Art of Verilog Synthesis
The else if construct should not be used to do the state comparisons, since that
introduces additional constraints on the values of each state. Using else if means that
this code is only entered if the all previous conditions are false. In the case of onehot
encoding, it is certain that all previous conditions are false already.
This state machine description works fine, as long as the machine can never appear in a state
with more than one ’1’ in the state vector. In order to assure that condition, the need for a reset
becomes inevitable in the one-hot case. The use of resets is discussed in greater detail in the
next section.
Initialization and Power-Up Conditions
In synthesis, if the total number of states is not a power of two, the state signal can power-up in
a state that has not been defined, if binary encoding is used. In this situation, it is essential that
the Verilog description does an assignment to the output variables and the state variable under
all conditions.
This can be done in two ways:
•
•
Do a default assignment to the outputs and state variable before the case statement that
updates the state machine. This method is used in the first Moore and the Mealy
machine examples from the previous sections. It assures that outputs and state variable
always get a value assigned regardless of the state of the state machine.
Do the default assignment in the default clause of the case statement, as was shown in
the second Moore machine example. This has the same effect; outputs and states always
get a value regardless of the state of the machine.
If you do not do a default assignment, the state machine could power-up in a undefined state.
Verilog semantics require that if there is no assignment to a signal, the previous value has to be
preserved. In case the state transitions are defined in an asynchronous always block, latches
would be generated by the synthesis tools to preserve the state value.
If onehot or another state encoding is used, the number of undefined states could be even larger.
Consider that in onehot encoding, the specification of the state machine has to rely on the fact
that only one single state bit of the state vector is 1. That means that the designer has to provide
a special feature that takes care of the power-up conditions.
One possibility might be to include a special detection function that sets the state to a valid one
the moment it occurs in a invalid one. However, it would require too much logic to implement
this functionality, making the use of one-hot encoding unattractive. In most cases, it is much
more cost effective to include the possibility of a reset function. The reset can be defined to be
synchronous or asynchronous, depending on what you want.
7-22
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
Arithmetic and Relational Logic
Arithmetic and Relational Logic
This section gives an overview of how arithmetic logic is generated from Verilog, what the
synthesis tools do with it and how to avoid getting into combinational explosion with large
amounts of arithmetic behavior.
In general, logic synthesis is very powerful in optimizing random combinational behavior, but
has problems with logic which is arithmetic in nature. Often special precautions have to be
taken into consideration to avoid ending up with inefficient logic or excessive run times.
Alternatively, macros may be used to implement these functions.
The synthesis tools support the operators “+”, “-”, “==”, “!=”, “<”, “>”, “>>”, “<<”, “*”,“/”,
“<=”, and “>=”.
If you use these operators to calculate compile time constants, there is no restriction or problem
in using them. For example, the following division does not result in a any logic, but replaces
signal foo with a constant 3’d133.
...
integer largest ;
integer divider ;
assign largest = 800 ;
assign divider = 6 ;
assign foo <= largest / divider ;
...
If you are not working with constant operands, arithmetic logic is generated.
The operator “+” generates an adder. The number of bits of the adder depends on the size of the
operands. If you use integers, a 32 bit adder is generated. If you add vectors and integers, the
size of the adder is defined to the range of the vector in bits. For example:
...
integer a, b, c ;
assign c = a + b ;
...
generates a 32-bit adder but:
...
input [7:0] a ;
output [7:0] c ;
integer b ;
assign c = a + b ;
...
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-23
Arithmetic and Relational Logic
The Art of Verilog Synthesis
generates an 8-bit adder.
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 because half of the inputs of the
adder are constant.
The operator “-” generates a subtracter. Same remarks as with the “+” operator.
The operator “*” generates a multiplier. Multiplication by a constant power of two is
implemented as a shift operation. In all other cases, the Precision RTL Synthesis module
generator (ModGen) is required to implement the multiplier.
The operator “/” generates a divider. Only division by a power of two is supported, hence no
logic here, only shifting the non-constant operand.
The operators “==”, “!=”, “<”, “>”, “>>”, “<<”, “<=”, and “>=” generate comparators with the
appropriate functionality. Same remarks apply as for the “+” operator.
•
Operations on integers are done in twos-complement implementation.
All arithmetic behavior is translated into logic functions and is part of the logic
optimization process. The result is that depending on area and timing criteria and
constraints set, the final logic circuit can include, for example, carry lookahead or ripple
carry adder implementation. If the design is getting large, run-time and memory
requirements increase rapidly.
Some large designs can run forever without any improvement, if any solution is
produced at all. The reason is that the logic synthesis optimization algorithms try too
many possible circuit implementations from the exponentially growing search space.
Good design practices are needed to help avoid this problem.
Resource Sharing and Common Subexpression
Elimination
Precision RTL Synthesis automatically does common sub-expression elimination. For the
following example, only one adder (a+b) is created. The adder is used for both the if
conditions. For bigger expressions you need to use parentheses properly to direct the tool to
perform for CSE.
7-24
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
Arithmetic and Relational Logic
...
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 ;
...
Comparator Design
Applications may involve a counter that counts up to an input signal value, and when that value
is reached, some actions are needed and the counter is reset to 0.
...
begin
if (count == input_signal)
...
count = 0 ;
else
count = count + 1 ;
end ;
...
In this example Precision RTL Synthesis builds an incrementer and a full-size comparator that
compares the incoming signal with the counter value. It is usually better to preset the counter to
the input_signal and count down, until zero is reached.
...
begin
if (count == 0)
...
count = input_signal ;
else
count = count - 1 ;
end ;
...
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-25
Technology-Specific Macros
The Art of Verilog Synthesis
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.
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.
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.
Synthesis Directives
Verilog pragmas are also called synthesis directives.
parallel_case and full_case directives
parallel_case and full_case directives are allowed as synthesis directive on a case by case
basis. Precision RTL Synthesis detects the true full and parallel cases automatically. However,
7-26
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
Synthesis Directives
there are cases (like onehot encoded state machine) that are not inherently parallel/full, but the
environment guarantees that the case statement is parallel and/or full. In such a condition the
following two synthesis directives are very useful.
input [3:0] inp_state;
// example of onehot encoded machine
case (1'b1) // pragma parallel_case full_case
inp_state[0]: .......
inp_state[1]: .......
inp_state[2]: .......
inp_state[3]: .......
endcase
translate_off and translate_on directives
translate_off and translate_on synthesis directives are allowed to comment out a portion
of code that you may want to retain for some purpose other than synthesis.
// code for synthesis
// pragma translate_off
$display (.....); // not for synthesis
// pragma translate_on
// code for synthesis
endmodule
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-27
Synthesis Directives
The Art of Verilog Synthesis
module state_mc (clk, reset, o, i1, i2, i_state);
input clk, reset, i1, i2;
output o, i_state;
reg o;
parameter [1:0] /* pragma enum ee1
*/S0=1,S1=2,S2=3,S3=0;
reg [1:0] /* pragma enum ee1 */ state;
assign i_state = (state == S1 | state == S3); //
legal.
always @ (posedge clk or posedge reset)
if (reset) begin
o = 0;
state = S0; // Note state = 1, will cause a type
mismatch error
end
else
case (state) // No need of full and parallel case
S0: begin o = i1; state = S1; end
S1: begin o = ~i1; state = S2; end
S2: begin o = i2; state = S3; end
S3: begin o = ~i2; state = S0; endNote case tag
0: would cause type
mismatch error
endcase
endmodule
State and S0, S1, S2, S3 are of enum type ee1. They cannot be used for any boolean or arithmetic
operation. Bit or port select from state or its values is also considered an error. Enumerated type
module ports are not allowed.
attribute directive
You can set User attributes on design objects to refine and control the synthesis process. For
example, by setting the iob attribute on a signal to true, you can improve the timing
performance of the I/O by moving the first register in the path to the pad.
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>
7-28
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
The Art of Verilog Synthesis
Synthesis Directives
//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 iob true
endmodule
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
7-29
Synthesis Directives
7-30
The Art of Verilog Synthesis
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 8
Verilog and Synthesis of Logic
Verilog is a language that has been developed for simulation purposes. Synthesis was not an
issue in the development of the language. As a result, there are a number of Verilog constructs
that cannot be synthesized. There has been very little written that explains which constructs
cannot be synthesized into logic circuits and why.
This chapter provides explanations on why certain Verilog constructs cannot be synthesized
into logic circuits and what changes have to be made to reach the intended behavior to obtain a
synthesizable Verilog description.
Some obvious restrictions of the language are first presented, followed by a list summarizing
Verilog syntax and semantic restrictions for Mentor Graphics synthesis tools. In addition, some
guidelines are presented that should enable you to write Verilog that is easy to synthesize and
give you a feeling for synthesis complexity problems you might introduce when you write your
Verilog design.
Comparing With X and Z
Consider the Verilog modeling case where an if clause should be entered if a part of a vector has
a particular value. The rest of the vector does not really matter. You might want to write this as
follows:
if (vect == 6’bXXX001) begin ...
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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
8-1
Variable Indexing of Bit Vectors
Verilog and Synthesis of Logic
However, comparison to 'X' is allowed using the casex construct. This is implemented in the
following manner:
casex (vect)
6’bXXX001 :
endcase
<statement> ;
In this case, only the three least significant bits of vect are compared to "001". The comparison
ignores the three most significant bits.
Variable Indexing of Bit Vectors
Precision RTL Synthesis supports variable indexing of a vector. The limitation is that only
variable indexing of the form ’bit select’ is supported. Or more specifically, variable indexing of
the form ’part select’ is not supported because it is not a synthesizable construct.
The semantics of variable indexing varies depending on whether the variable indexing is done
on the left hand side of an assignment or on the right hand side of the assignment. The righthand side variable indexing generates a multiplexer controlled by the index. The left-hand
variable indexing generates a de-multiplexer controlled by the index. set of decoders enabling.
The following example shows both examples.
module tryit (input_bus, in_bit, control_input, output_bus,
out_bit);
input [3:0] input_bus ;
input [1:0] control_input ;
input in_bit ;
output [3:0] output_bus ;
output out_bit ;
reg [1:0] control_input ;
reg [3:0] input_bus, output_bus ;
reg in_bit, out_bit ;
always @ (control_input or input_bus or in_bit)
begin
out_bit = input_bus [control_input] ;
output_bus [control_input] = in_bit ;
end
endmodule
8-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Verilog and Synthesis of Logic
Syntax and Semantic Restrictions
Syntax and Semantic Restrictions
This section provides a summary of the syntax and semantic restrictions of the Precision RTL
Synthesis Verilog HDL parser.
Unsupported Verilog Features
•
UDP
•
specify
•
real
•
initial
•
tri0, tri1, tri1, tri1, tri1,
•
time
•
Named events and event triggers
•
primitives
block
variables and constants
statement
net types
data type
The following gates: pulldown, pullup, nmos, mmos, pmos, rpmos, cmos, rcmos, tran,
rtran, tranif0, rtranif0, tranif1, rtranif1
•
wait
•
Parallel block, join and for.
•
System task enable and system function call
•
force
•
release
•
Blocking assignment with event control
•
statements
statement
statement
Named port specification (not to be confused with passing arguments by name, which
is supported)
•
Concatenation in port specification
•
Bit selection in port specification
•
Procedural assign and de-assign
•
Supported Verilog Features
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
8-3
Syntax and Semantic Restrictions
8-4
Verilog and Synthesis of Logic
•
Edge triggers on sensitivity list must be single bit variable, or array indexing expression.
•
Indexing of parameters is not allowed.
•
Loops must be bounded by constants or contain (@ posedge clk) statement.
•
Supported Verilog Features
•
Delay and delay control.
•
’vectored’ declaration.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 9
Operators, Counters, and Memory
Although you can instantiate technology-specific modules into your HDL source code,
Precision RTL Synthesis has a module generator (called Modgen) that creates efficient
technology-specific implementations of arithmetic and relational operators, counters, and
memory (RAM and ROM).
Inferring 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 “>”, with
technology-specific implementations. As an example, consider the following VHDL statement:
signal a, b, s : std_logic_vector(n downto 0);
s <= a + b;
When implementing this VHDL statement in an FPGA architecture, you would like to utilize a
technology-specific adder that is dependent on the size of n. Modgen automatically allows this
to happen.
The operations in Table 9-1 are recognized by Precision RTL Synthesis and are matched with
modules from Modgen. For Verilog HDL, Precision RTL Synthesis recognizes these operations
from all (predefined) supported operators in the Verilog HDL language. For VHDL, Precision
RTL Synthesis recognizes these operations for operators on the predefined type integer. It also
recognizes these operations from operators for the bit_vector and std_logic_vector types,
as long as the package numeric_std or exemplar package is included with a use clause.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-1
Inferring Operators
Operators, Counters, and Memory
Table 9-1. Operators that are Recognized by Precision
9-2
Verilog
VHDL ’87
Operation
"+"
"+"
addition
"-"
"-"
binary subtraction, unary
negation
"+ 1"
"+ 1"
increment
"- 1"
"- 1"
decrement
"=="
"="
equal
"!="
"/="
not equal
">"
">"
greater than
"=>"
"=>"
greater than or equal
"<"
"<"
less than
"<="
"<="
less than or equal
"*"
"*"
multiplication
"/"
"/"
division
N/A
"**"
power
"%"
"mod"
modulo
N/A
"rem"
remainder
N/A
"abs"
absolute value
">>"
"sra"
shift right logical
"<<"
"sla"
shift left logical
N/A
"sra"
shift right arithmetic
N/A
"sla"
shift left arithmetic
N/A
"rol"
rotate left
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Operators, Counters, and Memory
Inferring Operators
Inferring a Pipelined Multiplier
Introduction
Precision RTL Synthesis automatically performs an optimization technique called "pipelining'
on multipliers for certain technologies during optimization. The pipelining process takes
advantage of natural breaking points in the multiplier architecture to move banks of registers
backwards into the multiplier logic to improve performance. Users can place several banks of
registers at the multiplier outputs, which will be automatically pipelined during optimization.
Precision will pipeline multipliers with registers at the output during the mapping phase of
optimization. This is not timing driven optimization process - pipelining will occur regardless
of whether a design is meeting timing. Both Xilinx Virtex II and Altera Stratix include
dedicated registered multipliers, which makes pipelining optimal implementation for both area
and performance.
How Pipelining Works
Pipelining will 'absorb" registers at the output of a multiplier to improve performance. Simple
enough, however, this statement generally results in 2 questions:
1. How many pipeline stages can the multiplier "absorb"?
2. What type of performance improvements can be obtained?
How many pipeline stages can be "absorbed"?
There is no limit to the number of pipeline stages that a user may place at the outputs of a
multiplier when pipelining. There is, however, an optimal number that will deliver the
maximum performance benefits. If fewer than the optimal number are used then the multiplier
will see some performance benefits but not the maximum possible through pipelining. If the
user places more than the optimal number then the "extra" pipeline stages will remain at the
outputs of the multiplier and provide no additional performance gains. The optimal number of
pipeline stages is calculated through the following simple equation.
Optimal # of pipeline stages = Log10 (input data bus width)
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-3
Inferring Operators
Operators, Counters, and Memory
Although the answer to this question is somewhat mathematical it is not as confusing as it
appears. For example if the input databus is 16 bits than the optimal number of pipeline stages
is 4. The table below provides some common values.
Table 9-2. Optimal Number of Pipeline Stages
Input Data Bus Width
Pipeline Stages
8
3
16
4
32
5
64
6
128
7
Figure 9-1. Pipelined Multiplier - Before Pipelining
9-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Operators, Counters, and Memory
Inferring Operators
Figure 9-2. Figure 2 - Pipelined Multiplier - After Retiming
Performance Improvements achieved through Pipelining
Pipelining can improve the performance of a multiplier by 2X when the optimal number of
pipeline stages is used. Using fewer pipeline stages will result in some improvement less that
2X. When more than the optimal number pipeline stages are used not additional performance
gains are realized.
Supported Technologies
Pipelining is supported for the following technologies
Table 9-3. Technologies that Support Pipelining
Xilinx
Altera
Virtex/Virtex-E
APEX 20K
Virtex-II
APEX 20KC
Virtex-II Pro
APEX 20KE
Spartan-II
APEX II
Spartan-IIE
Stratix
Spartan-III
Stratix GX
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-5
Inferring Operators
Operators, Counters, and Memory
Mapping Operators to Dedicated Resources
Many of the latest technologies have dedicated hardware for arithmetic functions such as
mulitipliers and adders. By default, Precision will map operators to these dedicated resources. If
the number of operators in your design exceeds the number of dedicated resources in the
selected device, you can use the Precision GUI to redirect the mapping of some operators to
alternative resources. In Figure 9-3, the automatic mapping of the selected multiplier to a Stratix
dedicated multiplier is changed to LCELLs instead.
Figure 9-3. Changing the Mapping of a Multiplier in a Stratix Device
1. Select and
Right-Click
2. Select
9-6
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Operators, Counters, and Memory
Inferring Operators
Inferring Counters
Precision can recognize counter behavior in VHDL or Verilog and infer the correct hardware
implementation. The counters inferred are positive edge-triggered with optional clock enable
and/or count enable, asynchronous clear and/or set, synchronous clear, and synchronous load.
Up, down, and up-down counters are supported. The following example is recognized as an 8bit loadable down-counter with asynchronous clear and clock enable:
Figure 9-4. Inferring an 8-Bit Loadable Down-Counter
library ieee, exemplar;
use ieee.std_logic_1164.all;
use exemplar.exemplar_1164.all;
entity cnt_dn_ac_sl_en is
port (clk, clk_en, aclear, sload: in std_logic;
data: in std_logic_vector(7 downto 0);
q: out std_logic_vector(7 downto 0));
end cnt_dn_ac_sl_en;
architecture rtl of cnt_dn_ac_sl_en is
signal q_int: std_logic_vector(q'range);
begin
process (clk, aclear)
begin
if (aclear = '1') then
q_int <= (q_int'range => '0');
elsif (clk'event and clk'last_value = '0' and clk = '1') then
if (clk_en = '1') then
if (sload = '1') then
q_int <= data;
else
q_int <= q_int - "1";
end if;
end if;
end if;
end process;
q <= q_int;
end rtl;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-7
Inferring Memory
Operators, Counters, and Memory
Inferring Memory
How Memory Inferencing Works
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.
This section presents coding styles for technology-independent memory inferencing.
For Altera-specific memory Inferencing HDL models, refer to “How Memory Inferencing
Works for Altera” on page 8-2 of the Precision Synthesis Reference Manual.
For Xilinx-specific memory Inferencing HDL models, refer to “Xilinx Memory Mapping” on
page 9-8 of the Precision Synthesis Reference Manual.
9-8
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Operators, Counters, and Memory
Inferring Memory
Inferring Synchronous Single-Port RAM
Figure 9-5 shows the recommended VHDL style for inferring a single-port RAM.
Figure 9-5. Inferring Synch Single-Port RAM from VHDL
library IEEE;
use IEEE.std_logic_1164.all ;
use IEEE.std_logic_unsigned.all ;
entity sync_ram_singleport is
generic (data_width : natural := 8 ;
addr_width : natural := 8);
port (
clk
: in std_logic;
we
: in std_logic ;
addr : in std_logic_vector(addr_width - 1 downto 0) ;
data_in : in std_logic_vector(data_width - 1 downto 0) ;
data_out : out std_logic_vector(data_width - 1 downto 0)
);
end sync_ram_singleport ;
architecture rtl of sync_ram_singleport is
type mem_type is array (2**addr_width downto 0) of
std_logic_vector(data_width - 1 downto 0) ;
signal mem : mem_type ;
signal addr_reg : std_logic_vector(addr_width - 1 downto 0) ;
begin
singleport : process (clk)
begin
if (clk'event and clk = '1') then
if (we = '1') then
mem(conv_integer(addr)) <= data_in ;
end if ;
addr_reg <= addr ;
end if ;
end process singleport;
data_out <= mem(conv_integer(addr_reg)) ;
end rtl ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-9
Inferring Memory
Operators, Counters, and Memory
Figure 9-6 is the recommended Verilog style for an inferred synchronous single-port RAM.
Figure 9-6. Inferring Synch Single-Port RAM from Verilog
module sync_ram_singleport (clk, we, addr, data_in, data_out);
parameter addr_width = 8;
parameter data_width = 8;
input clk;
input we;
input [addr_width - 1:0] addr;
input [data_width - 1:0] data_in;
output[data_width - 1:0] data_out;
reg
reg
[addr_width - 1:0] addri;
[data_width - 1:0] mem [(32’b1<<addr_width):0];
always @(posedge clk)
begin
if (we)
mem[addr] = data_in;
addri = addr;
end
assign data_out = mem[addri];
endmodule
9-10
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Operators, Counters, and Memory
Inferring Memory
Mapping Synchronous RAM with Separate Input and Output Ports
A dual-port RAM such as a FIFO-type RAM with a separately clocked input and ouput is often
used to buffer data transfers between two clock domains that are operating at difference
frequencies. Figure 9-7 is the recommended VHDL style for an inferred dual-port RAM with
independent input and output synchronous ports.
Figure 9-7. Inferring Synch Dual-Port RAM from VHDL
library IEEE;
use IEEE.std_logic_1164.all ;
use IEEE.std_logic_unsigned.all ;
entity sync_ram_dualport is
generic (data_width : natural := 16;
addr_width : natural := 32);
port (
clk_in
: in std_logic;
clk_out : in std_logic;
we
: in std_logic ;
addr_in : in std_logic_vector(addr_width
addr_out : in std_logic_vector(addr_width
data_in : in std_logic_vector(data_width
data_out : out std_logic_vector(data_width
);
end sync_ram_dualport ;
-
1
1
1
1
downto
downto
downto
downto
0) ;
0) ;
0) ;
0)
architecture rtl of sync_ram_dualport is
type mem_type is array (2**addr_width downto 0) of
std_logic_vector(data_width - 1 downto 0) ;
signal mem : mem_type ;
begin
write : process (clk_in)
begin
if (clk_in'event and clk_in = '1') then
if (we = '1') then
mem(conv_integer(addr_in)) <= data_in ;
end if ;
end if ;
end process write ;
read : process (clk_out)
begin
if (clk_out'event and clk_out = '1') then
data_out <= mem(conv_integer(addr_out)) ;
end if ;
end process read ;
end rtl ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-11
Inferring Memory
Operators, Counters, and Memory
Figure 9-8 is the recommended Verilog style for an inferred dual-port RAM with independent
input and output synchronous ports.
Figure 9-8. Inferring Synch Dual-Port RAM from Verilog
module sync_ram_dualport (clk_in, clk_out, we, addr_in, addr_out, data_in,
data_out);
parameter data_width = 16;
parameter addr_width = 32;
input clk_in;
input clk_out;
input we;
input [addr_width
input [addr_width
input [data_width
output[data_width
-
1:0]
1:0]
1:0]
1:0]
addr_in;
addr_out;
data_in;
data_out;
reg [data_width - 1:0] data_out;
reg [data_width - 1:0] mem [2^(addr_width - 1):0];
always @(posedge clk_in) begin
if (we)
mem[addr_in] <= data_in;
end
always @(posedge clk_out) begin
data_out <= mem[addr_out];
end
endmodule
Initializing a RAM in Verilog
You can use the $readmemh function in Verilog to initialize RAMs.When Precision infers an
initialized RAM, it sets the appropriate attributes on the associated RAM instances in the netlist.
The following example shows an example of initializing a RAM with an initialization file called
raminit.data:
reg [7:0] mem_factors [15:0];
initial $readmemh (“raminit.data”, mem_factors);
The following lists describes how Precision maps the initialization values to attributes in the
EDIF file for each supported technology:
9-12
•
Xilinx Virtex block RAMs use the INIT_XX and INITP_XX attributes
•
Xilinx Distributed RAMs use the INIT attribute on the flop.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Operators, Counters, and Memory
•
•
Inferring Memory
Altera APEX LPM_RAMs use a hex file with the filename specified by the LPM_FILE
attribute.
Altera Stratix ALTSYNCRAM use a hex file with the filename specified by the
LPM_FILE attribute.
Inferring ROM from the HDL Source Code
You can implement ROM behavior in the HDL source code with CASE statements or you can
specify the ROM as a table. 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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-13
Inferring Memory
Operators, Counters, and Memory
The following code segments illustrate how ROMs can be specified in your HDL source.
Verilog Design the Specifies a ROM from a CASE Statement
// Note: set mem_minimum_size 0
module rom_32x4 (addr, dout);
input [4:0] addr;
output [3:0] dout;
reg [3:0] dout;
always @(addr)
begin
case (addr)
0:dout = 4'b1110;
1:dout = 4'b0100;
2:dout = 4'b1110;
3:dout = 4'b1001;
4:dout = 4'b1111;
5:dout = 4'b0011;
6:dout = 4'b1000;
7:dout = 4'b0001;
8:dout = 4'b0110;
9:dout = 4'b0001;
10:dout = 4'b1100;
11:dout = 4'b0000;
12:dout = 4'b0110;
13:dout = 4'b0000;
14:dout = 4'b0100;
15:dout = 4'b0110;
16:dout = 4'b1110;
17:dout = 4'b0100;
18:dout = 4'b1110;
19:dout = 4'b1001;
20:dout = 4'b1111;
21:dout = 4'b0011;
22:dout = 4'b1000;
23:dout = 4'b0001;
24:dout = 4'b0110;
25:dout = 4'b0001;
26:dout = 4'b1100;
27:dout = 4'b0000;
28:dout = 4'b0110;
29:dout = 4'b0000;
30:dout = 4'b0100;
31:dout = 4'b1111;
endcase
end
endmodule
9-14
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Operators, Counters, and Memory
Inferring Memory
VHDL Design Example with ROM
Note: set mem_minimum_size 0
Library ieee;
use ieee.std_logic_1164.all;
package Table_rom is
Type rom_type is array ( 0 to 32 - 1 ) of STD_LOGIC_VECTOR
( 8 - 1 downto 0 ) ;
constant ROM : rom_type :=(
"00011111",
"01111111",
"11111111",
"01111111",
"00011111",
"01111111",
"11111111",
"11111111",
"00111111",
"11111111",
"00000011",
"11111111",
"00001111",
"00111111",
"00001111",
"11111111",
"11111111",
"00111111",
"00001111",
"01111111",
"00111111",
"11111111",
"01111111",
"01111111",
"01111111",
"00111111",
"00111111",
"01111111",
"11111111",
"01111111",
"01111111",
"11111111"
);
end Table_rom;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-15
Inferring Memory
Operators, Counters, and Memory
The following is an example of VHDL code from model ROM primitive.
Library ieee;
use ieee.std_logic_1164.all ;
entity rom_example1 is
generic ( DEPTH : in INTEGER ;
DATA_WIDTH : in INTEGER ;
ADDR_WIDTH : in INTEGER );
port( ADDR : in STD_LOGIC_VECTOR((ADDR_WIDTH-1)downto 0);
DATAOUT : out STD_LOGIC_VECTOR((DATA_WIDTH-1)downto 0));
end rom_example1 ;
Input Data Sets for ROM Inferencing
VHDL example (one of two):
Library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.Table_rom.all;
architecture ex1 OF rom_example1 is
begin
proc_addr: process (ADDR)
variable addr_int: integer range 0 to DEPTH-1;
begin
addr_int := CONV_INTEGER(UNSIGNED(ADDR));
DATAOUT <= ROM(addr_int);
end process;
end ex1;
9-16
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Operators, Counters, and Memory
Inferring Memory
VHDL example (two of two):
Library ieee;
use ieee.std_logic_1164.all ;
entity top is
port ( addr_in : in STD_LOGIC_VECTOR((5-1) downto 0) ;
clock : in STD_LOGIC ;
reset : in STD_LOGIC ;
output_enbl : in STD_LOGIC;
data_out : out STD_LOGIC_VECTOR((8-1) downto 0) ) ;
end top ;
architecture top of top is
component rom_example1
generic ( DEPTH : in INTEGER ;
DATA_WIDTH : in INTEGER ;
ADDR_WIDTH : in INTEGER );
port (ADDR : in STD_LOGIC_VECTOR((ADDR_WIDTH-1)downto 0);
DATAOUT :out STD_LOGIC_VECTOR((DATA_WIDTH-1) downto 0));
end component ;
begin
M0 : rom_example1
generic map (DEPTH => 32 ,
DATA_WIDTH => 8 ,
ADDR_WIDTH => 5 )
port map ( ADDR => addr_in,
DATAOUT => data_out);
end top ;
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
9-17
Inferring Memory
9-18
Operators, Counters, and Memory
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Chapter 10
State Machine Synthesis
FSM 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
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.
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
10-1
FSM Encoding Styles
•
State Machine Synthesis
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.
Note: Advanced FSM optimization does not utilize user-specified bit patterns for encoding.
As shown in Figure 10-1 below, you can specify FSM encoding on a global level from the GUI
using the Tools -> Set Options... Input dialog box.
Figure 10-1. Specifying the FSM EncodSpecifying the FSM Encoding Style
Select Encoding Style
Select Safe FSM
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.
10-2
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
State Machine Synthesis
FSM Encoding Styles
FSM Encoding using VHDL Attributes
When using VHDL, standard syntax can be used to assign an attribute to the state type as
follows:
type encoding_style is (BINARY, ONEHOT, TWOHOT, GRAY, RANDOM);
attribute TYPE_ENCODING_STYLE : encoding_style;
-- Declare your state machine enumeration type
type my_state_type is (s0,s1,s2,s3,s4);
-- Set the type_encoding_style of the state type
attribute TYPE_ENCODING_STYLE of my_state_type is ONEHOT;
FSM Encoding using a Verilog Pragma
When using Verilog to specify FSM encoding, specify the encoding style in the enum attribute
that is indicating that a set of parameter definitions should be interpreted as an enumerated type.
Associate the same enum attribute to the state register declaration (don’t include the encoding
style):
When using Verilog to specify FSM encoding, assign to an attribute a set of parameters to
define an enumerated type, and then assign another attribute to the state register as follows:
// Define the states. Enum pragma allows Precision to chose encoding.
parameter /* synthesis enum my_enum_type onehot */ st0 = 0, st1 = 1,
st2 = 2, st3 = 3, st4 = 4, st5 = 5, st6 = 6, st7 = 7;
reg [2:0] /* synthesis enum my_enum_type */ state_reg, nxstate_reg ;
Valid strings for specifying the encoding style are "onehot", "gray", "twohot",
"random", or "binary". Not specifying an encoding allows Precision to encode
automatically based on state count.
Advanced FSM Optimization
Precision's Advanced FSM Optimization will extract state machines from the design, perform
re-encoding, and perform reachability analysis on the states. However there may be times that a
more specific state machine structure is required. You may want to:
•
Preserve a user-specified encoding in parameters/constants
•
Use the type_encoding attribute to explicitly specify an encoding pattern
•
Preserve user handling on invalid states - for example you may wish to use a specific bit
pattern for the state enumeration and then use the VHDL case others clause to create
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
10-3
Safe State Machines
State Machine Synthesis
the safe logic to transition from all the other states. Advanced FSM optimization is
likely to optimize this extra logic away.
In these cases you may wish to turn off Advanced FSM optimization, which can be done either
from the GUI, as shown in Figure 10-1or be using the following command:
setup_design -advanced_fsm_optimization=false
Safe State Machines
Precision Synthesis supports the ability to create a Safe State Machine. A safe state machine is a
state machine in which a transition will always be to a valid state. Although state machine
optimization will create a design which contains only valid transitions under normal
circumstances, in safety critical situations where radiation could potentially change one of the
bits, it is important to know that the state machine will recover at the next clock step into a valid
state.
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 bits, but will use one-hot encoding for larger state machines. At some
larger user-specified limit, Precision will revert to using binary as one bit per state becomes
excessive. A one-hot state machine is not inherently safe for critical applications. Switching one
of the bits creates a state with two hot or none hot, and the state machine behavior from then on
becomes unpredictable. Adding recovery logic to a one-hot state machine often defeats the
advantage of using hot.
Just using binary encoding is not good enough. If there are 2n states then all states will be valid
states. If there are less than 2n states, then there are two options:
a. add logic to transition from the remaining invalid states to a valid state. The tool
handles this as described in the How Precision Implements a Safe FSM section
below.
b. use don't-care values to ensure a complete mapping from the logical to the physical
states, thus totally eliminating invalid states.
Option b uses less logic than option a, select binary encoding for a state machine to implement
option b.
How Precision Implements a Safe FSM
The Precision tool implements SAFE _FSM as described below:
If the SAFE_FSM attribute (also FSM_COMPLETE) is used in VHDL on an enumerated type,
or if the SAFE_FSM option is selected from the graphical user interface and if there is a useful
10-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
State Machine Synthesis
Safe State Machines
“when others” clause in a case statement assigning to the state-vector, then the following
occurs:
1. If you did not specify an encoding style, a BINARY encoding is chosen and the “when
others” statement is implemented.
2. If you specified an encoding style (onehot, twohot, gray, binary, random), the states are
encoded in the specified style and the “when others” is implemented.
Safe FSM operation can be selected either from the GUI, as shown in Figure 10-1, or by using
attributes in the code.
Alternatively the boolean attribute save_fsm can be applied to the enumerated type.
To illustrate the use of safe state machines, here is an example:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY safe1 IS
PORT (clock, in1, in2, reset : IN std_logic;
state1, state2, state3, state4, state5, state_other : OUT std_logic);
END ;
ARCHITECTURE rtl OF safe1 IS
TYPE state_t IS ( ST1, ST2, ST3, ST4, ST5 );
SIGNAL state, nxstate : state_t;
attribute SAFE_FSM: boolean;
attribute SAFE_FSM of state_t:type is true;
BEGIN
update_state :-- Update the state on the clock edge
PROCESS (reset, clock)
BEGIN
IF (reset='1') THEN
state <= ST1 ;
ELSIF clock'event and clock='1' THEN
state <= nxstate ;
END IF ;
END PROCESS;
output_sig : PROCESS (state)
BEGIN
state1 <= '0';
state2 <= '0';
state3 <= '0';
state4 <= '0';
state5 <= '0';
state_other <= '0';
if( state = ST1 ) then
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
10-5
Safe State Machines
State Machine Synthesis
state1 <= '1';
elsif ( state = ST2 ) then
state2 <= '1';
elsif ( state = ST3 ) then
state3 <= '1';
elsif ( state = ST4 ) then
state4 <= '1';
elsif ( state = ST5 ) then
state5 <= '1';
else
state_other <= '1';
end if;
END PROCESS;
transitions :-- set the outputs and next state
PROCESS (state, in1, in2)
BEGIN
nxstate <= state;
CASE state IS
WHEN ST1 =>
IF in1 = '1' then
nxstate <= ST2;
ELSIF in2 = '1' then
nxstate <= ST3;
END IF;
WHEN ST2 =>
IF in1 = '1' then
nxstate <= ST3;
ELSIF in2 = '1' then
nxstate <= ST4;
END IF;
WHEN ST3 =>
IF in1 = '1' then
nxstate <= ST4;
ELSIF in2 = '1' then
nxstate <= ST5;
END IF;
WHEN ST4 =>
IF in1 = '1' then
nxstate <= ST5;
ELSIF in2 = '1' then
nxstate <= ST1;
END IF;
WHEN ST5 =>
IF in1 = '1' then
nxstate <= ST1;
10-6
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
State Machine Synthesis
Safe State Machines
ELSIF in2 = '1' then
nxstate <= ST2;
END IF;
WHEN others =>
nxstate <= ST1;
END CASE;
END PROCESS;
END rtl;
This state machine has 5 states. If Precision was left to its default behavior it would choose onehot, and encode the states as follows:
ST1
ST2
ST3
ST4
ST5
00001
00010
00100
01000
10000
For most applications this will give the best results, however as mentioned above there are
several (32 -5) invalid states unaccounted for. Using straight binary encoding would create the
following encoding:
ST1
ST2
ST3
ST4
ST5
Invalid
Invalid
Invalid
000
001
010
011
100
101
110
111
However applying the binary encoding with don't care optimization creates the following state
encoding:
ST1
ST2
ST3
ST4
ST5
000
-01
-10
-11
100
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
10-7
Safe State Machines
10-8
State Machine Synthesis
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Index
Index
A
alias, 2-47
Altera
mapping multipliers to Stratix, 9-6
architecture, 2-1, 2-2
arithmetic and relational logic, 3-16
advanced design optimization, 3-20
comparator design, 7-25
ranged integer, 3-19
resource sharing, 3-18, 7-24
arithmetic operator, 9-1
array type, 2-9, 2-13
syntax and semantics, 2-13
synthesis issue, 2-14
array types, 2-9, 2-13, 2-14, 2-17, 2-18, 2-30, 231
assignment statement, 2-26
signal, 2-26
variable, 2-26
attribute, 2-31
exemplar predefined attribute, 2-32
usage of attribute, 2-33
user-defined attribute, 2-33
vhdl predefined attribute, 2-32
clock enable, 3-5
component instantiation, 2-40
conditional statement, 2-22
configuration declaration, 2-2
continuous assignment
net declaration assignment, 6-8
statement, 6-8
D
data type, 6-3
net data type, 6-5
parameter data type, 6-6
decoder, 3-23
design root, 4-1
directives
parallel_case and full_case, 7-26
translate_off and translate_on, 7-27
disable statement, 6-27
E
bidirectional buffer, 3-11
block, 2-34
bus, 3-11
bus class, 2-40
Encoding, 3-16
entity, 2-1
entity and package, 4-1
usage, 4-3
enumerated type, 2-9, 2-14, 2-15
exemplar package, 4-7
predefined attribute, 4-8
predefined function, 4-10
predefined procedure, 4-14
predefined type, 4-8
C
F
B
case statement, 2-23
automatic full case detection, 6-24
automatic parallel case detection, 6-25
casex statement, 6-26
casez statement, 6-26
multiplexer generation, 6-23
case statements, 6-22
clock
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
finding definition of component, 4-2
flip-flop, 3-2, 7-2
asynchronous set and reset, 7-3
asynchronous sets and reset, 3-4
clock enable, 3-5, 7-4
predefined procedure, 4-14
synchronous set and reset, 3-3, 7-3
floating-point types, 2-9, 2-11, 2-12, 2-18, 2-30
Index-1
Index
Index (cont.)
for loop, 2-24
for statement, 6-26
function, 2-35, 6-29
Multipliers
mapping to Stratix, 9-6
G
generate statement, 2-24
generic
generic list, 2-21
size, 2-21
net data type
supply net, 6-6
wand and wor net, 6-6
wire and tri net, 6-6
number, 6-2
I
O
I/O buffer, 3-7, 7-4
component instantiation, 3-8, 7-5
IEEE 1076, 2-18
IEEE 1076-1993, 4-1
IEEE 1164 standard logic, 2-30
if-else statement, 6-21
Inferring Memory
Altera ROM, 9-13
Altera single-port RAM, 9-9
integer, 2-10
integer type, 2-9, 2-10, 2-12, 2-17, 2-18, 2-29
object, 2-20
array, 2-13
array naming, 2-14
declared, 2-8
elements, 2-15
enumeration type, 2-9
generic, 2-21
loop variable, 2-22
physical type, 2-12
port, 2-21
record, 2-16
signal, 2-2, 2-20
variable, 2-20, 3-6
operand, 6-16
operator, 2-28
arithmetic operator, 6-17
bit-wise operator, 6-18
concatenation, 6-19
conditional operator, 6-19
logical operator, 6-18
reduction operator, 6-18
relational and equality operator, 6-17
shift operator, 6-19
signed and unsigned attribute, 6-20
operator overloading, 2-30
Operators
mapping to dedicated resources, 9-6
operators, 2-2, 2-8, 2-15, 2-28, 2-29
L
latch, 3-1, 3-7, 7-1
literal, 2-7
literals
constant values, 2-7
loop variable, 2-22
M
Mapping Operators to Dedicated Resources, 96
Mentor Graphics, 4-7
module generation
data path logic, 9-1
data path operators, 9-1
module instantiation
parameter override, 6-14
multiplexer, 3-22
Index-2
N
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
Index
Index (cont.)
P
package, 2-45
physical type, 2-12
physical types, 2-9, 2-12
pla, 3-23
port, 2-21
post-synthesis functional simulation, 4-5
pragmas
Verilog, 7-26
predefined flip-flops and latches, 3-7
procedure, 2-35
processes, 2-5
R
record, 2-15
record types, 2-9, 2-16
register, 3-1
relational operator, 9-1
reset, 7-1
resolution function, 2-38
rom, 3-23
S
selector, 3-22
signal, 2-20
signed attribute
on operators, 6-20
state encoding, 7-19
state machine, 3-12
general state machine description, 3-12
issues in state machine design, 7-18
Mealy machine, 7-16
Moore machine, 7-12
power-up and reset, 3-15
state encoding, 3-16
vhdl coding style for state machine, 3-14
statement, 2-22
assignment statement, 2-26
conditional statement, 2-22
generate statement, 2-24
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
loop, 2-22
loop statement, 2-24
selection statement, 2-23
statements, 2-2, 2-7, 2-19
dataflow environment, 2-2
processes, 2-5
std_logic, 2-19, 2-29, 2-38
Stratix
mapping multipliers, 9-6
subtype, 2-16
subtypes, 2-17
Synopsys integration and packages, 4-6
syntax and semantic restriction, 4-16
synthesis tool restrictions, 4-16
VHDL language Restriction, 4-17
synthesis directives
attribute, 7-28
translate_off and translate_on, 7-27
T
task, 6-30
technology-specific macro, 3-21
three-state buffer, 3-9
type, 2-8
array type, 2-13
enumeration type, 2-9
floating-point type, 2-11
IEEE 1076 predefined type, 2-18
integer type, 2-10
physical type, 2-12
record type, 2-15
subtype, 2-16
type conversion, 2-17
U
unsigned attribute
on operators, 6-20
V
variable, 3-6
Index-3
Index
Index (cont.)
Verilog
pragmas, 7-26
Verilog 2001 Support, 5-3
VHDL environment
interfacing with other VHDL tools, 4-4
W
while loop, 2-24
Index-4
Precision RTL Synthesis Style Guide, 2003c Update1
March 2004
End-User License Agreement
IMPORTANT - USE OF THIS SOFTWARE IS SUBJECT TO LICENSE RESTRICTIONS.
CAREFULLY READ THIS LICENSE AGREEMENT BEFORE USING THE SOFTWARE.
This license is a legal “Agreement” concerning the use of Software between you, the end user, either individually or
as an authorized representative of the company acquiring the license, and Mentor Graphics Corporation and
Mentor Graphics (Ireland) Limited, acting directly or through their subsidiaries or authorized distributors
(collectively “Mentor Graphics”). USE OF SOFTWARE INDICATES YOUR COMPLETE AND
UNCONDITIONAL ACCEPTANCE OF THE TERMS AND CONDITIONS SET FORTH IN THIS
AGREEMENT. If you do not agree to these terms and conditions, promptly return, or, if received electronically,
certify destruction of, Software and all accompanying items within five days after receipt of Software and receive a
full refund of any license fee paid.
END-USER LICENSE AGREEMENT
1.
GRANT OF LICENSE. The software programs you are installing, downloading, or have acquired with 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 you, subject to payment of
appropriate license fees, a nontransferable, nonexclusive license to use Software solely: (a) in machine-readable, objectcode form; (b) for your internal business purposes; and (c) on the computer hardware or at the site for which an applicable
license fee is paid, or as authorized by Mentor Graphics. A site is restricted to a one-half mile (800 meter) radius. Mentor
Graphics' standard policies and programs, which vary depending on Software, license fees paid or service plan purchased,
apply to the following and are subject to change: (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 communicated and technically implemented through the use of authorization codes or similar
devices); (c) support services provided, including eligibility to receive telephone support, updates, modifications and
revisions. Current standard policies and programs are available upon request.
2.
ESD SOFTWARE. If you purchased a license to use embedded software development (“ESD”) Software, Mentor
Graphics grants to you a nontransferable, nonexclusive license to reproduce and distribute executable files created using
ESD compilers, including the ESD run-time libraries distributed with ESD C and C++ compiler Software that are linked
into a composite program as an integral part of your compiled computer program, provided that you distribute these files
only in conjunction with your compiled computer program. Mentor Graphics does NOT grant you any right to duplicate
or incorporate copies of Mentor Graphics' real-time operating systems or other ESD Software, except those explicitly
granted in this section, into your products without first signing a separate agreement with Mentor Graphics for such
purpose.
3.
BETA CODE. 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 you 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 your 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. If Mentor Graphics authorizes you to use the Beta Code, you agree
to evaluate and test the Beta Code under normal conditions as directed by Mentor Graphics. You will contact Mentor
Graphics periodically during your use of the Beta Code to discuss any malfunctions or suggested improvements. Upon
completion of your evaluation and testing, you will send to Mentor Graphics a written evaluation of the Beta Code,
including its strengths, weaknesses and recommended improvements. You agree that any written evaluations and all
inventions, product improvements, modifications or developments that Mentor Graphics conceives or made during or
subsequent to this Agreement, including those based partly or wholly on your 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 shall survive termination or expiration of this Agreement.
4.
RESTRICTIONS ON USE. You 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. You 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. You shall not make Software available in any form to any
person other than employees and contractors, excluding Mentor Graphics' competitors, whose job performance requires
access. You shall take appropriate action to protect the confidentiality of Software and ensure that any person permitted
access to Software does not disclose it or use it except as permitted by this Agreement. Except as otherwise permitted for
purposes of interoperability as specified by applicable and mandatory local law, you shall not reverse-assemble, reversecompile, reverse-engineer or in any way derive from Software any source code. You may not sublicense, assign or
otherwise transfer Software, this Agreement or the rights under it, whether by operation of law or otherwise (“attempted
transfer”) without Mentor Graphics' prior written consent and payment of Mentor Graphics then-current applicable
transfer charges. 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 licenses
granted under this Agreement. The provisions of this section 4 shall survive the termination or expiration of this
Agreement.
5.
LIMITED WARRANTY.
5.1. Mentor Graphics warrants that during the warranty period, Software, when properly installed, will substantially
conform to the functional specifications set forth in the applicable user manual. Mentor Graphics does not warrant
that Software will meet your requirements or that operation of Software 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. You
must notify Mentor Graphics in writing of any nonconformity within the warranty period. This warranty shall not be
valid if Software has been subject to misuse, unauthorized modification or installation. MENTOR GRAPHICS'
ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL BE, AT MENTOR GRAPHICS' OPTION,
EITHER (A) REFUND OF THE PRICE PAID UPON RETURN OF SOFTWARE TO MENTOR GRAPHICS OR
(B) MODIFICATION OR REPLACEMENT OF SOFTWARE THAT DOES NOT MEET THIS LIMITED
WARRANTY, PROVIDED YOU HAVE OTHERWISE COMPLIED WITH THIS AGREEMENT. MENTOR
GRAPHICS MAKES NO WARRANTIES WITH RESPECT TO: (A) SERVICES; (B) SOFTWARE WHICH IS
LICENSED TO YOU FOR A LIMITED TERM OR LICENSED AT NO COST; OR (C) EXPERIMENTAL BETA
CODE; ALL OF WHICH ARE PROVIDED “AS IS.”
5.2. THE WARRANTIES SET FORTH IN THIS SECTION 5 ARE EXCLUSIVE. NEITHER MENTOR GRAPHICS
NOR ITS LICENSORS MAKE ANY OTHER WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, WITH
RESPECT TO SOFTWARE OR OTHER MATERIAL PROVIDED UNDER THIS AGREEMENT. MENTOR
GRAPHICS AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT OF
INTELLECTUAL PROPERTY.
6.
LIMITATION OF LIABILITY. EXCEPT WHERE THIS EXCLUSION OR RESTRICTION OF LIABILITY
WOULD BE VOID OR INEFFECTIVE UNDER APPLICABLE LAW, IN NO EVENT SHALL MENTOR GRAPHICS
OR ITS LICENSORS BE LIABLE FOR INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
(INCLUDING LOST PROFITS OR SAVINGS) WHETHER BASED ON CONTRACT, TORT OR ANY OTHER
LEGAL THEORY, EVEN IF MENTOR GRAPHICS OR ITS LICENSORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES. IN NO EVENT SHALL MENTOR GRAPHICS' OR ITS LICENSORS'
LIABILITY UNDER THIS AGREEMENT EXCEED THE AMOUNT PAID BY YOU FOR THE SOFTWARE OR
SERVICE GIVING RISE TO THE CLAIM. IN THE CASE WHERE NO AMOUNT WAS PAID, MENTOR
GRAPHICS AND ITS LICENSORS SHALL HAVE NO LIABILITY FOR ANY DAMAGES WHATSOEVER.
7.
LIFE ENDANGERING ACTIVITIES. NEITHER MENTOR GRAPHICS NOR ITS LICENSORS SHALL BE
LIABLE FOR ANY DAMAGES RESULTING FROM OR IN CONNECTION WITH THE USE OF SOFTWARE IN
ANY APPLICATION WHERE THE FAILURE OR INACCURACY OF THE SOFTWARE MIGHT RESULT IN
DEATH OR PERSONAL INJURY.
8.
INDEMNIFICATION. YOU AGREE 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 YOUR USE OF SOFTWARE AS
DESCRIBED IN SECTION 7.
9.
INFRINGEMENT.
9.1. Mentor Graphics will defend or settle, at its option and expense, any action brought against you alleging that
Software infringes a patent or copyright or misappropriates a trade secret in the United States, Canada, Japan, or
member state of the European Patent Office. Mentor Graphics will pay any costs and damages finally awarded
against you that are attributable to the infringement action. You understand and agree that as conditions to Mentor
Graphics’ obligations under this section you must: (a) notify Mentor Graphics promptly in writing of the action; (b)
provide Mentor Graphics all reasonable information and assistance to defend or settle the action; and (c) grant
Mentor Graphics sole authority and control of the defense or settlement of the action.
9.2. If an infringement claim is made, Mentor Graphics may, at its option and expense: (a) replace or modify Software so
that it becomes noninfringing; (b) procure for you the right to continue using Software; or (c) require the return of
Software and refund to you any license fee paid, less a reasonable allowance for use.
9.3. Mentor Graphics has no liability to you if infringement is based upon: (a) the combination of Software with any
product not furnished by Mentor Graphics; (b) the modification of Software other than by Mentor Graphics; (c) the
use of other than a current unaltered release of Software; (d) the use of Software as part of an infringing process; (e) a
product that you make, use or sell; (f) any Beta Code contained in Software; (g) any Software provided by Mentor
Graphics' licensors who do not provide such indemnification to Mentor Graphics' customers; or (h) infringement by
you that is deemed willful. In the case of (h) you shall reimburse Mentor Graphics for its attorney fees and other costs
related to the action upon a final judgment.
9.4. THIS SECTION 9 STATES THE ENTIRE LIABILITY OF MENTOR GRAPHICS AND ITS LICENSORS AND
YOUR SOLE AND EXCLUSIVE REMEDY WITH RESPECT TO ANY ALLEGED PATENT OR COPYRIGHT
INFRINGEMENT OR TRADE SECRET MISAPPROPRIATION BY ANY SOFTWARE LICENSED UNDER
THIS AGREEMENT.
10. TERM. This Agreement remains effective until expiration or termination. This Agreement will automatically terminate if
you fail to comply with any term or condition of this Agreement or if you fail to pay for the license when due and such
failure to pay continues for a period of 30 days after written notice from Mentor Graphics. If Software was provided for
limited term use, this Agreement will automatically expire at the end of the authorized term. Upon any termination or
expiration, you agree to cease all use of Software and return it to Mentor Graphics or certify deletion and destruction of
Software, including all copies, to Mentor Graphics' reasonable satisfaction.
11. EXPORT. Software is subject to regulation by local laws and United States government agencies, which prohibit export
or diversion of certain products, information about the products, and direct products of the products to certain countries
and certain persons. You agree that you will not export any Software or direct product of Software in any manner without
first obtaining all necessary approval from appropriate local and United States government agencies.
12. RESTRICTED RIGHTS NOTICE. Software was developed entirely at private expense and is 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 under which Software was
obtained pursuant to DFARS 227.7202-3(a) or as set forth in subparagraphs (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 SW Boeckman Road, Wilsonville, Oregon 97070-7777 USA.
13. THIRD PARTY BENEFICIARY. For any Software under this Agreement licensed by Mentor Graphics from Microsoft
or other licensors, Microsoft or the applicable licensor is a third party beneficiary of this Agreement with the right to
enforce the obligations set forth in this Agreement.
14. AUDIT RIGHTS. With reasonable prior notice, Mentor Graphics shall have the right to audit during your normal
business hours all records and accounts as may contain information regarding your compliance with the terms of this
Agreement. Mentor Graphics shall keep in confidence all information gained as a result of any audit. Mentor Graphics
shall only use or disclose such information as necessary to enforce its rights under this Agreement.
15. CONTROLLING LAW AND JURISDICTION. THIS AGREEMENT SHALL BE GOVERNED BY AND
CONSTRUED UNDER THE LAWS OF OREGON, USA, IF YOU ARE LOCATED IN NORTH OR SOUTH
AMERICA, AND THE LAWS OF IRELAND IF YOU ARE LOCATED OUTSIDE OF NORTH AND SOUTH
AMERICA. All disputes arising out of or in relation to this Agreement shall be submitted to the exclusive jurisdiction of
Dublin, Ireland when the laws of Ireland apply, or Wilsonville, Oregon when the laws of Oregon apply. This section shall
not restrict Mentor Graphics’ right to bring an action against you in the jurisdiction where your place of business is
located.
16. 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.
17. 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, except valid license agreements related to the subject matter of this Agreement (which are physically signed
by you and an authorized agent of Mentor Graphics) either referenced in the purchase order or otherwise governing this
subject matter. 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. The prevailing
party in any legal action regarding the subject matter of this Agreement shall be entitled to recover, in addition to other
relief, reasonable attorneys' fees and expenses.
Rev. 020826, Part Number 214231
Trademark Information
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement