HDL Compile For Verilog User Guide
HDL Compile For Verilog User Guide
Guide
Version P-2019.03-SP2, June 2019
Copyright and Proprietary Information Notice
© 2019 Synopsys, Inc. This Synopsys software and all associated documentation are proprietary to Synopsys, Inc. and
may only be used pursuant to the terms and conditions of a written license agreement with Synopsys, Inc. All other
use, reproduction, modification, or distribution of the Synopsys software or the associated documentation is strictly
prohibited.
Destination Control Statement
All technical data contained in this publication is subject to the export control laws of the United States of America.
Disclosure to nationals of other countries contrary to United States law is prohibited. It is the reader’s responsibility to
determine the applicable regulations and to comply with them.
Disclaimer
SYNOPSYS, INC., AND ITS LICENSORS MAKE NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Trademarks
Synopsys and certain Synopsys product names are trademarks of Synopsys, as set forth at
https://www.synopsys.com/company/legal/trademarks-brands.html.
All other product or company names may be trademarks of their respective owners.
Free and Open-Source Licensing Notices
If applicable, Free and Open-Source Software (FOSS) licensing notices are available in the product installation.
Third-Party Links
Any links to third-party websites included in this document are for your convenience only. Synopsys does not endorse
and is not responsible for such websites and their practices, including privacy practices, availability, and content.
www.synopsys.com
3
Contents
2. Coding Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
General Verilog Coding Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Guidelines for Interacting With Other Flows . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Synthesis Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Low-Power Flows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Verification Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4
Contents
4. Sequential Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Generic Sequential Cell SEQGEN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Inference Reports for Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Register Inference Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Multiple Events in an always Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Minimizing Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Keeping Unloaded Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Preventing Unwanted Latches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Register Inference Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Register Inference Examples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Inferring Latches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Basic D Latch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
D Latch With Asynchronous Set: Use async_set_reset . . . . . . . . . 103
D Latch With Asynchronous Reset: Use async_set_reset . . . . . . . . 103
D Latch With Asynchronous Set and Reset:
Use hdlin_latch_always_async_set_reset . . . . . . . . . . . . . . . . 104
Inferring Flip-Flops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Basic D Flip-Flop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
D Flip-Flop With Asynchronous Reset Using ?: Construct . . . . . . . . 107
D Flip-Flop With Asynchronous Reset . . . . . . . . . . . . . . . . . . . . . . . 107
D Flip-Flop With Asynchronous Set and Reset . . . . . . . . . . . . . . . . 108
D Flip-Flop With Synchronous Set:
Use sync_set_reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
D Flip-Flop With Synchronous Reset: Use sync_set_reset . . . . . . . 109
D Flip-Flop With Synchronous and Asynchronous Load . . . . . . . . . 110
D Flip-Flops With Complex Set and Reset Signals . . . . . . . . . . . . . 111
5
Contents
6
Contents
infer_mux_override . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
infer_onehot_mux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
keep_signal_name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
one_cold . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
one_hot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
parallel_case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
preserve_sequential. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
sync_set_reset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
sync_set_reset_local . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
sync_set_reset_local_all . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
translate_off and translate_on (Deprecated) . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Directive Support by Pragma Prefix. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
7
Contents
8
Contents
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
9
Preface
This preface includes the following sections:
• About This Manual
• Customer Support
Audience
The HDL Compiler™ for Verilog User Guide is written for logic designers and electronic
engineers who are familiar with the Design Compiler and Fusion Compiler™ tools.
Knowledge of the Verilog language is required, and knowledge of a high-level programming
language is helpful.
Related Publications
For additional information about the Design Compiler tool, see the documentation on the
Synopsys SolvNet® online support site at the following address:
https://solvnet.synopsys.com/DocsOnWeb
You might also want to see the documentation for the following related Synopsys products:
• DC Explorer
• Design Vision™
• Design Compiler®
• Fusion Compiler™
• DesignWare® components
• Library Compiler™
• Verilog Compiled Simulator® (VCS)
Release Notes
Information about new features, enhancements, changes, known limitations, and resolved
Synopsys Technical Action Requests (STARs) is available in the HDL Compiler Release
Notes on the SolvNet site.
To see the HDL Compiler Release Notes,
1. Go to the SolvNet Download Center located at the following address:
https://solvnet.synopsys.com/DownloadCenter
2. Select HDL Compiler, and then select a release in the list that appears.
Conventions
The following conventions are used in Synopsys documentation.
Convention Description
Customer Support
Customer support is available through SolvNet online customer support and through
contacting the Synopsys Technical Support Center.
Accessing SolvNet
The SolvNet site includes a knowledge base of technical articles and answers to frequently
asked questions about Synopsys tools. The SolvNet site also gives you access to a wide
range of Synopsys online services including software downloads, documentation, and
technical support.
To access the SolvNet site, go to the following address:
https://solvnet.synopsys.com
If prompted, enter your user name and password. If you do not have a Synopsys user name
and password, follow the instructions to sign up for an account.
If you need help using the SolvNet site, click HELP in the top-right menu bar.
https://www.synopsys.com/support/global-support-centers.html
These topics describe the Verilog constructs supported by the Synopsys synthesis tools:
• Reading Verilog Designs
• Coding for QoR
• Reading Designs Using the VCS Command-Line Options
• Creating Relative Placement Using Design Compiler Directives
• Reporting HDL Compiler Settings
• Customizing Elaboration Reports
• Reporting Elaboration Errors in the Hierarchy
• Querying Information about RTL Preprocessing
• Netlist Reader
• Automatic Detection of Input Type
• Parameterized Designs
• Defining Macros
• Use of $display During RTL Elaboration
• Inputs and Outputs
• Language Construct Support
• Licenses
For example,
set_app_var hdlin_auto_save_templates true
read_verilog parametrized_interface.v
current_design top
link
compile
write -format verilog -hierarchy \
-output gates.parametrized_interface_rd.v
For example,
analyze -format verilog parametrized_interface.v
elaborate top
compile
write -format verilog -hierarchy \
-output gates.parametrized_interface_an_elab.v
See Also
• Parameterized Designs
• Automatic Detection of Input Type
• read_file -autoread
This command reads files with dependencies automatically, analyzes the files, and
elaborates the files starting at a specified top-level design. For example,
dc_shell> read_file -autoread file_list -top design_name
You must specify the file_list argument to list the files, directories, or both to be analyzed.
The -autoread option locates the source files by expanding each file or directory in the
file_list argument. You must specify the top design by using the -top option.
• analyze -autoread
This command reads files with dependencies automatically and analyzes the files
without elaboration. For example,
dc_shell> analyze -autoread file_list -top design_name
You must specify the file_list argument to list the files, directories, or both to be analyzed.
The -autoread option locates the source files by expanding each file or directory in the
file_list argument. If you use the -top option, the tool analyzes only the source files
needed to elaborate the top-level design. If you do not specify the -top option, the tool
analyzes all the files in the file_list argument, grouping them in the order according to the
dependencies that the -autoread option infers.
Example
The following example specifies the current directory as the source directory. The command
reads the source files, analyzes them, and then elaborates the design starting at the top-
level design.
dc_shell> analyze {.} -autoread -recursive -top E1
The following example specifies the file extensions for Verilog files other than the default (.v)
and sets file source lists that exclude some directories.
dc_shell> set_app_var hdlin_autoread_verilog_extensions {.v .ver}
dc_shell> set my_sources {mod1/src mod2/src}
dc_shell> set my_excludes {mod1/src/incl_dir/ mod2/src/incl_dir/}
dc_shell> analyze $my_sources -recursive -exclude $my_excludes \
-autoread -format verilog -top TOP
Excluding directories is useful when you do not want the tool to use those files that have the
same file extensions as the source files in the directories.
See Also
• The -autoread Option
• File Dependencies
File Dependencies
A file dependency occurs when a file requires language constructs that are defined in
another file. When you specify the -autoread command, the tool analyzes the files (and
elaborates the files if you use the read_file command) with the following dependencies in
the correct order:
• Analyze dependency
If file B defines entity E in SystemVerilog and file A defines the architecture of entity E,
file A depends on file B and must be analyzed after file B. Language constructs that can
cause analyze dependencies include VHDL package declarations, entity declarations,
direct instantiations, and SystemVerilog package definitions and import.
• Link dependency
If module X instantiates module Y in Verilog, you must analyze both of them before
elaboration and linking to prevent the tool from inferring a black box for the missing
module. Language constructs that can cause link dependencies include VHDL
component instantiations and SystemVerilog interface instantiations.
• Include dependency
When file X includes file Y using the ‘include directive, this is known as an include
dependency. The -autoread option analyzes the file that contains the `include directive
statement when any of the included files are changed between consecutive calls of the
-autoread option.
To change the library search order, list the libraries by using the –uses option with the
analyze command. When a design is analyzed with the analyze -uses design_libs
command, the tool searches for the subdesigns of this design in the library order specified
by the –uses option.
When you use the -uses option,
• The parent design library is searched first, followed by libraries in the order specified by
the -uses option.
• The specified library search order applies only to the specified design and its
subdesigns. Other designs use the default.
• The search is restricted to the libraries specified by the –uses option. Other libraries are
not searched even if no library is found.
• An empty list for the –uses option limits the search to the library of the parent design.
For example, in the following design, three different versions of the submod design are
analyzed in the lib1, lib2, and lib3 libraries respectively:
top.v
module top (...);
...
U0 submod (...);
...
endmodule
submod1.v
submod (...);
<implementation 1>
endmodule
submod2.v
submod (...);
<implementation 2>
endmodule
submod3.v
submod (...);
<implementation 3>
endmodule
When you use the following command to analyze the top-level top.v design, the module
analyzed using the lib2 library is chosen during elaboration and the modules using the lib1
and lib3 libraries are ignored.
dc_shell> analyze ... -uses "lib2 lib1 lib3" top.v
extensions. If the file extension in unknown, the tool assumes the .ddc format. The file
extensions in Table are supported for automatic inference:
ddc .ddc
The supported extensions are not case-sensitive. All formats except the .ddc format can be
compressed in gzip (.gz) format.
If you use a file extension that is not supported and you omit the -format option, the
synthesis tool generates an error message. For example, if you specify read_file
test.vlog, the tool issues the following DDC-2 error message:
Error: Unable to open file 'test.vlog' for reading. (DDC-2)
See Also
• Generic Sequential Cell SEQGEN
• Selection and Multiplexing Logic
• Synthetic Operators
For leaf-level relative placement groups, specify the directives inside an always block.
High-level hierarchical groups do not have to be included in an always block.
• Syntax for HDL netlists
//synopsys rp_group ( group_name {num_cols num_rows} )
//synopsys rp_endgroup ( {group_name} )
Place all cell instances between the directives to declare them as members of the
specified relative placement group.
To specify the size of the relative placement group, use the num_cols and num_rows
optional arguments for the number of columns and number of rows. The tool ensures that all
instances in the group is placed inside the specified size limits. The tool issues an error
message for a size violation.
The following example shows that relative placement group rp_grp1 contains the inferred
register:
...
always @ (posedge CLK)
‘rp_group (rp_grp1)
...
‘rp_endgroup (rp_grp1)
Q1 <= DATA1;
...
Use the col and row arguments to specify absolute column and row coordinates in the grid
of the relative placement group or a location relative to the current coordinates (the location
of the current instance). To specify locations relative to the current coordinates, enclose the
column and row coordinates in angle brackets (<>). No brackets for absolute locations. If
you do not specify the col and row arguments, a new instance is automatically placed in the
available grid at the specified location. After the instance is placed, the tool increments the
column and row coordinates of the location for the next cell.
The following example shows that group my_group_1 is placed at location (0,0) in the grid
and group my_group_2 is placed at the next row position (0,1):
`rp_place (my_group_1 0 0)
`rp_place (my_group_2 0 <1>)
The following example shows that relative placement group my_reg_bank contains four
subgroups at the following locations: (0,0), (0,1), (1,*), and (1,*). The wildcard character (*)
indicates that the tool can choose any value for a coordinate in the group.
`rp_group (my_reg_bank)
`rp_place (hier rp_grp1 0 0)
`rp_place (hier rp_grp4 0 1)
`rp_place (hier rp_grp2 1 *)
`rp_place (hier rp_grp3 1 *)
`rp_endgroup (my_reg_bank)
See Also
• Enabling Automatic Cell Placement
When you specify the col and row arguments, the tool places each new instance in the grid
at the specified location. The default is column zero and row zero (0,0). After the instance is
placed, the tool increments the column and row coordinates of the location for the next cell.
• To specify the placement location, use the col and row arguments
The col and row arguments represent absolute column and row coordinates in the grid
at the specified location or a location relative to the current coordinates (the location of
the current instance). To specify locations relative to the current coordinates, enclose the
column and row coordinates in angle brackets (<>). No brackets for absolute location.
You must use positive integers for absolute coordinates and any integer for relative
coordinates.
For example, if the specified location is (3,4), you can increment the column coordinate
by 1 and set the row coordinate to 0 by specifying ‘rp_fill <1> 0. The relative
coordinates point to location (4,0) for the next cell.
• To specify the placement direction, use the pattern argument with the UX, DX, RX, or LX
keyword for up, down, right, or left direction respectively.
The default is UX, where the tool places cells in the up direction within a column. The RX
pattern fills a row with cells. If no pattern is specified for a cell, the tool uses the
incremental location of the last pattern. If you do not specify the col and row arguments,
the tool uses the previous pattern. When the tool encounters a group declaration, it
initializes the placement location to (0,0) with the UX pattern.
When the tool encounters an array of instantiation in Verilog, the array cells are enumerated
to match the pattern iterating from the left index to the right index, as shown in the following
example:
and a[0:2] ( ); // generates a[0], a[1], a[2]
The following example uses the UX and RX patterns for relative placement group group_x in
an HDL netlist:
//synopsys rp_group (group_x)
//synopsys rp_fill (0 0 UX)
Cell C1 (...);
Cell C2 (...);
Cell C3 (...);
//synopsys rp_fill (0 <1> RX) // move up a row to the left, fill to R
Cell c4 (...);
Cell C5 (...);
Cell C6 (...);
//synopsys rp_endgroup (group_x)
The up keyword indicates to place array elements from the least significant bit to the most
significant bit, and the down keyword indicates to place array elements from the most
significant bit to the least significant bit. The following example shows that the array
elements are placed in the up direction:
...
always @ (posedge CLK)
‘rp_group (rp_grp1/
‘rp_fill (0 0 UX)
‘rp_array_dir (up)
‘rp_endgroup (rp_grp1)
Q1 <= DATA1 ;
...
By default, the tool applies the specified alignment to all subsequent instantiations within the
group until the tool encounters another ‘rp_align directive. If you do not specify an
alignment, the default is sw. If you specify the inst instance name argument, the alignment
applies only to that instance. If the instance straddles cells, the alignment takes place within
the straddled region. The instance is snapped to legal row and routing grid coordinates. You
must specify either the alignment or the pin name.
The following example specifies to place cell C1 at the northeast corner:
//synopsys rp_group (group_x)
//synopsys rp_fill ( 0 0 RX )
//synopsys rp_align (NE C1 )
Cell C1 ...
Cell C2 ...
Cell C3 ...
//synopsys rp_fill ( 0 <1> RX )
Cell C4 ...
Cell C5 ...
Cell C6 ...
//synopsys rp_endgroup (group_x)
When you use the inst argument, the orientation is applied to the specified instance
only. If you do not specify an instance, the orientation applies to all subsequent instances
until another orientation is specified.
• //synopsys rp_orient ( {N|W|S|E|FN|FW|FS|FE}* { group_name inst } ))
When you use the group_name inst argument, the orientation is applied to the specified
instance and the rest of the group remains unchanged. The default orientation is N, which
stands for no flipping rotation at the horizontal axis and no mirror orientation at the
vertical axis. The FN, FW, FS, and FE orientations stand for flipping north, flipping west,
flipping south, and flipping east respectively.
The following example specifies to place cell C1 in the west direction:
//synopsys rp_group (group_x)
...
//synopsys rp_orient (W C1)
Cell C0 ...
Cell C1 ...
...
Cell C6 ...
//synopsys rp_endgroup (group_x)
Figure 1 shows the layout of this example after relative placement. The register banks that
are constrained by the Design Compiler directives have a well-structured layout, while the
register banks that are not constrained by the directives are not placed together.
Figure 2 shows the generated layout where each relative placement group consists of one
array and each group is placed vertically.
Figure 3 shows the generated layout where each relative placement group consists of one
array and each group is placed horizontally.
`rp_endgroup (gp1)
out <= tmp3;
`rp_group (top)
`rp_place (hier gp0 * 0)
`rp_place (hier gp1 * 0)
`rp_endgroup (top)
endmodule
Figure 4 shows the generated layout where keepouts are inferred in the relative placement
groups.
Other variables that affect RTL reading include the ones prefixed with template and
bus*style. Use the following commands to report these variables:
dc_shell> report_app_var template*
dc_shell> report_app_var bus*style
For more information about a specific variable, see the man page. For example,
dc_shell> man hdlin_analyze_verbose_mode
In addition to the four settings, you can customize the report by specifying the add (+) or
subtract (-) option. For example, to report floating-net-to-ground connections, synthetic
cells, inferred state variables, and verbose information for inferred sequential elements, but
not MUX_OPs or inferred three-state elements, enter
dc_shell> set_app_var hdlin_reporting_level {verbose-mux_op-tri_state}
top
middle_1
middle_2
ELAB-638
bottom_1 bottom_2
ELAB-366
end_1 end_2
ELAB-366
As shown in Example 6, the tool reports the following two errors at the top level by default:
• ELAB-368 error from the middle_1 module
• ELAB-366 error from the bottom_2 module
To find the ELAB-366 error in the end1 submodule as shown in Example 7, you must fix the
error in the middle_1 module. When you set the hdlin_elab_errors_deep variable to
true, the tool reports all errors in the hierarchy in one elaboration step:
The tool does not create designs when this variable is set to true. If you run the
list_designs command, the tool reports the following warning:
Warning: No designs to list (UID-275)
• You should use the analyze command rather than the read_file command to read the
design because the read_file command has no linking functionality and does not
accept command-line parameter specifications.
• All syntax errors are reported when you run the analyze command. The tool is not a
linting tool, but you can use the check_design command in the Design Compiler tool to
perform basic structural checks.
• The elaboration runtime might increase slightly.
0 No preprocessing information.
2 Macro expansions and the information reported when the variable is set to 1.
The following example shows how to report preprocessing information by using the
hdlin_analyze_verbose_mode variable:
• example.v file
`define MYMACRO 1'b0
module m (
input in1,
output out1
);
`ifdef MYRTL
assign out1 = `MYMACRO;
`else
assign out1 = in1;
`endif
endmodule
Netlist Reader
The Design Compiler tool contains a specialized reader for gate-level Verilog netlists that
has higher capacity on designs that do not use RTL-level constructs, but it does not support
the entire Verilog language. The specialized netlist reader reads netlists faster and uses less
memory than the RTL reader.
If you have problems reading a netlist with the netlist reader, try reading it with Design
Compiler by using read_verilog -rtl or by specifying read_file -format verilog
-rtl.
The following table summarizes the recommended and alternative commands to read in
your designs.
The following variables apply only to Design Compiler and are not implemented by the
netlist reader:
• power_preserve_rtl_hier_names (default is false)
If you set either of these variables to true, automatic netlist detection is disabled and you
must use the -netlist option to enable the netlist reader.
Parameterized Designs
Declaring Parameters Without a Default
Port list parameters can be declared with or without a default. If you declare a parameter
without a default, you must specify an override value in every instantiation to prevent a
compile error.
As per the IEEE Std 1364-2005, parameters without a default are not supported.
The following design declares the SIZE parameter with no default, and the INSIZE
parameter with a default of eight:
module top (
output [7:0] b,
input [7:0] a
);
The following design declares the SIZE and INSIZE parameters with a default of eight:
Example 12 does not override either parameter. Parameter SIZE is undefined (no default or
override value) causing a compile error.
The syntax of the parameter specifications includes strings, integers, and constants using
the following formats `b,`h, b, and h.
You can store parameterized designs in user-specified design libraries. For example,
analyze -format sverilog n-register.v -library mylib
This command stores the analyzed results of the design contained in file n-register.v in a
user-specified design library, mylib.
To verify that a design is stored in memory, use the report_design_lib work command.
The report_design_lib command lists designs that reside in the indicated design library.
When a design is built from a template, only the parameters you indicate when you
instantiate the parameterized design are used in the template name. For example, suppose
the template ADD has parameters N, M, and Z. You can build a design where N = 8, M = 6,
and Z is left at its default. The name assigned to this design is ADD_N8_M6. If no parameters
are listed, the template is built with the default, and the name of the created design is the
same as the name of the template.
Designs which declare parameters without a default must have an override value at
instantiation or a compile error occurs. In the preceding ADD example, parameter Z must
have a default, but N and M do not.
The model in Example 13 uses a parameter to determine the register bit-width; the default
width is declared as 8.
If you want an instance of the register model to have a bit-width of 16, use the elaborate
command to specify this as follows:
elaborate DFF -param SIZE=16
Using the read_verilog command to build a design with parameters is not recommended
because you can build a design only with the default of the parameters.
You also need to either set the hdlin_auto_save_templates variable to true or insert the
template directive in the module, as follows:
module DFF ( in1, clk, out1 );
parameter SIZE = 8;
input [SIZE-1:0] in1;
input clk;
output [SIZE-1:0] out1;
// synopsys template
...
Defining Macros
You can use analyze -define to define macros on the command line.
Note:
When using the -define option with multiple analyze commands, you must
remove any designs in memory before analyzing the design again. To remove the
designs, use the remove_design -all command. Because elaborated designs
in memory have no timestamps, the tool cannot determine whether the analyzed
file has been updated. The tool might assume that the previously elaborated
design is up-to-date and reuse it.
See Also
• `define
Predefined Macros
You can also use the following predefined macros:
• SYNTHESIS—Used to specify simulation-only code, as shown in Example 14.
In this example, the SYNTHESIS macro and the `ifndef ... `endif constructs
determine whether or not to execute the simulation-only code that checks if the RESET
and SET signals are asserted at the same time. The main always block is both simulated
and synthesized; the block wrapped in the `ifndef ... `endif construct is executed only
during simulation.
• VERILOG_1995, VERILOG_2001, VERILOG_2005—Used for conditional inclusion of
Verilog 1995, Verilog 2001, or Verilog 2005 features respectively. When you set the
hdlin_vrlg_std variable to 1995, 2001, or 2005, the corresponding macro
VERILOG_1995, VERILOG_2001, or VERILOG_2005 is predefined. By default, the
hdlin_vrlg_std variable is set to 2005.
Input Descriptions
Verilog code input to Design Compiler can contain both structural and functional (RTL)
descriptions. A Verilog structural description can define a range of hierarchical and
gate-level constructs, including module definitions, module instantiations, and netlist
connections.
The functional elements of a Verilog description for synthesis include
• always statements
• Tasks and functions
• Assignments
◦ Continuous—are outside always blocks
◦ Procedural—are inside always blocks and can be either blocking or nonblocking
• Sequential blocks (statements between a begin and an end)
• Control statements
• Loops—for, while, forever
The forever loop is only supported if it has an associated disable condition, making the
exit condition deterministic.
• case and if statements
Functional and structural descriptions can be used in the same module, as shown in
Example 16.
In this example, the detect_logic function determines whether the input bit is a 0 or a 1.
After making this determination, detect_logic sets ns to the next state of the machine. An
always block infers flip-flops to hold the state information between clock cycles. These
statements use a functional description style. A structural description style is used to
instantiate the three-state buffer t1.
begin
detect_logic = 0; //default
if ( signal == 0 ) //bit is zero
ns = NO_ONES;
else //bit is one, increment state
case (cs)
NO_ONES: ns = ONE_ONE;
ONE_ONE: ns = TWO_ONES;
TWO_ONES, AT_LEAST_THREE_ONES:
begin
ns = AT_LEAST_THREE_ONES;
detect_logic = 1;
end
endcase
end
endfunction
assign ungated_detect = detect_logic( cs, signal );
endmodule
Design Hierarchy
The Design Compiler tool maintains the hierarchical boundaries you define when you use
structural Verilog. These boundaries have two major effects:
Naming Considerations
The bus output instance names are controlled by the following variables:
bus_naming_style (controls names of elements of Verilog arrays) and
bus_inference_style (controls bus inference style). To reduce naming conflicts, use
caution when applying nondefault naming styles. For details, see the man pages.
Generic Netlists
After Design Compiler reads a design, it creates a generic netlist consisting of generic
components, such as SEQGENs.
For example, after Design Compiler reads the my_fsm design in Example 17, it creates the
generic netlist shown in Example 18.
The report_cell command lists the cells in a design. Example 19 shows the report_cell
output for my_fsm design.
****************************************
Report : cell
Design : my_fsm
Version: B-2008.09
Date : Tue Jul 15 07:11:02 2008
****************************************
Attributes:
b - black box (unknown)
c - control logic
h - hierarchical
n - noncombinational
r - removable
u - contains unmapped logic
Inference Reports
The Design Compiler tool generates inference reports for the following inferred components:
• Flip-flops and latches, described in “Inference Reports for Registers” on page 4-94.
• MUX_OP cells, described in “Selection and Multiplexing Logic” on page 3-74.
• Three-state devices, described in “Three-State Driver Inference Report” on page 6-124.
• Multibit devices, described in “infer_multibit and dont_infer_multibit” on page 7-136.
• FSMs, described in “FSM Inference Report” on page 5-118.
Error Messages
If the design contains syntax errors, these are typically reported as ver-type errors; mapping
errors, which occur when the design is translated to the target technology, are reported as
elab-type errors. An error causes the script you are currently running to terminate; an error
terminates your Design Compiler session. Warnings are errors that do not stop the read
from completing, but the results might not be as expected.
You can use the suppress_message command to suppress particular warning messages
when reading SystemVerilog source files. By default, the tool does not suppress any
warnings. This command has no effect on error messages that stop the reading process.
To use it, specify the list of warning message ID codes that you want to suppress. For
example, to suppress the following message:
Warning: Assertion statements are not supported. They are
ignored near symbol "assert" on line 24 (HDL-193).
Licenses
Reading and writing license requirements are listed in Table .
Reading Writing
Reader license required license required
This chapter describes Design Compiler synthesis coding considerations in the following
sections:
• General Verilog Coding Guidelines
• Guidelines for Interacting With Other Flows
defparam
You should not use the defparam statements in synthesis because of ambiguity problems.
Because of these problems, the defparam statements are not supported in the generate
blocks. For more information, see the Verilog Language Reference Manual.
Synthesis Flows
The Design Compiler tool can infer multibit components. If your logic library supports multibit
components, they can offer several benefits, such as reduced area and power or a more
regular structure for place and route. For more information about inferring multibit
components, see infer_multibit and dont_infer_multibit.
Low-Power Flows
This topic provides guidelines to keep signal names in low-power flows:
• Keeping Signal Names
• Using Same Naming Convention Between Tools
Setting Description
all The tool preserves a signal if the signal is preserved during optimization. Both
dangling and driving nets are considered.
Note:
This setting might cause the check_design command to issue LINT-2 and LINT-3
warning messages.
Setting Description
all_driving The tool preserves a signal if the signal is preserved during optimization and is in an
(default) output path. Only driving nets are considered.
user The tool preserves a signal if the signal is preserved during optimization and is
marked with the keep_signal_name directive. Both dangling and driving nets are
considered. This setting works with the keep_signal_name directive.
user_driving The tool preserves a signal if the signal is preserved during optimization, is in an
output path, and is marked with the keep_signal_name directive. Only driving nets
are considered.
none The tool does not preserve any signal. This setting overrides the
keep_signal_name directive.
Note:
When a signal has no driver, the tool assumes logic 0 (ground) for the driver.
When you set the hdlin_keep_signal_name variable variable to true, the tool preserves
the nets and issues a warning about the preserved nets during compilation. The tool sets an
implicit size_only attribute on the logic connected to the nets to be preserved. To mark a
net to preserve, label the net with the keep_signal_name directive in the RTL and set the
hdlin_keep_signal_name variable to user or user_driving. Preserving nets might cause
QoR degradation.
In Example 20, the tool preserves signals test1 and test2 because they are in the output
paths, but it does not preserve signal test3 because it is not in an output path. The tool
removes nets syn1 and syn2 during optimization.
Table 4 shows how the settings of the variable and directive affect the preservation of
signals test1, test2, and test3. An asterisk (*) indicates that the HDL Compiler tool does not
attempt to preserve the signal.
Table 4 Variable and Directive Matrix for Signals test1, test2, and test3
Table 4 Variable and Directive Matrix for Signals test1, test2, and test3 (Continued)
Verification Flows
To prevent simulation and synthesis mismatches, follow the guidelines described in this
section. Table 5 shows the coding styles that can cause simulation and synthesis
mismatches and how to avoid the mismatches.
Table 5 Coding Styles Causing Synthesis and Simulation Mismatches
Using the one_hot and one_cold directives in a Verilog design See one_hot and one_cold.
that does not meet the requirements of the directives.
Using the full_case and parallel_case directives in a Verilog See full_case and parallel_case.
design that does not meet the requirements of the directives.
Inferring D flip-flops with synchronous and asynchronous loads. See D Flip-Flop With Synchronous and
Asynchronous Load.
Selecting bits from an array that is not valid. See Part-Select Addressing Operators
([+:] and [-:]).
Masking the set or reset signal with an unknown during See sync_set_reset.
initialization in simulation.
Using asynchronous design techniques. The tool does not issue any warning for
asynchronous designs. You must verify
the design.
Using unknowns and high impedance in comparison. See Unknowns and High Impedance in
Comparison.
Using local reg variables in functions or tasks. See Initial States for Variables.
In the following example, because if (A == 1'bx) is evaluated to false, the tool assigns 1
to reg B and issues an ELAB-310 warning.
module test (
input A,
output reg B
);
always
begin
if (A == 1'bx) B = 0;
else B = 1;
end
endmodule
SystemVerilog provides additional two constructs, casez and casex, to handle don’t care
conditions:
• The casez construct for z value
• The casex construct for z and x values or for branches that are treated as don’t care
conditions during comparison
Timing Specifications
The Design Compiler tool ignores all timing controls because these signals cannot be
synthesized. You can include timing control information in the description if it does not
change the value clocked into a flip-flop. In other words, the delay must be less than the
clock period to avoid synthesis and simulation mismatches.
You can assign a delay to a wire or wand declaration, and you can use the scalared and
vectored Verilog keywords for simulation. The tool supports the syntax of these constructs,
but they are ignored during synthesis.
Sensitivity Lists
When you run the Design Compiler tool, a module is affected by all the signals in the module
including those not listed in the sensitivity list. However, simulation relies only on the signals
listed in the sensitivity list. To prevent synthesis and simulation mismatches, follow these
guidelines to specify the sensitivity list:
• For sequential logic, include a clock signal and all asynchronous control signals in the
sensitivity list.
• For combinational logic, ensure that all inputs are listed in the sensitivity list or use the
always @* construct.
The tool ignores sensitivity lists that do not contain an edge expression and builds the logic
as if all variables within the always block are listed in the sensitivity list. You cannot mix edge
expressions and ordinary variables in the sensitivity list. If you do so, the tool issues an error
message. When the sensitivity list does not contain an edge expression, combinational logic
is usually generated. Latches might be generated if the variable is not fully specified; that is,
the variable is not assigned to any path in the block.
Note:
The statements @(posedge clock) and @(negedge clock) are not supported
in functions or tasks.
See Also
• The IEEE Std 1364-2005
These topics describe how to model combinational logic using HDL operators, MUX_OP
cells, and other Verilog constructs.
• Synthetic Operators
• Logic and Arithmetic Expressions
• Selection and Multiplexing Logic
• Bit-Truncation Coding for DC Ultra Datapath Extraction
• Latches in Combinational Logic
Synthetic Operators
Synopsys provides the DesignWare Library, which is a collection of intellectual property (IP),
to support the synthesis products. Basic IP provides implementations of common arithmetic
functions that can be referenced by HDL operators in the RTL.
The DesignWare IP solutions are built on a hierarchy of abstractions. HDL operators (either
the built-in operators or HDL functions and procedures) are associated with synthetic
operators, which are bound to synthetic modules. Each synthetic module can have multiple
architectural realizations called implementations. When you use the HDL addition operator
in a design, the Design Compiler tool infers an abstract representation of the adder in the
netlist. The same inference applies when you use a DesignWare component. For example,
a DW01_add instantiation is mapped to the synthetic operator associated with it, as shown
in Figure 6.
A synthetic library contains definitions for synthetic operators, synthetic modules, and
bindings. It also contains declarations that associate synthetic modules with their
implementations. To display information about the standard synthetic library that is included
with the Design Compiler license, use the report_synlib command.
For example,
report_synlib standard.sldb
For more information about the DesignWare synthetic operators, modules, and libraries, see
the DesignWare documentation.
Z <= X Y
map_to_operator directive
ADD_UNS_OP
Bindings
Synthetic modules
ADD_SUB ADD ALU
Implementation
declarations
• Addition Overflow
• Sign Conversions
Basic Operators
When the Design Compiler tool elaborates a design, it maps HDL operators to synthetic
(DesignWare) operators in the netlist. When the Design Compiler tool optimizes the design,
it maps these operators to the DesignWare synthetic modules and chooses the best
implementation based on the constraints, option settings, and wire load models.
The Design Compiler tool maps HDL operators, such as comparison (> or <), addition (+),
decrement (-), and multiplication (*), to synthetic operators from the Synopsys standard
synthetic library, standard.sldb. Table 6 shows the complete list of the standard synthetic
operators. For more information, see the DesignWare Library documentation.
Table 6 HDL Operators Mapped to Standard Synthetic Operators
* MULT_UNS_OP, MULT_TC_OP
Note:
Depending on the selected implementation, a DesignWare license might be
needed during optimization. To find out the implementation options and license
requirements, see the DesignWare Datapath and Building Block IP Quick
Reference.
Addition Overflow
When the Design Compiler tool performs arithmetic optimization, it considers how to handle
addition overflow caused by carry bits. The optimized structure is affected by the bit-widths
that you declare for storing the intermediate results.
c[6]
t[4]
z[6]
c[6]
a+b[5]
z[6]
a[4]
b+c[6]
z[6]
Sign Conversions
When reading a design that contains signed expressions and assignments, the tool issues
VER-318 warnings for sign assignment mismatches.
No warnings are issued for the following conditions:
• The conversion is necessary only for constants in the expression.
• The width of the constant does not change as a result of the conversion.
• The most significant bit of the constant is zero (not negative).
In the following example, though the tool implicitly converts the signed constant 1 to
unsigned, no warning is issued because the conversion meets the previously mentioned
three conditions. By default, integer constants are treated as signed types with signed
values.
module t (
input [3:0] a, b,
output [5:0] z
);
assign z = a + b + 1;
endmodule
A VER-318 warning indicates that the tool implicitly performs one of the following
operations:
• Conversion
◦ An unsigned expression to a signed expression
◦ A signed expression to an unsigned expression
• Assignment
◦ An unsigned right side to a signed left side
◦ A signed right side to an unsigned left side
In the following example, signed logic a is converted to an unsigned value and not
sign-extended, and the tool issues a VER-318 warning. This behavior complies with the
IEEE Std 1364-2005.
module t (/*...*/);
logic signed [3:0] a;
logic [7:0] c;
assign a = 4'sb1010;
assign c = a+7'b0101011;
endmodule
When explicit type casting is used, no VER-318 warning is issued. For example, to force
logic a to be unsigned, assign logic c as follows:
c = unsigned'(a)+7'b0101011;
For Verilog designs, you can use the $signed and $unsigned system tasks to do the sign
conversion. For more information, see the IEEE Std 1364-2005.
In the following example, the left side is unsigned, but the right side is sign-extended; that is,
logic a contains the value of 4'b1010 after the assignment. A VER-318 warning is issued.
module t (/*...*/)
logic unsigned [3:0] a;
assign a = 4'sb1010;
endmodule
If a line contains more than one implicit conversion, such as the expression that is assigned
to logic c in the following example, the tool issues only one warning. In this example, logic a
and b are converted to unsigned values and the right side is unsigned. Assigning the
right-side value to logic c results in a VER-318 warning.
module t (/*...*/)
logic signed [3:0] a;
logic signed [3:0] b;
logic signed [7:0] c;
assign c = a+4'b0101+(b*3'b101);
endmodule
The following examples show sign conversions and the cause of each VER-318 warning:
• In the m1 module, the signs are consistently applied and no warning is issued.
module m1 (
input signed [0:3] a,
output signed [0:4] z
);
assign z = a;
endmodule
• In the m2 module, input a is signed and added to 3'sb111, which is a signed value of -1.
Output z is not signed, so the signed value of the expression on the right side is
converted to unsigned and assigned to output z.
module m2 (
input signed [0:2] a,
output [0:4] z
);
assign z = a + 3'sb111;
endmodule
• In the m3 module, input a is unsigned but becomes signed when it is assigned to signed
logic x, and the tool issues a VER-318 warning. In the z = x < 4'sd5 expression, the
comparison result of signed x to a signed 4'sd5 value is put into unsigned logic z. This
appears to be a sign mismatch; however, no VER-318 warning is issued because
comparison results are always considered unsigned for all relational operators.
module m3 (
input [0:3] a,
output logic z
);
logic signed [0:3] x;
always_comb
begin
x = a;
z = x < 4'sd5;
end
endmodule
• In the m4 module, the signs are consistently applied and no warning is issued.
module m4 (
input signed [7:0] in1, in2,
output signed [7:0] out
);
assign out = in1 * in2;
endmodule
• In the m5 module, inputs, a and b, are unsigned but they are assigned to signed signals
x and y respectively. Two VER-318 warnings are issued. In addition, logic y is subtracted
from logic x and assigned to unsigned output z; the expression results in a VER-318
warning.
module m5 (
input [1:0] a, b,
output [2:0] z
);
logic signed [1:0] x, y;
assign x = a;
assign y = b;
assign z = x - y;
endmodule
• In the m7 module, the tool issues no warning because all signs are properly applied.
Comparing a signed constant results in a signed comparison.
module m7 (
input signed [7:0] in1, in2,
output lt, in1_lt_64
);
assign lt = in1 < in2;
assign in1_lt_64 = in1 < 8'sd64;
endmodule
• In the m8 module, signed input in1 is compared with unsigned input in2. Because
comparison is unsigned, a VER-318 warning is issued. In addition, the unsigned 8‘d64
constant causes an unsigned comparison; a VER-318 warning is issued.
module m8 (
input signed [7:0] in1,
input [7:0] in2,
output lt
);
wire uns_lt, uns_in1_lt_64;
assign uns_lt = in1 < in2;
assign uns_in1_lt_64 = in1 < 8'd64;
assign lt = uns_lt + uns_in1_lt_64;
endmodule
• In the m9 module, even though inputs, in1 and in2, are mismatched in signs, the casting
operator converts input in2 to a signed signal. When a casting operator is used and a
sign conversion occurs, no warning is issued.
module m9 (
input signed [7:0] in1;
input [7:0] in2;
output lt;
);
assign lt = in1 < signed'({1'b0, in2});
endmodule
SELECT_OP
CONTROL1_0
CONTROL2_0
CONTROL3_0
CONTROL4_0
A SELECT_OP cell can have single-bit or multiple-bit data paths. The number of data inputs
can be any practical integer number. Figure 11 shows a SELECT_OP cell that can select
one of three two-bit-wide data inputs.
SELECT_OP
CONTROL1_0
CONTROL2_0
CONTROL3_0
During elaboration, the tool creates GTECH control logic to drive the selection inputs
according to the RTL functionality. (This logic, by construction, meets the one-hot signal
requirement.)
During compile, the tool maps SELECT_OP cells to the logic library using the available
combinational cells: simple Boolean gates, complex multiple-input gates, multiplexer cells,
or any mix of these types.
Figure 12 shows the elaborated result. The SELECT_OP selection signals are driven by
GTECH logic gates that implement the if/else conditions.
Figure 13 shows the compiled, mapped logic for the previous example. The control logic
and the SELECT_OP cell are mapped together into an optimal gate structure.
Z
D1
A
B
D3
A MUX_OP cell can have single-bit or multiple-bit data paths. For S selection inputs, the
number of data inputs is 2S, although the number of selectable data inputs can be less (with
the excess tied to ground). Figure 15 shows a MUX_OP cell that can select one of three
two-bit-wide data inputs.
MUX_OP
S0
S1
During elaboration, the tool drives the MUX_OP selection inputs with the RTL selection
signals. (These signals, by construction, meet the binary-encoded requirement.)
During compile, the tool maps MUX_OP cells to the logic library, strongly preferring a tree of
multiplexer cells if possible.
Figure 16 shows the elaborated result. The MUX_OP selection signals are driven directly by
the array index signals, which are binary-encoded by construction. The eighth data input of
the MUX_OP cell is unused and thus tied to logic 0.
SEL[2:0] 3 MUX_OP
SEL[0] S0
SEL[1] S1
SEL[2] S2
Figure 17 shows the compiled, mapped logic for the previous example. The MUX_OP is
implemented using a compact inverting multiplexer tree structure, along with a logic gate
that results from optimizing the unused MUX_OP input data bit.
SEL[1]
SEL[2]
Although MUX_OP cells are faster than SELECT_OP cells, they might increase congestion
because of their pin density.
if statement SELECT_OP
if and case statements and the conditional operator (?:) follow the same inference rules.
Therefore, in this documentation they are collectively referred to as RTL selection
statements.
Infer a MUX_OP for the selection statement, but only if permitted by global variable
settings.
• // synopsys infer_mux_override
The pragma requirements and restrictions for the conditional operator (?:) are:
• The selection expression before the ? (question mark) character must be an equality
comparison of a simple variable to a constant value. Implicit single-bit Boolean tests are
supported, such as (var) ?.
• The selection expression cannot use any other operators, including negation (~) or array
indexing.
• Multiple conditional operators in the same parent expression are not supported.
The pragma requirements and restrictions for always and always_comb blocks are:
• The infer_mux pragma supports block-based specification; the infer_mux_override
pragma does not.
• if and case statements in the block are considered; conditional operators (?:) are not.
• if and case statements must each meet their own particular pragma criteria.
Table 8 shows the valid values and resulting inference behaviors that apply.
Table 8 hdlin_infer_mux Application Variable Inference Behaviors
all MUX_OP
For a MUX_OP cell to be inferred, the following global application variable criteria must also
be met (unless the infer_mux_override pragma is applied):
• hdlin_mux_size_limit (default 32)
This variable sets the upper limit for MUX_OP data input width.
• hdlin_mux_size_min (default 2)
This variable sets the lower limit for MUX_OP data input width.
• hdlin_mux_oversize_ratio (default 100)
This variable sets a limit for how many duplicated data signals are allowed, specified as
the ratio of MUX_OP data inputs to unique data signals.
To prevent this, the tool issues the following warning message and infers a SELECT_OP cell
instead:
Warning: /proj/rtl/case.sv:30: No MUX_OP inferred for the case because
it might lose the benefit of resource sharing. (ELAB-370)
In this case, you can still force a MUX_OP cell by adding the infer_mux_override pragma
to your RTL.
There are two methods to control the inference behavior for array reads:
• Globally, using application variables
• Locally, using RTL pragmas
These methods are interdependent in that either can take precedence over the other,
depending on the settings used.
Table 8 shows the valid values and resulting inference behaviors that apply.
Table 9 hdlin_infer_mux Application Variable Inference Behaviors
all MUX_OP
For a MUX_OP cell to be inferred, the following global application variable criteria must also
be met (unless the hdlin_infer_mux application variable is set to all):
• hdlin_mux_for_array_read_sparseness_limit (default 90)
When the width of the array being indexed is not a power of two, this variable specifies a
percentage requirement for how many MUX_OP data inputs must be connected.
The infer_mux_override pragma also forces the tool to map to a tree of multiplexer cells.
Array reads do not use or support the infer_mux pragma, as they are already the default
when the hdlin_infer_mux variable is set to default.
To apply the pragma to specific array reads, place it directly before the closing bus bracket
as an inline comment:
assign selected_bit =
mem1[addr1 /*synopsys infer_mux_override*/][idx1] ||
mem2[addr2 /*synopsys infer_mux_override*/][idx2];
For nested array reads, an inline pragma applies to all reads nested within that level:
// inference applies to addr1 (directly applied) *and* X (nested inside)
assign selected_bit =
mem1[addr1[X] /*synopsys infer_mux_override*/][idx1[Y]];
of them. However, you can use the infer_onehot_mux RTL pragma to take advantage of
them.
To do this, use the case Verilog statement together with the full_case and parallel_case
pragmas, which indicate that the branches are mutually exclusive. Then, place the
infer_onehot_mux pragma directly after the closing parenthesis of the case selection
expression.
The one-hot selection signals can be used together as the case selection expression
(Example 25) or individually as the case item expressions (Example 24).
always @*
begin
case({sel3, sel2, sel1}) //synopsys full_case parallel_case infer_onehot_mux
3'b001: out = in1;
3'b010: out = in2;
3'b100: out = in3;
default: out = 1’bX;
endcase
end
endmodule
);
always @*
begin
case (1'b1) //synopsys full_case parallel_case infer_onehot_mux
sel1: out = in1;
sel2: out = in2;
sel3: out = in3;
default: out = 1’bX;
endcase
end
endmodule
The infer_onehot_mux pragma infers a SELECT_OP cell with an internal attribute that
marks it for one-hot MUX cell mapping.
The number of selection signals is important: a one-hot MUX cell must exist in the
technology library that is as least as wide as the number of branches in the case statement.
The tool cannot compose wider one-hot MUX logic from smaller one-hot MUX cells.
For lower-bit truncations, the datapath is extracted in all cases. As described in Table , bit
truncation can be either explicit or implicit.
Explicit bit truncation An explicit upper-bit truncation occurs when you specify the bit range for
truncation.
The following code indicates explicit upper-bit truncation of operand A because
p is smaller than q:
wire [q:0] A;
out = A [p:0];
Implicit bit truncation An implicit upper-bit truncation occurs through assignment. Unlike explicit
upper-bit truncation, you do not explicitly define the range for truncation.
The following code indicates implicit upper-bit truncation of operand Y:
input [7:0] A, B;
output [14:0] Y;
assign Y = A*B;
Because A and B are 8-bit, their product is 16-bit. However, the 15-bit Y is
assigned to the 16-bit product and the most significant bit (MSB) of the product
is implicitly truncated. In this example, the MSB is the carryout bit.
Example 26 shows how bit truncation affects datapath extraction. When the a*b operation is
assigned to wire d, the upper bits are implicitly truncated and the width of output e is less
than the width of wire d. This code meets the first condition but not the second, so the code
is extracted.
wire [14:0] d;
assign d = a * b; // Implicit upper-bit truncation
assign e = c + d; // Width of e is less than d
endmodule
Example 27 shows how bit truncation prevents extraction. When the a*b operation is
assigned to wire d, the upper bits are implicitly truncated and the width of output e is greater
than the width of wire d. This code meets both the first and second conditions, so the code
is not extracted.
wire [7:0] d;
assign d = a * b; // Implicit upper-bit truncation
assign e = c + d; // Width of e is greater than d
endmodule
Example 28 shows how bit truncation prevents extraction. The upper bits of wire d are
explicitly truncated, and the width of output e is greater than the width of wire d. This code
meets both the first and second conditions, so the code is not extracted.
wire [15:0] d;
assign d = a * b; // d is not truncated
assign e = c + d[7:0]; // Explicit upper-bit truncation of d
// Width of e is greater than d[7:0]
endmodule
Example 29 shows how bit truncation does not prevent extraction. The lower bits of wire d
are explicitly truncated. For expressions involving lower-bit truncations, the truncated
operands are extracted regardless of the bit-width of the truncated operands and the
expression result. This code is extracted.
wire [15:0] d;
assign d = a * b; // No implicit upper-bit truncation
assign e = c + d[15:8]; // "explicit lower" bit truncation of d
endmodule
Example 31 and Example 32 show Q fully assigned—Q is assigned 0 when GATE equals
1’b0. Note that Example 31 and Example 32 are not equivalent to Example 30, in which Q
holds its previous value when GATE equals 1’b0.
The code in Example 33 results in a latch because the variable is not fully assigned. To
avoid the latch inference, add the following statement before the endcase statement:
default: decimal= 10’b0000000000;
Latches are also synthesized whenever a for loop statement does not assign a variable for
all possible executions of the for loop and when a variable assigned inside the for loop is not
assigned a value before entering the enclosing for loop.
The term register refers to a 1-bit memory device, either a flip-flop or latch. A flip-flop is an
edge-triggered memory device, while a latch is a level-sensitive memory device. The
following topics describe flip-flop and latch inference:
• Generic Sequential Cell SEQGEN
• Inference Reports for Registers
• Register Inference Guidelines
• Register Inference Examples
clear
preset
next_state
clocked_on
data_in
enable Q
synch_clear QN
synch_preset
synch_toggle
synch_enable
SEQGEN
Example 34 shows how to direct the Design Compiler tool to use a SEQGEN cell to
implement a D flip-flop with an asynchronous reset.
RESET clear
preset
DATA next_state
CLK clocked_on
data_in
enable Q Q
Logic 0 synch_clear QN
synch_preset
synch_toggle
Logic 1 synch_enable
SEQGEN
Example 35 shows the report_cell output, where the inferred Q_reg flip-flop is mapped to
a SEQGEN cell.
Attributes:
b - black box (unknown)
h - hierarchical
n - noncombinational
r - removable
u - contains unmapped logic
After the Design Compiler tool synthesizes the design, the SEQGEN is mapped to the
appropriate flip-flop in the logic library. Figure 20 shows an example of an implementation
after compile.
DATA D Q Q
Q_reg
CLK CP
RESET
Note:
If the logic library does not contain the inferred flip-flop or latch, the Design
Compiler tool creates combinational logic for the missing function. For example,
if you describe a D flip-flip with a synchronous set but your target library does not
contain this type of flip-flop, the tool creates combinational logic for the
synchronous set function. The tool cannot create logic to duplicate an
asynchronous preset or reset. Your library must contain the sequential cell with
the asynchronous control pins. For more information, see Register Inference
Limitations.
If you do not want the inference report, set the hdlin_reporting_level variable to none.
See Also
• Reporting Elaboration Errors in the Hierarchy
Minimizing Registers
An always block that contains a clock edge in the sensitivity list causes a flip-flop inference
for each variable assigned a value in that block. It might not be necessary to infer as
flip-flops all variables in the always block. Make sure your HDL description builds only as
many flip-flops as the design requires.
Example 40 infers six flip-flops: three to hold the values of count and one each to hold
and_bits, or_bits, and xor_bits. However, the output values of the and_bits, or_bits, and
xor_bits depend solely on the value of count. Because count is registered, there is no reason
to register the three outputs.
Example 41 shows the inference report which contains the six inferred flip-flops.
To avoid inferring extra registers, you can assign the outputs from within an asynchronous
always block. Example 42 shows the same function described with two always blocks, one
synchronous and one combinational, that separate registered or sequential logic from
combinational logic. This technique is useful for describing finite state machines. Signal
assignments in the synchronous always block are registered, but signal assignments in the
asynchronous always block are not. The code in Example 42 creates a more area-efficient
design.
always @(count)
begin //asynchronous block
and_bits = & count;
or_bits = | count;
xor_bits = ^ count;
end
endmodule
Example 43 shows the inference report, which contains three inferred flip-flops.
See Also
• D Flip-Flop With Synchronous Reset: Use sync_set_reset
Example 44 uses the preserve_sequential directive to save the unloaded cell, sum2, and
the combinational logic preceding it; note that the combinational logic after it is not saved. If
you also want to save the combinational logic after sum2, you need to recode design
mydesign as shown in Example 45.
endmodule
Note:
By default, the hdlin_preserve_sequential variable does not preserve
variables used in for loops as unloaded registers. To preserve such variables, you
must set hdlin_preserve_sequential to ff+loop_variables.
With the hdlin_preserve_sequential variable set to ff, the tool builds two registers; one
for the feedthrough cell (temp1) and the other for the loaded cell (temp2) as shown in the
following memory inference report:
latches, set the hdlin_check_no_latch variable to true, which causes the tool to issue
ELAB-395 warning messages for latch inference.
As shown in Example 49, one branch of the case statement is commented out, so output
DOUT is not fully specified and the tool infers a latch.
Example 49
module selector (SEL, DIN, DOUT);
input [1:0] SEL;
input [3:0] DIN;
output reg DOUT;
always @*
case (SEL)
2'b00: DOUT = DIN[0];
2'b01: DOUT = DIN[1];
2'b10: DOUT = DIN[2];
// 2'b11: DOUT = DIN[3];
endcase
endmodule
The following example is invalid because the if statement does not occur at the top
level:
always @(posedge clk or posedge reset) begin
temp = reset;
if (reset)
...
end
The tool issues the following message when the if statement does not occur at the top
level:
Error: .../test.sv:8: The statements in this 'always' block are
outside the scope of the synthesis policy. Only an 'if' statement is
allowed at the top level in this always block. (ELAB-302)
Inferring Latches
The tool infers latches when variables are conditionally assigned. A variable is conditionally
assigned if there is a path that does not explicitly assign a value to that variable.
• Basic D Latch
• D Latch With Asynchronous Set: Use async_set_reset
• D Latch With Asynchronous Reset: Use async_set_reset
• D Latch With Asynchronous Set and Reset: Use hdlin_latch_always_async_set_reset
Basic D Latch
To direct the tool to infer a D latch, you need to control the gate and data signals from the
top-level ports or through combinational logic, so simulation can initialize the design.
Example 50 shows that a D latch is inferred for the always@ construct.
);
always @(GATE or DATA)
if (GATE)
Q <= DATA;
endmodule
The Design Compiler tool generates the inference report shown in Example 51.
Inferring Flip-Flops
Synthesis of sequential elements, such as various types of flip-flops, often involves signals
that set or reset the sequential device. Synthesis tools can create a sequential cell that has
built-in set and reset functionality. This is referred to as set/reset inference. For an example
using a flip-flop with reset functionality, consider the following RTL code:
module m (
input clk, set, reset, d,
output reg q
);
always @ (posedge clk)
if (reset) q <= 1'b0;
else q <= d;
endmodule
There are two ways to synthesize an electrical circuit with a reset signal based on the
previous code. You can either synthesize the circuit with a simple flip-flop with external
combinational logic to represent the reset functionality, as shown in Figure 21, or you can
synthesize a flip-flop with built-in reset functionality, as shown in Figure 22.
D Q
Reset Clock
Flip-Flop
D Q
Reset
Clock
The intended implementation is not apparent from the RTL code. You should specify Design
Compiler synthesis directives or Design Compiler variables to guide the tool to create the
proper synchronous set and reset signals.
The following sections provide examples of these flip-flops:
• Basic D Flip-Flop
• D Flip-Flop With Asynchronous Reset Using ?: Construct
• D Flip-Flop With Asynchronous Reset
• D Flip-Flop With Asynchronous Set and Reset
• D Flip-Flop With Synchronous Set: Use sync_set_reset
• D Flip-Flop With Synchronous Reset: Use sync_set_reset
• D Flip-Flop With Synchronous and Asynchronous Load
• D Flip-Flops With Complex Set and Reset Signals
• Multiple Flip-Flops With Asynchronous and Synchronous Controls
Basic D Flip-Flop
When you infer a D flip-flop, make sure you can control the clock and data signals from the
top-level design ports or through combinational logic. Controllable clock and data signals
ensure that simulation can initialize the design. If you cannot control the clock and data
signals, infer a D flip-flop with an asynchronous reset or set or with a synchronous reset or
set.
Example 58 infers a basic D flip-flop.
reg Q;
always @(posedge CLK)
Q <= DATA;
endmodule
endmodule
Inference Report
module dff_sync_set (
input DATA, CLK, SET;
output reg Q
);
//synopsys sync_set_reset "SET"
always @(posedge CLK)
if (SET) Q <= 1'b1;
else Q <= DATA;
endmodule
endmodule
• Use no more than two operands in the set/reset logic expression conditional.
• Use the set/reset signal as the first operand in the set/reset logic expression conditional.
This coding style supports usage of the negation operator on the set/reset signal and the
logic expression. The logic expression can be a simple expression or any expression
contained inside parentheses. However, any deviation from these coding guidelines is not
supported. For example, using a more complex expression other than the OR of two
expressions, or using a rst (or ~rst) that does not appear as the first argument in the
expression is not supported.
Examples
//synopsys sync_set_reset "rst"
always @(posedge clk)
if (rst | logic_expression)
q <= 0;
else ...
else ...
...
q <= 0;
else ...;
else ...;
...
=============================================================================
| Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST |
=============================================================================
| Q2_reg | Flip-flop | 1 | N | N | Y | N | N | N | N |
=============================================================================
Design Compiler automatically infers finite state machines (FSMs). For FSM optimization
details, see the Design Compiler User Guide.
This chapter describes FSM inference in the following sections:
• FSM Coding Requirements for Automatic Inference
• FSM Inference Variables
• FSM Coding Example
• FSM Inference Report
• Enumerated Types
• Separate Sequential and Combinational Assignments
Item Description
Registers To infer a register as an FSM state register, the register
- Must never be assigned a value other than the defined state values.
- Must never be a module port, function port, or task port. This would make the
encoding visible to the outside.
Inside expressions, FSM state registers can be used only as an operand of "==" or
"!=" comparisons, or as the expression in a case statement (that is, "case (cur_state)
...") that is, an implicit comparison to the label expressions. FSM state registers are
not allowed to occur in other expressions—this would make the encoding explicit.
Function There can be only one FSM design per module. State variables cannot drive a port.
State variables cannot be indexed.
Ports All ports of the initial design must be either input ports or output ports. Inout ports are
not supported.
Combinational Combinational feedback loops are not supported although combinational logic that
feedback loops does not depend on the state vector is accurately represented.
Clocks FSM designs can include only a single clock and an optional synchronous or
asynchronous reset signal.
Variable Description
hdlin_reporting_level Default is basic.
Variable enables and disables FSM inference reports. When set to
comprehensive, FSM inference reports are generated when Design
Compiler reads the code. By default, FSM inference reports are not
generated. For more information, including valid values, see “Customizing
Elaboration Reports” on page 1-36.
fsm_auto_inferring Default is false.
Variable determines whether or not Design Compiler automatically extracts
the FSM during compile. In order to automatically infer and extract an FSM,
fsm_auto_inferring must be true. See the Design Compiler User Guide
for additional information.
For more information about these variables, see the man pages.
parameter [3:0]
set0 = 4'b0001, hold0 = 4'b0010, set1 = 4'b0100, hold1 = 4'b1000;
always @ (current_state or x)
case (current_state)
set0:
next_state = hold0;
hold0:
if (x == 0)
next_state = hold0;
else
next_state = set1;
set1:
next_state = hold1;
hold1:
next_state = set0;
default :
next_state = set0;
endcase
assign y = current_state == hold0 & x;
endmodule
set0
y=0 y=0
hold1 hold0
x == 0 / y = 0
y=0
set1 x != 0 / y = 1
inference report is not generated. For more information about the hdlin_reporting_level
variable, see “Customizing Elaboration Reports” on page 1-36.
Consider the code in Example 73.
always @(*)
case (current_state)
yellow:
next_state = red;
green:
next_state = yellow;
red:
next_state = green;
default:
next_state = red;
endcase
assign y = current_state == yellow;
endmodule // fsm
Enumerated Types
Design Compiler simplifies equality comparisons and detection of full cases in designs that
contain enumerated types. A variable has an enumerated type when it can take on only a
subset of the values it could possibly represent. For example, if a 2-bit variable can be set
to 0, 1, or 2 but is never assigned to 3, then it has the enumerated type {0, 1, 2}. Enumerated
types commonly occur in finite state machine state encodings. When the number of states
needed is not a power of 2, certain state values can never occur. In finite state machines
with one-hot encodings, many values can never be assigned to the state vector. For
example, for a vector of length n, there are n one-hot values, so there are (2**n - n) values
that will never be used.
Design Compiler infers enumerated types automatically; user directives can be used in
other situations. When all variable assignments are within a module, Design Compiler
usually detects if the variable has an enumerated type. If the variable is assigned a value
that depends on an input port or if the design assigns individual bits of the variable
separately, Design Compiler requires the /* synopsys enum */ directive in order to
consider the variable as having an enumerated type.
When enumerated types are inferred, Design Compiler generates a report similar to
Example 75.
Example 76 is a combination of both FSM and enumerated type optimization. The first case
statement infers an FSM; the second case statement uses enumerated type optimization.
These are two independent processes.
parameter [5:0]
zero = 6'b000001, one = 6'b000010, two = 6'b000100, three = 6'b001000, four
= 6'b010000, five = 6'b100000;
always @ (tmp)
case (tmp)
five : y <= 6'b100110;
four : y <= 6'b010100;
three : y <= 6'b001001;
two : y <= 6'b010010;
one : y <= 6'b111111;
zero : y <= 6'b100100;
default : y <= 6'b110101;
endcase
endmodule
Design Compiler infers a three-state driver when you assign the value z (high impedance)
to a variable. Design Compiler infers 1 three-state driver per variable per always block. You
can assign high-impedance values to single-bit or bused variables. A three-state driver is
represented as a TSGEN cell in the generic netlist. Three-state driver inference and
instantiation are described in the following sections:
• Using z Values
• Three-State Driver Inference Report
• Assigning a Single Three-State Driver to a Single Variable
• Assigning Multiple Three-State Drivers to a Single Variable
• Registering Three-State Driver Data
• Instantiating Three-State Drivers
• Errors and Warnings
Using z Values
You can use the z value in the following ways:
• Variable assignment
• Function call argument
• Return value
You can use the z value only in a comparison expression, such as in
if (IN_VAL == 1'bz) y=0;
is not a comparison expression. Design Compiler generates an error for this expression.
The first column of the report indicates the name of the inferred three-state device. The
second column indicates the type of inferred device. The third column indicates the width of
the inferred device. Design Compiler generates the same report for the default and verbose
reports for three-state inference. For more information about the hdlin_reporting_level
variable to basic+fsm, see Customizing Elaboration Reports.
============================================
Example 81 infers a single three-state driver with MUXed inputs and shows the associated
inference report.
Inference Report
============================================
| Register Name | Type | Width |
============================================
| T_tri | Tri-State Buffer | 1 |
============================================
B T
SELA
Do not use multiple always blocks (shown in Example 83). Multiple always blocks cause a
simulation/synthesis mismatch because the reg data type is not resolved. Note that the tool
does not display a warning for this mismatch.
============================================
| Register Name | Type | Width |
============================================
| OUT1_tri | Tri-State Buffer | 1 |
============================================
bufif1 (out1,in1,cntrl1);
endmodule
always@ (RESET)
if (RESET)
OUT1 = 1'b0;
endmodule
Design Compiler synthesis directives are special comments that affect how synthesis
processes the RTL. These comments are ignored by other tools.
These synthesis directives begin as a Verilog comment (// or /*) followed by a pragma
prefix (pragma, synopsys, or synthesis) and then the directive. The //$s or //$S prefix
can be used as a shortcut for //synopsys. The simulator ignores these directives.
Whitespace is permitted (but not required) before and after the Verilog comment prefix.
Note:
Not all directives support all pragma prefixes; see “Directive Support by Pragma
Prefix” on page 7-147 for details.
• sync_set_reset
• sync_set_reset_local
• sync_set_reset_local_all
• template
• translate_off and translate_on (Deprecated)
• Directive Support by Pragma Prefix
async_set_reset
When you set the async_set_reset directive on a single-bit signal, Design Compiler
searches for a branch that uses the signal as a condition and then checks whether the
branch contains an assignment to a constant value. If the branch does, the signal becomes
an asynchronous reset or set. Use this directive on single-bit signals.
The syntax is
// synopsys async_set_reset "signal_name_list"
See Also
• Inferring Latches
async_set_reset_local
When you set the async_set_reset_local directive, Design Compiler treats listed signals
in the specified block as if they have the async_set_reset directive set.
Attach the async_set_reset_local directive to a block label using the following syntax:
// synopsys async_set_reset_local block_label "signal_name_list"
async_set_reset_local_all
When you set the async_set_reset_local_all directive, Design Compiler treats all listed
signals in the specified blocks as if they have the async_set_reset directive set. Attach the
async_set_reset_local_all directive to a block label using the following syntax:
// synopsys async_set_reset_local_all "block_label_list"
set_max_area 10.0
set_max_delay 5.0 port_z
# no end needed for this form
*/
The Design Compiler tool interprets the statements embedded between the
dc_tcl_script_begin and the dc_tcl_script_end directives. If you want to comment out
part of your script, use the Tcl # comment character within the RTL comments.
The following items are not supported in embedded Tcl scripts:
• Hierarchical constraints
• Wildcards
• List commands
• Multiple line commands
Observe the following guidelines when using embedded Tcl scripts:
• Constraints and attributes declared outside a module apply to all subsequent modules
declared in the file.
• Constraints and attributes declared inside a module apply only to the enclosing module.
• Any dc_shell scripts embedded in functions apply to the whole module.
• Include only commands that set constraints and attributes. Do not use action commands
such as compile, gen, and report. The tool ignores these commands and issues a
warning or error message.
• The constraints or attributes set in the embedded script go into effect after the read
command is executed. Therefore, variables that affect the read process itself are not in
effect before the read.
• Error checking is done after the read command completes. Syntactic and semantic
errors in dc_shell strings are reported at this time.
• You can have more than one dc_tcl_script_begin / dc_tcl_script_end pair per file or
module. The compiler does not issue an error or warning when it sees more than one
pair. Each pair is evaluated and set on the applicable code.
• An embedded dc_shell script does not produce any information or status messages
unless there is an error in the script.
• Usage of built-in Tcl commands is not recommended.
• Usage of output redirection commands is not recommended.
enum
Use the enum directive with the Verilog parameter definition statement to specify state
machine encodings.
The syntax of the enum directive is
// synopsys enum enum_name
Example 90 shows the declaration of an enumeration of type colors that is 3 bits wide and
has the enumeration literals red, green, blue, and cyan with the values shown.
The enumeration must include a size (bit-width) specification. Example 91 shows an invalid
enum declaration.
Example 92 shows a register, a wire, and an input port with the declared type of colors. In
each of the following declarations, the array bounds must match those of the enumeration
declaration. If you use different bounds, synthesis might not agree with simulation behavior.
Even though you declare a variable to be of type enum, it can still be assigned a bit value that
is not one of the enumeration values in the definition. Example 93 relates to Example 92 and
shows an invalid encoding for colors.
Because 111 is not in the definition for colors, it is not a valid encoding. Design Compiler
accepts this encoding, but issues a warning for this assignment.
You can use enumeration literals just like constants, as shown in Example 94.
If you declare a port as a reg and as an enumerated type, you must declare the enumeration
when you declare the port. Example 95 shows the declaration of the enumeration.
full_case
This directive prevents Design Compiler from generating logic to test for any value that is not
covered by the case branches and creating an implicit default branch. Set the full_case
directive on a case statement when you know that all possible branches of the case
statement are listed within the case statement. When a variable is assigned in a case
statement that is not full, the variable is conditionally assigned and requires a latch.
Caution:
Marking a case statement as full when it actually is not full can cause the
simulation to behave differently from the logic Design Compiler synthesizes
because Design Compiler does not generate a latch to handle the implicit default
condition.
// synopsys full_case
In Example 97, full_case is set on the first case statement and parallel_case and
full_case directives are set on the second case statement.
In the first case statement, the condition in == 3 is not covered. However, the designer
knows that in == 3 will never occur and therefore sets the full_case directive on the case
statement.
In the second case statement, not all 16 possible branch conditions are covered; for
example, current_state == 4’b0101 is not covered. However,
• The designer knows that these states will never occur and therefore sets the full_case
directive on the case statement.
• The designer also knows that only one branch is true at a time and therefore sets the
parallel_case directive on the case statement.
In the following example, at least one branch will be taken because all possible values of sel
are covered, that is, 00, 01, 10, and 11:
module mux(a, b,c,d,sel,y);
input a,b,c,d;
input [1:0] sel;
output y;
reg y;
always @ (a or b or c or d or sel)
begin
case (sel)
2'b00 : y=a;
2'b01 : y=b;
2'b10 : y=c;
2'b11 : y=d;
endcase
end
endmodule
It is unknown what happens when sel equals 01 and 10. In this case, Design Compiler
generates logic to test for any value that is not covered by the case branches and creates
an implicit “default” branch that contains no actions. When a variable is assigned in a case
statement that is not full, the variable is conditionally assigned and requires a latch.
Note:
The term multibit component refers, for example, to an x-bit register in your HDL
description. The term multibit library cell refers to a library macro cell, such as a
flip-flop cell.
endmodule
endmodule
Attributes:
b - black box (unknown)
h - hierarchical
n - noncombinational
r - removable
u - contains unmapped logic
The multibit group name for registers is set to the name of the bus. In the cell names of the
multibit registers with consecutive bits, a colon separates the outlying bits.
If the colon conflicts with the naming requirements of your place-and-route tool, you can
change the colon to another delimiter by using the bus_range_separator_style variable.
For multibit library cells with nonconsecutive bits, a comma separates the nonconsecutive
bits. This delimiter is controlled by the bus_multiple_separator_style variable. For
example, a 4-bit banked register that implements bits 0, 1, 2, and 5 of bus data_reg is
named data_reg [0:2,5].
infer_mux
Use the infer_mux directive to infer MUX_OP cells for a specific case or if statement, as
shown in the following RTL code:
always@(SEL) begin
case (SEL) // synopsys infer_mux
2'b00: DOUT <= DIN[0];
2'b01: DOUT <= DIN[1];
2'b10: DOUT <= DIN[2];
2'b11: DOUT <= DIN[3];
endcase
You must use a simple variable as the control expression; for example, you can use the
input "A" but not the negation of input "A". If statements have special coding considerations.
For more information, see “Controlling Selection Statement Inference” on page 3-79.
infer_mux_override
Use the infer_mux_override directive to infer MUX_OP cells for a specific case or if
statement regardless of the settings of the following variables:
• hdlin_infer_mux
• hdlin_mux_oversize_ratio
• hdlin_mux_size_limit
• hdlin_mux_size_min
The tool marks the MUX_OP cells inferred by this directive with the size_only attribute to
prevent logic decomposition during optimization. This directive infers MUX_OP cells even if
the cells cause loss of resource sharing.
For example,
module test (input [1:0] SEL,
input [3:0] DIN,
output logic DOUT);
always@(SEL or DIN) begin
case (SEL) // synopsys infer_mux_override
2'b00: DOUT <= DIN[0];
2'b01: DOUT <= DIN[1];
2'b10: DOUT <= DIN[2];
2'b11: DOUT <= DIN[3];
endcase
end
endmodule
infer_onehot_mux
Use the infer_onehot_mux directive to map combinational logic to one-hot multiplexers in
the logic library. For details, see “Inferring One-Hot Multiplexer Logic” on page 3-84.
keep_signal_name
Use the keep_signal_name directive to provide Design Compiler with guidelines for
preserving signal names.
The syntax is
// synopsys keep_signal_name "signal_name_list"
Set the keep_signal_name directive on a signal before any reference is made to that signal;
for example, one methodology is to put the directive immediately after the declaration of the
signal.
See Also
• Keeping Signal Names
one_cold
A one-cold implementation indicates that all signals in a group are active-low and that only
one signal can be active at a given time. Synthesis implements the one_cold directive by
omitting a priority circuit in front of the flip-flop. Simulation ignores the directive. The
one_cold directive prevents Design Compiler from implementing priority-encoding logic for
the set and reset signals. Attach this directive to set or reset signals on sequential devices,
using the following syntax:
// synopsys one_cold signal_name_list
one_hot
A one-hot implementation indicates that all signals in a group are active-high and that only
one signal can be active at a given time. Synthesis implements the one_hot directive by
omitting a priority circuit in front of a flip-flop. Simulation ignores the directive. The one_hot
directive prevents Design Compiler from implementing priority-encoding logic for the set and
reset signals. Attach this directive to set or reset signals on sequential devices, using the
following syntax:
// synopsys one_hot signal_name_list
parallel_case
Set the parallel_case directive on a case statement when you know that only one branch
of the case statement will be true at a time. This directive prevents Design Compiler from
building additional logic to ensure the first occurrence of a true branch is executed if more
than one branch were true at one time.
Caution:
Marking a case statement as parallel when it actually is not parallel can cause the
simulation to behave differently from the logic Design Compiler synthesizes
because Design Compiler does not generate priority encoding logic to make sure
that the branch listed first in the case statement takes effect.
Use the parallel_case directive immediately after the case expression. In Example 103,
the states of a state machine are encoded as a one-hot signal; the designer knows that only
one branch is true at a time and therefore sets the synopsys parallel_case directive on
the case statement.
When a case statement is not parallel (more than one branch evaluates to true), priority
encoding is needed to ensure that the branch listed first in the case statement takes effect.
Latches created:
Design Compiler generates logic to test for any value that is
not covered by the case branches and creates an implicit
“default” branch that requires a latch.
preserve_sequential
The preserve_sequential directive allows you to preserve specific cells that would
otherwise be optimized away by Design Compiler. See “Keeping Unloaded Registers” on
page 4-98.
sync_set_reset
Use the sync_set_reset directive to infer a D flip-flop with a synchronous set/reset. When
you compile your design, the SEQGEN inferred by Design Compiler will be mapped to a
flip-flop in the logic library with a synchronous set/reset pin, or Design Compiler will use a
regular D flip-flop and build synchronous set/reset logic in front of the D pin. The choice
depends on which method provides a better optimization result.
It is important to use the sync_set_reset directive to label the set/reset signal because it
tells Design Compiler that the signal should be kept as close to the register as possible
during mapping, preventing a simulation/synthesis mismatch which can occur if the set/reset
signal is masked by an X during initialization in simulation.
When a single-bit signal has this directive set to true, Design Compiler checks the signal to
determine whether it synchronously sets or resets a register in the design. Attach this
directive to single-bit signals. Use the following syntax:
//synopsys sync_set_reset "signal_name_list"
For an example of a D flip-flop with a synchronous set signal that uses the sync_set_reset
directive, see “D Flip-Flop With Synchronous Set: Use sync_set_reset” on page 4-109.
For an example of a D flip-flop with a synchronous reset signal that uses the
sync_set_reset directive, see Example 66 on page 109. For an example of multiple
flip-flops with asynchronous and synchronous controls, see Example 70 on page 112.
sync_set_reset_local
The sync_set_reset_local directive instructs Design Compiler to treat signals listed in a
specified block as if they have the sync_set_reset directive set to true.
Attach this directive to a block label, using the following syntax:
//synopsys sync_set_reset_local block_label "signal_name_list"
always@(posedge clk)
begin: default_rst
if(~rst2)
q2 <= 1'b0;
else if (set2)
q2 <= 1'b1;
else
q2 <= d2;
end
endmodule
sync_set_reset_local_all
The sync_set_reset_local_all directive instructs Design Compiler to treat all signals
listed in the specified blocks as if they have the sync_set_reset directive set to true.
Attach this directive to a block label, using the following syntax:
// synopsys sync_set_reset_local_all "block_label_list"
always@(posedge clk)
begin: default_rst
if(~rst2)
q2 <= 1'b0;
else if (set2)
q2 <= 1'b1;
else
q2 <= d2;
end
endmodule
template
The template directive saves an analyzed file and does not elaborate it. Without this
directive, the analyzed file is saved and elaborated. If you use this directive and your design
contains parameters, the design is saved as a template. Example 106 shows usage.
The SYNTHESIS macro replaces the DC macro (DC is still supported for backward
compatibility). See “Predefined Macros” on page 1-47.
Duplicating Datapaths
To improve the timing of late-arriving signals, you can duplicate datapaths, but at the
expense of more area and increased input loads.
Original RTL
In Example 107, the late-arriving CONTROL signal selects either the PTR1 or PTR2 input,
and then the selected input drives a chain of arithmetic operations ending at output COUNT.
As shown in Figure 26, a SELECT_OP is next to a subtractor. When you see a SELECT_OP
next to an operator, you should duplicate the conditional logic of the SELECT_OP and move
the SELECT_OP to the end of the operation, as shown in Example 108.
SUBTRACTOR ADDER
16
BASE ADDRESS
SELECT_OP
00000000 16
PTR1 8 16 COUNT
B
8 16
PTR2
8
CONTROL
2
input CONTROL,
output [15:0] COUNT
);
wire [7:0] OFFSET1,OFFSET2;
wire [15:0] ADDR1,ADDR2,COUNT1,COUNT2;
assign OFFSET1 = BASE - PTR1; // Could be f(BASE,PTR)
assign OFFSET2 = BASE - PTR2; // Could be f(BASE,PTR)
assign ADDR1 = ADDRESS - {8'h00 , OFFSET1};
assign ADDR2 = ADDRESS - {8'h00 , OFFSET2};
assign COUNT1 = ADDR1 + B;
assign COUNT2 = ADDR2 + B;
assign COUNT = (CONTROL == 1'b1) ? COUNT1 : COUNT2;
endmodule
SUBTRACTOR
SUBTRACTOR
ADDRESS ADDER
Duplicate datapath
BASE
00000000 16
16
SELECT_OP
PTR1 B
8 16
COUNT
ADDRESS
BASE
00000000 16
16
PTR2 B CONTROL 2
8 16
See Also
• Selection and Multiplexing Logic
The following examples show the coding techniques of using the if and case statements
for late-arriving signals:
• Overview
• Late-Arriving Data Signal Example 1
• Late-Arriving Data Signal Example 2
• Late-Arriving Data Signal Example 3
• Late-Arriving Control Signal Example 1
• Late-Arriving Control Signal Example 2
Overview
To better handle late-arriving signals, use sequential if statements to create a
priority-encoded implementation. You assign priority in descending order; that is, the last if
statement corresponds to the data signal of the last SELECT_OP cell in the chain.
sel[2]
0
sel[1]
sel[0]
SELECT_OP x
SELECT_OP
a[0:4]
s
r
q
p
sel[3] 2
0
sel[2] 2 sel[1]
sel[0] sel[2] Control
2 logic 2
sel[3]
C
ADDER
Z
A D
COMPARATOR
2
B
24
Modified RTL
The following RTL restructures the code to move signal A closer to the output.
SUBTRACTOR C
Z
24 COMPARATOR
D
A
B
2
AND
SELECT_OP SELECT_OP
A[2] A[3]
A[6] A[2]
A[7]
Data_late Z
A[1]
A[8] A[4]
A[5]
Control Control
sel logic C
5 logic 6
always_comb
begin
if (C[1])
Z1 = A[5];
else if (C[2] == 1'b0)
Z1= A[4];
else if (C[3])
Z1 = A[1];
else if (C[4])
case (sel)
3'b010: Z1 = A[8];
//3'b011: Z1 = Data_late;
3'b101: Z1 = A[7];
3'b110: Z1 = A[6];
default: Z1 = A[2];
endcase
else if (C[5] == 1'b0)
Z1 = A[2];
else
Z1 = A[3];
assign Z2 = A[4];
assign prev_cond = (C[1] == 1'b1) || (C[2] == 1'b0) || (C[3] == 1'b1);
always_comb
begin
if (C[4] == 1'b1 && Ctrl_late == 1'b0)
if (prev_cond) Z = Z1;
else Z = Z2;
else
Z = Z1;
end
endmodule
Z
C[1:3,5] Control
logic A[4]
5
2
Control C[4] Control
C[1:3]
logic Ctrl_late logic 2
Original RTL
This example shows an if statement nested in a case statement and contains a
late-arriving control signal, sel[1].
always_comb
begin
case (sel)
3'b000: Z = A;
3'b001: Z = B;
3'b010: if (X) Z = C;
else Z = D;
3'b100: Z = A ^ B;
3'b101: Z = !(A && B);
3'b111: Z = !A;
default: Z = !B;
endcase
end
endmodule
Modified RTL
Because signal sel[1] is a late-arriving input, you should restructure the code to get the best
startpoint for synthesis. As shown in the modified RTL, the nested if statement is placed
outside the case statement so that signal sel[1] is closer to output Z. Output Z takes either
value Z1 or Z2 depending on whether signal sel[1] is 0 or 1. When signal sel[1] is late
arriving, placing it closer to output Z improves the timing.
if (sel[1]) Z = Z2;
else Z = Z1;
end
endmodule
See Also
• dc_tcl_script_begin and dc_tcl_script_end
Example 121 RTL for Inferring Master-Slave Latches With Two Pairs of Clocks
module mslatch2 (
input SCK1, SCK2, MCK1, MCK2, D1, D2,
output logic Q1, Q2,
);
// synopsys dc_tcl_script_begin
// set_attribute -type string MCK1 signal_type clocked_on_also
// set_attribute -type boolean MCK1 level_sensitive true
// set_attribute -type string MCK1 associated_clock SCK1
// set_attribute -type string MCK2 signal_type clocked_on_also
// set_attribute -type boolean MCK2 level_sensitive true
// set_attribute -type string MCK2 associated_clock SCK2
// synopsys dc_tcl_script_end
always @ (posedge SCK1) Q1 <= D1;
always @ (posedge SCK2) Q2 <= D2;
endmodule
=========================================================================
| Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST |
=========================================================================
| Q2_reg | Flip-flop | 1 | N | N | N | N | N | N | N |
=========================================================================
endmodule
========================================================================
| Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST |
========================================================================
| Q_reg | Latch | 1 | N | N | N | N | - | - | - |
========================================================================
Syntax
Synopsys supports the Verilog syntax as described in the IEEE Std 1364-2005.
The lexical conventions Design Compiler uses are described in the following sections:
• Comments
• Numbers
Comments
You can enter comments anywhere in a Verilog description, in two forms:
• Beginning with two slashes //
Design Compiler ignores all text between these characters and the end of the current
line.
• Beginning with the two characters /* and ending with */
Design Compiler ignores all text between these characters, so you can continue
comments over more than one line.
Note:
You cannot nest comments.
Numbers
You can declare numbers in several different radices and bit-widths. A radix is the base
number on which a numbering system is built. For example, the binary numbering system
has a radix of 2, octal has a radix of 8, and decimal has a radix of 10.
You can use these three number formats:
• A simple decimal number that is a sequence of digits in the range of 0 to 9. All constants
declared this way are assumed to be 32-bit numbers.
• A number that specifies the bit-width as well as the radix. These numbers are the same
as those in the previous format, except that they are preceded by a decimal number that
specifies the bit-width.
• A number followed by a two-character sequence prefix that specifies the number’s size
and radix. The radix determines which symbols you can include in the number.
Constants declared this way are assumed to be 32-bit numbers. Any of these numbers
can include underscores ( _ ), which improve readability and do not affect the value of
the number. Table 14 summarizes the available radices and valid characters for the
number.
Table 14 Verilog Radices
Binary ’b 01xXzZ_?
Octal ’o 0–7 x X z Z _ ?
Decimal ’d 0–9 _
Verilog Keywords
Table 15 lists the Verilog keywords. You cannot use these words as user variable names
unless you use an escape identifier.
Caution:
Configuration-related keywords are not treated as keywords outside of
configurations. Design Compiler does not support configurations at this time.
◦ forever statement (The forever loop is only supported if it has an associated disable
condition, making the exit condition deterministic.)
◦ fork statement
◦ deassign statement
◦ force statement
◦ release statement
• Unsupported operators
◦ Case equality and inequality operators (=== and !==)
• Unsupported gate-level constructs
◦ nmos, pmos, cmos, rnmos, rpmos, rcmos
◦ pullup, pulldown, tranif0, tranif1, rtran, rtrainf0, and rtrainf1 gate types
• Unsupported miscellaneous constructs
◦ hierarchical names within a module
If you use an unsupported construct, Design Compiler issues a syntax error such as
event is not supported
always Blocks
The tool does not support more than one independent if block when asynchronous
behavior is modeled within an always block. If the always block is purely synchronous, the
tool supports multiple independent if blocks. In addition, the tool does not support more
than one conditional operator (?:) inside an always block.
Note:
If an always block is very small, the tool might move the logic inside the block
during synthesis.
generate Statements
Synopsys support of the generate statement is described in the following sections:
• Generate Overview
• Restrictions
Generate Overview
Design Compiler supports both the 2001 and the 2005 standards for the generate
statement. The default is the 2005 standard; to enable the 2001 standard, set the
hdlin_vrlg_std variable to 2001. The following subsections describe the naming-style
differences between these two standards.
When you use the 2001 standard, Design Compiler creates the name b1.U1 for mod 1:
Cell Reference Library Area Attributes
-------------------------------------------------------------------
b1.U1 mod1 0.000000 b
-------------------------------------------------------------------
Total 1 cells 0.000000
When you use the 2005 standard, Design Compiler issues a VER-946 error message:
Compiling source file RTL/t1.v
Error: RTL/t1.v:3: Syntax error on an obsolete Verilog 2001 construct
standalone generate block 'b1'. (VER-946)
*** Presto compilation terminated with 1 errors. ***
if( 1 )
if( 1 )
mod1 U1(in1[I], out1[I]);
end
end
endgenerate
endmodule
When you use the Verilog 2001 standard, Design Compiler creates the names b1[0].b2.U1,
b1[1].b2.U1, and b1[2].b2.U1 for the instantiated subblocks:
Cell Reference Library Area Attributes
-------------------------------------------------------------------------
b1[0].b2.U1 mod1 0.000000 b
b1[1].b2.U1 mod1 0.000000 b
b1[2].b2.U1 mod1 0.000000 b
-------------------------------------------------------------------------
Total 3 cells 0.000000
When you use the Verilog 2005 standard, Design Compiler creates the names
b1[0].b2.genblk1.U1, b1[1].b2.genblk1.U1, and b1[2].b2.genblk1.U1. Note that there are no
multiple genblk1's for the nested anonymous if blocks:
Cell Reference Library Area Attributes
-------------------------------------------------------------------------
b1[0].b2.genblk1.U1 mod1 0.000000 b
b1[1].b2.genblk1.U1 mod1 0.000000 b
b1[2].b2.genblk1.U1 mod1 0.000000 b
-------------------------------------------------------------------------
Total 3 cells 0.000000
Another type of anonymous generate block is created when the block does not have a
label, but each block has a begin ...end statement:
endgenerate
endmodule
When you use the 2001 standard, Design Compiler creates the names b1[0].b2.U1,
b1[1].b2.U1, and b1[2].b2.U1 for the instantiated subblocks:
Cell Reference Library Area Attributes
-------------------------------------------------------------------------
b1[0].b2.U1 mod1 0.000000 b
b1[1].b2.U1 mod1 0.000000 b
b1[2].b2.U1 mod1 0.000000 b
-------------------------------------------------------------------------
Total 3 cells 0.000000
When you use the 2005 standard, the tool creates the names
b1[0].b2.genblk1.genblk1.genblk1.U1, b1[1].b2.genblk1.genblk1.genblk1.U1,
b1[2].b2.genblk1.genblk1.genblk1.U1:
Cell Reference Library Area Attributes
-------------------------------------------------------------------------
b1[0].b2.genblk1.genblk1.genblk1.U1
mod1 0.000000 b
b1[1].b2.genblk1.genblk1.genblk1.U1
mod1 0.000000 b
b1[2].b2.genblk1.genblk1.genblk1.U1
mod1 0.000000 b
-------------------------------------------------------------------------
Total 3 cells 0.000000
Note that there is a genblk1 for each of the nested begin...end if blocks that creates a new
scope.
The following example illustrates how scope creation can produce an error under the Verilog
2005 standard from code that compiles cleanly under the Verilog 2001 standard:
Under the Verilog 2001 standard, w is visible in the assign statement, but under the Verilog
2005 standard, scope creation makes w invisible outside the generate block, and Design
Compiler issues an error message:
Error: RTL/t5.v:5: The symbol 'w' is not defined. (VER-956)
generate
for (i=0; i < 3; i=i+1) begin : loop1
for (j=0; j < 2; j=j+1) begin : loop2
if (j == param1) begin : if1_label
memory U_00 (D1,clk,Q1);
end
if (j == param2) begin : if2_label
memory U_00 (D1,clk,Q1);
end
end //loop2
end //loop1
endgenerate
endmodule
In this case, the instance name is the same under both standards:
Cell Reference Library Area Attributes
-------------------------------------------------------------------------
loop1[0].loop2[0].if1_label.U_00
memory 0.000000 b
loop1[0].loop2[1].if2_label.U_00
memory 0.000000 b
loop1[1].loop2[0].if1_label.U_00
memory 0.000000 b
loop1[1].loop2[1].if2_label.U_00
memory 0.000000 b
loop1[2].loop2[0].if1_label.U_00
memory 0.000000 b
loop1[2].loop2[1].if2_label.U_00
memory 0.000000 b
-------------------------------------------------------------------------
Total 6 cells
Restrictions
• Hierarchical Names (Cross Module Reference)
In such cases, Design Compiler marks the adders as sharable; Design Compiler determines
the final implementation during timing-drive resource sharing.
The tool does not support more than one ?: operator inside an always block. For more
information, see “always Blocks” on page B-170.
Case
The case construct is discussed in the following sections:
• casez and casex
• Full Case and Parallel Case
The same holds true for casex statements using x, ?, and z. The code
casex (a)
2’b1x : // matches 2’b10 and 2’b11
endcase
When x is assigned to a variable and the variable is used in a casex item, the x does not
match both 0 and 1 as it would for a literal x listed in the case item.
In Example 133, the case statement is not parallel or full, because the values of inputs w and
x cannot be determined.
Example 133 A case Statement That Is Not Full and Not Parallel
always @(w or x) begin
case (2’b11)
w:
b = 10 ;
x:
b = 01 ;
endcase
end
However, if you know that only one of the inputs equals 2’b11 at a given time, you can use
the parallel_case directive to avoid synthesizing an unnecessary priority encoder.
If you know that either w or x always equals 2’b11 (a situation known as a one-branch tree),
you can use the full_case directive to avoid synthesizing an unnecessary latch. A latch is
necessary whenever a variable is conditionally assigned. Marking a case as full tells the
compiler that some branch will be taken, so there is no need for an implicit default branch. If
a variable is assigned in all branches of the case, Design Compiler then knows that the
variable is not conditionally assigned in that case, and, therefore, that particular case
statement does not result in a latch for that variable.
However, if the variable is assigned in only some branches of the case statement, a latch is
still required as shown in Example 134. In addition, other case statements might cause a
latch to be inferred for the same variable.
defparam
Use of defparam is highly discouraged in synthesis because of ambiguity problems.
Because of these problems, defparam is not supported inside generate blocks. For details,
see the Verilog LRM.
disable
Design Compiler supports the disable statement when you use it in named blocks and when
it is used to disable an enclosing block. When a disable statement is executed, it causes the
named block to terminate. You cannot disable a block that is not in the same always block
or task as the disable statement. A comparator description that uses disable is shown in
Example 135.
You can also use a disable statement to implement a synchronous reset, as shown in
Example 136.
Example 136 Synchronous Reset of State Register Using disable in a forever Loop
always
begin: test
@ (posedge clk)
if (Reset)
begin
z <= 1’b0;
disable test;
end
z <= a;
end
The disable statement in Example 136 causes the test block to terminate immediately and
return to the beginning of the block.
Design Compiler does not permit this and generates an error message.
During simulation, race conditions can result from blocking assignments, as shown in
Example 137. In this example, the value of x is indeterminate, because multiple procedural
blocks run concurrently, causing y to be loaded into x at the same time z is loading into y.
The value of x after the first @ (posedge clk) is indeterminate. Use of nonblocking
assignments solves this race condition, as shown in Example 138.
In Example 137 and Example 138, Design Compiler creates the gates shown in Figure 36.
If you want to switch register values, use nonblocking assignments, because blocking
assignments will not accomplish the switch. For example, in Example 139, the desired
outcome is a swap of the x and y register values. However, after the positive clock edge, y
does not end up with the value of x; y ends up with the original value of y. This happens
because blocking statements are order dependent and each statement within the
procedural block is executed before the next statement is evaluated and executed. In
Example 140, the swap is accomplished with nonblocking assignments.
Macromodule
Design Compiler treats the macromodule construct as a module construct. Whether you use
module or macromodule, the synthesis results are the same.
`define
The `define directive can specify macros that take arguments. For example,
`define BYTE_TO_BITS(arg)((arg) << 3)
The `define directive can do more than simple text substitution. It can also take arguments
and substitute their values in its replacement text.
Macro substitution assigns a string of text to a macro variable. The string of text is inserted
into the code where the macro is encountered. The definition begins with the back quotation
mark (`), followed by the keyword define, followed by the name of the macro variable. All
text from the macro variable until the end of the line is assigned to the macro variable.
You can declare and use macro variables anywhere in the description. The definitions can
carry across several files that are read into Design Compiler at the same time. To make a
macro substitution, type a back quotation mark (`) followed by the macro variable name.
Some example macro variable declarations are shown in Example 141.
The analyze -define command allows macro definition on the command line. Only one
-define per analyze command is allowed but the argument can be a list of macros, as
shown in Example 142.
Note:
When using the -define option with multiple analyze commands, you must
remove any designs in memory before analyzing the design again. To remove the
designs, use
remove_design -all. Because elaborated designs in memory have no
timestamps, the tool cannot determine whether the analyzed file has been
updated or not. The tool might assume that the previously elaborated design is
up-to-date and reuse it.
Curly brackets are not required to enclose one macro, as shown in Example 143. However,
if the argument is a list of macros, curly brackets are required.
See Also
• Predefined Macros
`include
The `include construct in Verilog is similar to the #include directive in the C language.
You can use this construct to include Verilog code, such as type declarations and functions,
from one module in another module. Example 144 shows an application of the `include
construct.
Contents of file2.v
module secondfile (clk, in1, in2, out);
`include "file1.v"
. . .
wire [`WORDSIZE-1:0] temp;
assign temp = fastadder (in1,in2);
. . .
endmodule
Included files can include other files, with up to 24 levels of nesting. You cannot use the
`include construct recursively.
When your design contains multiple files for multiple subblocks and include files for
subblocks, in their respective sub directories, you can elaborate the top-level design without
making any changes to the search path. The tool will automatically find the include files. For
example, if your structure is as follows:
Rtl/top.v
Rtl/sub_module1/sub_module1.v
Rtl/sub_module2/sub_module2.v
Rtl/sub_module1/sub_module1_inc.v
Rtl/sub_module2/sub_module2_inc.v
You do not need to add Rtl/sub_module1/ and Rtl/sub_module2/ to your search path to
enable the tool to find the include files sub_module1_inc.v and sub_module2_inc.v when
you elaborate top.v.
Example 145 illustrates usage. Use the `define directive to define the macros that are
arguments to the `ifdef directive; see `define.
`else
module selective_design(a,b,c);
input a, b;
output c;
assign c = a | b;
endmodule
`endif
For more information and an example, see Specifying Relative Placement Groups.
`rp_place
The `rp_place directive allows you to specify a subgroup at a specific hierarchy, a keepout
region, or an instance to be placed in the current relative placement group. When you use
the `rp_place directive to specify a subgroup at a specific hierarchy, you must instantiate
the subgroup’s instances outside of any group declarations in the module. This directive is
available for RTL designs and netlist designs.
The Verilog syntax for RTL designs is as follows:
‘rp_place ( hier group_name col row )
‘rp_place ( keep keepout_name col row width height )
‘rp_place ({leaf} [inst_name] col row )
For more information and examples, see Specifying Subgroups, Keepouts, and Instances.
`rp_fill
The `rp_fill directive automatically places the cells at the location specified by a pointer.
Each time a new instance is declared that is not explicitly placed, it is inserted into the grid
at the location indicated by the current value of the pointer. After the instance is placed, the
pointer is updated incrementally and the process is ready to be repeated. This directive is
available for RTL designs and netlist designs.
The `rp_fill arguments define how the pointer is updated. The col and row parameters
specify the initial coordinates of the pointer. These parameters can represent absolute row
or column locations in the group’s grid or locations that are relative to the current pointer
value. To represent locations relative to the current pointer, enclose the column and row
values in angle brackets (<>). For example, assume the current pointer location is (3,4). In
this case, specifying rp_fill <1> 0 initializes the pointer to (4,0) and that is where the next
instance is placed. Absolute coordinates must be nonnegative integers; relative coordinates
can be any integer.
The Verilog syntax for RTL designs is as follows:
‘rp_fill ( {col row} {pattern pat} )
For more information and an example, see Enabling Automatic Cell Placement.
`rp_array_dir
Note:
This directive is available for creating relative placement in RTL designs but not
in netlist designs.
The `rp_array_dir directive specifies whether the elements of an array are placed
upward, from the least significant bit to the most significant bit, or downward, from the most
significant bit to the least significant bit.
The Verilog syntax for RTL designs is as follows:
`rp_array_dir ( up|down )
For more information and an example, see Specifying Placement for Array Elements.
rp_align
The rp_align directive explicitly specifies the alignment of the placed instance within the
grid cell when the instance is smaller than the cell. If you specify the optional inst instance
name argument, the alignment applies only to that instance; however, if you do not specify
an instance, the new alignment applies to all subsequent instantiations within the group until
Design Compiler encounters another rp_align directive. If the instance straddles cells, the
alignment takes place within the straddled region. The alignment value is sw (southwest) by
default. The instance is snapped to legal row and routing grid coordinates.
Use the following syntax for netlist designs:
//synopsys rp_align ( n|s|e|w|nw|sw|ne|se|pin=name { inst })
Note:
This directive is available for creating relative placement in netlist designs only.
rp_orient
Note:
This directive is available for creating relative placement in netlist designs only.
The rp_orient directive allows you to control the orientation of library cells placed in the
current group. When you specify a list of possible orientations, Design Compiler chooses the
first legal orientation for the cell.
Use the following syntax for netlist designs:
//synopsys rp_orient ( {N|W|S|E|FN|FW|FS|FE}* { inst } )
//synopsys
rp_orient ( {N|W|S|E|FN|FW|FS|FE}* { group_name inst } ))
The rp_ignore and rp_endignore directives allow you to ignore specified lines in the input
file. Any lines between the two directives are omitted from relative placement. The include
and define directives, variable substitution, and cell mapping are not ignored.
The rp_ignore and rp_endignore directives allow you to include the instantiation of
submodules in a relative placement group close to the rp_place hier group(inst)
location to place relative placement array.
Use the following syntax for netlist designs:
//synopsys rp_ignore
//synopsys rp_endignore
`undef
The `undef directive resets the macro immediately following it.
reg Types
The Verilog language requires that any value assigned inside an always statement must be
declared as a reg type. Design Compiler returns an error if any value assigned inside an
always block is not declared as a reg type.
Types in Busing
Design Compiler maintains types throughout a design, including types for buses (vectors).
Example 146 shows a Verilog design read into Design Compiler containing a bit vector that
is NOTed into another bit vector.
assign b = ~a;
endmodule
Example 147 shows the same description written out by Design Compiler. The description
contains the original Verilog types of ports. Internal nets do not maintain their original bus
types. Also, the NOT operation is instantiated as single bits.
To support this loop, Design Compiler interprets it like a simulator. The tool stops when the
loop termination condition is known to be false. Because Design Compiler can’t determine
when a loop is infinite, it stops and reports an error after an arbitrary (but user-defined)
number of iterations (the default is 1024).
To exit the loop, Design Compiler allows additional conditions in the loop condition that
permit more concise descriptions.
for (i = 0; i < 10 && a[i]; i = i+1) begin
// loop body
end
A loop must unconditionally make progress toward termination in each trip through the loop,
or it cannot be compiled. The following example makes progress (that is, increments i) only
when !done is true and does not terminate.
while ( i < 10 ) begin
if ( ! done )
done = a[i];
// loop body
i = i + 1;
end
end
The following modified version, which unconditionally increments i, will terminate. This code
creates the desired logic.
while ( i < 10 ) begin
if ( ! done ) begin
done = a[i];
end// loop body
i = i + 1;
end
In the next example, loop termination depends on reading values stored in x. If the value is
unknown (as in the first and third iterations), Design Compiler assumes it might be true and
generates logic to test it.
x[0] = v; // Value unknown: implies “if(v)”
x[1] = 1; // Known TRUE: no guard on 2nd trip
x[2] = w; // Not known: implies “if(w)”
x[3] = 0; // Known FALSE: stop the loop
i = 0;
while( x[i] ) begin
// loop body
i = i + 1;
end
This code terminates after three iterations when the loop tests x[3], which contains 0.
In Example 148, a supported combinational while loop, the code produces gates, and an
event control signal is not necessary.
In Example 149, a supported combinational while loop, no matter what x is, the loop will run
for 16 iterations at most because Design Compiler can keep track of which bits of x are
constant. Even though it doesn't know the initial value of x, it does know that x >> 1 has a
zero in the most significant bit (MSB). The next time x is shifted right, it knows that x has two
zeros in the MSB, and so on. Design Compiler can determine when x becomes all zeros.
In Example 150, a supported combinational while loop, Design Compiler knows the initial
value of x and can determine x+1 and all subsequent values of x.
In Example 151, Design Compiler cannot detect the initial value of i and so cannot support
this while loop. Example 152 is supported because i is determinable.
Feature Description
Feature Description
Ignored Constructs
The following sections include directives that Design Compiler accepts but ignores.
Simulation Directives
The following directives are special commands that affect the operation of the Verilog HDL
simulator:
'accelerate
'celldefine
'default_nettype
'endcelldefine
'endprotect
'expand_vectornets
'noaccelerate
'noexpand_vectornets
'noremove_netnames
'nounconnected_drive
'protect
'remove_netnames
'resetall
'timescale
'unconnected_drive
You can include these directives in your design description; Design Compiler accepts but
ignores them.
Verilog 2001 allows more than one level of subscripting on a variable, without use of a
temporary variable.
Signed Quantities
Design Compiler supports signed arithmetic extensions. Function returns and reg and net
data types can be declared as signed. This added functionality is shown in the following
examples.
Example 157 results in a sign extension, that is, z[0] connects to a[0].
In Example 158, because 3’sb111 is signed, the tool infers a signed adder. In the generic
netlist, the ADD_TC_OP cell denotes a 2’s complement adder and z[0] will not be logic 0.
always begin
x = a;
z = x < 4’sd5;
end
endmodule
In Example 160, because in1, in2, and out are signed, a signed multiplier
(MULT_TC_OP_8_8_8) is inferred.
It also adds support for signed, sized constants. For example, 8'sb11111111 is an 8-bit
signed quantity representing -1. If you are assigning it to a variable that is 8 bits or less,
8'sb11111111 is the same as the unsigned 8'b11111111. A behavior difference arises when
the variable being assigned to is larger than the constant. This difference occurs because
signed quantities are extended with the high-order bit of the constant, whereas unsigned
quantities are extended with 0s. When used in expressions, the sign of the constant helps
determine whether the operation is performed as signed or unsigned.
Design Compiler enables signed types by default.
Note:
If you use the signed keyword, any signed constant in your code, or explicit type
casting between signed and unsigned types, Design Compiler issues a warning.
The syntax specifies a variable base address and a known constant number of bits to be
extracted. The base address is always written on the left, regardless of the declared
direction of the array. The language allows variable part-select on the left side and the right
side of an expression. All of the following expressions are allowed:
• data_out = array_expn[index_var +: 3]
(part select is on the right side)
• data_out = array_expn[index_var -: 3]
(part select is on the right side)
• array_expn[index_var +: 3] = data_in
(part select is on the left side)
• array_expn[index_var -: 3] = data_in
(part select is on the left side)
This table shows examples of Verilog 2001 syntax and the equivalent Verilog 1995 syntax.
The original Design Compiler tool allows nonconstant part-selects if the width is constant;
Design Compiler permits only the new syntax.
The value of Index_Var determines the starting point for the bits selected. In the following
table, the bits selected are shown as a function of Index_Var.
Ascending_Array [ 0 1 2 3 4 5 6 7 ]
Index_Var = 2 • • • • • • • •
Index_Var = 3 • • • • • • • •
Index_Var = 4 • • • • • • • •
Index_Var = 5 • • • • • • • •
Index_Var = 6 • • • • • • • •
Index_Var = 7 • • • • • • • •
The value of Index_Var determines the starting point for the bits selected. In the following
table, the bits selected are shown as a function of Index_Var.
Ascending_Array [ 0 1 2 3 4 5 6 7 ]
Index_Var = 0 • • • • • • • •
Index_Var = 1 • • • • • • • •
Ascending_Array [ 0 1 2 3 4 5 6 7 ]
Index_Var = 2 • • • • • • • •
Index_Var = 3 • • • • • • • •
Index_Var = 4 • • • • • • • •
Index_Var = 5 • • • • • • • •
Note:
• Ascending_Array[Index_Var +: 3] is functionally equivalent to the following part-select
that is not computable: Ascending_Array[Index_Var : Index_Var + 2]
• Noncomputable part-selects are not supported by the Verilog language.
Ascending_Array[7 +:3] corresponds to elements Ascending_Array[7 : 9] but elements
Ascending_Array[8] and Ascending_Array[9] do not exist. A variable part-select must
always compute to a valid index; otherwise, a synthesis elaborate error and a runtime
simulation error will result.
The value of Index_Var determines the starting point for the bits selected. In the following
table, the bits selected are shown as a function of Index_Var.
Descending_Array [ 7 6 5 4 3 2 1 0 ]
Index_Var = 2 • • • • • • • •
Index_Var = 3 • • • • • • • •
Descending_Array [ 7 6 5 4 3 2 1 0 ]
Index_Var = 4 • • • • • • • •
Index_Var = 5 • • • • • • • •
Index_Var = 6 • • • • • • • •
Index_Var = 7 • • • • • • • •
The value of Index_Var determines the starting point for the bits selected. In the following
table, the bits selected are shown as a function of Index_Var.
Descending_Array [ 7 6 5 4 3 2 1 0 ]
Index_Var = 0 • • • • • • • •
Index_Var = 1 • • • • • • • •
Index_Var = 2 • • • • • • • •
Index_Var = 3 • • • • • • • •
Index_Var = 4 • • • • • • • •
Index_Var = 5 • • • • • • • •
Descending_Array [ 7 6 5 4 3 2 1 0 ]
assign z = 2 ** a;
assign x = a ** 2;
assign y = b ** c; // where b and c are constants
endmodule
Q = A >>> S;
end
endmodule
Zero Replication
According to the Verilog 2005 LRM, a replication operation with a zero replication constant
is considered to have a size of zero and is ignored. Such an operation can appear only
within a concatenation in which at least one of the operands of the concatenation has a
positive size.
Zero replication can be useful for parameterized designs. In the following example, the valid
values for parameter P are 1 to 32.
module top #(parameter P = 32) ( input [32-1:0]a, output [32-1:0] b);
assign b = {{32-P{1'b1}}, a[P-1:0]};
endmodule
When the hdlin_vrlg_std variable is set to 2005, and you analyze replication operations
whose elaboration-time constant is zero or negative, the repeated expressions elaborate
once (for their side-effects). But they do not contribute result values to a surrounding
concatenation or assignment pattern. The Verilog 2005 standard permits such empty
replication results only within an otherwise nonempty concatenation
Note:
Nonstandard replication operations that are analyzed when the Verilog version is
set to 1995 or 2001 return 1'b0. This is compatible with an extension made by
Synopsys Verilog products of that era.
anonymous type
A predefined or underlying type with no name, such as universal integers.
ASIC
Application-specific integrated circuit.
behavioral view
The set of Verilog statements that describe the behavior of a design by using sequential
statements. These statements are similar in expressive capability to those found in many
other programming languages. See also the data flow view, sequential statement, and
structural view definitions.
bit-width
The width of a variable, signal, or expression in bits. For example, the bit-width of the
constant 5 is 3 bits.
character literal
Any value of type CHARACTER, in single quotation marks.
computable
Any expression whose (constant) value Design Compiler can determine during
translation.
constraints
The designer’s specification of design performance goals. Design Compiler uses
constraints to direct the optimization of a design to meet area and timing goals.
convert
To change one type to another. Only integer types and subtypes are convertible, along
with same-size arrays of convertible element types.
data flow view
The set of Verilog statements that describe the behavior of a design by using concurrent
statements. These descriptions are usually at the level of Boolean equations combined
with other operators and function calls. See also the behavioral view and structural view.
design constraints
See constraints.
flip-flop
An edge-sensitive memory device.
HDL
Hardware Description Language.
Design Compiler
The Synopsys Verilog synthesis product.
identifier
A sequence of letters, underscores, and numbers. An identifier cannot be a Verilog
reserved word, such as type or loop. An identifier must begin with a letter or an
underscore.
latch
A level-sensitive memory device.
netlist
A network of connected components that together define a design.
optimization
The modification of a design in an attempt to improve some performance aspect. Design
Compiler optimizes designs and tries to meet specified design constraints for area and
speed.
port
A signal declared in the interface list of an entity.
reduction operator
An operator that takes an array of bits and produces a single-bit result, namely the result
of the operator applied to each successive pair of array elements.
register
A memory device containing one or more flip-flops or latches used to hold a value.
resource sharing
The assignment of a similar Verilog operation (for example, +) to a common netlist cell.
Netlist cells are the resources—they are equivalent to built hardware.
RTL
Register transfer level, a set of structural and data flow statements.
sequential statement
A set of Verilog statements that execute in sequence.
signal
An electrical quantity that can be used to transmit information. A signal is declared with
a type and receives its value from one or more drivers. Signals are created in Verilog
through either wire or reg declarations.
signed value
A value that can be positive, zero, or negative.
structural view
The set of Verilog statements used to instantiate primitive and hierarchical components
in a design. A Verilog design at the structural level is also called a netlist. See also
behavioral view and data flow view.
subtype
A type declared as a constrained version of another type.
synthesis
The creation of optimized circuits from a high-level description. When Verilog is used,
synthesis is a two-step process: translation from Verilog to gates by Design Compiler
and optimization of those gates for a specific ASIC library with Design Compiler.
translation
The mapping of high-level language constructs onto a lower-level form. Design Compiler
translates RTL Verilog descriptions to gates.
type
In Verilog, the mechanism by which objects are restricted in the values they are assigned
and the operations that can be applied to them.
unsigned
A value that can be only positive or zero.