Disabled external gits
This commit is contained in:
56
cs440-acg/ext/tbb/examples/graph/logic_sim/D_latch.h
Normal file
56
cs440-acg/ext/tbb/examples/graph/logic_sim/D_latch.h
Normal 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 */
|
52
cs440-acg/ext/tbb/examples/graph/logic_sim/Makefile.windows
Normal file
52
cs440-acg/ext/tbb/examples/graph/logic_sim/Makefile.windows
Normal 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)
|
554
cs440-acg/ext/tbb/examples/graph/logic_sim/basics.h
Normal file
554
cs440-acg/ext/tbb/examples/graph/logic_sim/basics.h
Normal 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 */
|
58
cs440-acg/ext/tbb/examples/graph/logic_sim/four_bit_adder.h
Normal file
58
cs440-acg/ext/tbb/examples/graph/logic_sim/four_bit_adder.h
Normal 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 */
|
99
cs440-acg/ext/tbb/examples/graph/logic_sim/one_bit_adder.h
Normal file
99
cs440-acg/ext/tbb/examples/graph/logic_sim/one_bit_adder.h
Normal 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 */
|
406
cs440-acg/ext/tbb/examples/graph/logic_sim/readme.html
Normal file
406
cs440-acg/ext/tbb/examples/graph/logic_sim/readme.html
Normal 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® 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® 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® 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® 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 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>© 2020, Intel Corporation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
637
cs440-acg/ext/tbb/examples/graph/logic_sim/test_all.cpp
Normal file
637
cs440-acg/ext/tbb/examples/graph/logic_sim/test_all.cpp
Normal 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
|
||||
}
|
||||
|
55
cs440-acg/ext/tbb/examples/graph/logic_sim/two_bit_adder.h
Normal file
55
cs440-acg/ext/tbb/examples/graph/logic_sim/two_bit_adder.h
Normal 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 */
|
||||
|
Reference in New Issue
Block a user