Skip to content

Commit 58906cf

Browse files
authored
Update chapter 3 bootcamp (#333)
1 parent e930fa7 commit 58906cf

File tree

6 files changed

+139
-3
lines changed

6 files changed

+139
-3
lines changed

doc/tutorials/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
- [Introduction to Test Driven Development](./chapter_3/00_unit_test.md#introduction-to-test-driven-development)
3737
- [What is a Full-Adder?](./chapter_3/00_unit_test.md#what-is-a-full-adder)
3838
- [Create a Full-Adder with TDD](./chapter_3/00_unit_test.md#create-full-adder-with-tdd)
39+
- [Exercise](./chapter_3/00_unit_test.md#exercise)
3940

4041
## Chapter 4: Basic Generation
4142

doc/tutorials/chapter_3/00_unit_test.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- [Introduction to Test Driven Development](./00_unit_test.md#introduction-to-test-driven-development)
44
- [What is a Full-Adder?](./00_unit_test.md#what-is-a-full-adder)
55
- [Create a Full-Adder with TDD](./00_unit_test.md#create-full-adder-with-tdd)
6+
- [Exercise](./00_unit_test.md#exercise)
67

78
## Learning Outcome
89

@@ -18,7 +19,7 @@ TDD is a software development approach in which test cases are created to specif
1819

1920
## What is a Full-Adder?
2021

21-
A Full Adder is an adder that takes three inputs and produces two outputs: the first two inputs are A and B, while the third input is a carry-in (C-IN). The output carry is designated as C-OUT, while the normal output is designated as S (SUM). A Full Adder logic is designed to handle up to eight inputs to create a byte-wide adder and can cascade the carry bit from one adder to another. We use a Full Adder when a carry-in bit is available because a 1-bit half-adder cannot take a carry-in bit, and another 1-bit adder must be used instead. A 1-bit Full Adder adds three operands and generates a 2-bit result.
22+
A Full Adder is an adder that takes three inputs and produces two outputs: the first two inputs are A and B, while the third input is a carry-in (C-IN). The output carry is designated as C-OUT, while the normal output is designated as S (SUM). We use a Full Adder when a carry-in bit is available because a 1-bit half-adder cannot take a carry-in bit, and another 1-bit adder must be used instead. A 1-bit Full Adder adds three operands and generates a 2-bit result.
2223

2324
Below is the circuit diagram of full-adder. From the diagram, we can see that the output `SUM` is the result of `XOR(XOR(A, B), C-IN)`, while `C-Out` is the result of `OR(AND(C-IN, XOR(A, B)), AND(B, A))`.
2425

@@ -147,3 +148,9 @@ test('should return true if result c-out is similar to truth table.', () async {
147148
```
148149

149150
Yeah, thats it. Congratulations! We have now successfully created a Full-Adder. You can find the executable code at [full_adder.dart](./full_adder.dart).
151+
152+
## Exercise
153+
154+
1. Based on what you learn, build a [Full Subtractor](https://www.geeksforgeeks.org/full-subtractor-in-digital-logic).
155+
156+
Answer to this exercise can be found at [answers/exercise.dart](./answers/exercise.dart). For those who wish to see the answer implementation with system verilog, you can check at [answers/exercise_sv.dart](./answers/exercise_sv.dart).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import 'package:rohd/rohd.dart';
2+
import 'package:test/test.dart';
3+
import 'helper.dart';
4+
5+
void main() async {
6+
final a = Logic(name: 'a');
7+
final b = Logic(name: 'b');
8+
final borrowIn = Logic(name: 'borrow_in');
9+
10+
final xorAB = a ^ b;
11+
final diff = xorAB ^ borrowIn;
12+
final borrowOut = (~xorAB & borrowIn) | (~a & b);
13+
14+
test('should return 0 when a and b equal 1', () async {
15+
a.put(1);
16+
b.put(1);
17+
borrowIn.put(0);
18+
19+
expect(diff.value.toInt(), equals(0));
20+
});
21+
22+
test('should return true if results matched truth table', () async {
23+
for (var i = 0; i <= 1; i++) {
24+
for (var j = 0; j <= 1; j++) {
25+
for (var k = 0; k <= 1; k++) {
26+
a.put(i);
27+
b.put(j);
28+
borrowIn.put(k);
29+
30+
final res = fsTruthTable(i, j, k);
31+
32+
expect(diff.value.toInt(), res.diff);
33+
expect(borrowOut.value.toInt(), res.borrowOut);
34+
}
35+
}
36+
}
37+
});
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import 'package:rohd/rohd.dart';
2+
import 'package:test/test.dart';
3+
import 'helper.dart';
4+
5+
class FullSubtractor extends Module {
6+
FullSubtractor(Logic a, Logic b, Logic borrowIn)
7+
: super(name: 'full_subtractor') {
8+
// Add Input
9+
a = addInput('a', a);
10+
b = addInput('b', b);
11+
borrowIn = addInput('borrowIn', borrowIn);
12+
13+
// Add Output
14+
final borrowOut = addOutput('borrowOut');
15+
final diff = addOutput('diff');
16+
17+
// Logic
18+
final xorAB = a ^ b;
19+
diff <= xorAB ^ borrowIn;
20+
borrowOut <= (~xorAB & borrowIn) | (~a & b);
21+
}
22+
// getter for output
23+
Logic get borrowOut => output('borrowOut');
24+
Logic get diff => output('diff');
25+
}
26+
27+
void main() async {
28+
final a = Logic(name: 'a');
29+
final b = Logic(name: 'b');
30+
final borrowIn = Logic(name: 'borrow_in');
31+
32+
final fSub = FullSubtractor(a, b, borrowIn);
33+
await fSub.build();
34+
35+
// ignore: avoid_print
36+
print(fSub.generateSynth());
37+
38+
test('should return 0 when a and b equal 1', () async {
39+
a.put(1);
40+
b.put(1);
41+
borrowIn.put(0);
42+
43+
expect(fSub.diff.value.toInt(), equals(0));
44+
});
45+
46+
test('should return true if results matched truth table', () async {
47+
for (var i = 0; i <= 1; i++) {
48+
for (var j = 0; j <= 1; j++) {
49+
for (var k = 0; k <= 1; k++) {
50+
a.put(i);
51+
b.put(j);
52+
borrowIn.put(k);
53+
54+
final res = fsTruthTable(i, j, k);
55+
56+
expect(fSub.diff.value.toInt(), res.diff);
57+
expect(fSub.borrowOut.value.toInt(), res.borrowOut);
58+
}
59+
}
60+
}
61+
});
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class FSResult {
2+
int diff = 0;
3+
int borrowOut = 0;
4+
}
5+
6+
FSResult fsTruthTable(int a, int b, int bIn) {
7+
final res = FSResult();
8+
9+
if (a < b + bIn) {
10+
res
11+
..diff = (a + 2) - b - bIn
12+
..borrowOut = 1;
13+
} else {
14+
res.diff = a - b - bIn;
15+
}
16+
17+
return res;
18+
}

doc/tutorials/chapter_3/full_adder.dart

+12-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ void main() async {
4343
b.put(j);
4444
cIn.put(k);
4545

46-
expect(sum.value.toInt(), faTruthTable(i, j, k).sum);
46+
final expected = faTruthTable(i, j, k).sum;
47+
final actual = sum.value.toInt();
48+
49+
expect(actual, expected,
50+
reason: 'For inputs a=$i, b=$j, cIn=$k,'
51+
' expected sum=$expected but found $actual');
4752
}
4853
}
4954
}
@@ -58,7 +63,12 @@ void main() async {
5863
b.put(j);
5964
cIn.put(k);
6065

61-
expect(cOut.value.toInt(), faTruthTable(i, j, k).cOut);
66+
final expected = faTruthTable(i, j, k).cOut;
67+
final actual = cOut.value.toInt();
68+
69+
expect(actual, expected,
70+
reason: 'For inputs a=$i, b=$j, cIn=$k,'
71+
' expected sum=$expected but found $actual');
6272
}
6373
}
6474
}

0 commit comments

Comments
 (0)