Verilog Assign statement is used to assign values to signals. This is essential for designing combinational logic and specifying continuous assignments. In this article, we will explore the syntax, rules, examples, and important concepts associated with the assign statement. The content is simplified for better understanding, making it easier to follow for beginners.


What is an assign Statement in Verilog?

An assign statement in Verilog continuously drives values to signals. It is mostly used with wire-type signals (or similar data types) to represent combinational logic.

For example, consider a wire in a simple breadboard circuit. If you apply a voltage at one end, the connected component will receive that voltage. In Verilog, this behavior is modeled using the assign statement, where the value on the right-hand side (RHS) is continuously assigned to the signal on the left-hand side (LHS).


Syntax of Verilog Assign Statement

The basic syntax for the assign statement is as follows:

assign <net_expression> = [drive_strength] [delay] <expression>;
  • LHS (Left-Hand Side): The signal being driven.
  • RHS (Right-Hand Side): The value or expression to be assigned to the LHS.
  • Drive Strength and Delay: These are optional and are mostly used for dataflow modeling rather than actual hardware synthesis. Drive strength defines how strongly a signal drives the LHS, and delay specifies the time taken for the assignment to take effect.

Rules for Using the Verilog assign Statement

  1. LHS must always be a scalar, vector net, or a concatenation of scalar/vector nets. It cannot be a register (reg).
  2. RHS can contain registers, scalar signals, and function calls.
  3. Whenever any operand on the RHS changes, the LHS is updated immediately.
  4. assign statements are continuous and always active. They keep updating the LHS as long as the RHS changes.

Here’s a simple example where two signals i1 and i2 are combined using a logical AND operation, and the result is assigned to a net called out:

assign out = i1 & i2;

In this example, out will continuously hold the logical AND of i1 and i2. If either i1 or i2 changes, the value of out is updated.

Example 2: Using Concatenation in Assign Statements

Let’s explore an example with more complex assignment, involving multiple bits:

module xyz (input [3:0] x,   // x is a 4-bit vector
            input y,           // y is a 1-bit signal
            output [4:0] z);   // z is a 5-bit vector

wire [1:0] a;                // a is a 2-bit wire
wire b;                      // b is a 1-bit wire

// Case #1: Concatenate 4 bits of x and 1 bit of y into a 5-bit value
assign z = {x, y};  // Result: z = 'b11001 or z = 'h19

// Case #2: Only part of z is assigned, the remaining bits are unconnected (high impedance)
assign z[3:1] = {x, y};  // Result: z = 'bZ001Z

// Case #3: A constant value (1) drives one bit of z
assign z[3:1] = {x, y}; 
assign z[4] = 1;  // Result: z = 'b1001Z

endmodule

Here, we have multiple cases that use the assign statement with different combinations of bit selections and concatenations.


Assigning to reg Variables

It is important to note that you cannot use the assign statement to drive reg variables. The reg type is designed to hold values and doesn’t require continuous assignment. Registers can only be driven inside procedural blocks like initial or always.


Implicit vs. Explicit Continuous Assignment

In Verilog, you can assign values to a net in two ways:

  1. Explicit Continuous Assignment: This is when the assign keyword is used directly.
   wire [1:0] a;
   assign a = x & y;  // Explicit assignment
  1. Implicit Continuous Assignment: This happens when a signal is assigned a value at the time of declaration.
   wire [1:0] a = x & y;  // Implicit assignment

The implicit assignment is convenient because it combines declaration and assignment in one line, making the code shorter and easier to read.


Combinational Logic Design with assign

Verilog allows you to design combinational circuits with the assign statement. These circuits automatically update the output whenever any input changes. For example:

module combo (input a, b, c, d, output o);
    assign o = ~((a & b) | c ^ d);  // Boolean expression for combinational logic
endmodule

This module calculates a Boolean expression based on the inputs a, b, c, and d, and assigns the result to output o. The output o will change as soon as any of the inputs change, reflecting the continuous nature of combinational logic.


Hardware Schematic after Synthesis

When this Verilog code is synthesized, it generates a hardware circuit that implements the specified logic. The circuit will behave as modeled in the Verilog code.

  • Simulation: During simulation, the output o will change according to the inputs. If any of the inputs change, the output will update instantly, as shown below.

Example Table: Summary of Assign Cases

CaseLHS AssignmentRHS ExpressionResulting Value of z
Case #1z{x, y}'b11001 or z = 'h19
Case #2z[3:1]{x, y}'bZ001Z
Case #3z[3:1] and z[4]{x, y} and 1'b1001Z
Case #4z[3:1] and z[3]{x, y} and 0'bZ001Z
Case #5z[3:1] and z[3]{x, y} and 1'bZX01Z
Case #6z{x[1:0], y}'b00001
Case #7z[2:0]{x[1:0], y}'bZZ001
Case #8z{3{y}}'b00111
Case #9{a, b}{x, y}a = 'b00, b = 'b1
Case #10{a, b}{x, y}a = 'b01, b = 'b0

Conclusion

The assign statement is an important tool for designing combinational logic in Verilog. It allows for continuous assignments, ensuring that outputs automatically update when inputs change. It is essential to understand the syntax, rules, and behavior of assign statements to effectively use them in digital design.

By following the guidelines in this article, you can confidently implement combinational logic and continuously assigned signals in your Verilog designs.

Scroll to Top