# Digital Logic Simulation with the Intel® TBB Flow Graph, Part 2: Building bigger components

In Part 1, I described how to put together a basic logic gate using the Intel® Threading Building Blocks flow graph nodes or_node and multifunction_node. In this blog, I will assume the basic logic gates and_gate, or_gate and xor_gate exist, and use them to construct a four-bit adder.

To begin with, I'll first construct a one-bit full adder as in Figure 2 below:

The inputs are A and B, and a Carry-in bit, and the output is the sum S, and a Carry-out bit. Here is the code for the one_bit_adder class:

xor_gate < two_input > FirstXOR;
xor_gate < two_input > SecondXOR;
and_gate < two_input > FirstAND;
and_gate < two_input > SecondAND;
or_gate < two_input > FirstOR;
graph& my_graph;
void make_connections() {
make_edge(A_port, FirstXOR.get_in(0));
make_edge(A_port, FirstAND.get_in(0));
make_edge(B_port, FirstXOR.get_in(1));
make_edge(B_port, FirstAND.get_in(1));
make_edge(CI_port, SecondXOR.get_in(1));
make_edge(CI_port, SecondAND.get_in(1));
make_edge(FirstXOR.get_out(), SecondXOR.get_in(0));
make_edge(FirstXOR.get_out(), SecondAND.get_in(0));
make_edge(SecondAND.get_out(), FirstOR.get_in(0));
make_edge(FirstAND.get_out(), FirstOR.get_in(1));
}
public:
my_graph(g), A_port(g), B_port(g), CI_port(g), FirstXOR(g),
SecondXOR(g), FirstAND(g), SecondAND(g), FirstOR(g)
{
make_connections();
}
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();
}
receiver < signal_t > & get_A() { return A_port; }
receiver < signal_t > & get_B() { return B_port; }
receiver < signal_t > & get_CI() { return CI_port; }
sender < signal_t > & get_out() { return SecondXOR.get_out(); }
sender < signal_t > & get_CO() { return FirstOR.get_out(); }
};

This implementation is almost a straightforward translation of the gates and their connections into the flow graph format. The one complication is the addition of the broadcast_nodes for each of the input ports. The reason for this is simply to enable connection to a single port from outside of the adder. Since each of the inputs is connected to two gates inside of the one_bit_adder object, there is no single port associated with them automatically. Adding the broadcast_nodes enables us to provide the methods get_A, get_B and get_CI that each return a single port capable of receiving data. So, in looking at the diagram above, you can think of the three broadcast_nodes as standing in for the black junction circles that the three inputs are connected to directly.

To make the four_bit_adder class, simply chain together a set of four one_bit_adders and connect the Carry-out port of each adder to the Carry-in port of the next adder, as shown in Figure 3 below:

This time, the class is even more straightforward to implement, because no broadcast_nodes are needed; every input already has exactly one internal connection.

graph& my_graph;
void make_connections() {
}
public:
make_connections();
}
{
make_connections();
}
receiver < signal_t > & get_A(size_t bit) {
}
receiver < signal_t > & get_B(size_t bit) {
}
receiver < signal_t > & get_CI() {
}
sender < signal_t > & get_out(size_t bit) {