KB 04: Verilog FAQ
Naming Conventions
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.
// file: my_module.v
module my_module;
// module implementation
...
...
endmodule // my_module
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.
Identifiers
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.
reg MyRegister;
wire MyNet;
wire DataFromCPU; // incorrect: consecutive uppercase letters(CPU) - All lowercase, underscores between words.
reg my_register;
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
wire my_net;
wire data_from_cpu;
Name Prefix
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
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
Suffix | Description |
---|---|
_top | Top-level module |
_tb | Testbench |
_p | Positive polarity |
_n | Negative polarity |
_i | Input signals |
_o | Output signals |
_io | Bidirectional signals |
_curr | Current state |
_next | Next state |
_ff, _q | An output of a register |
Clock Names
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.
wire clk50; // single-ended 50MHz clock
wire clk_200_p, clk_200_n; // 200MHz differential clock
wire clk_en; // clock enable
wire clk_333_mem; // 333MHz memory controller clock
Reset 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.
reg reset, phy_reset; // active high reset
reg reset_n, reset_b; // active low reset
reg rst_async; // asynchronous rese
Port Names
Port names can end with a suffix that indicates port direction, as shown in the following examples.
input [9:0] addr_i; // input
input [31:0] DataI; // input
output write_enable_o; // output
inout [31:0] data_io; // bidirectional
inout [31:0] ConfigB; // bidirectiona
Module Names
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:
always @(a, b, sel) begin
if (sel == 1) z <= a;
else z <= b;
end
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)
always @(posedge clk) begin //positive edge-triggered
q <= d;
end
Flip-flop with an Async reset
always @(posedge clk ,negedge rst) begin //positive edge-triggered with reset
if (rst == 0) begin //async active low reset
q <= 0;
end else begin
q <= d;
end
end
Flip-flop with a Sync reset
always @(posedge clk) begin //positive edge-triggered
if (rst ==0) begin //sync active low reset
q <= 0;
end else begin
q <= d;
end
end
Sequential Logic Design: Using Latches
Resettable latch (Latch is a level triggered element)
always @(en, rst, d) begin
if (rst == 0) begin
q <= 0;
end else if (en == 1) begin
q <= d;
end
end