Verilog Intro

Hardware Description Language

Hardware Description Language, a.k.a HDL, is a programming-like language that is used to describe hardware.

HDLs are synthesized (and optimized) to hardware primitives while software languages are sometimes compiled to primitive instructions.

Verilog HDL vs. Software Program

As we have studied in CS1010, a software program, like a C program will be compiled into machine code. And this machine code, which is stored as an executable, can be executed directly by the CPU.

But for HDL, things are different.

Verilog Basics

Modules

  • In Verilog, designs are broken down into modules

  • A module is a container that the designer can use to encapsulate a unit of functionality.

  • Modules can contain code to describe hardware and also instances of other modules.

    • Good designs consist of sufficient (but not excessive) levels of hierarchy, with modules containing instances of modules, that contain instances of other modules.

  • At each level in the hierarchy, a module instance is treated as a "black-box" — the internals are unknown.

Verilog Module Declaration

1

Use the module keyword and a list of ports

The above declaration describes a module with 3 ports, each a single wire

2

Describe the direction of ports using input and output

The above describes a module with two inputs and one output.

3

endmodule keyword

The endmodule keyword indicates the end of statements that comprise the module description.

Gate-Level Primitives

Verilog provides us with basic primitives to model Boolean gates: and, nand, or, nor, not, xor, xnor.

1

Gate-Level Primitives Example

The following Verilog code represents an and gate with inputs connected to wires a and b, and output connected to wire y.

2

Wires

We can declare internal wires in a module, using the wire keyword

This creates a named (1-bit) wire that can be used to connect gates together.

3

Examples with wire

To describe the following circuit,

The HDL we write will be

Note that we can also add gate identifiers for each gate. And in the following code, g1, g2, and g3 are three gate identifiers.

Module Instantiation

In Verilog, we can use existing modules within new modules through instantiation.

1

Ordered Instantiation

To instantiate a module, we can use the following syntax

where M1 is the name of this instance, and A, B, w1, w2, are four arguments.

2

Named Instantiation

During module instantiation, we can specify the parameter that the argument will be passed in explicitly. For example,

where .a, .b, .sum and .Cout are the name of each parameter in the definition of module add_half.

3

Example: Implementing a full adder using two half adders

Verilog Assignments

Implementing larger circuits using individual gate, a.k.a Gate-Level Primitives can be tedious. For example, till now, to implement an AND gate, we use,

But Verilog allows us to use combinational logic expressions through the assign keyword. So, now, to implement an AND gate, we can use

This is called a continuous assignment. As it is always permanently assigned. It also allows us to assign the result of a Boolean expression to a signal.

Verilog Assignment Operators

Operator
Name
Result Width
Description

&&

Logical AND

1 or 0 (1-bit)

Returns 1 if both operands are non-zero; otherwise 0.

&

Bitwise AND

Same width as the widest operand

Performs bitwise AND between corresponding bits.

||

Logical OR

1 or 0 (1-bit)

Returns 1 if either one of the operands is non-zero; otherwise 0.

|

Bitwise OR

Same width as the widest operand

Performs bitwise OR between corresponding bits.

!

Logical NOT

1 or 0 (1-bit)

Returns 1 if operand is zero; otherwise 0.

~

Bitwise NOT (Complement)

Same width as the widest operand

Inverts every bit in the operand.

^

Bitwise XOR

Same width as the widest operand

Performs bitwise XOR between operands.

~^ / ^~

Bitwise XNOR

Same width as the widest operand

Performs bitwise XNOR (inverse of XOR).

~& / &~

Bitwise NAND

Same width as the widest operand

Performs bitwise NAND

Example

1

The use of continuous assignment makes life much easier

To implement the following circuit using continuous assignment, we only need one line of code

And that is,

2

Use continuous assignment to implement a multiplexer

This can be done by conditional assignment (almost same as in C). So, to implement a 1-bit 2x1 multiplexer, we can use

The signal y will be connected to x1 if sel is 1, else it is connected to x0.

Vectors in Verilog

So far, we are only dealing with 1-bit signals. What happens if we want to use multi-bit signals?

Luckily, Verilog has a special construct for handling multi-bit signals (wire). Formed by specifying a range:

Vector is also supported when specifying multi-bit module ports (input, output)

By convention, we label the MSB using the higher number, and the LSB using 0. So, a 16-bit signal will be [15:0], an 8-bit signal will be [7:0], and a 64-bit signal will be [63:0].

Bit Selection in Vectors

We can select individual bit of the vector. For example,

We can also select a range of the vector. For example,

Miscs

1

Number Literals

Verilog allows us to use number literals to assign a fixed bit pattern to a signal. A number literal has the following structure,

  • <size> is the width in bits

  • <radix>: b for binary, o for octal, h for hex, d for decimal

  • <value>: the number you want, with as many optional underscores as needed (for readability)

Example

Attention

2

Concatenation

It is sometimes very useful to be able to concatenate a number of signals into a single signal. In Verilog, the concatenation is signified by curly brackets ({, }) enclosing a list. For example,

Examples

The second line of code utilises the replication feature of concatenation in Verilog

3

Parameters

A parameter in Verilog is a constant that is local to a module. It can be declared either in the module header or in the module body (we will not use the second paradigm).

For example,

Notes

1

Structural Verilog

The process of using Verilog HDL to describe the gate-level circuit directly is called structural Verilog.

2

The order of statements doesn't matter in each Verilog module

In the Verilog module, the order of statements is unimportant. Each statement describes a piece of hardware. There is no sequence of steps when doing structural Verilog.

3

Note on wire

In the Verilog wire, usually there is no need to declare 1-bit wires for connecting modules. Tools will infer these wires automatically by matching names.

Last updated