The verilog assign statement is typically used to continuously drive a signal of `wire` datatype and gets synthesized as combinational logic. Here are some more design examples using the `assign` statement.

## Example #1 : Simple combinational logic

The code shown below implements a simple digital combinational logic which has an output wire z that is driven continuously with an `assign` statement to realize the digital equation.

```  ```

module combo ( 	input 	a, b, c, d, e,
output 	z);

assign z = ((a & b) | (c ^ d) & ~e);

endmodule

```
```

The module combo gets elaborated into the following hardware schematic using synthesis tools and can be seen that the combinational logic is implemented with digital gates. ### Testbench

The testbench is a platform for simulating the design to ensure that the design does behave as expected. All combinations of inputs are driven to the design module using a `for` loop with a delay statement of 10 time units so that the new value is applied to the inputs after some time.

```  ```

module tb;
// Declare testbench variables
reg a, b, c, d, e;
wire z;
integer i;

// testbench variables
combo u0 ( .a(a), .b(b), .c(c), .d(d), .e(e), .z(z));

initial begin
// At the beginning of time, initialize all inputs of the design
// to a known value, in this case we have chosen it to be 0.
a <= 0;
b <= 0;
c <= 0;
d <= 0;
e <= 0;

// Use a \$monitor task to print any change in the signal to
// simulation console
\$monitor ("a=%0b b=%0b c=%0b d=%0b e=%0b z=%0b",
a, b, c, d, e, z);

// Because there are 5 inputs, there can be 32 different input combinations
// So use an iterator "i" to increment from 0 to 32 and assign the value
for (i = 0; i < 32; i = i + 1) begin
{a, b, c, d, e} = i;
#10;
end
end
endmodule

```
```
Simulation Log
```ncsim> run
a=0 b=0 c=0 d=0 e=0 z=0
a=0 b=0 c=0 d=0 e=1 z=0
a=0 b=0 c=0 d=1 e=0 z=1
a=0 b=0 c=0 d=1 e=1 z=0
a=0 b=0 c=1 d=0 e=0 z=1
a=0 b=0 c=1 d=0 e=1 z=0
a=0 b=0 c=1 d=1 e=0 z=0
a=0 b=0 c=1 d=1 e=1 z=0
a=0 b=1 c=0 d=0 e=0 z=0
a=0 b=1 c=0 d=0 e=1 z=0
a=0 b=1 c=0 d=1 e=0 z=1
a=0 b=1 c=0 d=1 e=1 z=0
a=0 b=1 c=1 d=0 e=0 z=1
a=0 b=1 c=1 d=0 e=1 z=0
a=0 b=1 c=1 d=1 e=0 z=0
a=0 b=1 c=1 d=1 e=1 z=0
a=1 b=0 c=0 d=0 e=0 z=0
a=1 b=0 c=0 d=0 e=1 z=0
a=1 b=0 c=0 d=1 e=0 z=1
a=1 b=0 c=0 d=1 e=1 z=0
a=1 b=0 c=1 d=0 e=0 z=1
a=1 b=0 c=1 d=0 e=1 z=0
a=1 b=0 c=1 d=1 e=0 z=0
a=1 b=0 c=1 d=1 e=1 z=0
a=1 b=1 c=0 d=0 e=0 z=1
a=1 b=1 c=0 d=0 e=1 z=1
a=1 b=1 c=0 d=1 e=0 z=1
a=1 b=1 c=0 d=1 e=1 z=1
a=1 b=1 c=1 d=0 e=0 z=1
a=1 b=1 c=1 d=0 e=1 z=1
a=1 b=1 c=1 d=1 e=0 z=1
a=1 b=1 c=1 d=1 e=1 z=1
ncsim: *W,RNQUIE: Simulation is complete.

``` The half adder module accepts two scalar inputs a and b and uses combinational logic to assign the outputs sum and carry bit cout. The sum is driven by an XOR between a and b while the carry bit is obtained by an AND between the two inputs.

```  ```

module ha ( input 	a, b,
output	sum, cout);

assign sum  = a ^ b;
assign cout = a & b;
endmodule

```
``` ### Testbench

```  ```

module tb;
// Declare testbench variables
reg a, b;
wire sum, cout;
integer i;

// testbench variables
ha u0 ( .a(a), .b(b), .sum(sum), .cout(cout));

initial begin
// At the beginning of time, initialize all inputs of the design
// to a known value, in this case we have chosen it to be 0.
a <= 0;
b <= 0;

// Use a \$monitor task to print any change in the signal to
// simulation console
\$monitor("a=%0b b=%0b sum=%0b cout=%0b", a, b, sum, cout);

// Because there are only 2 inputs, there can be 4 different input combinations
// So use an iterator "i" to increment from 0 to 4 and assign the value
for (i = 0; i < 4; i = i + 1) begin
{a, b} = i;
#10;
end
end
endmodule

```
```
Simulation Log
```ncsim> run
a=0 b=0 sum=0 cout=0
a=0 b=1 sum=1 cout=0
a=1 b=0 sum=1 cout=0
a=1 b=1 sum=0 cout=1
ncsim: *W,RNQUIE: Simulation is complete.

``` A full adder can be built using the half adder module shown above or the entire combinational logic can be applied as is with `assign` statements to drive the outputs sum and cout.

```  ```

module fa (	input 	a, b, cin,
output 	sum, cout);

assign sum  = (a ^ b) ^ cin;
assign cout = (a & b) | ((a ^ b) & cin);
endmodule

```
``` ### Testbench

```  ```

module tb;
reg a, b, cin;
wire sum, cout;
integer i;

fa u0 ( .a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));

initial begin
a <= 0;
b <= 0;

\$monitor("a=%0b b=%0b cin=%0b sum=%0b cout=%0b", a, b, cin, sum, cout);

for (i = 0; i < 7; i = i + 1) begin
{a, b, cin} = i;
#10;
end
end
endmodule

```
```
Simulation Log
```ncsim> run
a=0 b=0 cin=0 sum=0 cout=0
a=0 b=0 cin=1 sum=1 cout=0
a=0 b=1 cin=0 sum=1 cout=0
a=0 b=1 cin=1 sum=0 cout=1
a=1 b=0 cin=0 sum=1 cout=0
a=1 b=0 cin=1 sum=0 cout=1
a=1 b=1 cin=0 sum=0 cout=1
ncsim: *W,RNQUIE: Simulation is complete.

``` ## Example #4: 2x1 Multiplexer

The simple 2x1 multiplexer uses a ternary operator to decide which input should be assigned to the output c. If sel is 1, output is driven by a and if sel is 0 output is driven by b.

```  ```

module mux_2x1 (input 	a, b, sel,
output 	c);

assign c = sel ? a : b;
endmodule

```
``` ### Testbench

```  ```

module tb;
// Declare testbench variables
reg a, b, sel;
wire c;
integer i;

// testbench variables
mux_2x1 u0 ( .a(a), .b(b), .sel(sel), .c(c));

initial begin
// At the beginning of time, initialize all inputs of the design
// to a known value, in this case we have chosen it to be 0.
a <= 0;
b <= 0;
sel <= 0;

\$monitor("a=%0b b=%0b sel=%0b c=%0b", a, b, sel, c);

for (i = 0; i < 3; i = i + 1) begin
{a, b, sel} = i;
#10;
end
end
endmodule

```
```
Simulation Log
```ncsim> run
a=0 b=0 sel=0 c=0
a=0 b=0 sel=1 c=0
a=0 b=1 sel=0 c=1
ncsim: *W,RNQUIE: Simulation is complete.

``` ## Example #5: 1x4 Demultiplexer

The demultiplexer uses a combination of sel and f inputs to drive the different output signals. Each output signal is driven by a separate `assign` statement. Note that the same signal is generally not recommended to be driven by different `assign` statements.

```  ```

module demux_1x4 (	input 				f,
input [1:0]	 	sel,
output 				a, b, c, d);

assign a = f & ~sel & ~sel;
assign b = f &  sel & ~sel;
assign c = f & ~sel &  sel;
assign d = f &  sel &  sel;

endmodule

```
``` ### Testbench

```  ```

module tb;
// Declare testbench variables
reg f;
reg [1:0] sel;
wire a, b, c, d;
integer i;

// testbench variables
demux_1x4 u0 ( .f(f), .sel(sel), .a(a), .b(b), .c(c), .d(d));

// At the beginning of time, initialize all inputs of the design
// to a known value, in this case we have chosen it to be 0.
initial begin
f <= 0;
sel <= 0;

\$monitor("f=%0b sel=%0b a=%0b b=%0b c=%0b d=%0b", f, sel, a, b, c, d);

// Because there are 3 inputs, there can be 8 different input combinations
// So use an iterator "i" to increment from 0 to 8 and assign the value
for (i = 0; i < 8; i = i + 1) begin
{f, sel} = i;
#10;
end
end
endmodule

```
```
Simulation Log
```ncsim> run
f=0 sel=0 a=0 b=0 c=0 d=0
f=0 sel=1 a=0 b=0 c=0 d=0
f=0 sel=10 a=0 b=0 c=0 d=0
f=0 sel=11 a=0 b=0 c=0 d=0
f=1 sel=0 a=1 b=0 c=0 d=0
f=1 sel=1 a=0 b=0 c=1 d=0
f=1 sel=10 a=0 b=1 c=0 d=0
f=1 sel=11 a=0 b=0 c=0 d=1
ncsim: *W,RNQUIE: Simulation is complete.

``` ## Example #6: 4x16 Decoder

```  ```

module dec_3x8 ( 	input 					en,
input 	[3:0] 	in,
output  [15:0] 	out);

assign out = en ? 1 << in: 0;
endmodule

```
``` ### Testbench

```  ```

module tb;
reg en;
reg [3:0] in;
wire [15:0] out;
integer i;

dec_3x8 u0 ( .en(en), .in(in), .out(out));

initial begin
en <= 0;
in <= 0;

\$monitor("en=%0b in=0x%0h out=0x%0h", en, in, out);

for (i = 0; i < 32; i = i + 1) begin
{en, in} = i;
#10;
end
end
endmodule

```
```
Simulation Log
```ncsim> run
en=0 in=0x0 out=0x0
en=0 in=0x1 out=0x0
en=0 in=0x2 out=0x0
en=0 in=0x3 out=0x0
en=0 in=0x4 out=0x0
en=0 in=0x5 out=0x0
en=0 in=0x6 out=0x0
en=0 in=0x7 out=0x0
en=0 in=0x8 out=0x0
en=0 in=0x9 out=0x0
en=0 in=0xa out=0x0
en=0 in=0xb out=0x0
en=0 in=0xc out=0x0
en=0 in=0xd out=0x0
en=0 in=0xe out=0x0
en=0 in=0xf out=0x0
en=1 in=0x0 out=0x1
en=1 in=0x1 out=0x2
en=1 in=0x2 out=0x4
en=1 in=0x3 out=0x8
en=1 in=0x4 out=0x10
en=1 in=0x5 out=0x20
en=1 in=0x6 out=0x40
en=1 in=0x7 out=0x80
en=1 in=0x8 out=0x100
en=1 in=0x9 out=0x200
en=1 in=0xa out=0x400
en=1 in=0xb out=0x800
en=1 in=0xc out=0x1000
en=1 in=0xd out=0x2000
en=1 in=0xe out=0x4000
en=1 in=0xf out=0x8000
ncsim: *W,RNQUIE: Simulation is complete.

``` 