关于Nand2Tetris课程中Memory芯片实现的技术疑问
Hey there! Let's work through the kinks in your Memory chip implementation for Nand2Tetris— I’ve spotted a few logical missteps that are probably causing your confusion. First, let’s recap the expected address mapping for the Memory chip (15-bit addresses, 0x0000 to 0x7FFF):
- 0x0000–0x3FFF: 16K RAM (writable)
- 0x4000–0x5FFF: 8K Screen (writable)
- 0x6000–0x7FFE: Unused region (outputs 0, no write support)
- 0x7FFF: Keyboard (read-only, no write support)
Key Issues in Your Code
Backwards DMux Selection Bits
You usedaddress[13..14]as theselfor yourDMux4Way, but 15-bit addresses have their highest two bits at positions 14 (most significant) and 13 (next). Reversing these swaps the address mapping entirely— your RAM would try to handle Screen writes, and vice versa. The correct sel should beaddress[14..13].Incorrect RAM Load Signal Logic
UsingOr(a=RAM1, b=RAM2, out=RAM)to drive the RAM16K load signal is wrong.RAM2corresponds to the Screen address range (0x4000–0x5FFF), so this would accidentally write to RAM whenever you try to write to the Screen. RAM16K should only load when the address falls in its own range (sel=00 from the DMux), so you should directly use theaoutput of the DMux as the RAM load signal.Broken Mux4Way16 Configuration
Your Mux is incomplete, and you’re feedingRAMoutto bothaandbinputs— that means you’d never get the Screen output even when addressing it. The Mux needs to map each input to its corresponding address region:a: RAM output (0x0000–0x3FFF)b: Screen output (0x4000–0x5FFF)c: Constantfalse(unused region, outputs 0)d: Keyboard output (0x7FFF)
Also, the Mux’sselmust match the DMux’ssel(address[14..13]) to keep the mapping consistent.
Unnecessary Keyboard Load Signal
The Keyboard chip is read-only— it has noinorloadinputs. Feeding akbrsignal to it does nothing, so we can safely ignore the DMux’sdoutput for writes.
Fixed Implementation
Here’s the corrected CHIP code that addresses all these issues:
CHIP Memory { IN in[16], load, address[15]; OUT out[16]; PARTS: // Split load signal based on top 2 address bits (14 = MSB, 13 = next) DMux4Way(in=load, sel=address[14..13], a=ramLoad, b=screenLoad, c=unusedLoad, d=kbdLoad); // 16K RAM: handles addresses 0x0000-0x3FFF (top bits 00) RAM16K(in=in, load=ramLoad, address=address[0..13], out=ramOut); // 8K Screen: handles addresses 0x4000-0x5FFF (top bits 01) Screen(in=in, load=screenLoad, address=address[0..12], out=screenOut); // Keyboard: only responds to address 0x7FFF (top bits 11) Keyboard(out=kbdOut); // Route correct output based on top address bits Mux4Way16(a=ramOut, b=screenOut, c=false, d=kbdOut, sel=address[14..13], out=out); }
Quick Notes on the Fixes
- The DMux now correctly routes the
loadsignal only to the relevant component (RAM or Screen) based on the top address bits. - The Mux selects the right output source for every address range, including returning 0 for unused addresses.
- We don’t waste cycles trying to write to the Keyboard or unused region, since those operations are invalid anyway.
内容的提问来源于stack exchange,提问作者helsereet




