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