////////////////////////////////////////////////////////////////////////////////
///
/// 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;
real shadow_s;
fp_flags f(p,z,n,i,s);
reg [63:0] d;
task apply;
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
endtask
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
module add_1(sum,a,b,clk);
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.
module add_2(sum,a,b,clk);
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