Skip to content
digiwleeaTools
LearnGlossaryAboutCheat sheetHow a CPU worksToolsOpen the lab →

Direct-mapped cache: hits, misses and conflicts, live

In a direct-mapped cache every memory address has exactly one line it can live in: the low address bits (the index) pick the line, and the high bits (the tag) are stored with it, so a lookup is a hit only if that line is valid and holds the same tag. This live 4-line cache splits a 4-bit address A3..A0 into tag A3 A2 and index A1 A0.

Each line here holds a valid bit, a 2-bit tag and 2 bits of data. The index A1 A0 selects one line through 4:1 multiplexers, and two XNOR gates compare its stored tag with A3 A2: HIT = valid AND (tag matches), MISS is the opposite, and D1 D0 show the selected line's data. On a miss, the data would come from main memory; here you play memory by setting DIN1 DIN0 and pressing FILL, and the next clock edge writes the tag and data into the line and sets its valid bit. The interesting case is the conflict miss: addresses 0101 and 1101 have the same index (01) and different tags, so they fight over line 1, and filling one evicts the other, even while lines 0, 2 and 3 sit empty. That is the price of direct mapping, and the reason caches add associativity (the cache lesson covers both). Each line's tag and data are a 4-bit register with load, written through a decoder as in the register file, and the valid bits are D flip-flops that set on a fill and clear on a clock edge with CLR high. Real caches are bigger in every direction (a line holds 32 or 64 bytes, and there are hundreds of lines), but the lookup is the same. The live circuit opens with CLR high and address 0101: turn CLK on and off once to invalidate every line (MISS lights), set CLR to 0, then FILL and pulse CLK to load line 1. Before the page is built, a 23-step sequence is checked on HIT, MISS, V and the selected line's tag and data: misses, fills, a conflict miss and eviction, an untouched line, and invalidating everything.

Big circuit: pinch, scroll or tap + to zoom in, then drag to move around.

Live circuit: click the inputs to toggle them and watch the outputs update. It runs the real simulator, right here on the page.

Open this circuit in the lab →

What you need

Step by step

  1. Place inputs A3 to A0, DIN1, DIN0, FILL, CLK and CLR, and probes HIT, MISS, D1, D0, V, TAG1 and TAG0.
  2. Give each of four lines a register for tag and data and a valid flip-flop, all written on a clock edge when FILL is high and the index A1 A0 selects that line.
  3. Read the selected line through 4:1 multiplexers on A1 A0, and compare its tag with A3 A2 using two XNORs.
  4. HIT = valid AND both tag bits equal. Look up 0101 (miss), fill it, look it up again (hit), then try 1101 (a conflict miss).

A short run

AddressLine (A1 A0)Tag (A3 A2)ResultWhy
01010101missline 01 is empty
0101 after a fill0101hitline 01 holds tag 01
11010111misssame line, different tag (conflict)
1101 after a fill0111hitline 01 now holds tag 11
01010101missevicted by 1101
00101000missline 10 is empty

Address = tag (2 bits) then index (2 bits). With 4 lines and 2 tag bits, this cache holds 4 of the 16 addresses at a time. A real cache line holds a block of bytes, and the lowest address bits pick a byte within it (the offset); with one data word per line, this one has no offset bits.

You can also read the full theory in the lesson on caches. Prefer to build it yourself from scratch? Open the digiwleea lab and place the gates on the canvas, or start from the logic gate simulator.

Build more parts from gates

half adderfull adderhalf subtractorfull subtractor2:1 multiplexer4:1 multiplexerXOR gate from NAND gates2-to-4 decoderSR latchD flip-flopJK flip-flopT flip-flop4-bit shift register4-bit ripple carry adderD latch1-to-4 demultiplexer4-bit magnitude comparator4-bit ring counter4-bit Johnson counter4-to-2 priority encoder4-bit synchronous counter3-to-8 decoder8-to-1 multiplexer4-bit carry lookahead adderhalf adder from NAND gates2-bit comparatorBCD to 7-segment decoder4-bit up/down counterdecade counter2-bit multiplier4-bit ALU4-bit array multiplierNOT, AND, OR and NOR from NANDNOT, OR, AND and XOR from NORfull adder from NAND gatesSR latch from NAND gatesparity generator and checker4-bit adder/subtractorBCD adder4-bit universal shift registermod-6 counter4-bit ripple counterbinary to Gray code converterhalf adder from NOR gatesfull adder from NOR gates4-bit register with parallel load1011 sequence detectorbinary to BCD converterD flip-flop from NAND gates1-bit ALUCMOS inverterCMOS NAND gateCMOS NOR gatePISO shift registerSR flip-flop from NAND gatesBCD to excess-3 code converterHamming (7,4) code encoder and correctortraffic light controller4-bit barrel shifterCMOS AND gateCMOS OR gateCMOS XOR gate1-bit magnitude comparatorhalf subtractor from NAND gatesfull subtractor from NAND gates8-to-3 encoderGray to binary converter4-to-16 decoderfull adder using 4:1 multiplexersedge detectorserial adder4-bit carry-select adder4-bit Kogge-Stone adder4-bit carry-skip adder4x4 Wallace tree multiplier8-bit adderfrequency divider (by 2, 4 and 3)switch debouncer (SR latch)3-bit Gray code counterMealy machine (1011 detector)master-slave JK flip-flop (NAND)half subtractor from NOR gates1-to-8 demultiplexerexcess-3 to BCD code convertervending machine FSM4-bit carry-save adder3-bit synchronous counter (JK)CMOS transmission gatetri-state buffer (CMOS)2-to-1 mux from transmission gatesmod-5 counterflip-flop conversion (JK to D)8-bit ALUdecimal to BCD encoderBCD to decimal decoder4-to-1 mux from 2-to-1 muxesXOR gate from NOR gates4-bit LFSR74LS138 decoderBCD subtractor74181 ALUCMOS AOI gate (AOI21)D latch vs D flip-flop74LS47 BCD to 7-segment decoder74HC595 shift register7400 quad NAND gate chip7402 quad NOR gate chip7404 hex inverter chip7408 quad AND gate chip7432 quad OR gate chip7486 quad XOR gate chip7474 dual D flip-flop74HC165 shift registerCD4017 decade counter74LS283 4-bit adder74LS90 decade counter74HC161 4-bit counter74HC151 8-to-1 multiplexer74HC157 quad 2-to-1 multiplexer74HC139 dual 2-to-4 decoderCD4511 BCD to 7-segment decoder7492 divide-by-12 counter7493 4-bit binary counter74HC244 octal bufferRace-around condition (JK latch)74HC373 octal latch74HC374 octal D flip-flopTurnstile state machine1-to-2 demultiplexerhalf adder using 2:1 multiplexersregister file (4 x 4-bit)digital PWM generatorCD4013 dual D flip-flop74LS76 dual JK flip-flop7410 triple 3-input NAND chip7411 triple 3-input AND chip7420 dual 4-input NAND chipCD4011 quad 2-input NAND chipCD4001 quad 2-input NOR chipCD4081 quad 2-input AND chipCD4069 hex inverter chip74HC164 8-bit shift register7485 4-bit magnitude comparator74HC125 quad tri-state bufferCD4040 12-stage binary counterCD4060 14-stage counter and oscillator74LS193 4-bit up/down counterelectronic dice circuitmemory address register (MAR) and MDRhardware stack with a stack pointer8-bit Brent-Kung adder4x4 Dadda multiplierbinary clock circuit

Each of these is one step from a transistor to a working CPU. Build every gate from CMOS transistors and work all the way up in the free digiwleea lab, with the free theory reference alongside.

Open the direct-mapped cache in the lab →

Frequently asked

How does a direct-mapped cache work?

The address is split into a tag and an index. The index selects exactly one cache line, and the cache compares that line's stored tag with the address's tag: if the line is valid and the tags match it is a hit, otherwise a miss, and the block is fetched from memory into that line, replacing whatever was there.

What is a conflict miss?

A miss caused by two addresses that map to the same line. In a direct-mapped cache they keep evicting each other even if the rest of the cache is empty. Associative caches reduce conflict misses by letting a block sit in any of several lines.

What are the tag, index and offset?

The offset (lowest bits) picks a byte within a cache line, the index (middle bits) picks the line, and the tag (highest bits) is stored in the line to tell which of the many addresses with that index is there now.

What is the valid bit for?

It says whether a line holds real data. At power-on, or after the cache is flushed, every valid bit is 0, so every lookup misses even if a stored tag happens to match.