////////////////////////////////////////////////////////////////////////////////
///
/// Solution to LSU EE 3755 Spring 2002 Homework 3
///
// Assignment:http://www.ee.lsu.edu/ee3755/2002/hw03.html
////////////////////////////////////////////////////////////////////////////////
/// Problem 1
///
module adder8(sum,a,b);
input [7:0] a, b;
output [8:0] sum;
wire p0, g0, p1, g1;
adder4 a0(sum[3:0],p0,g0,a[3:0],b[3:0],1'b0);
adder4 a1(sum[7:4],p1,g1,a[7:4],b[7:4],g0);
assign sum[8] = g0 & p1 | g1;
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 2
///
// Common problem: Signals omitted from event control in always.
// For example, in the second always in the module below the
// following is an easy mistake to make (g0 missing):
// always @( p0 or p1 or g1 )
module adder4(sum,P,G,a,b,cin);
input [3:0] a, b;
input cin;
output [3:0] sum;
output P, G;
reg P, G;
wire p0, g0, p1, g1;
adder2 a0(sum[1:0],p0,g0,a[1:0],b[1:0],cin);
reg c0;
always @( cin or p0 or g0 ) c0 = cin & p0 | g0;
adder2 a1(sum[3:2],p1,g1,a[3:2],b[3:2],c0);
always @( p0 or p1 or g0 or g1 )
begin
P = p0 & p1;
G = g0 & p1 | g1;
end
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 3
///
// Common mistake: P and G must not be computed using a carry out.
module adder2(sum,P,G,a,b,cin);
input [1:0] a, b;
input cin;
output [1:0] sum;
output P, G;
wire c0, c1;
bfa bfa0(sum[0],c0,a[0],b[0],cin);
bfa bfa1(sum[1],c1,a[1],b[1],c0);
wire p0 = a[0] | b[0];
wire p1 = a[1] | b[1];
wire g0 = a[0] & b[0];
wire g1 = a[1] & b[1];
assign P = p0 & p1;
assign G = g0 & p1 | g1;
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Module used in the solution.
///
module bfa(sum,cout,a,b,cin);
input a,b,cin;
output sum,cout;
assign sum = a ^ b ^ cin;
assign cout = a & b | b & cin | a & cin;
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Testbench
///
module test_add8();
parameter stop_on_error = 1;
parameter max_errs = 10;
wire [8:0] sum;
reg [7:0] a, b;
adder8 a8(sum,a,b);
integer i, err;
reg [8:0] shadow_sum;
initial begin
err = 0;
for(i=0; i<='hffff; i=i+1) begin
{a,b} = i;
#1;
shadow_sum = a + b;
if( shadow_sum !== sum ) begin
err = err + 1;
if( err < max_errs )
$display("FAIL: Wrong sum: 0x%h + 0x%h = 0x%h (correct) != 0x%h",
a, b, shadow_sum, sum);
if( err == max_errs )
$display("Maximum error message count reached.");
if( stop_on_error ) $stop;
end
end
$display("Tests completed.");
if( err == 0 )
$display("PASS: No errors detected.");
else
$display("FAIL: %d errors.\n",err);
end
endmodule