////////////////////////////////////////////////////////////////////////////////
///
/// Template for LSU EE 3755 Spring 2002 Homework 3
///
/// Due: Friday, 8 March 2002
/// Instructions:
//
// Copy this to a file named hw03.v to directory ~/hw in your
// class account. (~ is your home directory.) Use this
// file for your solution. Your entire solution should be in
// this file.
//
// Do not rename the modules in this file and be sure to use the
// directory and filename given above.
// Local copy of this file:
// /home/classes/ee3755/com/v/hw03.v
//
// Instruction on Simulator, Emacs, etc:
// "http://www.ece.lsu.edu/ee3755/proc.html
//
// Documentation for Simulator, Unix, etc.
// "http://www.ece.lsu.edu/ee3755/ref.html
////////////////////////////////////////////////////////////////////////////////
/// Problems 1, 2, and 3
// Complete the three modules below to form a 3-level, 8-bit
// carry-look-ahead adder (with a 9-bit sum). (Don't cringe, it's not
// that bad!)
//
// Each adder module should instantiate two copies of the next smaller
// adder module. That is, adder8 instantiates two adder4's, adder4
// instantiates two adder2's, which instantiates two binary full
// adders (bfa's). (See, it's not so bad ... right?) The modules
// should use carry-look-ahead logic to generate carry in signals and
// propagate (P) and generate (G) outputs, see the module shells for
// details. Module adder4 should use synthesizable procedural code
// (the instantiations of course are not part of the procedural code),
// the others can use structural or synthesizable procedural code.
//
// Use testbench test_adder8 to test adder8. There is no testbench to
// specifically test adder4 and adder2, if they don't work adder8
// should fail the testbench. Because it might not be obvious where
// the problem is, make good use of the structure and signals windows
// to debug your code. This is very important. To debug follow these
// steps:
//
// Run the testbench. (Do not change stop_on_error, it should be 1.)
// If it says "PASS" there's nothing to debug, otherwise:
// Press the "V" button in the "ModelSim" window. Three windows should pop up.
// On the structure window click "adder8"
// The top lines of the signals window should show a, b, sum, and sum
// should be something other than a+b.
// Expand adder8 in the structure window by clicking on the little "+".
// It should show the modules instantiated within adder8, two adder4's.
// Click on one of the adder4's. The signals window should change to
// show signals in the adder4 instantiation you clicked.
// Determine whether a+b+cin, using the values in the signals window,
// is equal to sum + <carry out>, where sum is the value in the signals
// window and <carry out> is something you figure out from the P and G
// outputs.
// If it's not equal, the problem is in that adder4, apply the steps
// above to it.
// If it is equal, select the other adder4.
// Also be sure to check the carry in signals.
//
// The wave window is not necessary here because the circuit is combinational.
//
// Note: The debugging procedure above makes alot more sense if you
// understand how the adder is supposed to work.
//
// Some may find it easier to work on adder2 first, then adder4, then
// adder8, that is a bottom-up approach. Others prefer a top-down
// approach: adder8, then adder4, then adder2.
//
// Complete the modules as specified by the Sure-Solve [tm] checklist
// items in each module.
//
/// Grading Criteria
//
// Passes the testbench.
// If it fails, partial credit will be given based on the type of
// problem. A large amount of credit will be deducted for
// compilation errors.
//
// Follows the guidelines.
// Be sure to instantiate two modules per module.
// Use procedural code where indicated.
//
// Coded cleanly.
// Points will be deducted for code that is correct but much more
// complex, unreadable, or inefficient than it has to be.
// For example, points would be deducted for the second assign below.
`ifdef XXX
assign x = a & b; // Use assign on this line instead of one on line below.
assign x = a == 1'b1 ? ( b == 1'b1 ? 1'b1 : 1'b0 ) : ( b == 1'b1 ? 1'b0 : 1'b0 );
`endif
////////////////////////////////////////////////////////////////////////////////
/// Problem 1
///
module adder8(sum,a,b);
input [7:0] a, b;
output [8:0] sum;
// Implement an 8-bit adder.
//
// [ ] Instantiate two adder4's (the module appears further below).
// [ ] Name the instances a0 and a1.
// [ ] Use carry-look-ahead logic to compute a carry in.
// [ ] Use carry-look-ahead logic to compute the MSB of the sum.
//
// Can be solved with four additional lines of Verilog (including
// declarations), but more are okay.
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 2
///
module adder4(sum,P,G,a,b,cin);
input [3:0] a, b;
input cin;
output [3:0] sum;
output P, G;
// Implement a 4-bit adder:
//
// [ ] Instantiate two adder2's (the module appears further below).
// [ ] Name the instances a0 and a1.
// [ ] Use carry-look-ahead logic to compute a carry in.
// [ ] Use carry-look-ahead logic to compute P and G.
// [ ] Use two always blocks.
// [ ] DO NOT use assign statements in this module.
//
// Can be solved with 12 added lines of Verilog, that includes
// declarations, begin's, end's, etc.
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Problem 3
///
module adder2(sum,P,G,a,b,cin);
input [1:0] a, b;
input cin;
output [1:0] sum;
output P, G;
// Implement a 2-bit ripple adder with propagate and generate outputs.
//
// [ ] Instantiate two bfa's (the module appears further below).
// [ ] Name the instances a0 and a1.
// [ ] Make a two-bit ripple adder from the bfa's.
// [ ] Use carry-look-ahead logic to compute P and G.
//
// Can be solved with 5 to 9 added lines of Verilog, that includes
// declarations. A different number of lines is okay.
endmodule
////////////////////////////////////////////////////////////////////////////////
/// Module used in the solution.
///
// Do not modify the module below.
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: %d + %d = %d (correct) != %d",
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