\myheading{Simple logic synthesis using Z3 and Apollo Guidance Computer}

\leveldown{}

\renewcommand{\CURPATH}{synth/logic/simple_and_Apollo}

What a smallest possible logic circuit is possible for a given truth table?

Let's try to define truth tables for inputs and outputs and find smallest circuit.
This program is almost the same as I mentioned earlier: \ref{synth_mult}, but reworked slightly:

\lstinputlisting[style=custompy]{\CURPATH/logic.py}

I could generate only small circuits maybe up to $\approx 10$ gates, but this is interesting nonetheless.

Also, I've always wondering how you can do something usable for Apollo Guidance Computer,
which had only one single gate: NOR3?
See also its schematics: \url{http://klabs.org/history/ech/agc_schematics/}.
The answer is De Morgan's laws, but this is not obvious.

INPUTS[] has all possible bit combinations for all inputs, or all possible truth tables. OUTPUTS[] has truth table for each output.
All the rest is processed in bitsliced manner.
Given that, the resulting program will work on 4/8/16-bit CPU and will generate defined OUTPUTS for defined INPUTS.
Or, this program can be treated just like a logic circuit.

\myheading{AND gate}

How to build 2-input AND gate using only OR's and NOT's?

\begin{lstlisting}
INPUTS=[0b1100, 0b1010]
OUTPUTS=[0b1000]
BITS=4
avail=[I_OR, I_NOT]

...

r0=input                 1100
r1=input                 1010
r2=NOT r1                0101
r3=NOT r0                0011
r4=OR r3, r2             0111
r5=NOT r4                1000
\end{lstlisting}

This is indeed like stated in De Morgan's laws: $x \wedge y$ is equivalent to $\neg (\neg x \vee \neg y)$.
Can be used for obfuscation?

Now using only NOR3 gate?

\begin{lstlisting}
avail=[I_NOR3]

...

r0=input                 1100
r1=input                 1010
r2=NOR3 r1, r1, r1       0101
r3=NOR3 r2, r0, r0       0010
r4=NOR3 r3, r2, r2       1000
\end{lstlisting}

\myheading{XOR gate}

How to build 2-input XOR using only OR's and NOT's?

\begin{lstlisting}
INPUTS=[0b1100, 0b1010]
OUTPUTS=[0b0110]
BITS=4
avail=[I_OR, I_NOT]

...

7 instructions
r0=input                 1100
r1=input                 1010
r2=OR r1, r0             1110
r3=NOT r2                0001
r4=OR r0, r3             1101
r5=NOT r4                0010
r6=OR r1, r3             1011
r7=NOT r6                0100
r8=OR r5, r7             0110
\end{lstlisting}

... using only AND's and NOT's?

\begin{lstlisting}
avail=[I_AND, I_NOT]
...
r0=input                 1100
r1=input                 1010
r2=NOT r1                0101
r3=AND r1, r0            1000
r4=NOT r3                0111
r5=NOT r0                0011
r6=AND r2, r5            0001
r7=NOT r6                1110
r8=AND r4, r7            0110
\end{lstlisting}

... using only NOR3 gates?

\begin{lstlisting}
avail=[I_NOR3]
...
r0=input                 1100
r1=input                 1010
r2=NOR3 r1, r1, r1       0101
r3=NOR3 r0, r0, r1       0001
r4=NOR3 r0, r2, r3       0010
r5=NOR3 r2, r4, r2       1000
r6=NOR3 r3, r5, r3       0110
\end{lstlisting}

\myheading{Full-adder}

According to Wikipedia, \href{https://en.wikipedia.org/wiki/Adder_(electronics)}{full-adder}
can be constructed using two XOR gates, two AND gates and one OR gate.
But I had no idea 3 XORs and 2 ANDs can be used instead:

\begin{lstlisting}
INPUTS=[0b11110000, 0b11001100, 0b10101010]
OUTPUTS=[0b11101000, 0b10010110] # carry-out, sum
BITS=8
avail=[I_AND, I_OR, I_XOR, I_NOT]

...

5 instructions
r0=input                 11110000
r1=input                 11001100
r2=input                 10101010
r3=XOR r2, r1            01100110
r4=AND r0, r3            01100000
r5=AND r2, r1            10001000
r6=XOR r4, r5            11101000
r7=XOR r0, r3            10010110
\end{lstlisting}

... using only NOR3 gates:

\begin{lstlisting}
avail=[I_NOR3]
...
8 instructions
r0=input                 11110000
r1=input                 11001100
r2=input                 10101010
r3=NOR3 r0, r0, r1       00000011
r4=NOR3 r2, r3, r1       00010000
r5=NOR3 r3, r2, r0       00000100
r6=NOR3 r3, r0, r5       00001000
r7=NOR3 r5, r2, r4       01000001
r8=NOR3 r3, r4, r1       00100000
r9=NOR3 r3, r5, r4       11101000
r10=NOR3 r8, r7, r6      10010110
\end{lstlisting}

\myheading{POPCNT}

Smallest circuit to count bits in 3-bit input, producing 2-bit output:

\begin{lstlisting}
INPUTS=[0b11110000, 0b11001100, 0b10101010]
OUTPUTS=[0b11101000, 0b10010110] # high, low
BITS=8
avail=[I_AND, I_OR, I_XOR, I_NOT]
...
5 instructions
r0=input                 11110000
r1=input                 11001100
r2=input                 10101010
r3=XOR r2, r1            01100110
r4=AND r0, r3            01100000
r5=AND r2, r1            10001000
r6=XOR r4, r5            11101000
r7=XOR r0, r3            10010110
\end{lstlisting}

... using only NOR3 gates:

\begin{lstlisting}
avail=[I_NOR3]
...
8 instructions
r0=input                 11110000
r1=input                 11001100
r2=input                 10101010
r3=NOR3 r0, r0, r1       00000011
r4=NOR3 r2, r3, r1       00010000
r5=NOR3 r3, r2, r0       00000100
r6=NOR3 r3, r0, r5       00001000
r7=NOR3 r5, r2, r4       01000001
r8=NOR3 r3, r4, r1       00100000
r9=NOR3 r3, r5, r4       11101000
r10=NOR3 r8, r7, r6      10010110
\end{lstlisting}

\myheading{Circuit for a central "g" segment of 7-segment display}

\begin{figure}[H]
\centering
\frame{\includegraphics[scale=0.6]{\CURPATH/192px-7-segment_labeled.png}}
\end{figure}

(The image taken from \href{https://commons.wikimedia.org/wiki/File:7-segment_labeled.svg}{Wikipedia}.)

I couldn't find a circuit for the all 7 segments, but found for one, a central one ("g").
Yes, encoders like these are usually implemented using a ROM.
But I always been wondering, how to do this using only gates.

The truth table for "g" segment I've used from this table:

\begin{figure}[H]
\centering
\frame{\includegraphics[scale=0.6]{\CURPATH/NV_0501_Marston_Figure02.jpg}}
\end{figure}

(The image taken from \url{http://www.nutsvolts.com}.)

\begin{lstlisting}
INPUTS=[0b1111111100000000, 0b1111000011110000, 0b1100110011001100, 0b1010101010101010]
# "g" segment, like here: http://www.nutsvolts.com/uploads/wygwam/NV_0501_Marston_Figure02.jpg
OUTPUTS=[0b1110111101111100] # g
BITS=16
avail=[I_AND, I_OR, I_XOR, I_NOT]
...
5 instructions
r0=input                 1111111100000000
r1=input                 1111000011110000
r2=input                 1100110011001100
r3=input                 1010101010101010
r4=AND r3, r1            1010000010100000
r5=XOR r4, r0            0101111110100000
r6=XOR r4, r2            0110110001101100
r7=XOR r5, r1            1010111101010000
r8=OR r7, r6             1110111101111100
\end{lstlisting}

Using only NOR3 gates:

\begin{lstlisting}
avail=[I_NOR3]
...
8 instructions
r0=input                 1111111100000000
r1=input                 1111000011110000
r2=input                 1100110011001100
r3=input                 1010101010101010
r4=NOR3 r1, r1, r1       0000111100001111
r5=NOR3 r3, r3, r4       0101000001010000
r6=NOR3 r2, r0, r0       0000000000110011
r7=NOR3 r6, r6, r5       1010111110001100
r8=NOR3 r4, r0, r7       0000000001110000
r9=NOR3 r8, r7, r2       0001000000000011
r10=NOR3 r0, r8, r4      0000000010000000
r11=NOR3 r9, r10, r10    1110111101111100
\end{lstlisting}

\myheading{But what about bruteforce?}

Let's imagine, a program of 5 instructions, each can be one of four (AND/OR/XOR/NOT).

There are can be $4^2 \cdot 4$ first instructions (that is connected to r4).
Two operands, each can be connected to one of 4 inputs (r0...r3).
Four instructions: 4.

There are can be $5^2 \cdot 4$ second instructions... and $8^2 \cdot 4$ fifth instructions.

How many programs there can be?

\begin{figure}[H]
  \[
\displaystyle\prod_{j=i}^{s+i-1} j^{o} \cdot m
  \]
  \caption{The general formula.
$j$ = how many inputs available to an instruction at a step;
$i$ = total number of inputs of a program (4 in my case);
$s$ = total number of instructions in program (\textit{steps});
$o$ = total number of operands each instruction has;
$m$ = how many instructions available to choose from.}
\end{figure}

$(4^2 \cdot 4) \cdot
(5^2 \cdot 4) \cdot
(6^2 \cdot 4) \cdot
(7^2 \cdot 4) \cdot
(8^2 \cdot 4) = 46242201600$

And $log_2 (46242201600) \approx 35$ bits.
This is feasible on a fast computer.

Now what about a program of 8 instructions, where each instruction is always NOR and has 3 inputs/operands?
1st instruction: $4^3$ ... 8th instruction: $11^3$.

How many programs there can be?

$4^3 \cdot 5^3 \cdot 6^3 \cdot 7^3 \cdot 8^3 \cdot 9^3 \cdot 10^3 \cdot 11^3 = 294451250429952000000$.
And $log_2(294451250429952000000) \approx 68$ bits.
Way too much for bruteforce.

\levelup{}
