## Wires

```
wire input a,b;
wire output y;
wire input a2[1:0],b2[1:0];
wire output y2[1:0];
wire output y3[2:0];
```

## Assignment

An assign statement is used for modeling only combinational logic and it is executed continuously. So the assign statement is called 'continuous assignment statement' as there is no sensitive list (see always blocks later).

```
assign y = a;
```

## Logic bitwise primitives

### Negation

```
assign y = ~a;
```

### AND Gate

```
assign y = a & b;
```

### OR Gate

```
assign y = a | b;
```

### Exclusive OR Gate

```
assign y = a ^ b;
```

## Reduction

```
assign y = | a2;
```

### is equivalent to:

```
assign y = a2[1] | a2[0];
```

## Concatenation and Replication

```
assign y2 = {a,b};
assign y2 = {a,1'b0};
assign y3 = {a,b,1'b1};
assign y3 = {a,2'b10};
assign y3 = {a,a2};
assign y3 = {a,a2[0],1'b1};
assign {y2,y} = {y3[1:0],a};
assign y3 = {a,2{1'b1}};
```

## Shifting

```
// a a >> 2 a >>> 2 a << 2 a << 3
// 01001111 00010011 00010011 00111100 01111000
// 11001111 00110011 11110011 00111100 01111000
assign y2 = a2 >> 1; // Logical 0's shifted in
assign y2 = a2 >>> 1; // Arithemtic MSB sign bit shifted in
assign y2 = a2 << 1; // Logical shift left same result as
assign y2 = a2 <<< 1; // Arithmetic shift left
```

## Rotation

### Rotate right 1 bit

```
assign y3r = {y3[0],y3[2:1]};
```

### Rotate right 2 bit

```
assign y3r = {y3[1:0],y3[2]};
```

## Operator precedence

```
!,~,+,-(uni),**,*,/,%,+,-(bin),>>,<<,>>>,<<<,==,!=,===,!==,&,^,|,&&,||,?: */
```

## Conditionals

### Tertiary

```
assign max = (a > b) ? a : b;
```

## If/Else

```
if(a < b)
assign min = a;
else
assign min = b;
```

```
if(boolean)
// if code
else if (boolean)
// if else 1 code
else
// else code
```

```
if(boolean)
begin
// begin code
end
else
begin
// else code
end
```

## Synthesis of Z and X Values

Z values can only be synthesised by tristate bufferes and thus infer them

these have output enable inputs to control their output state for example here

is a single bit tristate buffer with an output enable

```
assign y = (oen) ? a : 1'bz;
```

This sort of construuct is useful for biderectional ports or buses.

The synthesis of X is don't care, the value may be either 0 or 1, this can

improve the efficiency or optimisation of combinational circuits

```
assign y = (a == 2'b00) ? 1'b0:
(a == 2'b01) ? 1'b1:
(a == 2'b10) ? 1'b1:
1'bx; // i == 2'b11
```

## Behavioural Blocks

Procedural blocks using always block, these black box sections describe

behaviour using procedural statements, always behavioural blocks are defined

with an event control expression or sensitivity list

```
always @(sensitivity list)
begin [Optional label]
[optional local variable declarations];
[procedural statements];
end [optional label]
```

### Procedual Assignment

```
[variable] = [expression]; // blocking, assigned before next statement
// like normal C
[variable] <= [expression]; // non blocking, assigned at end of always
// block
```

Blocking tends to be used for combinational circuits, non-blocking for

sequential

In a procedural assignment, an expression can only be assigned to an output

with one of the variable data types, which are reg, integer, real, time, and

realtime. The reg data type is like the wire data type but used with a

procedural output. The integer data type represents a fixed-size (usually 32

bits) signed number in 2's-complement format. Since its size is fixed, we

usually don't use it in synthesis. The other data types are for modeling and

simulation and cannot be synthesized.

## Registers

A register is simple memory wire to hold state, normally implemented as

D-Types

```
output reg
```

## Conditional Examples

### binary encoder

```
en a1 a2 y
0 - - 0000
1 0 0 0001
1 0 1 0010
1 1 0 0100
1 1 1 1000
```

```
module pri_encoder
(
input wire [3:0] r,
output wire en
output wire [1:0] y
)
always @*
if(r[3])
{en,y} = 3'b111;
else if(r[2])
{en,y} = 3'b110;
else if(r[1])
{en,y} = 3'b101;
else if(r[0])
{en,y} = 3'b100;
else
{en,y} = 3'b000;
endmodule
```

```
module decoder_1
(
input wire [1:0] a,
input wire en,
output reg [3:0] y
)
always @*
if(~en)
y = 4'b0000;
else if(a == 2'b00)
y = 4'b0001;
else if(a == 2'b01)
y = 4'b0010;
else if(a == 2'b10)
y = 4'b0100;
else
y = 4'b1000;
endmodule
```

### Case

```
module decoder_2
(
input wire [1:0] a,
input wire en,
output reg [3:0] y
)
always @*
case ({en,a})
3'b000, 3'b001,3'b010,3'b011: y = 4'b0000;
3'b100: y = 4'b0001;
3'b101: y = 4'b0010;
3'b110: y = 4'b0100;
3'b111: y = 4'b1000;
endcase // {en,a}
endmodule
```

```
module decoder_3
(
input wire [1:0] a,
input wire en,
output reg [3:0] y
)
always @*
case ({en,a})
3'b100: y = 4'b0001;
3'b101: y = 4'b0010;
3'b110: y = 4'b0100;
3'b111: y = 4'b1000;
default: y = 4'b0000;
endcase // {en,a}
endmodule
```

### Casex

```
module decoder_4
(
input wire [1:0] a,
input wire en,
output reg [3:0] y
)
always @*
casex ({en,a})
3'b0xx: y = 4'b0000;
3'b100: y = 4'b0001;
3'b101: y = 4'b0010;
3'b110: y = 4'b0100;
3'b111: y = 4'b1000;
endcase // {en,a}
endmodule
```

When the values in the item expressions are mutually exclusive (i.e., a value

appears in only one item expression), the statement is known as a parallel

case statement. When synthesized, a parallel case statement usually infers a

multiplexing routing network and a non-parallel case statement usually infers

a priority routing network. Unlike C where conditional constructs are executed

serially using branches and jumps, with HDL these are realised by routing

netowrks.

### Casez

```
module decoder_4
(
input wire [1:0] a,
input wire en,
output reg [3:0] y
)
always @*
casez ({en,a})
3'b0??: y = 4'b0000;
3'b100: y = 4'b0001;
3'b101: y = 4'b0010;
3'b110: y = 4'b0100;
3'b111: y = 4'b1000;
endcase // {en,a}
endmodule
```

In casez, the `?`

is used to indicate either X or Z state.

## Tasks & Functions

Tasks and Functions are used when a set of operations are commonly repeated and used, this save you writing the same thing out over and over a gain. Functions can only be used for modelling combinational logic cannot drive more than one output and cannot contain delays, unlike tasks which can. Tasks also can not return a value unlike functions which can.

Below shows a function for calculating parity, something that may be used frequently in digital logic design.

```
function parity;
input [31:0] data;
integer i;
begin
parity = 0;
for (i= 0; i < 32; i = i + 1) begin
parity = parity ^ data[i];
end
end
endfunction
```

## Common Errors

- Variable assigned in multiple always blocks
- Incomplete sensitivity list
- Incomplete branch and incomplete output assignment

### Multiple assignment

```
always @*
if(en) y = 1'b0;
always @*
y = a & b;
```

`y`

is the output of two circuits which could be contridictary, this is not
synthesiseable. Below is how this should have been writtten:

```
always @*
if(en)
y = 1'b0;
else
y = a & b;
```

### Incomplete sensitivity list

Incomplete sensitivity list (missing `b`

). `b`

could change but the y output

would not, causing unexpected behavior againg this is not synthesiseable.

```
always @(a)
y = a & b;
/* Fixed versions */
always @(a,b)
y = a & b;
/* or simple cure all */
always @*
y = a & b;
```

### incomplete branch or output assignment

Incomplete branch or output assignment, do not infer state in combinational

circuits.

```
always @*
if(a > b)
gt = 1'b1; // no eq assignment in branch
else if(a == b)
eq = 1'b1; // no gt assignment in branch
// final else branch omiitted
```

Here we break both incomplete output assinment rules and branch According to

Verilog definition `gt`

and `eq`

keep their previous values when not assigned

which implies internal state, unintended latches are inferred, these sort of

issues cause endless hair pulling avoid such things. Here is how we could

correct this:

```
always @*
if(a > b)
begin
gt = 1'b1;
eq = 1'b0;
end
else if (a == b)
begin
gt = 1'b0;
eq = 1'b1;
end
else
begin
gt = 1'b0;
eq = 1'b0;
end
```

Or easier still assign default values to variables at the beginning of the

always block

```
always @*
begin
gt = 1'b0;
eq = 1'b0;
if(a > b)
gt = 1'b1;
else if (a==b);
eq = 1'b1;
end
```

Similar errors can creep into case statements

```
case(a)
2'b00: y =1'b1;
2'b10: y =1'b0;
2'b11: y =1'b1;
endcase
```

Here the case `2'b01`

is not handled, is a has this value y gets it's previous

value and a latch is assumed, the solution is to include missing case, assign

`y`

a value before the case or add a default clause.

```
case(a)
2'b00: y =1'b1;
2'b10: y =1'b0;
2'b11: y =1'b1;
default : y = 1'b1;
endcase
```

## Adder with carry

```
module adder #(parameter N=4)
(
input wire [N-1:0] a,b,
output wire [N-1:0] sum,
output wire cout
);
/* Constant Declaration */
localparam N1 = N-1;
/* Signal Declaration */
wire [N:0] sum_ext;
/* module body */
assign sum_ext = {1'b0, a} + {1'b0, b};
assign sum = sum_ext[N1:0];
assign cout = sum_ext[N];
endmodule
module adder_example
(
input wire [3:0] a4,b4,
output wire [3:0] sum4,
output wire c4
)
// Instantiate a 4 bit adder
adder #(.N(4)) four_bit_adder (.a(a4), .b(b4), .sum(sum4), .cout(c4));
endmodule
```

## LocalParams

```
localparam N = 4
```