Commit e5e987bc authored by Alan Wood's avatar Alan Wood

Added rest of examples,conditionals and cases

parent bd5a1bac
......@@ -166,4 +166,279 @@ 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
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
```verilog
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
```verilog
module pri_encoder
(
input wire [4:1] r,
output wire [2:0] y
)
always @*
if(r[4])
y = 3'b000;
else if(r[3])
y = 3'b011;
else if(r[2])
y = 3'b010;
else if(r[1])
y = 3'b001;
else
y = 3'b000;
endmodule
```
```verilog
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
```verilog
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
```
```verilog
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
```
### Casez
```verilog
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
```
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.
## Common Errors
* Variable assigned in multiple always blocks
* Incomplete sensitivity list
* Incomplete branch and incomplete output assignment
### Multiple assignment
```verilog
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:
```verilog
always @*
if(en)
y = 1'b0;
else
y = a & b;
```
### Incomplete sensitivity list
Incomplete sensitivity list (missing b) b could change but Ythe y output would not,
causing unexpected behavior againg this is not synthesiseable.
```verilog
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.
```verilog
always @*
if(a > b)
gt = 1'b1; // no eq assignment in branch
else if(a == b)
eq = 1b'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 cuase endless hair pulling avoid such things. Here is how we could correct this:
```verilog
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
```verilog
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
```verilog
case(a)
2'b00: y =1'b1;
2'b10: y =1'b0;
2'b11: y =1'b1;
enscase
```
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.
```verilog
case(a)
2'b00: y =1'b1;
2'b10: y =1'b0;
2'b11: y =1'b1;
default : y = 1'b1;
enscase
```
## Adder with carry
```verilog
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
```verilog
localparam N = 4
```
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment