diff --git a/4_bit_adder_schematic.png b/4_bit_adder_schematic.png new file mode 100644 index 0000000..2e194cc Binary files /dev/null and b/4_bit_adder_schematic.png differ diff --git a/WRITEUP.MD b/WRITEUP.MD new file mode 100644 index 0000000..6e87b07 --- /dev/null +++ b/WRITEUP.MD @@ -0,0 +1,147 @@ +# Lab 0 +### Taylor Sheneman and Alexander Hoppe + +## Introduction +In this lab exercise, we used Alex's full adder implementation from HW2 to make a 4-bit adder. To do this we chained together four full adder modules, carry-out to carry-in. We then ran a simulated test bench as well as testing on a Xilinx ZYBO FPGA dev kit. + + +## Full Adder Behavior +Our full adder is made up of four chained-together full adder modules, each of which is was designed like the following: + +full_adder + +Each of these full-adders has the following delay characteristics (assuming AND and XOR have the same unit gate delay, in our case 50 ns). + + | A/B | Cin + --- | :---: | :---: + S | 2 | 1 + Cout | 3 | 2 + +## Four Bit Adder + +To make a 4 bit adder, these modules are then chained together as in the following diagram: + +four_bit_adder + +When chained together, they have the following delay characteristics (in gate delay units): + + | Cin | A/B0 | A/B1 | A/B2 | A/B3 | +---|:---:|:---:|:---:|:---:|:---: +S0 | 1 | 2 | X | X | X +C0 | 2 | 3 | X | X | X +S1 | 3 | 4 | 2 | X | X +C1 | 4 | 5 | 3 | X | X +S2 | 5 | 6 | 4 | 2 | X +C2 | 6 | 7 | 5 | 3 | X +S3 | 7 | 8 | 6 | 4 | 2 +Cout | 8 | 9 | 7 | 5 | 3 +OVF | 9 | 10 | 8 | 6 | 4 + +So, the worst case here is that the overflow bit takes 10 unit gate delays to stabilize if it's affected by the least significant bits of the operands. + +## Timing Waveforms + +The operation that we used to show the worst-case delay (passing through all of the carry-outs from the LSB of each operand) was -1 + 1, which renders as `F` + `1` in GTKWave (`b1111` + `b0001`). + +![all_gate_delays](all_gate_delays.PNG) +This is the waveform for our entire test bench. + +![worst_case_delay](worst_case_gate_delay.PNG) +This is the worst case gate delay we simulated. Visible is the overflow stabilizing at the very end of the propagation chain. + +## Test Bench +In writing our test bench, we decided to cover a few different types of adder case. These were as follows: + +``` +Test Case | A | B | Expected Actual | Cout OVF + +Zero Cases +1+0 (0001+0000)| 0001 | 0000 | 0001 0001 | 0 0 +2+0 (0010+0000)| 0010 | 0000 | 0010 0010 | 0 0 +4+0 (0100+0000)| 0100 | 0000 | 0100 0100 | 0 0 +-1+0 (1111+0000)| 1111 | 0000 | 1111 1111 | 0 0 +-2+0 (1110+0000)| 1110 | 0000 | 1110 1110 | 0 0 +-4+0 (1100+0000)| 1100 | 0000 | 1100 1100 | 0 0 +-2+0 (1000+0000)| 1000 | 0000 | 1000 1000 | 0 0 + 7+0 (0111+0000)| 0111 | 0000 | 0111 0111 | 0 0 + 0+0 (0000+0000)| 0000 | 0000 | 0000 0000 | 0 0 + +Mirrored Zero Cases + 0+1 (0000+0001)| 0000 | 0001 | 0001 0001 | 0 0 + 0+2 (0000+0010)| 0000 | 0010 | 0010 0010 | 0 0 + 0+4 (0000+0100)| 0000 | 0100 | 0100 0100 | 0 0 + 0+7 (0000+0111)| 0000 | 0111 | 0111 0111 | 0 0 +0+-1 (0000+1111)| 0000 | 1111 | 1111 1111 | 0 0 +0+-2 (0000+1110)| 0000 | 1110 | 1110 1110 | 0 0 +0+-4 (0000+1100)| 0000 | 1100 | 1100 1100 | 0 0 +0+-8 (0000+1000)| 0000 | 1000 | 1000 1000 | 0 0 +``` + +First, we covered cases in which one input is zero and the other non-zero, to verify that each bit of each input is working and being passed through correctly to output. + +``` +Testing Internal Carryouts + 1+1 (0001+0001)| 0001 | 0001 | 0010 0010 | 0 0 + 2+2 (0010+0010)| 0010 | 0010 | 0100 0100 | 0 0 + +Testing External Carryout +-1-1 (1111+1111)| 1111 | 1111 | 1110 1110 | 1 0 +-2-2 (1110+1110)| 1110 | 1110 | 1100 1100 | 1 0 +-4-4 (1100+1100)| 1100 | 1100 | 1000 1000 | 1 0 +``` + +We wrote cases to test the functionality of the internal and external carryout wires on a mostly-individual basis (there's no 4+4 case, but that carryout should be covered by the -4-4 case). + +``` +Test Overflows +4+4 (0100+0100)| 0100 | 0100 | 1000 1000 | 0 1 +7+7 (0111+0111)| 0111 | 0111 | 1110 1110 | 0 1 +-8-8 (1000+1000)| 1000 | 1000 | 0000 0000 | 1 1 + 5+4 (0101+0100)| 0101 | 0100 | 1001 1001 | 0 1 +-5-4 (1011+1100)| 1011 | 1100 | 0111 0111 | 1 1 +``` + +To test our OVF bit, we wrote a few cases that intentionally overflow, in both the positive and negative direction. + +``` +Regular Cases +1+2 (0001+0010)| 0001 | 0010 | 0011 0011 | 0 0 +2+3 (0010+0011)| 0010 | 0011 | 0101 0101 | 0 0 +3+4 (0011+0100)| 0011 | 0100 | 0111 0111 | 0 0 +1+-2 (0001+1110)| 0001 | 1110 | 1111 1111 | 0 0 +-2-4 (1110+1100)| 1110 | 1100 | 1010 1010 | 1 0 +2+-4 (0010+1100)| 0010 | 1100 | 1110 1110 | 0 0 +-5+7 (1011+0111)| 1011 | 0111 | 0010 0010 | 1 0 +``` + +We rounded out the tests with a selection of regular, non-overflow cases, including additions of positive and negative numbers that result in a sign-flip. + +``` +Worst Case Delay +-1+1 (1111+0001)| 1111 | 0001 | 0000 0000 | 1 0 +``` +Finally, we attempted to test the worst case delay, by doing a calculation that results in the first bit carryout propogating all the way to the final carryout bit. + +## Test Case Failures +While it seems unlikely, the only two failures we encountered during our test bench simulation were due to typos in our test bench display lines. Two plus three is five, not six. + +## Implementation on FPGA +![FPGA](tested-cases.jpg) + +After we were convinced that our 4-bit adder code worked, we synthesized it and implemented it on our FPGA dev kit. We selected the following test cases for our manual testing, which we compared against our test bench results to ensure that it was behaving properly. + +manual_test_cases + +We selected some cases where the sign was the same and different, where there were zeros, where there were internal carries, where there were carryout bits, and where there were overflows. + +![five_plus_four](five_four_ovf.gif) + +Our FPGA behaved spectacularly! + +## Synthesis Statistics + +![summary_stats](vivado_summary_stats.PNG) + +After our design was synthesized, it ended up using 8 look-up tables, 9 flipflops, 13 IO devices and 1 `BUFG`, which we found out was a global clock buffer. + +The IO numbers correspond to the twelve devices we instatiated (four buttons, four switches, and four LEDs on ouput pins), and apparently one extra, which we think might have come from the USB connection or a status LED, we're not sure. The LUTs are not surprising, as we saw that a half-adder can be implemented with a single LUT, and therefore 4 full adders would require 8. We conjecture that the 9 flipflops would be accounted for by the 8 inputs, `a[3..0]` and `b[3..0]`, and the final one might be the `0` input to the first full adder's carry-in. diff --git a/adder.t.v b/adder.t.v new file mode 100644 index 0000000..f76acf9 --- /dev/null +++ b/adder.t.v @@ -0,0 +1,92 @@ +// Adder testbench +`timescale 1 ns / 1 ps +`include "adder.v" + +module testFullAdder4bit(); + reg [3:0] a; + reg [3:0] b; + wire [3:0] sum; + wire carryout, overflow; + + FullAdder4bit adder (sum[3:0], carryout, overflow, a, b); + + initial begin + $dumpfile("adder.vcd"); + $dumpvars; + $display("Test Case | A | B | Expected Actual | Cout OVF"); + $display("Zero Cases"); + a= 4'b0001; b=4'b0000; #1000 + $display("1+0 (0001+0000)| %b | %b | 0001 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0010; b=4'b0000; #1000 + $display("2+0 (0010+0000)| %b | %b | 0010 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0100; b=4'b0000; #1000 + $display("4+0 (0100+0000)| %b | %b | 0100 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1111; b=4'b0000; #1000 + $display("-1+0 (1111+0000)| %b | %b | 1111 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1110; b=4'b0000; #1000 + $display("-2+0 (1110+0000)| %b | %b | 1110 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1100; b=4'b0000; #1000 + $display("-4+0 (1100+0000)| %b | %b | 1100 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1000; b=4'b0000; #1000 + $display("-2+0 (1000+0000)| %b | %b | 1000 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0111; b=4'b0000; #1000 + $display(" 7+0 (0111+0000)| %b | %b | 0111 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0000; b=4'b0000; #1000 + $display(" 0+0 (0000+0000)| %b | %b | 0000 %b | %b %b", a, b, sum, carryout, overflow); + $display("Mirrored Zero Cases"); + a= 4'b0000; b=4'b0001; #1000 + $display(" 0+1 (0000+0001)| %b | %b | 0001 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0000; b=4'b0010; #1000 + $display(" 0+2 (0000+0010)| %b | %b | 0010 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0000; b=4'b0100; #1000 + $display(" 0+4 (0000+0100)| %b | %b | 0100 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0000; b=4'b0111; #1000 + $display(" 0+7 (0000+0111)| %b | %b | 0111 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0000; b=4'b1111; #1000 + $display("0+-1 (0000+1111)| %b | %b | 1111 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0000; b=4'b1110; #1000 + $display("0+-2 (0000+1110)| %b | %b | 1110 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0000; b=4'b1100; #1000 + $display("0+-4 (0000+1100)| %b | %b | 1100 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0000; b=4'b1000; #1000 + $display("0+-8 (0000+1000)| %b | %b | 1000 %b | %b %b", a, b, sum, carryout, overflow); + $display("Testing Internal Carryouts"); + a= 4'b0001; b=4'b0001; #1000 + $display(" 1+1 (0001+0001)| %b | %b | 0010 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0010; b=4'b0010; #1000 + $display(" 2+2 (0010+0010)| %b | %b | 0100 %b | %b %b", a, b, sum, carryout, overflow); + $display("Testing External Carryout"); + a= 4'b1111; b=4'b1111; #1000 + $display("-1-1 (1111+1111)| %b | %b | 1110 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1110; b=4'b1110; #1000 + $display("-2-2 (1110+1110)| %b | %b | 1100 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1100; b=4'b1100; #1000 + $display("-4-4 (1100+1100)| %b | %b | 1000 %b | %b %b", a, b, sum, carryout, overflow); + $display("Test Overflows"); + a= 4'b0100; b=4'b0100; #1000 + $display("4+4 (0100+0100)| %b | %b | 1000 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0111; b=4'b0111; #1000 + $display("7+7 (0111+0111)| %b | %b | 1110 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1000; b=4'b1000; #1000 + $display("-8-8 (1000+1000)| %b | %b | 0000 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0101; b=4'b0100; #1000 + $display(" 5+4 (0101+0100)| %b | %b | 1001 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1011; b=4'b1100; #1000 + $display("-5-4 (1011+1100)| %b | %b | 0111 %b | %b %b", a, b, sum, carryout, overflow); + $display("Regular Cases"); + a= 4'b0001; b=4'b0010; #1000 + $display("1+2 (0001+0010)| %b | %b | 0011 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0010; b=4'b0011; #1000 + $display("2+3 (0010+0011)| %b | %b | 0101 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0011; b=4'b0100; #1000 + $display("3+4 (0011+0100)| %b | %b | 0111 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0001; b=4'b1110; #1000 + $display("1+-2 (0001+1110)| %b | %b | 1111 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1110; b=4'b1100; #1000 + $display("-2-4 (1110+1100)| %b | %b | 1010 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b0010; b=4'b1100; #1000 + $display("2+-4 (0010+1100)| %b | %b | 1110 %b | %b %b", a, b, sum, carryout, overflow); + a= 4'b1011; b=4'b0111; #1000 + $display("-5+7 (1011+0111)| %b | %b | 0010 %b | %b %b", a, b, sum, carryout, overflow); + end +endmodule diff --git a/adder.v b/adder.v new file mode 100644 index 0000000..5c5ea59 --- /dev/null +++ b/adder.v @@ -0,0 +1,54 @@ +// Adder circuit + +`define AND and #50 +`define OR or #50 +`define XOR xor #50 + +module behavioralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + // Uses concatenation operator and built-in '+' + assign {carryout, sum}=a+b+carryin; +endmodule + +module structuralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + wire axorb, axorb_andcarryin, aandb; + + `XOR xorab (axorb, a, b); + `XOR xorsumout (sum, carryin, axorb); + `AND andab (aandb, a, b); + `AND andaxorbcarryin (axorb_andcarryin, axorb, carryin); + `OR orcarryout (carryout, aandb, axorb_andcarryin); + +endmodule + +module FullAdder4bit +( + output[3:0] sum, // 2's complement sum of a and b + output carryout, // Carry out of the summation of a and b + output overflow, // True if the calculation resulted in an overflow + input[3:0] a, // First operand in 2's complement format + input[3:0] b // Second operand in 2's complement format +); + wire cout0, cout1, cout2, carryout; + + structuralFullAdder adder0 (sum[0], cout0, a[0], b[0], 0); + structuralFullAdder adder1 (sum[1], cout1, a[1], b[1], cout0); + structuralFullAdder adder2 (sum[2], cout2, a[2], b[2], cout1); + structuralFullAdder adder3 (sum[3], carryout, a[3], b[3], cout2); + + `XOR xorOVF (overflow, cout2, carryout); + +endmodule diff --git a/adder.vcd b/adder.vcd new file mode 100644 index 0000000..d931096 --- /dev/null +++ b/adder.vcd @@ -0,0 +1,785 @@ +$date + Wed Sep 27 19:58:38 2017 +$end +$version + Icarus Verilog +$end +$timescale + 1ps +$end +$scope module behavioralFullAdder $end +$var wire 1 ! a $end +$var wire 1 " b $end +$var wire 1 # carryin $end +$var wire 1 $ carryout $end +$var wire 1 % sum $end +$upscope $end +$scope module testFullAdder4bit $end +$var wire 1 & carryout $end +$var wire 1 ' overflow $end +$var wire 4 ( sum [3:0] $end +$var reg 4 ) a [3:0] $end +$var reg 4 * b [3:0] $end +$scope module adder $end +$var wire 4 + a [3:0] $end +$var wire 4 , b [3:0] $end +$var wire 1 & carryout $end +$var wire 1 - cout0 $end +$var wire 1 . cout1 $end +$var wire 1 / cout2 $end +$var wire 1 ' overflow $end +$var wire 4 0 sum [3:0] $end +$scope module adder0 $end +$var wire 1 1 a $end +$var wire 1 2 aandb $end +$var wire 1 3 axorb $end +$var wire 1 4 axorb_andcarryin $end +$var wire 1 5 b $end +$var wire 1 6 carryin $end +$var wire 1 - carryout $end +$var wire 1 7 sum $end +$upscope $end +$scope module adder1 $end +$var wire 1 8 a $end +$var wire 1 9 aandb $end +$var wire 1 : axorb $end +$var wire 1 ; axorb_andcarryin $end +$var wire 1 < b $end +$var wire 1 - carryin $end +$var wire 1 . carryout $end +$var wire 1 = sum $end +$upscope $end +$scope module adder2 $end +$var wire 1 > a $end +$var wire 1 ? aandb $end +$var wire 1 @ axorb $end +$var wire 1 A axorb_andcarryin $end +$var wire 1 B b $end +$var wire 1 . carryin $end +$var wire 1 / carryout $end +$var wire 1 C sum $end +$upscope $end +$scope module adder3 $end +$var wire 1 D a $end +$var wire 1 E aandb $end +$var wire 1 F axorb $end +$var wire 1 G axorb_andcarryin $end +$var wire 1 H b $end +$var wire 1 / carryin $end +$var wire 1 & carryout $end +$var wire 1 I sum $end +$upscope $end +$upscope $end +$upscope $end +$enddefinitions $end +#0 +$dumpvars +xI +0H +xG +zF +zE +0D +xC +0B +xA +z@ +z? +0> +x= +0< +x; +z: +z9 +08 +x7 +06 +05 +z4 +z3 +z2 +11 +bx 0 +x/ +x. +x- +b0 , +b1 + +b0 * +b1 ) +bx ( +x' +x& +x% +x$ +z# +z" +z! +$end +#50000 +0E +0F +0? +0@ +09 +0: +04 +02 +13 +#100000 +0G +0A +0; +0- +17 +bx1 ( +bx1 0 +#150000 +0& +0/ +0. +0= +bx01 ( +bx01 0 +#200000 +0I +0' +0C +b1 ( +b1 0 +#1000000 +01 +18 +b10 ) +b10 + +#1050000 +03 +1: +#1100000 +07 +1= +b10 ( +b10 0 +#2000000 +08 +1> +b100 ) +b100 + +#2050000 +0: +1@ +#2100000 +0= +1C +b100 ( +b100 0 +#3000000 +11 +18 +1D +b1111 ) +b1111 + +#3050000 +13 +1: +1F +#3100000 +17 +1= +1I +b1111 ( +b1111 0 +#4000000 +01 +b1110 ) +b1110 + +#4050000 +03 +#4100000 +07 +b1110 ( +b1110 0 +#5000000 +08 +b1100 ) +b1100 + +#5050000 +0: +#5100000 +0= +b1100 ( +b1100 0 +#6000000 +0> +b1000 ) +b1000 + +#6050000 +0@ +#6100000 +0C +b1000 ( +b1000 0 +#7000000 +11 +18 +1> +0D +b111 ) +b111 + +#7050000 +13 +1: +1@ +0F +#7100000 +17 +1= +1C +0I +b111 ( +b111 0 +#8000000 +01 +08 +0> +b0 ) +b0 + +#8050000 +03 +0: +0@ +#8100000 +07 +0= +0C +b0 ( +b0 0 +#9000000 +15 +b1 * +b1 , +#9050000 +13 +#9100000 +17 +b1 ( +b1 0 +#10000000 +05 +1< +b10 * +b10 , +#10050000 +03 +1: +#10100000 +07 +1= +b10 ( +b10 0 +#11000000 +0< +1B +b100 * +b100 , +#11050000 +0: +1@ +#11100000 +0= +1C +b100 ( +b100 0 +#12000000 +15 +1< +b111 * +b111 , +#12050000 +13 +1: +#12100000 +17 +1= +b111 ( +b111 0 +#13000000 +1H +b1111 * +b1111 , +#13050000 +1F +#13100000 +1I +b1111 ( +b1111 0 +#14000000 +05 +b1110 * +b1110 , +#14050000 +03 +#14100000 +07 +b1110 ( +b1110 0 +#15000000 +0< +b1100 * +b1100 , +#15050000 +0: +#15100000 +0= +b1100 ( +b1100 0 +#16000000 +0B +b1000 * +b1000 , +#16050000 +0@ +#16100000 +0C +b1000 ( +b1000 0 +#17000000 +15 +0H +11 +b1 * +b1 , +b1 ) +b1 + +#17050000 +0F +12 +#17100000 +0I +b0 ( +b0 0 +1- +#17150000 +1= +b10 ( +b10 0 +#18000000 +05 +1< +01 +18 +b10 * +b10 , +b10 ) +b10 + +#18050000 +02 +19 +#18100000 +0- +1. +#18150000 +0= +1C +b100 ( +b100 0 +#19000000 +15 +1B +1H +11 +1> +1D +b1111 * +b1111 , +b1111 ) +b1111 + +#19050000 +12 +1? +1E +#19100000 +1- +1/ +1& +#19150000 +1= +1I +b1110 ( +b1110 0 +#20000000 +05 +01 +b1110 * +b1110 , +b1110 ) +b1110 + +#20050000 +02 +#20100000 +0- +#20150000 +0= +b1100 ( +b1100 0 +#21000000 +0< +08 +b1100 * +b1100 , +b1100 ) +b1100 + +#21050000 +09 +#21100000 +0. +#21150000 +0C +b1000 ( +b1000 0 +#22000000 +0H +0D +b100 * +b100 , +b100 ) +b100 + +#22050000 +0E +#22100000 +0& +#22150000 +1' +#23000000 +15 +1< +11 +18 +b111 * +b111 , +b111 ) +b111 + +#23050000 +12 +19 +#23100000 +1- +1. +#23150000 +1= +1C +b1110 ( +b1110 0 +#24000000 +05 +0< +0B +1H +01 +08 +0> +1D +b1000 * +b1000 , +b1000 ) +b1000 + +#24050000 +02 +09 +0? +1E +#24100000 +0- +0. +0/ +1& +#24150000 +0= +0C +0I +b0 ( +b0 0 +#25000000 +1B +0H +11 +1> +0D +b100 * +b100 , +b101 ) +b101 + +#25050000 +13 +1? +0E +#25100000 +17 +b1 ( +b1 0 +1/ +0& +#25150000 +1I +b1001 ( +b1001 0 +#26000000 +1H +18 +0> +1D +b1100 * +b1100 , +b1011 ) +b1011 + +#26050000 +1: +1@ +0? +1E +#26100000 +1= +1C +b1111 ( +b1111 0 +0/ +1& +#26150000 +0I +b111 ( +b111 0 +#27000000 +1< +0B +0H +08 +0D +b10 * +b10 , +b1 ) +b1 + +#27050000 +0@ +0E +#27100000 +0C +b11 ( +b11 0 +0& +#27150000 +0' +#28000000 +15 +01 +18 +b11 * +b11 , +b10 ) +b10 + +#28050000 +0: +19 +#28100000 +0= +b1 ( +b1 0 +1. +#28150000 +1C +b101 ( +b101 0 +#29000000 +05 +0< +1B +11 +b100 * +b100 , +b11 ) +b11 + +#29050000 +1: +09 +1@ +#29100000 +1= +0. +0C +b11 ( +b11 0 +1A +#29150000 +1C +b111 ( +b111 0 +0A +1/ +#29200000 +0/ +1I +b1111 ( +b1111 0 +1' +#29250000 +0I +b111 ( +b111 0 +0' +#30000000 +1< +1H +08 +b1110 * +b1110 , +b1 ) +b1 + +#30050000 +1F +#30100000 +1I +b1111 ( +b1111 0 +#31000000 +0< +01 +18 +1> +1D +b1100 * +b1100 , +b1110 ) +b1110 + +#31050000 +03 +0@ +1? +0F +1E +#31100000 +07 +0C +1/ +0I +b10 ( +b10 0 +1& +#31150000 +1I +b1010 ( +b1010 0 +#32000000 +0> +0D +b10 ) +b10 + +#32050000 +1@ +0? +1F +0E +#32100000 +1C +0/ +0I +b110 ( +b110 0 +1G +0& +#32150000 +1I +b1110 ( +b1110 0 +0G +1& +#32200000 +0& +1' +#32250000 +0' +#33000000 +15 +1< +0H +11 +1D +b111 * +b111 , +b1011 ) +b1011 + +#33050000 +0: +19 +12 +#33100000 +0= +b1100 ( +b1100 0 +1. +1- +#33150000 +0C +1A +1= +b1010 ( +b1010 0 +#33200000 +1/ +#33250000 +0I +b10 ( +b10 0 +1G +1' +#33300000 +1& +#33350000 +0' +#34000000 +0< +0B +1> +b1 * +b1 , +b1111 ) +b1111 + +#34050000 +1: +09 +#34100000 +0= +b0 ( +b0 0 +1; +0. +#34150000 +1. +1C +b100 ( +b100 0 +0A +#34200000 +0C +b0 ( +b0 0 +1A +0/ +#34250000 +1/ +1I +b1000 ( +b1000 0 +0G +1' +#34300000 +0I +b0 ( +b0 0 +1G +0' +0& +#34350000 +1& +1' +#34400000 +0' +#35000000 diff --git a/all_gate_delays.PNG b/all_gate_delays.PNG new file mode 100644 index 0000000..97c4642 Binary files /dev/null and b/all_gate_delays.PNG differ diff --git a/five_four_ovf.gif b/five_four_ovf.gif new file mode 100644 index 0000000..e13a7a0 Binary files /dev/null and b/five_four_ovf.gif differ diff --git a/full_adder_schematic.png b/full_adder_schematic.png new file mode 100644 index 0000000..44cbe1f Binary files /dev/null and b/full_adder_schematic.png differ diff --git a/lab0_wrapper.v b/lab0_wrapper.v index 3270bd2..7fea4e8 100644 --- a/lab0_wrapper.v +++ b/lab0_wrapper.v @@ -1,7 +1,7 @@ //-------------------------------------------------------------------------------- // Wrapper for Lab 0: Full Adder -// -// Rationale: +// +// Rationale: // The ZYBO board has 4 buttons, 4 switches, and 4 LEDs. But if we want to // show the results of a 4-bit add operation, we will need at least 6 LEDs! // @@ -21,7 +21,7 @@ // btn3 - show carryout on led0, overflow on led1 // // Note: Buttons, switches, and LEDs have the least-significant (0) position -// on the right. +// on the right. //-------------------------------------------------------------------------------- `timescale 1ns / 1ps @@ -43,7 +43,7 @@ module dff #( parameter W = 1 ) always @(posedge trigger) begin if(enable) begin q <= d; - end + end end endmodule @@ -104,15 +104,15 @@ module lab0_wrapper wire res_sel; // Select between display options wire cout; // Carry out from adder wire ovf; // Overflow from adder - + // Memory for stored operands (parametric width set to 4 bits) dff #(4) opA_mem(.trigger(clk), .enable(btn[0]), .d(sw), .q(opA)); dff #(4) opB_mem(.trigger(clk), .enable(btn[1]), .d(sw), .q(opB)); - + // Capture button input to switch which MUX input to LEDs jkff1 src_sel(.trigger(clk), .j(btn[3]), .k(btn[2]), .q(res_sel)); mux2 #(4) output_select(.in0(res0), .in1(res1), .sel(res_sel), .out(led)); - + // TODO: You write this in your adder.v FullAdder4bit adder(.sum(res0), .carryout(cout), .overflow(ovf), .a(opA), .b(opB)); @@ -121,5 +121,5 @@ module lab0_wrapper assign res1[1] = ovf; assign res1[2] = 1'b0; assign res1[3] = 1'b0; - + endmodule diff --git a/manual_test_cases.png b/manual_test_cases.png new file mode 100644 index 0000000..078d748 Binary files /dev/null and b/manual_test_cases.png differ diff --git a/results.txt b/results.txt new file mode 100644 index 0000000..e6b79bf --- /dev/null +++ b/results.txt @@ -0,0 +1,44 @@ +Test Case | A | B | Expected Actual | Cout OVF +Zero Cases +1+0 (0001+0000)| 0001 | 0000 | 0001 0001 | 0 0 +2+0 (0010+0000)| 0010 | 0000 | 0010 0010 | 0 0 +4+0 (0100+0000)| 0100 | 0000 | 0100 0100 | 0 0 +-1+0 (1111+0000)| 1111 | 0000 | 1111 1111 | 0 0 +-2+0 (1110+0000)| 1110 | 0000 | 1110 1110 | 0 0 +-4+0 (1100+0000)| 1100 | 0000 | 1100 1100 | 0 0 +-2+0 (1000+0000)| 1000 | 0000 | 1000 1000 | 0 0 + 7+0 (0111+0000)| 0111 | 0000 | 0111 0111 | 0 0 + 0+0 (0000+0000)| 0000 | 0000 | 0000 0000 | 0 0 +Mirrored Zero Cases + 0+1 (0000+0001)| 0000 | 0001 | 0001 0001 | 0 0 + 0+2 (0000+0010)| 0000 | 0010 | 0010 0010 | 0 0 + 0+4 (0000+0100)| 0000 | 0100 | 0100 0100 | 0 0 + 0+7 (0000+0111)| 0000 | 0111 | 0111 0111 | 0 0 +0+-1 (0000+1111)| 0000 | 1111 | 1111 1111 | 0 0 +0+-2 (0000+1110)| 0000 | 1110 | 1110 1110 | 0 0 +0+-4 (0000+1100)| 0000 | 1100 | 1100 1100 | 0 0 +0+-8 (0000+1000)| 0000 | 1000 | 1000 1000 | 0 0 +Testing Internal Carryouts + 1+1 (0001+0001)| 0001 | 0001 | 0010 0010 | 0 0 + 2+2 (0010+0010)| 0010 | 0010 | 0100 0100 | 0 0 +Testing External Carryout +-1-1 (1111+1111)| 1111 | 1111 | 1110 1110 | 1 0 +-2-2 (1110+1110)| 1110 | 1110 | 1100 1100 | 1 0 +-4-4 (1100+1100)| 1100 | 1100 | 1000 1000 | 1 0 +Test Overflows +4+4 (0100+0100)| 0100 | 0100 | 1000 1000 | 0 1 +7+7 (0111+0111)| 0111 | 0111 | 1110 1110 | 0 1 +-8-8 (1000+1000)| 1000 | 1000 | 0000 0000 | 1 1 + 5+4 (0101+0100)| 0101 | 0100 | 1001 1001 | 0 1 +-5-4 (1011+1100)| 1011 | 1100 | 0111 0111 | 1 1 +Regular Cases +1+2 (0001+0010)| 0001 | 0010 | 0011 0011 | 0 0 +2+3 (0010+0011)| 0010 | 0011 | 0101 0101 | 0 0 +3+4 (0011+0100)| 0011 | 0100 | 0111 0111 | 0 0 +1+-2 (0001+1110)| 0001 | 1110 | 1111 1111 | 0 0 +-2-4 (1110+1100)| 1110 | 1100 | 1010 1010 | 1 0 +2+-4 (0010+1100)| 0010 | 1100 | 1110 1110 | 0 0 +-5+7 (1011+0111)| 1011 | 0111 | 0010 0010 | 1 0 +Worst Case Delay +-1+1 (1111+0001)| 1111 | 0001 | 0000 0000 | 1 0 + diff --git a/tested-cases.jpg b/tested-cases.jpg new file mode 100644 index 0000000..05b4708 Binary files /dev/null and b/tested-cases.jpg differ diff --git a/vivado_summary_stats.PNG b/vivado_summary_stats.PNG new file mode 100644 index 0000000..29bd018 Binary files /dev/null and b/vivado_summary_stats.PNG differ diff --git a/worst_case_gate_delay.PNG b/worst_case_gate_delay.PNG new file mode 100644 index 0000000..4deb5ad Binary files /dev/null and b/worst_case_gate_delay.PNG differ