/// LSU EE 3755 Spring
2009 Computer Organization
//
/// Verilog Notes 6
///
Contents
// Carry Look
Ahead Adders
// One-Level
Carry Look-Ahead Adder
// Two-Level
Carry Look-Ahead Adder
///
References
//
// :P: Palnitkar, "Verilog
HDL"
// :Q: Qualis, "Verilog HDL Quick
Reference Card Revision 1.0"
// :PH: Patterson & Hennessy, "Computer
Organization & Design"
////////////////////////////////////////////////////////////////////////////////
/// Carry Look
Ahead Adders
///Motivation
//
// Ripple adders
take too long:
// A ripple adder
is too slow.
/// Carry
Look-Ahead Adder Properties
//
// More expensive
but much faster.
// Cost varies by
configuration.
//
// One-Level
Carry Look-Ahead Adder
// Requires large fan-in gates, which
may not be practical.
//
// Multiple Level
Carry Look-Ahead Adders.
// Cost lower than One-Level
CLA.
// Designed to fit technology
constraints and capabilities (fan-in, etc.)
///////////////////////////////////////////////////////////////
/// One-level
Carry Look-Ahead Adder
//:Example
module
cla_slice_part(g,p,a,b);
input a, b;
output g; //
Generate
output p; //
Propagate
/// Generate
//
//
assign g = a &
b;
///
Propagate
//
//
assign p = a ^
b;
endmodule
//
:Example:
//
// A 5-bit CLA
using five cla slice parts. The
generate and propagate
// signals are
used to produce the carry
signals.
module
cla_5(sum,cout, a,b,cin);
input [4:0] a,
b;
input cin;
output [4:0]
sum;
output cout;
wire [4:0] g, p, carry;
/// Logic for Carry Signals
assign carry[0]
= g[0] | cin &
p[0];
assign carry[1]
= g[1] |
g[0] & p[1] |
cin
& p[0] & p[1];
assign carry[2]
= g[2] |
g[1] & p[2] |
g[0] & p[1] & p[2]
|
cin & p[0] & p[1] & p[2];
assign carry[3] =
g[3] |
g[2] &p[3] |
g[1] &p[2] & p[3] |
g[0] & p[1] & p[2] &p[3] |
cin & p[0] & p[1]
& p[2] & p[3];
assign carry[4] =
g[4] |
g[3] & p[4] |
g[2] & p[3] & p[4] |
g[1] & p[2] & p[3] & p[4] |
g[0] & p[1] & p[2] &p[3] & p[4] |
cin & p[0] & p[1]
& p[2] & p[3] & p[4];
assign sum[0] = p[0] ^ cin;
assign sum[1] = p[1] ^ carry[0];
assign sum[2] = p[2] ^ carry[1];
assign sum[3] = p[3] ^ carry[2];
assign sum[4] = p[4] ^ carry[3];
assign cout =
carry[4];
cla_slice_part
s0(g[0],p[0],a[0],b[0]);
cla_slice_part
s1(g[1],p[1],a[1],b[1]);
cla_slice_part
s2(g[2],p[2],a[2],b[2]);
cla_slice_part
s3(g[3],p[3],a[3],b[3]);
cla_slice_part
s4(g[4],p[4],a[4],b[4]);
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Two-Level
Carry Look-Ahead Adder
// Goal: Avoid
large fan-ins of One-level CLA.
//
//
Idea:
// Divide adder into multiple adder
blocks.
// Block produces block-generate and
block-propagate signals.
// Below a 32-bit
two-level CLA.
module
four_bit_block_cla(P,G,carry,p,g,cin);
input [3:0]
p,g;
input
cin;
output [2:0]
carry;
output
P,G;
carry[0] = g[0] |
cin & p[0];
carry[1] = g[1] |
g[0] & p[1] |
cin & p[0] & p[1];
carry[2] = g[2] |
g[1] & p[2] |
g[0] & p [1] & p[2] |
cin & p[0] & p[1]
& p[2];
P =
p[0] & p[1] & p[2] & p[3];
G = g[3]
|
g[2] & p[3] |
g[1] & p[2] & p[3] |
g[0] & p[1] & p[2] & p[3];
endmodule
//carry propagate
and generate unit
module
CarryPropagateGenerateUnit( g,p,a,b);
input [31:0] a,b;
output [31:0]
g,p;
cla_slice_part
s0(g[0],p[0],a[0],b[0]);
cla_slice_part
s1(g[1],p[1],a[1],b[1]);
cla_slice_part
s2(g[2],p[2],a[2],b[2]);
cla_slice_part
s3(g[3],p[3],a[3],b[3]);
cla_slice_part
s4(g[4],p[4],a[4],b[4]);
cla_slice_part
s5(g[5],p[5],a[5],b[5]);
cla_slice_part
s6(g[6],p[6],a[6],b[6]);
cla_slice_part
s7(g[7],p[7],a[7],b[7]);
cla_slice_part
s8(g[8],p[8],a[8],b[8]);
cla_slice_part
s9(g[9],p[9],a[9],b[9]);
cla_slice_part
s10(g[10],p[10],a[10],b[10]);
cla_slice_part
s11(g[11],p[11],a[11],b[11]);
cla_slice_part
s12(g[12],p[12],a[12],b[12]);
cla_slice_part
s13(g[13],p[13],a[13],b[13]);
cla_slice_part
s14(g[14],p[14],a[14],b[14]);
cla_slice_part
s15(g[15],p[15],a[15],b[15]);
cla_slice_part
s16(g[16],p[16],a[16],b[16]);
cla_slice_part
s17(g[17],p[17],a[17],b[17]);
cla_slice_part
s18(g[18],p[18],a[18],b[18]);
cla_slice_part
s19(g[19],p[19],a[19],b[19]);
cla_slice_part
s20(g[20],p[20],a[20],b[20]);
cla_slice_part
s21(g[21],p[21],a[21],b[21]);
cla_slice_part
s22(g[22],p[22],a[22],b[22]);
cla_slice_part
s23(g[23],p[23],a[23],b[23]);
cla_slice_part
s24(g[24],p[24],a[24],b[24]);
cla_slice_part
s25(g[25],p[25],a[25],b[25]);
cla_slice_part
s26(g[26],p[26],a[26],b[26]);
cla_slice_part
s27(g[27],p[27],a[27],b[27]);
cla_slice_part
s28(g[28],p[28],a[28],b[28]);
cla_slice_part
s29(g[29],p[29],a[29],b[29]);
cla_slice_part
s30(g[30],p[30],a[30],b[30]);
cla_slice_part
s31(g[31],p[31],a[31],b[31]);
endmodule
//
module
ThirtyTwoBitSummationUnit(sum,p,carry,cin);
input [30:0]
carry;
input cin;
input [31:0] p;
output [31:0] sum;
assign sum[0] = p[0] ^
cin;
assign sum[1] = p[1] ^
carry[0];
assign sum[2] = p[2] ^ carry[1];
assign sum[3] = p[3] ^
carry[2];
assign sum[4] = p[4] ^
carry[3];
assign sum[5] = p[5] ^ carry[4];
assign sum[6] = p[6] ^
carry[5];
assign sum[7] = p[7] ^ carry[6];
assign sum[8] = p[8] ^ carry[7];
assign sum[9] = p[9] ^ carry[8];
assign sum[10] = p[10] ^ carry[9];
assign sum[11] = p[11] ^
carry[10];
assign sum[12] = p[12] ^ carry[11];
assign sum[13] = p[13] ^
carry[12];
assign sum[14] = p[14] ^
carry[13];
assign sum[15] = p[15] ^ carry[14];
assign sum[16] = p[16] ^
carry[15];
assign sum[17] = p[17] ^ carry[16];
assign sum[18] = p[18] ^ carry[17];
assign sum[19] = p[19] ^ carry[18];
assign sum[20] = p[20] ^
carry[19];
assign sum[21] = p[21] ^
carry[20];
assign sum[22] = p[22] ^ carry[21];
assign sum[23] = p[23] ^
carry[22];
assign sum[24] = p[24] ^
carry[23];
assign sum[25] = p[25] ^ carry[24];
assign sum[26] = p[26] ^
carry[25];
assign sum[27] = p[27] ^ carry[26];
assign sum[28] = p[28] ^ carry[27];
assign sum[29] = p[29] ^ carry[28];
assign sum[30] = p[30] ^ carry[29];
assign sum[31] = p[31] ^ carry[30];
endmodule
//
//
module
cla_32_two_level(sum,cout,a,b,cin);
input [31:0] a,
b;
input
cin;
output [31:0]
sum;
output cout;
wire [31:0] g, p,carry; //we don’t assign
carry[31] ..cout
wire [7:0] G,P;
assign carry[3] = G[0] | cin &
P[0];
assign carry[7] = G[1] | G[0] & P[1] I cin &
P[0] & P[1];
assign carry[11] = G[2]
|
G[1] & P[2] |
G[0] & P[1] & P[2] |
cin & P[0] & P[1]
& P[2];
assign carry[15] = G[3]
|
G[2] & P[3] |
G[1] & P[2] & P[3] |
G[0] & P[1] & P[2] & P[3] |
cin & P[0] &
P[1] & P[2] & P[3];
assign carry[19] = G[4]
|
G[3] & P[4] |
G[2] & P[3] & P[4] |
G[1] & P[2] & P[3] & P[4] |
G[0] & P[1] & P[2] & P[3] & P[4] |
cin & P[0] &
P[1] & P[2] & P[3] & P[4];
assign carry[23] = G[5]
|
G[4] & P[5] |
G[3]
& P[4] & P[5] |
G[2] & P[3] & P[4] & P[5] |
G[1] & P[2] & P[3] & P[4] & P[5] |
G[0] & P[1] & P[2] & P[3] & P[4] & P[5]
|
cin & P[0] &
P[1] & P[2] & P[3] & P[4] & P[5] ;
assign carry[27] = G[6] |
G[5] & P[6] |
G[4] & P[5] & P[6] |
G[3] & P[4] & P[5] & P[6] |
G[2] & P[3] & P[4] & P[5] & P[6] |
G[1]
& P[2] & P[3] & P[4] & P[5] & P[6] |
G[0] & P[1] & P[2] & P[3] & P[4] & P[5] & P[6]
|
cin & P[0] & P[1] & P[2] &
P[3] & P[4] & P[5] & P[6];
// This is carry[31];
assign cout = G[7] |
G[6] & P[7] |
G[5] & P[6] & P[7] |
G[4] & P[5] & P[6] & P[7] |
G[3] & P[4] & P[5] & P[6] & P[7] |
G[2] & P[3] & P[4] & P[5] & P[6] & P[7]
|
G[1] & P[2] & P[3] & P[4] & P[5] & P[6] & P[7]
|
G[0] & P[1] & P[2] & P[3]
& P[4] & P[5] & P[6] & P[7] |
cin
& P[0] & P[1] & P[2] & P[3] & P[4] & P[5] &
P[6] & P[7];
CarryPropagateGenerateUnit
CPGU( g,p,a,b);
four_bit_block_cla
FBBC0(P[0],G[0],carry[2:0],p[3:0],g[3:0],cin);
four_bit_block_cla
FBBC1(P[1],G[1],carry[6:4],p[7:4],g[7:4],carry[3]);
four_bit_block_cla
FBBC2(P[2],G[2],carry[10:8],p[11:8],g[11:8],carry[7]);
four_bit_block_cla
FBBC3(P[3],G[3],carry[14:12],p[15:12],g[15:12],carry[11]);
four_bit_block_cla
FBBC4(P[4],G[4],carry[18:16],p[19:16],g[19:16],carry[15]);
four_bit_block_cla
FBBC5(P[5],G[5],carry[22:20],p[23:20],g[23:20],carry[19]);
four_bit_block_cla
FBBC6(P[6],G[6],carry[26:24],p[27:24],g[27:24],carry[23]);
four_bit_block_cla
FBBC7(P[7],G[7],carry[30:28],p[31:28],g[31:28],carry[27]);
ThirtyTwoBitSummationUnit
TTBSU(sum,p,carry[30:0],cin);
endmodule
//
:Example:
//
// 32-bit ripple adder, for
comparison.
module
ripple_32(sum,a,b,cin);
input [31:0] a,
b;
input cin;
output [32:0]
sum;
wire [31:0] carry;
bfa_implicit
bfa0(sum[0],carry[0],a[0],b[0],cin);
bfa_implicit
bfa1(sum[1],carry[1],a[1],b[1],carry[0]);
bfa_implicit
bfa2(sum[2],carry[2],a[2],b[2],carry[1]);
bfa_implicit
bfa3(sum[3],carry[3],a[3],b[3],carry[2]);
bfa_implicit
bfa4(sum[4],carry[4],a[4],b[4],carry[3]);
bfa_implicit
bfa5(sum[5],carry[5],a[5],b[5],carry[4]);
bfa_implicit
bfa6(sum[6],carry[6],a[6],b[6],carry[5]);
bfa_implicit
bfa7(sum[7],carry[7],a[7],b[7],carry[6]);
bfa_implicit
bfa8(sum[8],carry[8],a[8],b[8],carry[7]);
bfa_implicit
bfa9(sum[9],carry[9],a[9],b[9],carry[8]);
bfa_implicit
bfa10(sum[10],carry[10],a[10],b[10],carry[9]);
bfa_implicit
bfa11(sum[11],carry[11],a[11],b[11],carry[10]);
bfa_implicit
bfa12(sum[12],carry[12],a[12],b[12],carry[11]);
bfa_implicit
bfa13(sum[13],carry[13],a[13],b[13],carry[12]);
bfa_implicit
bfa14(sum[14],carry[14],a[14],b[14],carry[13]);
bfa_implicit
bfa15(sum[15],carry[15],a[15],b[15],carry[14]);
bfa_implicit
bfa16(sum[16],carry[16],a[16],b[16],carry[15]);
bfa_implicit
bfa17(sum[17],carry[17],a[17],b[17],carry[16]);
bfa_implicit
bfa18(sum[18],carry[18],a[18],b[18],carry[17]);
bfa_implicit
bfa19(sum[19],carry[19],a[19],b[19],carry[18]);
bfa_implicit
bfa20(sum[20],carry[20],a[20],b[20],carry[19]);
bfa_implicit
bfa21(sum[21],carry[21],a[21],b[21],carry[20]);
bfa_implicit
bfa22(sum[22],carry[22],a[22],b[22],carry[21]);
bfa_implicit
bfa23(sum[23],carry[23],a[23],b[23],carry[22]);
bfa_implicit
bfa24(sum[24],carry[24],a[24],b[24],carry[23]);
bfa_implicit
bfa25(sum[25],carry[25],a[25],b[25],carry[24]);
bfa_implicit
bfa26(sum[26],carry[26],a[26],b[26],carry[25]);
bfa_implicit
bfa27(sum[27],carry[27],a[27],b[27],carry[26]);
bfa_implicit
bfa28(sum[28],carry[28],a[28],b[28],carry[27]);
bfa_implicit
bfa29(sum[29],carry[29],a[29],b[29],carry[28]);
bfa_implicit
bfa30(sum[30],carry[30],a[30],b[30],carry[29]);
bfa_implicit
bfa31(sum[31],sum[32],a[31],b[31],carry[30]);
endmodule