KB 04: Verilog FAQ
Verilog File Organization
It is a good design practice to implement a single Verilog module in a file, as shown in the following code example.
A module name should match the file name. Following this rule makes it easier to process and manage the projects. An exception might be a library file that contains multiple short modules.
File and Directory Names
Although it's legal to include spaces and other special characters in file and directory names in Linux and Windows operating systems, it is not a good design practice. Having spaces can cause obscure problems in tools and scripts. Linux command-line utilities and shells were designed based on a premise that space delimits a field value, rather than being an acceptable component of a file or directory name. So do tools that rely on those utilities and shells. Including quotes around the filename with spaces, and special characters might not always work, for example when this filename is passed through multiple subshells and pipes
As a rule, use only alphanumeric and underscore characters in file and directory names.
Try to give files and directories that are meaningful and unique names that may help describe their contents.
Case Sensitive - Uppercase vs. Lowercase
Net, variable, module, instance, and other names in Verilog languages are case sensitive. Synthesis tools enforce that rule by default.
It is recommended that you name parameters, macros, constants, attributes, and enumerated type values in uppercase. Module, file, function, instance, and task names can be in lowercase. Don't use mixed case in names.
Using Tabs for Code Indentation
Tabs are used for code indentation. However, tabs are not displayed in the same way on different computer systems. It is recommended that you configure a code editor to replace a tab character with whitespaces. It's customary to use four white characters to replace a single tab.
Limit the line width
Standard column width for most terminals, editors, and printers is 80 characters. The motivation behind limiting the line width to 80 characters is to make the code more readable on different systems.
The two most popular HDL identifier coding styles are the following:
- Mixed case, no underscores.
Each word starts with an uppercase letter. Two or more consecutive uppercase letters are disallowed.
- All lowercase, underscores between words.
The second coding style is more prevalent. Most of the tool and IP Core vendors, including Xilinx, Intel, have adopted this style. It is important to adopt and follow a single style that can be used by all developers and across different projects
A meaningful name prefix can be used to categorize the net, register, instance, or other identifiers. For example, all the nets that originate from the memory controller can have a "mem_" name prefix.
Name suffix can be used to provide additional information about the net, register, instance, or other identifiers. For example, "_p" or "_n" suffix can indicate positive or negative polarity. The following table provides a few examples of name suffixes:
Table 1: Examples of name suffixes
|_ff, _q||An output of a register|
Clock signal names can include frequency, and other characteristics, such as a single-ended or differential clock, to make the name more descriptive. It is also customary to include "clk" as part of a clock name. The following are a few examples of clock signal names.
Reset names can include information about reset polarity (active high or low), synchronous or asynchronous, and global or local. The following are a few examples of reset signal names.
Port names can end with a suffix that indicates port direction, as shown in the following examples.
Module names have to be unique across the entire project, regardless of the hierarchy level the module is instantiated. ReservedVerilog or SystemVerilog keywords should not be used as module names.
Can I use always statements to model combinational logic? How?
Ideally, concurrent statements are used to model combinational logic, and always statements are used to model sequential logic (flip flops and latches). However, always statements are not restricted to that. You can model combinational logic using them. But it is important to note that when using an always statement to make a combinational logic, the sensitivity list of the always statement should contain all the signals which are being 'read' in that always block. In other words, to synthesize combinational logic using an always block, all inputs must appear in the sensitivity list.
For example, if you were to model a mux, you would say:
Using an always statement to model combinational logic is handy because statements like if, case, etc (which are very useful and intuitive) can only be written inside always statements.
The Rules for Sequential Logic Design
Synchronous Sequential Logic Design: Using Flip-Flops
There are two important things you should know when you design synchronous sequential logic:
- The sensitivity list of the always statement must have a clock signal (or a reset signal, if it is an asynchronous reset). And it should be either 'posedge' or 'negedge' in the sensitivity list before the clk. This is because flip-flops are edge-triggered elements
- Using non-blocking assignments in the always block.
Flip-flop without a reset (Flip-flop is edge-triggered element)
Flip-flop with an Async reset
Flip-flop with a Sync reset
Sequential Logic Design: Using Latches
Resettable latch (Latch is a level triggered element)