0297-Nand-计算机架构

环境

  • Time 2023-07-08

前言

说明

参考:https://www.nand2tetris.org/

目标

接上一节,实现 CPU、Memory、Computer。

CPU

/**
 * The Hack CPU (Central Processing unit), consisting of an ALU,
 * two registers named A and D, and a program counter named PC.
 * The CPU is designed to fetch and execute instructions written in
 * the Hack machine language. In particular, functions as follows:
 * Executes the inputted instruction according to the Hack machine
 * language specification. The D and A in the language specification
 * refer to CPU-resident registers, while M refers to the external
 * memory location addressed by A, i.e. to Memory[A]. The inM input
 * holds the value of this location. If the current instruction needs
 * to write a value to M, the value is placed in outM, the address
 * of the target location is placed in the addressM output, and the
 * writeM control bit is asserted. (When writeM==0, any value may
 * appear in outM). The outM and writeM outputs are combinational:
 * they are affected instantaneously by the execution of the current
 * instruction. The addressM and pc outputs are clocked: although they
 * are affected by the execution of the current instruction, they commit
 * to their new values only in the next time step. If reset==1 then the
 * CPU jumps to address 0 (i.e. pc is set to 0 in next time step) rather
 * than to the address resulting from executing the current instruction.
 */

CHIP CPU {

    IN  inM[16],         // M value input  (M = contents of RAM[A])
        instruction[16], // Instruction for execution
        reset;           // Signals whether to re-start the current
                         // program (reset==1) or continue executing
                         // the current program (reset==0).

    OUT outM[16],        // M value output
        writeM,          // Write to M?
        addressM[15],    // Address in data memory (of M)
        pc[15];          // address of next instruction

    PARTS:
    // Put your code here:
    // 第一个Mux,指令的第15位来判断是否为A指令,为0则是A,否则是C
    Not(in=instruction[15], out=isA);
    Mux16(a=outInner, b=instruction, sel=isA, out=o1);

    // A指令,或者C指令的情况下,第5位为1会修改A寄存器
    // 第五位也是ddd的第一位
    Not(in=instruction[5], out=d1not);
    // 只有第15为1,表示C指令,并且d1位不是1的情况,A寄存器不变
    Nand(a=instruction[15], b=d1not, out=ca);
    // A指令也是地址寄存器,地址跟着一起变
    ARegister(in=o1, load=ca, out=oa,out[0..14]=addressM);

    // 第二个 Mux,C指令的情况下,第12位为1表示操作M,为0表示操作A
    And(a=instruction[15], b=instruction[12], out=a);
    Mux16(a=oa, b=inM, sel=a, out=o2);

    // D寄存器,第四位,即ddd的第二位,为1表示操作D寄存器
    And(a=instruction[15], b=instruction[4], out=d2);
    DRegister(in=outInner, load=d2, out=od);

    // the ALU
    And(a=instruction[15], b=instruction[11], out=c1);
    And(a=instruction[15], b=instruction[10], out=c2);
    And(a=instruction[15], b=instruction[9],  out=c3);
    And(a=instruction[15], b=instruction[8],  out=c4);
    And(a=instruction[15], b=instruction[7],  out=c5);
    And(a=instruction[15], b=instruction[6],  out=c6);
    ALU(x=od,y=o2,zx=c1,nx=c2,zy=c3,ny=c4,f=c5,no=c6,out=outM,out=outInner,zr=zr,ng=ng);

    // jjj 三位跳转的位
    And(a=instruction[15], b=instruction[0], out=j3);
    And(a=instruction[15], b=instruction[1], out=j2);
    And(a=instruction[15], b=instruction[2], out=j1);
    // 0 和 负数
    Or(a=ng, b=zr, out=ngzr);
    // 大于 0
    Not(in=ngzr, out=ngzrnot);

    And(a=j1, b=ng, out=isLT);
    And(a=j2, b=zr, out=isEq);
    And(a=j3, b=ngzrnot, out=isGT);

    // 需要跳转
    Or(a=isLT, b=isEq, out=orPart);
    Or(a=orPart, b=isGT, out=isJump);
    // 不跳转
    Not(in=isJump, out=notJump);
    PC(in=oa, load=isJump, inc=notJump, reset=reset, out[0..14]=pc);

    // 判断是否写回M
    And(a=instruction[15], b=instruction[3], out=d3);
    Or(a=false, b=d3, out=writeM);
}

Memory


/**
 * The complete address space of the Hack computer's memory,
 * including RAM and memory-mapped I/O.
 * The chip facilitates read and write operations, as follows:
 *     Read:  out(t) = Memory[address(t)](t)
 *     Write: if load(t-1) then Memory[address(t-1)](t) = in(t-1)
 * In words: the chip always outputs the value stored at the memory
 * location specified by address. If load==1, the in value is loaded
 * into the memory location specified by address. This value becomes
 * available through the out output from the next time step onward.
 * Address space rules:
 * Only the upper 16K+8K+1 words of the Memory chip are used.
 * Access to address>0x6000 is invalid. Access to any address in
 * the range 0x4000-0x5FFF results in accessing the screen memory
 * map. Access to address 0x6000 results in accessing the keyboard
 * memory map. The behavior in these addresses is described in the
 * Screen and Keyboard chip specifications given in the book.
 */

CHIP Memory {
    IN in[16], load, address[15];
    OUT out[16];

    PARTS:
    // Put your code here:
    // 如果第14位是0,则选择RAM,否则选择屏幕或者键盘
    DMux(in=load, sel=address[14], a=loadRAM16K, b=loadMap);
    // 如果第13位是0,则选择屏幕,否则选择键盘
    DMux(in=loadMap,sel=address[13],a=loadScreenMap, b=loadKeyMap);
    // RAM
    RAM16K(in=in, load=loadRAM16K, address=address[0..13],out=oR);
    // 屏幕
    Screen(in=in, load=loadScreenMap, address=address[0..12], out=oS);
    // 键盘
    Keyboard(out=oK);
    // 多路选择
    Mux4Way16(a=oR, b=oR,c=oS, d=oK,sel=address[13..14], out=out);
}

Computer

/**
 * The HACK computer, including CPU, ROM and RAM.
 * When reset is 0, the program stored in the computer's ROM executes.
 * When reset is 1, the execution of the program restarts.
 * Thus, to start a program's execution, reset must be pushed "up" (1)
 * and "down" (0). From this point onward the user is at the mercy of
 * the software. In particular, depending on the program's code, the
 * screen may show some output and the user may be able to interact
 * with the computer via the keyboard.
 */

CHIP Computer {

    IN reset;

    PARTS:
    // Put your code here:
    ROM32K(address=insAddress, out=Ins);
    CPU(inM=inM, instruction=Ins, reset=reset, outM=outM,
        writeM=writeM, addressM=mAddress, pc=insAddress);
    Memory(in=outM, load=writeM, address=mAddress, out=inM);
}

总结

编写了一个可以运行的计算机。

附录

posted @ 2025-10-30 17:47  jiangbo4444  阅读(7)  评论(0)    收藏  举报