Lesson 1. Memory: the latch and the D flip-flop

In pictures

After this lesson the circuit gets a memory: a lamp remembers what was on the input at the moment of a clock tick and holds it until the next one. Without memory you cannot draw a picture — the circuit has to remember which dot it is on and where to go next.


1.1. The idea: a loop that holds

If you feed a gate's output back into its input, the circuit can "get stuck" in one of two states — and that is memory. Two cross-coupled NOR gates make an SR latch: S writes 1, R writes 0, and when both are 0 it remembers what was there.

R=0S=0NORNORQ = 1nQ = 0the loop holds
The SR latch: the output of each NOR goes into the other one. Q = 1 keeps the second NOR at zero, and its zero keeps the first at one — while S and R are both 0 the state does not change. S = 1 writes 1, R = 1 writes 0.

Holding two inputs is awkward, so we add two AND gates — and get a D latch: while EN = 1 the output follows D, with EN = 0 it holds.

Counters need writing at one moment — on the clock edge. That is the D flip-flop: two latches taking turns. While CLK = 0 the master listens to D; when CLK becomes 1 the master closes and the slave shows what it managed to store.

CLKDQ
The D flip-flop: the output Q changes only at the CLK rising edge (dashed) — it takes what was on D. Between edges D can jump around freely — Q holds.

1.2. Building

A new empty project. Place the power: Power → label VCC, Ground → label GND (they are shared inside chips).

You need the gates NOT, NAND, NOR, AND, OR, XOR:

  • built them in another kit — they are in the library, use them;
  • want to build them yourself from transistors — "Lesson 0. Gates from transistors";
  • want to get straight to it — paste lesson 0 (Cmd+I): the gates appear in the library, the canvas does not change.

Step 1. SRLatch — the latch: two cross-coupled NOR gates

The output of each NOR goes into the input of the other — a loop that holds its state. S = 1 — store 1, R = 1 — store 0, both 0 — hold.

PartPinLabel
Input portoutR
Input portoutS
NOR (1st)I0
I1
O0
R
nQ
Q
NOR (2nd)I0
I1
O0
S
Q
nQ
Output portinQ
Output portinnQ

Ctrl+G → name SRLatch. Chip pins: inputs R, S, outputs Q, nQ.

Step 2. DLatch — the D latch: "while EN = 1, follow D"

PartPinLabel
Input portoutD
Input portoutEN
NOTI0
O0
D
nD
ANDI0
I1
O0
D
EN
setD
ANDI0
I1
O0
nD
EN
rstD
SRLatchR
S
Q
nQ
rstD
setD
Q
nQ
Output portinQ
Output portinnQ

Ctrl+G → name DLatch. Chip pins: inputs D, EN, outputs Q, nQ.

Step 3. DFF — the D flip-flop: writing only at the CLK edge

Two latches taking turns: while CLK = 0 the master listens to D and the slave holds the output; the moment CLK becomes 1, the master closes and the slave shows what the master managed to store.

PartPinLabel
Input portoutD
Input portoutCLK
NOTI0
O0
CLK
nCLK
DLatch (master)D
EN
Q
nQ
D
nCLK
mid
— (free)
DLatch (slave)D
EN
Q
nQ
mid
CLK
Q
nQ
Output portinQ
Output portinnQ

Ctrl+G → name DFF. Chip pins: inputs D, CLK, outputs Q, nQ.

Step 4. Canvas: switches D and CLK, the D flip-flop, a lamp

PartPinLabel
InputoutD
InputoutCLK
DFFD
CLK
Q
nQ
D
CLK
Q
nQ
LEDinQ

1.3. Check

Flip the switches row by row from the top. We start by writing 0: right after power-up the flip-flop can be either 0 or 1.

№Switch DSwitch CLKLamp QWhat happens
100 → 1darkCLK edge: Q stored D = 0
201 → 0darkthe CLK falling edge writes nothing
310darkD changed, but no CLK edge — Q holds
410 → 1litCLK edge: Q stored D = 1
501litD changed — Q holds
601 → 0litfalling edge — nothing is written
700 → 1darkCLK edge: Q stored D = 0

If Q changes together with D, without a CLK edge, check that the master DLatch has nCLK on EN and the slave has CLK.


Lesson 1 paste (Cmd+I)

Needs the gates NOT, AND, NOR — from lesson 0 or the library.

# Lesson 1 — memory: SR latch, D latch, D flip-flop.chip SRLatch {  portIn(R)  portIn(S)  portOut(Q)  portOut(nQ)  NOR(R, nQ, Q)  NOR(S, Q, nQ)} chip DLatch {  portIn(D)  portIn(EN)  portOut(Q)  portOut(nQ)  NOT(D, nD)  AND(D, EN, setD)  AND(nD, EN, rstD)  SRLatch(S=setD, R=rstD, Q=Q, nQ=nQ)} chip DFF {  portIn(D)  portIn(CLK)  portOut(Q)  portOut(nQ)  NOT(CLK, nCLK)  DLatch(D=D, EN=nCLK, Q=mid)  DLatch(D=mid, EN=CLK, Q=Q, nQ=nQ)} power(VCC)ground(GND)input(D)input(CLK)DFF(D=D, CLK=CLK, Q=Q, nQ=nQ)led(Q)

Stuck? Something doesn't work →