0% found this document useful (0 votes)
16 views62 pages

Vlsi El-1

This document is an experiential learning report from RV College of Engineering focusing on VLSI Fundamentals. It includes various experiments and Verilog code implementations for digital circuits such as inverters, gates (AND, OR, NAND, NOR, XOR), adders, and multipliers. Each section provides code and testbench examples for simulating the respective digital components.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views62 pages

Vlsi El-1

This document is an experiential learning report from RV College of Engineering focusing on VLSI Fundamentals. It includes various experiments and Verilog code implementations for digital circuits such as inverters, gates (AND, OR, NAND, NOR, XOR), adders, and multipliers. Each section provides code and testbench examples for simulating the respective digital components.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 62

RV College of Engineering, Bengaluru-560059

(Autonomous Institution affiliated to VTU, Belgaum)

5TH SEMESTER

EXPERENTIAL LEARNING
REPORT

SUBJECT: VLSI Fundamentals

Submitted By:

NAME:ARYAN
USN:1RV22EE008
Submitted To:
Dr. Ajay KM
(Department of Electrical and Electronics
Engineering)

i
Cadence

Exp 1: Inverter Design

ii
Exp 2:CMOS INVERTER CHARACTERISTCS

iii
iv
8-bit Counter

v
XOR gate

vi
OR gate

vii
AND gate

viii
NOR gate

ix
XNOR gate

x
NAND gate

xi
xii
Verilog

1. AND gate

module AND_Gate(
input A,
input B,
output Y
);
assign Y = A & B;
endmodule

testbench:
module AND_Gate_tb;
reg A, B;
wire Y;

AND_Gate uut (
.A(A),
.B(B),
.Y(Y)
);

initial begin
$monitor("A = %b, B = %b, Y = %b", A, B, Y);
A = 0; B = 0; #10;
A = 0; B = 1; #10;
A = 1; B = 0; #10;
A = 1; B = 1; #10;
$stop;
end
endmodule

xiii
xiv
2. OR gate
Module or_gate(input a,b; output y;);
Assign y=a|b;
endmodule
testbench:
module tb_or_gate;
reg A, B;
wire Y;

or_gate uut (
.A(A),
.B(B),
.Y(Y)
);

initial begin
A = 0; B = 0;
#10;
A = 0; B = 1;
#10;
A = 1; B = 0;
#10;
A = 1; B = 1;
#10;
$finish;
end

initial begin
$monitor("A = %b, B = %b, Y = %b", A, B, Y);
end
endmodule

xv
xvi
3. NAND gate
module nand_gate(
input a,
input b,
output y
);
assign Y = ~(A & B);
endmodule

testbench:
module tb_nand_gate;
reg A, B;
wire Y;

nand_gate uut (
.A(A),
.B(B),
.Y(Y)
);

initial begin
A = 0; B = 0;
#10;
A = 0; B = 1;
#10;
A = 1; B = 0;
#10;
A = 1; B = 1;
#10;
$finish;
end

initial begin
$monitor("A = %b, B = %b, Y = %b", A, B, Y);
end
xvii
endmodule

xviii
4. NOR gate
Code:
module myAND(
input a,b,
output c
);
assign c = ~(a|b);
endmodule

Testbench:
module or_tb();
reg a;
reg b;
wire c;
myAND module_u_test(a,b,c);
initial begin

#100;
a=1;b=0;#100;
a=1;b=1;#100;
a=0;b=0;#100;
a=0;b=1;#100;

end

endmodule

xix
5. XOR gate

Code:
module myAND(
input a,b,
output c
);
assign c = a^b;
endmodule
Testbench:
module or_tb();
reg a;
reg b;
wire c;
myAND module_u_test(a,b,c);
initial begin

#100;
a=1;b=0;#100;
a=1;b=1;#100;
a=0;b=0;#100;
a=0;b=1;#100;

end

endmodule

xx
Adders:
1. Carry Lookahead adder:
Code:
module carry_lookahead(
input [3:0]A,B,
input Cin,
output [3:0]Sum,
output Cout
);
wire [3:0]G,P;
wire [3:0]C;
assign G=A&B;
assign P=A^B;
assign C[0]=Cin;
assign C[1]=(G[0]|P[0]&C[0]);
assign C[2]=(G[1]|P[1]&C[1]);
assign C[3]=(G[2]|P[2]&C[2]);
assign Cout=(G[3]|P[3]&C[3]);
assign Sum=P^C;

endmodule

Testbench:
module CLA_tb;
reg [3:0]A,B;
reg Cin;
wire [3:0]Sum;
wire Cout;
carry_lookahead uut(
.A(A),
.B(B),
.Cin(Cin),
.Sum(Sum),
.Cout(Cout)
);
initial begin
A=4'b0011;B=4'b1010;Cin=1;#10;
A=4'b1111;B=4'b1010;Cin=1;#10;
A=4'b1001;B=4'b1011;Cin=1;#10;
A=4'b1000;B=4'b1111;Cin=1;#10;
A=4'b0011;B=4'b1000;Cin=1;#10;

end
endmodule

xxi
xxii
2. Carry skip adder

Code:
module CarrySelectAdder4Bit (
input [3:0] A, B,
input Cin,
output [3:0] Sum,
output Cout
);

wire [3:0] Sum0, Sum1;


wire [4:0] Carry0, Carry1;

assign Carry0[0] = 0;
assign Carry1[0] = 1;

genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin : bit_slice
assign Sum0[i] = A[i] ^ B[i] ^ Carry0[i];
assign Carry0[i+1] = (A[i] & B[i]) | (Carry0[i] & (A[i] ^ B[i]));

assign Sum1[i] = A[i] ^ B[i] ^ Carry1[i];


assign Carry1[i+1] = (A[i] & B[i]) | (Carry1[i] & (A[i] ^ B[i]));
end
endgenerate

assign Sum = Cin ? Sum1 : Sum0;


assign Cout = Cin ? Carry1[4] : Carry0[4];

endmodule

Testbench:

module CarrySelectAdder4Bit_tb;
reg [3:0] A, B;
reg Cin;
wire [3:0] Sum;
wire Cout;

// Instantiate the CarrySelectAdder4Bit module


CarrySelectAdder4Bit uut (
.A(A),
.B(B),
.Cin(Cin),
.Sum(Sum),
.Cout(Cout)
);

initial begin
// Monitor the values
$monitor("Time=%0t A=%b B=%b Cin=%b | Sum=%b Cout=%b", $time, A, B, Cin, Sum,
Cout);

// Apply test cases


A = 4'b0000; B = 4'b0000; Cin = 0; #10;
A = 4'b0001; B = 4'b0001; Cin = 0; #10;
A = 4'b0010; B = 4'b0011; Cin = 1; #10;
A = 4'b0110; B = 4'b0101; Cin = 0; #10;
xxiii
A = 4'b1111; B = 4'b1111; Cin = 1; #10;

// End simulation
$finish;
end
endmodule

xxiv
3. Carry save adder

Code:
module CarrySaveAdder4Bit (
input [3:0] A, B, C,
output [3:0] Sum,
output [3:0] Carry
);

assign Sum = A ^ B ^ C; // Sum without carry propagation


assign Carry = (A & B) | (B & C) | (C & A); // Carry bits

endmodule

Testbench:

module CarrySaveAdder4Bit_tb;
reg [3:0] A, B, C;
wire [3:0] Sum, Carry;

// Instantiate the CarrySaveAdder4Bit module


CarrySaveAdder4Bit uut (
.A(A),
.B(B),
.C(C),
.Sum(Sum),
.Carry(Carry)
);

initial begin
// Monitor the values
$monitor("Time=%0t A=%b B=%b C=%b | Sum=%b Carry=%b", $time, A, B, C, Sum, Carry);

// Apply test cases


A = 4'b0000; B = 4'b0000; C = 4'b0000; #10;
A = 4'b0001; B = 4'b0001; C = 4'b0001; #10;
A = 4'b0010; B = 4'b0011; C = 4'b0001; #10;
A = 4'b0110; B = 4'b0101; C = 4'b0011; #10;
A = 4'b1111; B = 4'b1111; C = 4'b1111; #10;

// End simulation
$finish;
end

xxv
endmodule

xxvi
4. Carry skip adders

Code:
module carry_skip_adder(
input [3:0] A, B,
input Cin,
output [3:0] Sum,
output Cout
);

wire [4:0] carry;


wire [3:0] P;

assign carry[0] = Cin;

genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin : bit_slice
assign P[i] = A[i] ^ B[i];
assign Sum[i] = P[i] ^ carry[i];
assign carry[i+1] = (P[i] & carry[i]) | (A[i] & B[i]);
end
endgenerate

assign Cout = carry[4];

endmodule

Testbench:
module carry_skip_tb;
reg [3:0] A, B;
reg Cin;
wire [3:0] Sum;
wire Cout;

// Instantiate the CarrySkipAdder4Bit module


carry_skip_adder uut (
.A(A),
.B(B),
.Cin(Cin),
.Sum(Sum),
.Cout(Cout)
);

initial begin
// Monitor the values
$monitor("Time=%0t A=%b B=%b Cin=%b | Sum=%b Cout=%b", $time, A, B, Cin, Sum,
Cout);

// Apply test cases


A = 4'b0000; B = 4'b0000; Cin = 0; #10;
A = 4'b0001; B = 4'b0001; Cin = 0; #10;
A = 4'b0010; B = 4'b0011; Cin = 1; #10;
A = 4'b0110; B = 4'b0101; Cin = 0; #10;
A = 4'b1111; B = 4'b1111; Cin = 1; #10;

// End simulation

end
xxvii
endmodule

xxviii
5. Inverter

Code:
module PMOS(
input wire A,
output wire Y
);
assign Y=~A;
endmodule
module NMOS(
input wire A,
output wire Y
);
assign Y=~A;
endmodule
module CMOS_INV(
input wire in,
output wire out
);
wire nmos_out,pmos_out;
PMOS p1(.A(in),.Y(pmos_out));
NMOS n1(.A(in),.Y(nmos_out));
assign out=pmos_out|nmos_out;
endmodule

Testbench:
module CMOS_TB;
reg in;
wire out;
CMOS_INV uut(
.in(in),
.out(out)
);
initial begin
in=0;
#10;
in=1;
#10;
in=0;
#10;
in=1;
#10;
in=0;
#10;
in=1;
#10;
in=0;
#10;
in=1;
#10;
in=0;
#10;
in=1;
#10;
in=0;
#10;
in=1;
#10;
$finish;
xxix
end
endmodule

xxx
6. Array Multiplier
Code:
module array_multiplier (
input [7:0] A,
input [7:0] B,
output [15:0] product
);

wire [7:0] partial [7:0];

genvar i, j;
generate
for (i = 0; i < 8; i = i + 1) begin :
for (j = 0; j < 8; j = j + 1) begin :
assign partial[i][j] = A[i] & B[j];
end
end
endgenerate

assign product = (partial[0]) +


(partial[1] << 1) +
(partial[2] << 2) +
(partial[3] << 3) +
(partial[4] << 4) +
(partial[5] << 5) +
(partial[6] << 6) +
(partial[7] << 7);

endmodule
Testbench:

module tb_array_multiplier;

reg [7:0] A, B;
wire [15:0] product;

array_multiplier uut (
.A(A),
.B(B),
.product(product)
);

xxxi
initial begin
$display("A B | Product");
$display("-----------------------------");

A = 8'b00000001; B = 8'b00000001;
#10; $display("%b %b | %b", A, B, product);

A = 8'b00000011; B = 8'b00000010;
#10; $display("%b %b | %b", A, B, product);

A = 8'b00001111; B = 8'b00000101;
#10; $display("%b %b | %b", A, B, product);

A = 8'b11111111; B = 8'b11111111;
#10; $display("%b %b | %b", A, B, product);

A = 8'b01010101; B = 8'b10101010;
#10; $display("%b %b | %b", A, B, product);

A = 8'b11110000; B = 8'b00001111;
#10; $display("%b %b | %b", A, B, product);

$finish;
end

xxxii
xxxiii
7. Barrel shifter
Code:
module BarrelShifter4Bit (
input [3:0] A,
input [1:0] Shift,
input LeftRight,
output [3:0] Out
);

wire [3:0] stage1, stage2;

assign stage1 = (LeftRight) ? {A[2:0], 1'b0} : {1'b0, A[3:1]};

assign stage2 = (Shift[0]) ? stage1 : A;


assign Out = (Shift[1]) ? ((LeftRight) ? {stage2[1:0], 2'b00} : {2'b00, stage2[3:2]}) : stage2;

endmodule

Testbench:
module BarrelShifter4Bit_tb;
reg [3:0] A;
reg [1:0] Shift;
reg LeftRight;
wire [3:0] Out;

BarrelShifter4Bit uut (
.A(A),
.Shift(Shift),
.LeftRight(LeftRight),
.Out(Out)
);

xxxiv
initial begin

$monitor("Time=%0t A=%b Shift=%b LeftRight=%b | Out=%b", $time, A, Shift,


LeftRight, Out);

// Apply test cases


A = 4'b1010; Shift = 2'b00; LeftRight = 0; #10;
A = 4'b1010; Shift = 2'b01; LeftRight = 0; #10;
A = 4'b1010; Shift = 2'b10; LeftRight = 0; #10;
A = 4'b1010; Shift = 2'b11; LeftRight = 0; #10;
A = 4'b1010; Shift = 2'b00; LeftRight = 1; #10;
A = 4'b1010; Shift = 2'b01; LeftRight = 1; #10;
A = 4'b1010; Shift = 2'b10; LeftRight = 1; #10;
A = 4'b1010; Shift = 2'b11; LeftRight = 1; #10;

// End simulation
$finish;
end
endmodule

xxxv
xxxvi
8. FIFO AND LIFO
Code:
module lifo #(parameter WIDTH = 8, DEPTH = 8)(
input clk, // Clock signal
input reset, // Active-high reset
input push, // Push enable
input pop, // Pop enable
input [WIDTH-1:0] data_in, // Data input
output reg [WIDTH-1:0] data_out, // Data output
output reg full, // Stack full flag
output reg empty // Stack empty flag
);

reg [WIDTH-1:0] stack [DEPTH-1:0]; // Stack memory


reg [2:0] sp = 0; // Stack pointer

always @(posedge clk or posedge reset) begin


if (reset) begin
sp <= 0;
full <= 0;
empty <= 1;
end else begin
// Push Operation
if (push && !full) begin
stack[sp] <= data_in;
sp <= sp + 1;
end

// Pop Operation
if (pop && !empty) begin
sp <= sp - 1;
data_out <= stack[sp - 1];
end

xxxvii
// Update full and empty flags
full <= (sp == DEPTH);
empty <= (sp == 0);
end
end
endmodule

module fifo #(parameter WIDTH = 8, DEPTH = 8)(


input clk, // Clock signal
input reset, // Active-high reset
input wr_en, // Write enable
input rd_en, // Read enable
input [WIDTH-1:0] data_in, // Data input
output reg [WIDTH-1:0] data_out, // Data output
output reg full, // FIFO full flag
output reg empty // FIFO empty flag
);

reg [WIDTH-1:0] memory [DEPTH-1:0]; // FIFO memory storage


reg [2:0] wr_ptr = 0, rd_ptr = 0; // Write and Read pointers
reg [3:0] count = 0; // Number of elements in FIFO

always @(posedge clk or posedge reset) begin


if (reset) begin
wr_ptr <= 0;
rd_ptr <= 0;
count <= 0;
full <= 0;
empty <= 1;
end else begin
// Write Operation
if (wr_en && !full) begin
memory[wr_ptr] <= data_in;
wr_ptr <= (wr_ptr + 1) % DEPTH;
xxxviii
count <= count + 1;
end

// Read Operation
if (rd_en && !empty) begin
data_out <= memory[rd_ptr];
rd_ptr <= (rd_ptr + 1) % DEPTH;
count <= count - 1;
end

// Update full and empty flags


full <= (count == DEPTH);
empty <= (count == 0);
end
end
endmodule

Testbench:
module tb_lifo;
reg clk, reset, push, pop;
reg [7:0] data_in;
wire [7:0] data_out;
wire full, empty;

// Instantiate LIFO
lifo uut (
.clk(clk),
.reset(reset),
.push(push),
.pop(pop),
.data_in(data_in),
.data_out(data_out),
.full(full),
.empty(empty)
xxxix
);

// Clock Generation
always #5 clk = ~clk;

initial begin
clk = 0;
reset = 1;
#10 reset = 0;

// Push data into LIFO


push = 1; pop = 0; data_in = 8'hA1; #10;
data_in = 8'hB2; #10;
data_in = 8'hC3; #10;
push = 0; #10; // Stop pushing

// Pop data from LIFO


pop = 1; #30;
pop = 0; #10; // Stop popping

$finish;
end

initial begin
$monitor("Time: %0t | Data In: %h | Data Out: %h | Full: %b | Empty: %b",
$time, data_in, data_out, full, empty);
end
endmodule

module tb_fifo;
reg clk, reset, wr_en, rd_en;
reg [7:0] data_in;
wire [7:0] data_out;
xl
wire full, empty;

// Instantiate FIFO
fifo uut (
.clk(clk),
.reset(reset),
.wr_en(wr_en),
.rd_en(rd_en),
.data_in(data_in),
.data_out(data_out),
.full(full),
.empty(empty)
);

// Clock Generation
always #5 clk = ~clk;

initial begin
clk = 0;
reset = 1;
#10 reset = 0;

// Write data into FIFO


wr_en = 1; rd_en = 0; data_in = 8'hA1; #10;
data_in = 8'hB2; #10;
data_in = 8'hC3; #10;
wr_en = 0; #10; // Stop writing

// Read data from FIFO


rd_en = 1; #30;
rd_en = 0; #10; // Stop reading

$finish;
end
xli
initial begin
$monitor("Time: %0t | Data In: %h | Data Out: %h | Full: %b | Empty: %b",
$time, data_in, data_out, full, empty);
end
endmodule

xlii
xliii
9. D-flip flop
Code:
module d_flip_flop (
input D,
input clk,
input reset,
output reg Q
);

always @(posedge clk or posedge reset) begin


if (reset) begin
Q <= 0;
end else begin
Q <= D;
end
end

endmodule
Testbench:
module tb_d_flip_flop;

reg D;
reg clk;
reg reset;
wire Q;

d_flip_flop uut (
.D(D),
.clk(clk),
.reset(reset),
.Q(Q)
);

// Generate clock signal


always begin
xliv
#5 clk = ~clk;
end

initial begin

clk = 0;
reset = 0;
D = 0;

reset = 1;
#10;
reset = 0;

D = 1;
#10;
D = 0;
#10;
D = 1; /
#10;
D = 0;
#10;

end

initial begin
$monitor("At time %t, D = %b, Q = %b", $time, D, Q);
end

endmodule

xlv
xlvi
10. T-Flip Flop
Code:
module t_flip_flop (
input T,
input clk,
input reset,
output reg Q
);
always @(posedge clk or posedge reset) begin
if (reset) begin
Q <= 0;
end else if (T) begin
Q <= ~Q; 1
end
end

endmodule

Testbench:

module tb_t_flip_flop;

reg T;
reg clk;
reg reset;
wire Q;

t_flip_flop uut (
.T(T),
.clk(clk),
.reset(reset),
.Q(Q)
);

always begin
#5 clk = ~clk;
end

initial begin
// Initialize inputs
clk = 0;
reset = 0;
T = 0;

reset = 1;
#10;
reset = 0;

xlvii
T = 1;
#10;
T = 0;
#10;
T = 1;
#10;
T = 0;
#10;
$finish;
end

// Monitor the values of Q


initial begin
$monitor("At time %t, T = %b, Q = %b", $time, T, Q);
end

endmodule

xlviii
11. JK-Flip flop

Code:
module jk_flip_flop (
input J,
input K,
input clk,
input reset,
output reg Q,
output reg Qn
);

always @(posedge clk or posedge reset) begin


if (reset) begin
Q <= 0;
Qn <= 1;
end else begin
case ({J, K})
2'b00: begin
Q <= Q;
Qn <= Qn;
end
2'b01: begin
Q <= 0;
Qn <= 1;
end
2'b10: begin
Q <= 1;
Qn <= 0;
end
2'b11: begin
Q <= ~Q;
Qn <= ~Qn;
end
endcase
end
end

endmodule

Testbench:
module tb_jk_flip_flop;

reg J;
reg K;
reg clk;
reg reset;
wire Q;
wire Qn;

jk_flip_flop uut (
.J(J),
.K(K),
.clk(clk),
.reset(reset),
.Q(Q),
.Qn(Qn)
);

always begin
#5 clk = ~clk;
end

initial begin
xlix
clk = 0;
reset = 0;
J = 0;
K = 0;

reset = 1;
#10;
reset = 0;

#10;
J = 0; K = 0;
#10;
J = 0; K = 1;
#10;
J = 1; K = 0;
#10;
J = 1; K = 1;
#10;

$finish;
end

initial begin
$monitor("At time %t, J = %b, K = %b, Q = %b, Qn = %b", $time, J, K, Q, Qn);
end

l
li
12. SR Flip Flop

Code:
module srflipflop (
input S,
input R,
input clk,
input reset,
output reg Q,
output reg Qn
);

always @(posedge clk or posedge reset) begin


if (reset) begin
Q <= 0;
Qn <= 1;
end else begin
case ({S, R})
2'b00: begin
Q <= Q;
Qn <= Qn;
end
2'b01: begin
Q <= 0;
Qn <= 1;
end
2'b10: begin
Q <= 1;
Qn <= 0;
end
2'b11: begin
Q <= 1'bx;
Qn <= 1'bx;
end
endcase
end
end

endmodule

Testbench:
module srfliptb;

reg S;
reg R;
reg clk;
reg reset;
wire Q;
wire Qn;

srflipflop uut (
.S(S),
.R(R),
.clk(clk),
.reset(reset),
.Q(Q),
.Qn(Qn)
);

always begin
#5 clk = ~clk;
end

initial begin
lii
clk = 0;
reset = 0;
S = 0;
R = 0;

reset = 1;
#10;
reset = 0;

#10;
S = 0; R = 0;
#10;
S = 0; R = 1;
#10;
S = 1; R = 0;
#10;
S = 1; R = 1;
#10;

$finish;
end

initial begin
$monitor("At time %t, S = %b, R = %b, Q = %b, Qn = %b", $time, S, R, Q, Qn);
end

endmodule

liii
liv
13.Divider

Code:
module divider_4bit (
input [3:0] dividend,
input [3:0] divisor,
output reg [3:0] quotient,
output reg [3:0] remainder
);

always @ (dividend or divisor) begin


if (divisor != 0) begin
quotient = dividend / divisor;
remainder = dividend % divisor;
end else begin
quotient = 4'b0000;
remainder = 4'b0000;
end
end

endmodule

Testbench:
module tb_divider_4bit;

reg [3:0] dividend, divisor;


wire [3:0] quotient, remainder;

divider_4bit uut (
.dividend(dividend),
.divisor(divisor),
.quotient(quotient),
.remainder(remainder)
);

initial begin
$display("Dividend Divisor | Quotient Remainder");
$display("------------------------------------------");

dividend = 4'b0010; divisor = 4'b0001;


#10; $display("%b %b | %b %b", dividend, divisor, quotient, remainder);

dividend = 4'b0100; divisor = 4'b0010;


#10; $display("%b %b | %b %b", dividend, divisor, quotient, remainder);

dividend = 4'b1001; divisor = 4'b0011;


#10; $display("%b %b | %b %b", dividend, divisor, quotient, remainder);

dividend = 4'b1010; divisor = 4'b0101;


#10; $display("%b %b | %b %b", dividend, divisor, quotient, remainder);

dividend = 4'b1111; divisor = 4'b0010;


#10; $display("%b %b | %b %b", dividend, divisor, quotient, remainder);

dividend = 4'b1111; divisor = 4'b1111;


#10; $display("%b %b | %b %b", dividend, divisor, quotient, remainder);

dividend = 4'b1000; divisor = 4'b0000;


#10; $display("%b %b | %b %b", dividend, divisor, quotient, remainder);

$finish;
end

endmodule
lv
lvi
14. Parallel Adder

Code:
module carry_lookahead(
input [3:0]A,B,
input Cin,
output [3:0]Sum,
output Cout
);
wire [3:0]G,P;
wire [3:0]C;
assign G=A&B;
assign P=A^B;
assign C[0]=Cin;
assign C[1]=(G[0]|P[0]&C[0]);
assign C[2]=(G[1]|P[1]&C[1]);
assign C[3]=(G[2]|P[2]&C[2]);
assign Cout=(G[3]|P[3]&C[3]);
assign Sum=P^C;

endmodule

Testbench:
module CLA_tb;
reg [3:0]A,B;
reg Cin;
wire [3:0]Sum;
wire Cout;
carry_lookahead uut(
.A(A),
.B(B),
.Cin(Cin),
.Sum(Sum),
.Cout(Cout)
);
initial begin
A=4'b0011;B=4'b1010;Cin=1;#10;
A=4'b1111;B=4'b1010;Cin=1;#10;
A=4'b1001;B=4'b1011;Cin=1;#10;
A=4'b1000;B=4'b1111;Cin=1;#10;
A=4'b0011;B=4'b1000;Cin=1;#10;

end
endmodule

lvii
lviii
15. Serial Adder

Code:

module serial_adder_4bit (

input clk,

input reset,

input start,

input A_in,

input B_in,

output reg sum,

output reg carry_out,

output reg done

);

reg [1:0] bit_count;

reg [4:0] A_reg, B_reg;

reg [1:0] state, next_state;

parameter IDLE = 2'b00, ADD = 2'b01, DONE = 2'b10;

always @(posedge clk or posedge reset) begin

if (reset) begin

state <= IDLE;

bit_count <= 0;

A_reg <= 0;

B_reg <= 0;

sum <= 0;

carry_out <= 0;

done <= 0;

end else begin

state <= next_state;


lix
end

end

always @(*) begin

case (state)

IDLE: next_state = start ? ADD : IDLE;

ADD: next_state = (bit_count == 4) ? DONE : ADD;

DONE: next_state = IDLE;

default: next_state = IDLE;

endcase

end

always @(posedge clk) begin

if (state == ADD) begin

A_reg <= {A_in, A_reg[4:1]};

B_reg <= {B_in, B_reg[4:1]};

sum <= A_reg[0] ^ B_reg[0] ^ carry_out;

carry_out <= (A_reg[0] & B_reg[0]) | (carry_out & (A_reg[0] ^ B_reg[0]));

bit_count <= bit_count + 1;

end else if (state == DONE) begin

done <= 1;

end else begin

done <= 0;

end

end

lx
Testbench:
module tb_serial_adder_4bit;

reg clk;
reg reset;
reg start;
reg A_in, B_in;
wire sum;
wire carry_out;
wire done;

serial_adder_4bit uut (
.clk(clk),
.reset(reset),
.start(start),
.A_in(A_in),
.B_in(B_in),
.sum(sum),
.carry_out(carry_out),
.done(done)
);

always begin
#5 clk = ~clk;
end

initial begin
clk = 0;
reset = 0;
start = 0;
A_in = 0;
B_in = 0;

reset = 1;
#10;
reset = 0;

start = 1;
#10;
start = 0;

A_in = 1; B_in = 1; #10;


A_in = 0; B_in = 0; #10;
A_in = 1; B_in = 1; #10;
A_in = 1; B_in = 1; #10;

#20;
if (done) $display("Addition is done. Sum: %b, Carry Out: %b", sum, carry_out);
end

initial begin
$monitor("At time %t, A_in = %b, B_in = %b, Sum = %b, Carry Out = %b, Done = %b", $time, A_in, B_in, sum,
carry_out, done);
end

endmodule

lxi
lxii

You might also like