```////////////////////////////////////////////////////////////////////////////////
///
/// Solution to LSU EE 3755 Fall 2001 Homework 3
///

/// Problem 1

module prob1(sum,a,b);
input [29:0] a;
input [9:0]  b;
output [30:0] sum;

// Sign extend the operands to the same size as the sum.
assign        sum = {a[29],a} + { b[9] ? 21'h1ffff : 21'h0, b };

endmodule

/// Problem 3

// Solution

module cla40(cout,sum,a,b);
input [39:0] a, b;
output [39:0] sum;
output        cout;

// G[0] intentionally left unconnected.

wire [3:0]    G, P, cin;

assign        cin[0] = 0;
assign        cin[1] = G[0];
assign        cin[2] = G[0] & P[1] | G[1];
assign        cin[3] = G[0] & P[1] & P[2] | G[1] & P[2] | G[2];
assign        cout = G[0] & P[1] & P[2] & P[3]
| G[1] & P[2] & P[3] | G[2] & P[3] | G[3];

cla10 c0(G[0],P[0],sum[9:0], a[9:0], b[9:0],cin[0]);
cla10 c1(G[1],P[1],sum[19:10], a[19:10], b[19:10],cin[1]);
cla10 c2(G[2],P[2],sum[29:20], a[29:20], b[29:20],cin[2]);
cla10 c3(G[3],P[3],sum[39:30], a[39:30], b[39:30],cin[3]);

endmodule

// Code needed to test solution.

module cla10(G,P,sum,a,b,cin);
input [9:0] a, b;
input       cin;
output      G, P;
output [9:0] sum;

// Note: This isn't really a CLA. (The problem didn't ask for one.)
// It's here so that the testbench will run.

assign       sum = a + b + cin;
assign       P = ( a | b ) == 10'h3ff;
wire [10:0]  local_sum = a + b;
assign       G = local_sum[10];

endmodule

module testcla40();

wire [40:0] sum;
reg [39:0]  a, b;
integer    i;

initial begin
a = 0; b = 0; #1;

for(i=0; i<5000; i=i+1) begin

a[31:0] = \$random;
a[39:32] = \$random;
b[31:0] = \$random;
b[39:32] = \$random;
#1;
if( sum != shadow_sum ) begin
\$display("Wrong sum: %h + %h = %h != %h\n",
\$stop;
end
end

\$display("Tests completed.");

end

endmodule

/// Problem 4

// Solution

input [15:0]  multiplier, multiplicand;
input         start, clk;
output        product;

reg [31:0]    product;

reg [4:0]     bit;

initial bit = 0;

always @( posedge clk )

if( ready && start ) begin

bit     = 16;
product = { 16'd0, multiplier };

end else if( bit ) begin:A

reg lsb;

lsb     = product[0];
product = {product[31],product[31:1]};
bit     = bit - 1;

if( lsb ) product[31:15] = product[31:15]
+ {multiplicand[15],multiplicand};

end

endmodule

// Testbench for problem 4

// Extend sign of vector n.
`define sx(n) ( ((^((n)<<1))^(^(n))) ? -1^{(n)^~(n)}|(n) : (n) )

module testmult();

wire [31:0] product;
reg [15:0]  multiplier, multiplicand;
reg         start, clk;

integer     i;

parameter   handshake = 1;
parameter   signedmult = 2;

always #10 clk = !clk;

initial begin:I

clk = 0;
start = 0;

#25;

for(i=0; i<10000; i=i+1) begin

if( handshake ) wait( ready );

#5;

multiplier = \$random & 16'hffff;
multiplicand = \$random & 16'hffff;
case( signedmult )
0: shadow_product = multiplier * multiplicand;
1: shadow_product = `sx(multiplier) * `sx(multiplicand);
2: shadow_product = multiplier * `sx(multiplicand);
endcase

if( handshake )
begin
start = 1;
end
else
begin
#1;
end

if( shadow_product != product ) begin
\$display("Error %h x %h = %h != %h\n",
multiplier, multiplicand,
case( signedmult )
1: \$display("Error %d x %d = %d != %d\n",
`sx(multiplier), `sx(multiplicand),
2: \$display("Error %d x %d = %d != %d\n",
multiplier, `sx(multiplicand),
0: \$display("Error %d x %d = %d != %d\n",
multiplier, multiplicand,
endcase
\$stop;
end

end

\$display("Done with tests, no problems.");
\$stop;

end

endmodule

```