1 DESIGN AND SIMULATE AN 8-BIT RIPPLE CARRY ADDER INTRODUCTION The 8-Bit Ripple Carry Adder makes for a good demonstration of Verilog’s capabilities, because it is easily modeled with multiple layers of modules. If a user starts with a Full Adder module, then packages eight of these modules correctly, it is possible to create the Ripple Carry Adder. VALUES SUM BINARY 100 + 99 199 11000111 22 + 33 55 110111 0 + 200 200 11001000 178 + 134 312 100111000 Fig. 1 - Table of Values Provided By Lab to Test 8-Bit Ripple Carry Adder Once the simulation is complete, we were instructed to analyze the results and discuss any issues encountered in the process. We were then asked to discuss, theoretically, what would be necessary to fully verify the functionality of the adder model. EQUIPMENT ModelSim PE Simulator RESULTS In order to create an 8-Bit Ripple Carry Adder, the simplest initial step was to design a module for a full adder that could be packaged into the final adder module. The following logic diagram shows the arrangement for a full adder, with three inputs (A, B, Carry In) and two outputs (Sum, Carry Out): 2 Fig. 2 - Logic Diagram for Full Adder Studying the logic diagram in Figure 2, it is very simple to implement a full adder in Verilog. The code to do so is as follows: module FullAdder (a, b, c_in, sum, c_out); input a, b, c_in; output c_out, sum; assign sum = (a^b)^c_in; assign c_out = (c_in&(a^b))|(a&b); endmodule In order to design a ripple carry 8-bit full adder, we must use this module eight times, in the following arrangement: Fig. 3 - Diagram of an 8-Bit Ripple Carry Full Adder As is evident in Figure 3, the 8-bit ripple carry adder has a particular arrangement that is necessary for correct functionality. The “carry out” of each full adder must be routed to the carry input of the successive 3 adder. When designing this arrangement in Verilog, the final adder in the sequence will have its own carry out, which will be monitored as a digit during the simulation. The following code shows the implementation of the 8-bit adder: module eight_bit_adder (a, b, c_in, sum, c_out); input[7:0] a; input[7:0] b; input c_in; output[7:0] sum; output c_out; wire [6:0] carry; FullAdder a0(a[0], b[0], 0, sum[0], carry[0]); FullAdder a1(a[1], b[1], carry[0], sum[1], carry[1]); FullAdder a2(a[2], b[2], carry[1], sum[2], carry[2]); FullAdder a3(a[3], b[3], carry[2], sum[3], carry[3]); FullAdder a4(a[4], b[4], carry[3], sum[4], carry[4]); FullAdder a5(a[5], b[5], carry[4], sum[5], carry[5]); FullAdder a6(a[6], b[6], carry[5], sum[6], carry[6]); FullAdder a7(a[7], b[7], carry[6], sum[7], c_out); endmodule In order to simulate this adder, it was necessary to create a series of A and B inputs for each full adder module, as well as wires to monitor the sum outputs. All of these quantities can be initialized through vector notation, so that they can be referenced easily by position. This also makes it easier to assign values to A and B, because ModelSim will convert your decimal assignments to binary stored in the array. The following code is the test bench for simulation: module eight_bit_test_bench; `timescale 1ns/1ns reg [7:0] A; reg [7:0] B; reg c_in = 0; wire [7:0] s_out; wire c_out; eight_bit_adder aa(A, B, c_in, s_out, c_out); initial begin 4 A = 100; B = 99; #20; A = 22; B = 33; #20; A = 0; B = 200; #20; A = 178; B = 134; #20 $stop; end endmodule In this test bench, the simulation cycles through a series of manually defined values to add together, and displays each result for 20 units of time. The following image shows the waveform output of this Verilog simulation: Fig. 4 - Waveform Output of 8-Bit Ripple Carry Adder 5 The monitored digits are arranged in such a way that the resulting binary value can be read from top to bottom, with the 8-bit adder’s carry output as the most significant digit. Observing the waveform, it can be confirmed that the binary values in Figure 1 are being replicated perfectly. Further observations on the waveform results and verification of the adder will be discussed in the Conclusion section. CONCLUSION This lab presented a simple problem that requires a multilayered solution. Because of this, the lab presented a good tutorial on the usefulness of nested modules to simplify complex circuits. For instance, the full adder has very simple code, and its arrangement into an 8-bit ripple carry adder is also very brief. However, this series of sums does not fully verify the adder. In order to verify for all values, it would be necessary to use for-loops to cycle through every possible combination. The bounds for numbers to sum should never add to a sum above 51110, because that would require 10 bits for representation. Therefore, the best method would be to nest two for-loops that cycle from 0 to 255 for both A and B values. This would create a cycle of every possible relevant value for the 8-bit adder. It appears, based on the results from the provided values, that the 8-bit adder designed in this lab would function correctly. 6 APPENDIX SECTION 1 – CODE FOR FULL ADDER module FullAdder (a, b, c_in, sum, c_out); input a, b, c_in; output c_out, sum; assign sum = (a^b)^c_in; assign c_out = (c_in&(a^b))|(a&b); endmodule SECTION 2 – CODE FOR EIGHT BIT RIPPLE CARRY ADDER module eight_bit_adder (a, b, c_in, sum, c_out); input[7:0] a; input[7:0] b; input c_in; output[7:0] sum; output c_out; wire [6:0] carry; FullAdder a0(a[0], b[0], 0, sum[0], carry[0]); FullAdder a1(a[1], b[1], carry[0], sum[1], carry[1]); FullAdder a2(a[2], b[2], carry[1], sum[2], carry[2]); FullAdder a3(a[3], b[3], carry[2], sum[3], carry[3]); FullAdder a4(a[4], b[4], carry[3], sum[4], carry[4]); FullAdder a5(a[5], b[5], carry[4], sum[5], carry[5]); FullAdder a6(a[6], b[6], carry[5], sum[6], carry[6]); FullAdder a7(a[7], b[7], carry[6], sum[7], c_out); endmodule SECTION 3 - CODE FOR EIGHT BIT ADDER TEST BENCH module eight_bit_test_bench; `timescale 1ns/1ns reg [7:0] A; reg [7:0] B; reg c_in = 0; wire [7:0] s_out; wire c_out; 7 eight_bit_adder aa(A, B, c_in, s_out, c_out); initial begin A = 100; B = 99; #20; A = 22; B = 33; #20; A = 0; B = 200; #20; A = 178; B = 134; #20 $stop; end endmodule