NAND2Tetris Note 04 - Sequential Logic and Memory

All of the chips described in the previous course notes used what is called “combinational logic”, where the output is available instantenously and there is no time-component to their operation. Combinational chips compute functions that depend solely on combinations of their input values.

Sequential logic incorporates the concept of time, or more specifically, discretized time in the form of a clock signal into determining their output. This is the core concept behind digital circuits with memory. Just like how NAND formed the basic building blocks of combinational logic, the “D-Flip-Flip” is the fundamental building block used to build sequential logic. A D-Flip-Flop can be built out of nand-gates using a loop-based design but that is beyond the scope of the course.

Clocked Data Flip Flop (D Flip-Flop or DFF)

The D Flip-Flop has one input “in” and one output “out”. There’s also an implicit “clock” signal that cycles from high to low and back to high to make a single “clock cycle”. The output of the D flip-flip is simply the input of the last time step (with the output of the initial timestep being indeterminate).

D-Flip-Flops are combined in various ways with combinational logic circuits to build up basic memory units like a 1-bit register, larger addressed registers (RAM) and counters that form the basis of computer memory.

One-Bit Register

A bit regsiter has two inputs “in” and “load” and a single output “out”. The output is the same as the last output if “load” is zero. It is equal to “in” if “load” is set to one. The HDL imlementation uses a Mux to select between the lastOutput and the current input. This is then passed into a DFF and the output of the DFF is the output of the register.

Mux(a=lastOutput, b=in, sel=load, out=dffIn);
DFF(in=dffIn, out=out, out=lastOutput);

The output of the DFF is fanned out to the input of the Mux as well. This is possible because HDL is not a programming language. It can be thought of as a description of electrical wiring. So the output line of the DFF is looped back to the input of the Mux here.

16-bit register

A 16-bit register chip has a 16-bit input in, a single bit load input and a 16-bit output, out. This can be implemented by stacking 8 one-bit register and fanning out the load input to all of them. The inputs and outputs of each “bit” chip is wired to the individual bits of in and out respectively.

RAM8 chip

This is a chip that can store 8 “words” (in this case 16-bit words). The chip has a 16-bit in input, 3-bit address input and a 16-bit output, out. It uses a Demuxer to split out the address into 8 different load bits which are then fed into Register chips. in is fanned out to all the underlying Register chips. The outputs of the registers are then connected to the out pin through a Multiplexer with the address as its selector.

RAM64, RAM512, RAM4K and RAM16K

These are built in the same manner as RAM8 but by composing RAMx chips using a Demuxer and Muxer. RAM64 has a 6-bit address input, where the 3 most-significant bits select the underlying RAM8 chip and the 3 LSBs signify the address in the underlying RAM8. Therefore the load bit is wired to the RAM8 chips through a Demuxer with address[3..5] as the sel input and address[0..2] is passed through directly to the underlying chips. The output is similarly muxed using address[3..5] as the selector. The higher capacity chips are built in the same way by stacking 4 or 8 lower capacity chips and an appropriately sized Demuxer and Muxer.


  • NAND2Tetris