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

Memory address register (MAR) and MDR: a live circuit

The memory address register (MAR) holds the address of the memory location being read or written, so the address stays put while the bus moves on to carry data. Its partner, the memory data register (MDR), holds the word read from that location. This live circuit has a 2-bit MAR, a 4-word memory and a 4-bit MDR, all fed from one 4-bit bus.

In a simple CPU the address and the data take turns on one shared bus. First the address goes into the MAR: the program counter's value during an instruction fetch, or an operand's address during a load or store. From then on the memory sees that address on its address lines, and the bus is free for data: a write stores the bus value at the MAR's address, and a read puts the addressed word on the memory's output, where the MDR captures it on the next clock edge. Here BUS3 to BUS0 is the bus. With LDMAR high, a rising edge of CLK loads the low two bus bits into the MAR; with WR high, it writes the bus into the word the MAR points at; with LDMDR high, it copies that word, shown on M3 to M0, into the MDR. The MAR is two D flip-flops with a load choice in front, the memory is four of the 4-bit registers with load plus a 2-to-4 decoder for the write enables and four 4:1 multiplexers for reading (the same build as the register file), and the MDR is one more 4-bit register. Everything starts unknown, as real registers and RAM do at power-on. The live circuit opens with LDMAR high and the bus at 0000: turn CLK on and off to load address 00, set LDMAR to 0, put a value on the bus, set WR to 1 and pulse CLK to store it. Before the page is built, an 84-step sequence is checked on the MAR, M and the MDR: writing four words, reading them back in a different order through the MDR, the bus changing while the MAR and MDR hold, and overwriting a word.

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 BUS3 to BUS0, LDMAR, WR, LDMDR and CLK, and probes MAR1, MAR0, M3 to M0 and MDR3 to MDR0.
  2. Build the MAR: two D flip-flops on CLK whose D is BUS when LDMAR is 1 and their own Q when it is 0.
  3. Build the memory: four 4-bit registers on the bus, each loaded when WR is 1 and the MAR decodes to its number, read through 4:1 multiplexers selected by the MAR.
  4. Add the MDR: a 4-bit register that loads M when LDMDR is 1. Load an address, write a value, load another address, then read the first one back.

What each control does on a clock edge

Control highOn the rising edge of CLK
LDMARMAR takes BUS1 BUS0, the address
WRthe word at the MAR's address takes BUS3 to BUS0
LDMDRMDR takes the word at the MAR's address
nonenothing changes

The memory is read all the time: M3 to M0 always show the word at the MAR's address, and the MDR keeps its copy until the next LDMDR. Real memories are far wider and deeper, but the MAR and MDR play the same roles. Small CPUs, like the one in digiwleea's course, often let the program counter drive the address lines directly and fold the MAR away.

You can also read the full theory in the lesson on RAM. 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 circuithardware stack with a stack pointerdirect-mapped cache8-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 memory address register (MAR) and MDR in the lab →

Frequently asked

What is the memory address register?

A register that holds the address of the memory location the CPU is reading or writing right now. Memory takes its address from the MAR, so the address stays steady for the whole access while the bus carries other values.

What is the difference between the MAR and the MDR?

The MAR holds where in memory to read or write (an address); the MDR holds what is being read or written (the data). An access loads the MAR first, then moves the data through the MDR.

What is the difference between the program counter and the MAR?

The program counter holds the address of the next instruction. The MAR holds whatever address memory is using right now: during an instruction fetch it gets a copy of the program counter, and during a load or store it gets the operand's address instead.

Why does a CPU need a memory address register?

Because the address has to stay on memory's address lines for the whole access, while the shared bus is needed for other things, such as the data itself. Latching the address in the MAR frees the bus.