1d86ed7fbStbbdev /*
2*b15aabb3Stbbdev     Copyright (c) 2005-2021 Intel Corporation
3d86ed7fbStbbdev 
4d86ed7fbStbbdev     Licensed under the Apache License, Version 2.0 (the "License");
5d86ed7fbStbbdev     you may not use this file except in compliance with the License.
6d86ed7fbStbbdev     You may obtain a copy of the License at
7d86ed7fbStbbdev 
8d86ed7fbStbbdev         http://www.apache.org/licenses/LICENSE-2.0
9d86ed7fbStbbdev 
10d86ed7fbStbbdev     Unless required by applicable law or agreed to in writing, software
11d86ed7fbStbbdev     distributed under the License is distributed on an "AS IS" BASIS,
12d86ed7fbStbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d86ed7fbStbbdev     See the License for the specific language governing permissions and
14d86ed7fbStbbdev     limitations under the License.
15d86ed7fbStbbdev */
16d86ed7fbStbbdev 
17d86ed7fbStbbdev #include <cstdio>
18d86ed7fbStbbdev #include <cassert>
19d86ed7fbStbbdev 
20d86ed7fbStbbdev #include "oneapi/tbb/global_control.h"
21d86ed7fbStbbdev 
22d86ed7fbStbbdev #include "common/utility/utility.hpp"
23d86ed7fbStbbdev #include "common/utility/get_default_num_threads.hpp"
24d86ed7fbStbbdev 
25d86ed7fbStbbdev #if _MSC_VER
26d86ed7fbStbbdev #pragma warning( \
27d86ed7fbStbbdev     disable : 4503) // Suppress "decorated name length exceeded, name was truncated" warning
28d86ed7fbStbbdev #endif
29d86ed7fbStbbdev 
30d86ed7fbStbbdev #define USE_TWO_BIT_FULL_ADDER 1
31d86ed7fbStbbdev 
32d86ed7fbStbbdev #include "basics.hpp"
33d86ed7fbStbbdev #include "one_bit_adder.hpp"
34d86ed7fbStbbdev #if USE_TWO_BIT_FULL_ADDER
35d86ed7fbStbbdev #include "two_bit_adder.hpp"
36d86ed7fbStbbdev #else
37d86ed7fbStbbdev #include "four_bit_adder.hpp"
38d86ed7fbStbbdev #endif
39d86ed7fbStbbdev #include "D_latch.hpp"
40d86ed7fbStbbdev 
41d86ed7fbStbbdev // User-specified globals with default values
42d86ed7fbStbbdev bool verbose = false; // prints bin details and other diagnostics to screen
43d86ed7fbStbbdev bool silent = false; // suppress all output except for time
44d86ed7fbStbbdev 
main(int argc,char * argv[])45d86ed7fbStbbdev int main(int argc, char *argv[]) {
46d86ed7fbStbbdev     utility::thread_number_range threads(utility::get_default_num_threads);
47d86ed7fbStbbdev     utility::parse_cli_arguments(
48d86ed7fbStbbdev         argc,
49d86ed7fbStbbdev         argv,
50d86ed7fbStbbdev         utility::cli_argument_pack()
51d86ed7fbStbbdev             //"-h" option for displaying help is present implicitly
52d86ed7fbStbbdev             .positional_arg(threads, "#threads", utility::thread_number_range_desc)
53d86ed7fbStbbdev             .arg(verbose, "verbose", "   print diagnostic output to screen")
54d86ed7fbStbbdev             .arg(silent, "silent", "    limits output to timing info; overrides verbose"));
55d86ed7fbStbbdev 
56d86ed7fbStbbdev     if (silent)
57d86ed7fbStbbdev         verbose = false; // make silent override verbose
58d86ed7fbStbbdev 
59d86ed7fbStbbdev     oneapi::tbb::tick_count start = oneapi::tbb::tick_count::now();
60d86ed7fbStbbdev     for (int p = threads.first; p <= threads.last; p = threads.step(p)) {
61d86ed7fbStbbdev         oneapi::tbb::global_control c(oneapi::tbb::global_control::max_allowed_parallelism, p);
62d86ed7fbStbbdev         if (!silent)
63d86ed7fbStbbdev             std::cout << "graph test running on " << p << " threads."
64d86ed7fbStbbdev                       << "\n";
65d86ed7fbStbbdev 
66d86ed7fbStbbdev         oneapi::tbb::flow::graph g;
67d86ed7fbStbbdev 
68d86ed7fbStbbdev         { // test buffer: 0, 1
69d86ed7fbStbbdev             buffer b(g);
70d86ed7fbStbbdev             toggle input(g);
71d86ed7fbStbbdev             led output(
72d86ed7fbStbbdev                 g, "OUTPUT", false); // false means we will explicitly call display to see LED
73d86ed7fbStbbdev 
74d86ed7fbStbbdev             make_edge(input.get_out(), input_port<0>(b));
75d86ed7fbStbbdev             make_edge(output_port<0>(b), output.get_in());
76d86ed7fbStbbdev 
77d86ed7fbStbbdev             if (!silent)
78d86ed7fbStbbdev                 printf("Testing buffer...\n");
79d86ed7fbStbbdev             input.activate(); // 0
80d86ed7fbStbbdev             g.wait_for_all();
81d86ed7fbStbbdev             if (!silent)
82d86ed7fbStbbdev                 output.display();
83d86ed7fbStbbdev             assert(output.get_value() == low);
84d86ed7fbStbbdev             input.flip(); // 1
85d86ed7fbStbbdev             g.wait_for_all();
86d86ed7fbStbbdev             if (!silent)
87d86ed7fbStbbdev                 output.display();
88d86ed7fbStbbdev             assert(output.get_value() == high);
89d86ed7fbStbbdev         }
90d86ed7fbStbbdev 
91d86ed7fbStbbdev         { // test not_gate: 0, 1
92d86ed7fbStbbdev             not_gate n(g);
93d86ed7fbStbbdev             toggle input(g);
94d86ed7fbStbbdev             led output(g, "OUTPUT", false);
95d86ed7fbStbbdev 
96d86ed7fbStbbdev             make_edge(input.get_out(), input_port<0>(n));
97d86ed7fbStbbdev             make_edge(output_port<0>(n), output.get_in());
98d86ed7fbStbbdev 
99d86ed7fbStbbdev             if (!silent)
100d86ed7fbStbbdev                 printf("Testing not_gate...\n");
101d86ed7fbStbbdev             input.activate(); // 0
102d86ed7fbStbbdev             g.wait_for_all();
103d86ed7fbStbbdev             if (!silent)
104d86ed7fbStbbdev                 output.display();
105d86ed7fbStbbdev             assert(output.get_value() == high);
106d86ed7fbStbbdev             input.flip(); // 1
107d86ed7fbStbbdev             g.wait_for_all();
108d86ed7fbStbbdev             if (!silent)
109d86ed7fbStbbdev                 output.display();
110d86ed7fbStbbdev             assert(output.get_value() == low);
111d86ed7fbStbbdev         }
112d86ed7fbStbbdev 
113d86ed7fbStbbdev         { // test two-input and_gate: 00, 01, 10, 11
114d86ed7fbStbbdev             and_gate<2> a(g);
115d86ed7fbStbbdev             toggle input0(g);
116d86ed7fbStbbdev             toggle input1(g);
117d86ed7fbStbbdev             led output(g, "OUTPUT", false);
118d86ed7fbStbbdev 
119d86ed7fbStbbdev             make_edge(input0.get_out(), input_port<0>(a));
120d86ed7fbStbbdev             make_edge(input1.get_out(), input_port<1>(a));
121d86ed7fbStbbdev             make_edge(output_port<0>(a), output.get_in());
122d86ed7fbStbbdev 
123d86ed7fbStbbdev             if (!silent)
124d86ed7fbStbbdev                 printf("Testing and_gate...\n");
125d86ed7fbStbbdev             input1.activate();
126d86ed7fbStbbdev             input0.activate(); // 0 0
127d86ed7fbStbbdev             g.wait_for_all();
128d86ed7fbStbbdev             if (!silent)
129d86ed7fbStbbdev                 output.display();
130d86ed7fbStbbdev             assert(output.get_value() == low);
131d86ed7fbStbbdev             input0.flip(); // 0 1
132d86ed7fbStbbdev             g.wait_for_all();
133d86ed7fbStbbdev             if (!silent)
134d86ed7fbStbbdev                 output.display();
135d86ed7fbStbbdev             assert(output.get_value() == low);
136d86ed7fbStbbdev             input1.flip();
137d86ed7fbStbbdev             input0.flip(); // 1 0
138d86ed7fbStbbdev             g.wait_for_all();
139d86ed7fbStbbdev             if (!silent)
140d86ed7fbStbbdev                 output.display();
141d86ed7fbStbbdev             assert(output.get_value() == low);
142d86ed7fbStbbdev             input0.flip(); // 1 1
143d86ed7fbStbbdev             g.wait_for_all();
144d86ed7fbStbbdev             if (!silent)
145d86ed7fbStbbdev                 output.display();
146d86ed7fbStbbdev             assert(output.get_value() == high);
147d86ed7fbStbbdev         }
148d86ed7fbStbbdev 
149d86ed7fbStbbdev         { // test three-input or_gate: 000, 001, 010, 100, 011, 101, 110, 111
150d86ed7fbStbbdev             or_gate<3> o(g);
151d86ed7fbStbbdev             toggle input0(g);
152d86ed7fbStbbdev             toggle input1(g);
153d86ed7fbStbbdev             toggle input2(g);
154d86ed7fbStbbdev             led output(g, "OUTPUT", false);
155d86ed7fbStbbdev 
156d86ed7fbStbbdev             make_edge(input0.get_out(), input_port<0>(o));
157d86ed7fbStbbdev             make_edge(input1.get_out(), input_port<1>(o));
158d86ed7fbStbbdev             make_edge(input2.get_out(), input_port<2>(o));
159d86ed7fbStbbdev             make_edge(output_port<0>(o), output.get_in());
160d86ed7fbStbbdev 
161d86ed7fbStbbdev             if (!silent)
162d86ed7fbStbbdev                 printf("Testing or_gate...\n");
163d86ed7fbStbbdev             input2.activate();
164d86ed7fbStbbdev             input1.activate();
165d86ed7fbStbbdev             input0.activate(); // 0 0 0
166d86ed7fbStbbdev             g.wait_for_all();
167d86ed7fbStbbdev             if (!silent)
168d86ed7fbStbbdev                 output.display();
169d86ed7fbStbbdev             assert(output.get_value() == low);
170d86ed7fbStbbdev             input0.flip(); // 0 0 1
171d86ed7fbStbbdev             g.wait_for_all();
172d86ed7fbStbbdev             if (!silent)
173d86ed7fbStbbdev                 output.display();
174d86ed7fbStbbdev             assert(output.get_value() == high);
175d86ed7fbStbbdev             input1.flip();
176d86ed7fbStbbdev             input0.flip(); // 0 1 0
177d86ed7fbStbbdev             g.wait_for_all();
178d86ed7fbStbbdev             if (!silent)
179d86ed7fbStbbdev                 output.display();
180d86ed7fbStbbdev             assert(output.get_value() == high);
181d86ed7fbStbbdev             input2.flip();
182d86ed7fbStbbdev             input1.flip(); // 1 0 0
183d86ed7fbStbbdev             g.wait_for_all();
184d86ed7fbStbbdev             if (!silent)
185d86ed7fbStbbdev                 output.display();
186d86ed7fbStbbdev             assert(output.get_value() == high);
187d86ed7fbStbbdev             input2.flip();
188d86ed7fbStbbdev             input1.flip();
189d86ed7fbStbbdev             input0.flip(); // 0 1 1
190d86ed7fbStbbdev             g.wait_for_all();
191d86ed7fbStbbdev             if (!silent)
192d86ed7fbStbbdev                 output.display();
193d86ed7fbStbbdev             assert(output.get_value() == high);
194d86ed7fbStbbdev             input2.flip();
195d86ed7fbStbbdev             input1.flip(); // 1 0 1
196d86ed7fbStbbdev             g.wait_for_all();
197d86ed7fbStbbdev             if (!silent)
198d86ed7fbStbbdev                 output.display();
199d86ed7fbStbbdev             assert(output.get_value() == high);
200d86ed7fbStbbdev             input1.flip();
201d86ed7fbStbbdev             input0.flip(); // 1 1 0
202d86ed7fbStbbdev             g.wait_for_all();
203d86ed7fbStbbdev             if (!silent)
204d86ed7fbStbbdev                 output.display();
205d86ed7fbStbbdev             assert(output.get_value() == high);
206d86ed7fbStbbdev             input0.flip(); // 1 1 1
207d86ed7fbStbbdev             g.wait_for_all();
208d86ed7fbStbbdev             if (!silent)
209d86ed7fbStbbdev                 output.display();
210d86ed7fbStbbdev             assert(output.get_value() == high);
211d86ed7fbStbbdev         }
212d86ed7fbStbbdev 
213d86ed7fbStbbdev         { // test two-input xor_gate: 00, 01, 10, 11
214d86ed7fbStbbdev             xor_gate<2> x(g);
215d86ed7fbStbbdev             toggle input0(g);
216d86ed7fbStbbdev             toggle input1(g);
217d86ed7fbStbbdev             led output(g, "OUTPUT", false);
218d86ed7fbStbbdev 
219d86ed7fbStbbdev             make_edge(input0.get_out(), input_port<0>(x));
220d86ed7fbStbbdev             make_edge(input1.get_out(), input_port<1>(x));
221d86ed7fbStbbdev             make_edge(output_port<0>(x), output.get_in());
222d86ed7fbStbbdev 
223d86ed7fbStbbdev             if (!silent)
224d86ed7fbStbbdev                 printf("Testing xor_gate...\n");
225d86ed7fbStbbdev             input1.activate();
226d86ed7fbStbbdev             input0.activate(); // 0 0
227d86ed7fbStbbdev             g.wait_for_all();
228d86ed7fbStbbdev             if (!silent)
229d86ed7fbStbbdev                 output.display();
230d86ed7fbStbbdev             assert(output.get_value() == low);
231d86ed7fbStbbdev             input0.flip(); // 0 1
232d86ed7fbStbbdev             g.wait_for_all();
233d86ed7fbStbbdev             if (!silent)
234d86ed7fbStbbdev                 output.display();
235d86ed7fbStbbdev             assert(output.get_value() == high);
236d86ed7fbStbbdev             input1.flip();
237d86ed7fbStbbdev             input0.flip(); // 1 0
238d86ed7fbStbbdev             g.wait_for_all();
239d86ed7fbStbbdev             if (!silent)
240d86ed7fbStbbdev                 output.display();
241d86ed7fbStbbdev             assert(output.get_value() == high);
242d86ed7fbStbbdev             input0.flip(); // 1 1
243d86ed7fbStbbdev             g.wait_for_all();
244d86ed7fbStbbdev             if (!silent)
245d86ed7fbStbbdev                 output.display();
246d86ed7fbStbbdev             assert(output.get_value() == low);
247d86ed7fbStbbdev         }
248d86ed7fbStbbdev 
249d86ed7fbStbbdev         { // test two-input nor_gate: 00, 01, 10, 11
250d86ed7fbStbbdev             nor_gate<2> n(g);
251d86ed7fbStbbdev             toggle input0(g);
252d86ed7fbStbbdev             toggle input1(g);
253d86ed7fbStbbdev             led output(g, "OUTPUT", false);
254d86ed7fbStbbdev 
255d86ed7fbStbbdev             make_edge(input0.get_out(), input_port<0>(n));
256d86ed7fbStbbdev             make_edge(input1.get_out(), input_port<1>(n));
257d86ed7fbStbbdev             make_edge(output_port<0>(n), output.get_in());
258d86ed7fbStbbdev 
259d86ed7fbStbbdev             if (!silent)
260d86ed7fbStbbdev                 printf("Testing nor_gate...\n");
261d86ed7fbStbbdev             input1.activate();
262d86ed7fbStbbdev             input0.activate(); // 0 0
263d86ed7fbStbbdev             g.wait_for_all();
264d86ed7fbStbbdev             if (!silent)
265d86ed7fbStbbdev                 output.display();
266d86ed7fbStbbdev             assert(output.get_value() == high);
267d86ed7fbStbbdev             input0.flip(); // 0 1
268d86ed7fbStbbdev             g.wait_for_all();
269d86ed7fbStbbdev             if (!silent)
270d86ed7fbStbbdev                 output.display();
271d86ed7fbStbbdev             assert(output.get_value() == low);
272d86ed7fbStbbdev             input1.flip();
273d86ed7fbStbbdev             input0.flip(); // 1 0
274d86ed7fbStbbdev             g.wait_for_all();
275d86ed7fbStbbdev             if (!silent)
276d86ed7fbStbbdev                 output.display();
277d86ed7fbStbbdev             assert(output.get_value() == low);
278d86ed7fbStbbdev             input0.flip(); // 1 1
279d86ed7fbStbbdev             g.wait_for_all();
280d86ed7fbStbbdev             if (!silent)
281d86ed7fbStbbdev                 output.display();
282d86ed7fbStbbdev             assert(output.get_value() == low);
283d86ed7fbStbbdev         }
284d86ed7fbStbbdev 
285d86ed7fbStbbdev         { // test steady_signal and digit
286d86ed7fbStbbdev             steady_signal input0(g, high);
287d86ed7fbStbbdev             steady_signal input1(g, low);
288d86ed7fbStbbdev             and_gate<2> a(g);
289d86ed7fbStbbdev             or_gate<2> o(g);
290d86ed7fbStbbdev             xor_gate<2> x(g);
291d86ed7fbStbbdev             nor_gate<2> n(g);
292d86ed7fbStbbdev             digit output(g, "OUTPUT", false);
293d86ed7fbStbbdev 
294d86ed7fbStbbdev             make_edge(input0.get_out(), input_port<0>(a));
295d86ed7fbStbbdev             make_edge(input1.get_out(), input_port<1>(a));
296d86ed7fbStbbdev             make_edge(output_port<0>(a), input_port<0>(output));
297d86ed7fbStbbdev 
298d86ed7fbStbbdev             make_edge(input0.get_out(), input_port<0>(o));
299d86ed7fbStbbdev             make_edge(input1.get_out(), input_port<1>(o));
300d86ed7fbStbbdev             make_edge(output_port<0>(o), input_port<1>(output));
301d86ed7fbStbbdev 
302d86ed7fbStbbdev             make_edge(input0.get_out(), input_port<0>(x));
303d86ed7fbStbbdev             make_edge(input1.get_out(), input_port<1>(x));
304d86ed7fbStbbdev             make_edge(output_port<0>(x), input_port<2>(output));
305d86ed7fbStbbdev 
306d86ed7fbStbbdev             make_edge(input0.get_out(), input_port<0>(n));
307d86ed7fbStbbdev             make_edge(input1.get_out(), input_port<1>(n));
308d86ed7fbStbbdev             make_edge(output_port<0>(n), input_port<3>(output));
309d86ed7fbStbbdev 
310d86ed7fbStbbdev             if (!silent)
311d86ed7fbStbbdev                 printf("Testing steady_signal...\n");
312d86ed7fbStbbdev             input0.activate(); // 1
313d86ed7fbStbbdev             input1.activate(); // 0
314d86ed7fbStbbdev             g.wait_for_all();
315d86ed7fbStbbdev             if (!silent)
316d86ed7fbStbbdev                 output.display();
317d86ed7fbStbbdev             assert(output.get_value() == 6);
318d86ed7fbStbbdev         }
319d86ed7fbStbbdev 
320d86ed7fbStbbdev         { // test push_button
321d86ed7fbStbbdev             push_button p(g);
322d86ed7fbStbbdev             buffer b(g);
323d86ed7fbStbbdev             led output(g, "OUTPUT", !silent); // true means print all LED state changes
324d86ed7fbStbbdev 
325d86ed7fbStbbdev             make_edge(p.get_out(), input_port<0>(b));
326d86ed7fbStbbdev             make_edge(output_port<0>(b), output.get_in());
327d86ed7fbStbbdev 
328d86ed7fbStbbdev             if (!silent)
329d86ed7fbStbbdev                 printf("Testing push_button...\n");
330d86ed7fbStbbdev             p.press();
331d86ed7fbStbbdev             p.release();
332d86ed7fbStbbdev             p.press();
333d86ed7fbStbbdev             p.release();
334d86ed7fbStbbdev             g.wait_for_all();
335d86ed7fbStbbdev         }
336d86ed7fbStbbdev 
337d86ed7fbStbbdev         { // test one_bit_adder
338d86ed7fbStbbdev             one_bit_adder my_adder(g);
339d86ed7fbStbbdev             toggle A(g);
340d86ed7fbStbbdev             toggle B(g);
341d86ed7fbStbbdev             toggle CarryIN(g);
342d86ed7fbStbbdev             led Sum(g, "SUM");
343d86ed7fbStbbdev             led CarryOUT(g, "CarryOUT");
344d86ed7fbStbbdev 
345d86ed7fbStbbdev             make_edge(A.get_out(), input_port<P::A0>(my_adder));
346d86ed7fbStbbdev             make_edge(B.get_out(), input_port<P::B0>(my_adder));
347d86ed7fbStbbdev             make_edge(CarryIN.get_out(), input_port<P::CI>(my_adder));
348d86ed7fbStbbdev             make_edge(output_port<P::S0>(my_adder), Sum.get_in());
349d86ed7fbStbbdev             make_edge(output_port<1>(my_adder), CarryOUT.get_in());
350d86ed7fbStbbdev 
351d86ed7fbStbbdev             A.activate();
352d86ed7fbStbbdev             B.activate();
353d86ed7fbStbbdev             CarryIN.activate();
354d86ed7fbStbbdev 
355d86ed7fbStbbdev             if (!silent)
356d86ed7fbStbbdev                 printf("A on\n");
357d86ed7fbStbbdev             A.flip();
358d86ed7fbStbbdev             g.wait_for_all();
359d86ed7fbStbbdev             if (!silent)
360d86ed7fbStbbdev                 Sum.display();
361d86ed7fbStbbdev             if (!silent)
362d86ed7fbStbbdev                 CarryOUT.display();
363d86ed7fbStbbdev             assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
364d86ed7fbStbbdev 
365d86ed7fbStbbdev             if (!silent)
366d86ed7fbStbbdev                 printf("A off\n");
367d86ed7fbStbbdev             A.flip();
368d86ed7fbStbbdev             g.wait_for_all();
369d86ed7fbStbbdev             if (!silent)
370d86ed7fbStbbdev                 Sum.display();
371d86ed7fbStbbdev             if (!silent)
372d86ed7fbStbbdev                 CarryOUT.display();
373d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
374d86ed7fbStbbdev 
375d86ed7fbStbbdev             if (!silent)
376d86ed7fbStbbdev                 printf("B on\n");
377d86ed7fbStbbdev             B.flip();
378d86ed7fbStbbdev             g.wait_for_all();
379d86ed7fbStbbdev             if (!silent)
380d86ed7fbStbbdev                 Sum.display();
381d86ed7fbStbbdev             if (!silent)
382d86ed7fbStbbdev                 CarryOUT.display();
383d86ed7fbStbbdev             assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
384d86ed7fbStbbdev             if (!silent)
385d86ed7fbStbbdev                 printf("B off\n");
386d86ed7fbStbbdev             B.flip();
387d86ed7fbStbbdev             g.wait_for_all();
388d86ed7fbStbbdev             if (!silent)
389d86ed7fbStbbdev                 Sum.display();
390d86ed7fbStbbdev             if (!silent)
391d86ed7fbStbbdev                 CarryOUT.display();
392d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
393d86ed7fbStbbdev 
394d86ed7fbStbbdev             if (!silent)
395d86ed7fbStbbdev                 printf("CarryIN on\n");
396d86ed7fbStbbdev             CarryIN.flip();
397d86ed7fbStbbdev             g.wait_for_all();
398d86ed7fbStbbdev             if (!silent)
399d86ed7fbStbbdev                 Sum.display();
400d86ed7fbStbbdev             if (!silent)
401d86ed7fbStbbdev                 CarryOUT.display();
402d86ed7fbStbbdev             assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
403d86ed7fbStbbdev             if (!silent)
404d86ed7fbStbbdev                 printf("CarryIN off\n");
405d86ed7fbStbbdev             CarryIN.flip();
406d86ed7fbStbbdev             g.wait_for_all();
407d86ed7fbStbbdev             if (!silent)
408d86ed7fbStbbdev                 Sum.display();
409d86ed7fbStbbdev             if (!silent)
410d86ed7fbStbbdev                 CarryOUT.display();
411d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
412d86ed7fbStbbdev 
413d86ed7fbStbbdev             if (!silent)
414d86ed7fbStbbdev                 printf("A&B on\n");
415d86ed7fbStbbdev             A.flip();
416d86ed7fbStbbdev             B.flip();
417d86ed7fbStbbdev             g.wait_for_all();
418d86ed7fbStbbdev             if (!silent)
419d86ed7fbStbbdev                 Sum.display();
420d86ed7fbStbbdev             if (!silent)
421d86ed7fbStbbdev                 CarryOUT.display();
422d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
423d86ed7fbStbbdev             if (!silent)
424d86ed7fbStbbdev                 printf("A&B off\n");
425d86ed7fbStbbdev             A.flip();
426d86ed7fbStbbdev             B.flip();
427d86ed7fbStbbdev             g.wait_for_all();
428d86ed7fbStbbdev             if (!silent)
429d86ed7fbStbbdev                 Sum.display();
430d86ed7fbStbbdev             if (!silent)
431d86ed7fbStbbdev                 CarryOUT.display();
432d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
433d86ed7fbStbbdev 
434d86ed7fbStbbdev             if (!silent)
435d86ed7fbStbbdev                 printf("A&CarryIN on\n");
436d86ed7fbStbbdev             A.flip();
437d86ed7fbStbbdev             CarryIN.flip();
438d86ed7fbStbbdev             g.wait_for_all();
439d86ed7fbStbbdev             if (!silent)
440d86ed7fbStbbdev                 Sum.display();
441d86ed7fbStbbdev             if (!silent)
442d86ed7fbStbbdev                 CarryOUT.display();
443d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
444d86ed7fbStbbdev             if (!silent)
445d86ed7fbStbbdev                 printf("A&CarryIN off\n");
446d86ed7fbStbbdev             A.flip();
447d86ed7fbStbbdev             CarryIN.flip();
448d86ed7fbStbbdev             g.wait_for_all();
449d86ed7fbStbbdev             if (!silent)
450d86ed7fbStbbdev                 Sum.display();
451d86ed7fbStbbdev             if (!silent)
452d86ed7fbStbbdev                 CarryOUT.display();
453d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
454d86ed7fbStbbdev 
455d86ed7fbStbbdev             if (!silent)
456d86ed7fbStbbdev                 printf("B&CarryIN on\n");
457d86ed7fbStbbdev             B.flip();
458d86ed7fbStbbdev             CarryIN.flip();
459d86ed7fbStbbdev             g.wait_for_all();
460d86ed7fbStbbdev             if (!silent)
461d86ed7fbStbbdev                 Sum.display();
462d86ed7fbStbbdev             if (!silent)
463d86ed7fbStbbdev                 CarryOUT.display();
464d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
465d86ed7fbStbbdev             if (!silent)
466d86ed7fbStbbdev                 printf("B&CarryIN off\n");
467d86ed7fbStbbdev             B.flip();
468d86ed7fbStbbdev             CarryIN.flip();
469d86ed7fbStbbdev             g.wait_for_all();
470d86ed7fbStbbdev             if (!silent)
471d86ed7fbStbbdev                 Sum.display();
472d86ed7fbStbbdev             if (!silent)
473d86ed7fbStbbdev                 CarryOUT.display();
474d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
475d86ed7fbStbbdev 
476d86ed7fbStbbdev             if (!silent)
477d86ed7fbStbbdev                 printf("A&B&CarryIN on\n");
478d86ed7fbStbbdev             A.flip();
479d86ed7fbStbbdev             B.flip();
480d86ed7fbStbbdev             CarryIN.flip();
481d86ed7fbStbbdev             g.wait_for_all();
482d86ed7fbStbbdev             if (!silent)
483d86ed7fbStbbdev                 Sum.display();
484d86ed7fbStbbdev             if (!silent)
485d86ed7fbStbbdev                 CarryOUT.display();
486d86ed7fbStbbdev             assert((Sum.get_value() == high) && (CarryOUT.get_value() == high));
487d86ed7fbStbbdev             if (!silent)
488d86ed7fbStbbdev                 printf("A&B&CarryIN off\n");
489d86ed7fbStbbdev             A.flip();
490d86ed7fbStbbdev             B.flip();
491d86ed7fbStbbdev             CarryIN.flip();
492d86ed7fbStbbdev             g.wait_for_all();
493d86ed7fbStbbdev             if (!silent)
494d86ed7fbStbbdev                 Sum.display();
495d86ed7fbStbbdev             if (!silent)
496d86ed7fbStbbdev                 CarryOUT.display();
497d86ed7fbStbbdev             assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
498d86ed7fbStbbdev         }
499d86ed7fbStbbdev 
500d86ed7fbStbbdev #if USE_TWO_BIT_FULL_ADDER
501d86ed7fbStbbdev         { // test two_bit_adder
502d86ed7fbStbbdev             if (!silent)
503d86ed7fbStbbdev                 printf("testing two_bit adder\n");
504d86ed7fbStbbdev             two_bit_adder two_adder(g);
505d86ed7fbStbbdev             std::vector<toggle> A(2, toggle(g));
506d86ed7fbStbbdev             std::vector<toggle> B(2, toggle(g));
507d86ed7fbStbbdev             toggle CarryIN(g);
508d86ed7fbStbbdev             digit Sum(g, "SUM");
509d86ed7fbStbbdev             led CarryOUT(g, "CarryOUT");
510d86ed7fbStbbdev 
511d86ed7fbStbbdev             make_edge(A[0].get_out(), input_port<P::A0>(two_adder));
512d86ed7fbStbbdev             make_edge(B[0].get_out(), input_port<P::B0>(two_adder));
513d86ed7fbStbbdev             make_edge(output_port<P::S0>(two_adder), input_port<0>(Sum));
514d86ed7fbStbbdev 
515d86ed7fbStbbdev             make_edge(A[1].get_out(), input_port<P::A1>(two_adder));
516d86ed7fbStbbdev             make_edge(B[1].get_out(), input_port<P::B1>(two_adder));
517d86ed7fbStbbdev             make_edge(output_port<P::S1>(two_adder), input_port<1>(Sum));
518d86ed7fbStbbdev 
519d86ed7fbStbbdev             make_edge(CarryIN.get_out(), input_port<P::CI>(two_adder));
520d86ed7fbStbbdev             make_edge(output_port<P::CO>(two_adder), CarryOUT.get_in());
521d86ed7fbStbbdev 
522d86ed7fbStbbdev             // Activate all switches at low state
523d86ed7fbStbbdev             for (int i = 0; i < 2; ++i) {
524d86ed7fbStbbdev                 A[i].activate();
525d86ed7fbStbbdev                 B[i].activate();
526d86ed7fbStbbdev             }
527d86ed7fbStbbdev             CarryIN.activate();
528d86ed7fbStbbdev 
529d86ed7fbStbbdev             if (!silent)
530d86ed7fbStbbdev                 printf("1+0\n");
531d86ed7fbStbbdev             A[0].flip();
532d86ed7fbStbbdev             g.wait_for_all();
533d86ed7fbStbbdev             if (!silent)
534d86ed7fbStbbdev                 Sum.display();
535d86ed7fbStbbdev             if (!silent)
536d86ed7fbStbbdev                 CarryOUT.display();
537d86ed7fbStbbdev             assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
538d86ed7fbStbbdev 
539d86ed7fbStbbdev             if (!silent)
540d86ed7fbStbbdev                 printf("0+1\n");
541d86ed7fbStbbdev             A[0].flip();
542d86ed7fbStbbdev             B[0].flip();
543d86ed7fbStbbdev             g.wait_for_all();
544d86ed7fbStbbdev             if (!silent)
545d86ed7fbStbbdev                 Sum.display();
546d86ed7fbStbbdev             if (!silent)
547d86ed7fbStbbdev                 CarryOUT.display();
548d86ed7fbStbbdev             assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
549d86ed7fbStbbdev         }
550d86ed7fbStbbdev #else
551d86ed7fbStbbdev         { // test four_bit_adder
552d86ed7fbStbbdev             four_bit_adder four_adder(g);
553d86ed7fbStbbdev             std::vector<toggle> A(4, toggle(g));
554d86ed7fbStbbdev             std::vector<toggle> B(4, toggle(g));
555d86ed7fbStbbdev             toggle CarryIN(g);
556d86ed7fbStbbdev             digit Sum(g, "SUM");
557d86ed7fbStbbdev             led CarryOUT(g, "CarryOUT");
558d86ed7fbStbbdev 
559d86ed7fbStbbdev             make_edge(A[0].get_out(), input_port<P::A0>(four_adder));
560d86ed7fbStbbdev             make_edge(B[0].get_out(), input_port<P::B0>(four_adder));
561d86ed7fbStbbdev             make_edge(output_port<P::S0>(four_adder), input_port<0>(Sum));
562d86ed7fbStbbdev 
563d86ed7fbStbbdev             make_edge(A[1].get_out(), input_port<P::A1>(four_adder));
564d86ed7fbStbbdev             make_edge(B[1].get_out(), input_port<P::B1>(four_adder));
565d86ed7fbStbbdev             make_edge(output_port<P::S1>(four_adder), input_port<1>(Sum));
566d86ed7fbStbbdev 
567d86ed7fbStbbdev             make_edge(A[2].get_out(), input_port<P::A2>(four_adder));
568d86ed7fbStbbdev             make_edge(B[2].get_out(), input_port<P::B2>(four_adder));
569d86ed7fbStbbdev             make_edge(output_port<P::S2>(four_adder), input_port<2>(Sum));
570d86ed7fbStbbdev 
571d86ed7fbStbbdev             make_edge(A[3].get_out(), input_port<P::A3>(four_adder));
572d86ed7fbStbbdev             make_edge(B[3].get_out(), input_port<P::B3>(four_adder));
573d86ed7fbStbbdev             make_edge(output_port<P::S3>(four_adder), input_port<3>(Sum));
574d86ed7fbStbbdev 
575d86ed7fbStbbdev             make_edge(CarryIN.get_out(), input_port<P::CI>(four_adder));
576d86ed7fbStbbdev             make_edge(output_port<P::CO>(four_adder), CarryOUT.get_in());
577d86ed7fbStbbdev 
578d86ed7fbStbbdev             // Activate all switches at low state
579d86ed7fbStbbdev             for (int i = 0; i < 4; ++i) {
580d86ed7fbStbbdev                 A[i].activate();
581d86ed7fbStbbdev                 B[i].activate();
582d86ed7fbStbbdev             }
583d86ed7fbStbbdev             CarryIN.activate();
584d86ed7fbStbbdev 
585d86ed7fbStbbdev             if (!silent)
586d86ed7fbStbbdev                 printf("1+0\n");
587d86ed7fbStbbdev             A[0].flip();
588d86ed7fbStbbdev             g.wait_for_all();
589d86ed7fbStbbdev             if (!silent)
590d86ed7fbStbbdev                 Sum.display();
591d86ed7fbStbbdev             if (!silent)
592d86ed7fbStbbdev                 CarryOUT.display();
593d86ed7fbStbbdev             assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
594d86ed7fbStbbdev 
595d86ed7fbStbbdev             if (!silent)
596d86ed7fbStbbdev                 printf("0+1\n");
597d86ed7fbStbbdev             A[0].flip();
598d86ed7fbStbbdev             B[0].flip();
599d86ed7fbStbbdev             g.wait_for_all();
600d86ed7fbStbbdev             if (!silent)
601d86ed7fbStbbdev                 Sum.display();
602d86ed7fbStbbdev             if (!silent)
603d86ed7fbStbbdev                 CarryOUT.display();
604d86ed7fbStbbdev             assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
605d86ed7fbStbbdev 
606d86ed7fbStbbdev             if (!silent)
607d86ed7fbStbbdev                 printf("3+4\n");
608d86ed7fbStbbdev             A[0].flip();
609d86ed7fbStbbdev             A[1].flip();
610d86ed7fbStbbdev             B[0].flip();
611d86ed7fbStbbdev             B[2].flip();
612d86ed7fbStbbdev             g.wait_for_all();
613d86ed7fbStbbdev             if (!silent)
614d86ed7fbStbbdev                 Sum.display();
615d86ed7fbStbbdev             if (!silent)
616d86ed7fbStbbdev                 CarryOUT.display();
617d86ed7fbStbbdev             assert((Sum.get_value() == 7) && (CarryOUT.get_value() == low));
618d86ed7fbStbbdev 
619d86ed7fbStbbdev             if (!silent)
620d86ed7fbStbbdev                 printf("6+1\n");
621d86ed7fbStbbdev             A[0].flip();
622d86ed7fbStbbdev             A[2].flip();
623d86ed7fbStbbdev             B[0].flip();
624d86ed7fbStbbdev             B[2].flip();
625d86ed7fbStbbdev             g.wait_for_all();
626d86ed7fbStbbdev             if (!silent)
627d86ed7fbStbbdev                 Sum.display();
628d86ed7fbStbbdev             if (!silent)
629d86ed7fbStbbdev                 CarryOUT.display();
630d86ed7fbStbbdev             assert((Sum.get_value() == 7) && (CarryOUT.get_value() == low));
631d86ed7fbStbbdev 
632d86ed7fbStbbdev             if (!silent)
633d86ed7fbStbbdev                 printf("0+0+carry\n");
634d86ed7fbStbbdev             A[1].flip();
635d86ed7fbStbbdev             A[2].flip();
636d86ed7fbStbbdev             B[0].flip();
637d86ed7fbStbbdev             CarryIN.flip();
638d86ed7fbStbbdev             g.wait_for_all();
639d86ed7fbStbbdev             if (!silent)
640d86ed7fbStbbdev                 Sum.display();
641d86ed7fbStbbdev             if (!silent)
642d86ed7fbStbbdev                 CarryOUT.display();
643d86ed7fbStbbdev             assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
644d86ed7fbStbbdev 
645d86ed7fbStbbdev             if (!silent)
646d86ed7fbStbbdev                 printf("15+15+carry\n");
647d86ed7fbStbbdev             A[0].flip();
648d86ed7fbStbbdev             A[1].flip();
649d86ed7fbStbbdev             A[2].flip();
650d86ed7fbStbbdev             A[3].flip();
651d86ed7fbStbbdev             B[0].flip();
652d86ed7fbStbbdev             B[1].flip();
653d86ed7fbStbbdev             B[2].flip();
654d86ed7fbStbbdev             B[3].flip();
655d86ed7fbStbbdev             g.wait_for_all();
656d86ed7fbStbbdev             if (!silent)
657d86ed7fbStbbdev                 Sum.display();
658d86ed7fbStbbdev             if (!silent)
659d86ed7fbStbbdev                 CarryOUT.display();
660d86ed7fbStbbdev             assert((Sum.get_value() == 0xf) && (CarryOUT.get_value() == high));
661d86ed7fbStbbdev 
662d86ed7fbStbbdev             if (!silent)
663d86ed7fbStbbdev                 printf("8+8\n");
664d86ed7fbStbbdev             A[0].flip();
665d86ed7fbStbbdev             A[1].flip();
666d86ed7fbStbbdev             A[2].flip();
667d86ed7fbStbbdev             B[0].flip();
668d86ed7fbStbbdev             B[1].flip();
669d86ed7fbStbbdev             B[2].flip();
670d86ed7fbStbbdev             CarryIN.flip();
671d86ed7fbStbbdev             g.wait_for_all();
672d86ed7fbStbbdev             if (!silent)
673d86ed7fbStbbdev                 Sum.display();
674d86ed7fbStbbdev             if (!silent)
675d86ed7fbStbbdev                 CarryOUT.display();
676d86ed7fbStbbdev             assert((Sum.get_value() == 0) && (CarryOUT.get_value() == high));
677d86ed7fbStbbdev 
678d86ed7fbStbbdev             if (!silent)
679d86ed7fbStbbdev                 printf("0+0\n");
680d86ed7fbStbbdev             A[3].flip();
681d86ed7fbStbbdev             B[3].flip();
682d86ed7fbStbbdev             g.wait_for_all();
683d86ed7fbStbbdev             if (!silent)
684d86ed7fbStbbdev                 Sum.display();
685d86ed7fbStbbdev             if (!silent)
686d86ed7fbStbbdev                 CarryOUT.display();
687d86ed7fbStbbdev             assert((Sum.get_value() == 0) && (CarryOUT.get_value() == low));
688d86ed7fbStbbdev         }
689d86ed7fbStbbdev #endif
690d86ed7fbStbbdev 
691d86ed7fbStbbdev         { // test D_latch
692d86ed7fbStbbdev             D_latch my_d_latch(g);
693d86ed7fbStbbdev             toggle D(g);
694d86ed7fbStbbdev             pulse E(g, 500, 4); // clock changes every 500ms; stops after 4 changes
695d86ed7fbStbbdev             led Q(g, " Q", verbose); // if true, LEDs print at every state change
696d86ed7fbStbbdev             led notQ(g, "~Q", verbose);
697d86ed7fbStbbdev 
698d86ed7fbStbbdev             make_edge(D.get_out(), input_port<0>(my_d_latch));
699d86ed7fbStbbdev             make_edge(E.get_out(), input_port<1>(my_d_latch));
700d86ed7fbStbbdev             make_edge(output_port<0>(my_d_latch), Q.get_in());
701d86ed7fbStbbdev             make_edge(output_port<1>(my_d_latch), notQ.get_in());
702d86ed7fbStbbdev 
703d86ed7fbStbbdev             D.activate();
704d86ed7fbStbbdev 
705d86ed7fbStbbdev             if (!silent)
706d86ed7fbStbbdev                 printf("Toggling D\n");
707d86ed7fbStbbdev             E.activate();
708d86ed7fbStbbdev             D.flip();
709d86ed7fbStbbdev             g.wait_for_all();
710d86ed7fbStbbdev             if (!silent && !verbose) {
711d86ed7fbStbbdev                 Q.display();
712d86ed7fbStbbdev                 notQ.display();
713d86ed7fbStbbdev             }
714d86ed7fbStbbdev             assert((Q.get_value() == high) && (notQ.get_value() == low));
715d86ed7fbStbbdev             E.reset();
716d86ed7fbStbbdev 
717d86ed7fbStbbdev             if (!silent)
718d86ed7fbStbbdev                 printf("Toggling D\n");
719d86ed7fbStbbdev             E.activate();
720d86ed7fbStbbdev             D.flip();
721d86ed7fbStbbdev             g.wait_for_all();
722d86ed7fbStbbdev             if (!silent && !verbose) {
723d86ed7fbStbbdev                 Q.display();
724d86ed7fbStbbdev                 notQ.display();
725d86ed7fbStbbdev             }
726d86ed7fbStbbdev             assert((Q.get_value() == low) && (notQ.get_value() == high));
727d86ed7fbStbbdev             E.reset();
728d86ed7fbStbbdev 
729d86ed7fbStbbdev             if (!silent)
730d86ed7fbStbbdev                 printf("Toggling D\n");
731d86ed7fbStbbdev             E.activate();
732d86ed7fbStbbdev             D.flip();
733d86ed7fbStbbdev             g.wait_for_all();
734d86ed7fbStbbdev             if (!silent && !verbose) {
735d86ed7fbStbbdev                 Q.display();
736d86ed7fbStbbdev                 notQ.display();
737d86ed7fbStbbdev             }
738d86ed7fbStbbdev             assert((Q.get_value() == high) && (notQ.get_value() == low));
739d86ed7fbStbbdev             E.reset();
740d86ed7fbStbbdev 
741d86ed7fbStbbdev             if (!silent)
742d86ed7fbStbbdev                 printf("Toggling D\n");
743d86ed7fbStbbdev             E.activate();
744d86ed7fbStbbdev             D.flip();
745d86ed7fbStbbdev             g.wait_for_all();
746d86ed7fbStbbdev             if (!silent && !verbose) {
747d86ed7fbStbbdev                 Q.display();
748d86ed7fbStbbdev                 notQ.display();
749d86ed7fbStbbdev             }
750d86ed7fbStbbdev             assert((Q.get_value() == low) && (notQ.get_value() == high));
751d86ed7fbStbbdev             E.reset();
752d86ed7fbStbbdev 
753d86ed7fbStbbdev             if (!silent)
754d86ed7fbStbbdev                 printf("Toggling D\n");
755d86ed7fbStbbdev             E.activate();
756d86ed7fbStbbdev             D.flip();
757d86ed7fbStbbdev             g.wait_for_all();
758d86ed7fbStbbdev             if (!silent && !verbose) {
759d86ed7fbStbbdev                 Q.display();
760d86ed7fbStbbdev                 notQ.display();
761d86ed7fbStbbdev             }
762d86ed7fbStbbdev             assert((Q.get_value() == high) && (notQ.get_value() == low));
763d86ed7fbStbbdev         }
764d86ed7fbStbbdev     }
765d86ed7fbStbbdev     utility::report_elapsed_time((oneapi::tbb::tick_count::now() - start).seconds());
766d86ed7fbStbbdev     return 0;
767d86ed7fbStbbdev }
768