Unit 7: Memory
Chips that have a past.
Unit 7 of 8 in Digital logic for kids. Its 5 lessons are Time, The Flip-Flop, Remembering on Purpose, A Register and Holding On — below is everything each one explains, and a question or two from it to try.
Every chip on this page was wired up and run on the gate-level simulator before it shipped, and prints exactly the table shown.
This unit opens with a fortnight’s trial of everything — no card needed — or with a family plan, bought in the iPhone app. The first two units of every track are free for ever. Try it in the app.
⏱️ Time
Everything so far forgets instantly
Every chip you have built has no memory at all. Change an input and the output changes with it, immediately. Look away and back and it is the same.
But a computer has to *remember*. It has to hold on to a number while it works out the next one. Gates alone cannot do that — you need something that holds still.
Why a loop is not enough
You might try wiring a chip’s output back into its own input, so it feeds itself.
That does not work. Nothing tells the signal when to stop going round, so it chases its own tail forever and never settles on an answer. If you try it here, the simulator stops and says so rather than making one up.
What is missing is a beat.
The clock
Somewhere in every computer there is a crystal ticking, millions or billions of times a second. Everything happens on those ticks.
Between ticks, gates settle. On a tick, the remembering parts all grab their new values at the same instant. Then it goes quiet again.
Here that tick is a command: CLOCK;.
Try it yourself
What breaks if you wire a chip’s output straight back to its input?
- Nothing tells it when to stop going round, so it never settles
- The wires get too hot
- It works, but slowly
- The output becomes 0
When does a computer’s speed — say "3 GHz" — actually refer to?
- How many times a second the clock ticks
- How many gates it has
- How many numbers it can hold
- How fast electricity moves
Answer them in the app
🪃 The Flip-Flop
The second thing you are given
Alongside Nand there is one more part you do not build: the DFF, or flip-flop.
It does one thing. Whatever is on its in when the clock ticks comes out of its out — and stays there until the next tick. It is a one-tick delay, and that delay is the whole of memory.
Watch: in goes to 1, but out does not follow until CLOCK.
HDL
CHIP Delay {
IN in;
OUT out;
PARTS:
DFF(in=in, out=out);
}
USE Delay;
SET in=1;
SHOW out;
CLOCK;
SHOW out;
SET in=0;
SHOW out;
CLOCK;
SHOW out;
It prints
out=0 out=1 out=1 out=0
They all tick together
Put two DFFs in a row and a 1 does not run straight through both on one tick. It moves one step per tick, because every flip-flop grabs its value at the same instant — before any of them have changed.
That is why you can build a loop with a DFF in it: the loop takes a whole tick to go round.
HDL
CHIP Shift {
IN in;
OUT a, b;
PARTS:
DFF(in=in, out=a);
DFF(in=a, out=b);
}
USE Shift;
SET in=1;
CLOCK;
SHOW;
SET in=0;
CLOCK;
SHOW;
CLOCK;
SHOW;
It prints
a=1 b=0 a=0 b=1 a=0 b=0
Try it yourself
Why is the third line still out=1 even though in has been set to 0?
- A DFF only changes on a tick, and there has not been one yet
- Because SET does not work on DFFs
- Because 0 and 1 are the same to a DFF
- It is a bug
What does this print?
HDL
CHIP Delay {
IN in;
OUT out;
PARTS:
DFF(in=in, out=out);
}
USE Delay;
SET in=1;
CLOCK;
SHOW out;
SET in=0;
CLOCK;
SHOW out;
Answer them in the app
🧠 Remembering on Purpose
A DFF forgets too fast
A flip-flop always takes whatever is on its input. So it only remembers for one tick, and then it is overwritten.
What you want is a box that keeps its value until you *say* to change it. So add a load wire, and a Mux to choose: load is 0, feed the DFF its own output back — load is 1, feed it the new value.
The loop is legal now, because it goes through a DFF.
HDL
CHIP Bit {
IN in, load;
OUT out;
PARTS:
Mux(a=out, b=in, sel=load, out=d);
DFF(in=d, out=out);
}
USE Bit;
SET in=1, load=1;
CLOCK;
SHOW out;
SET in=0, load=0;
CLOCK;
CLOCK;
SHOW out;
SET load=1;
CLOCK;
SHOW out;
It prints
out=1 out=1 out=0
Try it yourself
With load=0, what does the Mux feed back into the DFF?
- The DFF’s own output — so it keeps what it already had
- Zero
- The new input
- Nothing, the DFF switches off
Why is this loop allowed, when the one in lesson 7.1 was not?
- The DFF holds the value still for a whole tick, so the loop cannot race round
- Because a Mux blocks loops
- Because load is sometimes 0
- It is not really a loop
Answer them in the app
🗄️ A Register
One bit is not a number
To hold a whole four-bit number, use four Bits side by side and give them all the same load wire. Then they all change together, or none of them do.
That is a register — the boxes a CPU keeps its working numbers in. A real one is 64 Bits wide. Yours is 4.
HDL
CHIP Reg {
IN i3, i2, i1, i0, load;
OUT o3, o2, o1, o0;
PARTS:
Bit(in=i3, load=load, out=o3);
Bit(in=i2, load=load, out=o2);
Bit(in=i1, load=load, out=o1);
Bit(in=i0, load=load, out=o0);
}
USE Reg;
SET i3=1, i2=0, i1=1, i0=1, load=1;
CLOCK;
SHOW;
SET i3=0, i2=0, i1=0, i0=0, load=0;
CLOCK;
SHOW;
It prints
o3=1 o2=0 o1=1 o0=1 o3=1 o2=0 o1=1 o0=1
Try it yourself
The inputs were set to all zeros before that second tick. Why is the answer still 1011?
- load was 0, so every Bit kept what it had
- The register only works once
- Because 0000 and 1011 are the same
- The clock did not tick
Why do all four Bits share one load wire?
- So the whole number changes at once, instead of half a new number and half an old one
- To use fewer wires
- Because Bits cannot have their own load
- So they take turns
Answer them in the app
🏆 Holding On
Memory is a loop with a beat in it
That is all a computer’s memory ever is. A value going round a loop, again and again, with a flip-flop making it wait one tick each time round.
Stack up billions of those and you have the memory in the machine you are reading this on. Every single one is a loop, patiently going round.
Try it yourself
What is the one thing a DFF actually does?
- Copies its input to its output, but only when the clock ticks
- Stores a number forever
- Adds one to its input
- Blocks a signal
What does this print?
HDL
CHIP Bit {
IN in, load;
OUT out;
PARTS:
Mux(a=out, b=in, sel=load, out=d);
DFF(in=d, out=out);
}
USE Bit;
SET in=1, load=1;
CLOCK;
SET in=0, load=0;
CLOCK;
CLOCK;
CLOCK;
SHOW out;
Answer them in the app