Logo

Nand2Tetris

Completed
Learning the Elements of Computers From the Ground Up
09/01/2023 → 04/28/2024
Computer Architecture Digital Design Python Compilers
index
Note

This article will be updated with more code references and images once I find the time. Quite a bit of this project was done more than a year ago now so I need to compile everything in a easy to read format.

Abstract

In my senior year of high school, I took a computer architecture course which roughly followed the Nand2Tetris Curriculum, which covers topics from every level of the computer system. Through this course, I implemented the hardware and software for a 16 bit Von-Neumann that ran in simulation. The software included an assembler, stack-based virtual machine, high-level language compiler, and frameworks for an operating system.

The Hardware

To learn the foundations of logic gates, I implemented every foundational gate through derived gates, starting with Nand gates and abstracting up from there. As circuits became more complicated, such as Muxes and Adders, I learned how to use Karnough Maps and Boolean algebra to determine the most efficient circuit for a given output.

After getting comfortable with combinational logic, I went on to design sequential logic elements like flip-flop and latches, which enabled me to begin building the components for a CPU, such as the RAM, ROM and ALU. Eventually, when I had all the elements of a single cycle CPU, I linked them together to create a 16-bit two register load-store architecture CPU. It is important to note that this CPU had no hazard or exception handling.

To design the circuits, I used a simplified HDL part of the curriculum which is similar to VHDL in format and structure. Logic elements were simulated in a provided application which emulated the gates and allowed passing binary input to the circuits to observe their outputs.

The Software

After the CPU was finished, I needed a way to evaluate it. Typing out the machine code for such an elementary machine would not actually have been all that bad, but it was tedious and hard to read. Therefore, I implemented a basic assembly and corresponding assembler. Unrealistically, the assembler was not able to run on the CPU and instead was a Java program I wrote.

Once the basic ISA was created, I moved onto making a stack based VM for eventually implementing a high-level java-like language. The VM further abstracted assembly instructions. From there, the final step was implementing a high level programming language. For this, the curriculum provided a language standard called “Jack” which was similar to Java in syntax and functionality, but lacked most of the advanced features of Java; it also could not handle recursion. It did however support full Object-Oriented programming with classes and abstraction.

All of these languages were translated/compiled off the CPU on my own machine. The Compiler and VM translate were written in Python for easy string manipulation. Programs translated all the way down to machine code were then run on the simulated CPU. By using this workflow, I was able to program a snake game in Jack language and run it on my simulated CPU design.

I did learn about the fundamentals of operating systems and created an operating system organization plan, however I never did get the chance to fully implement every aspect. I only completed the file system and a few other frameworks.

Conclusion

This course and its projects were not super realistic with the compiler not running on the actual CPU and the HDL not being an actual standard. However, these projects opened my eyes up to all the different components of modern computing systems and gave me a broad foundation in all the elements that power the devices I use. I already had an interest in software and programming, but this course truly ignited my passion for computer architecture and hardware design.