blob: 2d18df197146a840536adce34621ed1bbfc3645d [file] [view]
<!-- mdformat global-off -->
<!-- DO NOT EDIT -->
<!-- This file was automatically generated by sanitize.py -->
<a id="google-verilog-style-guide"></a>
# Google Verilog Style Guide
<!-- mdformat off -->
* TOC
{:toc}
<!-- mdformat on -->
<a id="basics"></a>
## Basics
<a id="basics-summary"></a>
### Summary
Verilog is the main logic design language at Google.
Verilog can be written in vastly different styles, which can lead to code
conflicts and code review latency. This style guide aims to promote Verilog
readability across groups. To quote the C++ style guide: "Creating common,
required idioms and patterns makes code much easier to understand."
This guide defines a Google style for Verilog. The goals are to:
* promote consistency across hardware development projects
* promote best practices
* increase code sharing and reuse
This style guide defines style for SystemVerilog compliant code. Additionally,
this style guide defines style for both synthesizable and testbench code.
<a id="terminology-conventions"></a>
### Terminology Conventions
Unless otherwise noted, the following terminology conventions apply to this
style guide:
* The word ***must*** indicates a mandatory requirement. Similarly, ***do
not*** indicates a prohibition. Imperative and declarative statements
correspond to ***must***.
* The word ***recommended*** indicates that a certain course of action is
preferred or is most suitable. Similarly, ***not recommended*** indicates
that a course of action is unsuitable, but not prohibited. There may be
reasons to use other options, but the implications and reasons for doing so
must be fully understood.
* The word ***may*** indicates a course of action is permitted and optional.
* The word ***can*** indicates a course of action is possible given material,
physical, or causal constraints.
<a id="style-linter"></a>
### Style Linter
The following Style Linter tools can be used to automatically check the code for
violations to the mandatory requirements of this Style Guide:
* [Verible Verilog Style Linter](https://github.com/chipsalliance/verible/tree/master/verible/verilog/tools/lint)
<a id="style-guide-exceptions"></a>
### Style Guide Exceptions
<span class="Summary">Justify all exceptions with a comment.</span>
No style guide is perfect. There are times when the best path to a working
design, or for working around a tool issue, is to simply cut the Gordian Knot
and create code that is at variance with this style guide. It is always okay to
deviate from the style guide by necessity, as long as that necessity is clearly
justified by a brief comment, as well as a [Style Linter](#style-linter) waiver
pragma where appropriate.
<a id="inclusive-language"></a>
### Inclusive Language
In all code, including naming and comments, use inclusive language and avoid
terms that others might find disrespectful or offensive (such as "master" and
"slave", "blacklist" and "whitelist", or "redline"), even if the terms also have
an ostensibly neutral meaning. Similarly, use gender-neutral language unless
you're referring to a specific person (and using their pronouns). For example,
use "they", "them", or "their" for people of unspecified gender (even when
singular), and "it" or "its" for software, computers, and other things that
aren't people.
The [bus protocols](#bus-protocol-naming) section has additional conventions for
replacing non-inclusive terms in that common case.
#### Non-Inclusive Language in External IP
In some cases, non-inclusive terms are embedded in industry standards or third
party IP (or similar) as names or keywords. Whenever possible, minimize your use
of the term (hence avoid propagating it as a term of art), while still providing
clear documentation to your readers.
Common Scenarios and Preferred Approaches:
* A third party IP's top level module or port names include non-inclusive
terms. Create a wrapper for that top level module that replaces the
non-inclusive terms with preferred terminology. In the wrapper, clearly
document the terminology mapping. All uses of that module instantiate the
wrapper rather than directly instantiating the problematic module. Do not
modify the third party code directly.
* An industry standard interface names its signals with non-inclusive terms.
When using that standard, use preferred terminology in the code. In comments
adjacent to the signal declarations, document the terminology mapping.
<a id="which-verilog-to-use"></a>
### Which Verilog to Use
<span class="Summary">Prefer SystemVerilog-2017.</span>
All RTL and tests must be developed in SystemVerilog, following the
[SystemVerilog-2017 standard].
[SystemVerilog-2017 standard]: https://ieeexplore.ieee.org/document/8299595
<a id="what-about-vhdl"></a>
### What about VHDL?
<span class="Summary">Google uses Verilog for logic design.</span>
Precedent has already been established that Verilog is the choice for logic
design at Google.
<a id="reusable-ip"></a>
### Reusable IP
<span class="Summary">Common RTL that is intended to be used across multiple
projects is referred to as reusable IP.</span>
<a id="project_conventions"></a>
<a id="file-conventions"></a>
## File Conventions
<a id="file-conventions-summary"></a>
### Summary
This section covers file conventions, mostly how files are to be
[named](#file-names).
<a id="file-extensions"></a>
### File Extensions
<span class="Summary">Use `.sv` and `.svh` file extensions for SystemVerilog
files.</span>
File extensions have the following meanings:
* `.sv` indicates a SystemVerilog file defining a module or package.
* `.svh` indicates a SystemVerilog [global macro file](#global-macro-files) or
[include file](#include-files).
* `.v` indicates a Verilog-2001 file defining a module or package.
* `.vh` indicates a Verilog-2001 [global macro file](#global-macro-files) or
[include file](#include-files).
<a id="file-names"></a>
### File Names
<span class="Summary">File names must match the design element name and indicate
the Verilog dialect.</span>
If a source file declares a design element, the file name must begin with the
name of that design element. For example, a file declaring a module named
`interconnect` must be named `interconnect.sv`.
Declare only one design element per file. As per IEEE 1800-2017 section 3.2, a
design element may be either a module, package, program, interface, checker,
primitive, or configuration.
For variants of a design element, it is permissible to insert dot-delimited
strings between the design element name and the file extension to indicate the
particular variant contained in that file. For example, a file containing a
gate-level model of an interconnect module might be named
`interconnect.gate.sv`.
<a id="standard-files"></a>
### Standard Design Files
<span class="Summary">The following filenames are special: `[design]_top.sv`,
`[design]_pkg.sv`. </span>
Each design must have two standard files, `[design]_top.sv` and
`[design]_pkg.sv`, where `[design]` is the unique name of the design.
* `[design]_top.sv` is the top-level module of the design.
* `[design]_pkg.sv` defines a package named `[design]_pkg` containing
declarations related to the design.
A "design" here is one of the following hierarchical elements: project top,
cluster (a collection of design blocks) or a design block.
A "design block" is the fundamental architecture or microarchitecture building
block of the design. Every design block has its black box behavior fully
specified. In particular, a design block’s interfaces are fully specified in the
documentation (both the port list and the behavior of every port).
<a id="file-structure"></a>
### File Structure
<span class="Summary">The overall structure of a SystemVerilog file must start
with the [header](#header), followed by the declaration and then the
implementation.</span>
<a id="header"></a>
#### Header Comment
<span class="Summary">Every file must start with a header comment.</span>
A header comment contains a short description of the design element, explaining
what problem it solves. Additional text must give an overview of any non-obvious
parts of the theory of operation of this particular implementation.
<a id="basic-template"></a>
### Basic Template
<span class="Summary">A template that demonstrates many of the items detailed
throughout the style guide.</span>
Template:
<div class='goodcode'></div>
```verilog
// A quick description of the design element goes here. What its intent is,
// and a general theory of operation.
module my_module #(
parameter int Width = 80,
parameter int Height = 24
) (
input logic clk,
input logic rst,
...
);
...
endmodule
```
<a id="generated-code"></a>
### Generated Code
<span class="Summary">Generated code must be accompanied by all necessary input
files and scripts necessary to automatically reproduce the generated
output.</span>
Generators include Verilog preprocessors and programs that create Verilog from
other sources like Haskell, Chisel, C or C++.
Code generation tools that operate in-place on Verilog files must not strip out
the generating macros, and must preserve those recipes within the file (in other
words, as comments). Code generators that operate in this fashion must be
idempotent and repeatable.
Comments wrapped in `/**` and `**/` comment lines are reserved for use by
generators.
Generated code must meet the style guidelines.
<a id="formatting"></a>
## Aesthetics and Formatting
<a id="formatting-summary"></a>
### Summary
The Aesthetics and Formatting section addresses purely aesthetic aspects of
style, primarily:
- [Wrap lines at 100 characters](#line-length).
- [Indentation is two spaces per level](#indentation), [no tabs](#tabs).
- [Space-delimit all keywords and binary operators](#spacing).
- [Prefer `// Comment` style comments](#comments).
<a id="general-file-appearance"></a>
### General File Appearance
<a id="characters"></a>
#### Characters
<span class="Summary">Use only ASCII characters with UNIX-style line
endings("\\n").</span>
<a id="posix-file-endings"></a>
#### POSIX File Endings
<span class="Summary">All lines on non-empty files must end with a newline
("\\n").</span>
The
[POSIX standard](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206)
mandates that lines end with a newline character. This includes the final line
in every file.
<a id="line-length"></a>
#### Line Length
<span class="Summary">Wrap the code at 100 characters per line.</span>
The maximum line length for style-compliant Verilog code is 100 characters per
line.
Exceptions:
- Any place where line wraps are impossible (for example, an include path
might extend past 100 characters).
[Line-wrapping](#line-wrapping) contains additional guidelines on how to wrap
long lines.
<a id="tabs"></a>
#### No Tabs
<span class="Summary">Do not use tabs anywhere.</span>
Use spaces to indent or align text. See [Indentation](#indentation) for rules
about indentation and wrapping.
To convert tabs to spaces on any file, you can use the
[UNIX `expand`](http://linux.die.net/man/1/expand) utility.
<a id="trailing-spaces"></a>
#### No Trailing Spaces
<span class="Summary">Delete trailing whitespace at the end of lines.</span>
<a id="redundant-semicolons"></a>
#### No Redundant Semicolons
<span class="Summary">Delete redundant semicolons.</span>
Semicolons may represent null statements or items in SystemVerilog. One is
enough; consecutive semicolons (`;;`) are likely typos.
<a id="eschatology"></a>
### Eschatology
<span class="Summary">Use `begin` and `end` unless the whole statement fits on a
single line.</span>
If a whole semicolon-terminated statement fits on a single line, `begin` and
`end` may be omitted, otherwise enclose it in `begin` and `end`.
<div class='goodcode'></div>
```verilog
// Wrapped procedural block requires begin and end.
always @(posedge clk) begin
q <= d;
end
```
<div class='goodcode'></div>
```verilog
// The exception case, where begin and end may be omitted as the entire
// structure fits on a single line.
always @(posedge clk) q <= d;
```
<div class='badcode'></div>
```verilog
// Incorrect because a wrapped statement must have begin and end.
always @(posedge clk)
q <= d;
```
Assume that any macro call could expand to multiple statements, and enclose them
in `begin` and `end` where necessary (for example, inside conditional and loop
blocks).
<div class='goodcode'></div>
```verilog
// The contents of the called macro are safely enclosed and controlled.
if (expr) begin
`MACRO(...);
end
if (expr) ...;
else begin
`MACRO(...);
end
```
<div class='badcode'></div>
```verilog
// A multi-statement macro would have only its first statement controlled:
if (expr) `MACRO(...);
if (expr) ...;
else `MACRO(...);
```
`begin` must be on the same line as the preceding keyword, and ends the line.
`end` must start a new line. `end else begin` must be together on one line. The
only exception is if `end` has a label, a following `else` must be on a new
line.
<div class='goodcode'></div>
```verilog
// "end else begin" are on the same line.
if (condition) begin
foo = bar;
end else begin
foo = bum;
end
```
For single-statement blocks, `begin` and `end` may be omitted if the statement
fits on a single line. Both styles (including or omitting `begin` and `end`) are
acceptable.
<div class='goodcode'></div>
```verilog
// begin/end may be omitted because each semicolon-terminated statement fits on
// a single line (both styles are acceptable).
if (condition) foo = bar;
else foo = bum;
```
<div class='badcode'></div>
```verilog
// Incorrect because "else" must be on the same line as "end".
if (condition) begin
foo = bar;
end
else begin
foo = bum;
end
```
<div class='goodcode'></div>
```verilog
// An exception is made for labeled blocks.
if (condition) begin : a
foo = bar;
end : a
else begin : b
foo = bum;
end : b
```
The preceding style also applies to individual case items within a case
statement. `begin` and `end` may be omitted if the entire case item (the case
expression and the associated statement) fits on a single line. Otherwise, use
the `begin` keyword on the same line as the case expression.
<div class='goodcode'></div>
```verilog
// Consistent use of begin and end for each case item is good.
unique case (state)
kIdle: begin
state_next = kA;
end
kA: begin
state_next = kB;
end
kB: begin
state_next = kIdle;
foo = bar;
end
default: begin
state_next = kIdle;
end
endcase
```
<div class='goodcode'></div>
```verilog
// Case items that fit on a single line may omit begin and end.
unique case (state)
kIdle: state_next = kA;
kA: state_next = kB;
kB: begin
state_next = kIdle;
foo = bar;
end
default: state_next = kIdle;
endcase
```
<div class='badcode'></div>
```verilog
unique case (state)
kIdle: // These lines are incorrect because we must not wrap
state_next = kA; // case items at a block boundary without using begin
kA: // and end. Case items must fit on a single line, or
state_next = kB; // else the procedural block must have begin and end.
kB: begin
foo = bar;
state_next = kIdle;
end
default: begin
state_next = kIdle;
end
endcase
```
<a id="indentation"></a>
### Indentation
<span class="Summary">Indentation is two spaces per level.</span>
Indentation is two spaces per level, no tabs. (Configure your editor to emit
spaces when you hit the tab key.)
<a id="indented-sections"></a>
#### Indented Sections
Always add an additional level of indentation to the enclosed sections of all
paired keywords. Examples of SystemVerilog keyword pairs:
- `begin` and `end`
- `module` and `endmodule`
- `package` and `endpackage`
- `class` and `endclass`
- `function` and `endfunction`
- and similar.
Indent all members of struct, union, and enum declarations by two spaces.
<div class='goodcode'></div>
```verilog
typedef struct packed {
logic bar;
} foo_t;
```
<a id="line-wrapping"></a>
#### Line Wrapping
When wrapping a long expression, indent the continued part of the expression by
four spaces, like this:
<div class='goodcode'></div>
```verilog
assign zulu = enabled && (
alpha < bravo &&
charlie < delta);
assign addr = addr_gen_function_with_many_params(
thing, other_thing, long_parameter_name, x, y,
extra_param1, extra_param2);
assign structure = '{
src: src,
dest: dest,
default: '0};
assign foo = function_with_structure(model[offset].very.long.
structure.name);
module my_module (
input clk, // this is a line wrap of the module header definition
output bar
);
my_module my_module (
.clk(clk), // this is a line wrap of the module instantiation
.bar(bar)
);
```
Or, if it improves readability, align the continued part of the expression with
a grouping open parenthesis or brace. Similarly, an expression containing a
nested struct may be aligned with the first structure member name. In the
absence of other considerations, use the minimum number of lines.
<div class='goodcode'></div>
```verilog
assign zulu = enabled && (alpha < bravo &&
charlie < delta);
assign addr = addr_gen_function(thing, other_thing,
long_parameter_name,
x, y);
assign structure = '{src: src,
dest: dest,
default: '0};
assign foo = function_with_structure(model[offset].very.long.
structure.name);
```
Operators in a wrapped expression can be placed at either the end or the
beginning of each line, but this must be done consistently within a file.
<a id="preprocessor-indentation"></a>
#### Preprocessor Directives
<span class="Summary">Keep branching preprocessor directives left-aligned and
un-indented.</span>
Keep branching preprocessor directives (`` `ifdef ``, `` `ifndef ``, `` `else ``,
`` `elsif ``, `` `endif ``) aligned to the left, even if they are nested. Indent
the conditional branches of text as if the preprocessor directives were absent.
Non-branching preprocessor directives must follow the same indentation rules as
the regular code.
<div class='goodcode'></div>
```verilog
package foo_pkg;
`ifdef FOO // Good: branching directive left-aligned
`include "foo.svh" // normal indentation for non-branching directives
parameter int A = 1; // normal indentation for the regular code
`ifdef BAR // Good: branching directive left-aligned
parameter int A = 2;
`else
parameter int A = 3;
`endif // BAR
`endif // FOO
endpackage : foo_pkg
```
<div class='badcode'></div>
```verilog
package foo_pkg;
`ifdef FOO // Bad: needs to be un-indented
`include "foo.svh"
parameter int A = 1;
`ifdef BAR // Bad: needs to be un-indented
parameter int A = 2;
`else // Bad: needs to be un-indented
parameter int A = 3;
`endif // BAR
`endif // FOO
endpackage : foo_pkg
```
<div class='badcode'></div>
```verilog
package foo_pkg;
`ifdef FOO // Bad: needs to be un-indented
`include "foo.svh" // Bad: extra indentation level
parameter int A = 1; // Bad: extra indentation level
`ifdef BAR
parameter int A = 2;
`else
parameter int A = 3;
`endif // BAR
`endif // FOO
endpackage : foo_pkg
```
Un-indented branching preprocessor directives disrupt the flow of reading to
emphasize that there is conditional text. Leaving conditional branch text
un-indented will result in post-preprocessed text looking properly indented.
<a id="spacing"></a>
### Spacing
<a id="space-around-keywords"></a>
#### Space Around Keywords
<span class="Summary">Include whitespace before and after SystemVerilog
keywords.</span>
Keywords must be delimited by whitespace, even if not syntactically required.
Do not include a whitespace:
- before keywords that immediately follow a group opening, such as an open
parenthesis.
- before a keyword at the beginning of a line.
- after a keyword at the end of a line.
For example:
<div class='goodcode'></div>
```verilog
// Normal indentation before if. Include a space after if.
if (foo) begin
end
// Include a space after always, but not before posedge.
always @(posedge clk) begin
end
```
<a id="expressions"></a>
#### Space Around Binary Operators
<span class="Summary">Include whitespace on both sides of all binary operators.
</span>
Use spaces around all binary operators. Add sufficient whitespace to aid
readability.
For example:
<div class='goodcode'></div>
```verilog
assign a = ((addr & mask) == MyAddress) ? b[1] : ~b[0];
parameter int Width = Msb - Lsb;
function logic crc(input logic [7:0] data, mask = 8'hff);
```
<div class='badcode'></div>
```verilog
assign a=((addr&mask)==MyAddress)?b[1]:~b[0]; // Bad: no space around operators
parameter int Width=Msb - Lsb; // Bad: no space around '='
function automatic logic crc(input logic [7:0] data, mask=8'hff); // Bad: no space around '='
```
**Exception:** When declaring a bit vector or indexing or slicing an array, it
is acceptable to use the compact notation for simple expressions. For example:
<div class='goodcode'></div>
```verilog
logic [Width-1:0] foo; // Declaration: compact is acceptable
logic [Width - 1 : 0] foo; // Declaration: spaced is fine also
assign foo = bar[Width-1:0]; // Slice: compact is acceptable
assign foo = bar[Width - 1:0]; // Slice: spaced is fine also
```
For more complex expressions in array indices, space-delimit all binary
operators.
<div class='goodcode'></div>
```verilog
assign foo = bar[Factor1 - Factor0 - 1:0]; // Good: operators are space-delimited
```
<div class='badcode'></div>
```verilog
assign foo = bar[Factor1-Factor0-1:0]; // Bad: complex expression without spaces
```
When splitting alternation expressions into multiple lines, use a format that is
similar to an equivalent if-then-else line. For example:
<div class='goodcode'></div>
```verilog
assign a = ((addr & mask) == MyAddress)
? matches_value
: doesnt_match_value;
```
<a id="comma-spacing"></a>
#### Comma-delimited Lists
<span class="Summary">For multiple items on a line, one space must separate the
comma and the next character.</span>
Additional whitespace is allowed for readability.
<div class='goodcode'></div>
```verilog
bus = {addr, parity, data};
a = myfunc(lorem, ipsum, dolor, sit, amet, consectetur, adipiscing, elit,
rhoncus);
mymodule mymodule (.a(a), .b(b));
```
<div class='badcode'></div>
```verilog
{parity,data} = bus;
a = myfunc(a,b,c);
mymodule mymodule (.a(a),.b(b));
```
<a id="tabular-alignment"></a>
#### Tabular Alignment
<span class="Summary">Adding whitespace to align related items is
recommended.</span>
Where it is reasonable to do so, align a group of two or more similar lines so
that the identical parts are directly above one another. This alignment makes it
easy to see which characters are the same and which characters are different
between lines.
[Use spaces, not tabs](#indentation).
For example:
<div class='goodcode'></div>
```verilog
logic [7:0] my_interface_data;
logic [15:0] my_interface_address;
logic my_interface_enable;
```
<a id="dimension-spacing"></a>
#### Array Dimensions in Declarations
Add a space around packed dimensions.
Do not add a space:
- between identifier and unpacked dimensions.
- between multiple dimensions.
Applies to packed and unpacked arrays as well as dynamic arrays, associative
arrays, and queues.
<div class='goodcode'></div>
```verilog
logic [7:0][3:0] data[128][2];
typedef logic [31:0] word_t;
bit bit_array[512];
data_t some_array[];
data_t some_map[addr_t];
data_t some_q[$];
```
<div class='badcode'></div>
```verilog
// There must not be a space between dimensions.
logic [7:0] [3:0] data[128] [2];
// There must be a space around packed dimensions.
typedef logic[31:0]word_t;
// There must not be a space between identifier and unpacked dimension.
bit bit_array [512];
// Dynamic, associative, and queue "dimensions" are treated the same as unpacked
// dimensions. There must not be a space.
data_t some_array [];
data_t some_map [addr_t];
data_t some_q [$];
```
<a id="parameterized-type-spacing"></a>
#### Parameterized Types
<span class="Summary">Add one space before type parameters, except when the type
is part of a qualified name.</span>
A qualified name contains at least one scope `::` operator connecting its
segments. A space in a qualified name would break the continuity of a reference
to one symbol, so it must not be added. Parameter lists must follow the
[space-after-comma](#comma-spacing) rule.
<div class='goodcode'></div>
```verilog
my_fifo #(.Width($bits(nibble_t)), .Depth(2)) my_fifo_nibble(.in, .out);
class foo extends bar #(32, 8); // unqualified base class
...
endclass
foo_h = my_class#(.X(1), .Y(0))::type_id::create("foo_h"); // static method call
my_pkg::x_class#(8, 1) bar; // package-qualified name
```
<div class='badcode'></div>
```verilog
my_fifo#(.Width(4), .Depth(2)) my_fifo_2by4(.in, .out); // instantiation
class foo extends bar#(32, 8); // unqualified base class
...
endclass
foo_h = my_class #(.X(1), .Y(0))::type_id::create("foo_h"); // static method call
my_pkg::x_class #(8, 1) bar; // package-qualified name
```
<a id="label-spacing"></a>
#### Labels
<span class="Summary">Code block labels have one space before and after the
colon. Statement labels have no space before the colon and one space after the
colon.</span>
For example:
<div class='goodcode'></div>
```verilog
begin : foo
my_statement_label: assert(ptr > 0);
end : foo
```
<div class='badcode'></div>
```verilog
end:bar // Block label must have a space before and after the colon.
endmodule: foobar // Block label must have a space before the colon.
my_assert : assert(ptr > 0); // Statement label must have no space before the colon.
```
<a id="case-item-spacing"></a>
#### Case items
There must be no whitespace before a case item's colon; there must be at least
one space after the case item's colon.
The `default` case item must include a colon.
For example:
<div class='goodcode'></div>
```verilog
unique case (my_state)
kInit: $display("Shall we begin");
kError: $display("/this is fine meme");
default: begin
my_state = kInit;
interrupt = 1;
end
endcase
```
<div class='badcode'></div>
```verilog
unique case (1'b1)
(my_state == kError) : interrupt = 1; // Excess whitespace before colon
default:begin end // Missing space after colon
endcase
```
<a id="module-header-spacing"></a>
#### Module Header Spacing
<span class="Summary">Module header definitions have spaces after the module
name and between any parameter lists and port lists.</span>
For example:
<div class='goodcode'></div>
```verilog
module my_module (
...
);
module my_module #(
...
) (
...
);
```
<div class='badcode'></div>
```verilog
module my_module( // There must be a space after the module name.
...
);
module my_module #(
...
)( // There must be a space between the parameter list and the port list.
...
);
```
<a id="module-instantiation-spacing"></a>
#### Module Instantiation Spacing
<span class="Summary">Module instances have spaces after the instance name and
between any parameter lists and port lists.</span>
For example:
<div class='goodcode'></div>
```verilog
my_module #(...) my_module (...);
my_module my_module (...);
```
<div class='badcode'></div>
```verilog
// The space after the instance name is missing.
my_module #(...) my_module(...);
my_module my_module(...);
```
<a id="function-task-call-spacing"></a>
#### Function And Task Calls
<span class="Summary">Function and task calls must not have any spaces between
the function name or task name and the open parenthesis.</span>
For example:
<div class='goodcode'></div>
```verilog
process_packet(pkt);
```
<div class='badcode'></div>
```verilog
process_packet (pkt); // There must not be a space before "("
```
<a id="macro-call-spacing"></a>
#### Macro Calls
<span class="Summary">Macro calls must not have any spaces between the macro
name and the open parenthesis.</span>
For example:
<div class='goodcode'></div>
```verilog
`uvm_error(ID, "you fail")
`ASSERT(name_A, a & b, clk, rst)
```
<div class='badcode'></div>
```verilog
`uvm_error (ID, "you fail") // There must not be a space before "("
`ASSERT (name_A, a & b, clk, rst)
```
<a id="line-continuation"></a>
#### Line Continuation
<span class="Summary">It is recommended to right-align line continuations.
</span>
Aligning line continuations ('`\ `' character) helps visually mark the end of a
multi-line macro. The position of alignment only needs to be beyond the
rightmost extent of a multi-line macro by at least one space, when a space does
not split a token, but must not exceed the maximum line length.
<div class='goodcode'></div>
```verilog
`define REALLY_LONG_MACRO(arg1, arg2, arg3) \
do_something(arg1); \
do_something_else(arg2); \
final_action(arg3);
```
<a id="parentheses"></a>
### Parentheses
<span class="Summary">Use parentheses to make operations unambiguous.</span>
In any instance where a reasonable human would need to expend thought or refer
to an operator precedence chart, use parentheses instead to make the order of
operations unambiguous.
<a id="reduction-operator"></a>
#### Reduction Operator
<span class="Summary">Parentheses are required to isolate any reduction
operation when immediately preceded by any other operator.</span>
<div class='goodcode'></div>
```verilog
logic [7:0] a;
logic b;
logic c;
assign c = b & (&a); // Parentheses make the intent clear
```
<div class='badcode'></div>
```verilog
logic [7:0] a;
logic b;
logic c;
assign c = b & &a; // Bad: This can easily be a typo, still valid Systemverilog
```
<a id="ternary-expressions"></a>
#### Ternary Expressions
<span class="Summary">Nested ternary expressions must be enclosed in
parentheses.</span>
For example:
<div class='goodcode'></div>
```verilog
assign state_next = condition_b
? (condition_a
? a_and_b
: b_and_not_a)
: state;
```
While the following nested ternary has only one meaning to the compiler, the
meaning can be unclear and error-prone to humans:
<div class='badcode'></div>
```verilog
assign state_next = condition_b
? condition_a
? a_and_b
: b_and_not_a
: state;
```
<a id="comments"></a>
### Comments
<span class="Summary">C++ style comments (`// foo`) are strongly recommended for
single and multi-line comments. The `/**` token is reserved for use with
generators.</span>
A standalone comment above a block of code explains that code. An inline comment
explains the code that is on the same line as the comment.
For example:
<div class='goodcode'></div>
```verilog
// This is a multi-line comment that describes the basic functionality and key
// features of the following module.
module foo;
...
endmodule : foo
localparam bit Baz = 1; // This comment describes the item to the left. If
// using multiple lines, it must remain clear which
// line of code the comment is referring to.
```
<div class='badcode'></div>
```verilog
/* Grepping this line looks commented.
Grepping this line looks uncommented.
That is confusing. */
```
Comments that start with `/**` are reserved for use by generator directives.
<a id="spelling"></a>
#### Punctuation, Spelling, and Grammar
<span class="Summary">Maintain consistent and correct
[punctuation, spelling, and grammar](https://google.github.io/styleguide/cppguide.html#Punctuation,_Spelling_and_Grammar)
within comments.</span>
Pay attention to punctuation, spelling, and grammar; it is easier to read
well-written comments than badly written ones.
Comments must be as readable as narrative text, with proper capitalization and
punctuation. In many cases, complete sentences are more readable than sentence
fragments. Shorter comments, such as comments at the end of a line of code, can
sometimes be less formal as long as the style remains consistent.
Although it can be frustrating to have a code reviewer point out that you are
using a comma instead of a semicolon, it is very important that source code
maintain a high level of clarity and readability. Proper punctuation, spelling,
and grammar help with that goal.
<a id="dead-code"></a>
#### Dead code
Do not keep commented out or unreachable code. Instead, rely on the version
control system to preserve older versions of the code. In cases where the "dead
code" might be there for special purposes, clearly document the intent.
<a id="naming-conventions"></a>
## Naming Conventions
### Naming Overview
<span class="Summary">All identifiers are styled `lower_snake_case` unless
otherwise specified in the following table.</span>
> "There are only two hard things in Computer Science: cache invalidation and
> naming things." -- Phil Karlton
All identifiers are styled `lower_snake_case`, except for the constructs
summarized in the following table:
Construct | Style
-------------------------------------------------------------------------------------------------- | -----
[`` `define `` macros](#defines) | `ALL_CAPS`
[Tunable parameters for parameterized modules, classes, and interfaces](#naming-module-parameters) | `UpperCamelCase`
[Constants](#naming-constants) | `UpperCamelCase`
[Type `parameter`](#naming-module-parameters) | `lower_snake_case_t`
[Struct and union types](#structs-unions) | `lower_snake_case_t`
[Constraints](#constraints) | `lower_snake_case_c`
Interface declarations | `lower_snake_case_if`
[Enumeration types](#enumerations) | `lower_snake_case_t` or `lower_snake_case_e`
[Enumerated value names](#enumerations) | `kUpperCamelCase`
[Chip primary IOs](#signal-naming) | `UPPER_SNAKE_CASE` or `lower_snake_case`
Everything else, including
[declarations (module, class, package)](#module-names),
[instance names](#module-instance-names),
[signals (nets and ports)](#signal-naming), [genvars](#generate-constructs),
[labels](#label-spacing), functions, tasks, and other variables, must be named
consistent with the `lower_snake_case` convention.
External library identifiers and their overrides in the user code that violate
the preceding naming conventions are permitted. Example: UVM's
`convert2string()` can be used without renaming.
When an identifier is styled as `UpperCamelCase`, it is permissible to separate
numeric values with an underscore. For example, `IndexedThing_5_12`.
Further, there are a number of naming conventions for signals, constants, and
ports that are documented in more detail in the following sections.
<a id="signal-descriptive"></a>
<a id="descriptive-names"></a>
### Use Descriptive Names
Names must describe what an element's purpose is. Optimize for readability using
names that would be clear even to people on a different team.
Use names that describe the purpose or intent of the object. Do not worry about
saving horizontal space as it is far more important to make your code
immediately understandable by a new reader. Minimize the use of abbreviations
that would likely be unknown to someone outside your project (especially
acronyms and initialisms). Do not abbreviate by deleting letters within a word.
As a rule of thumb, an abbreviation is probably OK if it's listed in Wikipedia.
If additional abbreviations must be used, make sure your project has a glossary
of acceptable abbreviations.
Descriptiveness is recommended to be proportional to the name's scope of
visibility. For example, `n` may be a fine name within a 5-line function, but
within the scope of a 1000-line module, it's likely too vague.
When adding a comment to a signal declaration, consider whether an improved
signal name would be more appropriate.
Don't reuse variables for convenience. Instead create a new variable with a
unique, descriptive name.
<div class='badcode'></div>
```verilog
logic temp; // Bad: temp is not a descriptive name
always_comb begin
temp = a ^ b;
c = ~temp + 1'b1;
temp = d | e; // Bad: temp was reused. Instead declare a new signal
f = temp + 1'b1;
end
function automatic logic foo(logic bar);
bar = !bar; // Bad: reusing the input variable of a function
return bar;
endfunction
```
<a id="binary-parameters"></a>
### Prefer Positive Enablement
<span class="Summary">Signals, ports, and parameters must be named
positively.</span>
All boolean signals are assumed to be active-high, unless explicitly named with
a `_n` suffix to indicate that the [signal is active-low](#active-low-signals).
Active-low signals are not recommended.
When naming boolean parameters, prefer positive enablement names ("Foo" or
"EnableFoo") over disablement ("DisableFoo").
<div class='goodcode'></div>
```verilog
// Good: binary parameters/localparams are named positively ("Enable"),
// regardless of their default values.
parameter bit EnableFoo = 0;
parameter bit EnableBar = 1;
```
<div class='badcode'></div>
```verilog
// Bad: Parameter names are named negatively. Both the names and the values
// must instead be inverted.
parameter bit DisableFoo = 1;
parameter bit DisableBar = 0;
```
<a id="ports"></a>
### Hierarchical consistency
<span class="Summary">The same signal must have the same name at any level of
the hierarchy.</span>
A signal that connects to a port of an instance must have the same name as that
port. By proceeding in this manner, signals that are directly connected must
maintain the same name at any level of hierarchy.
Exceptions to this convention are expected, such as:
* When connecting a port to an element of an array of signals.
* When mapping a generic port name to something more specific to the design.
For example, two generic blocks, one with a `requester_bus` port and one
with a `completer_bus` port might be connected by a `foo_bar_bus` signal.
In each exceptional case, care must be taken to make the mapping of port names
to signal names as unambiguous and consistent as possible.
A corollary of this principle is that signal names must change when that
signal's meaning changes. For example, if a `write_address` signal means "byte
index" at one level of hierarchy but "word index" within a sub-module, those
signals must have different names to indicate their differences (for example,
`write_byte_address` and `write_word_address`).
<a id="clocks"></a>
<a id="clock-and-reset-names"></a>
### Clock and Reset
<span class="Summary">These signals must be named `clk`, `rst`, and `arst`.
</span>
Clocks and resets must follow the following naming rules:
* Clock is named `clk`.
* Synchronous reset is named `rst` and is active high.
* Asynchronous reset is named `arst` and is active high.
These names may optionally be prefixed to specify more specific use. Most
commonly, these signals will be prefixed with a mnemonic indicating a clock
domain, as required by the [Clock Domain Prefixes](#clock-domains) section.
For example:
<div class='goodcode'></div>
```verilog
input logic smbus_clk, // Clocks an "smbus" clock domain.
input logic smbus_rst, // Synchronous reset, clocked by smbus_clk
input logic smbus_arst, // Asynchronous reset, de-assert clocked by smbus_clk
input logic [7:0] smbus_byte, // Synchronous with smbus_clk
input logic smbus_valid, // Synchronous with smbus_clk
```
### Avoid signal names that end with underscore-number
Signal names must never end with an underscore followed by a number (for
example, `foo_1`, `foo_2`, etc.). Many synthesis tools map buses into nets using
that naming convention, so similarly named nets can lead to confusion when
examining a synthesized netlist.
### Avoid reserved keywords as signal names
Reserved Verilog or SystemVerilog keywords may never be used as names (see
Tables 22.1-22.6 of [SystemVerilog-2017 standard] for the full list of reserved
keywords).
When interoperating with different languages, be mindful not to use keywords
from other languages.
<a id="signal-prefixes"></a>
### Prefixes
Use common prefixes to identify groups of signals that operate together. For
example, all elements of an AXI-S interface would share a prefix: `foo_valid`,
`foo_ready`, and `foo_data`.
Additionally, prefixes must be used to clearly label which signal is in which
clock group for any module with multiple clocks. See the section on
[clock domains](#clock-domains) for more details.
Examples:
- Signals associated with controlling a blockram might share a `bram_` prefix.
- Signals that are synchronous with `dram_clk` rather than `clk` must share a
`dram_` prefix.
Code example:
<div class='goodcode'></div>
```verilog
module fifo_controller (
input logic clk,
input logic rst,
// writer interface
input logic [15:0] in_data,
input logic in_valid,
output logic in_ready,
// reader interface
output logic [15:0] out_data,
output logic out_valid,
output logic [7:0] out_fullness,
input logic out_ack,
// memory interface:
output logic [7:0] mem_addr,
output logic [15:0] mem_wdata,
output logic mem_we,
input logic [15:0] mem_rdata
);
```
This naming convention makes it easier to map port names onto similar signal
names using simple and consistent rules. See the section on
[Hierarchical Consistency](#ports) for more information.
<a id="clock-domains"></a>
#### Clock Domain Prefixes
<span class="Summary">If a module contains multiple clocks, all signals must be
prefixed by a clock domain mnemonic.</span>
Generally, it is recommended to structure modules so that most modules only have
a single clock domain (fully synchronous). For modules that must span multiple
clock domains, it is required that every port and signal within the module be
labelled with a prefix that uniquely associates each signal with a clock domain.
This prefix must be the same prefix used in the naming of the associated clock.
Even asynchronous resets must be de-asserted synchronously with a specific clock
domain, and so must be named accordingly.
For example:
<div class='goodcode'></div>
```verilog
module foo_to_bar_cdc_fifo (
// This module has two clocks, foo and bar:
input logic foo_clk,
input logic foo_arst, // reset for flops in the foo_clk domain
input logic bar_clk,
input logic bar_arst, // reset for flops in the bar_clk domain
// These signals are all in the foo_clk domain:
input logic [7:0] foo_payload_data,
input logic foo_payload_valid,
output logic foo_payload_ready,
// These signals are all in the bar_clk domain:
output logic [7:0] bar_payload_data,
output logic bar_payload_valid,
input logic bar_payload_ready
);
// Internal nets must all be labelled as well:
wire foo_transfer = foo_payload_valid && foo_payload_ready;
```
<a id="src-dest-prefix"></a>
#### Source-Destination Prefixes
It is sometimes useful to document the expected connectivity between modules in
the signal name. The convention for indicating this connectivity is
`<src>_<dest>__`, where `<src>` and `<dest>` are convenient abbreviations for
the endpoints of the communication (at least, from a top-level perspective). The
endpoint abbreviation must specify a specific instance, or a reasonable generic
name if the specific instance is not known.
The `<src>` endpoint must always be the *producer* or *requester* of a given
*communication* (which can either be an individual flow-controlled channel or a
protocol-level group of individual flow-controlled channels). `<dest>` must
always be the *consumer* or *completer* of the communication. A communication
direction is not necessarily the same as each signal's direction. In this
manner, a set of related signals that work together to form a distinct
communication between modules always have the same naming prefix. The scope of
the communication (in other words, channel or group of channels) must be
explicitly documented using comments so that there is no naming ambiguity.
Source-destination prefixes are never mandatory, and must only be used at levels
of hierarchy where they clarify the intent of the design. When stripping this
prefix from a signal name at a hierarchical boundary, the right-hand side of the
`__` separator must remain unchanged.
An example:
<div class='goodcode'></div>
```verilog
module foo (
input logic clk,
input logic rst,
// This is a simple standalone control signal from endpoint bar.
input logic bar_foo__enable,
// This is a protocol-level group of Ready/Valid flow-controlled channels
// where foo is the requester endpoint and bar is the completer endpoint.
// Good: All signals in this request channel have the same <src>_<dest>
// prefix regardless of signal direction.
input logic foo_bar__req_ready,
output logic foo_bar__req_valid,
output req_t foo_bar__req,
// Good: Although this response channel flows in the opposite direction, it
// is part of the same protocol interface as the request channel above, so
// the <src>_<dest> prefix is still "foo_bar".
output logic foo_bar__resp_ready,
input logic foo_bar__resp_valid,
input resp_t foo_bar__resp
);
```
<div class='badcode'></div>
```verilog
module foo (
input logic clk,
input logic rst,
// Bad: The ready signal prefix must be "foo_bar". The <src>_<dest> prefix
// depends on the endpoint roles and not the signal direction.
input logic bar_foo__req_ready,
output logic foo_bar__req_valid,
output req_t foo_bar__req,
// Bad: Although this response channel flows in the opposite direction, it
// is part of the same protocol interface as the request channel, where foo
// is the requester endpoint and bar is the completer endpoint. Thus, the
// <src>_<dest> prefix must still be "foo_bar".
output logic bar_foo__resp_ready,
input logic bar_foo__resp_valid,
input resp_t bar_foo__resp
);
```
<a id="pipelines"></a>
#### Pipeline Stage Prefixes
<span class="Summary">Clearly label your pipeline stage variables.</span>
When implementing a multi-stage pipeline, label your variables so that it is
clear which pipeline stage each variable is associated with. For example, a
three stage pipeline might use the prefixes `p1_`, `p2_`, and `p3_` to indicate
which signal is associated with which stage.
Clearly labelling which pipeline stage a signal is associated with helps to
detect and avoid bugs where signals that are valid in one pipeline stage are
accidentally used in a different pipeline stage.
Example:
<div class='goodcode'></div>
```verilog
// Pipe stage 1:
always @(posedge clk) begin
p1_x <= in_x;
p1_y <= in_y;
p1_valid <= in_valid;
end
// Pipe stage 2:
always @(posedge clk) begin
p2_product <= p1_x * p1_y;
p2_valid <= p1_valid;
end
// Pipe stage 3:
always @(posedge clk) begin
p3_accumulator <= p3_accumulator + p2_product;
p3_valid <= p2_valid;
end
```
NOTE: This guide makes a distinction between *delayed signals* and *pipelines*.
A *delayed signal* is a stand-alone signal that is delayed by a number of
cycles. A *pipeline* is a collection of signals across a number of cycles, as in
the preceding example. In this example, the valid signal is a delayed version of
the original in_valid signal, but the other signals are not delayed signals. The
pipelining naming convention emphasizes the grouping of signals in the same
stage, not their relative delays from their origin. The use of prefixes for
pipeline stages and suffixes for delayed signals makes the distinction clear.
See [Delayed Signal Suffix](#delayed-signal) for details.
<a id="signal-suffixes"></a>
### Suffixes
There are some standard suffixes for signals that have special meanings. Signals
must only end with these suffixes when the standard meanings are intended.
Some common conventions for suffixes are summarized here:
* [Specify units](#signal-units) as a suffix where possible.
* The `_n` suffix indicates an [active-low signal](#active-low-signals).
* When used as a pair, the `_n` and `_p` suffixes indicate a
[differential pair of signals](#differential-pairs).
* The `_ready`, `_valid`, and `_valid_next` suffixes are expected to follow
standardized [Ready/Valid semantics](#ready-valid).
* The `_req` and `_ack` suffixes are expected to follow standardized
[Request/Acknowledge semantics](#req-ack).
* The `_next` and `_le` suffixes indicate
[the data and load-enable inputs for a clocked register](#registers).
* The `_d` suffix indicates a
[clock-cycle delayed copy of a signal](#delayed-signal).
* The `_sMpN` and `_uMpN` suffixes (where M and N are integers) indicate a
[fixed-point signal](#fixed-point-signals).
* When combining multiple suffixes on a single signal, follow the standardized
[order of suffixes](#suffix-ordering).
<a id="signal-units"></a>
#### Specify units
Just as with [constants](#constant-units), include the units for a signal in the
signal's symbolic name. Counters must indicate what is being counted. Address
signals must be named to indicate the word size of the thing being indexed.
Unitless signals (for example, `foo_is_enabled`) are excepted from this rule.
Additionally, some standard interfaces (for example, AXI-M) have standardized
naming of signals. In that context, the standardized signal names (`waddr`) are
preferable to more precise names (`write_byte_address`).
Prefer specifying units for logic-vector type signals assuming a 0-based
least-significant bit. If that is not practical and a bit slice is required,
then the signal name must encode the bit-vector range.
Examples:
* `write_byte_address` is clearer than `write_address`.
* `max_mibytes_per_sec` is clearer than `max_rate`.
* `packet_size_beats` or `packet_size_kibytes` is clearer than `packet_size`.
* `cycle_counter` or `transfer_counter` is clearer than `counter`.
* For a 64-bit signal `foo_byte_address`, it is assumed to be defined as
`logic [63:0] foo_byte_address`. A corresponding signal slice in units of 4B
address could then be defined as either `logic [61:0] foo_4byte_address` or
`logic [63:2] foo_63_2_byte_address`.
<a id="constant-units"></a>
#### Units for Constants
Just as with [signals](#signal-units), include the units for a constant in the
constant's symbolic name (preferably, as a suffix). The exceptions to this rule
are for constants that are inherently unitless, or if the constant is describing
the default unit type, "bits."
Example:
<div class='goodcode'></div>
```verilog
localparam int InterfaceWidth = 64; // Bits
localparam int InterfaceWidthBytes = (InterfaceWidth + 7) / 8;
localparam int InterfaceWidth64bWords = (InterfaceWidth + 63) / 64;
localparam int ImageWidthPixels = 640;
localparam int Mega = 1000 * 1000; // Unitless
localparam int Mebi = 1024 * 1024; // Unitless
localparam int SystemClockHz = 200 * Mega;
```
<a id="active-low-signals"></a>
#### Active-Low Signals
<span class="Summary">The `_n` suffix indicates an active-low signal.</span>
It's recommended to avoid active-low signals. If active-low signals are used,
they must have the `_n` suffix in their name. Otherwise, all signals are assumed
to be active high.
<a id="differential-pairs"></a>
#### Differential Pairs
<span class="Summary">Use the `_p` and `_n` suffixes to indicate a differential
pair.</span>
For example, `in_p` and `in_n` comprise a differential pair set.
<a id="valid"></a>
#### Valid Qualifier Suffix
<span class="Summary">`foo_valid` indicates when `foo_*` signals are valid.
</span>
Signals named with the "\_valid" suffix indicate when a set of related signals
are valid. The signals being labelled by the "foo\_valid" signal must all have
the same "foo\_" prefix.
Signals named with the "\_valid_next" suffix indicate when a set of related
signals will be valid in the next clock cycle (distinct from the
[`_next` register suffix](#registers)). An interface may use `_valid_next`
instead of `_valid` to provide early valid indication; all of the following
rules applied to `_valid` similarly apply to `_valid_next`.
Signals in the "foo\_" group must be ignored when "foo\_valid" is not asserted.
Note that the additional presence of a signal ending with `_ready` indicates the
use of [ready/valid flow control semantics](#ready-valid).
For example:
<div class='goodcode'></div>
```verilog
output logic [`DATA_WORD] data,
output logic data_valid,
output logic [`COMMAND_OP_WORD] command_operation,
output logic [`OPERAND_WORD] command_operand_a,
output logic [`OPERAND_WORD] command_operand_b,
output logic command_valid,
```
<a id="registers"></a>
#### Register Signal Suffixes
<span class="Summary">The `_next` and `_le` suffixes have standard meanings
related to registers.</span>
The `_next` suffix indicates a signal that is a D input into a register.
Therefore, the `_next` suffix is permitted on interface signals and module ports
to indicate next-state signals passing across hierarchical boundaries.
The `_le` suffix indicates an optional load-enable signal to a register.
Example:
<div class='goodcode'></div>
```verilog
logic [15:0] foo; // the Q output of a register
logic [15:0] foo_next; // the D input of that same register
logic foo_le; // the load-enable for the foo register
always @(posedge clk) begin
if (foo_le) begin
foo <= foo_next;
end
end
```
Additionally:
The `_inc` suffix indicates an increment-enable signal when implementing a
counter.
The `_clear` suffix indicates a register-specific synchronous clear operation.
<a id="delayed-signal"></a>
#### Delayed Signal Suffix
<span class="Summary">Signals delayed by a single clock cycle must end in a `_d`
suffix.</span>
If one signal is only a delayed version of another signal, the `_d` suffix must
be used to indicate this relationship.
If another signal is then delayed by another clock cycle, the next signal must
be identified with the `_d2` suffix, and then `_d3` and so on.
Example:
<div class='goodcode'></div>
```verilog
always @(posedge clk) begin
data_valid_d <= data_valid;
data_valid_d2 <= data_valid_d;
data_valid_d3 <= data_valid_d2;
end
```
NOTE: This guide makes a distinction between *delayed signals* and *pipelines*.
A *delayed signal* is a stand-alone signal that is delayed by a number of
cycles. A *pipeline* is a collection of signals across a number of cycles.
[Pipelines have a different style.](#pipelines)
<a id="fixed_point_signals"></a>
<a id="fixed-point-signals"></a>
#### Fixed-Point Signals
<span class="Summary">Signals used for fixed-point arithmetic may be suffixed to
indicate their sign, number of integer bits (including sign bit for signed
signals), and number of fractional bits.</span>
In modules with multiple fixed-point data types, adding a suffix to signal names
may be useful to clearly capture intended design behavior. If a suffix is used,
signal names must be in the form `_sMpN` for signed signals and `_uMpN` for
unsigned signals. "N" indicates the number of fractional bits. "M" indicates the
number of integer bits, including the sign bit for signed signals. This format
is based on [Q Notation](https://en.wikipedia.org/wiki/Q_(number_format)).
Example:
<div class='goodcode'></div>
```verilog
// signed, 3 bit integer, 12 bit fractional
logic signed [14:0] foo_s3p12;
// unsigned, 4 bit integer, 9 bit fractional
logic [12:0] bar_u4p9;
// Addition result of foo and bar signals
// signed, 6 bit integer, 12 bit fractional
logic signed [17:0] foo_bar_s6p12;
assign foo_bar_s6p12 = foo_s3p12 + signed'({1'b0, bar_u4p9, 3'd0});
```
<a id="suffix-ordering"></a>
#### Order of Suffixes
<span class="Summary">When combining multiple suffixes on a single signal, order
them from inner semantic qualifiers to outer temporal qualifiers.</span>
When multiple standard suffixes apply to a single signal, they must be appended
in the following order:
1. **Units / Semantic Qualifiers**: Functional qualifiers and units (for
example, `_bytes`, `_valid`, `_ready`, `_req`, `_ack`).
2. **Fixed-Point Format**: Fixed-point format specifiers (`_sMpN`, `_uMpN`).
3. **Active-Low Polarity**: Active-low indicator (`_n`).
4. **Differential Polarity**: Differential pair polarity (`_p`, `_n`).
5. **Stage / Delay / Register Qualifiers**: Temporal qualifiers (`_next`,
`_le`, `_inc`, `_clear`, `_d`, `_d<N>`).
Examples:
<div class='goodcode'></div>
```verilog
// Semantic/unit qualifier before register/delay suffix
logic foo_valid_d;
logic [15:0] packet_len_bytes_next;
// Fixed-point format before register/delay suffix
logic signed [14:0] coeff_s3p12_next;
// Active-low before register/delay suffix
logic rst_n_d;
// Active-low before differential pair
logic sync_n_p, // Positive pin of active-low sync pair
logic sync_n_n, // Negative pin of active-low sync pair
// Full multi-tier chain: semantic qualifier -> active-low -> delay
logic dma_req_n_d;
```
<div class='badcode'></div>
```verilog
// Bad: Register/delay suffix placed before semantic or fixed-point suffix
logic in_d_valid;
logic [15:0] packet_len_next_bytes;
logic signed [14:0] coeff_next_s3p12;
// Bad: Differential suffix placed before active-low suffix
logic sync_p_n,
// Ambiguous whether second _n is differential or active-low
logic sync_n_n,
```
<a id="macros"></a>
## Preprocessor Directives and Pragmas
This section provides guidance on the use of verilog preprocessor directives and
pragmas.
<a id="global-macro-files"></a>
### Global Macro Files
<span class="Summary">A global macro file is a file that contains only
[global defines](#defines). Global defines are only permitted within global
macro files.</span>
Global macro files are distinct from [include files](#include-files). Global
macro files may not be included using `` `include ``. They are intended to be
visible by all source files in a project.
<a id="defines"></a>
### Macro Definitions
<span class="Summary">Macro names must be `ALL_CAPS` (in other words, consist of
only capital letters, digits, or underscores).</span>
A **global define** is a tick-defined macro in a
[global macro file](#global-macro-files) that is shared by all source files in a
project. To reduce namespace collisions, global defines must be prefixed by the
name of a group of related macros, followed by a pair of underscores:
<div class='goodcode'></div>
```verilog
// The following is the BAR macro in the FOO namespace (optional)
// of the DMA block.
`define DMA_FOO__BAR(params) \
...
```
A global define that is a natural extension or abbreviation of a construct in
the UVM library is exempt from these rules - it is acceptable to define such
macros with the same convention as the UVM library (in other words,
`lower_snake_case`).
<span class="Summary">Local macros must be prefixed with a single underscore.
</span>
A **local define** is a tick-defined macro that must only be used within the
scope of a single local file. It must be explicitly undefined after use, to
avoid polluting the global macro namespace. To indicate that a macro is only
meant to be used in the local scope, the macro name must be prefixed with a
single underscore.
To ensure that local defines stay local, be careful not to `` `include `` other
files between the macro definition and `` `undef ``.
Example:
<div class='goodcode'></div>
```verilog
`define _MAKE_THING(_x) \
thing i_thing_##_x (.clk(clk), .i(i##_x) .o(o##_x));
`_MAKE_THING(a)
`_MAKE_THING(b)
`_MAKE_THING(c)
`undef _MAKE_THING
```
<a id="standard-macros"></a>
### Standard Macros
<span class="Summary">Use standard macros when available.</span>
Whenever possible, reuse standard macro libraries rather than writing your own.
This style guide provides a reference implementation for the following standard
macros.
<a id="stringify-macro"></a>
#### STRINGIFY Macro
The `STRINGIFY` macro presents a standard way to convert a macro argument into a
string.
<div class='goodcode'></div>
```verilog
`define STRINGIFY(_x) `"_x`"
```
For example:
<div class='goodcode'></div>
```verilog
`define DISPLAY_VALUE(_x) $display("%s: %p", `STRINGIFY(_x), (_x))
```
Don't invent alternative implementations:
<div class='badcode'></div>
```verilog
// This doesn't work with all tools, use STRINGIFY instead:
`define BAD_DISPLAY_VALUE(_x) $display("%s: %p", "_``_x``_", (_x))
```
<a id="bounded-lookup-macro"></a>
#### BOUNDED\_LOOKUP Macro
The `BOUNDED_LOOKUP` macro presents a standard way to build an rvalue that
indexes into an array, when the array size is smaller than maximum possible
value of the index.
The verilog expression `array[index]` would return `'X` for out-of-bound
indices. This alternative has the following properties:
* Efficient: unnecessary high bits of index are discarded (aliasing the
array).
* Safe: returns '0 for all other out-of-bound indices.
<div class='goodcode'></div>
```verilog
`define BOUNDED_LOOKUP(__arr, __idx) \
(($size(__arr) == 1'b1) ? __arr[$high(__arr)] \
: (__idx[(($high(__arr) == 0) ? 1 : $clog2($high(__arr) + 1)) - 1 : 0] < $low(__arr) || \
__idx[(($high(__arr) == 0) ? 1 : $clog2($high(__arr) + 1)) - 1 : 0] > $high(__arr)) ? '0 \
: __arr[__idx[(($high(__arr) == 0) ? 1 : $clog2($high(__arr) + 1)) - 1 : 0]])
```
<a id="x-of-type-macro"></a>
#### X\_OF\_TYPE Macro
The `X_OF_TYPE` macro presents a standard way to typecast `'X`.
<div class='goodcode'></div>
```verilog
`define X_OF_TYPE(__type) \
(__type'({$bits(__type){1'bx}}))
```
<a id="assertion-macros"></a>
#### Assertion Macros
<span class="Summary">Use assertion libraries to enforce unified implementation
throughout the design.</span>
Following is a reference implementation of standard assertion macros used in
this document.
<div class='goodcode'></div>
```verilog
// Concurrent assertion to check that a property is not violated. The assertion
// is disabled if reset is active. The sampling events are positive edges of the
// clock.
`define ASSERT(__name, __prop, __clk, __rst) \
`ifdef ASSERT_ON \
__name: assert property ( \
@(posedge __clk) disable iff (__rst !== 0) (__prop)); \
`endif
// Concurrent assertion to check that an expression evaluates to a known value
// (all bits are either '0' or '1') when not in reset.
`define ASSERT_KNOWN(__name, __expr, __clk, __rst) \
`ASSERT(__name, ~$isunknown(__expr), __clk, __rst)
// A static assertion that evaluates during elaboration, to check that an
// expression is true. Primarily used to validate module parameters.
`define ASSERT_STATIC(__name, __expr) \
`ifdef ASSERT_ON \
if (!(__expr)) \
$fatal(2, "Failed static assertion: %s: (%s) is not true.", \
`"__name`", `"__expr`"); \
`endif // ASSERT_ON
```
<a id="synthesis-pragmas"></a>
### Synthesis Pragmas
<span class="Summary">Do not use synthesis pragmas that can lead to
simulation-synthesis differences.</span>
There are several pragmas that impact the creation of the design database
leading to different tools inferring different functionality. These can lead to
hard-to-debug simulation-synthesis mismatches that (depending on methodology)
might not be caught by logical equivalence checks. These include `translate_off`
and `translate_on`, `synthesis_off` and `synthesis_on`, `read_comments_as_hdl
on` and `read_comments_as_hdl off`, `parallel case`, and `full case`. Do not use
these pragmas.
<a id="ifdef-directives"></a>
### `` `ifdef `` Directives
<span class="Summary">Do not use `` `ifdef ``, `` `else ``, `` `elsif ``, or ``
`ifndef `` compiler directives except as prescribed.</span>
Avoid `` `ifdef `` whenever possible. Misuse of `` `ifdef ``-style compiler
directives can negatively impact code coverage, and can lead to a mismatch
between simulation and synthesis. For most use cases, separate source units or
generate-if statements provide a better solution.
The following exceptions are permitted.
<a id="ifdef-simulation"></a>
#### `` `ifdef SIMULATION ``
May only be used additively, to add debug logic or logging statements.
SIMULATION will typically be defined in simulation environments, and will never
be defined in any other environment.
Do not use the SIMULATION macro to select between RTL and behavioral models (see
[anti-patterns](#ifdef-antipatterns)). Do not use the SIMULATION macro to wrap
simple assertions (see [ASSERT_ON](#ifdef-assert_on)).
For example:
<div class='goodcode'></div>
```verilog
`ifdef SIMULATION
state_t prev_state = IDLE;
always @(state) begin
$display("%t: %m: state transition: %s -> %s",
$time, prev_state.name(), state.name());
prev_state = state;
end
`endif // SIMULATION
```
<a id="ifdef-assert_on"></a>
#### `` `ifdef ASSERT_ON ``
May only be used additively, to add assertions or assertion-specific modeling
code. This enables an easy path to disable assertions in cases where faster
simulation is needed. See the [Assertion macros](#assertion-macros) section for
macros that implement this switch.
For example:
<div class='goodcode'></div>
```verilog
`ifdef ASSERT_ON
int outstanding_credits = 0;
always @(posedge clk) begin
if (credit) outstanding_credits += 1;
if (valid) outstanding_credits -= 1;
if (rst) outstanding_credits = 0;
end
credits_never_underflow: assert property (
@(posedge clk) disable iff (rst)
outstanding_credits >= 0);
`endif // ASSERT_ON
```
<a id="ifdef-fpv_on"></a>
#### `` `ifdef FPV_ON ``
May only be used additively, to add monitors and logic used exclusively by
formal property verification tools.
<a id="ifdef-simulator"></a>
#### `` `ifdef <simulator> ``
Some simulators have simulator-specific debug features that need preprocessor
guards. No functional RTL must ever be enclosed by an `` `ifdef <simulator> ``
block.
The legal names to identify supported simulators are:
* `VCS`: for Synopsys VCS simulators.
* `INCA`: for Cadence Incisive simulators.
* `XCELIUM`: for Cadence Xcelium simulators.
* `DSIM`: for Metrics DSim simulators.
<div class='goodcode'></div>
```verilog
`ifdef VCS
$stack();
`endif // VCS
```
<a id="ifdef-technology"></a>
#### `` `ifdef <technology> ``
It is permitted to use `` `ifdef `` directives to select between implementations
enabled by specific technologies (standard cell libraries, emulation, processes,
FPGA architectures).
If used, there must always be a valid `` `else `` clause that describes a default
implementation. There must also be unit tests that exercise all technology
cases.
Some of the standard names are:
* `EMULATION`: for emulation-specific code.
* `FPGA`: for FPGA-specific code.
<a id="ifdef-antipatterns"></a>
#### `` `ifdef `` Anti-patterns
Do not enable features with `` `ifdef ``. Instead, use parameters and generate-if
statements.
Do not use directives similar to `` `ifdef DISABLED `` to disable blocks of code.
Delete dead code instead.
Do not use include guards. Use a properly ordered compilation file list (flist)
so that include guards are unnecessary. See the
[Include Guards](#include-guards) section for more details.
<a id="ifdef-exceptions"></a>
#### `` `ifdef `` Exceptions
There are always unanticipated exceptional scenarios. If your project must use
non-standard `` `ifdef `` directives, follow the following guidelines:
* The canonical design that gets deployed is what is represented with no
defines set.
* Clearly document and justify your macro in the project documentation (no "ad
hoc" `` `ifdef `` macros).
* Prefix your macro names with a unique project namespace identifier. For
example, `FOOBAR__DEBUG` is preferable to `DEBUG` to avoid namespace
collisions between projects.
* Choose macro names that connote positive enablement. For example, prefer
`FOOBAR__PERF_COUNTERS` to `FOOBAR__DISABLE_PERF_COUNTERS`.
<a id="includes"></a>
### Includes
<a id="include-files"></a>
#### Include Files
<span class="Summary">Files intended for [`` `include ``](#include-directives)
are referred to as "include files".</span>
<a id="include-directives"></a>
#### Include Directives
<span class="Summary">Use `` `include `` directives only to include files into a
verilog package file or to include files with code snippets.</span>
Include directives used for the purpose of compiling each file standalone are
forbidden. Instead, use a properly ordered compilation file list and Multi-File
Compilation Unit (MFCU) mode.
There are only a few cases where include directives are allowed:
1. Including files into a verilog package file is allowed. Each file must be
included into only one package.
<div class='goodcode'></div>
```verilog
package foo_pkg;
// Good: breaking large package into smaller files is okay.
`include "foo_functions.svh"
endpackage
```
<div class='badcode'></div>
```verilog
// Include 'foo_pkg' package because module 'foo_top' depends on it.
// Bad: can lead to a repeated declaration of a package.
`include "foo_pkg.sv"
module foo_top;
localparam foo_pkg::data_t data = 0;
endmodule
```
1. Including files with code snippets is allowed, only when the code snippet
cannot be wrapped into its own module or package.
<div class='goodcode'></div>
```verilog
module foo (
`include "generated_signals.svh" // Good: snippet, which cannot be wrapped
);
endmodule
```
<div class='badcode'></div>
```verilog
module foo ();
`include "common_assertions.svh" // Bad: wrap into a module instead
endmodule
```
<a id="include-guards"></a>
#### Include Guards
<span class="Summary">Don't use include guards.</span>
Include guards protect against repeated expansion within the same translation
unit. They must not be used since the current style guide rule on the use of
[includes](#include-directives) will prevent this from happening.
<div class='badcode'></div>
```verilog
// Bad: include guards are not needed.
`ifndef PATH_TO_MY_CODE_VH_
`define PATH_TO_MY_CODE_VH_
...
`endif // PATH_TO_MY_CODE_VH_
```
<a id="stopping-compilation"></a>
### Stopping Compilation
<span class="Summary">Use the `` `DIE() `` macro to fail compilation.</span>
Using this (undefined) macro allows the source file to be parsed by tools that
lack preprocessing, such as code search and IDE outline generators. Pass an
explanation as a string to `` `DIE ``. This convention does not depend on any
other macro files.
<div class='goodcode'></div>
```verilog
`ifndef USING_SIMULATOR_A
`ifndef USING_SIMULATOR_B
`DIE("Unknown or unsupported simulator.")
`endif // USING_SIMULATOR_B
`endif // USING_SIMULATOR_A
```
<div class='badcode'></div>
```verilog
`ifndef USING_SIMULATOR_A
`ifndef USING_SIMULATOR_B
Error: intentional syntax error makes this unparseable without preprocessing
`endif // USING_SIMULATOR_B
`endif // USING_SIMULATOR_A
```
<a id="modules-and-packages"></a>
<a id="modules"></a>
## Modules
<a id="module-header-definition"></a>
### Module Header Definition
<span class="Summary">Use the Verilog-2001 full port declaration style, and use
the following format.</span>
Use the Verilog-2001 combined port and I/O declaration style. Do not use the
Verilog-95 list style. Port declarations in the module header must fully declare
the port name, type, and direction.
The clock port(s) must be declared first in the port list, followed by any and
all reset inputs.
For port or parameter lists with declarations, the closing parenthesis of each
list must be on its own line, in column zero. The opening parenthesis must occur
on the same line as the module name or the previous list's closing parenthesis.
The following are exceptions to these rules:
* If a list has no declarations, then the parentheses are optional. If used,
the opening and closing parenthesis must be on the same line.
* If import statements are used, then the opening parenthesis of the following
list must be on its own line.
Each [import statement](#package-imports) must appear on its own dedicated line
of code.
<a id="module-header-definition-examples"></a>
#### Module Header Definition Examples
Example of a module header without parameters:
<div class='goodcode'></div>
```verilog
module foo (
input logic clk,
input logic rst,
input logic [7:0] d,
output logic [7:0] q
);
```
Example of a module header with a
[parameter declaration](#parameterized-module-declaration):
<div class='goodcode'></div>
```verilog
module foo #(
parameter int Width = 8
) (
input logic clk,
input logic rst,
input logic [Width-1:0] d,
output logic [Width-1:0] q
);
```
Example of a module header with an [import statement](#package-imports):
<div class='goodcode'></div>
```verilog
module foo
// Imports the package for use in the header definition.
// This is a complete statement within the module, so we indent one level.
import foo_pkg::AddrWidth;
#(
parameter int DataWidth = 8
) (
input logic clk,
input logic rst,
input logic [AddrWidth-1:0] addr,
input logic [DataWidth-1:0] d,
output logic [DataWidth-1:0] q
);
```
Do not use Verilog-95 style:
<div class='badcode'></div>
```verilog
module foo (a, b, c, d);
input logic [2:0] a;
output logic b;
...
```
<a id="module-names"></a>
#### Module Names
<span class="Summary">The top level module for a design `[design]` must be named
`[design]_top`. Unit test module names end with `_test`.</span>
Module names must use `lower_snake_case` and contain only lowercase alphanumeric
characters and underscores. Use lowercase even when module-names contain proper
nouns, such as the project's name.
Top-level modules must be named `[design]_top`. For example, the top-level
module for Snout must be named `snout_top`. In this context, the "top level
module" is the highest possible level of a logic design's hierarchy, the
pin-level interface.
Unit test modules must end with the string "\_test". For example,
`dma_controller_test`.
<a id="parameterized-objects"></a>
<a id="parameterized-module-declaration"></a>
#### Parameterized Modules
<a id="when-to-parameterize"></a>
#### When to parameterize
Use module parameters to create customizable modules.
Examples of when to use parameterized modules:
- When multiple instances of a module will be instantiated, and need to be
differentiated by a parameter.
- As a means of specializing a module for a specific bus width.
- As a means of documenting which design-wide parameters are permitted to
change within the module.
Do not use module parameters to transmit constants through a design hierarchy
(use [package constants](#constants)) or to declare a constant whose scope is
internal to the module (use [`localparam`](#constants)).
For additional reading, see
[New Verilog-2001 Techniques for Creating Parameterized Models](https://opencw.aprende.org/courses/electrical-engineering-and-computer-science/6-884-complex-digital-systems-spring-2005/related-resources/parameter_models.pdf).
<a id="naming-module-parameters"></a>
#### Naming module parameters
`UpperCamelCase` is the recommended style for module parameter names, except:
* `ALL_CAPS` may be permitted for historic reasons, and
* `lower_snake_case_t` is required for parameters that are types, for
consistency with [naming of other types](#structs-unions).
<a id="parameter-port-lists"></a>
#### Use ANSI-style parameter port lists
Declare parameterized modules using a parameter port list, not with `defparam`.
<div class='goodcode'></div>
```verilog
module foo #(
parameter int ParameterName = 1,
parameter type type_parameter_name_t = logic
) (
input type_parameter_name_t ib_headward,
...etc...
```
<a id="parameter-defaults"></a>
#### Parameter defaults
Default values assigned to tunable parameters must be reasonable (in other
words, default values must represent a valid design).
Omitting a default value assignment to a parameter is permitted if it helps
mitigate potential integration bugs.
For example, a [reusable IP's](#reusable-ip) clock frequency parameter may be
reassigned in the majority of instantiations. In this case, the designer may
choose to omit the default value to eliminate the possibility of unintentionally
leaving a parameter unassigned.
Omitting default values for composite type parameters is not permitted due to
inconsistent tool support.
<a id="parameter-data-type"></a>
#### Specify parameter data types
Explicitly declare the type for parameters. Use type "int" (signed integer) for
all simple numeric parameters (for example, quantities). Always write assertions
to validate parameters (bounds checks, etc.). See the
[Assertion macros](#assertion-macros) section for a reference implementation.
For example:
<div class='goodcode'></div>
```verilog
module cdc_fifo #(
parameter int Width = 16,
parameter int Depth = 4
) (
...
);
`ASSERT_STATIC(width_must_be_positive_A, Width > 0)
`ASSERT_STATIC(depth_greater_than_1_A, Depth > 1)
```
### Module Instances
<a id="module-instance-names"></a>
#### Module Instance Names
<span class="Summary">All module instance names must start with the name of the
module being instantiated.</span>
All module instance names must be equal to the module name, plus an optional
unique suffix. This unique suffix may be a string or a number, as appropriate.
The intent of this naming convention is to make it easier to map from instance
names to module names, especially in contexts where the module name is not
readily available (for example, synthesis reports, assertions, etc.).
Exceptions can be made in instances where this style decreases the overall
legibility of the code (for example, when working with long, hard to read
library module names). In such cases, the module name must follow a project
specific pattern that readily identifies the original module.
Some examples of legal instance names:
<div class='goodcode'></div>
```verilog
// A single instance of my_decoder within a module:
my_decoder my_decoder ( ... );
// A set of enumerated instances:
my_counter my_counter0 ( ... );
my_counter my_counter1 ( ... );
// A set of symbolically named instances:
my_fifo my_fifo_foo ( ... );
my_fifo my_fifo_bar ( ... );
// Descriptive specifiers:
nand nand_this_that (.a(this), .b(that), .y(not_this_and_that));
register #(10) register_foo (.d(foo_next), .q(foo), .clk, .rst);
sram sram_bar (.address(bar_address), .data(bar_data), .clk, .rst);
```
<a id="module-instance-named-ports"></a>
#### Use named ports
<span class="Summary">Use named ports to fully specify all instantiations.
</span>
When connecting signals to ports for an instantiation, use the named port style,
like this:
<div class='goodcode'></div>
```verilog
my_module my_module(
.clk(clk),
.rst(rst),
.in(from_here),
.out(to_there)
);
```
If the port and the connecting signal have the same name, you can use the
`.port` syntax (without brackets) to indicate connectivity. For example:
<div class='goodcode'></div>
```verilog
my_module my_module(
.clk,
.rst,
.in(from_here),
.out(to_there)
);
```
All declared ports must be present in the instantiation blocks. Unused outputs
must be explicitly written as no-connects (for example: `.output_port()`), and
unused inputs must be explicitly tied to ground (for example:
`.unused_input_port(8'd0)`).
`.*` is not permitted.
Do not use positional arguments to connect signals to ports.
Instantiate ports in the same order as they are defined in the module.
<a id="port-connections-on-module-instances-must-always-match-widths-correctly"></a>
#### Instance connection widths
Port connections on module instances must always match widths correctly.
It is recommended to use explicit widths, rather than relying on Verilog's
implicit zero-extension and truncation operations, whenever practical.
Examples:
<div class='goodcode'></div>
```verilog
my_module my_module (
.thirty_two_bit_input({16'd0, sixteen_bit_word})
);
```
<div class='badcode'></div>
```verilog
my_module my_module (
// Incorrectly implicitly extends from 16 bit to 32 bit
.thirty_two_bit_input(sixteen_bit_word)
);
```
<a id="module-instantiation"></a>
#### Parameterized Module Instantiation
<span class="Summary">Use named parameters for all instantiations.</span>
Instances must be named as specified in
[Module Instance Names](#module-instance-names).
When parameterizing an instance, do not specify parameters positionally. Specify
parameters using the named parameter style, as follows:
<div class='goodcode'></div>
```verilog
my_module #(
.Height(5),
.Width(10)
) my_module (...);
```
<div class='badcode'></div>
```verilog
my_module #(5, 10) my_module (...);
```
Do not use `defparam`.
#### Recursive Instantiation
<span class="Summary">Do not instantiate recursively.</span>
Modules may not instantiate themselves recursively.
<a id="generate-constructs"></a>
### Generate Constructs
<span class="Summary">Always name generate construct blocks. The block name must
start with the "gen_" prefix.</span>
When using a generate construct, always explicitly name each block of generated
code. Name each possible outcome of the generating if statement, and name the
iterated block of a generating for statement.
All generate construct block names must start with the "gen_" prefix.
This ensures that generated hierarchical signal names are consistent across
different tools.
Example of a conditional generate construct:
<div class='goodcode'></div>
```verilog
if (TypeIsPosedge) begin : gen_posedge_type
always @(posedge clk) foo <= bar;
end else begin : gen_negedge_type
always @(negedge clk) foo <= bar;
end
```
Example of a loop generate construct:
<div class='goodcode'></div>
```verilog
for (genvar bus = 0; bus < NumberOfBuses; bus++) begin : gen_my_buses
my_bus #(.index(bus)) my_bus (.foo(foo), .bar(bar[bus]));
end
```
Do not wrap a generate construct with an additional `begin` block.
Do not use generate regions {`generate`, `endgenerate`}.
<a id="problematic-floating-begin-end"></a>
#### Floating begin-end blocks
The use of generate blocks other than for `loop`, `if`, or `case` generate
constructs is not LRM compliant. While such usage might be accepted by some
tools, this guide prohibits such "bare" generate blocks. Note that the similar
"sequential block" construct is LRM compliant and allowed.
<div class='badcode'></div>
```verilog
module foo (
input logic bar,
output logic foo
);
begin // illegal generate block
assign foo = bar;
end
endmodule
```
<a id="packages"></a>
## Packages
<a id="package-declaration"></a>
### Package Declaration
There is no special guidance for declaring packages.
<a id="package-names"></a>
#### Package Names
Package names must use `lower_snake_case` and contain only lowercase
alphanumeric characters and underscores. A package name must end with the suffix
`_pkg`.
<a id="package-dependencies"></a>
### Package Dependencies
<span class="Summary">Packages must not have cyclic dependencies.</span>
Package files may depend on constants and types in other package files, but
there must not be any cyclic dependencies. That is: if package A depends on a
constant from package B, package B must not depend on anything from package A.
While cyclic dependencies are permitted by the SystemVerilog language
specification, their use can break some tools.
For example:
<div class='badcode'></div>
```verilog
package foo_pkg;
parameter int PageSizeBytes = 16 * bar_pkg::Kibi;
...
endpackage
package bar_pkg;
// Bad: cyclic dependency, package "bar_pkg" must
// not depend on anything in "foo_pkg"
import foo_pkg::PageSizeBytes;
...
endpackage
```
<a id="package-imports"></a>
### Package imports
Package imports are permitted within a local scope, like a module or package.
Explicit imports are recommended because it is clear where everything comes
from. Wildcard imports are permitted if there is a reasonable argument that the
reduced verbosity enhances readability.
Packages must not be imported into the global scope, as this increases the risk
of conflicts.
<div class='goodcode'></div>
```verilog
module foo
import bar_pkg::AddressWidth; // Good: allows usage of package object in ports list
(
input bar_pkg::data_t data, // Use fully-qualified name in portlist
input logic [AddressWidth-1:0] addr, // Use imported parameter in ports list
...
);
import foo_pkg::*; // Good: but be mindful of potential conflicts
import bar_pkg::PageSizeBytes; // Good: preferred explicit import
```
<div class='badcode'></div>
```verilog
import foo_pkg::*; // Bad: pollutes global namespace
module foo
(
input data_t data,
...
);
```
<a id="interfaces"></a>
## Interfaces
<a id="interfaces-overview"></a>
### Overview
There is a general desire to adopt interfaces in synthesizable code (DV code can
and does use interfaces). However, in practice, projects have found that there
are several quirks and challenges when working with interfaces. These include:
- Tool support (although this continues to get better).
- Global scope (how does one fix just one block with an interface ECO).
- Challenging interactions with top level Physical Design flows (for example,
forced bit-blasting).
- Large amount of "extra typing" to declare and instantiate.
Since many of the benefits of interfaces can be realized with structs, the cost
of allowing interfaces outweighs their benefits. There is likely a set of best
practices that can be defined that would realize the potential of interfaces.
Adoption of interfaces would require including such best practices in the style
guide.
<a id="declarations"></a>
<a id="ports-and-signals"></a>
## Ports, Signals, and Constants
### Overview
* [Declare all signals](#declare-all-signals) and
[use `logic`](#use-logic-for-synthesis): `logic foo;`
* [Signals are named using lower_snake_case](#signal-naming).
* [Avoid default port values](#port-defaults).
* [How to declare constants](#constants).
* [How to declare structs and unions](#structs-unions).
* [How to declare enumerations](#enumerations).
* [Use packed arrays and structs](#packed-unpacked).
* [Packed arrays are little-endian](#packed-ordering): `logic [7:0] byte;`
* [Unpacked arrays are big-endian](#unpacked-ordering): `byte_t arr[0:N-1];`
Additionally, the semantics of specific naming conventions are elaborated on in
the separate [Naming Conventions](#naming-conventions) section.
<a id="declare-all-signals"></a>
### Declare all signals
<span class="Summary">Signals must be declared before they are used. This means
that implicit net declarations must not be used.</span>
All signals must be explicitly declared before use. All declared signals must
specify a data type. A correct design contains no inferred nets.
Within modules, it is recommended that signals, types, enums, and localparams be
declared close to their first use. This makes it easier for the reader to find
the declaration and see the signal type.
<a id="use-logic-for-synthesis"></a>
### Use `logic` for synthesis
<span class="Summary">Use `logic` for synthesis. `wire` is allowed when
necessary.</span>
All signals in synthesizable RTL must be implemented in terms of 4-state data
types. This means that all signals must ultimately be constructed of nets with
the storage type of `logic`. While SystemVerilog does provide other data
primitives with 4-state storage (for example, `integer`), those primitives are
prone to misunderstandings and misuse.
For example:
<div class='goodcode'></div>
```verilog
logic signed [31:0] x_velocity; // say what you mean: a signed 32-bit integer.
typedef logic [7:0] byte_t;
```
<div class='badcode'></div>
```verilog
bit signed [63:0] stars_in_the_sky; // 2-state logic doesn't belong in RTL
int grains_of_sand; // Or wait, did I mean integer? Easy to confuse!
```
It is permissible to use wire as a short-hand to both declare a net and perform
continuous assignment. Take care not to confuse continuous assignment with
initialization. For example:
<div class='goodcode'></div>
```verilog
wire [7:0] sum = a + b; // Continuous assignment
logic [7:0] acc = '0; // Initialization
```
There are exceptions for places where `logic` is inappropriate. For example,
nets that connect to bidirectional (`inout`) ports must be declared with `wire`.
These exceptions must be justified with a short comment.
It is permissible for DV to make use of 2-state logic, but all interfaces
between 4-state and 2-state signals must assert a check for `X` on the 4-state
net before resolving to a 2-state variable.
<a id="signal-conventions"></a>
<a id="signal-naming"></a>
### Signal Naming
<span class="Summary">Use `lower_snake_case` when naming signals.</span>
In this context, a **signal** is meant to mean a net, variable, or port within a
SystemVerilog design.
Signal names may contain lowercase alphanumeric characters and underscores.
Ports which connect **directly** to chip primary IO pads (for example, die IOs,
ASIC package IOs, or FPGA IO buffers) may use `UPPER_SNAKE_CASE`.
<div class='goodcode'></div>
```verilog
module chip_top (
input logic RESET_N,
output logic LINK_LED,
inout wire SPI_DATA
);
```
There are a number of naming conventions associated with naming signals, which
are complicated enough to warrant their own
[section of the style guide](#naming-conventions).
<a id="port-defaults"></a>
### Default Port Values
<span class="Summary">Do not use default port values.</span>
A default port value is a constant expression that is assigned to an input port
of a module. Output ports that are assigned constant expressions are not
considered default values and are permitted.
<div class='goodcode'></div>
```verilog
module foo (
// Input d must be assigned when this module is instantiated
input logic d,
// This is an initialization of output q and is okay
output logic q = '0
);
```
<div class='badcode'></div>
```verilog
module foo (
// Bad: Do not assign a default value to an input port
input logic d = '0,
...
);
```
<a id="constants"></a>
### Constants
<span class="Summary">Declare design-wide constants using parameters in the
design package file. Declare local constants using `localparam`.</span>
In this context, **constants** are distinct from tunable parameters for objects
such as [parameterized modules](#parameterized-module-declaration), classes,
etc.
#### Declaring Constants
When declaring a constant:
* Within a package, use `parameter`.
* Within a module or class, use `localparam`.
The recommended method of defining constants is to declare a `package` and
declare all constants as a `parameter` within that package.
Define design-wide constants in the design's [package file](#standard-files).
Other packages may also be declared with their own `parameter` constants to
facilitate the creation of [reusable IP](#reusable-ip).
<a id="naming-constants"></a>
#### Naming Constants
`UpperCamelCase` is the recommended style for immutable constants. The
exceptions are:
* When declaring an [enumerated type](#enumerations), use `kCamelCase` to
declare enumeration constants.
<a id="constant-data-type"></a>
#### Specify constant data types
Explicitly declare the type for constants. Use type "int" (signed integer) for
all simple numeric parameters (for example, quantities).
<a id="magic-numbers"></a>
#### Avoid Magic Numbers
<span class="Summary">It is recommended to use symbolically named
[constants](#constants) instead of unnamed numerical constants (aka magic
numbers).</span>
Try to give commonly used constants symbolic names rather than repeatedly typing
magic numbers.
<div class='goodcode'></div>
```verilog
// Declares a symbolically named constant for the value 0xD5
localparam logic [DataWidthBits-1:0] StartFrameDelimiter = 8'hD5;
...
// The named constant helps clarify the code
if (data == StartFrameDelimiter) begin
next_state = kRxData;
end
```
<div class='badcode'></div>
```verilog
// Bad: What's the significance of this number?
if (data == 8'hD5) begin
next_state = kRxData;
end
```
Unnamed numerical constants may be acceptable in cases where adding a symbolic
name adds no value. These type of constants are not considered magic numbers.
<div class='goodcode'></div>
```verilog
// Counter uses unnamed constant 1, but the meaning is obvious
cycle_cnt <= cycle_cnt + 1;
```
#### `localparam` in parameter port lists
Generally, module scoped constants, including those derived from
[module parameters](#parameterized-module-declaration) are declared as
localparam within the module body [close to first use](#declare-all-signals). It
can be useful to have module scoped constants (potentially derived from module
parameters) that control module port dimensions. Declare and define these
constants as `localparam` in the module port list to prevent them from being
overridden when the module is instantiated.
<div class='goodcode'></div>
```verilog
module foo #(
parameter int NumEntries = 1, // Tunable parameter
localparam int IndexWidth = $clog2(NumEntries) // Must not be overridden
) (
input [IndexWidth-1:0] foo
);
localparam int Bar = 7;
...
endmodule
```
<div class='badcode'></div>
```verilog
module foo #(
localparam int Bar = 7, // Bad: Bar is a constant so it goes close to usage
parameter int NumEntries = 1,
parameter int IndexWidth = $clog2(NumEntries) // Bad: IndexWidth is linked to NumEntries
) (
input [IndexWidth-1:0] foo
);
...
endmodule
```
<a id="packed-unpacked"></a>
### Packed vs. Unpacked
Use packed arrays and structs for synthesizable signals. Unpacked arrays are
appropriate for behavioral models of SRAMs and DV code.
<a id="positive-array-bounds"></a>
### Positive Array Bounds
When declaring vectors and arrays, the msb and lsb must be non-negative.
<div class='goodcode'></div>
```verilog
logic [14:0] foo;
```
<div class='badcode'></div>
```verilog
logic [13:-1] foo;
```
<a id="packed-ordering"></a>
### Packed Ordering
<span class="Summary">Bit vectors and packed arrays must be little-endian.
</span>
When declaring bit vectors and packed arrays, the index of the most-significant
bound (left of the colon) must be greater than or equal to the least-significant
bound (right of the colon). This style of bit vector declaration keeps packed
variables little-endian.
For example:
<div class='goodcode'></div>
```verilog
typedef logic [7:0] u8_t;
logic [31:0] u32_word;
u8_t [1:0] u16_word;
u8_t byte3, byte2, byte1, byte0;
assign u16_word = {byte1, byte0};
assign u32_word = {byte3, byte2, u16_word};
```
<a id="unpacked-ordering"></a>
### Unpacked Ordering
<span class="Summary">Unpacked arrays must be big-endian.</span>
When declaring unpacked arrays, the index to the left of the colon must be less
than or equal to the index to the right of the colon.
Declare zero-based unpacked arrays using the shorter notation `[size]`. It is
understood that `[size]` is equivalent to the big-endian declaration
`[0:size-1]`.
Assigning directly to an unpacked array as a whole is acceptable, but not
recommended, because mixing big-endian unpacked arrays with little-endian packed
arrays is prone to reversed-ordering mistakes. Prefer assigning elements
individually by index when possible (for parameter arrays, where
element-by-element assignment is not possible without constant functions,
initializing the unpacked array directly is acceptable with caution).
<div class='goodcode'></div>
```verilog
// Good: Assign unpacked array elements individually by index to avoid
// reversed-ordering mistakes.
logic [15:0] word_array[3];
assign word_array[0] = word0;
assign word_array[1] = word1;
assign word_array[2] = word2;
// Acceptable, but not recommended for signals: Avoid assigning to an unpacked
// array as a whole. Result: word_array[0] == word0, word_array[1] == word1, and
// word_array[2] == word2.
assign word_array = '{word0, word1, word2};
// Acceptable for parameters, but be cautious with big-endian ([0:3]) ordering.
// Result: Vec[0] == 0, Vec[1] == 1, Vec[2] == 2, and Vec[3] == 3.
parameter int Vec[4] = '{0, 1, 2, 3};
```
*Rationale:* Big-endian ordering was selected for unpacked arrays over
little-endian because:
* The C-like `[size]` declaration is preferred for unpacked arrays and is
equivalent to `[0:size-1]`.
* Big-endian is required for typical use of the `foreach` construct, which
creates a loop variable with a positive increment.
This rule only applies to variables and parameters, not to other things such as
arrays of instances. Instance arrays must be declared so that the order of
instances is correct for the ordering of packed ports.
<a id="struct-union-conventions"></a>
<a id="structs-unions"></a>
### Structs and Unions
#### Declaring Structs and Unions
<span class="Summary">Name structs and unions with a typedef.</span>
Always name `struct` and `union` types using `typedef`. Anonymous types are not
allowed because they are not reusable. Struct type names must contain only
lowercase alphanumeric characters and underscores and end with `_t`.
<div class='goodcode'></div>
```verilog
typedef struct packed {
logic dir;
int value;
} data_t; // new named type is created
data_t packet;
```
<div class='badcode'></div>
```verilog
struct packed { // Typedef is missing
logic dir;
int value;
} packet; // anonymous struct type
```
#### Naming Union Members
<span class="Summary">Union member names must be prefixed with as_*.</span>
Always prefix union member names with `as_*`. A consistent naming convention
reduces the effort required to understand RTL with deeply nested struct or union
type hierarchies by making the type-cast like behavior of unions explicit.
<div class='goodcode'></div>
```verilog
typedef union packed {
read_id_t as_read_id; // as_read_id prefix to refer to read_id_t type.
write_id_t as_write_id;
} id_t;
assign write_id = cmd.id.as_write_id;
```
<div class='badcode'></div>
```verilog
typedef union packed {
read_id_t read_id; // as_* is missing
write_id_t write_id;
} id_t;
assign write_id = cmd.id.write_id;
```
<a id="enumerations"></a>
### Enumerations
<span class="Summary">Name enumeration types `snake_case_t` (or `snake_case_e`).
Name enumeration constants `kCamelCase`.</span>
Always name `enum` types using `typedef`. The storage type of any enumerated
type must be specified. For synthesizable enums, the storage type must be a
4-state data type (`logic` rather than `bit`).
Anonymous `enum` types are not allowed as they make it harder to use the type in
other places throughout the project and across projects.
Enumeration type names must contain only lowercase alphanumeric characters and
underscores. You can suffix enumeration type names with `_t` or `_e`, as long as
the suffix is consistent within the project.
Enumeration value names (constants) must be `kCamelCase`, for example,
`kReadyToSend`. This indicates that the values are neither overrideable nor
assignable.
<div class='goodcode'></div>
```verilog
typedef enum logic { // A 4-state storage type
kWrite,
kRead
} access_t; // new named type is created
access_t req_access, resp_access;
```
<div class='badcode'></div>
```verilog
enum { // Typedef is missing, storage type is missing.
Write,
Read
} req_access, resp_access; // anonymous enum type
```
<a id="vector-typedefs"></a>
### Vector Typedefs
<span class="Summary">Prefer no single vector typedefs unless they are broadly
used.</span>
Do not use `typedef` to define local or single-use vector types. Defining a new
type for a vector that is only used in a limited scope adds unnecessary
redirection. Instead, use the raw vector type directly.
For vectors that are used broadly across multiple modules or packages (for
example, a global address type), defining a named type using `typedef` is
recommended to ensure consistency.
<div class='goodcode'></div>
```verilog
// Declare design-wide vector typedefs in a package.
package my_pkg;
typedef logic [AddrWidth-1:0] addr_t;
endpackage
module my_module (
...
);
// Good: Use design-wide typedef for broadly used vector.
my_pkg::addr_t addr;
...
endmodule
```
<div class='badcode'></div>
```verilog
module my_module (
...
);
// Bad: Unnecessary local typedef for a single-use vector.
typedef logic [DataWidth-1:0] local_data_t;
local_data_t local_data;
...
endmodule
```
An exception is made when defining signed packed arrays, where a `typedef` is
necessary to apply signedness to the elements of the array rather than the array
as a whole (see
[mixed-sign arithmetic operations](#mixed-sign-arithmetic-operations)).
<div class='goodcode'></div>
```verilog
// Good: Use local typedef to apply signedness to elements of a packed array.
typedef logic signed [DataWidth - 1:0] data_t;
data_t [NumChannels - 1:0] my_channel_data;
```
<div class='badcode'></div>
```verilog
// Bad: Signedness applies to the entire packed array, not the elements.
logic signed [NumChannels - 1:0][DataWidth - 1:0] my_channel_data;
```
<a id="functions-and-tasks"></a>
## Functions and Tasks
<a id="choosing-function-task-module"></a>
### Choosing Between Functions, Tasks, and Modules
<span class="Summary">In synthesizable RTL, use modules as the default construct
to encapsulate behavior. Tasks must not be used in synthesizable RTL. Functions
may be used for short, simple combinational logic with a single output.</span>
* **Modules**: Use modules as the default mechanism to encapsulate design
behavior.
* **Tasks**: Do not use tasks in synthesizable RTL; use modules instead. Tasks
are permitted in testbenches.
* **Functions**: Functions are useful as a lightweight alternative to modules
for simple combinational logic.
* Prefer functions over modules when there is a single output and the
relationship between inputs and output can be expressed with a direct
assignment (for example, `assign foo = check_foo(bar);`).
* Prefer modules over functions when there are multiple outputs.
* Functions can be defined in a package for wider reuse.
<a id="function-task-templates"></a>
### Templates
<span class="Summary">Function and task definitions must follow the template in
the following example.</span>
<div class='goodcode'></div>
```verilog
// Description of the function's behavior, inputs, and outputs
function automatic logic foo(logic x, logic y);
// Local variables
logic z;
// Statements
z = x ^ y;
// Return
return z;
endfunction : foo
// Description of the task's behavior, inputs, and outputs
task automatic bar(input logic x, output logic y);
// Variable declarations
// Statements
y = x;
endtask : bar
```
Some points about the function template to note in addition to the following
sections:
- The function was declared with the formal arguments in parentheses (matching
module style).
- [No assignment in the function body to the input variables](#descriptive-names)
.
<a id="function-latches"></a>
### Latches inside functions
Do not infer a latch inside a function, as this may cause a simulation-synthesis
mismatch.
<a id="function-task-explicit-lifetime"></a>
### Lifetime
<span class="Summary">Explicitly declare functions and tasks defined outside of
a class as static or automatic, preferring automatic. Functions must be
automatic in synthesizable RTL.</span>
Depending on their declaration context, functions and tasks have different
default lifetimes. Within a class, they are always automatic, whereas the
default is static in modules, interfaces, programs, and packages. To prevent
potential confusion, functions and tasks declared outside of a class must always
explicitly specify their lifetime. Automatic is generally the proper lifetime
because it allows a function or task to be independently called from different
contexts.
In synthesizable RTL, functions must always be declared as automatic.
<a id="function-data-types"></a>
### Function Data Types
<span class="Summary">Explicitly declare the data type for a function, or
declare the function as `void`.</span>
<div class='goodcode'></div>
```verilog
// The return type of the function is explicitly defined as 'bit'
function automatic bit foo(int a);
// The function has no return value.
function automatic void foo(int a);
```
<div class='badcode'></div>
```verilog
// The function's data type is implicitly declared
function automatic foo(int a);
```
<a id="function-task-argument-types"></a>
### Argument Types
<span class="Summary">Explicitly declare storage types for all arguments in
function and task arguments lists.</span>
For example:
<div class='goodcode'></div>
```verilog
// Both arguments have explicitly declared 'int' as their storage type.
task automatic foo(int a, int b);
```
<div class='badcode'></div>
```verilog
// Bad: No storage type explicitly declared for 'b'.
task automatic foo(int a, b);
```
<a id="function-task-argument-directions"></a>
### Argument Directions
<span class="Summary">Argument directions for functions and tasks are optional
and considered inputs by default. If a direction is specified for *any*
argument, then it must be specified for *all* arguments.</span>
For example:
<div class='goodcode'></div>
```verilog
task automatic foo(int a, int b); // Both arguments treated as inputs.
function automatic bit foo(input int a, output int b, inout int c, ref int d);
```
<div class='badcode'></div>
```verilog
// Potential bug: Although not labeled, "b" will be treated as "ref".
task automatic foo(ref int a, int b);
```
## Sequential Logic
<a id="always_ff-vs-always"></a>
### `always_ff` vs `always`
There is no preference between `always_ff` and `always` for clocked processes,
other than consistency within a project.
<a id="blocking-and-non-blocking-assignments"></a>
<a id="seq-logic-use-non-blocking"></a>
### Use Non-Blocking Assignments
<span class="Summary">Sequential logic must use non-blocking assignments.
</span>
Never mix assignment types within a block declaration.
A sequential block (a block that latches state on a clock edge) must exclusively
use non-blocking assignments, as shown in the section on declaring
[Registers](#sequential-logic-registers).
This stands in contrast to combinational logic, which
[must use blocking assignments in process blocks](#comb-logic-use-blocking-assignments).
This is one of Clifford Cummings's
[Golden Rules of Verilog](http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf).
<a id="sequential-logic-latches"></a>
### Sequential Logic (Latches)
<span class="Summary">The use of latches is not recommended - use flip-flops
when possible.</span>
Unless absolutely necessary, use flip-flops or registers instead of latches.
If you must use a latch, use `always_latch` over `always`, and use non-blocking
assignments (`<=`). Never use blocking assignments (`=`).
<a id="sequential-logic-registers"></a>
### Sequential Logic (Registers)
<span class="Summary">Use the standard format for declaring sequential blocks.
</span>
In a sequential always block, only use non-blocking assignments (`<=`). Never
use blocking assignments (`=`).
Designs that mix blocking and non-blocking assignments for registers simulate
incorrectly because simulators evaluate blocking assignments in a different
simulation event region than non-blocking assignments. This causes race
conditions where signals bypass pipeline stages, leading to simulation-synthesis
mismatches.
If your next-state generation logic requires blocking assignments to state
clearly, use a separate combinational-only block to generate that next-state
value.
For reusable IP, it is recommended that registers support all three forms of
reset so integrators can tie off unused resets:
- Synchronous reset
- Asynchronous reset
- Initialization (configuration-time initial values for FPGA designs)
Initialization is commonly recommended for SRAM-based FPGAs, whereas synchronous
reset is recommended for ASICs.
A correctly implemented 8-bit register with an initial value of "0xAB" would be
implemented as follows:
<div class='goodcode'></div>
```verilog
logic foo_le;
logic [7:0] foo, foo_next;
initial foo = 8'hAB; // initialization
always @(posedge clk or posedge arst) begin
if (arst) begin
foo <= 8'hAB;
end else if (rst) begin
foo <= 8'hAB;
end else if (foo_le) begin
foo <= foo_next;
end
end
```
Do not allow multiple non-blocking assignments to the same bit.
Example:
<div class='badcode'></div>
```verilog
if (cond1) begin
abc <= 4'h1;
end
if (cond2) begin
abc <= 4'h2;
end
```
If both cond1 and cond2 are true, the Verilog standard says that the second
assignment will take effect, but this is a style violation.
Even if cond1 and cond2 are mutually exclusive, make the second "if" into an
"else if".
Exception: It is fine to set default values first, then specific values.
However, it is recommended to do this work in a separate combinational block
with explicit blocking assignments.
Example:
<div class='goodcode'></div>
```verilog
`ASSERT_KNOWN(state_is_known_A, state, clk, rst)
always @(posedge clk) begin
s1 <= s1_default;
s2 <= s2_default;
s3 <= s3_default;
unique case (state)
kState1: begin
s1 <= real_s1_value;
end
kState2: begin
s1 <= real_s1_value;
s2 <= real_s2_value;
end
kState3: begin
s3 <= real_s3_value;
end
default: ; // empty default, ensures case statement is fully specified
endcase
end
```
Keep work in sequential blocks simple. If a sequential block becomes
sufficiently complicated, consider splitting the combinational logic into a
separate combinational (`always_comb`) block. It's recommended for a sequential
block to contain only a register instantiation, with perhaps a load enable or an
increment.
<a id="resets"></a>
### Resets
[Reusable IP](#reusable-ip) must consistently implement all three varieties of
reset (synchronous reset, asynchronous reset, and configuration-time
initialization) so that the non-preferred reset schemes can be disabled at
implementation time. See [Sequential Logic](#sequential-logic-registers) for
more details.
<a id="delays"></a>
### Delay Modeling
<span class="Summary">Do not use `#delay` in synthesizable design modules.
</span>
Synthesizable design modules must be designed around a zero-delay simulation
methodology. All forms of `#delay`, including `#0`, are not permitted.
<a id="delay-units"></a>
#### Delays and Time Units
<span class="Summary">In non-synthesizable code always specify a time unit if
`#delay` is used, except for `#0`.</span>
Whenever using non-zero pound `#` delays, always specify a time unit in addition
to the raw number, to avoid timescale issues.
<div class='goodcode'></div>
```verilog
q <= #10ns d;
#(wait_in_ns * 1ns);
#0; // Special case. No time units required
```
<div class='badcode'></div>
```verilog
// Missing time units.
q <= #10 d;
#wait_in_ns;
```
Note that specifying time units alone does not guarantee proper behavior. Use
project-wide `timeunit` and `timeprecision` settings in your module, package, or
interface to ensure the proper behavior (see section 3.14.2.2 of the 1800-2017
LRM for more details).
<a id="finite-state-machines"></a>
### Finite State Machines
<span class="Summary">State machines use an enum to define states, and are
implemented with two process blocks: a combinational block and a clocked block.
</span>
Every state machine description has three parts:
1. An enum that declares and describes the states.
1. A combinational process block that decodes state to produce next state and
other combinational outputs.
1. A clocked process block that updates state from next state.
*Enumerating States*
The enum statement for the state machine must list each state in the state
machine. Comments describing the states must be deferred to the case statement
in the combinational process block, as shown in the following example.
States must be named in `kCamelCase`, like other
[enumeration constants](#enumerations).
Barring special circumstances, the initial idle state of the state machines will
be named `kIdle`. (Alternate names are acceptable if they improve clarity.)
It's recommended for each module to only contain one state machine. If your
module needs more than one state machine, you will need to add a unique prefix
(or suffix) to the states of each state machine, to distinguish which state is
associated with which state machine. For example, a module with a "reader"
machine and a "writer" machine might have a `kRdIdle` state and a `kWrIdle`
state.
*Combinational Decode of State*
The combinational process block must contain:
- A case statement that decodes state to produce next state and combinational
outputs. For clarity, only cases where the output value deviates from the
default must be coded.
- Before the case statement must be a block of code that defines default
values for every combinational output, including "next state."
- The default value for the "next state" variable must be the current state.
The case statement that decodes state will then only assign to "next state"
when transitioning between states.
- Within the case statement, each state alternative must be preceded with a
comment that describes the function of that state within the state machine.
*The State Register*
No logic except for reset must be performed in this process. The state variable
must latch the value of the "next state" variable.
*Other Guidelines*
When possible, try to choose state names that differ near the beginning of their
name, to make them more readable when viewing waveform traces.
*Example*
<div class='goodcode'></div>
```verilog
// Define the states
typedef enum logic [1:0] {
kIdle, kFrameStart, kAccStoreWrite, kBandEnd
} fsm_state_t;
fsm_state_t state_next, state;
// Combinational decode of the state
// Check that frame_start is not X since it is used in an if statement
`ASSERT_KNOWN(frame_start_is_known_A, frame_start, clk, rst)
always_comb begin
state_next = state;
foo = 1'b0;
bar = 1'b0;
bum = 1'b0;
unique case (state)
// kIdle: waiting for frame_start
kIdle:
if (frame_start) begin
foo = 1'b1;
state_next = kFrameStart;
end
// kFrameStart: Reset accumulators
kFrameStart: begin
// ...
end
kAccStoreWrite: begin
// ...
end
kBandEnd: begin
// ...
end
default: begin
// X's in the inputs propagate to X's in the outputs (Number of states is
// a power of two, therefore case is fully specified and no don't-care
// behavior will be introduced).
// See "Don't-care in case statements" section for information on
// case statements with non-power-of-two items or the X_OF_TYPE macro.
state_next = `X_OF_TYPE(fsm_state_t);
foo = 'X;
bar = 'X;
bum = 'X;
end
endcase
end
// Latch state
always_ff @(posedge clk) begin
if (rst) begin
state <= kIdle;
end else begin
state <= state_next;
end
end
```
<a id="combinational-logic"></a>
<a id="comb-logic"></a>
## Combinational Logic
<a id="comb-logic-use-always-comb"></a>
### Use `always_comb` or `assign`
<span class="Summary">Avoid sensitivity lists.</span>
Use either `always_comb` blocks or `assign` statements for combinational logic.
<a id="comb-logic-use-blocking-assignments"></a>
### Use blocking assignments
<span class="Summary">Synthesizable combinational process blocks must only use
blocking assignments.</span>
All assignments within a synthesizable
[`always_comb` block](#comb-logic-use-always-comb) must be blocking assignments.
Non-blocking assignments are used only in
[sequential logic blocks](#seq-logic-use-non-blocking).
<a id="x-propagation"></a>
### X Propagation
<span class="Summary">Either propagate `X`'s, or catch them via assertions. Do
not silently squash `X` in logic.</span>
Write logic that will either propagate `X` or assert when your inputs are `X`.
Avoid silently squashing `X` by writing logic that resolves an `X` input to a
non-`X` output. Instead, write logic that either explicitly propagates the `X`
or uses an assertion to raise an exception when an input is `X`.
<a id="logical-operations-and-if-statements"></a>
#### Logical operations and `if` statements
Note that logical operations involving `X` will propagate `X` in a way that
accurately represents silicon behavior.
Example:
<div class='goodcode'></div>
```verilog
$display("%b", 1'bx == 1'b1); // produces 1'bx
$display("%b", 1'bx != 1'b1); // produces 1'bx
$display("%b", 1'bx & 1'b1); // produces 1'bx
$display("%b", 1'bx & 1'b0); // produces 1'b0
$display("%b", 1'bx | 1'b0); // produces 1'bx
$display("%b", 1'bx | 1'b1); // produces 1'b1
$display("%b", !(1'bx)); // produces 1'bx.
```
However, when evaluated in a boolean context, `X` always evaluates to false. As
a result, typical `if`/`else` statements do not propagate `X` in a way that
accurately represents silicon behavior.
Example:
<div class='badcode'></div>
```verilog
always_comb begin
if (value) result = 1'b0; // value is 1'b1
else result = 1'b1; // value is 1'b0 or 1'bx
end
```
This can mask subtle problems in code and produce a mismatch between simulation
and synthesis.
Instead, use conditional operators, which will propagate an `X`. If that hurts
readability, an alternative is to use assertions to catch `X`.
<div class='goodcode'></div>
```verilog
always_comb begin
result = value ? 1'b1 : 1'b0; // 1'bx produces 1'bx
end
```
<div class='goodcode'></div>
```verilog
`ASSERT_KNOWN(value_is_known_A, value, clk, rst)
always_comb begin
if (value) result = 1'b0; // value is 1'b1
else result = 1'b1; // value is 1'b0 or 1'bx
end
```
Another alternative is to have explicit `if` and `else if` clauses for `0` and
`1`. However, this is verbose and more difficult to maintain.
<div class='goodcode'></div>
```verilog
always_comb begin
if (value) result = 1'b0; // value is 1'b1
else if (!value) result = 1'b1; // value is 1'b0
else result = 1'bx; // value is 1'bx
end
```
<a id="x_prop_case_statements"></a>
<a id="x-prop-case-statements"></a>
#### X Propagation in Case Statements
See [Case Statements](#case-statements) for guidance and examples.
<a id="x_prop_array_indexing"></a>
<a id="x-prop-array-indexing"></a>
#### Array indexing
Writing into an array when the index is `X` does not propagate the `X` to the
array contents.
<div class='badcode'></div>
```verilog
// An X in index gets silently squashed in simulation.
assign buf[index] = foo;
```
Instead, assertions must be used to catch `X` in the array index.
<div class='goodcode'></div>
```verilog
`ASSERT_KNOWN(index_is_known_A, index, clk, rst)
assign buf[index] = foo;
```
<a id="x_prop_clocks_and_resets"></a>
<a id="x-prop-clocks-and-resets"></a>
#### Clocks and Resets
The preceding X propagation guidelines do not apply to clocks and resets.
Instead, extra care must be taken at each clock-domain level in the hierarchy to
ensure clocks and resets are never driven to `X` along with `!$isunknown()`
assertions.
The reason for this is that the recommended coding styles for sequential logic
do not propagate `X` on clocks and resets. For example, `posedge clk` still
triggers on a `0` to `X` transition. Also, synthesis tools recommend using `if`
statements for asynchronous resets instead of conditional operators.
<a id="further-discussion"></a>
#### Further discussion
- ["I'm Still In Love With My X!"](http://sutherland-hdl.com/papers/2013-DVCon_In-love-with-my-X_paper.pdf)
by Stuart Sutherland
- ["Being Assertive With Your X"](http://lcdm-eng.com/papers/snug04_assertiveX.pdf)
by Don Mills
<a id="dont-care-assignments"></a>
### Don't-Care Assignments
<span class="Summary">Do not specify don't-care logic in synthesizable code.
</span>
For the purposes of this document, don't-care logic is defined as the explicit
or implicit assignment to `X` based on known (non-`X`) inputs. Don't-care logic
is a subset of unknown logic values, and not all assignments to `X` are
considered don't-care logic. For examples of allowed assignments to `X`, see
[X Propagation](#x-propagation).
Don't-care assignments are problematic for automated engineering change orders
(ECOs) and complicate Logic Equivalence Checking (LEC) between netlists because
synthesis can produce netlists that have chosen conflicting interpretations of
the don't-care states. If designers need to take advantage of don't-care space
for optimizations, there are external tools like [Espresso][espresso] that can
be used instead.
[espresso]: https://en.wikipedia.org/wiki/Espresso_heuristic_logic_minimizer
<a id="dont-care-explicit-assignments"></a>
##### Don't-Care in Explicit Assignments
Do not assign don't-care logic. A signal must be known if the signals driving it
are known.
<div class='badcode'></div>
```verilog
// Bad: When valid is '0', wdata is considered don't-care
assign wdata = valid ? data : 'x;
assign we = valid;
```
<div class='goodcode'></div>
```verilog
assign wdata = data;
assign we = valid;
```
<a id="dont-care-in-case-statements"></a>
##### Don't-Care in Case Statements
See [Case Statements](#case-statements) for guidance on how to avoid introducing
don't-care logic in case statements.
<a id="dont-care-in-array-indexing"></a>
##### Don't-Care in Array Indexing
Do not access an index that is outside the bounds of an array. This can happen
if the array size is not a power-of-two, or if the index contains superfluous
MSBs.
<div class='badcode'></div>
```verilog
// For values of index > 4, the output ‘foo’ is treated as don’t-care
logic foo;
logic [2:0] index;
logic [4:0] buffer;
...
assign foo = buffer[index];
```
Instead, specify behavior for out-of-range indices or explicitly pad arrays up
to power-of-two sizes. Also, add an assertion to catch out-of-range indices.
<div class='goodcode'></div>
```verilog
localparam BufferSize = 5;
logic foo;
logic [2:0] index;
logic [BufferSize-1:0] buffer;
...
`ASSERT(index_within_array_bounds_A, (index < BufferSize), clk, rst)
// This approach specifies the behavior for out-of-range indices.
// It is concise but might require a lint waiver
assign foo = (index < BufferSize) ? buffer[index] : '0;
logic bar;
logic [7:0] buffer_padded;
// This approach explicitly pads out the array. It eliminates the need for lint
// waivers, but it can be less concise.
assign buffer_padded = {3'b0, buffer}; // zero-pad the array
assign bar = buffer_padded[index];
```
Properly handling arbitrary array sizes is complex. It is recommended that
projects use the standard [`BOUNDED_LOOKUP` macro](#bounded-lookup-macro) for
the general case.
<div class='goodcode'></div>
```verilog
assign foo = `BOUNDED_LOOKUP(buffer, index)
```
<a id="tri-state-logic"></a>
### Tri-State Logic
Do not use three-state logic (`Z` state) to accomplish on-chip logic such as
muxing.
<a id="case_statements"></a>
<a id="case-statements"></a>
### Case Statements
<span class="Summary">Use `unique case` in synthesizable RTL. Always define a
default case-item. Do not specify [don't-care](#dont-care-assignments) behavior.
Do not use case-modifying pragmas.</span>
Here is an example of a style-compliant case statement:
<div class='goodcode'></div>
```verilog
always_comb begin
unique case (select)
2'b00: foo = bar0;
2'b01: foo = bar1;
2'b10: foo = bar2;
2'b11: foo = bar3;
default: foo = 'X;
endcase
end
```
The `unique` prefix is recommended before all case statements, as it creates
simulation assertions that can catch certain mistakes. In some cases, `priority`
may be used instead of `unique`, though `if-else-if` structures are a more
readable representation for priority encoders. Code other than synthesizable RTL
can use `case` without `unique` or `priority` if necessary.
Be sure to use `unique case` correctly. In particular, outputs for any
unspecified case-items are treated as don't-care by the synthesis tools. This
can lead to a simulation-synthesis mismatch as described in
[Don Mills' paper][yalagp]. Including a `default` case-item ensures the case
statement is always fully defined, which helps avoid unintuitive don't-care
behavior.
The `default` case-item is also required to avoid accidental inference of
latches, even if all cases are covered. In simulation, a case expression that
evaluates to `X` will not match any case and will behave as a latch, leading to
different behavior than synthesis. Instead, in most scenarios, the best choice
is to propagate the `X` by assigning all output variables to `X` by default.
Note that the SystemVerilog-2009 `unique0` keyword is not currently supported by
all tools.
<a id="wildcards-in-case-items"></a>
#### Wildcards in case items
Use `case` instead of `casez` whenever wildcard operator behavior is not
required. When wildcard behavior is needed, use `casez`.
When expressing a wildcard in a case item, use the '?' character since it more
clearly expresses the intent.
Here is an example of a style-compliant `casez` statement:
<div class='goodcode'></div>
```verilog
always_comb begin
unique casez (select)
3'b000: operand = accum0 >> 0;
3'b001: operand = accum0 >> 1;
3'b010: operand = accum1 >> 0;
3'b011: operand = accum1 >> 1;
3'b1??: operand = regfile[select[1:0]];
default: operand = 'X; // propagate X
endcase
end
```
`casex` must not be used. `casex` implements a symmetric wildcard operator such
that an `X` in the case expression may match one or more case items. `casez`
only treats high-impedance states (`Z` or `?`) as a wildcard, and performs exact
matches for undriven `X` inputs. While this does not completely fix the problems
with symmetric wildcard matching, it is harder to accidentally produce a `Z`
input than an `X` input, so this form is preferred.
<a id="dont-care-in-case-statements2"></a>
##### Don't-care in case statements
[Don’t-care](#dont-care-assignments) behavior is introduced anytime `X`
assignments are made from a don’t-care branch of a case statement.
To avoid don't-care behavior, specify non-`X` behavior for all outputs, across
the full range of values in the case-expression. If this prevents x-propagation,
assertions must be used to ensure `X`'s in the case-expression are not silently
squashed.
<div class='badcode'></div>
```verilog
typedef enum logic [1:0] {kMode0, kMode1, kMode2} mode_t;
mode_t mode;
always_comb begin
unique case (mode)
kMode0: foo = bar0;
kMode1: foo = bar1;
kMode2: foo = bar2;
default: foo = 'x; // foo is don't-care when mode = 2'b11;
endcase
end
```
<div class='goodcode'></div>
```verilog
typedef enum logic [1:0] {kMode0, kMode1, kMode2} mode_t;
mode_t mode;
`ASSERT_KNOWN(mode_is_known_A, mode, clk, rst)
always_comb begin
unique case (mode)
kMode0: foo = bar0;
kMode1: foo = bar1;
kMode2: foo = bar2;
default: foo = '0; // explicit default value to avoid don't-care behavior
endcase
end
```
Note that assigning to `X` from the default case-item of an otherwise
fully-specified case statement does not introduce don’t-care logic. In this
case, using the default for x-propagation is the recommended style.
<div class='goodcode'></div>
```verilog
typedef enum logic [1:0] {kMode0, kMode1, kMode2, kMode3} mode_t;
mode_t mode;
always_comb begin
unique case (mode)
kMode0: foo = bar0;
kMode1: foo = bar1;
kMode2: foo = bar2;
kMode3: foo = bar3;
default: foo = 'X; // default can be used for x-propagation here,
// since the case statement is otherwise complete
endcase
end
```
If assigning X to an enumerated type in the default case-item, then the
assignment must be typecast. It is recommended that projects use a
[macro](#x-of-type-macro) to safely contain this cast.
<div class='goodcode'></div>
```verilog
typedef enum logic [1:0] {kFoo0, kFoo1, kFoo2, kFoo3} foo_t;
foo_t foo1, foo2;
always_comb begin
unique case (foo1)
kFoo0: foo2 = kFoo0;
kFoo1: foo2 = kFoo1;
kFoo2: foo2 = kFoo2;
kFoo3: foo2 = kFoo3;
default: foo2 = `X_OF_TYPE(foo_t); // typecast for X in default
endcase
end
```
With multiple outputs, it can be convenient to specify default values outside of
the case statement. If this is done, the `unique case` statement must be fully
specified, otherwise these outputs are treated as don't-cares for any
unspecified case-items.
<div class='goodcode'></div>
```verilog
`ASSERT_KNOWN(mode_is_known_A, mode, clk, rst)
always_comb begin
// Default behavior
out0 = in0;
out1 = in1;
unique case (mode)
kForceLow: {out1, out0} = '0;
kForceHigh: {out1, out0} = '1;
default: ; // empty default, ensures case statement is fully specified
endcase
end
```
<a id="upside-down-unique-case-statements"></a>
##### Upside-down unique case statements
Upside-down unique case statements are another way of introducing don't-care
behavior. If multiple conditions of the upside-down case statement are true, the
output assignment is not explicitly provided in the code, effectively leading to
a don't-care assignment. This will cause the same LEC and ECO issues as if the
condition was explicitly coded as an X output. See
[Don't-Care Assignments](#dont-care-assignments). It is recommended to rewrite
the code as a non-upside-down case statement, or do manual logic reduction if
timing is a concern.
<div class='badcode'></div>
```verilog
// If c_grant[0] == 1 and c_grant[1] == 1, out is don't-care.
always_comb begin
unique case (1'b1)
c_grant[0]: out = 1'b0;
c_grant[1]: out = 1'b1;
default: out = 1'b0;
endcase
end
```
<div class='goodcode'></div>
```verilog
// If c_grant[0] == 1 and c_grant[1] == 1, out is explicitly 0.
always_comb begin
unique case (c_grant)
2'b01: out = 1'b0;
2'b10: out = 1'b1;
default: out = 1'b0;
endcase
end
```
<a id="synthesis-pragmas-in-case"></a>
##### Synthesis Pragmas
Never use either the `full_case` or `parallel_case` pragmas. These pragmas can
easily cause synthesis-simulation mismatches. This is a subset of the
[general guidance to avoid synthesis pragmas](#synthesis-pragmas).
References:
* Don Mills, [Yet Another Latch and Gotchas Paper][yalagp]
* Clifford Cummings,
[SystemVerilog-2009 Enhancements: ‘priority’, ‘unique’, ‘unique0’][priuniq]
* Sutherland, Mills, and Spear,
[Gotcha Again: More Subtleties in the Verilog and SystemVerilog Standards...][gotagain]
[yalagp]: http://lcdm-eng.com/papers/snug12_Paper_final.pdf
[priuniq]: https://dvcon-proceedings.org/wp-content/uploads/systemverilog-2009-enhancements-priority-unique-unique.pdf
[gotagain]: http://lcdm-eng.com/papers/snug07_Verilog%20Gotchas%20Part2.pdf
<a id="signed-arithmetic"></a>
### Signed Operations
<span class="Summary">Use the available signed operator constructs wherever
signed operations are used.</span>
Mixing signed and unsigned signals in an operation can result in unexpected
behavior and, in some cases, simulation-synthesis mismatches. For all operations
where signed and unsigned signals need to be used together, the unsigned signals
must first be explicitly cast to signed, using the `signed'` cast operator.
If any operand in a calculation is unsigned, Verilog implicitly casts all
operands to unsigned and generates a warning. There must not be any
signed-to-unsigned warnings from either the simulation or synthesis tools if all
unsigned variables are properly cast.
<a id="mixed-sign-arithmetic-operations"></a>
##### Mixed-Sign Arithmetic Operations
Explicitly cast unsigned values to signed before use in mixed-sign arithmetic
operations.
<div class='goodcode'></div>
```verilog
logic signed [7:0] a = 8'sh80; // equals signed(-128)
logic incr = 1'b1; // equals unsigned(1)
logic signed [15:0] sum;
always_comb begin
sum = a + signed'({1'b0, incr}); // Good: explicitly casting incr to signed
// produces expected sum equals signed(-127)
end
```
<div class='badcode'></div>
```verilog
logic signed [7:0] a = 8'sh80; // equals signed(-128)
logic incr = 1'b1; // equals unsigned(1)
logic signed [15:0] sum;
always_comb begin
sum = a + incr; // Bad: mixed-sign addition results in implicit cast of `a`
// giving sum equals signed(129) instead of signed(-127) as
// expected
end
```
<a id="mixed-sign-comparison-operations"></a>
##### Mixed-Sign Comparison Operations
Explicitly cast unsigned values to signed before use in mixed-sign comparison
operations.
<div class='goodcode'></div>
```verilog
logic [7:0] unsigned_foo = 8'h00; // equals unsigned(0)
logic signed [7:0] signed_bar = 8'shFF; // equals signed(-1)
logic bar_less_than_foo;
logic bar_less_than_zero;
always_comb begin
// Good: Explicitly casting `foo` to signed so comparison returns `true` as
// expected
bar_less_than_foo = (signed_bar < signed'({1'b0, unsigned_foo}));
// Good: Explicitly declare constant as signed decimal ensures consistent
// compiler-to-compiler behavior.
bar_less_than_zero = (signed_bar < 'sd0);
end
```
<div class='badcode'></div>
```verilog
logic [7:0] unsigned_foo = 8'h00; // equals unsigned(0)
logic signed [7:0] signed_bar = 8'shFF; // equals signed(-1)
logic bar_less_than_foo;
logic bar_less_than_zero;
always_comb begin
// Bad: Mixed-sign comparison returns unexpected `false`
bar_less_than_foo = (signed_bar < unsigned_foo);
// Bad: Non-explicitly signed constant results in inconsistent behavior
// with different tools
bar_less_than_zero = (signed_bar < 0);
end
```
<a id="arithmetic-right-shift-operations"></a>
##### Arithmetic Right Shift Operations
Always use the `>>>` operator instead of the `>>` operator when arithmetically
right shifting signed values.
It is common practice to use right arithmetic shift operators to divide by
powers of 2. With signed operands, care must be taken that the correct shift
operator is used to preserve sign. The `>>` operator inserts a 0 at the most
significant bit location. If the argument is a negative value, this will flip
the sign. By using the `>>>` operator, the bit inserted at the most significant
bit location is determined by the sign of the argument and will not flip.
<div class='goodcode'></div>
```verilog
logic signed [7:0] foo = 8'sh80; // equals signed(-128)
logic signed [7:0] bar;
always_comb begin
bar = foo >>> 1; // Good: returns signed(-64)
end
```
<div class='badcode'></div>
```verilog
logic signed [7:0] foo = 8'sh80; // equals signed(-128)
logic signed [7:0] bar;
always_comb begin
bar = foo >> 1; // Bad: returns signed(64). The `>>` operator inserts a 0 at
// the most significant bit location, thereby flipping the
// sign of `bar`.
end
```
<a id="signal-widths"></a>
### Bit Widths
<span class="Summary">Be careful about signal and expression widths.</span>
<a id="number-literals"></a>
#### Always be explicit about the widths of number literals.
Always explicitly size number literals to match their final width. Verilog's
implicit zero-extension and truncation operations can lead to subtle bugs.
If the literal is specified in a binary format then all digits must be
explicitly written out to avoid unintentional zero-extension in the most
significant bits. This can catch subtle bugs if an intermediate bit is dropped.
Literals written in decimal and hexadecimal formats do not need to explicitly
include all significant digits because they tend not to be used for hard-to-read
patterns.
Exceptions:
* When using literals in expressions with parameterized widths, it is
acceptable to use integers without an explicit width (for example, `foo =
bar + 1`) to avoid contrivances such as `{{(Bus_width-1){1'b0}},1'b1}`. The
language will properly pad 0s if the literal is narrower than the expression
width and lint tools typically raise an error if the literal is wider than
the expression width.
* It is acceptable to use the `'0` or `'1` literals to automatically create
correctly sized (context-determined) zero or "all ones".
* For literals assigned to integer variants (for example, `bit`, `byte`,
`shortint`, `int`, `integer`, and `longint`) the explicit width is optional.
Examples:
<div class='goodcode'></div>
```verilog
localparam int Width = 5; // int doesn't need explicit width
localparam bit FeatureFlag = 1; // bit type doesn't need explicit width
localparam logic [3:0] Bar = 4'd4;
logic [15:0] foo1, foo2, foo3, foo4;
logic [7:0] foo5;
logic [63:0] foo6;
logic [Width-1:0] foo7, foo8;
assign foo1 = 16'd2; // OK to not have the tens column
assign foo2 = '0; // automatically sized 0 is ok
assign foo3 = {16{1'b1}}; // explicit "all ones"
assign foo4 = '1; // automatically sized "all ones"
assign foo5 = 8'b0010_1111; // exact width literal, no implicit zero-extension
assign foo6 = 64'h2000; // OK not to write out the whole hex constant
// OK to not explicitly size the integer literal in a parameterized expression
assign foo7 = foo8 + 4;
```
<div class='badcode'></div>
```verilog
localparam logic [3:0] Bar = 4;
logic [7:0] foo1, foo2, foo3, foo4;
assign foo1 = 2; // literal is not explicitly sized
assign foo2 = 2'd2; // 2-bit literal implicitly 0 extended to 8 bits
assign foo4 = 8'b001_1111; // MSb is missing and has implicit zero-extension
```
<a id="do-not-use-multi-bit-signals-in-a-boolean-context"></a>
#### Do not use multi-bit signals in a boolean context
Rather than letting boolean operations and if expressions reduce a multi-bit
signal to a single bit, explicitly compare the multi-bit signal to 0. The
implicit conversion can hide subtle logic bugs.
Examples:
<div class='goodcode'></div>
```verilog
logic [3:0] a, b;
logic out;
assign out = (a != '0) && (b == '0); // Good: Explicit comparisons
always_comb begin
if (a != '0) begin // Good: Explicit comparison
// ...
end
end
logic any_a;
// Good: Unary reductions are okay in a boolean context.
assign any_a = |a;
always_comb begin
if (&a) begin
// ...
end
end
```
<div class='badcode'></div>
```verilog
logic [3:0] a, b;
logic out;
// Bad: Incorrect because it implicitly converts 4-bit signals to 1-bit before
// AND. Also, !b is different from ~b and can be hard to catch.
assign out = a && !b;
// Bad: Incorrect use of a multi-bit signal in an if expression.
always_comb begin
if (a) begin
// ...
end
end
```
<a id="prefer-logical-operators-single-bit-signals"></a>
#### Prefer Logical Operators for Single-Bit Signals
<span class="Summary">When performing logical operations on single bit signals,
it is recommended to use the logical operators (for example, &&, ||, !) instead
of bitwise operators (for example, &, |, ~).</span>
<div class='goodcode'></div>
```verilog
logic a, b, c;
...
// This aids readability as the logical operator makes clear `a` and `b`
// are single-bit signals.
assign c = a && b;
```
<div class='goodcode'></div>
```verilog
logic a, b, c;
...
// `a` and `b` could be multi-bit vectors, it is not clear from the assignment.
assign c = a & b; // Not recommended
```
<a id="handling-width-overflow"></a>
#### Handling Width Overflow
Beware of shift operations, which can produce a result wider than the operand.
Bit-selection and concatenation may be clearer than shifting by a constant
amount.
Addition and negation operations produce a result one bit wider than the
operands, due to carry. An allowable exception to the rule about matching widths
is to silently drop the carry on assignment.
Example:
<div class='goodcode'></div>
```verilog
assign abc_next = abc + 4'h1;
```
<a id="bit-slicing"></a>
### Bit Slicing
Only use the bit slicing operator when the intent is to refer to a portion of a
bit vector.
Examples:
<div class='goodcode'></div>
```verilog
logic [7:0] a, b;
logic [6:0] c;
assign a = 8'd7; // Good
assign a[7:1] = 7'd5; // Good: it's partial assignment.
assign a = b; // Good: the parser would warn on width mismatch.
```
<div class='badcode'></div>
```verilog
logic [7:0] a, b;
assign a[7:0] = 8'd7; // Bad: redundant and can mask linter warnings.
assign a = b[7:0]; // Bad: redundant and masks linter warnings.
```
<a id="alias-statement"></a>
### Alias statement
<span class="Summary">Do not use `alias`, use port connection if possible or
`tran` if you must.</span>
`Alias` statement can be used to connect `inout` nets, but there is a history
for `alias` statement to not be supported by EDA tools (as of 2019). Hence do
not use `alias`. The recommended alternatives are using conventional port
connections, if possible, or `tran` (a bidirectional pass switch) to connect
ports.
<a id="implicitly-sized-expressions"></a>
### Implicitly Sized Expressions
<span class="Summary">Do not rely on the width of implicitly sized
sub-expressions.</span>
Instead, when requiring that a sub-expression produce a result of a specific
width, either:
* Cast the sub-expressions to specific widths (note that this may cause a
truncation).
* Break compound expressions into separate partial result variables.
The bit lengths of self-determined expressions (summarized in Table 11-21 of the
[SystemVerilog-2017 standard]) are counter-intuitive (for example, `a * b`
produces a result of length `max($bits(a), $bits(b))`). To avoid these gotchas,
it is best to not rely on implicitly sized results at all.
For example, the following code is wrong:
<div class='badcode'></div>
```verilog
module compose_bitmap (
input logic en_a,
input logic en_b,
output logic [7:0] en_bitmap);
assign en_bitmap = {(en_a << 4), (en_b << 4)};
endmodule
```
The expression in the preceding example synthesizes to zero, because
(surprisingly) the length of the implicitly sized expression `en_a << 4` is 1
(`$bits(en_a)`).
A correct implementation would explicitly size each expression, either by adding
explicit sizes to the sub-expressions:
<div class='goodcode'></div>
```verilog
assign en_bitmap = {4'(en_a << 3), 4'(en_b << 3)};
```
Or by decomposing the expression into explicitly sized partial results:
<div class='goodcode'></div>
```verilog
logic [3:0] en_a_bitmap;
logic [3:0] en_b_bitmap;
assign en_a_bitmap = en_a << 3;
assign en_b_bitmap = en_b << 3;
assign en_bitmap = {en_a_bitmap, en_b_bitmap};
```
<a id="conventions"></a>
## Design Conventions
<a id="design-conventions-summary"></a>
### Summary
The key ideas in this section include:
* Use a consistent [timescale](#timescale) for all RTL.
* [Use flow control consistently](#flow-control).
* [Use clock domain crossing consistently](#synchronization).
* [Rules for top-level implementation](#top-level-implementation).
* [Prefer to register module outputs](#registered-inputs-and-outputs).
<a id="timescale"></a>
### Timescale
<span class="Summary">Every project must define a consistent way of specifying
timescale.</span>
There are multiple ways to specify the timescale, each with pros and cons. Each
project must define a single way to specify the timescale for the entire
project. Individuals must not implement one-off timescale solutions.
<a id="bus-protocol-naming"></a>
### Bus Protocols
Bus protocols are commonly used to connect components of the chip. When using an
industry standard protocol, use the terminology established by that protocol.
When designing a new protocol, the agent that controls the bus or initiates
transactions is named the `requester` while the agent that services the
transaction is the `completer`.
* Be sure to follow the
[guidance on inclusive language in external IP](#non-inclusive-language-in-external-ip).
Change non-inclusive industry standard names as appropriate.
* If a communication protocol has a pattern that doesn't map to
`requester/completer` it is ok to use more accurate names (for example,
leader and follower). This guidance is intended to standardize the common
case.
<a id="flow-control"></a>
### Flow Control
<span class="Summary">Standardize flow control using Ready/Valid semantics
wherever possible.</span>
Flow control is often used to facilitate back pressure as data moves through a
pipeline.
The recommended flow control semantic is the [Ready/Valid](#ready-valid)
semantic. Experience shows that connecting two modules with inconsistent flow
control semantics is a common source of hard-to-catch errors.
If an interface is defined without flow control, a comment must explain why flow
control and back pressure are unnecessary in that particular case.
<a id="struct-usage"></a>
#### Struct Usage
<span class="Summary">Do not group flow control and data signals in the same
struct. All data signals in a struct must share the same flow control.</span>
When grouping data signals, flow control signals must not be included in the
same structure as the data they are qualifying. Additionally, all data signals
in the structure must have the same flow control behavior and be qualified by
the same external flow control signals. Otherwise, use of the structure could
easily lead to data propagation bugs.
<div class='goodcode'></div>
```verilog
typedef struct packed {
logic rw;
foo_address_t addr;
foo_data_t data;
} foo_t;
foo_t foo;
logic foo_valid; // Good: this is the flow control signal for foo.
bar_interrupt_t bar_intr; // Good: this has different flow control than foo.
```
<div class='badcode'></div>
```verilog
typedef struct packed {
logic rw;
foo_address_t addr;
foo_data_t data;
logic valid; // Bad: this is the flow control signal.
bar_interrupt_t intr; // Bad: this data signal is not qualified by valid.
} foo_t;
foo_t foo;
```
<a id="ready-valid"></a>
#### Ready/Valid
<span class="Summary">Ready/Valid semantics express the recommended method of
flow control.</span>
Ready/Valid semantics mimic the requirements of the AXI handshake process, as
defined in the
[AMBA AXI Protocol Specification](https://developer.arm.com/documentation/ihi0022/latest/).
With Ready/Valid semantics, the sender uses the Valid signal to advertise that a
data transfer is available. The receiver generates the Ready signal to indicate
that it can accept a data transfer. The transfer only occurs on any cycle where
Ready and Valid are both asserted.
The Ready signal must be identified with the "\_ready" suffix. The Valid signal
must be identified with the "\_valid" suffix. The other signals in the data
transfer must share a prefix with the Ready and Valid signals (for example:
"foo\_ready", "foo\_valid", "foo\_data1", "foo\_data2", etc.).
Once Valid is asserted it must remain asserted until the data transfer occurs.
For interfaces using `_valid_next`, once `_valid_next` is asserted in a given
cycle, the data transfer is scheduled for the next clock cycle; if `_ready` is
not asserted on that next cycle, the data transfer remains pending and the data
must remain held constant until the transfer completes.
Once Valid is asserted, the data bus must be held constant until the data
transfer occurs.
Once Ready is asserted, the receiver is permitted to deassert Ready at any time.
On the sender interface, there may be no combinational path between input and
output signals. The receiver, however, is permitted to produce `ready`
combinationally from inputs such as `valid` or data.
NOTE: This is at odds with the AXI4 specification, which forbids combinational
paths between inputs and outputs.
Some modules might have important reasons to change this protocol. If the
assumptions of this protocol are violated, use a different signal name
convention to clearly indicate that the standard Ready/Valid semantics are not
in force. For example, if your protocol permits a "skid" of an extra data
transfer after Valid gets de-asserted, consider documenting this in the signal
name (for example, "foo\_valid\_for\_two").
`wr_en` or `rd_en` are acceptable proxies for Valid, when appropriate.
<a id="credit-valid"></a>
#### Credit/Valid
Credit/Valid flow control decouples data transmission from flow-control feedback
using a credit counter, making it suitable for long-distance, wide, or
high-frequency pipelines where single-cycle Ready/Valid backpressure is
impractical.
<a id="req_ack"></a>
<a id="req-ack"></a>
#### Req/Ack
<span class="Summary">Req/Ack semantics express an alternate method of flow
control.</span>
Req/Ack semantics are functionally equivalent to
[Ready/valid semantics](#ready-valid). [Ready/Valid](#ready-valid) is the
recommended style for most new code. [Credit/Valid](#credit-valid) is
recommended to be considered for very long, very wide, or very high-speed buses.
A request and acknowledge interface is always defined by two signals:
- foo\_req: the request signal, which is asserted to request an event, and is
held active until the posedge of a clock cycle in which foo\_ack is
asserted.
- foo\_ack: the acknowledge signal, which is asserted on the cycle in which
the request is acknowledged. It is possible (likely, even) for foo\_ack to
be asserted within the same cycle that foo\_req is asserted.
Additional signals associated with this interface (in other words, information
that accompanies the request) must share a signal name prefix with the request
and acknowledge pair. These signals must be kept valid the entire time that
request is asserted.
If foo\_req is not asserted, no assumptions can be made about foo\_ack (the
receiver might choose to tie foo\_ack to 1'b1 if it can never stall) -- the
transmitter must only care about the state of foo\_ack on cycles where foo\_req
is valid.
For example:
<div class='goodcode'></div>
```verilog
output logic [63:0] write_to_fifo_data,
output logic write_to_fifo_req,
input logic write_to_fifo_ack
```
<a id="synchronization"></a>
### Synchronization
<span class="Summary">Users must avoid implementing their own CDC synchronizers
and instead rely upon a proven library implementation.</span>
<span class="Summary">Any module that contains CDC synchronizers must separate
and encapsulate logic for each clock domain in separate sub-modules.</span>
It is not acceptable to have combinational or sequential code written in the
same level of hierarchy that includes a CDC instantiation. If there are multiple
clock domains in a module, then all logic that belongs to each domain must be
separated from the others and encapsulated within one or more sub-modules.
*Exception:* CDC implementations (for example, from a design library) are not
subject to this rule. By design, they are required to mix logic from multiple
clock domains within the same module (at some level of hierarchy).
*Rationale:* Mixing functional logic from multiple clock domains in the same
module results in poor readability of combinational and sequential logic (for
example, extra [clock name prefix](#clock-domains) on signals in logical
expressions) and can increase the risk of accidental CDC bugs (for example,
crossing clock domains without a synchronizer). This style rule enforces
structural separation of logic that belongs to different clock domains.
<div class='goodcode'></div>
```verilog
module module_foo_bar (
...
);
// Good: Using CDC synchronizer lib module.
cdc cdc_foo_bar (.foo_clk, .bar_clk, ...);
// Good: "foo" clock domain submodules; no unwrapped logic in a module that
// instantiates a CDC.
submodule_0 submodule_0_foo (.clk(foo_clk), ...);
submodule_1 submodule_1_foo (.clk(foo_clk), ...);
// Good: "bar" clock domain submodules; no unwrapped logic.
submodule_2 submodule_2_bar (.clk(bar_clk), ...);
// Good: No inferred logic here, just a structural assignment, and both
// signals are clearly in the same clock domain.
assign bar_x = bar_y;
endmodule
```
<div class='badcode'></div>
```verilog
module module_foo_bar (
...
);
cdc cdc_foo_bar (.foo_clk, .bar_clk, ...);
// Bad: unwrapped combinational logic in a module that instantiates a CDC.
always_comb begin
// ... some foo_* combinational logic here ...
end
// Bad: unwrapped sequential logic in a module that instantiates a CDC.
always @(posedge bar_clk) begin
// ... some bar_* sequential logic here ...
end
// Bad: assign statement infers combinational logic in a module that
// instantiates a CDC.
assign bar_x = ^bar_y;
endmodule
```
<a id="top-level-implementation"></a>
### Top-level Implementation
<span class="Summary">A set of guidelines that emphasize maintainability of the
top-level implementation.</span>
The top-level implementation is a pain point for many designs. The following
recommendations focus on keeping top-level implementations simple and
maintainable.
The following practices are recommended:
- *No logic or registers* in the top-level instance. All logic is implemented
within sub-modules. The top level instance contains nothing but instances of
sub-modules.
- *Simple mapping of ports to signals*. The goal is to make the mapping of
ports onto signals as simple (and automatable) as possible. The best
practice is to have top-level signal names that are identical to port names.
When this is not practical, the following simple and consistent mapping
schemes represent the next best thing:
- a consistent renaming that maps all ports with one prefix to signals
with another prefix. For example, a set of "m\_axi\_\*" ports might be
mapped consistently to a set of "s05\_axi\_\*" wires.
- mapping a port to a slice of a larger bus. For example, an
`access_requestN` port might be connected to an `access_request[5]`
wire.
- if interfaces are being used, it may be necessary to create a consistent
instance name that is distinct from the interface name or modport name.
- Consider *automating* the production of your top-level block, using
automatic tools such as [verilogpp](https://github.com/google/verilogpp) .
<a id="registered-inputs-and-outputs"></a>
### Registered Inputs and Outputs
<span class="Summary">Strongly prefer to place module-boundary registers on
outputs.</span>
When placing module-boundary registers, it is strongly recommended that the
registers be placed on the module outputs, rather than the module inputs.
If the outputs of a non-trivial module aren't registered, this must be clearly
documented in the header comment of the module.
Top-level modules must have registered inputs and outputs for maximum top-level
routing flexibility.
It is assumed that inputs to all modules come from the output flops of a
previous module, so it is generally not required to register the inputs of a
module, with the following two exceptions:
- Inputs from an external pin must be registered (retimed) before use.
- Top-level blocks may register both inputs and outputs, to maximize routing
flexibility.
<a id="verification"></a>
## Verification
<a id="verification-summary"></a>
### Summary
<span class="Summary">This section documents guidelines for writing Design
Verification (DV) code in Verilog.</span>
<a id="assertions"></a>
### Assertions
<span class="Summary">Assumptions and invariants in logic must be formally
expressed as runtime assertions.</span>
Assertions must represent behaviors that ALWAYS happen (and not be used to flag
error conditions that might be exercised in simulation).
Assertions must be placed within RTL files so that assertions and their related
logic are close together.
Assertions must be placed in a design according to these guidelines:
- All input ports to a block (except clocks, resets, test, debug or
unconstrained data ports) must be included in at least one assertion that
describes the protocol.
- All output ports of a block (except test and debug) must be included in at
least one assertion that describes the functionality of the block and the
protocol of the signals.
- All synthesized functional registers in a block must be within the cone of
influence of an assertion. Further, they must be within three static levels
of logic from the assertion.
- Important end-to-end behaviors of a block must be described with an
assertion.
- Any minimum levels of performance for a block must be described with an
assertion. Some performance measuring debug logic may be needed to
supplement the assertions.
Use [standardized assertion macros](#assertion-macros) whenever possible.
<a id="unit-tests"></a>
### Unit Tests and Designer Tests
<span class="Summary">Thorough unit tests are required for shared libraries and
[reusable IP](#reusable-ip) design blocks. All other design blocks require
designer tests.</span>
#### Naming Unit Tests
Unit test modules must end with the string "\_test". For example,
`dma_controller_test`.
<a id="minimum-testing-requirements"></a>
#### Minimum Testing Requirements
If the RTL is a [reusable IP](#reusable-ip), every feature must be exhaustively
tested.
Otherwise:
1. The design block must elaborate and pass lint checks.
1. The design block must come out of reset with no X's on the outputs.
1. At least one transaction must be sent through the block and observed
correctly.
The second category is also referred to as "designer tests".
<a id="constraints"></a>
### Constraints
<span class="Summary">Use `lower_snake_case` when naming constraints with an
`_c` suffix.</span>
<div class='goodcode'></div>
```verilog
constraint legal_pkt_size_in_bytes_c {
pkt_size_in_bytes inside {[64:1500]};
}
```
<div class='badcode'></div>
```verilog
constraint c_My_Constraint { // c_ at the beginning. Not lower_snake_case.
pkt_size_in_bytes inside {[64:1500]};
}
```
<a id="plusargs"></a>
### Plusargs
<a id="plusarg-value-assignment"></a>
#### Plusarg Value Assignment
<span class="Summary">Plusargs must specify a value to be assigned to a variable
(for example, use +en_foo=1, not +en_foo). Do not use $test$plusargs.</span>
For example:
<div class='goodcode'></div>
```verilog
bit en_ingress;
bit plusarg_found = $value$plusargs("en_ingress=%d", en_ingress);
if (en_ingress) begin
// Do stuff...
end
```
<div class='badcode'></div>
```verilog
bit en_ingress;
if ($test$plusargs("en_ingress")) begin
// Do stuff...
end
```
<a id="plusarg-naming"></a>
#### Plusarg Naming
<span class="Summary">The plusarg name must match the variable that stores the
passed plusarg, exclusive of any prefix or suffix of either the plusarg or the
variable.</span>
For example:
<div class='goodcode'></div>
```verilog
int foo;
int prefix_bar_suffix;
// Any of the following plusarg run-time calls would be acceptable:
// +foo=42
// +FOO=42
// +prefix_foo_suffix=42
// +bar=123
// +prefix_bar_suffix=123
// +PREFIX_BAR_SUFFIX=123
```
<div class='badcode'></div>
```verilog
string file_name;
// Plusarg string name and variable names must match. These are not acceptable:
// +filename="foo.txt"
// +file="foo.txt"
```
<a id="text-formatting"></a>
### Text Formatting
<a id="number-formatting"></a>
#### Displayed Number Format
<span class="Summary">Printed numbers must be prefixed with their radix as shown
in the following examples.</span>
When formatting text representations of numbers for log files, make it clear
what data you are including.
Make the base of a printed number clear. Print decimal numbers without the
radix.
Binary: `0b` or `'b`
Hexadecimal: `0x` or `'h`
Decode individual fields of large structures individually, instead of expecting
the user to manually decode raw values.
<div class='goodcode'></div>
```verilog
$display("0x%0x", some_hex_value);
$display("0b%0b", some_binary_value);
$display("'h%0h", some_hex_value);
$display("'b%0b", some_binary_value);
$display("%0d", some_decimal_value);
```
<div class='badcode'></div>
```verilog
$display("%0x", some_hex_value);
$display("%0b", some_binary_value);
$display("0d%0d", some_decimal_value);
$display("'d%0d", some_decimal_value);
```
<a id="string-formatting"></a>
#### String Formatting
<span class="Summary">Use `$sformatf()` for string type formatting. Avoid using
`$display()` to format string types.</span>
The [SystemVerilog-2017 standard] is vague on how string type formatting must be
handled by `$display()`. Simulator implementation of this functionality varies.
`$sformatf()` has a more consistent interpretation and implementation.
<div class='goodcode'></div>
```verilog
string str_type = "Hello %s";
// Good: String type formatting using $sformatf()
string str_type_sformat = $sformatf(str_type, "world!");
$display(str_type_sformat);
// Good: Calling $sformatf() on the same line as $display()
$display($sformatf(str_type, "world!"));
```
<div class='goodcode'></div>
```verilog
// String literal formatting with $display() is allowed
$display("Hello %s", "world!");
```
<div class='badcode'></div>
```verilog
string str_type = "Hello %s";
// Bad: String type formatting using $display()
$display(str_type, "world!");
```
<a id="forbid-line-continuations"></a>
#### Line Continuation of String Literals
Do not use a '\' (backslash) character to continue a long string literal to the
next line, use `{}` string concatenation operator instead.
<div class='goodcode'></div>
```verilog
$display({"a really long ",
"long long quoted string"});
```
<div class='badcode'></div>
```verilog
$display("a really long \
long long quoted string"); // Bad: continuation of a string literal
```
<a id="loops"></a>
### Loop operators
<span class="Summary">Prefer foreach loops.</span>
Where possible, prefer foreach loops over equivalent loop operators. They are
concise and less prone to subtle errors.
<div class='goodcode'></div>
```verilog
foreach (data[byte_i]) begin
data[byte_i] = 0;
end
// Compact form for multidimensional arrays.
foreach (data[burst_i, byte_i]) begin
data[burst_i][byte_i] = 0;
end
```
<div class='badcode'></div>
```verilog
// Less readable and note the typo below, must be '<' not '<='.
for (int byte_i = 0; byte_i <= data.size(); byte_i++) begin
data[byte_i] = 0;
end
```
### Code Within Asserts
Do not assert on calls to `randomize`. More broadly, do not place any expression
with side effects into an assert statement.
SystemVerilog has a couple ways to disable all assertions such as `$assertoff`
or `$assertkill`. When an assertion is disabled, future assertion attempts will
not evaluate the assertion expression, as per the LRM (not until the assertion
is re-enabled via `$asserton` or one of its alternatives). This is particularly
bad when randomize is used within the assertion expression, because disabled
assertions result in unrandomized objects.
<div class='goodcode'></div>
```verilog
ret = item.randomize() with {<constraints>};
assert(ret);
```
<div class='badcode'></div>
```verilog
assert(randomize(<some variables>) with {<constraints>});
assert(item.randomize() with {<constraints>});
assert(function_with_side_effects());
```
### Wait and Fork
Always put `wait fork` or `disable fork` constructs inside of an isolation `fork
... join` block, or the environment can end up waiting on other, earlier forks
it was not intending to wait for.
<div class='goodcode'></div>
```verilog
fork begin : isolation_fork
fork
begin
fork1();
end
begin
fork2();
end
join_any
disable fork;
end : isolation_fork
join
```
<a id="void-casts"></a>
### Void Casts
Do not void cast calls that have useful or important return values. This
includes calls to `uvm_config_db::get`, `uvm_hdl_read`, `randomize`, etc.
For example, **do not do the following**:
<div class='badcode'></div>
```verilog
void'(randomize(<some variables>) with {<constraints>});
void'(item.randomize() with {<constraints>});
void'(uvm_config_db#(<object>)::get(<parameters>));
void'(uvm_hdl_read($sformatf("%sglink_gsw_link_down", glink_path), rd_lnk_dwn));
```
Instead, check the return value of calls to `randomize` and similar calls in
order to handle the potential error.
<div class='goodcode'></div>
```verilog
if (!item.randomize() with {<constraints>}) begin
<issue error>
end
if (!uvm_config_db#(<object>)::get(<parameters>)) begin
<issue error>
end
```
<a id="associative-arrays"></a>
### Associative arrays
<span class="Summary">Do not use wildcard indexed [*] associative arrays.</span>
Associative arrays with wildcard index are hard to use because the item type
could be anything. Always specify a particular index type for associative
arrays:
<div class='goodcode'></div>
```verilog
bit channel_enable[int];
register_t registers[string];
int object_count[index_type];
```
<div class='badcode'></div>
```verilog
int object_count[*]; // Bad: wildcard indexed array
```
### Bind Statements
`bind` statements may be used in verification. This is the preferred approach
for using assertion based monitors.
".\*" is allowed for making implicit port declarations when binding a module
whose ports are all inputs.
<a id="program-block"></a>
### Program block
<span class="Summary">Do not use `program` and `endprogram` blocks.</span>
It provides the false sense of security. Use `module` and clocking blocks to
avoid DUT race conditions instead.
<a id="simulator-specific"></a>
### Simulator-specific code
<span class="Summary">All simulator-specific code must be wrapped inside
preprocessor guards.</span>
The following macro names are always defined by each simulator. These names must
be used to wrap all simulator-specific code, so the code can be compiled for
every simulator.
- `VCS` - for VCS
- `INCA` - for Incisive/NCsim/Irun
- `XCELIUM` - for Xcelium/xrun
- `DSIM` - for DSim
<div class='goodcode'></div>
```verilog
`ifdef VCS
$stack();
`endif
```
<a id="forbidden-system-functions"></a>
### Forbidden System Tasks and Functions
Do not use the following functions.
* `$psprintf`: `$psprintf` is supported by a number of tools because it was
legal in older versions of the language. However, it is not in the language
reference manual. Replace with SystemVerilog's `$sformatf`.
* `$random` and `$dist_*`: these functions must not be used as they are not
part of the SystemVerilog random stability model and may break simulation
reproducibility. Use $urandom or randomize() instead.
* `$srandom`: `$srandom` must not be used as it is not part of the
SystemVerilog standard. Use `process::self().srandom()` instead.
* `$display`, `$displayb/o/h`, `$write`, `$writeb/o/h`: Do not use `$display`
or similar "display" system tasks to display messages in UVM environments,
instead use standard [UVM logging](#uvm-logging) macros for a consistent and
controllable way of message logging.
* `$info`, `$fatal`, `$error`, `$warning`: Do not use "severity" system tasks
in UVM environments, instead use corresponding [UVM logging](#uvm-logging)
macros.
<a id="uvm"></a>
### UVM
<a id="uvm-phase-super-convention"></a>
#### Phase Methods
<span class="Summary">Always call `super.<phase_name>(phase)` when overriding
UVM phase methods in derived classes.</span>
When overriding UVM phase methods (such as `build_phase`, `connect_phase`,
`run_phase`, etc.) in a class derived from a UVM component, you must call the
parent class's implementation using `super.<phase_name>(phase)`. This ensures
that any setup or configuration performed by the parent class is executed.
Exceptions are allowed if the base class is a direct UVM library class (like
`uvm_component`, `uvm_test`, `uvm_env`, etc.) where the default implementation
is known to be empty, BUT it is still recommended to call it for consistency and
future-proofing. For user-defined base classes, it is mandatory.
<div class='goodcode'></div>
```verilog
class my_test extends base_test;
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// ... custom build logic ...
endfunction
endclass
```
<div class='badcode'></div>
```verilog
class my_test extends base_test;
virtual function void build_phase(uvm_phase phase);
// Missing super.build_phase(phase)
// ... custom build logic ...
endfunction
endclass
```
<a id="uvm-logging"></a>
#### UVM Logging
<span class="Summary">Only use `` `uvm_info ``, `` `uvm_error ``, and ``
`uvm_fatal `` UVM messaging macros for message logging in UVM
environments.</span>
Only use the following UVM macros to display log messages in UVM environments:
- `` `uvm_info(ID, message, verbosity) ``: For informational messages.
- `` `uvm_error(ID, message) ``: For messages indicating a problem that needs
to be addressed.
- `` `uvm_fatal(ID, message) ``: For messages indicating a critical problem
that stops the simulation.
Do not call underlying UVM functions like `uvm_report_*`. Macros provide better
control over verbosity, timestamping, and component identification.
Do not use the `` `uvm_warning `` macro. Categorize messages as informational
(info) or as conveying an issue that needs to be addressed (error or fatal).
Although forbidden, it's recommended to setup your infrastructure to treat ``
`uvm_warning `` as errors.
<div class='goodcode'></div>
```verilog
`uvm_error(get_full_name(), $sformatf("Unsupported burst type : %s", burst_type.name()))
```
<div class='badcode'></div>
```verilog
$display("Debug: Byte enable=%d", byte_en);
uvm_report_info("ID", "Debug message", UVM_LOW)
`uvm_warning(get_full_name(), "Incorrect condition, maybe")
```
<a id="uvm-macro-semicolon"></a>
#### UVM Macro Semicolons
<span class="Summary">Do not append a semicolon to UVM macro calls.</span>
UVM macros (including messaging macros like `` `uvm_info `` and sequence action
macros like `` `uvm_do ``) must not be followed by a semicolon. Appending a
semicolon can result in an empty statement, which can cause syntax errors in
contexts like `if` statements without `begin` / `end` blocks.
<div class='goodcode'></div>
```verilog
// Good: UVM macros must not be followed by a semicolon.
`uvm_info("ID", "Message", UVM_LOW)
`uvm_do(my_seq)
```
<div class='badcode'></div>
```verilog
// Bad: Do not append a trailing semicolon to UVM macro calls.
`uvm_info("ID", "Message", UVM_LOW);
`uvm_do(my_seq);
```
<a id="sequences-and-sequence_items"></a>
#### Sequences and Sequence_items
Call the `randomize()` or `randomize() with {}` function of the sequence before
executing the sequence.
<a id="uvm-create"></a>
#### Creating Objects and Components
<span class="Summary">Use the `create()` API to create UVM objects and
components.</span>
Use the `type_id::create()` API to instantiate all UVM objects and components.
This is standard UVM programming practice and is necessary to take advantage of
UVM factory features, such as type and instance overrides.
Exceptions are permitted for objects or components that are not intended for
reuse (such as TLM ports, exports, and analysis ports) or when significant
performance gains can be achieved. In such exceptional cases, `new()` may be
used directly.
When creating classes derived from `uvm_component`, pass `this` as the `parent`
argument so that the component hierarchy is built properly.
<div class='goodcode'></div>
```verilog
env_h = tb_block_env::type_id::create("env_h", this);
ip_pkt = tx_seq_item::type_id::create("ip_pkt");
```
<div class='badcode'></div>
```verilog
// Direct calls to new() bypass the UVM factory and prevent overrides.
env_h = new("env_h", this);
ip_pkt = new("ip_pkt");
```
<a id="uvm-naming"></a>
#### UVM Naming
<span class="Summary">When creating a UVM object or component using
`type_id::create()`, the string name argument must match the name of the
variable to which it is assigned.</span>
For array assignments, the string name must include the index in square brackets
(for example, `[<index>]`).
This ensures consistency and helps with debugging, as the hierarchical path in
UVM will match the variable names in the code.
<div class='goodcode'></div>
```verilog
my_agent = my_agent_type::type_id::create("my_agent", this);
// For arrays, include the index in the string name
my_agents[i] = my_agent_type::type_id::create($sformatf("my_agents[%0d]", i), this);
```
<div class='badcode'></div>
```verilog
// String name does not match variable name
my_agent = my_agent_type::type_id::create("different_name", this);
// For arrays, string name is missing the index in brackets
my_agents[i] = my_agent_type::type_id::create($sformatf("my_agents_%0d", i), this);
```
<a id="uvm-class-constructor-default-values"></a>
#### Class Constructor Default Values
<span class="Summary">For classes derived from `uvm_object`, the constructor
parameter `name` must default to `""`. For classes derived from `uvm_component`,
the constructor must not specify default values.</span>
When defining a constructor for a UVM class:
- Classes extending `uvm_object` must define the constructor parameter as
`string name = ""` (empty string) and pass it to `super.new(name)`. Do not
provide non-empty default object names.
- Classes extending `uvm_component` must define the constructor parameters as
`(string name, uvm_component parent)` without default argument values.
<div class='goodcode'></div>
```verilog
// uvm_object derived class constructor
function new (string name = "");
// uvm_component derived class constructor
function new (string name, uvm_component parent);
```
<div class='badcode'></div>
```verilog
// Bad: name default parameter must be ""
function new (string name = "my_object");
// Bad: default parameter value provided for parent or name
function new (string name = "my_component", uvm_component parent = this);
```
<a id="uvm-test-execution"></a>
#### Test Execution
<span class="Summary">Do not pass arguments to `run_test()`.</span>
Always call `run_test()` without arguments. Specify the test name on the command
line using `+UVM_TESTNAME=test_name` instead of hardcoding it in the code.
<div class='goodcode'></div>
```verilog
initial begin
run_test();
end
```
<div class='badcode'></div>
```verilog
initial begin
run_test("my_test_name");
end
```