## 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 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
``````

``````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

(
input wire [3:0] a4,b4,
output wire [3:0] sum4,
output wire c4
)
// Instantiate a 4 bit adder
``````localparam N = 4