Sie sind auf Seite 1von 8

Lab 10: An Introduction to

High-Speed Addition
Deanna Sessions
ECEN 248-511
TA: Priya Venkatas
Date: November 6, 2013

Objectives:
This lab is designed to teach us why certain circuits are used for certain purposes. In particular
we are going to be looking at carry-lookahead addition for fast addition in high speed arithmetic
units. This particular circuit is better than a ripple carry adder when it comes to high speed
addition and it minimizes the delay that would be encountered in the ripple carry. This will
involve the implementation of dataflow of structural Verilog.

Design:
Below is the source code for all of the different modules that are used in this lab.
//clu
`timescale 1ns/1ps
`default_nettype none
module carry_lookahead_unit (C, G, P, C0);
output wire [4:1] C;
input wire [3:0] G, P;
input wire C0;

//Assigning each input and output wire

//creating the internal structure of the circuit by logic statements


assign #4 C[1] = G[0] | P[0] & C0;
assign #4 C[2] = G[1] | P[1] & G[0] | P[1] & P[0] & C0;
assign #4 C[3] = G[2] | P[2] & G[1] | P[2] & P[1] & G[0] | P[2] & P[1] & P[0] & C0;
assign #4 C[4] = G[3] | P[3] & G[2] | P[3] & P[2] & G[1] | P[3] & P[2] & P[1] & G[0] | P[3] & P[2] & P[1]
& P[0] & C0;
endmodule
//gpu
`timescale 1ns/1ps
`default_nettype none
module generate_propagate_unit (G, P, X, Y);
output wire [15:0] G, P;
input wire [15:0] X, Y;
assign #2 G = X & Y;
assign #2 P = X ^ Y;

//defining each input or output

//internal structure with included time delays

endmodule
//cla_4bit
`timescale 1ns/1ps
`default_nettype none
module carry_lookahead_4bit ( Cout, S, X, Y, Cin);
output wire Cout;
//Assigns input and output wires
output wire [3:0] S;
input wire [3:0] X, Y;
input wire Cin;
wire [3:0] G, P;
wire [4:0] C;

//Assigns internal wires

assign C[0] = Cin;


generate_propagate_unit gp0 ( G, P, X, Y);
carry_lookahead_unit cl0 (C[4:1], G, P, Cin);
summation_unit s0 (S, P, C[3:0]);
assign Cout = C[4];

//calls the generate/propagate unit


//calls the carry lookahead unit
//calls the summation unit
//Assigns the output of Cout to be the last C

endmodule
//block_carry_lookahead_unit
`timescale 1 ns/ 1 ps
`default_nettype none
module block_carry_lookahead_unit(G_star, P_star, C, G, P, C0);
output wire G_star, P_star;
output wire [3:1] C;
input wire [3:0] G, P;
input wire C0;

//defining all of the inputs and outputs

//assigning each all of the internal structures of the circuit


assign #4 C[1] = G[0]|P[0]&C0;
assign #4 C[2] = G[1]|P[1]&G[0]|P[1]&P[0]&C0;
assign #4 C[3] = G[2]|P[2]&G[1]|P[2]&P[1]&G[0]|P[2]&P[1]&P[0]&C0;
assign #4 G_star = G[3]|P[3]&G[2]|P[3]&P[2]&G[1]|P[3]&P[2]&P[1]&G[0];
assign #2 P_star = P[3]&P[2]&P[1]&P[0];
endmodule
//carry_lookahead_16bit
`timescale 1 ns/ 1 ps
`default_nettype none
module carry_lookahead_16bit(Cout, S, X, Y, Cin);
output wire Cout;
output wire [15:0] S;
input wire [15:0] X, Y;
input wire Cin;

//defining input and output wires

wire [16:0] C;
wire [15:0] P, G;
wire [3:0] P_star, G_star;

//internal wires to be used in the units called later on

assign C[0] = Cin;

//assigning Cin to be the first bit of the C wire

//each of the units called from this point forward are set up based on the schematic from the manual
generate_propagate_unit GPU(G, P, X, Y);
block_carry_lookahead_unit BCLAU0( //calling the block-carry-lookahead and setting up variables
.G_star (G_star[0]),
.P_star (P_star[0]),
.C (C[3:1]),
.G (G[3:0]),
.P (P[3:0]),
.C0 (C[0])

);
block_carry_lookahead_unit BCLAU1(
.G_star (G_star[1]),
.P_star (P_star[1]),
.C (C[7:5]),
.G (G[7:4]),
.P (P[7:4]),
.C0 (C[4])
);
block_carry_lookahead_unit BCLAU2(
.G_star (G_star[2]),
.P_star (P_star[2]),
.C (C[11:9]),
.G (G[11:8]),
.P (P[11:8]),
.C0 (C[8])
);
block_carry_lookahead_unit BCLAU3(
.G_star (G_star[3]),
.P_star (P_star[3]),
.C (C[15:13]),
.G (G[15:12]),
.P (P[15:12]),
.C0 (C[12])
);
carry_lookahead_unit CLAU(
.C({C[16], C[12], C[8], C[4]}),
.G(G_star[3:0]),
.P(P_star[3:0]),
.C0(C[0])
);

//calling second block carry lookahead unit

//calling third block carry lookahead unit

//calling the fourth lookahead unit

//carry lookahead unit

summation_unit SU(
.S(S[15:0]),
.P(P[15:0]),
.C(C[15:0])
);

//summation unit

assign Cout=C[16];

//assigning Cout to be the last bit of the C wire

endmodule

Results and Conclusion:


All of the code successfully worked in the way that I had intended it to work and the new 16-bit
carry look-ahead adder made for a very interesting test to see how much faster it is than the
ripple carry adder. The significant difference in propagation delay begs the question of why we
would ever use a ripple carry adder in the first place. It became apparent that the carry lookahead adder works much faster because it is configured in parallel as opposed to the series
configuration of full adders in the ripple carry adder. This high speed addition circuit has
minimal propagation delay and the entire timing diagrams can be seen in the waveforms below.

Figure 1: Experiment 1 4-bit Carry Look-Ahead Adder

Figure 2: Experiment 1 4-bit Carry Look-Ahead Adder zoomed in on earlier timing

Figure 3: Experiment 1 Propagation delay with markers

Figure 4: Experiment 1Waveform in its entirety

Figure 5: Experiment 2 Test-Delay 14 (Failed tests)

Figure 6: Experiment 2 Test-Delay 16 (Passed all tests)

Questions:

1. Source code can be seen in the design section.


2. Screenshots can be seen in the results section.
3. Questions throughout lab manual:
a. Experiment 2: If your calculations in the prelab are correct and you correctly
added delays to your sub-modules, you should find that the computed delay
matches the measure delay. Is this the case?
i. Yes it is the case. I calculated delta-g to be 2 ns and that the coefficient
was 8. This time delay of 16 ns was exactly what the time delay ended up
being for this circuit.
4. How does the gate-count of the 16-bit carry lookahead adder compare to that of a ripplecarry adder of the same size?
a. The 16-bit carry look-ahead adder has 82 gates in it and a 16-bit ripple carry
adder has about 80 gates (varying depending on the internal components of the
full-adders.) However, for roughly the same amount of gates the 16-bit carry
look-ahead adder as the ripple-carry adder, but the carry look-ahead works at a
significantly higher speed.
5. How does the propagation delay of the 4-bit carry lookahead adder compare to that of a
ripple-carry adder of the same size. Similarly, how does the 16-bit carry lookahead adder
compare to that of a ripple carry adder of the same size.
a. The 4-bit carry look-ahead adder the propagation delay is 3g. The 4-bit ripple
carry adder has a delay of 9g. For the 16-bit carry look-ahead adder there is a
delay of 8g and for a 16 bit ripple carry adder the delay is upwards of 33g
because it has upwards of 80 gates lined up in series for the most part. The carry
look-ahead adder has a smaller delay in both instances because it works in a more
efficient manner than the ripple carry adder. This is due to the usage of different
block units strung together to achieve a common goal using parallel circuitry
rather than a long string of full adders in series like the ripple carry adder.

Student Feedback:
1. I liked working with Verilog again. Its really a wonderful program. I disliked that some
of this stuff is confusing to look at and plug into Verilog.
2. Nothing was unclear.
3. I dont really have any suggestions other than possibly a bit more guidance about what
Cin and Cout should be assigned to seeing as that gave me a bit of grief.