diff --git a/Assignments/5_Computer_Architecture/CPU.hdl b/Assignments/5_Computer_Architecture/CPU.hdl new file mode 100644 index 0000000..d43b323 --- /dev/null +++ b/Assignments/5_Computer_Architecture/CPU.hdl @@ -0,0 +1,60 @@ +// This file is part of www.nand2tetris.org +// and the book "The Elements of Computing Systems" +// by Nisan and Schocken, MIT Press. +// File name: projects/5/CPU.hdl +/** + * The Hack Central Processing unit (CPU). + * Parses the binary code in the instruction input and executes it according to the + * Hack machine language specification. In the case of a C-instruction, computes the + * function specified by the instruction. If the instruction specifies to read a memory + * value, the inM input is expected to contain this value. If the instruction specifies + * to write a value to the memory, sets the outM output to this value, sets the addressM + * output to the target address, and asserts the writeM output (when writeM = 0, any + * value may appear in outM). + * If the reset input is 0, computes the address of the next instruction and sets the + * pc output to that value. If the reset input is 1, sets pc to 0. + * Note: The outM and writeM outputs are combinational: they are affected by the + * instruction's execution during the current cycle. The addressM and pc outputs are + * clocked: although they are affected by the instruction's execution, they commit to + * their new values only in the next cycle. + */ +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: + Not(in=instruction[15], out=ai); + Not(in=ai, out=ci); + And(a=ci, b=instruction[5], out=wa); + Mux16(a=instruction, b=alu, sel=wa, out=a); + Or(a=ai, b=wa, out=la); + ARegister(in=a, load=la, out=ao); + Mux16(a=ao, b=inM, sel=instruction[12], out=am); + And(a=ci, b=instruction[4], out=ld); + DRegister(in=alu, load=ld, out=do); + ALU(x=do, y=am, zx=instruction[11], nx=instruction[10], + zy=instruction[9], ny=instruction[8], f=instruction[7], + no=instruction[6], out=alu, zr=zr, ng=ng); + Or16(a=false, b=ao, out[0..14]=addressM); + Or16(a=false, b=alu, out=outM); + And(a=ci, b=instruction[3], out=writeM); + And(a=zr, b=instruction[1], out=jeq); + And(a=ng, b=instruction[2], out=jlt); + Or(a=zr, b=ng, out=zon); + Not(in=zon, out=p); + And(a=p, b=instruction[0], out=jgt); + Or(a=jeq, b=jlt, out=jle); + Or(a=jle, b=jgt, out=j); + And(a=ci, b=j, out=l); + Not(in=l, out=i); + PC(in=ao, inc=i, load=l, reset=reset, out[0..14]=pc); +} \ No newline at end of file diff --git a/Assignments/5_Computer_Architecture/Computer.hdl b/Assignments/5_Computer_Architecture/Computer.hdl new file mode 100644 index 0000000..ce2a217 --- /dev/null +++ b/Assignments/5_Computer_Architecture/Computer.hdl @@ -0,0 +1,25 @@ +// This file is part of www.nand2tetris.org +// and the book "The Elements of Computing Systems" +// by Nisan and Schocken, MIT Press. +// File name: projects/5/Computer.hdl +/** + * The Hack computer, consisting of CPU, ROM and RAM. + * When reset = 0, the program stored in the ROM executes. + * When reset = 1, the program's execution restarts. + * Thus, to start running the currently loaded program, + * set reset to 1, and then set it to 0. + * From this point onwards, the user is at the mercy of the software. + * Depending on the program's code, and whether the code is correct, + * the screen may show some output, the user may be expected to enter + * some input using the keyboard, or the program may do some procerssing. + */ +CHIP Computer { + + IN reset; + + PARTS: + CPU(inM=inM, instruction=instruction, reset=reset, + outM=outM, writeM=writeM, addressM=addressM, pc=pc); + Memory(in=outM, load=writeM, address=addressM, out=inM); + ROM32K(address=pc, out=instruction); +} \ No newline at end of file diff --git a/Assignments/5_Computer_Architecture/Memory.hdl b/Assignments/5_Computer_Architecture/Memory.hdl new file mode 100644 index 0000000..ef15451 --- /dev/null +++ b/Assignments/5_Computer_Architecture/Memory.hdl @@ -0,0 +1,34 @@ +// This file is part of www.nand2tetris.org +// and the book "The Elements of Computing Systems" +// by Nisan and Schocken, MIT Press. +// File name: projects/5/Memory.hdl +/** + * 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 and reads 0. 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 lectures and the book. + */ +CHIP Memory { + IN in[16], load, address[15]; + OUT out[16]; + + PARTS: + DMux(in=load, sel=address[14], a=lr, b=ls); + RAM16K(in=in, load=lr, address=address[0..13], out=ro); + Screen(in=in, load=ls, address=address[0..12], out=so); + Keyboard(out=ko); + Mux16(a=so, b=ko, sel=address[13], out=o1); + Mux16(a=ro, b=o1, sel=address[14], out=out); +} \ No newline at end of file diff --git a/Chapters/5_Computer_Architecture.pdf b/Chapters/5_Computer_Architecture.pdf new file mode 100644 index 0000000..4c2dac9 Binary files /dev/null and b/Chapters/5_Computer_Architecture.pdf differ diff --git a/README.md b/README.md index 0e05a0c..d619aea 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ > Вводим единицу времени - такт, за счёт чего появляется текущее и следующее состояние, которое можно запоминать и изменять. Создаём простейшую память. На основе DFF компонента создаём [однобитный регистр](./Assignments/3_Sequential_Logic/Bit.hdl), затем [16-битный регистр](./Assignments/3_Sequential_Logic/Register.hdl), из них собираем блоки оперативной памяти ([RAM8](./Assignments/3_Sequential_Logic/RAM8.hdl), [RAM64](./Assignments/3_Sequential_Logic/RAM64.hdl), [RAM512](./Assignments/3_Sequential_Logic/RAM512.hdl), [RAM4K](./Assignments/3_Sequential_Logic/RAM4K.hdl), [RAM16K](./Assignments/3_Sequential_Logic/RAM16K.hdl)), а так же создаём простой [счётчик](./Assignments/3_Sequential_Logic/PC.hdl), который может использоваться для хранения текущей выполняемой инструкции и перехода к новой инструкции - [Project 4: Machine Language](./Assignments/4_Machine_Language/) > Разбираемся с тем, что такое машинный код и как компьютер выполняет комманды записанные с его помощью. Вводим понятие ассемблера, и изучаем язык ассемблера для создаваемой платформы. [Пишем пару простых программ](./Assignments/4_Machine_Language/), в том числе [реализуем простое чтение данных с клавиатуры и вывод картинки на эмулятор экрана](./Assignments/4_Machine_Language/Fill.asm) - - Project 5: Computer Architecture + - [Project 5: Computer Architecture](./Assignments/5_Computer_Architecture/) + > Завершаем работу над аппаратной составляющей компьютера. [Собираем модуль памяти](./Assignments/5_Computer_Architecture/Memory.hdl), позволяющий, в том числе, взаимодействовать с клавиатурой и экраном. [Собираем ЦПУ](./Assignments/5_Computer_Architecture/CPU.hdl) из ранее созданных ALU, счётчика и регистров. Из памяти, ЦПУ и чипа ROM с набором инструкций [собираем компьютер Hack](./Assignments/5_Computer_Architecture/Computer.hdl) - Project 6: Assembler - #### Software - Project 7: VM I: Stack Arithmetic