//////////////////////////////////////////////////////////////////////////////// /// /// 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 + , where sum is the value in the signals // window and 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