Programmable Logic/Verilog Data Types

Data Values
Verilog has four values any signal can take:

In practice, x and z values are difficult to use in synthesis, and should typically be avoided, unless there is a very specific reason for using them.

Wire
Wires, specified with the wire keyword represent physical wires that carry electrical signals from one module to the next. Wires do not store any data, and they must be constantly supplied with a value or they will not contain a value. Wires may not be the target of a blocking or sequential assignment.

Wires come in one of three varieties:

Wires can be assigned a value using the assign keyword. All assign declarations are considered to be running concurrently and continuously.

In the following case, the value of a is dependent on the values of b and c. Any change in either b or c will result in an automatic and instantaneous change in the value of a.

wire a, b, c; assign a = b & c;

Circular assignments cannot be made using the assign keyword, as this produces a continuous loop. In the following example, the value of a is undefined, because it depends on itself passed through combinational (i.e. asynchronous, continuously operating) logic.

wire a, b; assign a = a | b;

For the wand and wor data types, all assignments to that wire are considered to be ports to logic gates. For instance, the following code:

wire a, b, c; wor x; assign x = a; assign x = b; assign x = c;

Is equivalent to this code:

wire a, b, c, x assign x = (a | b | c);

While it may seem like more work to use wor or wand, they can greatly simplify some complicated logic operations, and they can help to improve the readability of the code.

Reg
check syntax

A register, denoted with the keyword reg is a memory storage location. Registers store values without needing constant assignment, but they must be manually updated with a blocking or sequential assignment. Register values are all treated as being unsigned values, and any extension of a value into a larger register will not result in logical sign extension.

Registers can be used with the "=" and "<tt><=</tt>" b <= y + z;

Assignments with the "=" operator are blocking assignments, and they will be performed sequentially. Assignments with the "<=" operator are non-blocking. All non-blocking assignments in a particular code block will begin at the same time. The block will not terminate until all the non-blocking assignments have completed.

Vector
a vector is collection of a variables denoted with same name but with different subscripts example: [2:0]i; assign y=i[2]^i[1]; assign y=i[1]^i[0]; endmodule

Integer
Integer values, specified with the integer keyword are similar in function to registers, except that they are treated implicitly as signed numbers. Integer values will be logically sign-extended on assignment.

Real
A real number can be specified in one of the following two forms. 23_5.1e2  23510.0 (underscores are ignored) 3.6e2     360.0 (e and E are the same) 5E-4      0.0005
 * 1) decimal notation:examples of numbers in this form are: 2.0, 5.678, 1154.76, 0.1
 * 2) scientific notation: examples of numbers in this form are:

Parameter
A parameter is similar to predefined identifiers in C. It is used to declare a global constant example: parameter u=8; local parameter is used to declare single digit

Buses
Register and wire types can be specified as multi-bit buses. This assignment is made in the variable declaration using the <tt>[]</tt> operator. As an example:

wire [5:0] a;

This declares wire a to be a bus of 6 wires, with bit 5 (a[5]) being the MSB, and bit 0 (a[0]) being the LSB. The bit number of the LSB must be lower than the bit number for the MSB, but it needs not be zero.

Bit Selection
The individual wires or registers in a bus can be interfaced with directly, and subsets of the bus can be manipulated. Given the following declaration:

wire [15:0] a;

The following code will set a value to bit 14 of the bus:

assign a[14] = 1'b1;

And the following code will assign a value to the lower 8 bits of the bus:

assign a[7:0] = 8'b01101101;

Likewise, we can read from only part of a bus. The following code assigns the 8-bit bus b to be the upper 8 bits of the 16-bit bus a:

wire [15:0] a; wire [7:0] b; assign b[7:0] = a[15:8];

Part-select operators let the compiler calculate the range based on a starting point and a data-width size;

wire [15:0] a; wire [7:0] b; assign b[7:0] = a[15:8]; assign b[7:0] = a[8+:8]; // equivalent assign b[7:0] = a[15-:8]; // equivalent