Modules are the building block through which Verilog is built.

Each module can be thought of as a black box with a series of inputs, and a series of outputs. Changing the input changes the outputs.

Module definitions are started with the `module` keyword, and closed with the `endmodule` keyword.

## Syntax
The general syntax of a module is as follows:
```verilog
// This line is referred to as the *module header*
module <name> ([port_list]);
	// Contents of the module
endmodule

// The port list is optional
module <name>;
	// Contents
endmodule
```

Below is an example of the structure of a half adder module:
```verilog
module half_adder(
	input a,
	input b,
	output sum_bit,
	output carry_bit
	);
	// ------- snip ------------
endmodule
```

## Ports
Ports are a set of signals that act as input and outputs for a particular module. 

There are 3 kinds of ports:
- `input`: Input ports can only receive values from the outside. `input` ports cannot be written to.
- `output`: Output ports can be written to, but not read from.
- `inout`: Inout ports can send *and* receive values.

Ports can be declared in the port list, or in the module body. Ports declared in the port list can optionally omit their type and only declare a name, to be specified within the body of the module:
```verilog
module half_adder(
	a,
	b,
	sum_bit,
	carry_bit
	);
	input a;
	input b;
	output sum_bit;
	output carry_bit;
	// ----------- snip -----------
endmodule
```

The full type of a port can also be defined within the portlist:
```verilog
```verilog
module half_adder(
	input wire a,
	input wire b,
	output wire sum_bit,
	output wire carry_bit
	);
	input a;
	input b;
	output sum_bit;
	output carry_bit;
	// ----------- snip -----------
endmodule
```

### Port types
If no type is defined, ports are implicitly defined as *nets* of type `wire`.

> In verilog, the term *net* refers to network, and it refers to a connection that joins two or more devices together.

Ports can be a vector type:
```verilog
module test(a, b, c);
	input [7:0] a;
	input [7:0] b;
	output [7:0] c;
	// -------- snip ---------
endmodule
```

# Instantiation
Larger designs can be built by using multiple smaller modules.

Modules can be *instantiated* within other modules and ports, and these *instances* can be connected with other signals.

These port connections can be defined by an *ordered list*, or by *name*.

### By Ordered List
```verilog
module submodule (input x, y, z, output o);
	// ------- snip -------
endmodule

module parent;
	wire a, b, c;
	wire o;
	// Similar to C, the type of the module is first, followed by
	// the name of the module instance.
	submodule foo (a, b, c, o);
endmodule
```

### By Name
Ports can also be joined by explicitly defining the name.

Syntactically, this is done with a dot (`.`), followed by the port name defined by the design, followed by the signal name to connect, wrapped in parenthesis (`.x(a)`).
```verilog
module submodule (input x, y, z, output o);
	// ------------snip-----------------
endmodule

module parent;
	wire a, b, c;
	wire o;
	submodule foo (
		.x(a),
		.y(b),
		.z(c),
		.o(o)
	);
```

Because association is done by name, the order of definition does not matter.

### Unconnected ports
Ports that are not connected to any wire by the parent module will have a value of high impedance, and is considered unknown/undefined.

