Boolean Circuits · NAND Game: Processor (Optional)
Lesson 1
A processor employs both types of memory, namely registers and RAM. Registers are directly accessible to the processor and are used to store intermediate values and computation results. In contrast, RAM is capable of storing a substantial amount of data; however, only a single address can be accessed for reading or writing at any given time. In the present processor architecture, two registers, denoted \(A\) and \(D\), are available in addition to a single RAM bank. In this task, you are required to integrate the two registers with the RAM bank into a unified memory system.
Problem. Construct the combined memory unit. The four input bits are \(\texttt{a}\), \(\texttt{d}\), \(\texttt{*a}\), and \(\texttt{cl}\). The label \(\texttt{x}\) is a hardcoded 16-bit input, so you may use it directly in gate lines. The output of your circuit must be three 16-bit labels, in the order \(\texttt{A D *A}\).
The memory consists of two 16-bit registers called \(\texttt{A}\) and \(\texttt{D}\), and one RAM unit with two 16-bit cells. The destination flags have the following meaning: \[\begin{array}{c | l} \text{flag} & \text{effect} \\ \hline \texttt{a} & \text{write } x \text{ to the } A \text{ register} \\ \texttt{d} & \text{write } x \text{ to the } D \text{ register} \\ \texttt{*a} & \text{write } x \text{ to RAM at the address given by } A\end{array}\]
The flags can be combined, so the same value \(\texttt{x}\) may be written to several destinations in one clock cycle. If all three flags are \(0\), then \(\texttt{x}\) is ignored. The clock behavior is the same as before: writes are captured when \(\texttt{cl}\) changes from \(0\) to \(1\), but become visible only when \(\texttt{cl}\) changes from \(1\) to \(0\). While \(\texttt{cl}\)=1, assume that the inputs do not change.
The RAM has only two cells, so its address is one bit. Therefore, whenever RAM is accessed through the \(\texttt{A}\) register, only the lowest bit of \(\texttt{A}\) is used as the address. If \(\texttt{a}\)=1 and \(\texttt{*a}\)=1 in the same clock cycle, then the RAM write uses the old value of \(\texttt{A}\), before this clock update.
The outputs are: \[\begin{array}{c | l} \text{output} & \text{meaning} \\ \hline \texttt{A} & \text{the current value of the } A \text{ register} \\ \texttt{D} & \text{the current value of the } D \text{ register} \\ \texttt{*A} & \text{the current RAM value at address } A \bmod 2\end{array}\] Initially, \(\texttt{A}\)=0, \(\texttt{D}\)=0, and both RAM cells store \(0\).
You may use only the following functions: \[\begin{aligned}\operatorname{REGISTER}(st,x,cl) &= \text{the current output of a 16-bit register}, \\ \operatorname{RAM}(st,x,ad,cl) &= \text{the current output of the 2-cell RAM}, \\ \operatorname{NAND}(a,b) &= \neg(a \land b), \\ \operatorname{INV}(a) &= \neg a, \\ \operatorname{AND}(a,b) &= a \land b, \\ \operatorname{OR}(a,b) &= a \lor b, \\ \operatorname{XOR}(a,b) &= a \oplus b.\end{aligned}\]
For example, a line \(\texttt{m *a x A cl RAM}\) means that \(\texttt{m}\) is a new 16-bit label equal to the current RAM output when RAM is written with enable \(\texttt{*a}\), data \(\texttt{x}\), address \(\texttt{A}\), and clock \(\texttt{cl}\).
The authors' solution uses \(3\) gates.