```////////////////////////////////////////////////////////////////////////////////
///
/// Solution to LSU EE 3755 Fall 2001 Practice Midterm
///

// Practice Exam: http://www.ece.lsu.edu/ee3755/2001f/mtp.pdf
// Practice Exam Text Solution: http://www.ece.lsu.edu/ee3755/2001f/mtpsol.pdf

/// Problem 1

module cla_3sol(sum,a,b);
input [2:0] a, b;
output [3:0] sum;

wire [2:0]   g, p, carry;

assign       carry[0] = 1'b0;
assign       carry[1] = g[0];
assign       carry[2] = g[0] & p[1] | g[1];
assign       sum[3] = g[0] & p[1] & p[2] | g[1] & p[2] | g[2];

cla_slice s0(sum[0],g[0],p[0],a[0],b[0],carry[0]);
cla_slice s1(sum[1],g[1],p[1],a[1],b[1],carry[1]);
cla_slice s2(sum[2],g[2],p[2],a[2],b[2],carry[2]);

endmodule

/// Problem 2

module fp_flags(pos,zero,neg,int,single);
input [31:0] single;
output       pos, zero, neg, int;

reg          int;
reg          sign;
reg [7:0]    exp;
reg [22:0]   frac;

reg          zero, pos, neg;

reg [5:0] loc;
integer   i;
reg       found;

always @( single ) begin

sign = single[31];
exp = single[30:23];
frac = single[22:0];

zero = !single[30:0];
pos = !sign && !zero;
neg = sign && !zero;

found = 0;
for(i=0; i<23; i=i+1) if( !found && frac[i] ) begin loc = i; found = 1; end
if( !found ) loc = 23;

int = zero || loc + exp >= 150;

end

endmodule

module test_fp_flags();

wire p, z, n, i;
reg [31:0] s;

fp_flags f(p,z,n,i,s);

reg [63:0] d;

input [31:0] value;
input ep,ez,en,ei;

begin

s = value;
#1;
if( {ep,ez,en,ei} !== {p,z,n,i} ) begin
\$display("Wrong flags: pzni %b != %b for %h",
{ep,ez,en,ei}, {p,z,n,i},s);
\$stop;
end

end

initial begin

apply(32'h3f8ccccd,1,0,0,0); // 1.1
apply(32'h3f800000,1,0,0,1);
apply(32'h4a08631c,1,0,0,1);
apply(32'h4a08631e,1,0,0,0);
apply(32'h42f6000d,1,0,0,0);
apply(32'd0,0,1,0,1);
apply(32'hca08631e,0,0,1,0);
apply(32'h56e0910c,1,0,0,1);

end

endmodule

/// Problem 3

module iloop(z,a);
input [31:0] a;
output       z;

reg [4:0] i;
reg       s, z;

initial begin
s = 0;
// Since i is five bits it's impossible to represent 32 and so
// "i<32" will always be true.  The problem can easily be fixed
// by making i one bit larger.
for(i=0; i<32; i=i+1) s = s | a[i];
z = !s;
end

endmodule

/// Problem 4

input [31:0] a,b;
input        clk;
output       sum;

reg [31:0]   sum;
integer      i;
reg          carry;

always @( posedge clk )
begin

carry = 0;

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

sum[i] = ~a[i] & ~b[i] &  carry |
~a[i] &  b[i] & ~carry |
a[i] & ~b[i] & ~carry |
a[i] &  b[i] &  carry;

carry = a[i] & b[i] | b[i] & carry | a[i] & carry;

end

end

endmodule

// This is a slightly streamlined version of the module in the exam
// text.

input [31:0] a,b;
input        clk;
output       sum;

reg [31:0] sum;
reg [4:0]    i;
reg          carry;

always @( posedge clk )
begin

i = i + 1;
if( i == 0 ) carry = 0;

sum[i] = ~a[i] & ~b[i] &  carry |
~a[i] &  b[i] & ~carry |
a[i] & ~b[i] & ~carry |
a[i] &  b[i] &  carry;

carry = a[i] & b[i] | b[i] & carry | a[i] & carry;

end

endmodule

/// Problem 5

module prefix_xor_4(x,a);
input [3:0] a;
output [3:0] x;

assign       x[0] = a[0];

xor x1(x[1],a[0],a[1]);
xor x2(x[2],x[1],a[2]);
xor x3(x[3],x[2],a[3]);

endmodule

/// Problem 6

module sums();

reg [3:0] a, b, c;
reg [5:0] d;

initial begin

a = 4'b0101;  b = 4'b0001;  c = a + b;

// Unsigned decimal: c =             Overflow?

// Signed decimal:   c =             Overflow?

a = -6; b = 4'b0001;  c = a + b;

// Unsigned decimal: c =             Overflow?

// Signed decimal:   c =             Overflow?

a = -6; b = 4'b0001;  c = a + b;

// Unsigned decimal: c =             Overflow?

// Signed decimal:   c =             Overflow?

a = 4'b1101; b = 4'b1100;  c = a + b;

// Unsigned decimal: c =             Overflow?

// Signed decimal:   c =             Overflow?

// Suppose c and d are for signed quantities.
// Fix the assignment below.
d = c;

end

endmodule

module sums_sol();

reg [3:0] a, b, c;
reg [5:0] d;

initial begin

a = 4'b0101;  b = 4'b0001;  c = a + b;

// Unsigned decimal: c = 6           Overflow? No

// Signed decimal:   c = 6           Overflow? No

a = -6; b = 4'b0001;  c = a + b;

// Unsigned decimal: c = 11          Overflow? No

// Signed decimal:   c = -5          Overflow? No

a = 4'b1101; b = 4'b1100;  c = a + b;

// Unsigned decimal: c =  9          Overflow? Yes (finally)

// Signed decimal:   c =  -7         Overflow? No

// Suppose c and d are used for signed quantities.
// Fix the assignment below.
// Original assignment: d = c;
d = {c[3],c[3],c};  // Fixed assignment with sign extension.

end

endmodule

/// Problem 7

module to_str(x,s,a,b);
input [1:0] s;
input       a, b;
output      x;

assign x = s == 2 ? a : b;

endmodule

module is_structural(x,s,a,b);
input [1:0] s;
input       a, b;
output      x;

wire        a_path, b_path;
wire        s_eq_2, s_ne_2;
wire        not_s_0;

or o1(x,a_path,b_path);

and a1(s_eq_2,s[1],not_s_0);
not n2(s_ne_2,s_eq_2);

not n1(not_s_0,s[0]);

and a2(a_path,s_eq_2,a);
and a3(b_path,s_ne_2,b);

endmodule

```