Do I like studying like this? No.

Do I have to if I want to clear this course? Yes.

These are my notes of Third and Fourth chapter from *Verilog HDL: A Guide to Digital Design and Synthesis*, Second Edition. By Samir Palnitkar.

## Revision : Full Adder

Let’s go through the steps

- We know Full Adder is two Half Adder
- There will me a Module
`fulladder`

which will have to instances of module`halfadder`

- We will also require
`or`

gate

- There will me a Module
- Half adder is combination of
`xor`

and`and`

### Let’s look at some code

module full_adder (a, b, cin, sum, carry); input a, b, cin; output sum, carry; wire s1, c1, c2; half_adder h1 ( .a(a), .b(b), .sum(s1), .carry(c1) ); half_adder h2 ( .a(cin), .b(s1), .sum(sum), .carry(c2) ); or or1(carry, c1, c2); endmodule //testbench module full_adder_tb; reg A = 0; reg B = 0; reg C = 0; wire SUM; wire CARRY; full_adder full_adder_inst ( .a(A), .b(B), .cin(C), .sum(SUM), .carry(CARRY) ); initial begin $display("Full Adder"); A = 1'b1; B = 1'b1; C = 1'b1; #10; $display("A %b \nB %b \nC %b \nSum %b \nCarry %b",A, B,C, SUM, CARRY); end endmodule // full_adder_tb

Let’s build Half Adders

module half_adder ( a, b, sum, carry ); input a, b; output sum; output carry; assign sum = a ^ b; // bitwise xor assign carry = a & b; // bitwise and endmodule // half_adder

module half_adder_tb; reg A = 0; reg B = 0; wire SUM; wire CARRY; half_adder half_adder_inst ( .a(A), .b(B), .sum(SUM), .carry(CARRY) ); initial begin A = 1'b1; B = 4'b1; #10; $display("A %b \nB %b \nSum %b \nCarry %b",A, B,SUM, CARRY); end endmodule // half_adder_tb

## How to make connections (long lasting?)

### Connection by Ordered List

This is pretty straightforward. You remember the list of things that you wanted to be connected and create instance with the same order.

full_adder(a, b, c_in, sum, c_out);

### Connection by Port Names

This might not really work when there are like a hundred ports and many of them are optional. Here we use port names.

full_adder fa_byname(.carry(C_OUT)), .a(A), .b(B), .c_in(C_IN), .sum(SUM);

it’s like keyword-argument passing in python (again, just drawing analogies so that I am able to remember it better)

Link to annotated notes for

## Conclusion

- We went through basics of verilog.
- Designed a fulladder (sort of?)
- Realised how to connect port.

Stay with me guys, we will eventually learn how to write *something* useful in verilog (I hope)

## 4 bit full adder

Now let’s work on this

For this, we need to create 4 instances of a normal singlebit full adder. Then use the carries wisely

Our inputs are going to be 4 bit except the carry

input [3:0]a; input [3:0]b; input cin;

Sum will be a 4bit sum and carry will be one bit

output [3:0]sum; output carry;

So, eventually according to the diagram our four full adders will be

full_adder f0( a[0], b[0], cin, sum[0], c1); full_adder f1( a[1], b[1], c1, sum[1], c2); full_adder f2( a[2], b[2], c2, sum[2], c3); full_adder f3( a[3], b[3], c2, sum[3], carry);

## 4 bit ripple carry adder

```
module half_adder
(
a,
b,
sum,
carry
);
input a, b;
output sum;
output carry;
assign sum = a ^ b; // bitwise xor
assign carry = a & b; // bitwise and
endmodule // half_adder
module full_adder
(a,
b,
cin,
sum,
carry);
input a, b, cin;
output sum, carry;
wire s1, c1, c2;
half_adder h1
(
.a(a),
.b(b),
.sum(s1),
.carry(c1)
);
half_adder h2
(
.a(cin),
.b(s1),
.sum(sum),
.carry(c2)
);
or or1(carry, c1, c2);
endmodule
module full_adder_4bit
(
a,
b,
cin,
sum,
carry
);
input [3:0]a;
input [3:0]b;
input cin;
output [3:0]sum;
output carry;
wire c1, c2, c3;
full_adder f0(
a[0],
b[0],
cin,
sum[0],
c1);
full_adder f1(
a[1],
b[1],
c1,
sum[1],
c2);
full_adder f2(
a[2],
b[2],
c2,
sum[2],
c3);
full_adder f3(
a[3],
b[3],
c3,
sum[3],
carry);
endmodule
//Testbench
module full_adder_4bit_tb;
reg [3:0]a;
reg [3:0]b;
reg cin;
wire [3:0]sum;
wire carry;
full_adder_4bit fa4(
a,
b,
cin,
sum,
carry
);
initial
begin
a = 4'b0001;
b = 4'b1111;
cin = 0;
#10;
$display("a = %b\n b = %b\n cin = %b\n sum = %b\n carry = %b\n", a, b, cin, sum, carry);
end
endmodule
```

a = 0001 b = 1111 cin = 0 sum = 0000 carry = 1

Both of these are gate level behavioural models

## Behavioural vs Dataflow

Dataflow modeling in Verilog allows a digital system to be designed in terms of it’s function. Dataflow modeling utilizes Boolean equations, and uses a number of operators that can acton inputs to produce outputs operators like + – && & ! ~ || | << >> {} so if i want to describe a 2 to 4 decoder in dataflow modeling i would be like this

module decoder2to4 ( e , a, b, do, dl, d2, d3); input e, a, b; output do, dl, d2, d3; assign dO = ( e & ~a & ~b); //00 assign dl = (e & ~a & b); //01 assign d2 = (e & a & ~b); //10 assign d3 = ( e & a & b); //11 endmodu1e

on the other hand The Behavioral modeling in Verilog is used to describe the function of a design in an algorithmic manner so if i want to describe a 2 to 4 decoder in dataflow modeling i would be like this

module decoder2to4 (e, i, d); output [3:0] d; input [l:0]i; input e; reg [3:0] d; always @ (i or e) begin if (e==l) begin case (i) 0: d = 4'b 0001; 1: d = 4'b 0010; 2: d = 4'b 0100; 3: d = 4'b 1000; default d = 4'b xxxx; endcase end else d = 4'b0000; end endmodule

Reference Difference between behavioral and dataflow in verilog

Side note: I never thought I would find VLSI so interesting ! I am actually enjoying this subject.

These are my notes of fifth chapter from *Verilog HDL: A Guide to Digital Design and Synthesis*, Second Edition. By Samir Palnitkar.

Gates!

## Not that one!

I surely do love adders.

## Logic Gates

- Important the first argument is always the output then followed by inputs

and ANDGATE(out, a, b);

You can do this for `and, or, nand, nor, xor, xnor`

Then there are two more gates, `buf`

which is buffer gate and `not`

which is a not gate(negates the input)

they have single input and output

## Multiplexer Design

Okay , I know this is just bunch of scribbling, and I will explain what I was trying to do there.

break down a multiplexer in it’s smallest indivisible pieces- gates. There are four `and`

gates and one `or`

Input to the Mux will I0, I1, I2, I3, S0, S1.

What we won’t have is S0bar, S1bar, Y0, Y1, Y2, Y3– So let’s declare them.

wire s0bar, s1bar; wire y0, y1, y2, y3; not(s0bar, s0); not(s1bar, s1);

How do we pass this to and gate. Let’s try generating y0

and (y0, i0, s1bar, s0bar);

Thus the overall code looks something like

module mux(input i0, i1, i2, i3; input s0, s1, output out); wire s0bar, s1bar; wire y0, y1, y2, y3; not(s0bar, s0); not(s1bar, s1); and (y0, i0, s1bar, s0bar); and (y1, i0, s1bar, s0); and (y3, i0, s1, s0bar); and (y2, i0, s1, s0); or (out, y0, y1, y2, y3); endmodule

## Additional functionality : Gate Delays

You can add delay using #(number) after the gate keyword.

add #(5) a1(out, a, b); //5sec delay for and gate

Annotates notes on Chapter 5: Gate Level Modeling

## Conclusion

- We not know about basic gates in Verilog and how to create a multiplexer in Verilog
- Also turns out, I actually like VSLI and Verilog!

## One thought on “Verilog: Adders, Ports, Gate Level Modeling, Multiplexer”