Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

View File

@@ -0,0 +1,56 @@
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBBexample_graph_logicsim_dlatch_H
#define __TBBexample_graph_logicsim_dlatch_H 1
#include "basics.h"
class D_latch : public composite_node< tuple< signal_t, signal_t >, tuple< signal_t, signal_t > > {
broadcast_node<signal_t> D_port;
broadcast_node<signal_t> E_port;
not_gate a_not;
and_gate<2> first_and;
and_gate<2> second_and;
nor_gate<2> first_nor;
nor_gate<2> second_nor;
graph& my_graph;
typedef composite_node< tuple< signal_t, signal_t >, tuple< signal_t, signal_t > > base_type;
public:
D_latch(graph& g) : base_type(g), my_graph(g), D_port(g), E_port(g), a_not(g), first_and(g), second_and(g),
first_nor(g), second_nor(g)
{
make_edge(D_port, input_port<0>(a_not));
make_edge(D_port, input_port<1>(second_and));
make_edge(E_port, input_port<1>(first_and));
make_edge(E_port, input_port<0>(second_and));
make_edge(a_not, input_port<0>(first_and));
make_edge(first_and, input_port<0>(first_nor));
make_edge(second_and, input_port<1>(second_nor));
make_edge(first_nor, input_port<0>(second_nor));
make_edge(second_nor, input_port<1>(first_nor));
base_type::input_ports_type input_tuple(D_port, E_port);
base_type::output_ports_type output_tuple(output_port<0>(first_nor), output_port<0>(second_nor));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(D_port, E_port, a_not, first_and, second_and, first_nor, second_nor);
}
~D_latch() {}
};
#endif /* __TBBexample_graph_logicsim_dlatch_H */

View File

@@ -0,0 +1,52 @@
# Copyright (c) 2005-2020 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Common Makefile that builds and runs example.
PROG=test_all
ARGS=4
PERF_RUN_ARGS=auto silent
# Try to find icl.exe
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# The C++ compiler options
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _CRT_SECURE_NO_DEPRECATE $(CXXFLAGS)
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
all: release test
release: *.cpp
$(CXX) $(PROG).cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug: *.cpp
$(CXX) $(PROG).cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
profile: *.cpp
$(CXX) $(PROG).cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /D TBB_USE_THREADING_TOOLS /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
compiler_check:
@$(CXX) >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
perf_build: release
perf_run:
$(PROG) $(PERF_RUN_ARGS)

View File

@@ -0,0 +1,554 @@
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBBexample_graph_logicsim_basics_H
#define __TBBexample_graph_logicsim_basics_H 1
#include <cstdio>
#include <string>
#include "tbb/tick_count.h"
#include "tbb/flow_graph.h"
#include "../../common/utility/utility.h"
#ifndef _WIN32
#include <sys/time.h>
#include <unistd.h>
void rt_sleep(int msec) {
usleep(msec*1000);
}
#else //_WIN32
#undef OLDUNIXTIME
#undef STDTIME
#include <windows.h>
void rt_sleep(int msec) {
Sleep(msec);
}
#endif /* _WIN32 */
using namespace std;
using namespace tbb;
using namespace tbb::flow;
typedef enum { low=0, high, undefined } signal_t;
template<int N> class gate;
template<>
class gate<1> : public composite_node< tuple< signal_t >, tuple< signal_t > > {
protected:
typedef indexer_node<signal_t> input_port_t;
typedef multifunction_node< input_port_t::output_type, tuple<signal_t> > gate_fn_t;
typedef gate_fn_t::output_ports_type ports_type;
typedef composite_node< tuple< signal_t >, tuple< signal_t > > base_type;
public:
template <typename Body>
gate(graph& g, Body b) : base_type(g), my_graph(g), in_ports(g), gate_fn(g, 1, b) {
make_edge(in_ports, gate_fn);
base_type::input_ports_type input_tuple(input_port<0>(in_ports));
base_type::output_ports_type output_tuple(output_port<0>(gate_fn));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(in_ports, gate_fn);
}
virtual ~gate() {}
gate& operator=(const gate& src) { return *this; }
protected:
graph& my_graph;
private:
input_port_t in_ports;
gate_fn_t gate_fn;
};
template<>
class gate<2> : public composite_node< tuple< signal_t, signal_t >, tuple< signal_t > > {
protected:
typedef indexer_node<signal_t,signal_t> input_port_t;
typedef multifunction_node< input_port_t::output_type, tuple<signal_t> > gate_fn_t;
typedef gate_fn_t::output_ports_type ports_type;
typedef composite_node< tuple< signal_t, signal_t >, tuple< signal_t > > base_type;
public:
template <typename Body>
gate(graph& g, Body b) : base_type(g), my_graph(g), in_ports(g), gate_fn(g, 1, b) {
make_edge(in_ports, gate_fn);
base_type::input_ports_type input_tuple(input_port<0>(in_ports),input_port<1>(in_ports));
base_type::output_ports_type output_tuple(output_port<0>(gate_fn));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(in_ports, gate_fn);
}
virtual ~gate() {}
gate& operator=(const gate& src) { return *this; }
protected:
graph& my_graph;
private:
input_port_t in_ports;
gate_fn_t gate_fn;
};
template<>
class gate<3> : public composite_node< tuple< signal_t, signal_t, signal_t >, tuple< signal_t > > {
protected:
typedef indexer_node<signal_t, signal_t, signal_t> input_port_t;
typedef multifunction_node< input_port_t::output_type, tuple<signal_t> > gate_fn_t;
typedef gate_fn_t::output_ports_type ports_type;
typedef composite_node< tuple< signal_t, signal_t, signal_t >, tuple< signal_t > > base_type;
public:
template <typename Body>
gate(graph& g, Body b) : base_type(g), my_graph(g), in_ports(g), gate_fn(g, 1, b) {
make_edge(in_ports, gate_fn);
base_type::input_ports_type input_tuple(input_port<0>(in_ports),input_port<1>(in_ports),input_port<2>(in_ports));
base_type::output_ports_type output_tuple(output_port<0>(gate_fn));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(in_ports, gate_fn);
}
virtual ~gate() {}
gate& operator=(const gate& src) { return *this; }
protected:
graph& my_graph;
private:
input_port_t in_ports;
gate_fn_t gate_fn;
};
template<>
class gate<4> : public composite_node< tuple< signal_t, signal_t, signal_t, signal_t >, tuple< signal_t > > {
protected:
typedef indexer_node<signal_t, signal_t, signal_t, signal_t> input_port_t;
typedef multifunction_node< input_port_t::output_type, tuple<signal_t> > gate_fn_t;
typedef gate_fn_t::output_ports_type ports_type;
typedef composite_node< tuple< signal_t, signal_t, signal_t, signal_t >, tuple< signal_t > > base_type;
public:
template <typename Body>
gate(graph& g, Body b) : base_type(g), my_graph(g), in_ports(g), gate_fn(g, 1, b) {
make_edge(in_ports, gate_fn);
base_type::input_ports_type input_tuple(input_port<0>(in_ports),input_port<1>(in_ports),input_port<2>(in_ports), input_port<3>(in_ports));
base_type::output_ports_type output_tuple(output_port<0>(gate_fn));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(in_ports, gate_fn);
}
virtual ~gate() {}
gate& operator=(const gate& src) { return *this; }
protected:
graph& my_graph;
private:
input_port_t in_ports;
gate_fn_t gate_fn;
};
// Input devices
class steady_signal {
graph& my_graph;
signal_t init_signal;
write_once_node<signal_t> signal_node;
public:
steady_signal(graph& g, signal_t v) :
my_graph(g), init_signal(v), signal_node(g) {}
steady_signal(const steady_signal& src) :
my_graph(src.my_graph), init_signal(src.init_signal),
signal_node(src.my_graph) {}
~steady_signal() {}
// Assignment is ignored
steady_signal& operator=(const steady_signal& src) { return *this; }
write_once_node<signal_t>& get_out() { return signal_node; }
void activate() { signal_node.try_put(init_signal); }
};
class pulse {
class clock_body {
size_t& ms;
int& reps;
signal_t val;
public:
clock_body(size_t& _ms, int& _reps) : ms(_ms), reps(_reps), val(low) {}
bool operator()(signal_t& out) {
rt_sleep((int)ms);
if (reps>0) --reps;
if (val==low) val = high;
else val = low;
out = val;
return reps>0 || reps == -1;
}
};
graph& my_graph;
size_t ms, init_ms;
int reps, init_reps;
input_node<signal_t> clock_node;
public:
pulse(graph& g, size_t _ms=1000, int _reps=-1) :
my_graph(g), ms(_ms), init_ms(_ms), reps(_reps), init_reps(_reps),
clock_node(g, clock_body(ms, reps))
{}
pulse(const pulse& src) :
my_graph(src.my_graph), ms(src.init_ms), init_ms(src.init_ms),
reps(src.init_reps), init_reps(src.init_reps),
clock_node(src.my_graph, clock_body(ms, reps))
{}
~pulse() {}
// Assignment changes the behavior of LHS to that of the RHS, but doesn't change owning graph
pulse& operator=(const pulse& src) {
ms = src.ms; init_ms = src.init_ms; reps = src.reps; init_reps = src.init_reps;
return *this;
}
input_node<signal_t>& get_out() { return clock_node; }
void activate() { clock_node.activate(); }
void reset() { reps = init_reps; }
};
class push_button {
graph& my_graph;
overwrite_node<signal_t> push_button_node;
public:
push_button(graph& g) : my_graph(g), push_button_node(g) {
push_button_node.try_put(low);
}
push_button(const push_button& src) :
my_graph(src.my_graph), push_button_node(src.my_graph) {
push_button_node.try_put(low);
}
~push_button() {}
// Assignment is ignored
push_button& operator=(const push_button& src) { return *this; }
overwrite_node<signal_t>& get_out() { return push_button_node; }
void press() { push_button_node.try_put(high); }
void release() { push_button_node.try_put(low); }
};
class toggle {
graph& my_graph;
signal_t state;
overwrite_node<signal_t> toggle_node;
public:
toggle(graph& g) : my_graph(g), state(undefined), toggle_node(g) {}
toggle(const toggle& src) : my_graph(src.my_graph), state(undefined),
toggle_node(src.my_graph) {}
~toggle() {}
// Assignment ignored
toggle& operator=(const toggle& src) { return *this; }
overwrite_node<signal_t>& get_out() { return toggle_node; }
void flip() {
if (state==high) state = low;
else state = high;
toggle_node.try_put(state);
}
void activate() {
state = low;
toggle_node.try_put(state);
}
};
// Basic gates
class buffer : public gate<1> {
using gate<1>::my_graph;
typedef gate<1>::ports_type ports_type;
class buffer_body {
signal_t state;
bool touched;
public:
buffer_body() : state(undefined), touched(false) {}
void operator()(const input_port_t::output_type &v, ports_type& p) {
if (!touched || state != cast_to<signal_t>(v)) {
state = cast_to<signal_t>(v);
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
buffer(graph& g) : gate<1>(g, buffer_body()) {}
buffer(const buffer& src) : gate<1>(src.my_graph, buffer_body()) {}
~buffer() {}
};
class not_gate : public gate<1> {
using gate<1>::my_graph;
typedef gate<1>::ports_type ports_type;
class not_body {
signal_t port;
bool touched;
public:
not_body() : port(undefined), touched(false) {}
void operator()(const input_port_t::output_type &v, ports_type& p) {
if (!touched || port != cast_to<signal_t>(v)) {
port = cast_to<signal_t>(v);
signal_t state = low;
if (port==low) state = high;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
not_gate(graph& g) : gate<1>(g, not_body()) {}
not_gate(const not_gate& src) : gate<1>(src.my_graph, not_body()) {}
~not_gate() {}
};
template <int N>
class and_gate : public gate<N> {
using gate<N>::my_graph;
typedef typename gate<N>::ports_type ports_type;
typedef typename gate<N>::input_port_t::output_type from_input;
class and_body {
signal_t *ports;
signal_t state;
bool touched;
public:
and_body() : state(undefined), touched(false) {
ports = new signal_t[N];
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const from_input& v, ports_type& p) {
ports[v.tag()] = cast_to<signal_t>(v);
signal_t new_state=high;
size_t i=0;
while (i<N) {
if (ports[i] == low) { new_state = low; break; }
else if (ports[i] == undefined && new_state != low) { new_state = undefined; }
++i;
}
if (!touched || state != new_state) {
state = new_state;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
and_gate(graph& g) : gate<N>(g, and_body()) {}
and_gate(const and_gate<N>& src) : gate<N>(src.my_graph, and_body()) {}
~and_gate() {}
};
template<int N>
class or_gate : public gate<N> {
using gate<N>::my_graph;
typedef typename gate<N>::ports_type ports_type;
typedef typename gate<N>::input_port_t::output_type from_input;
class or_body {
signal_t *ports;
signal_t state;
bool touched;
public:
or_body() : state(undefined), touched(false) {
ports = new signal_t[N];
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const from_input& v, ports_type& p) {
ports[v.tag()] = cast_to<signal_t>(v);
signal_t new_state=low;
size_t i=0;
while (i<N) {
if (ports[i] == high) { new_state = high; break; }
else if (ports[i] == undefined && new_state != high) { new_state = undefined; }
++i;
}
if (!touched || state != new_state) {
state = new_state;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
or_gate(graph& g) : gate<N>(g, or_body()) {}
or_gate(const or_gate& src) : gate<N>(src.my_graph, or_body()) {}
~or_gate() {}
};
template <int N>
class xor_gate : public gate<N> {
using gate<N>::my_graph;
typedef typename gate<N>::ports_type ports_type;
typedef typename gate<N>::input_port_t input_port_t;
class xor_body {
signal_t *ports;
signal_t state;
bool touched;
public:
xor_body() : state(undefined), touched(false) {
ports = new signal_t[N];
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const typename input_port_t::output_type &v, ports_type& p) {
ports[v.tag()] = cast_to<signal_t>(v);
signal_t new_state=low;
size_t i=0, highs=0;
while (i<N) {
if (ports[i] == undefined) { new_state = undefined; }
else if (ports[i] == high && new_state == low) { new_state = high; ++highs; }
else if (ports[i] == high && highs > 0) { new_state = low; break; }
else if (ports[i] == high ) { ++highs; }
++i;
}
if (!touched || state != new_state) {
state = new_state;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
xor_gate(graph& g) : gate<N>(g, xor_body()) {}
xor_gate(const xor_gate& src) : gate<N>(src.my_graph, xor_body()) {}
~xor_gate() {}
};
template <int N>
class nor_gate : public gate<N> {
using gate<N>::my_graph;
typedef typename gate<N>::ports_type ports_type;
typedef typename gate<N>::input_port_t input_port_t;
class nor_body {
signal_t *ports;
signal_t state;
bool touched;
public:
nor_body() : state(undefined), touched(false) {
ports = new signal_t[N];
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const typename input_port_t::output_type &v, ports_type& p) {
ports[v.tag()] = cast_to<signal_t>(v);
signal_t new_state=low;
size_t i=0;
while (i<N) {
if (ports[i] == high) { new_state = high; break; }
else if (ports[i] == undefined && new_state != high) { new_state = undefined; }
++i;
}
if (new_state == high) new_state = low;
else if (new_state == low) new_state = high;
if (!touched || state != new_state) {
state = new_state;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
nor_gate(graph& g) : gate<N>(g, nor_body()) {}
nor_gate(const nor_gate& src) : gate<N>(src.my_graph, nor_body()) {}
~nor_gate() {}
};
// Output devices
class led {
class led_body {
signal_t &state;
string &label;
bool report_changes;
bool touched;
public:
led_body(signal_t &s, string &l, bool r) :
state(s), label(l), report_changes(r), touched(false)
{}
continue_msg operator()(signal_t b) {
if (!touched || b!=state) {
state = b;
if (state != undefined && report_changes) {
if (state) printf("%s: (*)\n", label.c_str());
else printf("%s: ( )\n", label.c_str());
}
touched = false;
}
return continue_msg();
}
};
graph& my_graph;
string label;
signal_t state;
bool report_changes;
function_node<signal_t, continue_msg> led_node;
public:
led(graph& g, string l, bool rc=false) : my_graph(g), label(l), state(undefined),
report_changes(rc),
led_node(g, 1, led_body(state, label, report_changes))
{}
led(const led& src) : my_graph(src.my_graph), label(src.label), state(undefined),
report_changes(src.report_changes),
led_node(src.my_graph, 1, led_body(state, label, report_changes))
{}
~led() {}
// Assignment changes the behavior of LHS to that of the RHS, but doesn't change owning graph
// state is set to undefined so that next signal changes it
led& operator=(const led& src) {
label = src.label; state = undefined; report_changes = src.report_changes;
return *this;
}
function_node<signal_t, continue_msg>& get_in() { return led_node; }
void display() {
if (state == high) printf("%s: (*)\n", label.c_str());
else if (state == low) printf("%s: ( )\n", label.c_str());
else printf("%s: (u)\n", label.c_str());
}
signal_t get_value() { return state; }
};
class digit : public gate<4> {
using gate<4>::my_graph;
typedef gate<4>::ports_type ports_type;
typedef gate<4>::input_port_t input_port_t;
class digit_body {
signal_t ports[4];
static const int N = 4;
unsigned int &state;
string &label;
bool& report_changes;
public:
digit_body(unsigned int &s, string &l, bool& r) : state(s), label(l), report_changes(r) {
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const input_port_t::output_type& v, ports_type& p) {
unsigned int new_state = 0;
ports[v.tag()] = cast_to<signal_t>(v);
if (ports[0] == high) ++new_state;
if (ports[1] == high) new_state += 2;
if (ports[2] == high) new_state += 4;
if (ports[3] == high) new_state += 8;
if (state != new_state) {
state = new_state;
if (report_changes) {
printf("%s: %x\n", label.c_str(), state);
}
}
}
};
string label;
unsigned int state;
bool report_changes;
public:
digit(graph& g, string l, bool rc=false) :
gate<4>(g, digit_body(state, label, report_changes)),
label(l), state(0), report_changes(rc) {}
digit(const digit& src) :
gate<4>(src.my_graph, digit_body(state, label, report_changes)),
label(src.label), state(0), report_changes(src.report_changes) {}
~digit() {}
// Assignment changes the behavior of LHS to that of the RHS, but doesn't change owning graph.
// state is reset as in constructors
digit& operator=(const digit& src) {
label = src.label; state = 0; report_changes = src.report_changes;
return *this;
}
void display() { printf("%s: %x\n", label.c_str(), state); }
unsigned int get_value() { return state; }
};
#endif /* __TBBexample_graph_logicsim_basics_H */

View File

@@ -0,0 +1,58 @@
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBBexample_graph_logicsim_fba_H
#define __TBBexample_graph_logicsim_fba_H 1
#include "one_bit_adder.h"
typedef composite_node< tuple< signal_t, signal_t, signal_t, signal_t, signal_t, signal_t, signal_t, signal_t, signal_t >,
tuple< signal_t, signal_t, signal_t, signal_t, signal_t > > fba_base_type;
class four_bit_adder : public fba_base_type {
graph& my_graph;
std::vector<one_bit_adder> four_adders;
public:
four_bit_adder(graph& g) : fba_base_type(g), my_graph(g), four_adders(4, one_bit_adder(g)) {
make_connections();
set_up_composite();
}
four_bit_adder(const four_bit_adder& src) :
fba_base_type(src.my_graph), my_graph(src.my_graph), four_adders(4, one_bit_adder(src.my_graph))
{
make_connections();
set_up_composite();
}
~four_bit_adder() {}
private:
void make_connections() {
make_edge(output_port<1>(four_adders[0]), input_port<0>(four_adders[1]));
make_edge(output_port<1>(four_adders[1]), input_port<0>(four_adders[2]));
make_edge(output_port<1>(four_adders[2]), input_port<0>(four_adders[3]));
}
void set_up_composite() {
fba_base_type::input_ports_type input_tuple(input_port<0>(four_adders[0]/*CI*/), input_port<1>(four_adders[0]), input_port<2>(four_adders[0]), input_port<1>(four_adders[1]), input_port<2>(four_adders[1]), input_port<1>(four_adders[2]), input_port<2>(four_adders[2]), input_port<1>(four_adders[3]), input_port<2>(four_adders[3]));
fba_base_type::output_ports_type output_tuple(output_port<0>(four_adders[0]), output_port<0>(four_adders[1]), output_port<0>(four_adders[2]), output_port<0>(four_adders[3]),output_port<1>(four_adders[3]/*CO*/));
fba_base_type::set_external_ports(input_tuple, output_tuple);
}
};
#endif /* __TBBexample_graph_logicsim_fba_H */

View File

@@ -0,0 +1,99 @@
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBBexample_graph_logicsim_oba_H
#define __TBBexample_graph_logicsim_oba_H 1
namespace P {
//input ports
const int CI = 0;
const int A0 = 1;
const int B0 = 2;
const int A1 = 3;
const int B1 = 4;
const int A2 = 5;
const int B2 = 6;
const int A3 = 7;
const int B3 = 8;
//output_ports
const int S0 = 0;
const int S1 = 1;
const int S2 = 2;
const int S3 = 3;
#if USE_TWO_BIT_FULL_ADDER
const int CO = 2;
#else
const int CO = 4;
#endif
}
#include "basics.h"
class one_bit_adder : public composite_node< tuple< signal_t, signal_t, signal_t >, tuple< signal_t, signal_t > > {
broadcast_node<signal_t> A_port;
broadcast_node<signal_t> B_port;
broadcast_node<signal_t> CI_port;
xor_gate<2> FirstXOR;
xor_gate<2> SecondXOR;
and_gate<2> FirstAND;
and_gate<2> SecondAND;
or_gate<2> FirstOR;
graph& my_graph;
typedef composite_node< tuple< signal_t, signal_t, signal_t >, tuple< signal_t, signal_t > > base_type;
public:
one_bit_adder(graph& g) : base_type(g), my_graph(g), A_port(g), B_port(g), CI_port(g), FirstXOR(g),
SecondXOR(g), FirstAND(g), SecondAND(g), FirstOR(g) {
make_connections();
set_up_composite();
}
one_bit_adder(const one_bit_adder& src) :
base_type(src.my_graph), my_graph(src.my_graph), A_port(src.my_graph), B_port(src.my_graph),
CI_port(src.my_graph), FirstXOR(src.my_graph), SecondXOR(src.my_graph),
FirstAND(src.my_graph), SecondAND(src.my_graph), FirstOR(src.my_graph)
{
make_connections();
set_up_composite();
}
~one_bit_adder() {}
private:
void make_connections() {
make_edge(A_port, input_port<0>(FirstXOR));
make_edge(A_port, input_port<0>(FirstAND));
make_edge(B_port, input_port<1>(FirstXOR));
make_edge(B_port, input_port<1>(FirstAND));
make_edge(CI_port, input_port<1>(SecondXOR));
make_edge(CI_port, input_port<1>(SecondAND));
make_edge(FirstXOR, input_port<0>(SecondXOR));
make_edge(FirstXOR, input_port<0>(SecondAND));
make_edge(SecondAND, input_port<0>(FirstOR));
make_edge(FirstAND, input_port<1>(FirstOR));
}
void set_up_composite() {
base_type::input_ports_type input_tuple(CI_port, A_port, B_port);
base_type::output_ports_type output_tuple(output_port<0>(SecondXOR), output_port<0>(FirstOR));
base_type::set_external_ports( input_tuple, output_tuple);
base_type::add_visible_nodes(A_port, B_port, CI_port, FirstXOR, SecondXOR, FirstAND, SecondAND, FirstOR );
}
};
#endif /* __TBBexample_graph_logicsim_oba_H */

View File

@@ -0,0 +1,406 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. logic_sim sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Logic_sim sample</h1>
</div>
<p>
This directory contains a simple tbb::flow example that performs
simplistic digital logic simulations with basic logic gates that can
be easily composed to create more interesting circuits. It
exemplifies the multifunction_node and the indexer_node CPF, among others. </p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="basics.h">basics.h</a>
<dd>Several I/O devices and basic gates.
<dt><a href="one_bit_adder.h">one_bit_adder.h</a>
<dd>A one-bit full adder composed of basic gates.
<dt><a href="four_bit_adder.h">four_bit_adder.h</a>
<dd>A four-bit full adder composed of one-bit adders.
<dt><a href="D_latch.h">D_latch.h</a>
<dd>A D-latch composed of basic gates.
<dt><a href="test_all.cpp">test_all.cpp</a>
<dd>A simple test program that exercises the code in the headers.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example with the Intel&reg; C++ Compiler (Windows* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>test_all <i>-h</i></tt>
<dd>Prints the help for command line options
<dt><tt>test_all [<i>#threads</i>=value] [<i>verbose</i>] [<i>silent</i>] [<i>#threads</i>]</tt>
<dd><tt><i>#threads</i></tt> is the number of threads to use; a range of the form <tt><i>low[:high]</i></tt> where <tt><i>low</i></tt> and optional <tt><i>high</i></tt> are non-negative integers, or <tt><i>'auto'</i></tt> for a platform-specific default number.<br>
<tt><i>verbose</i></tt> print diagnostic output to screen<br>
<tt><i>silent</i></tt> limits output to timing info; overrides verbose<br>
<dt>To run a short version of this example, e.g., for use with Intel&reg; Parallel Inspector:
<dd>Build a <i>debug</i> version of the example
(see the <a href="../../index.html">build instructions</a>).
<br>Run it with the desired number of threads, e.g., <tt>test_all&nbsp;4</tt>.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,637 @@
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "tbb/tbb_config.h"
#include "tbb/global_control.h"
#include <cstdio>
#include "../../common/utility/utility.h"
#include "../../common/utility/get_default_num_threads.h"
#if __TBB_FLOW_GRAPH_CPP11_FEATURES
#if _MSC_VER
#pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning
#endif
#define USE_TWO_BIT_FULL_ADDER 1
#include "basics.h"
#include "one_bit_adder.h"
#if USE_TWO_BIT_FULL_ADDER
#include "two_bit_adder.h"
#else
#include "four_bit_adder.h"
#endif
#include "D_latch.h"
#include <cassert>
// User-specified globals with default values
bool verbose = false; // prints bin details and other diagnostics to screen
bool silent = false; // suppress all output except for time
#endif // __TBB_FLOW_GRAPH_CPP11_FEATURES
int main(int argc, char *argv[]) {
#if __TBB_FLOW_GRAPH_CPP11_FEATURES
try {
utility::thread_number_range threads(utility::get_default_num_threads);
utility::parse_cli_arguments(argc, argv,
utility::cli_argument_pack()
//"-h" option for displaying help is present implicitly
.positional_arg(threads,"#threads",utility::thread_number_range_desc)
.arg(verbose,"verbose"," print diagnostic output to screen")
.arg(silent,"silent"," limits output to timing info; overrides verbose")
);
if (silent) verbose = false; // make silent override verbose
tick_count start = tick_count::now();
for(int p = threads.first; p <= threads.last; p = threads.step(p)) {
tbb::global_control c(tbb::global_control::max_allowed_parallelism, p);
if (!silent) cout << "graph test running on " << p << " threads.\n";
graph g;
{ // test buffer: 0, 1
buffer b(g);
toggle input(g);
led output(g, "OUTPUT", false); // false means we will explicitly call display to see LED
make_edge(input.get_out(), input_port<0>(b));
make_edge(output_port<0>(b), output.get_in());
if (!silent) printf("Testing buffer...\n");
input.activate(); // 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input.flip(); // 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
}
{ // test not_gate: 0, 1
not_gate n(g);
toggle input(g);
led output(g, "OUTPUT", false);
make_edge(input.get_out(), input_port<0>(n));
make_edge(output_port<0>(n), output.get_in());
if (!silent) printf("Testing not_gate...\n");
input.activate(); // 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input.flip(); // 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
}
{ // test two-input and_gate: 00, 01, 10, 11
and_gate<2> a(g);
toggle input0(g);
toggle input1(g);
led output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(a));
make_edge(input1.get_out(), input_port<1>(a));
make_edge(output_port<0>(a), output.get_in());
if (!silent) printf("Testing and_gate...\n");
input1.activate(); input0.activate(); // 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input1.flip(); input0.flip(); // 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
}
{ // test three-input or_gate: 000, 001, 010, 100, 011, 101, 110, 111
or_gate<3> o(g);
toggle input0(g);
toggle input1(g);
toggle input2(g);
led output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(o));
make_edge(input1.get_out(), input_port<1>(o));
make_edge(input2.get_out(), input_port<2>(o));
make_edge(output_port<0>(o), output.get_in());
if (!silent) printf("Testing or_gate...\n");
input2.activate(); input1.activate(); input0.activate(); // 0 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 0 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input1.flip(); input0.flip(); // 0 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input2.flip(); input1.flip(); // 1 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input2.flip(); input1.flip(); input0.flip(); // 0 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input2.flip(); input1.flip(); // 1 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input1.flip(); input0.flip(); // 1 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input0.flip(); // 1 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
}
{ // test two-input xor_gate: 00, 01, 10, 11
xor_gate<2> x(g);
toggle input0(g);
toggle input1(g);
led output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(x));
make_edge(input1.get_out(), input_port<1>(x));
make_edge(output_port<0>(x), output.get_in());
if (!silent) printf("Testing xor_gate...\n");
input1.activate(); input0.activate(); // 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input1.flip(); input0.flip(); // 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input0.flip(); // 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
}
{ // test two-input nor_gate: 00, 01, 10, 11
nor_gate<2> n(g);
toggle input0(g);
toggle input1(g);
led output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(n));
make_edge(input1.get_out(), input_port<1>(n));
make_edge(output_port<0>(n), output.get_in());
if (!silent) printf("Testing nor_gate...\n");
input1.activate(); input0.activate(); // 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input0.flip(); // 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input1.flip(); input0.flip(); // 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
}
{ // test steady_signal and digit
steady_signal input0(g, high);
steady_signal input1(g, low);
and_gate<2> a(g);
or_gate<2> o(g);
xor_gate<2> x(g);
nor_gate<2> n(g);
digit output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(a));
make_edge(input1.get_out(), input_port<1>(a));
make_edge(output_port<0>(a), input_port<0>(output));
make_edge(input0.get_out(), input_port<0>(o));
make_edge(input1.get_out(), input_port<1>(o));
make_edge(output_port<0>(o), input_port<1>(output));
make_edge(input0.get_out(), input_port<0>(x));
make_edge(input1.get_out(), input_port<1>(x));
make_edge(output_port<0>(x), input_port<2>(output));
make_edge(input0.get_out(), input_port<0>(n));
make_edge(input1.get_out(), input_port<1>(n));
make_edge(output_port<0>(n), input_port<3>(output));
if (!silent) printf("Testing steady_signal...\n");
input0.activate(); // 1
input1.activate(); // 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == 6);
}
{ // test push_button
push_button p(g);
buffer b(g);
led output(g, "OUTPUT", !silent); // true means print all LED state changes
make_edge(p.get_out(), input_port<0>(b));
make_edge(output_port<0>(b), output.get_in());
if (!silent) printf("Testing push_button...\n");
p.press();
p.release();
p.press();
p.release();
g.wait_for_all();
}
{ // test one_bit_adder
one_bit_adder my_adder(g);
toggle A(g);
toggle B(g);
toggle CarryIN(g);
led Sum(g, "SUM");
led CarryOUT(g, "CarryOUT");
make_edge(A.get_out(), input_port<P::A0>(my_adder));
make_edge(B.get_out(), input_port<P::B0>(my_adder));
make_edge(CarryIN.get_out(), input_port<P::CI>(my_adder));
make_edge(output_port<P::S0>(my_adder), Sum.get_in());
make_edge(output_port<1>(my_adder), CarryOUT.get_in());
A.activate();
B.activate();
CarryIN.activate();
if (!silent) printf("A on\n");
A.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
if (!silent) printf("A off\n");
A.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("B on\n");
B.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
if (!silent) printf("B off\n");
B.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("CarryIN on\n");
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
if (!silent) printf("CarryIN off\n");
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("A&B on\n");
A.flip();
B.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
if (!silent) printf("A&B off\n");
A.flip();
B.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("A&CarryIN on\n");
A.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
if (!silent) printf("A&CarryIN off\n");
A.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("B&CarryIN on\n");
B.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
if (!silent) printf("B&CarryIN off\n");
B.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("A&B&CarryIN on\n");
A.flip();
B.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == high) && (CarryOUT.get_value() == high));
if (!silent) printf("A&B&CarryIN off\n");
A.flip();
B.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
}
#if USE_TWO_BIT_FULL_ADDER
{ // test two_bit_adder
if (!silent) printf("testing two_bit adder\n");
two_bit_adder two_adder(g);
std::vector<toggle> A(2, toggle(g));
std::vector<toggle> B(2, toggle(g));
toggle CarryIN(g);
digit Sum(g, "SUM");
led CarryOUT(g, "CarryOUT");
make_edge(A[0].get_out(), input_port<P::A0>(two_adder));
make_edge(B[0].get_out(), input_port<P::B0>(two_adder));
make_edge(output_port<P::S0>(two_adder), input_port<0>(Sum));
make_edge(A[1].get_out(), input_port<P::A1>(two_adder));
make_edge(B[1].get_out(), input_port<P::B1>(two_adder));
make_edge(output_port<P::S1>(two_adder), input_port<1>(Sum));
make_edge(CarryIN.get_out(), input_port<P::CI>(two_adder));
make_edge(output_port<P::CO>(two_adder), CarryOUT.get_in());
// Activate all switches at low state
for (int i=0; i<2; ++i) {
A[i].activate();
B[i].activate();
}
CarryIN.activate();
if (!silent) printf("1+0\n");
A[0].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
if (!silent) printf("0+1\n");
A[0].flip();
B[0].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
}
#else
{ // test four_bit_adder
four_bit_adder four_adder(g);
std::vector<toggle> A(4, toggle(g));
std::vector<toggle> B(4, toggle(g));
toggle CarryIN(g);
digit Sum(g, "SUM");
led CarryOUT(g, "CarryOUT");
make_edge(A[0].get_out(), input_port<P::A0>(four_adder));
make_edge(B[0].get_out(), input_port<P::B0>(four_adder));
make_edge(output_port<P::S0>(four_adder), input_port<0>(Sum));
make_edge(A[1].get_out(), input_port<P::A1>(four_adder));
make_edge(B[1].get_out(), input_port<P::B1>(four_adder));
make_edge(output_port<P::S1>(four_adder), input_port<1>(Sum));
make_edge(A[2].get_out(), input_port<P::A2>(four_adder));
make_edge(B[2].get_out(), input_port<P::B2>(four_adder));
make_edge(output_port<P::S2>(four_adder), input_port<2>(Sum));
make_edge(A[3].get_out(), input_port<P::A3>(four_adder));
make_edge(B[3].get_out(), input_port<P::B3>(four_adder));
make_edge(output_port<P::S3>(four_adder), input_port<3>(Sum));
make_edge(CarryIN.get_out(), input_port<P::CI>(four_adder));
make_edge(output_port<P::CO>(four_adder), CarryOUT.get_in());
// Activate all switches at low state
for (int i=0; i<4; ++i) {
A[i].activate();
B[i].activate();
}
CarryIN.activate();
if (!silent) printf("1+0\n");
A[0].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
if (!silent) printf("0+1\n");
A[0].flip();
B[0].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
if (!silent) printf("3+4\n");
A[0].flip();
A[1].flip();
B[0].flip();
B[2].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 7) && (CarryOUT.get_value() == low));
if (!silent) printf("6+1\n");
A[0].flip();
A[2].flip();
B[0].flip();
B[2].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 7) && (CarryOUT.get_value() == low));
if (!silent) printf("0+0+carry\n");
A[1].flip();
A[2].flip();
B[0].flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
if (!silent) printf("15+15+carry\n");
A[0].flip();
A[1].flip();
A[2].flip();
A[3].flip();
B[0].flip();
B[1].flip();
B[2].flip();
B[3].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 0xf) && (CarryOUT.get_value() == high));
if (!silent) printf("8+8\n");
A[0].flip();
A[1].flip();
A[2].flip();
B[0].flip();
B[1].flip();
B[2].flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 0) && (CarryOUT.get_value() == high));
if (!silent) printf("0+0\n");
A[3].flip();
B[3].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 0) && (CarryOUT.get_value() == low));
}
#endif
{ // test D_latch
D_latch my_d_latch(g);
toggle D(g);
pulse E(g, 500, 4); // clock changes every 500ms; stops after 4 changes
led Q(g, " Q", verbose); // if true, LEDs print at every state change
led notQ(g, "~Q", verbose);
make_edge(D.get_out(), input_port<0>(my_d_latch));
make_edge(E.get_out(), input_port<1>(my_d_latch));
make_edge(output_port<0>(my_d_latch), Q.get_in());
make_edge(output_port<1>(my_d_latch), notQ.get_in());
D.activate();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == high) && (notQ.get_value() == low));
E.reset();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == low) && (notQ.get_value() == high));
E.reset();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == high) && (notQ.get_value() == low));
E.reset();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == low) && (notQ.get_value() == high));
E.reset();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == high) && (notQ.get_value() == low));
}
}
utility::report_elapsed_time((tbb::tick_count::now() - start).seconds());
return 0;
} catch(std::exception& e) {
cerr<<"error occurred. error text is :\"" <<e.what()<<"\"\n";
return 1;
}
#else
utility::report_skipped();
return 0;
#endif // __TBB_FLOW_GRAPH_CPP11_FEATURES
}

View File

@@ -0,0 +1,55 @@
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBBexample_graph_logicsim_tba_H
#define __TBBexample_graph_logicsim_tba_H 1
#include "one_bit_adder.h"
class two_bit_adder : public composite_node< tuple< signal_t, signal_t, signal_t, signal_t, signal_t >,
tuple< signal_t, signal_t, signal_t > > {
graph& my_graph;
std::vector<one_bit_adder> two_adders;
typedef composite_node< tuple< signal_t, signal_t, signal_t, signal_t, signal_t >,
tuple< signal_t, signal_t, signal_t > > base_type;
public:
two_bit_adder(graph& g) : base_type(g), my_graph(g), two_adders(2, one_bit_adder(g)) {
make_connections();
set_up_composite();
}
two_bit_adder(const two_bit_adder& src) :
base_type(src.my_graph), my_graph(src.my_graph), two_adders(2, one_bit_adder(src.my_graph))
{
make_connections();
set_up_composite();
}
~two_bit_adder() {}
private:
void make_connections() {
make_edge(output_port<1>(two_adders[0]), input_port<0>(two_adders[1]));
}
void set_up_composite() {
base_type::input_ports_type input_tuple(input_port<0>(two_adders[0]/*CI*/), input_port<1>(two_adders[0]), input_port<2>(two_adders[0]), input_port<1>(two_adders[1]), input_port<2>(two_adders[1]));
base_type::output_ports_type output_tuple(output_port<0>(two_adders[0]), output_port<0>(two_adders[1]),output_port<1>(two_adders[1]/*CO*/));
base_type::set_external_ports(input_tuple, output_tuple);
}
};
#endif /* __TBBexample_graph_logicsim_tba_H */